1
2 /*--------------------------------------------------------------------*/
3 /*--- Startup: the real stuff m_main.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2000-2011 Julian Seward
11 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29 */
30
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_vkiscnums.h"
34 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
35 #include "pub_core_threadstate.h"
36 #include "pub_core_xarray.h"
37 #include "pub_core_clientstate.h"
38 #include "pub_core_aspacemgr.h"
39 #include "pub_core_aspacehl.h"
40 #include "pub_core_commandline.h"
41 #include "pub_core_debuglog.h"
42 #include "pub_core_errormgr.h"
43 #include "pub_core_execontext.h"
44 #include "pub_core_gdbserver.h"
45 #include "pub_core_initimg.h"
46 #include "pub_core_libcbase.h"
47 #include "pub_core_libcassert.h"
48 #include "pub_core_libcfile.h"
49 #include "pub_core_libcprint.h"
50 #include "pub_core_libcproc.h"
51 #include "pub_core_libcsignal.h"
52 #include "pub_core_syscall.h" // VG_(strerror)
53 #include "pub_core_mach.h"
54 #include "pub_core_machine.h"
55 #include "pub_core_mallocfree.h"
56 #include "pub_core_options.h"
57 #include "pub_core_debuginfo.h"
58 #include "pub_core_redir.h"
59 #include "pub_core_scheduler.h"
60 #include "pub_core_seqmatch.h" // For VG_(string_match)
61 #include "pub_core_signals.h"
62 #include "pub_core_stacks.h" // For VG_(register_stack)
63 #include "pub_core_syswrap.h"
64 #include "pub_core_tooliface.h"
65 #include "pub_core_translate.h" // For VG_(translate)
66 #include "pub_core_trampoline.h"
67 #include "pub_core_transtab.h"
68
69
70 /*====================================================================*/
71 /*=== Counters, for profiling purposes only ===*/
72 /*====================================================================*/
73
print_all_stats(void)74 static void print_all_stats ( void )
75 {
76 VG_(print_translation_stats)();
77 VG_(print_tt_tc_stats)();
78 VG_(print_scheduler_stats)();
79 VG_(print_ExeContext_stats)();
80 VG_(print_errormgr_stats)();
81
82 // Memory stats
83 if (VG_(clo_verbosity) > 2) {
84 VG_(message)(Vg_DebugMsg, "\n");
85 VG_(message)(Vg_DebugMsg,
86 "------ Valgrind's internal memory use stats follow ------\n" );
87 VG_(sanity_check_malloc_all)();
88 VG_(message)(Vg_DebugMsg, "------\n" );
89 VG_(print_all_arena_stats)();
90 VG_(message)(Vg_DebugMsg, "\n");
91 }
92 }
93
94
95 /*====================================================================*/
96 /*=== Command-line: variables, processing, etc ===*/
97 /*====================================================================*/
98
99 // See pub_{core,tool}_options.h for explanations of all these.
100
usage_NORETURN(Bool debug_help)101 static void usage_NORETURN ( Bool debug_help )
102 {
103 /* 'usage1' contains a %s
104 - for the name of the GDB executable
105 - for the name of vgdb's path prefix
106 which must be supplied when they are VG_(printf)'d. */
107 Char* usage1 =
108 "usage: valgrind [options] prog-and-args\n"
109 "\n"
110 " tool-selection option, with default in [ ]:\n"
111 " --tool=<name> use the Valgrind tool named <name> [memcheck]\n"
112 "\n"
113 " basic user options for all Valgrind tools, with defaults in [ ]:\n"
114 " -h --help show this message\n"
115 " --help-debug show this message, plus debugging options\n"
116 " --version show version\n"
117 " -q --quiet run silently; only print error msgs\n"
118 " -v --verbose be more verbose -- show misc extra info\n"
119 " --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]\n"
120 " --trace-children-skip=patt1,patt2,... specifies a list of executables\n"
121 " that --trace-children=yes should not trace into\n"
122 " --trace-children-skip-by-arg=patt1,patt2,... same as --trace-children-skip=\n"
123 " but check the argv[] entries for children, rather\n"
124 " than the exe name, to make a follow/no-follow decision\n"
125 " --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n"
126 " --vgdb=no|yes|full activate gdbserver? [yes]\n"
127 " full is slower but provides precise watchpoint/step\n"
128 " --vgdb-error=<number> invoke gdbserver after <number> errors [%d]\n"
129 " to get started quickly, use --vgdb-error=0\n"
130 " and follow the on-screen directions\n"
131 " --track-fds=no|yes track open file descriptors? [no]\n"
132 " --time-stamp=no|yes add timestamps to log messages? [no]\n"
133 " --log-fd=<number> log messages to file descriptor [2=stderr]\n"
134 " --log-file=<file> log messages to <file>\n"
135 " --log-socket=ipaddr:port log messages to socket ipaddr:port\n"
136 "\n"
137 " user options for Valgrind tools that report errors:\n"
138 " --xml=yes emit error output in XML (some tools only)\n"
139 " --xml-fd=<number> XML output to file descriptor\n"
140 " --xml-file=<file> XML output to <file>\n"
141 " --xml-socket=ipaddr:port XML output to socket ipaddr:port\n"
142 " --xml-user-comment=STR copy STR verbatim into XML output\n"
143 " --demangle=no|yes automatically demangle C++ names? [yes]\n"
144 " --num-callers=<number> show <number> callers in stack traces [12]\n"
145 " --error-limit=no|yes stop showing new errors if too many? [yes]\n"
146 " --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
147 " --show-below-main=no|yes continue stack traces below main() [no]\n"
148 " --suppressions=<filename> suppress errors described in <filename>\n"
149 " --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
150 " --db-attach=no|yes start debugger when errors detected? [no]\n"
151 " --db-command=<command> command to start debugger [%s -nw %%f %%p]\n"
152 " --input-fd=<number> file descriptor for input [0=stdin]\n"
153 " --dsymutil=no|yes run dsymutil on Mac OS X when helpful? [no]\n"
154 " --max-stackframe=<number> assume stack switch for SP changes larger\n"
155 " than <number> bytes [2000000]\n"
156 " --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
157 " [use current 'ulimit' value]\n"
158 "\n"
159 " user options for Valgrind tools that replace malloc:\n"
160 " --alignment=<number> set minimum alignment of heap allocations [%ld]\n"
161 "\n"
162 " uncommon user options for all Valgrind tools:\n"
163 " --fullpath-after= (with nothing after the '=')\n"
164 " show full source paths in call stacks\n"
165 " --fullpath-after=string like --fullpath-after=, but only show the\n"
166 " part of the path after 'string'. Allows removal\n"
167 " of path prefixes. Use this flag multiple times\n"
168 " to specify a set of prefixes to remove.\n"
169 " --smc-check=none|stack|all|all-non-file [stack]\n"
170 " checks for self-modifying code: none, only for\n"
171 " code found in stacks, for all code, or for all\n"
172 " code except that from file-backed mappings\n"
173 " --read-var-info=yes|no read debug info on stack and global variables\n"
174 " and use it to print better error messages in\n"
175 " tools that make use of it (Memcheck, Helgrind,\n"
176 " DRD) [no]\n"
177 " --vgdb-poll=<number> gdbserver poll max every <number> basic blocks [%d] \n"
178 " --vgdb-shadow-registers=no|yes let gdb see the shadow registers [no]\n"
179 " --vgdb-prefix=<prefix> prefix for vgdb FIFOs [%s]\n"
180 " --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
181 " --sim-hints=hint1,hint2,... known hints:\n"
182 " lax-ioctls, enable-outer, fuse-compatible [none]\n"
183 " --kernel-variant=variant1,variant2,... known variants: bproc [none]\n"
184 " handle non-standard kernel variants\n"
185 " --show-emwarns=no|yes show warnings about emulation limits? [no]\n"
186 " --require-text-symbol=:sonamepattern:symbolpattern abort run if the\n"
187 " stated shared object doesn't have the stated\n"
188 " text symbol. Patterns can contain ? and *.\n"
189 "\n";
190
191 Char* usage2 =
192 "\n"
193 " debugging options for all Valgrind tools:\n"
194 " -d show verbose debugging output\n"
195 " --stats=no|yes show tool and core statistics [no]\n"
196 " --sanity-level=<number> level of sanity checking to do [1]\n"
197 " --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
198 " --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
199 " --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
200 " --trace-syscalls=no|yes show all system calls? [no]\n"
201 " --trace-signals=no|yes show signal handling details? [no]\n"
202 " --trace-symtab=no|yes show symbol table details? [no]\n"
203 " --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
204 " --trace-cfi=no|yes show call-frame-info details? [no]\n"
205 " --debug-dump=syms mimic /usr/bin/readelf --syms\n"
206 " --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
207 " --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
208 " --trace-redir=no|yes show redirection details? [no]\n"
209 " --trace-sched=no|yes show thread scheduler details? [no]\n"
210 " --profile-heap=no|yes profile Valgrind's own space use\n"
211 " --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
212 " --sym-offsets=yes|no show syms in form 'name+offset' ? [no]\n"
213 " --command-line-only=no|yes only use command line options [no]\n"
214 "\n"
215 " Vex options for all Valgrind tools:\n"
216 " --vex-iropt-verbosity=<0..9> [0]\n"
217 " --vex-iropt-level=<0..2> [2]\n"
218 " --vex-iropt-precise-memory-exns=no|yes [no]\n"
219 " --vex-iropt-unroll-thresh=<0..400> [120]\n"
220 " --vex-guest-max-insns=<1..100> [50]\n"
221 " --vex-guest-chase-thresh=<0..99> [10]\n"
222 " --vex-guest-chase-cond=no|yes [no]\n"
223 " --trace-flags and --profile-flags values (omit the middle space):\n"
224 " 1000 0000 show conversion into IR\n"
225 " 0100 0000 show after initial opt\n"
226 " 0010 0000 show after instrumentation\n"
227 " 0001 0000 show after second opt\n"
228 " 0000 1000 show after tree building\n"
229 " 0000 0100 show selecting insns\n"
230 " 0000 0010 show after reg-alloc\n"
231 " 0000 0001 show final assembly\n"
232 " (Nb: you need --trace-notbelow with --trace-flags for full details)\n"
233 "\n"
234 " debugging options for Valgrind tools that report errors\n"
235 " --dump-error=<number> show translation for basic block associated\n"
236 " with <number>'th error context [0=show none]\n"
237 "\n"
238 " debugging options for Valgrind tools that replace malloc:\n"
239 " --trace-malloc=no|yes show client malloc details? [no]\n"
240 "\n";
241
242 Char* usage3 =
243 "\n"
244 " Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
245 "\n"
246 " %s is %s\n"
247 " Valgrind is Copyright (C) 2000-2011, and GNU GPL'd, by Julian Seward et al.\n"
248 " LibVEX is Copyright (C) 2004-2011, and GNU GPL'd, by OpenWorks LLP et al.\n"
249 "\n"
250 " Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
251 "\n";
252
253 Char* gdb_path = GDB_PATH;
254
255 // Ensure the message goes to stdout
256 VG_(log_output_sink).fd = 1;
257 VG_(log_output_sink).is_socket = False;
258
259 /* 'usage1' expects two int, two char* argument, and one SizeT argument. */
260 VG_(printf)(usage1,
261 VG_(clo_vgdb_error), gdb_path, VG_MIN_MALLOC_SZB,
262 VG_(clo_vgdb_poll), VG_(vgdb_prefix_default)());
263 if (VG_(details).name) {
264 VG_(printf)(" user options for %s:\n", VG_(details).name);
265 if (VG_(needs).command_line_options)
266 VG_TDICT_CALL(tool_print_usage);
267 else
268 VG_(printf)(" (none)\n");
269 }
270 if (debug_help) {
271 VG_(printf)("%s", usage2);
272
273 if (VG_(details).name) {
274 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
275
276 if (VG_(needs).command_line_options)
277 VG_TDICT_CALL(tool_print_debug_usage);
278 else
279 VG_(printf)(" (none)\n");
280 }
281 }
282 VG_(printf)(usage3, VG_(details).name, VG_(details).copyright_author,
283 VG_BUGS_TO);
284 VG_(exit)(0);
285 }
286
287
288 /* Peer at previously set up VG_(args_for_valgrind) and do some
289 minimal command line processing that must happen early on:
290
291 - show the version string, if requested (-v)
292 - extract any request for help (--help, -h, --help-debug)
293 - get the toolname (--tool=)
294 - set VG_(clo_max_stackframe) (--max-stackframe=)
295 - set VG_(clo_main_stacksize) (--main-stacksize=)
296
297 That's all it does. The main command line processing is done below
298 by main_process_cmd_line_options. Note that
299 main_process_cmd_line_options has to handle but ignore the ones we
300 have handled here.
301 */
early_process_cmd_line_options(Int * need_help,HChar ** tool)302 static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
303 /*OUT*/HChar** tool )
304 {
305 UInt i;
306 HChar* str;
307
308 vg_assert( VG_(args_for_valgrind) );
309
310 /* parse the options we have (only the options we care about now) */
311 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
312
313 str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
314 vg_assert(str);
315
316 // Nb: the version string goes to stdout.
317 if VG_XACT_CLO(str, "--version", VG_(log_output_sink).fd, 1) {
318 VG_(log_output_sink).is_socket = False;
319 VG_(printf)("valgrind-" VERSION "\n");
320 VG_(exit)(0);
321 }
322 else if VG_XACT_CLO(str, "--help", *need_help, *need_help+1) {}
323 else if VG_XACT_CLO(str, "-h", *need_help, *need_help+1) {}
324
325 else if VG_XACT_CLO(str, "--help-debug", *need_help, *need_help+2) {}
326
327 // The tool has already been determined, but we need to know the name
328 // here.
329 else if VG_STR_CLO(str, "--tool", *tool) {}
330
331 // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
332 // These are needed by VG_(ii_create_image), which happens
333 // before main_process_cmd_line_options().
334 else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
335 else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
336 }
337 }
338
reopen_output_fd(Bool xml)339 Int reopen_output_fd(Bool xml) {
340 // Returns FD
341 Char *filename = NULL;
342 Char *fsname_unexpanded = xml ? VG_(clo_xml_fname_unexpanded) :
343 VG_(clo_log_fname_unexpanded);
344 const Char *output_type = xml ? "xml" : "log";
345 Int ret = -1;
346 SysRes sres;
347
348 vg_assert(fsname_unexpanded != NULL);
349 vg_assert(VG_(strlen)(fsname_unexpanded) <= 900); /* paranoia */
350
351 // Nb: we overwrite an existing file of this name without asking
352 // any questions.
353 filename = VG_(expand_file_name)(xml ? "--xml-file" : "--log-file",
354 fsname_unexpanded);
355 sres = VG_(open)(filename,
356 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
357 VKI_S_IRUSR|VKI_S_IWUSR);
358 if (!sr_isError(sres)) {
359 ret = sr_Res(sres);
360 if (xml)
361 VG_(clo_xml_fname_expanded) = filename;
362 else
363 VG_(clo_log_fname_expanded) = filename;
364
365 /* strdup here is probably paranoid overkill, but ... */
366 // TODO: do we need to do anything with it?
367 /* *fsname_unexpanded = VG_(strdup)( "main.mpclo.2",
368 xml_fsname_unexpanded ); */
369 } else {
370 VG_(message)(Vg_UserMsg,
371 "Can't create %s file '%s' (%s); giving up!\n",
372 output_type, filename, VG_(strerror)(sr_Err(sres)));
373 VG_(fmsg_bad_option)("--[xml|log]-file=<file>",
374 "--[xml|log]-file=<file> (didn't work out for some reason.)");
375 /*NOTREACHED*/
376 }
377
378 return ret;
379 }
380
move_fd_into_safe_range(Int fd,Bool xml)381 static Int move_fd_into_safe_range(Int fd, Bool xml) {
382 OutputSink *sink = xml ? &(VG_(xml_output_sink)) : &(VG_(log_output_sink));
383 // Move fd into the safe range, so it doesn't conflict with any app fds.
384 fd = VG_(fcntl)(fd, VKI_F_DUPFD, VG_(fd_hard_limit));
385 if (fd < 0) {
386 VG_(printf)("valgrind: failed to move %s file fd "
387 "into safe range, using stderr\n", xml ? "XML" : "log");
388 sink->fd = 2; // stderr
389 sink->is_socket = False;
390 } else {
391 sink->fd = fd;
392 VG_(fcntl)(fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
393 }
394 return fd;
395 }
396
397 /* The main processing for command line options. See comments above
398 on early_process_cmd_line_options.
399
400 Comments on how the logging options are handled:
401
402 User can specify:
403 --log-fd= for a fd to write to (default setting, fd = 2)
404 --log-file= for a file name to write to
405 --log-socket= for a socket to write to
406
407 As a result of examining these and doing relevant socket/file
408 opening, a final fd is established. This is stored in
409 VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
410 specified, then STR, after expansion of %p and %q templates within
411 it, is stored in VG_(clo_log_fname_expanded), in m_options, just in
412 case anybody wants to know what it is.
413
414 When printing, VG_(log_output_sink) is consulted to find the
415 fd to send output to.
416
417 Exactly analogous actions are undertaken for the XML output
418 channel, with the one difference that the default fd is -1, meaning
419 the channel is disabled by default.
420 */
421 static
main_process_cmd_line_options(Bool * logging_to_fd,const HChar * toolname)422 void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
423 const HChar* toolname )
424 {
425 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
426 // and we cannot change it until we know what we are changing it to is
427 // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
428 Int i, tmp_log_fd, tmp_xml_fd;
429 Int toolname_len = VG_(strlen)(toolname);
430 Char* tmp_str; // Used in a couple of places.
431 enum {
432 VgLogTo_Fd,
433 VgLogTo_File,
434 VgLogTo_Socket
435 } log_to = VgLogTo_Fd, // Where is logging output to be sent?
436 xml_to = VgLogTo_Fd; // Where is XML output to be sent?
437
438 /* Temporarily holds the string STR specified with
439 --{log,xml}-{name,socket}=STR. 'fs' stands for
440 file-or-socket. */
441 Char* log_fsname_unexpanded = NULL;
442 Char* xml_fsname_unexpanded = NULL;
443
444 /* Log to stderr by default, but usage message goes to stdout. XML
445 output is initially disabled. */
446 tmp_log_fd = 2;
447 tmp_xml_fd = -1;
448
449 /* Check for sane path in ./configure --prefix=... */
450 if (VG_LIBDIR[0] != '/')
451 VG_(err_config_error)("Please use absolute paths in "
452 "./configure --prefix=... or --libdir=...\n");
453
454 vg_assert( VG_(args_for_valgrind) );
455
456 /* BEGIN command-line processing loop */
457
458 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
459
460 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
461 HChar* colon = arg;
462
463 // Look for a colon in the option name.
464 while (*colon && *colon != ':' && *colon != '=')
465 colon++;
466
467 // Does it have the form "--toolname:foo"? We have to do it at the start
468 // in case someone has combined a prefix with a core-specific option,
469 // eg. "--memcheck:verbose".
470 if (*colon == ':') {
471 if (VG_STREQN(2, arg, "--") &&
472 VG_STREQN(toolname_len, arg+2, toolname) &&
473 VG_STREQN(1, arg+2+toolname_len, ":"))
474 {
475 // Prefix matches, convert "--toolname:foo" to "--foo".
476 // Two things to note:
477 // - We cannot modify the option in-place. If we did, and then
478 // a child was spawned with --trace-children=yes, the
479 // now-non-prefixed option would be passed and could screw up
480 // the child.
481 // - We create copies, and never free them. Why? Non-prefixed
482 // options hang around forever, so tools need not make copies
483 // of strings within them. We need to have the same behaviour
484 // for prefixed options. The pointer to the copy will be lost
485 // once we leave this function (although a tool may keep a
486 // pointer into it), but the space wasted is insignificant.
487 // (In bug #142197, the copies were being freed, which caused
488 // problems for tools that reasonably assumed that arguments
489 // wouldn't disappear on them.)
490 if (0)
491 VG_(printf)("tool-specific arg: %s\n", arg);
492 arg = VG_(strdup)("main.mpclo.1", arg + toolname_len + 1);
493 arg[0] = '-';
494 arg[1] = '-';
495
496 } else {
497 // prefix doesn't match, skip to next arg
498 continue;
499 }
500 }
501
502 /* Ignore these options - they've already been handled */
503 if VG_STREQN( 7, arg, "--tool=") {}
504 else if VG_STREQN(20, arg, "--command-line-only=") {}
505 else if VG_STREQ( arg, "--") {}
506 else if VG_STREQ( arg, "-d") {}
507 else if VG_STREQN(16, arg, "--max-stackframe") {}
508 else if VG_STREQN(16, arg, "--main-stacksize") {}
509 else if VG_STREQN(14, arg, "--profile-heap") {}
510
511 // These options are new.
512 else if (VG_STREQ(arg, "-v") ||
513 VG_STREQ(arg, "--verbose"))
514 VG_(clo_verbosity)++;
515
516 else if (VG_STREQ(arg, "-q") ||
517 VG_STREQ(arg, "--quiet"))
518 VG_(clo_verbosity)--;
519
520 else if VG_BOOL_CLO(arg, "--stats", VG_(clo_stats)) {}
521 else if VG_BOOL_CLO(arg, "--xml", VG_(clo_xml))
522 VG_(debugLog_setXml)(VG_(clo_xml));
523
524 else if VG_XACT_CLO(arg, "--vgdb=no", VG_(clo_vgdb), Vg_VgdbNo) {}
525 else if VG_XACT_CLO(arg, "--vgdb=yes", VG_(clo_vgdb), Vg_VgdbYes) {}
526 else if VG_XACT_CLO(arg, "--vgdb=full", VG_(clo_vgdb), Vg_VgdbFull) {}
527 else if VG_INT_CLO (arg, "--vgdb-poll", VG_(clo_vgdb_poll)) {}
528 else if VG_INT_CLO (arg, "--vgdb-error", VG_(clo_vgdb_error)) {}
529 else if VG_STR_CLO (arg, "--vgdb-prefix", VG_(clo_vgdb_prefix)) {}
530 else if VG_BOOL_CLO(arg, "--vgdb-shadow-registers",
531 VG_(clo_vgdb_shadow_registers)) {}
532 else if VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach)) {}
533 else if VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle)) {}
534 else if VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit)) {}
535 else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
536 else if VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns)) {}
537
538 else if VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres)) {}
539 else if VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main)) {}
540 else if VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp)) {}
541 else if VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds)) {}
542 else if VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children)) {}
543 else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
544 VG_(clo_child_silent_after_fork)) {}
545 else if VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched)) {}
546 else if VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals)) {}
547 else if VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab)) {}
548 else if VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt)) {}
549 else if VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi)) {}
550 else if VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms),
551 True) {}
552 else if VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line),
553 True) {}
554 else if VG_XACT_CLO(arg, "--debug-dump=frames",
555 VG_(clo_debug_dump_frames), True) {}
556 else if VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir)) {}
557
558 else if VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls)) {}
559 else if VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb)) {}
560 else if VG_STR_CLO (arg, "--db-command", VG_(clo_db_command)) {}
561 else if VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints)) {}
562 else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
563 else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
564
565 else if VG_INT_CLO (arg, "--dump-error", VG_(clo_dump_error)) {}
566 else if VG_INT_CLO (arg, "--input-fd", VG_(clo_input_fd)) {}
567 else if VG_INT_CLO (arg, "--sanity-level", VG_(clo_sanity_level)) {}
568 else if VG_BINT_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
569 VG_DEEPEST_BACKTRACE) {}
570
571 else if VG_XACT_CLO(arg, "--smc-check=none", VG_(clo_smc_check),
572 Vg_SmcNone);
573 else if VG_XACT_CLO(arg, "--smc-check=stack", VG_(clo_smc_check),
574 Vg_SmcStack);
575 else if VG_XACT_CLO(arg, "--smc-check=all", VG_(clo_smc_check),
576 Vg_SmcAll);
577 else if VG_XACT_CLO(arg, "--smc-check=all-non-file",
578 VG_(clo_smc_check),
579 Vg_SmcAllNonFile);
580
581 else if VG_STR_CLO (arg, "--memfs-malloc-path", VG_(clo_memfs_malloc_path)) {}
582 else if VG_INT_CLO (arg, "--memfs-page-size", VG_(clo_memfs_page_size)) {}
583 else if VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant)) {}
584
585 else if VG_BOOL_CLO(arg, "--dsymutil", VG_(clo_dsymutil)) {}
586
587 else if VG_STR_CLO (arg, "--trace-children-skip",
588 VG_(clo_trace_children_skip)) {}
589 else if VG_STR_CLO (arg, "--trace-children-skip-by-arg",
590 VG_(clo_trace_children_skip_by_arg)) {}
591
592 else if VG_BINT_CLO(arg, "--vex-iropt-verbosity",
593 VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
594 else if VG_BINT_CLO(arg, "--vex-iropt-level",
595 VG_(clo_vex_control).iropt_level, 0, 2) {}
596 else if VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
597 VG_(clo_vex_control).iropt_precise_memory_exns) {}
598 else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
599 VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
600 else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
601 VG_(clo_vex_control).guest_max_insns, 1, 100) {}
602 else if VG_BINT_CLO(arg, "--vex-guest-chase-thresh",
603 VG_(clo_vex_control).guest_chase_thresh, 0, 99) {}
604 else if VG_BOOL_CLO(arg, "--vex-guest-chase-cond",
605 VG_(clo_vex_control).guest_chase_cond) {}
606
607 else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
608 log_to = VgLogTo_Fd;
609 log_fsname_unexpanded = NULL;
610 }
611 else if VG_INT_CLO(arg, "--xml-fd", tmp_xml_fd) {
612 xml_to = VgLogTo_Fd;
613 xml_fsname_unexpanded = NULL;
614 }
615
616 else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
617 log_to = VgLogTo_File;
618 VG_(clo_log_fname_unexpanded) =
619 VG_(strdup)("", log_fsname_unexpanded);
620 }
621 else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) {
622 xml_to = VgLogTo_File;
623 VG_(clo_xml_fname_unexpanded) =
624 VG_(strdup)("", xml_fsname_unexpanded);
625 }
626
627 else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) {
628 log_to = VgLogTo_Socket;
629 }
630 else if VG_STR_CLO(arg, "--xml-socket", xml_fsname_unexpanded) {
631 xml_to = VgLogTo_Socket;
632 }
633
634 else if VG_STR_CLO(arg, "--xml-user-comment",
635 VG_(clo_xml_user_comment)) {}
636
637 else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
638 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
639 VG_(fmsg_bad_option)(arg,
640 "Too many suppression files specified.\n"
641 "Increase VG_CLO_MAX_SFILES and recompile.\n");
642 }
643 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = tmp_str;
644 VG_(clo_n_suppressions)++;
645 }
646
647 else if VG_STR_CLO (arg, "--fullpath-after", tmp_str) {
648 if (VG_(clo_n_fullpath_after) >= VG_CLO_MAX_FULLPATH_AFTER) {
649 VG_(fmsg_bad_option)(arg,
650 "Too many --fullpath-after= specifications.\n"
651 "Increase VG_CLO_MAX_FULLPATH_AFTER and recompile.\n");
652 }
653 VG_(clo_fullpath_after)[VG_(clo_n_fullpath_after)] = tmp_str;
654 VG_(clo_n_fullpath_after)++;
655 }
656
657 else if VG_STR_CLO(arg, "--require-text-symbol", tmp_str) {
658 if (VG_(clo_n_req_tsyms) >= VG_CLO_MAX_REQ_TSYMS) {
659 VG_(fmsg_bad_option)(arg,
660 "Too many --require-text-symbol= specifications.\n"
661 "Increase VG_CLO_MAX_REQ_TSYMS and recompile.\n");
662 }
663 /* String needs to be of the form C?*C?*, where C is any
664 character, but is the same both times. Having it in this
665 form facilitates finding the boundary between the sopatt
666 and the fnpatt just by looking for the second occurrence
667 of C, without hardwiring any assumption about what C
668 is. */
669 Char patt[7];
670 Bool ok = True;
671 ok = tmp_str && VG_(strlen)(tmp_str) > 0;
672 if (ok) {
673 patt[0] = patt[3] = tmp_str[0];
674 patt[1] = patt[4] = '?';
675 patt[2] = patt[5] = '*';
676 patt[6] = 0;
677 ok = VG_(string_match)(patt, tmp_str);
678 }
679 if (!ok) {
680 VG_(fmsg_bad_option)(arg,
681 "Invalid --require-text-symbol= specification.\n");
682 }
683 VG_(clo_req_tsyms)[VG_(clo_n_req_tsyms)] = tmp_str;
684 VG_(clo_n_req_tsyms)++;
685 }
686
687 /* "stuvwxyz" --> stuvwxyz (binary) */
688 else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
689 Int j;
690
691 if (8 != VG_(strlen)(tmp_str)) {
692 VG_(fmsg_bad_option)(arg,
693 "--trace-flags argument must have 8 digits\n");
694 }
695 for (j = 0; j < 8; j++) {
696 if ('0' == tmp_str[j]) { /* do nothing */ }
697 else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
698 else {
699 VG_(fmsg_bad_option)(arg,
700 "--trace-flags argument can only contain 0s and 1s\n");
701 }
702 }
703 }
704
705 /* "stuvwxyz" --> stuvwxyz (binary) */
706 else if VG_STR_CLO(arg, "--profile-flags", tmp_str) {
707 Int j;
708
709 if (8 != VG_(strlen)(tmp_str)) {
710 VG_(fmsg_bad_option)(arg,
711 "--profile-flags argument must have 8 digits\n");
712 }
713 for (j = 0; j < 8; j++) {
714 if ('0' == tmp_str[j]) { /* do nothing */ }
715 else if ('1' == tmp_str[j]) VG_(clo_profile_flags) |= (1 << (7-j));
716 else {
717 VG_(fmsg_bad_option)(arg,
718 "--profile-flags argument can only contain 0s and 1s\n");
719 }
720 }
721 }
722
723 else if VG_INT_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow)) {}
724
725 else if VG_XACT_CLO(arg, "--gen-suppressions=no",
726 VG_(clo_gen_suppressions), 0) {}
727 else if VG_XACT_CLO(arg, "--gen-suppressions=yes",
728 VG_(clo_gen_suppressions), 1) {}
729 else if VG_XACT_CLO(arg, "--gen-suppressions=all",
730 VG_(clo_gen_suppressions), 2) {}
731
732 else if VG_STR_CLO(arg, "--nacl-file", VG_(clo_nacl_file)) {}
733
734 else if ( ! VG_(needs).command_line_options
735 || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
736 VG_(fmsg_bad_option)(arg, "");
737 }
738 }
739
740 /* END command-line processing loop */
741
742 /* Determine the path prefix for vgdb */
743 if (VG_(clo_vgdb_prefix) == NULL)
744 VG_(clo_vgdb_prefix) = VG_(vgdb_prefix_default)();
745
746 /* Make VEX control parameters sane */
747
748 if (VG_(clo_vex_control).guest_chase_thresh
749 >= VG_(clo_vex_control).guest_max_insns)
750 VG_(clo_vex_control).guest_chase_thresh
751 = VG_(clo_vex_control).guest_max_insns - 1;
752
753 if (VG_(clo_vex_control).guest_chase_thresh < 0)
754 VG_(clo_vex_control).guest_chase_thresh = 0;
755
756 /* Check various option values */
757
758 if (VG_(clo_verbosity) < 0)
759 VG_(clo_verbosity) = 0;
760
761 VG_(dyn_vgdb_error) = VG_(clo_vgdb_error);
762
763 /* If XML output is requested, check that the tool actually
764 supports it. */
765 if (VG_(clo_xml) && !VG_(needs).xml_output) {
766 VG_(clo_xml) = False;
767 VG_(message)(Vg_UserMsg,
768 "%s does not support XML output.\n", VG_(details).name);
769 VG_(fmsg_bad_option)("--xml=yes", "\n");
770 /*NOTREACHED*/
771 }
772
773 vg_assert( VG_(clo_gen_suppressions) >= 0 );
774 vg_assert( VG_(clo_gen_suppressions) <= 2 );
775
776 /* If we've been asked to emit XML, mash around various other
777 options so as to constrain the output somewhat, and to remove
778 any need for user input during the run.
779 */
780 if (VG_(clo_xml)) {
781
782 /* We can't allow --gen-suppressions=yes, since that requires us
783 to print the error and then ask the user if she wants a
784 suppression for it, but in XML mode we won't print it until
785 we know whether we also need to print a suppression. Hence a
786 circular dependency. So disallow this.
787 (--gen-suppressions=all is still OK since we don't need any
788 user interaction in this case.) */
789 if (VG_(clo_gen_suppressions) == 1) {
790 VG_(fmsg_bad_option)(
791 "--xml=yes together with --gen-suppressions=yes",
792 "When --xml=yes is specified, --gen-suppressions=no\n"
793 "or --gen-suppressions=all is allowed, but not "
794 "--gen-suppressions=yes.\n");
795 }
796
797 /* We can't allow DB attaching (or we maybe could, but results
798 could be chaotic ..) since it requires user input. Hence
799 disallow. */
800 if (VG_(clo_db_attach)) {
801 VG_(fmsg_bad_option)(
802 "--xml=yes together with --db-attach=yes",
803 "--db-attach=yes is not allowed with --xml=yes\n"
804 "because it would require user input.\n");
805 }
806
807 /* Disallow dump_error in XML mode; sounds like a recipe for
808 chaos. No big deal; dump_error is a flag for debugging V
809 itself. */
810 if (VG_(clo_dump_error) > 0) {
811 VG_(fmsg_bad_option)("--xml=yes together with --dump-error", "");
812 }
813
814 /* Disable error limits (this might be a bad idea!) */
815 VG_(clo_error_limit) = False;
816 /* Disable emulation warnings */
817
818 /* Also, we want to set options for the leak checker, but that
819 will have to be done in Memcheck's flag-handling code, not
820 here. */
821 }
822
823 /* All non-logging-related options have been checked. If the logging
824 option specified is ok, we can switch to it, as we know we won't
825 have to generate any other command-line-related error messages.
826 (So far we should be still attached to stderr, so we can show on
827 the terminal any problems to do with processing command line
828 opts.)
829
830 So set up logging now. After this is done, VG_(log_output_sink)
831 and (if relevant) VG_(xml_output_sink) should be connected to
832 whatever sink has been selected, and we indiscriminately chuck
833 stuff into it without worrying what the nature of it is. Oh the
834 wonder of Unix streams. */
835
836 vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
837 vg_assert(VG_(log_output_sink).is_socket == False);
838 vg_assert(VG_(clo_log_fname_expanded) == NULL);
839
840 vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
841 vg_assert(VG_(xml_output_sink).is_socket == False);
842 vg_assert(VG_(clo_xml_fname_expanded) == NULL);
843
844 /* --- set up the normal text output channel --- */
845
846 switch (log_to) {
847
848 case VgLogTo_Fd:
849 vg_assert(log_fsname_unexpanded == NULL);
850 break;
851
852 case VgLogTo_File: {
853 tmp_log_fd = reopen_output_fd(False);
854 break;
855 }
856
857 case VgLogTo_Socket: {
858 vg_assert(log_fsname_unexpanded != NULL);
859 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
860 tmp_log_fd = VG_(connect_via_socket)( log_fsname_unexpanded );
861 if (tmp_log_fd == -1) {
862 VG_(fmsg)("Invalid --log-socket spec of '%s'\n",
863 log_fsname_unexpanded);
864 VG_(exit)(1);
865 /*NOTREACHED*/
866 }
867 if (tmp_log_fd == -2) {
868 VG_(umsg)("failed to connect to logging server '%s'.\n"
869 "Log messages will sent to stderr instead.\n",
870 log_fsname_unexpanded );
871
872 /* We don't change anything here. */
873 vg_assert(VG_(log_output_sink).fd == 2);
874 tmp_log_fd = 2;
875 } else {
876 vg_assert(tmp_log_fd > 0);
877 VG_(log_output_sink).is_socket = True;
878 }
879 break;
880 }
881 }
882
883 /* --- set up the XML output channel --- */
884
885 switch (xml_to) {
886
887 case VgLogTo_Fd:
888 vg_assert(xml_fsname_unexpanded == NULL);
889 break;
890
891 case VgLogTo_File: {
892 tmp_xml_fd = reopen_output_fd(True);
893 break;
894 }
895
896 case VgLogTo_Socket: {
897 vg_assert(xml_fsname_unexpanded != NULL);
898 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
899 tmp_xml_fd = VG_(connect_via_socket)( xml_fsname_unexpanded );
900 if (tmp_xml_fd == -1) {
901 VG_(fmsg)("Invalid --xml-socket spec of '%s'\n",
902 xml_fsname_unexpanded );
903 VG_(exit)(1);
904 /*NOTREACHED*/
905 }
906 if (tmp_xml_fd == -2) {
907 VG_(umsg)("failed to connect to XML logging server '%s'.\n"
908 "XML output will sent to stderr instead.\n",
909 xml_fsname_unexpanded);
910 /* We don't change anything here. */
911 vg_assert(VG_(xml_output_sink).fd == 2);
912 tmp_xml_fd = 2;
913 } else {
914 vg_assert(tmp_xml_fd > 0);
915 VG_(xml_output_sink).is_socket = True;
916 }
917 break;
918 }
919 }
920
921 /* If we've got this far, and XML mode was requested, but no XML
922 output channel appears to have been specified, just stop. We
923 could continue, and XML output will simply vanish into nowhere,
924 but that is likely to confuse the hell out of users, which is
925 distinctly Ungood. */
926 if (VG_(clo_xml) && tmp_xml_fd == -1) {
927 VG_(fmsg_bad_option)(
928 "--xml=yes, but no XML destination specified",
929 "--xml=yes has been specified, but there is no XML output\n"
930 "destination. You must specify an XML output destination\n"
931 "using --xml-fd, --xml-file or --xml-socket.\n"
932 );
933 }
934
935 // Finalise the output fds: the log fd ..
936
937 if (tmp_log_fd >= 0) {
938 tmp_log_fd = move_fd_into_safe_range(tmp_log_fd, False);
939 } else {
940 // If they said --log-fd=-1, don't print anything. Plausible for use in
941 // regression testing suites that use client requests to count errors.
942 VG_(log_output_sink).fd = -1;
943 VG_(log_output_sink).is_socket = False;
944 }
945
946 // Finalise the output fds: and the XML fd ..
947
948 if (tmp_xml_fd >= 0) {
949 tmp_xml_fd = move_fd_into_safe_range(tmp_xml_fd, True);
950 } else {
951 // If they said --xml-fd=-1, don't print anything. Plausible for use in
952 // regression testing suites that use client requests to count errors.
953 VG_(xml_output_sink).fd = -1;
954 VG_(xml_output_sink).is_socket = False;
955 }
956
957 // Suppressions related stuff
958
959 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
960 (VG_(needs).core_errors || VG_(needs).tool_errors)) {
961 /* If we haven't reached the max number of suppressions, load
962 the default one. */
963 static const Char default_supp[] = "default.supp";
964 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
965 Char *buf = VG_(arena_malloc)(VG_AR_CORE, "main.mpclo.3", len);
966 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
967 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
968 VG_(clo_n_suppressions)++;
969 }
970
971 *logging_to_fd = log_to == VgLogTo_Fd || log_to == VgLogTo_Socket;
972 }
973
974 // Write the name and value of log file qualifiers to the xml file.
print_file_vars(Char * format)975 static void print_file_vars(Char* format)
976 {
977 Int i = 0;
978
979 while (format[i]) {
980 if (format[i] == '%') {
981 // We saw a '%'. What's next...
982 i++;
983 if ('q' == format[i]) {
984 i++;
985 if ('{' == format[i]) {
986 // Get the env var name, print its contents.
987 Char* qualname;
988 Char* qual;
989 i++;
990 qualname = &format[i];
991 while (True) {
992 if ('}' == format[i]) {
993 // Temporarily replace the '}' with NUL to extract var
994 // name.
995 format[i] = 0;
996 qual = VG_(getenv)(qualname);
997 break;
998 }
999 i++;
1000 }
1001
1002 VG_(printf_xml)(
1003 "<logfilequalifier> <var>%pS</var> "
1004 "<value>%pS</value> </logfilequalifier>\n",
1005 qualname,qual
1006 );
1007 format[i] = '}';
1008 i++;
1009 }
1010 }
1011 } else {
1012 i++;
1013 }
1014 }
1015 }
1016
1017
1018 /*====================================================================*/
1019 /*=== Printing the preamble ===*/
1020 /*====================================================================*/
1021
1022 // Print the command, escaping any chars that require it.
umsg_arg(const Char * arg)1023 static void umsg_arg(const Char* arg)
1024 {
1025 SizeT len = VG_(strlen)(arg);
1026 Char* special = " \\<>";
1027 Int i;
1028 for (i = 0; i < len; i++) {
1029 if (VG_(strchr)(special, arg[i])) {
1030 VG_(umsg)("\\"); // escape with a backslash if necessary
1031 }
1032 VG_(umsg)("%c", arg[i]);
1033 }
1034 }
1035
1036 // Send output to the XML-stream and escape any XML meta-characters.
xml_arg(const Char * arg)1037 static void xml_arg(const Char* arg) {
1038 VG_(printf_xml)("%t", arg);
1039 }
1040
1041 /* Ok, the logging sink is running now. Print a suitable preamble.
1042 If logging to file or a socket, write details of parent PID and
1043 command line args, to help people trying to interpret the
1044 results of a run which encompasses multiple processes. */
1045 // TODO(timurrrr): we add a non-static declaration of this function since
1046 // we need it in coregrind/m_libcproc.c
1047 // NOTE: Keep this definition in sync with coregrind/m_libcproc.c
1048 // in case of merge conflict.
1049 // Should we move it to some header file?
1050 void print_preamble ( Bool logging_to_fd, const HChar* toolname );
1051
print_preamble(Bool logging_to_fd,const HChar * toolname)1052 void print_preamble ( Bool logging_to_fd, const HChar* toolname )
1053 {
1054 Int i;
1055 HChar* xpre = VG_(clo_xml) ? " <line>" : "";
1056 HChar* xpost = VG_(clo_xml) ? "</line>" : "";
1057 UInt (*umsg_or_xml)( const HChar*, ... )
1058 = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
1059
1060 void (*umsg_or_xml_arg)( const Char* )
1061 = VG_(clo_xml) ? xml_arg : umsg_arg;
1062
1063 static const char* last_toolname = NULL;
1064 vg_assert( VG_(args_for_client) );
1065 vg_assert( VG_(args_for_valgrind) );
1066
1067 // This way you may pass toolname == NULL provided the first invocation
1068 // with toolname != NULL takes place in valgrind_main().
1069 toolname = (toolname == NULL ? last_toolname : toolname);
1070 vg_assert( toolname );
1071 last_toolname = toolname;
1072
1073 if (VG_(clo_xml)) {
1074 VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
1075 VG_(printf_xml)("\n");
1076 VG_(printf_xml)("<valgrindoutput>\n");
1077 VG_(printf_xml)("\n");
1078 VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
1079 VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", toolname);
1080 VG_(printf_xml)("\n");
1081 }
1082
1083 if (VG_(clo_xml) || VG_(clo_verbosity) > 0) {
1084
1085 if (VG_(clo_xml))
1086 VG_(printf_xml)("<preamble>\n");
1087
1088 /* Tool details */
1089 umsg_or_xml( VG_(clo_xml) ? "%s%pS%pS%pS, %pS%s\n" : "%s%s%s%s, %s%s\n",
1090 xpre,
1091 VG_(details).name,
1092 NULL == VG_(details).version ? "" : "-",
1093 NULL == VG_(details).version
1094 ? (Char*)"" : VG_(details).version,
1095 VG_(details).description,
1096 xpost );
1097
1098 if (VG_(strlen)(toolname) >= 4 && VG_STREQN(4, toolname, "exp-")) {
1099 umsg_or_xml(
1100 "%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
1101 xpre, xpost
1102 );
1103 }
1104
1105 umsg_or_xml( VG_(clo_xml) ? "%s%pS%s\n" : "%s%s%s\n",
1106 xpre, VG_(details).copyright_author, xpost );
1107
1108 /* Core details */
1109 umsg_or_xml(
1110 "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
1111 xpre, VERSION, xpost
1112 );
1113
1114 // Print the command line. At one point we wrapped at 80 chars and
1115 // printed a '\' as a line joiner, but that makes it hard to cut and
1116 // paste the command line (because of the "==pid==" prefixes), so we now
1117 // favour utility and simplicity over aesthetics.
1118 umsg_or_xml("%sCommand: ", xpre);
1119 if (VG_(args_the_exename))
1120 umsg_or_xml_arg(VG_(args_the_exename));
1121
1122 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1123 HChar* s = *(HChar**)VG_(indexXA)( VG_(args_for_client), i );
1124 umsg_or_xml(" ");
1125 umsg_or_xml_arg(s);
1126 }
1127 umsg_or_xml("%s\n", xpost);
1128
1129 if (VG_(clo_xml))
1130 VG_(printf_xml)("</preamble>\n");
1131 }
1132
1133 // Print the parent PID, and other stuff, if necessary.
1134 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
1135 VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
1136 }
1137 else
1138 if (VG_(clo_xml)) {
1139 Char *xml_fname_unexpanded = VG_(clo_xml_fname_unexpanded);
1140 VG_(printf_xml)("\n");
1141 VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
1142 VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
1143 VG_(printf_xml)("<tool>%pS</tool>\n", toolname);
1144 if (xml_fname_unexpanded)
1145 print_file_vars(xml_fname_unexpanded);
1146 if (VG_(clo_xml_user_comment)) {
1147 /* Note: the user comment itself is XML and is therefore to
1148 be passed through verbatim (%s) rather than escaped
1149 (%pS). */
1150 VG_(printf_xml)("<usercomment>%s</usercomment>\n",
1151 VG_(clo_xml_user_comment));
1152 }
1153 VG_(printf_xml)("\n");
1154 VG_(printf_xml)("<args>\n");
1155
1156 VG_(printf_xml)(" <vargv>\n");
1157 if (VG_(name_of_launcher))
1158 VG_(printf_xml)(" <exe>%pS</exe>\n",
1159 VG_(name_of_launcher));
1160 else
1161 VG_(printf_xml)(" <exe>%pS</exe>\n",
1162 "(launcher name unknown)");
1163 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
1164 VG_(printf_xml)(
1165 " <arg>%pS</arg>\n",
1166 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1167 );
1168 }
1169 VG_(printf_xml)(" </vargv>\n");
1170
1171 VG_(printf_xml)(" <argv>\n");
1172 if (VG_(args_the_exename))
1173 VG_(printf_xml)(" <exe>%pS</exe>\n",
1174 VG_(args_the_exename));
1175 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1176 VG_(printf_xml)(
1177 " <arg>%pS</arg>\n",
1178 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1179 );
1180 }
1181 VG_(printf_xml)(" </argv>\n");
1182
1183 VG_(printf_xml)("</args>\n");
1184 }
1185
1186 // Last thing in the preamble is a blank line.
1187 if (VG_(clo_xml))
1188 VG_(printf_xml)("\n");
1189 else if (VG_(clo_verbosity) > 0)
1190 VG_(umsg)("\n");
1191
1192 if (VG_(clo_verbosity) > 1) {
1193 SysRes fd;
1194 VexArch vex_arch;
1195 VexArchInfo vex_archinfo;
1196 if (!logging_to_fd)
1197 VG_(message)(Vg_DebugMsg, "\n");
1198 VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
1199 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
1200 VG_(message)(Vg_DebugMsg,
1201 " %s\n",
1202 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
1203 }
1204
1205 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
1206 fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
1207 if (sr_isError(fd)) {
1208 VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
1209 } else {
1210 # define BUF_LEN 256
1211 Char version_buf[BUF_LEN];
1212 Int n = VG_(read) ( sr_Res(fd), version_buf, BUF_LEN );
1213 vg_assert(n <= BUF_LEN);
1214 if (n > 0) {
1215 version_buf[n-1] = '\0';
1216 VG_(message)(Vg_DebugMsg, " %s\n", version_buf);
1217 } else {
1218 VG_(message)(Vg_DebugMsg, " (empty?)\n");
1219 }
1220 VG_(close)(sr_Res(fd));
1221 # undef BUF_LEN
1222 }
1223
1224 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
1225 VG_(message)(
1226 Vg_DebugMsg,
1227 "Arch and hwcaps: %s, %s\n",
1228 LibVEX_ppVexArch ( vex_arch ),
1229 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1230 );
1231 VG_(message)(
1232 Vg_DebugMsg,
1233 "Page sizes: currently %d, max supported %d\n",
1234 (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
1235 );
1236 VG_(message)(Vg_DebugMsg,
1237 "Valgrind library directory: %s\n", VG_(libdir));
1238 }
1239 }
1240
1241
1242 /*====================================================================*/
1243 /*=== File descriptor setup ===*/
1244 /*====================================================================*/
1245
1246 /* Number of file descriptors that Valgrind tries to reserve for
1247 it's own use - just a small constant. */
1248 #define N_RESERVED_FDS (10)
1249
setup_file_descriptors(void)1250 static void setup_file_descriptors(void)
1251 {
1252 struct vki_rlimit rl;
1253 Bool show = False;
1254
1255 /* Get the current file descriptor limits. */
1256 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
1257 rl.rlim_cur = 1024;
1258 rl.rlim_max = 1024;
1259 }
1260
1261 # if defined(VGO_darwin)
1262 /* Darwin lies. It reports file max as RLIM_INFINITY but
1263 silently disallows anything bigger than 10240. */
1264 if (rl.rlim_cur >= 10240 && rl.rlim_max == 0x7fffffffffffffffULL) {
1265 rl.rlim_max = 10240;
1266 }
1267 # endif
1268
1269 if (show)
1270 VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
1271 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
1272
1273 /* kcc: workaround for a Linux Kernel bug */
1274 if (rl.rlim_cur > 1000000)
1275 rl.rlim_cur = 1000000;
1276
1277 /* Work out where to move the soft limit to. */
1278 if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
1279 rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
1280 } else {
1281 rl.rlim_cur = rl.rlim_max;
1282 }
1283
1284 /* Reserve some file descriptors for our use. */
1285 VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
1286 VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
1287
1288 /* Update the soft limit. */
1289 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
1290
1291 if (show) {
1292 VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
1293 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
1294 VG_(printf)("fd limits: guest : cur %u max %u\n",
1295 VG_(fd_soft_limit), VG_(fd_hard_limit));
1296 }
1297
1298 if (VG_(cl_exec_fd) != -1)
1299 VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
1300 }
1301
1302
1303 /*====================================================================*/
1304 /*=== BB profiling ===*/
1305 /*====================================================================*/
1306
1307 static
show_BB_profile(BBProfEntry tops[],UInt n_tops,ULong score_total)1308 void show_BB_profile ( BBProfEntry tops[], UInt n_tops, ULong score_total )
1309 {
1310 ULong score_cumul, score_here;
1311 Char buf_cumul[10], buf_here[10];
1312 Char name[64];
1313 Int r;
1314
1315 VG_(printf)("\n");
1316 VG_(printf)("-----------------------------------------------------------\n");
1317 VG_(printf)("--- BEGIN BB Profile (summary of scores) ---\n");
1318 VG_(printf)("-----------------------------------------------------------\n");
1319 VG_(printf)("\n");
1320
1321 VG_(printf)("Total score = %lld\n\n", score_total);
1322
1323 score_cumul = 0;
1324 for (r = 0; r < n_tops; r++) {
1325 if (tops[r].addr == 0)
1326 continue;
1327 name[0] = 0;
1328 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1329 name[63] = 0;
1330 score_here = tops[r].score;
1331 score_cumul += score_here;
1332 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1333 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1334 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1335 r,
1336 score_cumul, buf_cumul,
1337 score_here, buf_here, tops[r].addr, name );
1338 }
1339
1340 VG_(printf)("\n");
1341 VG_(printf)("-----------------------------------------------------------\n");
1342 VG_(printf)("--- BB Profile (BB details) ---\n");
1343 VG_(printf)("-----------------------------------------------------------\n");
1344 VG_(printf)("\n");
1345
1346 score_cumul = 0;
1347 for (r = 0; r < n_tops; r++) {
1348 if (tops[r].addr == 0)
1349 continue;
1350 name[0] = 0;
1351 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1352 name[63] = 0;
1353 score_here = tops[r].score;
1354 score_cumul += score_here;
1355 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1356 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1357 VG_(printf)("\n");
1358 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin BB rank %d "
1359 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1360 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1361 r,
1362 score_cumul, buf_cumul,
1363 score_here, buf_here, tops[r].addr, name );
1364 VG_(printf)("\n");
1365 VG_(discard_translations)(tops[r].addr, 1, "bb profile");
1366 VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0, True);
1367 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= end BB rank %d "
1368 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1369 }
1370
1371 VG_(printf)("\n");
1372 VG_(printf)("-----------------------------------------------------------\n");
1373 VG_(printf)("--- END BB Profile ---\n");
1374 VG_(printf)("-----------------------------------------------------------\n");
1375 VG_(printf)("\n");
1376 }
1377
1378
1379 /*====================================================================*/
1380 /*=== main() ===*/
1381 /*====================================================================*/
1382
1383 /* When main() is entered, we should be on the following stack, not
1384 the one the kernel gave us. We will run on this stack until
1385 simulation of the root thread is started, at which point a transfer
1386 is made to a dynamically allocated stack. This is for the sake of
1387 uniform overflow detection for all Valgrind threads. This is
1388 marked global even though it isn't, because assembly code below
1389 needs to reference the name. */
1390
1391 /*static*/ VgStack VG_(interim_stack);
1392
1393 /* These are the structures used to hold info for creating the initial
1394 client image.
1395
1396 'iicii' mostly holds important register state present at system
1397 startup (_start_valgrind). valgrind_main() then fills in the rest
1398 of it and passes it to VG_(ii_create_image)(). That produces
1399 'iifii', which is later handed to VG_(ii_finalise_image). */
1400
1401 /* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1402 This should get some address inside the stack on which we gained
1403 control (eg, it could be the SP at startup). It doesn't matter
1404 exactly where in the stack it is. This value is passed to the
1405 address space manager at startup. On Linux, aspacem then uses it
1406 to identify the initial stack segment and hence the upper end of
1407 the usable address space. */
1408
1409 static IICreateImageInfo the_iicii;
1410 static IIFinaliseImageInfo the_iifii;
1411
1412
1413 /* A simple pair structure, used for conveying debuginfo handles to
1414 calls to VG_TRACK(new_mem_startup, ...). */
1415 typedef struct { Addr a; ULong ull; } Addr_n_ULong;
1416
1417
1418 /* --- Forwards decls to do with shutdown --- */
1419
1420 static void final_tidyup(ThreadId tid);
1421
1422 /* Do everything which needs doing when the last thread exits */
1423 static
1424 void shutdown_actions_NORETURN( ThreadId tid,
1425 VgSchedReturnCode tids_schedretcode );
1426
1427 /* --- end of Forwards decls to do with shutdown --- */
1428
1429
1430 /* By the time we get to valgrind_main, the_iicii should already have
1431 been filled in with any important details as required by whatever
1432 OS we have been built for.
1433 */
1434 static
valgrind_main(Int argc,HChar ** argv,HChar ** envp)1435 Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
1436 {
1437 HChar* toolname = "memcheck"; // default to Memcheck
1438 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
1439 ThreadId tid_main = VG_INVALID_THREADID;
1440 Bool logging_to_fd = False;
1441 Int loglevel, i;
1442 struct vki_rlimit zero = { 0, 0 };
1443 XArray* addr2dihandle = NULL;
1444
1445 //============================================================
1446 //
1447 // Nb: startup is complex. Prerequisites are shown at every step.
1448 // *** Be very careful when messing with the order ***
1449 //
1450 // The first order of business is to get debug logging, the address
1451 // space manager and the dynamic memory manager up and running.
1452 // Once that's done, we can relax a bit.
1453 //
1454 //============================================================
1455
1456 /* This is needed to make VG_(getenv) usable early. */
1457 VG_(client_envp) = (Char**)envp;
1458
1459 //--------------------------------------------------------------
1460 // Start up Mach kernel interface, if any
1461 // p: none
1462 //--------------------------------------------------------------
1463 # if defined(VGO_darwin)
1464 VG_(mach_init)();
1465 # endif
1466
1467 //--------------------------------------------------------------
1468 // Start up the logging mechanism
1469 // p: none
1470 //--------------------------------------------------------------
1471 /* Start the debugging-log system ASAP. First find out how many
1472 "-d"s were specified. This is a pre-scan of the command line. Also
1473 get --profile-heap=yes which is needed by the time we start up dynamic
1474 memory management. */
1475 loglevel = 0;
1476 for (i = 1; i < argc; i++) {
1477 if (argv[i][0] != '-') break;
1478 if VG_STREQ(argv[i], "--") break;
1479 if VG_STREQ(argv[i], "-d") loglevel++;
1480 if VG_BOOL_CLO(argv[i], "--profile-heap", VG_(clo_profile_heap)) {}
1481 }
1482
1483 /* ... and start the debug logger. Now we can safely emit logging
1484 messages all through startup. */
1485 VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
1486 VG_(debugLog)(1, "main", "Welcome to Valgrind version "
1487 VERSION " debug logging\n");
1488
1489 //--------------------------------------------------------------
1490 // Ensure we're on a plausible stack.
1491 // p: logging
1492 //--------------------------------------------------------------
1493 VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
1494 { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
1495 HChar* limHi = limLo + sizeof(VG_(interim_stack));
1496 HChar* aLocal = (HChar*)&zero; /* any auto local will do */
1497 if (aLocal < limLo || aLocal >= limHi) {
1498 /* something's wrong. Stop. */
1499 VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
1500 limLo, limHi, aLocal );
1501 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1502 "Initial stack switched failed.\n");
1503 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1504 VG_(exit)(1);
1505 }
1506 }
1507
1508 //--------------------------------------------------------------
1509 // Ensure we have a plausible pointer to the stack on which
1510 // we gained control (not the current stack!)
1511 // p: logging
1512 //--------------------------------------------------------------
1513 VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
1514 if (the_iicii.sp_at_startup == 0) {
1515 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1516 "Initial stack was not noted.\n");
1517 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1518 VG_(exit)(1);
1519 }
1520
1521 //--------------------------------------------------------------
1522 // Start up the address space manager, and determine the
1523 // approximate location of the client's stack
1524 // p: logging, plausible-stack
1525 //--------------------------------------------------------------
1526 VG_(debugLog)(1, "main", "Starting the address space manager\n");
1527 vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536);
1528 vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536);
1529 vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
1530 vg_assert(VKI_PAGE_SIZE == (1 << VKI_PAGE_SHIFT));
1531 vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
1532 the_iicii.clstack_top = VG_(am_startup)( the_iicii.sp_at_startup );
1533 VG_(debugLog)(1, "main", "Address space manager is running\n");
1534
1535 //--------------------------------------------------------------
1536 // Start up the dynamic memory manager
1537 // p: address space management
1538 // p: getting --profile-heap
1539 // In fact m_mallocfree is self-initialising, so there's no
1540 // initialisation call to do. Instead, try a simple malloc/
1541 // free pair right now to check that nothing is broken.
1542 //--------------------------------------------------------------
1543 VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
1544 { void* p = VG_(malloc)( "main.vm.1", 12345 );
1545 if (p) VG_(free)( p );
1546 }
1547 VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
1548
1549 //============================================================
1550 //
1551 // Dynamic memory management is now available.
1552 //
1553 //============================================================
1554
1555 //--------------------------------------------------------------
1556 // Initialise m_debuginfo
1557 // p: dynamic memory allocation
1558 VG_(debugLog)(1, "main", "Initialise m_debuginfo\n");
1559 VG_(di_initialise)();
1560
1561 //--------------------------------------------------------------
1562 // Look for alternative libdir
1563 { HChar *cp = VG_(getenv)(VALGRIND_LIB);
1564 if (cp != NULL)
1565 VG_(libdir) = cp;
1566 VG_(debugLog)(1, "main", "VG_(libdir) = %s\n", VG_(libdir));
1567 }
1568
1569 //--------------------------------------------------------------
1570 // Extract the launcher name from the environment.
1571 VG_(debugLog)(1, "main", "Getting launcher's name ...\n");
1572 VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
1573 if (VG_(name_of_launcher) == NULL) {
1574 VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
1575 VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
1576 VG_(exit)(1);
1577 }
1578 VG_(debugLog)(1, "main", "... %s\n", VG_(name_of_launcher));
1579
1580 //--------------------------------------------------------------
1581 // Get the current process datasize rlimit, and set it to zero.
1582 // This prevents any internal uses of brk() from having any effect.
1583 // We remember the old value so we can restore it on exec, so that
1584 // child processes will have a reasonable brk value.
1585 VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1586 zero.rlim_max = VG_(client_rlimit_data).rlim_max;
1587 VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
1588
1589 // Get the current process stack rlimit.
1590 VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
1591
1592 //--------------------------------------------------------------
1593 // Figure out what sort of CPU we're on, and whether it is
1594 // able to run V.
1595 VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
1596 { VexArch vex_arch;
1597 VexArchInfo vex_archinfo;
1598 Bool ok = VG_(machine_get_hwcaps)();
1599 if (!ok) {
1600 VG_(printf)("\n");
1601 VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
1602 VG_(printf)(" Supported CPUs are:\n");
1603 VG_(printf)(" * x86 (practically any; Pentium-I or above), "
1604 "AMD Athlon or above)\n");
1605 VG_(printf)(" * AMD Athlon64/Opteron\n");
1606 VG_(printf)(" * PowerPC (most; ppc405 and above)\n");
1607 VG_(printf)(" * System z (64bit only - s390x; z900 and above)\n");
1608 VG_(printf)("\n");
1609 VG_(exit)(1);
1610 }
1611 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
1612 VG_(debugLog)(
1613 1, "main", "... arch = %s, hwcaps = %s\n",
1614 LibVEX_ppVexArch ( vex_arch ),
1615 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1616 );
1617 }
1618
1619 //--------------------------------------------------------------
1620 // Record the working directory at startup
1621 // p: none
1622 VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
1623 { Bool ok = VG_(record_startup_wd)();
1624 if (!ok)
1625 VG_(err_config_error)( "Can't establish current working "
1626 "directory at startup\n");
1627 }
1628 { Char buf[VKI_PATH_MAX+1];
1629 Bool ok = VG_(get_startup_wd)( buf, sizeof(buf) );
1630 vg_assert(ok);
1631 buf[VKI_PATH_MAX] = 0;
1632 VG_(debugLog)(1, "main", "... %s\n", buf );
1633 }
1634
1635 //============================================================
1636 // Command line argument handling order:
1637 // * If --help/--help-debug are present, show usage message
1638 // (including the tool-specific usage)
1639 // * (If no --tool option given, default to Memcheck)
1640 // * Then, if client is missing, abort with error msg
1641 // * Then, if any cmdline args are bad, abort with error msg
1642 //============================================================
1643
1644 //--------------------------------------------------------------
1645 // Split up argv into: C args, V args, V extra args, and exename.
1646 // p: dynamic memory allocation
1647 //--------------------------------------------------------------
1648 VG_(debugLog)(1, "main", "Split up command line\n");
1649 VG_(split_up_argv)( argc, argv );
1650 vg_assert( VG_(args_for_valgrind) );
1651 vg_assert( VG_(args_for_client) );
1652 if (0) {
1653 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
1654 VG_(printf)(
1655 "varg %s\n",
1656 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1657 );
1658 VG_(printf)(" exe %s\n", VG_(args_the_exename));
1659 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
1660 VG_(printf)(
1661 "carg %s\n",
1662 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1663 );
1664 }
1665
1666 //--------------------------------------------------------------
1667 // Extract tool name and whether help has been requested.
1668 // Note we can't print the help message yet, even if requested,
1669 // because the tool has not been initialised.
1670 // p: split_up_argv [for VG_(args_for_valgrind)]
1671 //--------------------------------------------------------------
1672 VG_(debugLog)(1, "main",
1673 "(early_) Process Valgrind's command line options\n");
1674 early_process_cmd_line_options(&need_help, &toolname);
1675
1676 // Set default vex control params
1677 LibVEX_default_VexControl(& VG_(clo_vex_control));
1678
1679 //--------------------------------------------------------------
1680 // Load client executable, finding in $PATH if necessary
1681 // p: early_process_cmd_line_options() [for 'exec', 'need_help',
1682 // clo_max_stackframe,
1683 // clo_main_stacksize]
1684 // p: layout_remaining_space [so there's space]
1685 //
1686 // Set up client's environment
1687 // p: set-libdir [for VG_(libdir)]
1688 // p: early_process_cmd_line_options [for toolname]
1689 //
1690 // Setup client stack, eip, and VG_(client_arg[cv])
1691 // p: load_client() [for 'info']
1692 // p: fix_environment() [for 'env']
1693 //
1694 // Setup client data (brk) segment. Initially a 1-page segment
1695 // which abuts a shrinkable reservation.
1696 // p: load_client() [for 'info' and hence VG_(brk_base)]
1697 //
1698 // p: _start_in_C (for zeroing out the_iicii and putting some
1699 // initial values into it)
1700 //--------------------------------------------------------------
1701 if (!need_help) {
1702 VG_(debugLog)(1, "main", "Create initial image\n");
1703
1704 # if defined(VGO_linux) || defined(VGO_darwin)
1705 the_iicii.argv = argv;
1706 the_iicii.envp = envp;
1707 the_iicii.toolname = toolname;
1708 # else
1709 # error "Unknown platform"
1710 # endif
1711
1712 /* NOTE: this call reads VG_(clo_main_stacksize). */
1713 the_iifii = VG_(ii_create_image)( the_iicii );
1714 }
1715
1716 //==============================================================
1717 //
1718 // Finished loading/setting up the client address space.
1719 //
1720 //==============================================================
1721
1722 //--------------------------------------------------------------
1723 // setup file descriptors
1724 // p: n/a
1725 //--------------------------------------------------------------
1726 VG_(debugLog)(1, "main", "Setup file descriptors\n");
1727 setup_file_descriptors();
1728
1729 //--------------------------------------------------------------
1730 // create the fake /proc/<pid>/cmdline file and then unlink it,
1731 // but hold onto the fd, so we can hand it out to the client
1732 // when it tries to open /proc/<pid>/cmdline for itself.
1733 // p: setup file descriptors
1734 //--------------------------------------------------------------
1735 #if !defined(VGO_linux)
1736 // client shouldn't be using /proc!
1737 VG_(cl_cmdline_fd) = -1;
1738 #else
1739 if (!need_help) {
1740 HChar buf[50], buf2[50+64];
1741 HChar nul[1];
1742 Int fd, r;
1743 const HChar* exename;
1744
1745 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
1746
1747 VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
1748 fd = VG_(mkstemp)( buf, buf2 );
1749 if (fd == -1)
1750 VG_(err_config_error)("Can't create client cmdline file in %s\n", buf2);
1751
1752 nul[0] = 0;
1753 exename = VG_(args_the_exename) ? VG_(args_the_exename)
1754 : "unknown_exename";
1755 VG_(write)(fd, exename, VG_(strlen)( exename ));
1756 VG_(write)(fd, nul, 1);
1757
1758 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1759 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
1760 VG_(write)(fd, arg, VG_(strlen)( arg ));
1761 VG_(write)(fd, nul, 1);
1762 }
1763
1764 /* Don't bother to seek the file back to the start; instead do
1765 it every time a copy of it is given out (by PRE(sys_open)).
1766 That is probably more robust across fork() etc. */
1767
1768 /* Now delete it, but hang on to the fd. */
1769 r = VG_(unlink)( buf2 );
1770 if (r)
1771 VG_(err_config_error)("Can't delete client cmdline file in %s\n", buf2);
1772
1773 VG_(cl_cmdline_fd) = fd;
1774 }
1775 #endif
1776
1777 //--------------------------------------------------------------
1778 // Init tool part 1: pre_clo_init
1779 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1780 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1781 //--------------------------------------------------------------
1782 VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
1783 VG_(tl_pre_clo_init)();
1784
1785 //--------------------------------------------------------------
1786 // If --tool and --help/--help-debug was given, now give the core+tool
1787 // help message
1788 // p: early_process_cmd_line_options() [for 'need_help']
1789 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
1790 //--------------------------------------------------------------
1791 VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
1792 if (need_help) {
1793 usage_NORETURN(/*--help-debug?*/need_help >= 2);
1794 }
1795
1796 //--------------------------------------------------------------
1797 // Process command line options to Valgrind + tool
1798 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1799 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1800 //--------------------------------------------------------------
1801 VG_(debugLog)(1, "main",
1802 "(main_) Process Valgrind's command line options, "
1803 "setup logging\n");
1804 main_process_cmd_line_options ( &logging_to_fd, toolname );
1805
1806 //--------------------------------------------------------------
1807 // Zeroise the millisecond counter by doing a first read of it.
1808 // p: none
1809 //--------------------------------------------------------------
1810 (void) VG_(read_millisecond_timer)();
1811
1812 //--------------------------------------------------------------
1813 // Print the preamble
1814 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
1815 // p: main_process_cmd_line_options()
1816 // [for VG_(clo_verbosity), VG_(clo_xml),
1817 // logging_to_fd]
1818 //--------------------------------------------------------------
1819 VG_(debugLog)(1, "main", "Print the preamble...\n");
1820 print_preamble(logging_to_fd, toolname);
1821 VG_(debugLog)(1, "main", "...finished the preamble\n");
1822
1823 //--------------------------------------------------------------
1824 // Init tool part 2: post_clo_init
1825 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1826 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1827 // p: print_preamble() [so any warnings printed in post_clo_init
1828 // are shown after the preamble]
1829 //--------------------------------------------------------------
1830 VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
1831 VG_TDICT_CALL(tool_post_clo_init);
1832 {
1833 /* The tool's "needs" will by now be finalised, since it has no
1834 further opportunity to specify them. So now sanity check
1835 them. */
1836 Char* s;
1837 Bool ok;
1838 ok = VG_(sanity_check_needs)( &s );
1839 if (!ok) {
1840 VG_(tool_panic)(s);
1841 }
1842 }
1843
1844 //--------------------------------------------------------------
1845 // Initialise translation table and translation cache
1846 // p: aspacem [??]
1847 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
1848 //--------------------------------------------------------------
1849 VG_(debugLog)(1, "main", "Initialise TT/TC\n");
1850 VG_(init_tt_tc)();
1851
1852 //--------------------------------------------------------------
1853 // Initialise the redirect table.
1854 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
1855 // p: aspacem [so can change ownership of sysinfo pages]
1856 //--------------------------------------------------------------
1857 VG_(debugLog)(1, "main", "Initialise redirects\n");
1858 VG_(redir_initialise)();
1859
1860 //--------------------------------------------------------------
1861 // Allow GDB attach
1862 // p: main_process_cmd_line_options() [for VG_(clo_wait_for_gdb)]
1863 //--------------------------------------------------------------
1864 /* Hook to delay things long enough so we can get the pid and
1865 attach GDB in another shell. */
1866 if (VG_(clo_wait_for_gdb)) {
1867 ULong iters, q;
1868 VG_(debugLog)(1, "main", "Wait for GDB\n");
1869 VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
1870
1871 # if defined(VGP_x86_linux)
1872 iters = 5;
1873 # elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
1874 iters = 10;
1875 # elif defined(VGP_ppc32_linux)
1876 iters = 5;
1877 # elif defined(VGP_arm_linux)
1878 iters = 1;
1879 # elif defined(VGP_s390x_linux)
1880 iters = 10;
1881 # elif defined(VGO_darwin)
1882 iters = 3;
1883 # else
1884 # error "Unknown plat"
1885 # endif
1886
1887 iters *= 1000ULL * 1000 * 1000;
1888 for (q = 0; q < iters; q++)
1889 __asm__ __volatile__("" ::: "memory","cc");
1890 }
1891
1892 //--------------------------------------------------------------
1893 // Search for file descriptors that are inherited from our parent
1894 // p: main_process_cmd_line_options [for VG_(clo_track_fds)]
1895 //--------------------------------------------------------------
1896 if (VG_(clo_track_fds)) {
1897 VG_(debugLog)(1, "main", "Init preopened fds\n");
1898 VG_(init_preopened_fds)();
1899 }
1900
1901 //--------------------------------------------------------------
1902 // Load debug info for the existing segments.
1903 // p: setup_code_redirect_table [so that redirs can be recorded]
1904 // p: mallocfree
1905 // p: probably: setup fds and process CLOs, so that logging works
1906 // p: initialise m_debuginfo
1907 //
1908 // While doing this, make a note of the debuginfo-handles that
1909 // come back from VG_(di_notify_mmap).
1910 // Later, in "Tell the tool about the initial client memory permissions"
1911 // (just below) we can then hand these handles off to the tool in
1912 // calls to VG_TRACK(new_mem_startup, ...). This gives the tool the
1913 // opportunity to make further queries to m_debuginfo before the
1914 // client is started, if it wants. We put this information into an
1915 // XArray, each handle along with the associated segment start address,
1916 // and search the XArray for the handles later, when calling
1917 // VG_TRACK(new_mem_startup, ...).
1918 //--------------------------------------------------------------
1919 VG_(debugLog)(1, "main", "Load initial debug info\n");
1920
1921 tl_assert(!addr2dihandle);
1922 addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2",
1923 VG_(free), sizeof(Addr_n_ULong) );
1924 tl_assert(addr2dihandle);
1925
1926 # if defined(VGO_linux)
1927 { Addr* seg_starts;
1928 Int n_seg_starts;
1929 Addr_n_ULong anu;
1930
1931 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
1932 vg_assert(seg_starts && n_seg_starts >= 0);
1933
1934 /* show them all to the debug info reader. allow_SkFileV has to
1935 be True here so that we read info from the valgrind executable
1936 itself. */
1937 for (i = 0; i < n_seg_starts; i++) {
1938 anu.ull = VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/,
1939 -1/*Don't use_fd*/);
1940 /* anu.ull holds the debuginfo handle returned by di_notify_mmap,
1941 if any. */
1942 if (anu.ull > 0) {
1943 anu.a = seg_starts[i];
1944 VG_(addToXA)( addr2dihandle, &anu );
1945 }
1946 }
1947
1948 VG_(free)( seg_starts );
1949 }
1950 # elif defined(VGO_darwin)
1951 { Addr* seg_starts;
1952 Int n_seg_starts;
1953 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
1954 vg_assert(seg_starts && n_seg_starts >= 0);
1955
1956 /* show them all to the debug info reader.
1957 Don't read from V segments (unlike Linux) */
1958 // GrP fixme really?
1959 for (i = 0; i < n_seg_starts; i++) {
1960 VG_(di_notify_mmap)( seg_starts[i], False/*don't allow_SkFileV*/,
1961 -1/*don't use_fd*/);
1962 }
1963
1964 VG_(free)( seg_starts );
1965 }
1966 # else
1967 # error Unknown OS
1968 # endif
1969
1970 //--------------------------------------------------------------
1971 // Tell aspacem of ownership change of the asm helpers, so that
1972 // m_translate allows them to be translated. However, only do this
1973 // after the initial debug info read, since making a hole in the
1974 // address range for the stage2 binary confuses the debug info reader.
1975 // p: aspacem
1976 //--------------------------------------------------------------
1977 { Bool change_ownership_v_c_OK;
1978 Addr co_start = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
1979 Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
1980 VG_(debugLog)(1,"redir",
1981 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
1982 (ULong)co_start, (ULong)co_endPlus-1 );
1983
1984 change_ownership_v_c_OK
1985 = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
1986 vg_assert(change_ownership_v_c_OK);
1987 }
1988
1989 if (VG_(clo_xml)) {
1990 HChar buf[50];
1991 VG_(elapsed_wallclock_time)(buf);
1992 VG_(printf_xml)( "<status>\n"
1993 " <state>RUNNING</state>\n"
1994 " <time>%pS</time>\n"
1995 "</status>\n",
1996 buf );
1997 VG_(printf_xml)( "\n" );
1998 }
1999
2000 //--------------------------------------------------------------
2001 // Initialise the scheduler (phase 1) [generates tid_main]
2002 // p: none, afaics
2003 //--------------------------------------------------------------
2004 VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
2005 tid_main = VG_(scheduler_init_phase1)();
2006 vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
2007 && tid_main != VG_INVALID_THREADID);
2008 /* Tell the tool about tid_main */
2009 VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
2010
2011 //--------------------------------------------------------------
2012 // Tell the tool about the initial client memory permissions
2013 // p: aspacem
2014 // p: mallocfree
2015 // p: setup_client_stack
2016 // p: setup_client_dataseg
2017 //
2018 // For each segment we tell the client about, look up in
2019 // addr2dihandle as created above, to see if there's a debuginfo
2020 // handle associated with the segment, that we can hand along
2021 // to the tool, to be helpful.
2022 //--------------------------------------------------------------
2023 VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
2024 { Addr* seg_starts;
2025 Int n_seg_starts;
2026
2027 tl_assert(addr2dihandle);
2028
2029 /* Mark the main thread as running while we tell the tool about
2030 the client memory so that the tool can associate that memory
2031 with the main thread. */
2032 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
2033 VG_(running_tid) = tid_main;
2034
2035 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
2036 vg_assert(seg_starts && n_seg_starts >= 0);
2037
2038 /* show interesting ones to the tool */
2039 for (i = 0; i < n_seg_starts; i++) {
2040 Word j, n;
2041 NSegment const* seg
2042 = VG_(am_find_nsegment)( seg_starts[i] );
2043 vg_assert(seg);
2044 if (seg->kind == SkFileC || seg->kind == SkAnonC) {
2045 /* This next assertion is tricky. If it is placed
2046 immediately before this 'if', it very occasionally fails.
2047 Why? Because previous iterations of the loop may have
2048 caused tools (via the new_mem_startup calls) to do
2049 dynamic memory allocation, and that may affect the mapped
2050 segments; in particular it may cause segment merging to
2051 happen. Hence we cannot assume that seg_starts[i], which
2052 reflects the state of the world before we started this
2053 loop, is the same as seg->start, as the latter reflects
2054 the state of the world (viz, mappings) at this particular
2055 iteration of the loop.
2056
2057 Why does moving it inside the 'if' make it safe? Because
2058 any dynamic memory allocation done by the tools will
2059 affect only the state of Valgrind-owned segments, not of
2060 Client-owned segments. And the 'if' guards against that
2061 -- we only get in here for Client-owned segments.
2062
2063 In other words: the loop may change the state of
2064 Valgrind-owned segments as it proceeds. But it should
2065 not cause the Client-owned segments to change. */
2066 vg_assert(seg->start == seg_starts[i]);
2067 VG_(debugLog)(2, "main",
2068 "tell tool about %010lx-%010lx %c%c%c\n",
2069 seg->start, seg->end,
2070 seg->hasR ? 'r' : '-',
2071 seg->hasW ? 'w' : '-',
2072 seg->hasX ? 'x' : '-' );
2073 /* search addr2dihandle to see if we have an entry
2074 matching seg->start. */
2075 n = VG_(sizeXA)( addr2dihandle );
2076 for (j = 0; j < n; j++) {
2077 Addr_n_ULong* anl = VG_(indexXA)( addr2dihandle, j );
2078 if (anl->a == seg->start) {
2079 tl_assert(anl->ull > 0); /* check it's a valid handle */
2080 break;
2081 }
2082 }
2083 vg_assert(j >= 0 && j <= n);
2084 VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
2085 seg->hasR, seg->hasW, seg->hasX,
2086 /* and the retrieved debuginfo handle, if any */
2087 j < n
2088 ? ((Addr_n_ULong*)VG_(indexXA)( addr2dihandle, j ))->ull
2089 : 0 );
2090 }
2091 }
2092
2093 VG_(free)( seg_starts );
2094 VG_(deleteXA)( addr2dihandle );
2095
2096 /* Also do the initial stack permissions. */
2097 {
2098 SSizeT inaccessible_len;
2099 NSegment const* seg
2100 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
2101 vg_assert(seg);
2102 vg_assert(seg->kind == SkAnonC);
2103 vg_assert(the_iifii.initial_client_SP >= seg->start);
2104 vg_assert(the_iifii.initial_client_SP <= seg->end);
2105
2106 /* Stuff below the initial SP is unaddressable. Take into
2107 account any ABI-mandated space below the stack pointer that
2108 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
2109 will have allocated an extra page if a red zone is required,
2110 to be on the safe side. */
2111 inaccessible_len = the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
2112 - seg->start;
2113 vg_assert(inaccessible_len >= 0);
2114 if (inaccessible_len > 0)
2115 VG_TRACK( die_mem_stack,
2116 seg->start,
2117 inaccessible_len );
2118 VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
2119 seg->start,
2120 the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
2121 }
2122
2123 /* Also the assembly helpers. */
2124 VG_TRACK( new_mem_startup,
2125 (Addr)&VG_(trampoline_stuff_start),
2126 (Addr)&VG_(trampoline_stuff_end)
2127 - (Addr)&VG_(trampoline_stuff_start),
2128 False, /* readable? */
2129 False, /* writable? */
2130 True /* executable? */,
2131 0 /* di_handle: no associated debug info */ );
2132
2133 /* Clear the running thread indicator */
2134 VG_(running_tid) = VG_INVALID_THREADID;
2135 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
2136 }
2137
2138 //--------------------------------------------------------------
2139 // Initialise the scheduler (phase 2)
2140 // p: Initialise the scheduler (phase 1) [for tid_main]
2141 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
2142 // p: setup_client_stack
2143 //--------------------------------------------------------------
2144 VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
2145 { NSegment const* seg
2146 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
2147 vg_assert(seg);
2148 vg_assert(seg->kind == SkAnonC);
2149 vg_assert(the_iifii.initial_client_SP >= seg->start);
2150 vg_assert(the_iifii.initial_client_SP <= seg->end);
2151 VG_(scheduler_init_phase2)( tid_main,
2152 seg->end, the_iifii.clstack_max_size );
2153 }
2154
2155 //--------------------------------------------------------------
2156 // Set up state for the root thread
2157 // p: ?
2158 // setup_scheduler() [for sched-specific thread 1 stuff]
2159 // VG_(ii_create_image) [for 'the_iicii' initial info]
2160 //--------------------------------------------------------------
2161 VG_(debugLog)(1, "main", "Finalise initial image\n");
2162 VG_(ii_finalise_image)( the_iifii );
2163
2164 //--------------------------------------------------------------
2165 // Initialise the signal handling subsystem
2166 // p: n/a
2167 //--------------------------------------------------------------
2168 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
2169 VG_(debugLog)(1, "main", "Initialise signal management\n");
2170 /* Check that the kernel-interface signal definitions look sane */
2171 VG_(vki_do_initial_consistency_checks)();
2172 /* .. and go on to use them. */
2173 VG_(sigstartup_actions)();
2174
2175 //--------------------------------------------------------------
2176 // Read suppression file
2177 // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
2178 //--------------------------------------------------------------
2179 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
2180 VG_(debugLog)(1, "main", "Load suppressions\n");
2181 VG_(load_suppressions)();
2182 }
2183
2184 //--------------------------------------------------------------
2185 // register client stack
2186 //--------------------------------------------------------------
2187 VG_(clstk_id) = VG_(register_stack)(VG_(clstk_base), VG_(clstk_end));
2188
2189 //--------------------------------------------------------------
2190 // Show the address space state so far
2191 //--------------------------------------------------------------
2192 VG_(debugLog)(1, "main", "\n");
2193 VG_(debugLog)(1, "main", "\n");
2194 VG_(am_show_nsegments)(1,"Memory layout at client startup");
2195 VG_(debugLog)(1, "main", "\n");
2196 VG_(debugLog)(1, "main", "\n");
2197
2198 //--------------------------------------------------------------
2199 // Run!
2200 //--------------------------------------------------------------
2201 VG_(debugLog)(1, "main", "Running thread 1\n");
2202
2203 /* As a result of the following call, the last thread standing
2204 eventually winds up running shutdown_actions_NORETURN
2205 just below. Unfortunately, simply exporting said function
2206 causes m_main to be part of a module cycle, which is pretty
2207 nonsensical. So instead of doing that, the address of said
2208 function is stored in a global variable 'owned' by m_syswrap,
2209 and it uses that function pointer to get back here when it needs
2210 to. */
2211
2212 /* Set continuation address. */
2213 VG_(address_of_m_main_shutdown_actions_NORETURN)
2214 = & shutdown_actions_NORETURN;
2215
2216 /* Run the first thread, eventually ending up at the continuation
2217 address. */
2218 VG_(main_thread_wrapper_NORETURN)(1);
2219
2220 /*NOTREACHED*/
2221 vg_assert(0);
2222 }
2223
2224 /* Do everything which needs doing when the last thread exits or when
2225 a thread exits requesting a complete process exit.
2226
2227 We enter here holding The Lock. For the case VgSrc_ExitProcess we
2228 must never release it, because to do so would allow other threads
2229 to continue after the system is ostensibly shut down. So we must
2230 go to our grave, so to speak, holding the lock.
2231
2232 In fact, there is never any point in releasing the lock at this
2233 point - we have it, we're shutting down the entire system, and
2234 for the case VgSrc_ExitProcess doing so positively causes trouble.
2235 So don't.
2236
2237 The final_tidyup call makes a bit of a nonsense of the ExitProcess
2238 case, since it will run the libc_freeres function, thus allowing
2239 other lurking threads to run again. Hmm. */
2240
2241 static
shutdown_actions_NORETURN(ThreadId tid,VgSchedReturnCode tids_schedretcode)2242 void shutdown_actions_NORETURN( ThreadId tid,
2243 VgSchedReturnCode tids_schedretcode )
2244 {
2245 VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
2246 VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
2247
2248 vg_assert(VG_(is_running_thread)(tid));
2249
2250 vg_assert(tids_schedretcode == VgSrc_ExitThread
2251 || tids_schedretcode == VgSrc_ExitProcess
2252 || tids_schedretcode == VgSrc_FatalSig );
2253
2254 if (tids_schedretcode == VgSrc_ExitThread) {
2255
2256 // We are the last surviving thread. Right?
2257 vg_assert( VG_(count_living_threads)() == 1 );
2258
2259 // Wait for all other threads to exit.
2260 // jrs: Huh? but they surely are already gone
2261 VG_(reap_threads)(tid);
2262
2263 // Clean the client up before the final report
2264 // this causes the libc_freeres function to run
2265 final_tidyup(tid);
2266
2267 /* be paranoid */
2268 vg_assert(VG_(is_running_thread)(tid));
2269 vg_assert(VG_(count_living_threads)() == 1);
2270
2271 } else {
2272
2273 // We may not be the last surviving thread. However, we
2274 // want to shut down the entire process. We hold the lock
2275 // and we need to keep hold of it all the way out, in order
2276 // that none of the other threads ever run again.
2277 vg_assert( VG_(count_living_threads)() >= 1 );
2278
2279 // Clean the client up before the final report
2280 // this causes the libc_freeres function to run
2281 // perhaps this is unsafe, as per comment above
2282 final_tidyup(tid);
2283
2284 /* be paranoid */
2285 vg_assert(VG_(is_running_thread)(tid));
2286 vg_assert(VG_(count_living_threads)() >= 1);
2287 }
2288
2289 VG_(threads)[tid].status = VgTs_Empty;
2290 //--------------------------------------------------------------
2291 // Finalisation: cleanup, messages, etc. Order not so important, only
2292 // affects what order the messages come.
2293 //--------------------------------------------------------------
2294 // First thing in the post-amble is a blank line.
2295 if (VG_(clo_xml))
2296 VG_(printf_xml)("\n");
2297 else if (VG_(clo_verbosity) > 0)
2298 VG_(message)(Vg_UserMsg, "\n");
2299
2300 if (VG_(clo_xml)) {
2301 HChar buf[50];
2302 VG_(elapsed_wallclock_time)(buf);
2303 VG_(printf_xml)( "<status>\n"
2304 " <state>FINISHED</state>\n"
2305 " <time>%pS</time>\n"
2306 "</status>\n"
2307 "\n",
2308 buf);
2309 }
2310
2311 /* Print out file descriptor summary and stats. */
2312 if (VG_(clo_track_fds))
2313 VG_(show_open_fds)();
2314
2315 /* Call the tool's finalisation function. This makes Memcheck's
2316 leak checker run, and possibly chuck a bunch of leak errors into
2317 the error management machinery. */
2318 VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
2319
2320 /* Show the error counts. */
2321 if (VG_(clo_xml)
2322 && (VG_(needs).core_errors || VG_(needs).tool_errors)) {
2323 VG_(show_error_counts_as_XML)();
2324 }
2325
2326 /* In XML mode, this merely prints the used suppressions. */
2327 if (VG_(needs).core_errors || VG_(needs).tool_errors)
2328 VG_(show_all_errors)(VG_(clo_verbosity), VG_(clo_xml));
2329
2330 if (VG_(clo_xml)) {
2331 VG_(printf_xml)("\n");
2332 VG_(printf_xml)("</valgrindoutput>\n");
2333 VG_(printf_xml)("\n");
2334 }
2335
2336 VG_(sanity_check_general)( True /*include expensive checks*/ );
2337
2338 if (VG_(clo_stats))
2339 print_all_stats();
2340
2341 /* Show a profile of the heap(s) at shutdown. Optionally, first
2342 throw away all the debug info, as that makes it easy to spot
2343 leaks in the debuginfo reader. */
2344 if (VG_(clo_profile_heap)) {
2345 if (0) VG_(di_discard_ALL_debuginfo)();
2346 VG_(print_arena_cc_analysis)();
2347 }
2348
2349 if (VG_(clo_profile_flags) > 0) {
2350 #define N_MAX 200
2351 BBProfEntry tops[N_MAX];
2352 ULong score_total = VG_(get_BB_profile) (tops, N_MAX);
2353 show_BB_profile(tops, N_MAX, score_total);
2354 }
2355
2356 /* Print Vex storage stats */
2357 if (0)
2358 LibVEX_ShowAllocStats();
2359
2360 /* Flush any output cached by previous calls to VG_(message). */
2361 VG_(message_flush)();
2362
2363 /* terminate gdbserver if ever it was started. We terminate it here so that it get
2364 the output above if output was redirected to gdb */
2365 VG_(gdbserver) (0);
2366
2367 /* Ok, finally exit in the os-specific way, according to the scheduler's
2368 return code. In short, if the (last) thread exited by calling
2369 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2370 signal, terminate the entire system with that same fatal signal. */
2371 VG_(debugLog)(1, "core_os",
2372 "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
2373
2374 switch (tids_schedretcode) {
2375 case VgSrc_ExitThread: /* the normal way out (Linux) */
2376 case VgSrc_ExitProcess: /* the normal way out (AIX) -- still needed? */
2377 /* Change the application return code to user's return code,
2378 if an error was found */
2379 if (VG_(clo_error_exitcode) > 0
2380 && VG_(get_n_errs_found)() > 0) {
2381 VG_(exit)( VG_(clo_error_exitcode) );
2382 } else {
2383 /* otherwise, return the client's exit code, in the normal
2384 way. */
2385 VG_(exit)( VG_(threads)[tid].os_state.exitcode );
2386 }
2387 /* NOT ALIVE HERE! */
2388 VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
2389 break; /* what the hell :) */
2390
2391 case VgSrc_FatalSig:
2392 /* We were killed by a fatal signal, so replicate the effect */
2393 vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
2394 VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
2395 /* we shouldn't be alive at this point. But VG_(kill_self)
2396 sometimes fails with EPERM on Darwin, for unclear reasons. */
2397 # if defined(VGO_darwin)
2398 VG_(debugLog)(0, "main", "VG_(kill_self) failed. Exiting normally.\n");
2399 VG_(exit)(0); /* bogus, but we really need to exit now */
2400 /* fall through .. */
2401 # endif
2402 VG_(core_panic)("main(): signal was supposed to be fatal");
2403 break;
2404
2405 default:
2406 VG_(core_panic)("main(): unexpected scheduler return code");
2407 }
2408 }
2409
2410 /* -------------------- */
2411
2412 /* Final clean-up before terminating the process.
2413 Clean up the client by calling __libc_freeres() (if requested)
2414 This is Linux-specific?
2415 GrP fixme glibc-specific, anyway
2416 */
final_tidyup(ThreadId tid)2417 static void final_tidyup(ThreadId tid)
2418 {
2419 #if !defined(VGO_darwin)
2420 # if defined(VGP_ppc64_linux)
2421 Addr r2;
2422 # endif
2423 Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
2424
2425 vg_assert(VG_(is_running_thread)(tid));
2426
2427 if ( !VG_(needs).libc_freeres ||
2428 !VG_(clo_run_libc_freeres) ||
2429 0 == __libc_freeres_wrapper )
2430 return; /* can't/won't do it */
2431
2432 # if defined(VGP_ppc64_linux)
2433 r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
2434 if (r2 == 0) {
2435 VG_(message)(Vg_UserMsg,
2436 "Caught __NR_exit, but can't run __libc_freeres()\n");
2437 VG_(message)(Vg_UserMsg,
2438 " since cannot establish TOC pointer for it.\n");
2439 return;
2440 }
2441 # endif
2442
2443 if (VG_(clo_verbosity) > 2 ||
2444 VG_(clo_trace_syscalls) ||
2445 VG_(clo_trace_sched))
2446 VG_(message)(Vg_DebugMsg,
2447 "Caught __NR_exit; running __libc_freeres()\n");
2448
2449 /* set thread context to point to libc_freeres_wrapper */
2450 /* ppc64-linux note: __libc_freeres_wrapper gives us the real
2451 function entry point, not a fn descriptor, so can use it
2452 directly. However, we need to set R2 (the toc pointer)
2453 appropriately. */
2454 VG_(set_IP)(tid, __libc_freeres_wrapper);
2455 # if defined(VGP_ppc64_linux)
2456 VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
2457 # endif
2458
2459 /* Block all blockable signals by copying the real block state into
2460 the thread's block state*/
2461 VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
2462 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
2463
2464 /* and restore handlers to default */
2465 VG_(set_default_handler)(VKI_SIGSEGV);
2466 VG_(set_default_handler)(VKI_SIGBUS);
2467 VG_(set_default_handler)(VKI_SIGILL);
2468 VG_(set_default_handler)(VKI_SIGFPE);
2469
2470 // We were exiting, so assert that...
2471 vg_assert(VG_(is_exiting)(tid));
2472 // ...but now we're not again
2473 VG_(threads)[tid].exitreason = VgSrc_None;
2474
2475 // run until client thread exits - ideally with LIBC_FREERES_DONE,
2476 // but exit/exitgroup/signal will do
2477 VG_(scheduler)(tid);
2478
2479 vg_assert(VG_(is_exiting)(tid));
2480 #endif
2481 }
2482
2483
2484 /*====================================================================*/
2485 /*=== Getting to main() alive: LINUX ===*/
2486 /*====================================================================*/
2487
2488 #if defined(VGO_linux)
2489
2490 /* If linking of the final executables is done with glibc present,
2491 then Valgrind starts at main() above as usual, and all of the
2492 following code is irrelevant.
2493
2494 However, this is not the intended mode of use. The plan is to
2495 avoid linking against glibc, by giving gcc the flags
2496 -nodefaultlibs -lgcc -nostartfiles at startup.
2497
2498 From this derive two requirements:
2499
2500 1. gcc may emit calls to memcpy and memset to deal with structure
2501 assignments etc. Since we have chosen to ignore all the
2502 "normal" supporting libraries, we have to provide our own
2503 implementations of them. No problem.
2504
2505 2. We have to provide a symbol "_start", to which the kernel
2506 hands control at startup. Hence the code below.
2507 */
2508
2509 /* ---------------- Requirement 1 ---------------- */
2510
2511 void* memcpy(void *dest, const void *src, SizeT n);
memcpy(void * dest,const void * src,SizeT n)2512 void* memcpy(void *dest, const void *src, SizeT n) {
2513 return VG_(memcpy)(dest,src,n);
2514 }
2515 void* memset(void *s, int c, SizeT n);
memset(void * s,int c,SizeT n)2516 void* memset(void *s, int c, SizeT n) {
2517 return VG_(memset)(s,c,n);
2518 }
2519
2520 /* BVA: abort() for those platforms that need it (PPC and ARM). */
2521 void abort(void);
abort(void)2522 void abort(void){
2523 VG_(printf)("Something called raise().\n");
2524 vg_assert(0);
2525 }
2526
2527 /* EAZG: ARM's EABI will call floating point exception handlers in
2528 libgcc which boil down to an abort or raise, that's usually defined
2529 in libc. Instead, define them here. */
2530 #if defined(VGP_arm_linux)
2531 void raise(void);
raise(void)2532 void raise(void){
2533 VG_(printf)("Something called raise().\n");
2534 vg_assert(0);
2535 }
2536
2537 void __aeabi_unwind_cpp_pr0(void);
__aeabi_unwind_cpp_pr0(void)2538 void __aeabi_unwind_cpp_pr0(void){
2539 VG_(printf)("Something called __aeabi_unwind_cpp_pr0()\n");
2540 vg_assert(0);
2541 }
2542
2543 void __aeabi_unwind_cpp_pr1(void);
__aeabi_unwind_cpp_pr1(void)2544 void __aeabi_unwind_cpp_pr1(void){
2545 VG_(printf)("Something called __aeabi_unwind_cpp_pr1()\n");
2546 vg_assert(0);
2547 }
2548 #endif
2549
2550 /* ---------------- Requirement 2 ---------------- */
2551
2552 /* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2553 comment, which explains how the stack looks right at process start
2554 (when _start is jumped to). Hence _start passes %esp to
2555 _start_in_C_linux, which extracts argc/argv/envp and starts up
2556 correctly. */
2557
2558 /* This is the canonical entry point, usually the first thing in the text
2559 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2560 point runs, most registers' values are unspecified, except for:
2561
2562 %edx Contains a function pointer to be registered with `atexit'.
2563 This is how the dynamic linker arranges to have DT_FINI
2564 functions called for shared libraries that have been loaded
2565 before this code runs.
2566
2567 %esp The stack contains the arguments and environment:
2568 0(%esp) argc
2569 4(%esp) argv[0]
2570 ...
2571 (4*argc)(%esp) NULL
2572 (4*(argc+1))(%esp) envp[0]
2573 ...
2574 NULL
2575 */
2576
2577 /* The kernel hands control to _start, which extracts the initial
2578 stack pointer and calls onwards to _start_in_C_linux. This also switches
2579 the new stack. */
2580 #if defined(VGP_x86_linux)
2581 asm("\n"
2582 ".text\n"
2583 "\t.globl _start\n"
2584 "\t.type _start,@function\n"
2585 "_start:\n"
2586 /* set up the new stack in %eax */
2587 "\tmovl $vgPlain_interim_stack, %eax\n"
2588 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2589 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2590 "\tsubl $16, %eax\n"
2591 "\tandl $~15, %eax\n"
2592 /* install it, and collect the original one */
2593 "\txchgl %eax, %esp\n"
2594 /* call _start_in_C_linux, passing it the startup %esp */
2595 "\tpushl %eax\n"
2596 "\tcall _start_in_C_linux\n"
2597 "\thlt\n"
2598 ".previous\n"
2599 );
2600 #elif defined(VGP_amd64_linux)
2601 asm("\n"
2602 ".text\n"
2603 "\t.globl _start\n"
2604 "\t.type _start,@function\n"
2605 "_start:\n"
2606 /* set up the new stack in %rdi */
2607 "\tmovq $vgPlain_interim_stack, %rdi\n"
2608 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2609 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2610 "\tandq $~15, %rdi\n"
2611 /* install it, and collect the original one */
2612 "\txchgq %rdi, %rsp\n"
2613 /* call _start_in_C_linux, passing it the startup %rsp */
2614 "\tcall _start_in_C_linux\n"
2615 "\thlt\n"
2616 ".previous\n"
2617 );
2618 #elif defined(VGP_ppc32_linux)
2619 asm("\n"
2620 ".text\n"
2621 "\t.globl _start\n"
2622 "\t.type _start,@function\n"
2623 "_start:\n"
2624 /* set up the new stack in r16 */
2625 "\tlis 16,vgPlain_interim_stack@ha\n"
2626 "\tla 16,vgPlain_interim_stack@l(16)\n"
2627 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2628 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2629 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2630 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2631 "\tadd 16,17,16\n"
2632 "\tadd 16,18,16\n"
2633 "\trlwinm 16,16,0,0,27\n"
2634 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2635 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2636 boundary. And r1 is the original SP. Set the SP to r16 and
2637 call _start_in_C_linux, passing it the initial SP. */
2638 "\tmr 3,1\n"
2639 "\tmr 1,16\n"
2640 "\tbl _start_in_C_linux\n"
2641 "\ttrap\n"
2642 ".previous\n"
2643 );
2644 #elif defined(VGP_ppc64_linux)
2645 asm("\n"
2646 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2647 So we must have one, and that is what goes into the .opd section. */
2648 "\t.align 2\n"
2649 "\t.global _start\n"
2650 "\t.section \".opd\",\"aw\"\n"
2651 "\t.align 3\n"
2652 "_start:\n"
2653 "\t.quad ._start,.TOC.@tocbase,0\n"
2654 "\t.previous\n"
2655 "\t.type ._start,@function\n"
2656 "\t.global ._start\n"
2657 "._start:\n"
2658 /* set up the new stack in r16 */
2659 "\tlis 16, vgPlain_interim_stack@highest\n"
2660 "\tori 16,16,vgPlain_interim_stack@higher\n"
2661 "\tsldi 16,16,32\n"
2662 "\toris 16,16,vgPlain_interim_stack@h\n"
2663 "\tori 16,16,vgPlain_interim_stack@l\n"
2664 "\txor 17,17,17\n"
2665 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2666 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2667 "\txor 18,18,18\n"
2668 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2669 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2670 "\tadd 16,17,16\n"
2671 "\tadd 16,18,16\n"
2672 "\trldicr 16,16,0,59\n"
2673 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2674 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2675 boundary. And r1 is the original SP. Set the SP to r16 and
2676 call _start_in_C_linux, passing it the initial SP. */
2677 "\tmr 3,1\n"
2678 "\tmr 1,16\n"
2679 "\tbl ._start_in_C_linux\n"
2680 "\tnop\n"
2681 "\ttrap\n"
2682 );
2683 #elif defined(VGP_s390x_linux)
2684 /*
2685 This is the canonical entry point, usually the first thing in the text
2686 segment. Most registers' values are unspecified, except for:
2687
2688 %r14 Contains a function pointer to be registered with `atexit'.
2689 This is how the dynamic linker arranges to have DT_FINI
2690 functions called for shared libraries that have been loaded
2691 before this code runs.
2692
2693 %r15 The stack contains the arguments and environment:
2694 0(%r15) argc
2695 8(%r15) argv[0]
2696 ...
2697 (8*argc)(%r15) NULL
2698 (8*(argc+1))(%r15) envp[0]
2699 ...
2700 NULL
2701 */
2702 asm("\n\t"
2703 ".text\n\t"
2704 ".globl _start\n\t"
2705 ".type _start,@function\n\t"
2706 "_start:\n\t"
2707 /* set up the new stack in %r1 */
2708 "larl %r1, vgPlain_interim_stack\n\t"
2709 "larl %r5, 1f\n\t"
2710 "ag %r1, 0(%r5)\n\t"
2711 "ag %r1, 2f-1f(%r5)\n\t"
2712 "nill %r1, 0xFFF0\n\t"
2713 /* install it, and collect the original one */
2714 "lgr %r2, %r15\n\t"
2715 "lgr %r15, %r1\n\t"
2716 /* call _start_in_C_linux, passing it the startup %r15 */
2717 "brasl %r14, _start_in_C_linux\n\t"
2718 /* trigger execution of an invalid opcode -> halt machine */
2719 "j .+2\n\t"
2720 "1: .quad "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n\t"
2721 "2: .quad "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n\t"
2722 ".previous\n"
2723 );
2724 #elif defined(VGP_arm_linux)
2725 asm("\n"
2726 "\t.text\n"
2727 "\t.align 4\n"
2728 "\t.type _start,#function\n"
2729 "\t.global _start\n"
2730 "_start:\n"
2731 "\tldr r0, [pc, #36]\n"
2732 "\tldr r1, [pc, #36]\n"
2733 "\tadd r0, r1, r0\n"
2734 "\tldr r1, [pc, #32]\n"
2735 "\tadd r0, r1, r0\n"
2736 "\tmvn r1, #15\n"
2737 "\tand r0, r0, r1\n"
2738 "\tmov r1, sp\n"
2739 "\tmov sp, r0\n"
2740 "\tmov r0, r1\n"
2741 "\tb _start_in_C_linux\n"
2742 "\t.word vgPlain_interim_stack\n"
2743 "\t.word "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
2744 "\t.word "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
2745 );
2746 #else
2747 # error "Unknown linux platform"
2748 #endif
2749
2750 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
2751 #define _GNU_SOURCE
2752 #define _FILE_OFFSET_BITS 64
2753 /* This is in order to get AT_NULL and AT_PAGESIZE. */
2754 #include <elf.h>
2755 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
2756
2757 /* Avoid compiler warnings: this fn _is_ used, but labelling it
2758 'static' causes gcc to complain it isn't. */
2759 void _start_in_C_linux ( UWord* pArgc );
_start_in_C_linux(UWord * pArgc)2760 void _start_in_C_linux ( UWord* pArgc )
2761 {
2762 Int r;
2763 Word argc = pArgc[0];
2764 HChar** argv = (HChar**)&pArgc[1];
2765 HChar** envp = (HChar**)&pArgc[1+argc+1];
2766
2767 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2768 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2769
2770 the_iicii.sp_at_startup = (Addr)pArgc;
2771
2772 # if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
2773 {
2774 /* ppc/ppc64 can be configured with different page sizes.
2775 Determine this early. This is an ugly hack and really should
2776 be moved into valgrind_main. */
2777 UWord *sp = &pArgc[1+argc+1];
2778 while (*sp++ != 0)
2779 ;
2780 for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
2781 if (*sp == AT_PAGESZ) {
2782 VKI_PAGE_SIZE = sp[1];
2783 for (VKI_PAGE_SHIFT = 12;
2784 VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
2785 if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
2786 break;
2787 }
2788 }
2789 # endif
2790
2791 r = valgrind_main( (Int)argc, argv, envp );
2792 /* NOTREACHED */
2793 VG_(exit)(r);
2794 }
2795
2796
2797 /*====================================================================*/
2798 /*=== Getting to main() alive: darwin ===*/
2799 /*====================================================================*/
2800
2801 #elif defined(VGO_darwin)
2802
2803 /*
2804 Memory layout established by kernel:
2805
2806 0(%esp) argc
2807 4(%esp) argv[0]
2808 ...
2809 argv[argc-1]
2810 NULL
2811 envp[0]
2812 ...
2813 envp[n]
2814 NULL
2815 executable name (presumably, a pointer to it)
2816 NULL
2817
2818 Ditto in the 64-bit case, except all offsets from SP are obviously
2819 twice as large.
2820 */
2821
2822 /* The kernel hands control to _start, which extracts the initial
2823 stack pointer and calls onwards to _start_in_C_darwin. This also
2824 switches to the new stack. */
2825 #if defined(VGP_x86_darwin)
2826 asm("\n"
2827 ".text\n"
2828 ".align 2,0x90\n"
2829 "\t.globl __start\n"
2830 "__start:\n"
2831 /* set up the new stack in %eax */
2832 "\tmovl $_vgPlain_interim_stack, %eax\n"
2833 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2834 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2835 "\tsubl $16, %eax\n"
2836 "\tandl $~15, %eax\n"
2837 /* install it, and collect the original one */
2838 "\txchgl %eax, %esp\n"
2839 /* call _start_in_C_darwin, passing it the startup %esp */
2840 "\tpushl %eax\n"
2841 "\tcall __start_in_C_darwin\n"
2842 "\tint $3\n"
2843 "\tint $3\n"
2844 );
2845 #elif defined(VGP_amd64_darwin)
2846 asm("\n"
2847 ".text\n"
2848 "\t.globl __start\n"
2849 ".align 3,0x90\n"
2850 "__start:\n"
2851 /* set up the new stack in %rdi */
2852 "\tmovabsq $_vgPlain_interim_stack, %rdi\n"
2853 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2854 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2855 "\tandq $~15, %rdi\n"
2856 /* install it, and collect the original one */
2857 "\txchgq %rdi, %rsp\n"
2858 /* call _start_in_C_darwin, passing it the startup %rsp */
2859 "\tcall __start_in_C_darwin\n"
2860 "\tint $3\n"
2861 "\tint $3\n"
2862 );
2863 #endif
2864
2865 void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2);
__memcpy_chk(void * dest,const void * src,SizeT n,SizeT n2)2866 void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2) {
2867 // skip check
2868 return VG_(memcpy)(dest,src,n);
2869 }
2870 void* __memset_chk(void *s, int c, SizeT n, SizeT n2);
__memset_chk(void * s,int c,SizeT n,SizeT n2)2871 void* __memset_chk(void *s, int c, SizeT n, SizeT n2) {
2872 // skip check
2873 return VG_(memset)(s,c,n);
2874 }
2875 void bzero(void *s, SizeT n);
bzero(void * s,SizeT n)2876 void bzero(void *s, SizeT n) {
2877 VG_(memset)(s,0,n);
2878 }
2879
2880 void* memcpy(void *dest, const void *src, SizeT n);
memcpy(void * dest,const void * src,SizeT n)2881 void* memcpy(void *dest, const void *src, SizeT n) {
2882 return VG_(memcpy)(dest,src,n);
2883 }
2884 void* memset(void *s, int c, SizeT n);
memset(void * s,int c,SizeT n)2885 void* memset(void *s, int c, SizeT n) {
2886 return VG_(memset)(s,c,n);
2887 }
2888
2889 /* Avoid compiler warnings: this fn _is_ used, but labelling it
2890 'static' causes gcc to complain it isn't. */
2891 void _start_in_C_darwin ( UWord* pArgc );
_start_in_C_darwin(UWord * pArgc)2892 void _start_in_C_darwin ( UWord* pArgc )
2893 {
2894 Int r;
2895 Int argc = *(Int *)pArgc; // not pArgc[0] on LP64
2896 HChar** argv = (HChar**)&pArgc[1];
2897 HChar** envp = (HChar**)&pArgc[1+argc+1];
2898
2899 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2900 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2901
2902 the_iicii.sp_at_startup = (Addr)pArgc;
2903
2904 r = valgrind_main( (Int)argc, argv, envp );
2905 /* NOTREACHED */
2906 VG_(exit)(r);
2907 }
2908
2909
2910 #else
2911
2912 # error "Unknown OS"
2913 #endif
2914
2915
2916 /*====================================================================*/
2917 /*=== {u,}{div,mod}di3 replacements ===*/
2918 /*====================================================================*/
2919
2920 /* For static linking on x86-darwin, we need to supply our own 64-bit
2921 integer division code, else the link dies thusly:
2922
2923 ld_classic: Undefined symbols:
2924 ___udivdi3
2925 ___umoddi3
2926 */
2927 #if defined(VGP_x86_darwin)
2928
2929 /* Routines for doing signed/unsigned 64 x 64 ==> 64 div and mod
2930 (udivdi3, umoddi3, divdi3, moddi3) using only 32 x 32 ==> 32
2931 division. Cobbled together from
2932
2933 http://www.hackersdelight.org/HDcode/divlu.c
2934 http://www.hackersdelight.org/HDcode/divls.c
2935 http://www.hackersdelight.org/HDcode/newCode/divDouble.c
2936
2937 The code from those three files is covered by the following license,
2938 as it appears at:
2939
2940 http://www.hackersdelight.org/permissions.htm
2941
2942 You are free to use, copy, and distribute any of the code on
2943 this web site, whether modified by you or not. You need not give
2944 attribution. This includes the algorithms (some of which appear
2945 in Hacker's Delight), the Hacker's Assistant, and any code
2946 submitted by readers. Submitters implicitly agree to this.
2947 */
2948
2949 /* Long division, unsigned (64/32 ==> 32).
2950 This procedure performs unsigned "long division" i.e., division of a
2951 64-bit unsigned dividend by a 32-bit unsigned divisor, producing a
2952 32-bit quotient. In the overflow cases (divide by 0, or quotient
2953 exceeds 32 bits), it returns a remainder of 0xFFFFFFFF (an impossible
2954 value).
2955 The dividend is u1 and u0, with u1 being the most significant word.
2956 The divisor is parameter v. The value returned is the quotient.
2957 Max line length is 57, to fit in hacker.book. */
2958
nlz32(UInt x)2959 static Int nlz32(UInt x)
2960 {
2961 Int n;
2962 if (x == 0) return(32);
2963 n = 0;
2964 if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
2965 if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
2966 if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
2967 if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
2968 if (x <= 0x7FFFFFFF) {n = n + 1;}
2969 return n;
2970 }
2971
2972 /* 64 x 32 ==> 32 unsigned division, using only 32 x 32 ==> 32
2973 division as a primitive. */
divlu2(UInt u1,UInt u0,UInt v,UInt * r)2974 static UInt divlu2(UInt u1, UInt u0, UInt v, UInt *r)
2975 {
2976 const UInt b = 65536; // Number base (16 bits).
2977 UInt un1, un0, // Norm. dividend LSD's.
2978 vn1, vn0, // Norm. divisor digits.
2979 q1, q0, // Quotient digits.
2980 un32, un21, un10, // Dividend digit pairs.
2981 rhat; // A remainder.
2982 Int s; // Shift amount for norm.
2983
2984 if (u1 >= v) { // If overflow, set rem.
2985 if (r != NULL) // to an impossible value,
2986 *r = 0xFFFFFFFF; // and return the largest
2987 return 0xFFFFFFFF;} // possible quotient.
2988
2989 s = nlz32(v); // 0 <= s <= 31.
2990 v = v << s; // Normalize divisor.
2991 vn1 = v >> 16; // Break divisor up into
2992 vn0 = v & 0xFFFF; // two 16-bit digits.
2993
2994 un32 = (u1 << s) | ((u0 >> (32 - s)) & (-s >> 31));
2995 un10 = u0 << s; // Shift dividend left.
2996
2997 un1 = un10 >> 16; // Break right half of
2998 un0 = un10 & 0xFFFF; // dividend into two digits.
2999
3000 q1 = un32/vn1; // Compute the first
3001 rhat = un32 - q1*vn1; // quotient digit, q1.
3002 again1:
3003 if (q1 >= b || q1*vn0 > b*rhat + un1) {
3004 q1 = q1 - 1;
3005 rhat = rhat + vn1;
3006 if (rhat < b) goto again1;}
3007
3008 un21 = un32*b + un1 - q1*v; // Multiply and subtract.
3009
3010 q0 = un21/vn1; // Compute the second
3011 rhat = un21 - q0*vn1; // quotient digit, q0.
3012 again2:
3013 if (q0 >= b || q0*vn0 > b*rhat + un0) {
3014 q0 = q0 - 1;
3015 rhat = rhat + vn1;
3016 if (rhat < b) goto again2;}
3017
3018 if (r != NULL) // If remainder is wanted,
3019 *r = (un21*b + un0 - q0*v) >> s; // return it.
3020 return q1*b + q0;
3021 }
3022
3023
3024 /* 64 x 32 ==> 32 signed division, using only 32 x 32 ==> 32 division
3025 as a primitive. */
divls(Int u1,UInt u0,Int v,Int * r)3026 static Int divls(Int u1, UInt u0, Int v, Int *r)
3027 {
3028 Int q, uneg, vneg, diff, borrow;
3029
3030 uneg = u1 >> 31; // -1 if u < 0.
3031 if (uneg) { // Compute the absolute
3032 u0 = -u0; // value of the dividend u.
3033 borrow = (u0 != 0);
3034 u1 = -u1 - borrow;}
3035
3036 vneg = v >> 31; // -1 if v < 0.
3037 v = (v ^ vneg) - vneg; // Absolute value of v.
3038
3039 if ((UInt)u1 >= (UInt)v) goto overflow;
3040
3041 q = divlu2(u1, u0, v, (UInt *)r);
3042
3043 diff = uneg ^ vneg; // Negate q if signs of
3044 q = (q ^ diff) - diff; // u and v differed.
3045 if (uneg && r != NULL)
3046 *r = -*r;
3047
3048 if ((diff ^ q) < 0 && q != 0) { // If overflow,
3049 overflow: // set remainder
3050 if (r != NULL) // to an impossible value,
3051 *r = 0x80000000; // and return the largest
3052 q = 0x80000000;} // possible neg. quotient.
3053 return q;
3054 }
3055
3056
3057
3058 /* This file contains a program for doing 64/64 ==> 64 division, on a
3059 machine that does not have that instruction but that does have
3060 instructions for "long division" (64/32 ==> 32). Code for unsigned
3061 division is given first, followed by a simple program for doing the
3062 signed version by using the unsigned version.
3063 These programs are useful in implementing "long long" (64-bit)
3064 arithmetic on a machine that has the long division instruction. It will
3065 work on 64- and 32-bit machines, provided the compiler implements long
3066 long's (64-bit integers). It is desirable that the machine have the
3067 Count Leading Zeros instruction.
3068 In the GNU world, these programs are known as __divdi3 and __udivdi3,
3069 and similar names are used here.
3070 This material is not in HD, but may be in a future edition.
3071 Max line length is 57, to fit in hacker.book. */
3072
3073
nlz64(ULong x)3074 static Int nlz64(ULong x)
3075 {
3076 Int n;
3077 if (x == 0) return(64);
3078 n = 0;
3079 if (x <= 0x00000000FFFFFFFFULL) {n = n + 32; x = x << 32;}
3080 if (x <= 0x0000FFFFFFFFFFFFULL) {n = n + 16; x = x << 16;}
3081 if (x <= 0x00FFFFFFFFFFFFFFULL) {n = n + 8; x = x << 8;}
3082 if (x <= 0x0FFFFFFFFFFFFFFFULL) {n = n + 4; x = x << 4;}
3083 if (x <= 0x3FFFFFFFFFFFFFFFULL) {n = n + 2; x = x << 2;}
3084 if (x <= 0x7FFFFFFFFFFFFFFFULL) {n = n + 1;}
3085 return n;
3086 }
3087
3088 // ---------------------------- udivdi3 --------------------------------
3089
3090 /* The variables u0, u1, etc. take on only 32-bit values, but they
3091 are declared long long to avoid some compiler warning messages and to
3092 avoid some unnecessary EXTRs that the compiler would put in, to
3093 convert long longs to ints.
3094
3095 First the procedure takes care of the case in which the divisor is a
3096 32-bit quantity. There are two subcases: (1) If the left half of the
3097 dividend is less than the divisor, one execution of DIVU is all that
3098 is required (overflow is not possible). (2) Otherwise it does two
3099 divisions, using the grade school method, with variables used as
3100 suggested below.
3101
3102 q1 q0
3103 ________
3104 v) u1 u0
3105 q1*v
3106 ____
3107 k u0 */
3108
3109 /* These macros must be used with arguments of the appropriate type
3110 (unsigned long long for DIVU and long long for DIVS. They are
3111 simulations of the presumed machines ops. I.e., they look at only the
3112 low-order 32 bits of the divisor, they return garbage if the division
3113 overflows, and they return garbage in the high-order half of the
3114 quotient doubleword.
3115 In practice, these would be replaced with uses of the machine's DIVU
3116 and DIVS instructions (e.g., by using the GNU "asm" facility). */
3117
DIVU(ULong u,UInt v)3118 static UInt DIVU ( ULong u, UInt v )
3119 {
3120 UInt uHi = (UInt)(u >> 32);
3121 UInt uLo = (UInt)u;
3122 return divlu2(uHi, uLo, v, NULL);
3123 }
3124
DIVS(Long u,Int v)3125 static Int DIVS ( Long u, Int v )
3126 {
3127 Int uHi = (Int)(u >> 32);
3128 UInt uLo = (UInt)u;
3129 return divls(uHi, uLo, v, NULL);
3130 }
3131
3132 /* 64 x 64 ==> 64 unsigned division, using only 32 x 32 ==> 32
3133 division as a primitive. */
udivdi3(ULong u,ULong v)3134 static ULong udivdi3(ULong u, ULong v)
3135 {
3136 ULong u0, u1, v1, q0, q1, k, n;
3137
3138 if (v >> 32 == 0) { // If v < 2**32:
3139 if (u >> 32 < v) // If u/v cannot overflow,
3140 return DIVU(u, v) // just do one division.
3141 & 0xFFFFFFFF;
3142 else { // If u/v would overflow:
3143 u1 = u >> 32; // Break u up into two
3144 u0 = u & 0xFFFFFFFF; // halves.
3145 q1 = DIVU(u1, v) // First quotient digit.
3146 & 0xFFFFFFFF;
3147 k = u1 - q1*v; // First remainder, < v.
3148 q0 = DIVU((k << 32) + u0, v) // 2nd quot. digit.
3149 & 0xFFFFFFFF;
3150 return (q1 << 32) + q0;
3151 }
3152 }
3153 // Here v >= 2**32.
3154 n = nlz64(v); // 0 <= n <= 31.
3155 v1 = (v << n) >> 32; // Normalize the divisor
3156 // so its MSB is 1.
3157 u1 = u >> 1; // To ensure no overflow.
3158 q1 = DIVU(u1, v1) // Get quotient from
3159 & 0xFFFFFFFF; // divide unsigned insn.
3160 q0 = (q1 << n) >> 31; // Undo normalization and
3161 // division of u by 2.
3162 if (q0 != 0) // Make q0 correct or
3163 q0 = q0 - 1; // too small by 1.
3164 if ((u - q0*v) >= v)
3165 q0 = q0 + 1; // Now q0 is correct.
3166 return q0;
3167 }
3168
3169
3170 // ----------------------------- divdi3 --------------------------------
3171
3172 /* This routine presumes that smallish cases (those which can be done in
3173 one execution of DIVS) are common. If this is not the case, the test for
3174 this case should be deleted.
3175 Note that the test for when DIVS can be used is not entirely
3176 accurate. For example, DIVS is not used if v = 0xFFFFFFFF8000000,
3177 whereas if could be (if u is sufficiently small in magnitude). */
3178
3179 // ------------------------------ cut ----------------------------------
3180
my_llabs(Long x)3181 static ULong my_llabs ( Long x )
3182 {
3183 ULong t = x >> 63;
3184 return (x ^ t) - t;
3185 }
3186
3187 /* 64 x 64 ==> 64 signed division, using only 32 x 32 ==> 32 division
3188 as a primitive. */
divdi3(Long u,Long v)3189 static Long divdi3(Long u, Long v)
3190 {
3191 ULong au, av;
3192 Long q, t;
3193 au = my_llabs(u);
3194 av = my_llabs(v);
3195 if (av >> 31 == 0) { // If |v| < 2**31 and
3196 // if (v << 32 >> 32 == v) { // If v is in range and
3197 if (au < av << 31) { // |u|/|v| cannot
3198 q = DIVS(u, v); // overflow, use DIVS.
3199 return (q << 32) >> 32;
3200 }
3201 }
3202 q = udivdi3(au,av); // Invoke udivdi3.
3203 t = (u ^ v) >> 63; // If u, v have different
3204 return (q ^ t) - t; // signs, negate q.
3205 }
3206
3207 // ---------------------------- end cut --------------------------------
3208
3209 ULong __udivdi3 (ULong u, ULong v);
__udivdi3(ULong u,ULong v)3210 ULong __udivdi3 (ULong u, ULong v)
3211 {
3212 return udivdi3(u,v);
3213 }
3214
3215 Long __divdi3 (Long u, Long v);
__divdi3(Long u,Long v)3216 Long __divdi3 (Long u, Long v)
3217 {
3218 return divdi3(u,v);
3219 }
3220
3221 ULong __umoddi3 (ULong u, ULong v);
__umoddi3(ULong u,ULong v)3222 ULong __umoddi3 (ULong u, ULong v)
3223 {
3224 ULong q = __udivdi3(u, v);
3225 ULong r = u - q * v;
3226 return r;
3227 }
3228
3229 Long __moddi3 (Long u, Long v);
__moddi3(Long u,Long v)3230 Long __moddi3 (Long u, Long v)
3231 {
3232 Long q = __divdi3(u, v);
3233 Long r = u - q * v;
3234 return r;
3235 }
3236
3237 /* ------------------------------------------------
3238 ld_classic: Undefined symbols:
3239 ___fixunsdfdi
3240 ------------------------------------------------
3241 */
3242
3243 /* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------===
3244 *
3245 * The LLVM Compiler Infrastructure
3246 *
3247 * This file is dual licensed under the MIT and the University of Illinois Open
3248 * Source Licenses. See LICENSE.TXT for details.
3249 *
3250 * ===----------------------------------------------------------------------===
3251 *
3252 * This file implements __fixunsdfdi for the compiler_rt library.
3253 *
3254 * ===----------------------------------------------------------------------===
3255 */
3256
3257 /* As per http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses,
3258
3259 the "NCSA/University of Illinois Open Source License" is compatible
3260 with the GPL (both version 2 and 3). What is claimed to be
3261 compatible is this
3262
3263 http://www.opensource.org/licenses/UoI-NCSA.php
3264
3265 and the LLVM documentation at
3266
3267 http://www.llvm.org/docs/DeveloperPolicy.html#license
3268
3269 says all the code in LLVM is available under the University of
3270 Illinois/NCSA Open Source License, at this URL
3271
3272 http://www.opensource.org/licenses/UoI-NCSA.php
3273
3274 viz, the same one that the FSF pages claim is compatible. So I
3275 think it's OK to include it.
3276 */
3277
3278 /* Returns: convert a to a unsigned long long, rounding toward zero.
3279 * Negative values all become zero.
3280 */
3281
3282 /* Assumption: double is a IEEE 64 bit floating point type
3283 * du_int is a 64 bit integral type
3284 * value in double is representable in du_int or is negative
3285 * (no range checking performed)
3286 */
3287
3288 /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
3289
3290 typedef unsigned long long du_int;
3291 typedef unsigned su_int;
3292
3293 typedef union
3294 {
3295 du_int all;
3296 struct
3297 {
3298 #if VG_LITTLEENDIAN
3299 su_int low;
3300 su_int high;
3301 #else
3302 su_int high;
3303 su_int low;
3304 #endif /* VG_LITTLEENDIAN */
3305 }s;
3306 } udwords;
3307
3308 typedef union
3309 {
3310 udwords u;
3311 double f;
3312 } double_bits;
3313
3314 du_int __fixunsdfdi(double a);
3315
3316 du_int
__fixunsdfdi(double a)3317 __fixunsdfdi(double a)
3318 {
3319 double_bits fb;
3320 fb.f = a;
3321 int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
3322 if (e < 0 || (fb.u.s.high & 0x80000000))
3323 return 0;
3324 udwords r;
3325 r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
3326 r.s.low = fb.u.s.low;
3327 if (e > 52)
3328 r.all <<= (e - 52);
3329 else
3330 r.all >>= (52 - e);
3331 return r.all;
3332 }
3333
3334
3335 #endif
3336
3337
3338 /*--------------------------------------------------------------------*/
3339 /*--- end ---*/
3340 /*--------------------------------------------------------------------*/
3341