2 /*--------------------------------------------------------------------*/
3 /*--- Startup: the real stuff m_main.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2017 Julian Seward
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.
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.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #include "vgversion.h"
30 #include "pub_core_basics.h"
31 #include "pub_core_vki.h"
32 #include "pub_core_threadstate.h"
33 #include "pub_core_xarray.h"
34 #include "pub_core_clientstate.h"
35 #include "pub_core_aspacemgr.h"
36 #include "pub_core_aspacehl.h"
37 #include "pub_core_clreq.h"
38 #include "pub_core_commandline.h"
39 #include "pub_core_debuglog.h"
40 #include "pub_core_errormgr.h"
41 #include "pub_core_execontext.h"
42 #include "pub_core_gdbserver.h"
43 #include "pub_core_initimg.h"
44 #include "pub_core_libcbase.h"
45 #include "pub_core_libcassert.h"
46 #include "pub_core_libcfile.h"
47 #include "pub_core_libcprint.h"
48 #include "pub_core_libcproc.h"
49 #include "pub_core_libcsignal.h"
50 #include "pub_core_sbprofile.h"
51 #include "pub_core_mach.h"
52 #include "pub_core_machine.h"
53 #include "pub_core_mallocfree.h"
54 #include "pub_core_options.h"
55 #include "pub_core_debuginfo.h"
56 #include "pub_core_redir.h"
57 #include "pub_core_scheduler.h"
58 #include "pub_core_seqmatch.h" // For VG_(string_match)
59 #include "pub_core_signals.h"
60 #include "pub_core_stacks.h" // For VG_(register_stack)
61 #include "pub_core_syswrap.h"
62 #include "pub_core_tooliface.h"
63 #include "pub_core_translate.h" // For VG_(translate)
64 #include "pub_core_trampoline.h"
65 #include "pub_core_transtab.h"
66 #include "pub_core_inner.h"
67 #if defined(ENABLE_INNER_CLIENT_REQUEST)
68 #include "pub_core_clreq.h"
72 /*====================================================================*/
73 /*=== Command-line: variables, processing, etc ===*/
74 /*====================================================================*/
76 // See pub_{core,tool}_options.h for explanations of all these.
78 // need_help: 0 = no, 1 = --help-dyn-options, 2 = --help 3 = --help-debug
79 static void usage_NORETURN ( int need_help
)
81 /* 'usage1' contains a %s
82 - for the name of the GDB executable
83 - for the name of vgdb's path prefix
84 which must be supplied when they are VG_(printf)'d. */
85 const HChar usage1
[] =
86 "usage: valgrind [options] prog-and-args\n"
88 " tool-selection option, with default in [ ]:\n"
89 " --tool=<name> use the Valgrind tool named <name> [memcheck]\n"
90 " available tools are:\n"
91 " memcheck cachegrind callgrind helgrind drd\n"
92 " massif dhat lackey none exp-bbv\n"
94 " basic user options for all Valgrind tools, with defaults in [ ]:\n"
95 " -h --help show this message\n"
96 " --help-debug show this message, plus debugging options\n"
97 " --help-dyn-options show the dynamically changeable options\n"
98 " --version show version\n"
99 " -q --quiet run silently; only print error msgs\n"
100 " -v --verbose be more verbose -- show misc extra info\n"
101 " --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]\n"
102 " --trace-children-skip=patt1,patt2,... specifies a list of executables\n"
103 " that --trace-children=yes should not trace into\n"
104 " --trace-children-skip-by-arg=patt1,patt2,... same as --trace-children-skip=\n"
105 " but check the argv[] entries for children, rather\n"
106 " than the exe name, to make a follow/no-follow decision\n"
107 " --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n"
108 " --vgdb=no|yes|full activate gdbserver? [yes]\n"
109 " full is slower but provides precise watchpoint/step\n"
110 " --vgdb-error=<number> invoke gdbserver after <number> errors [%d]\n"
111 " to get started quickly, use --vgdb-error=0\n"
112 " and follow the on-screen directions\n"
113 " --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none]\n"
114 " where event is one of:\n"
115 " startup exit abexit valgrindabexit all none\n"
116 " --track-fds=no|yes|all track open file descriptors? [no]\n"
117 " all includes reporting stdin, stdout and stderr\n"
118 " --time-stamp=no|yes add timestamps to log messages? [no]\n"
119 " --log-fd=<number> log messages to file descriptor [2=stderr]\n"
120 " --log-file=<file> log messages to <file>\n"
121 " --log-socket=ipaddr:port log messages to socket ipaddr:port\n"
122 #if defined(VGO_linux)
123 " --enable-debuginfod=no|yes query debuginfod servers for missing\n"
127 " user options for Valgrind tools that report errors:\n"
128 " --xml=yes emit error output in XML (some tools only)\n"
129 " --xml-fd=<number> XML output to file descriptor\n"
130 " --xml-file=<file> XML output to <file>\n"
131 " --xml-socket=ipaddr:port XML output to socket ipaddr:port\n"
132 " --xml-user-comment=STR copy STR verbatim into XML output\n"
133 " --demangle=no|yes automatically demangle decorated names? [yes]\n"
134 " supported languages: C++, D, Rust, Java, Ada\n"
135 " --num-callers=<number> show <number> callers in stack traces [12]\n"
136 " --error-limit=no|yes stop showing new errors if too many? [yes]\n"
137 " --exit-on-first-error=no|yes exit code on the first error found? [no]\n"
138 " --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
139 " --error-markers=<begin>,<end> add lines with begin/end markers before/after\n"
140 " each error output in plain text mode [none]\n"
141 " --show-error-list=no|yes|all show detected errors list and\n"
142 " suppression counts at exit [no].\n"
143 " all means to also print suppressed errors.\n"
144 " -s same as --show-error-list=yes\n"
145 " --keep-debuginfo=no|yes Keep symbols etc for unloaded code [no]\n"
146 " This allows saved stack traces (e.g. memory leaks)\n"
147 " to include file/line info for code that has been\n"
148 " dlclose'd (or similar)\n"
149 " --show-below-main=no|yes continue stack traces below main() [no]\n"
150 " --default-suppressions=yes|no\n"
151 " load default suppressions [yes]\n"
152 " --suppressions=<filename> suppress errors described in <filename>\n"
153 " --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
154 " --input-fd=<number> file descriptor for input [0=stdin]\n"
155 " --dsymutil=no|yes run dsymutil on Mac OS X when helpful? [yes]\n"
156 " --max-stackframe=<number> assume stack switch for SP changes larger\n"
157 " than <number> bytes [2000000]\n"
158 " --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
159 " [min(max(current 'ulimit' value,1MB),16MB)]\n"
161 " user options for Valgrind tools that replace malloc:\n"
162 " --alignment=<number> set minimum alignment of heap allocations [%s]\n"
163 " --redzone-size=<number> set minimum size of redzones added before/after\n"
164 " heap blocks (in bytes). [%s]\n"
165 " --xtree-memory=none|allocs|full profile heap memory in an xtree [none]\n"
166 " and produces a report at the end of the execution\n"
167 " none: no profiling, allocs: current allocated\n"
168 " size/blocks, full: profile current and cumulative\n"
169 " allocated size/blocks and freed size/blocks.\n"
170 " --xtree-memory-file=<file> xtree memory report file [xtmemory.kcg.%%p]\n"
171 " --realloc-zero-bytes-frees=yes|no [yes on Linux glibc, no otherwise]\n"
172 " should calls to realloc with a size of 0\n"
173 " free memory and return NULL or\n"
174 " allocate/resize and return non-NULL\n"
176 " uncommon user options for all Valgrind tools:\n"
177 " --fullpath-after= (with nothing after the '=')\n"
178 " show full source paths in call stacks\n"
179 " --fullpath-after=string like --fullpath-after=, but only show the\n"
180 " part of the path after 'string'. Allows removal\n"
181 " of path prefixes. Use this flag multiple times\n"
182 " to specify a set of prefixes to remove.\n"
183 " --extra-debuginfo-path=path absolute path to search for additional\n"
184 " debug symbols, in addition to existing default\n"
185 " well known search paths.\n"
186 " --debuginfo-server=ipaddr:port also query this server\n"
187 " (valgrind-di-server) for debug symbols\n"
188 " --allow-mismatched-debuginfo=no|yes [no]\n"
189 " for the above two flags only, accept debuginfo\n"
190 " objects that don't \"match\" the main object\n"
191 " --smc-check=none|stack|all|all-non-file [all-non-file]\n"
192 " checks for self-modifying code: none, only for\n"
193 " code found in stacks, for all code, or for all\n"
194 " code except that from file-backed mappings\n"
195 " --read-inline-info=yes|no read debug info about inlined function calls\n"
196 " and use it to do better stack traces.\n"
197 " [yes] on Linux/Android/Solaris for the tools\n"
198 " Memcheck/Massif/Helgrind/DRD only.\n"
199 " [no] for all other tools and platforms.\n"
200 " --read-var-info=yes|no read debug info on stack and global variables\n"
201 " and use it to print better error messages in\n"
202 " tools that make use of it (Memcheck, Helgrind,\n"
204 " --vgdb-poll=<number> gdbserver poll max every <number> basic blocks [%d] \n"
205 " --vgdb-shadow-registers=no|yes let gdb see the shadow registers [no]\n"
206 " --vgdb-prefix=<prefix> prefix for vgdb FIFOs [%s]\n"
207 " --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
208 " --run-cxx-freeres=no|yes free up libstdc++ memory at exit on Linux\n"
209 " and Solaris? [yes]\n"
210 " --sim-hints=hint1,hint2,... activate unusual sim behaviours [none] \n"
211 " where hint is one of:\n"
212 " lax-ioctls lax-doors fuse-compatible enable-outer\n"
213 " no-inner-prefix no-nptl-pthread-stackcache fallback-llsc none\n"
214 " --scheduling-quantum=<number> thread-scheduling timeslice in number of\n"
215 " basic blocks [100000]\n"
216 " --fair-sched=no|yes|try schedule threads fairly on multicore systems [no]\n"
217 " --kernel-variant=variant1,variant2,...\n"
218 " handle non-standard kernel variants [none]\n"
219 " where variant is one of:\n"
220 " bproc android-no-hw-tls\n"
221 " android-gpu-sgx5xx android-gpu-adreno3xx none\n"
222 " --merge-recursive-frames=<number> merge frames between identical\n"
223 " program counters in max <number> frames) [0]\n"
224 " --num-transtab-sectors=<number> size of translated code cache [%d]\n"
225 " more sectors may increase performance, but use more memory.\n"
226 " --avg-transtab-entry-size=<number> avg size in bytes of a translated\n"
227 " basic block [0, meaning use tool provided default]\n"
228 " --aspace-minaddr=0xPP avoid mapping memory below 0xPP [guessed]\n"
229 " --valgrind-stacksize=<number> size of valgrind (host) thread's stack\n"
231 VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)
233 " --show-emwarns=no|yes show warnings about emulation limits? [no]\n"
234 " --require-text-symbol=:sonamepattern:symbolpattern abort run if the\n"
235 " stated shared object doesn't have the stated\n"
236 " text symbol. Patterns can contain ? and *.\n"
237 " --soname-synonyms=syn1=pattern1,syn2=pattern2,... synonym soname\n"
238 " specify patterns for function wrapping or replacement.\n"
239 " To use a non-libc malloc library that is\n"
240 " in the main exe: --soname-synonyms=somalloc=NONE\n"
241 " in libxyzzy.so: --soname-synonyms=somalloc=libxyzzy.so\n"
242 " --sigill-diagnostics=yes|no warn about illegal instructions? [yes]\n"
243 " --unw-stack-scan-thresh=<number> Enable stack-scan unwind if fewer\n"
244 " than <number> good frames found [0, meaning \"disabled\"]\n"
245 " NOTE: stack scanning is only available on arm-linux.\n"
246 " --unw-stack-scan-frames=<number> Max number of frames that can be\n"
247 " recovered by stack scanning [5]\n"
248 " --resync-filter=no|yes|verbose [yes on MacOS, no on other OSes]\n"
249 " attempt to avoid expensive address-space-resync operations\n"
250 " --max-threads=<number> maximum number of threads that valgrind can\n"
254 const HChar usage2
[] =
256 " debugging options for all Valgrind tools:\n"
257 " -d show verbose debugging output\n"
258 " --stats=no|yes show tool and core statistics [no]\n"
259 " --sanity-level=<number> level of sanity checking to do [1]\n"
260 " 1 - does occasional stack checking\n"
261 " 2 - more stack checks and malloc checks\n"
262 " 3 - as 2 and mmap checks\n"
263 " 4 - as 3 and translation sector checks\n"
264 " --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
265 " --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
266 " --profile-interval=<number> show profile every <number> event checks\n"
267 " [0, meaning only at the end of the run]\n"
268 " --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
269 " --trace-notabove=<number> only show BBs below <number> [0]\n"
270 " --trace-syscalls=no|yes show all system calls? [no]\n"
271 " --trace-signals=no|yes show signal handling details? [no]\n"
272 " --trace-symtab=no|yes show symbol table details? [no]\n"
273 " --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
274 " --trace-cfi=no|yes show call-frame-info details? [no]\n"
275 " --debug-dump=syms mimic /usr/bin/readelf --syms\n"
276 " --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
277 " --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
278 " --trace-redir=no|yes show redirection details? [no]\n"
279 " --trace-sched=no|yes show thread scheduler details? [no]\n"
280 " --profile-heap=no|yes profile Valgrind's own space use\n"
281 " --core-redzone-size=<number> set minimum size of redzones added before/after\n"
282 " heap blocks allocated for Valgrind internal use (in bytes) [4]\n"
283 " --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
284 " --sym-offsets=yes|no show syms in form 'name+offset'? [no]\n"
285 " --progress-interval=<number> report progress every <number>\n"
286 " CPU seconds [0, meaning disabled]\n"
287 " --command-line-only=no|yes only use command line options [no]\n\n"
288 " Vex options for all Valgrind tools:\n"
289 " --vex-iropt-verbosity=<0..9> [0]\n"
290 " --vex-iropt-level=<0..2> [2]\n"
291 " --vex-iropt-unroll-thresh=<0..400> [120]\n"
292 " --vex-guest-max-insns=<1..100> [50]\n"
293 " --vex-guest-chase=no|yes [yes]\n"
294 " Precise exception control. Possible values for 'mode' are as follows\n"
295 " and specify the minimum set of registers guaranteed to be correct\n"
296 " immediately prior to memory access instructions:\n"
297 " sp-at-mem-access stack pointer only\n"
298 " unwindregs-at-mem-access registers needed for stack unwinding\n"
299 " allregs-at-mem-access all registers\n"
300 " allregs-at-each-insn all registers are always correct\n"
301 " Default value for all 3 following flags is [unwindregs-at-mem-access].\n"
302 " --vex-iropt-register-updates=mode setting to use by default\n"
303 " --px-default=mode synonym for --vex-iropt-register-updates\n"
304 " --px-file-backed=mode optional setting for file-backed (non-JIT) code\n"
305 " Tracing and profile control:\n"
306 " --trace-flags and --profile-flags values (omit the middle space):\n"
307 " 1000 0000 show conversion into IR\n"
308 " 0100 0000 show after initial opt\n"
309 " 0010 0000 show after instrumentation\n"
310 " 0001 0000 show after second opt\n"
311 " 0000 1000 show after tree building\n"
312 " 0000 0100 show selecting insns\n"
313 " 0000 0010 show after reg-alloc\n"
314 " 0000 0001 show final assembly\n"
315 " 0000 0000 show summary profile only\n"
316 " (Nb: you need --trace-notbelow and/or --trace-notabove\n"
317 " with --trace-flags for full details)\n"
318 " --vex-regalloc-version=2|3 [3]\n"
320 " debugging options for Valgrind tools that report errors\n"
321 " --dump-error=<number> show translation for basic block associated\n"
322 " with <number>'th error context [0=show none]\n"
324 " debugging options for Valgrind tools that replace malloc:\n"
325 " --trace-malloc=no|yes show client malloc details? [no]\n"
326 " --xtree-compress-strings=no|yes compress strings in xtree callgrind format [yes]\n"
329 const HChar usage3
[] =
331 " Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
334 " Valgrind is Copyright (C) 2000-2024, and GNU GPL'd, by Julian Seward et al.\n"
335 " LibVEX is Copyright (C) 2004-2024, and GNU GPL'd, by OpenWorks LLP et al.\n"
337 " Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
340 const HChar dyn_usage
[] =
341 "Some command line settings are \"dynamic\", meaning they can be changed\n"
342 "while Valgrind is running, like this:\n"
343 " From the shell, using vgdb. Example:\n"
344 " $ vgdb \"v.clo --trace-children=yes --child-silent-after-fork=no\"\n"
345 " From a gdb attached to the valgrind gdbserver. Example:\n"
346 " (gdb) monitor v.clo --trace-children=yes --child-silent-after-fork=no\"\n"
347 " From your program, using a client request. Example:\n"
348 " #include <valgrind/valgrind.h>\n"
349 " VALGRIND_CLO_CHANGE(\"--trace-children=yes\");\n"
350 " VALGRIND_CLO_CHANGE(\"--child-silent-after-fork=no\");\n\n";
353 HChar default_alignment
[30]; // large enough
354 HChar default_redzone_size
[30]; // large enough
356 // Ensure the message goes to stdout
357 VG_(log_output_sink
).fd
= 1;
358 VG_(log_output_sink
).type
= VgLogTo_Fd
;
360 if (VG_(needs
).malloc_replacement
) {
361 VG_(sprintf
)(default_alignment
, "%d", VG_MIN_MALLOC_SZB
);
362 VG_(sprintf
)(default_redzone_size
, "%lu", VG_(tdict
).tool_client_redzone_szB
);
364 VG_(strcpy
)(default_alignment
, "not used by this tool");
365 VG_(strcpy
)(default_redzone_size
, "not used by this tool");
368 /* 'usage1' a type as described after each arg. */
370 VG_(clo_vgdb_error
) /* int */,
371 default_alignment
/* char* */,
372 default_redzone_size
/* char* */,
373 VG_(clo_vgdb_poll
) /* int */,
374 VG_(vgdb_prefix_default
)() /* char* */,
375 N_SECTORS_DEFAULT
/* int */,
376 MAX_THREADS_DEFAULT
/* int */
378 if (need_help
> 1 && VG_(details
).name
) {
379 VG_(printf
)(" user options for %s:\n", VG_(details
).name
);
380 if (VG_(needs
).command_line_options
)
381 VG_TDICT_CALL(tool_print_usage
);
383 VG_(printf
)(" (none)\n");
385 if (need_help
== 1) {
386 VG_(printf
)(dyn_usage
);
387 VG_(list_dynamic_options
) ();
388 VG_(printf
)("valgrind: Use --help for more information.\n");
392 VG_(printf
)("%s", usage2
);
394 if (VG_(details
).name
) {
395 VG_(printf
)(" debugging options for %s:\n", VG_(details
).name
);
397 if (VG_(needs
).command_line_options
)
398 VG_TDICT_CALL(tool_print_debug_usage
);
400 VG_(printf
)(" (none)\n");
404 VG_(printf
)(usage3
, VG_(details
).name
, VG_(details
).copyright_author
,
410 struct process_option_state
{
411 /* Whether the user has asked for --version/--help. */
415 /* Whether the user has explicitly provided --sigill-diagnostics
416 or --show-error-list.
417 If not explicitly given depends on general verbosity setting. */
418 Bool sigill_diag_set
;
419 Bool show_error_list_set
;
421 /* Log to stderr by default, but usage message goes to stdout. XML
422 output is initially disabled. */
423 VgLogTo log_to
; // Where is logging output to be sent?
424 VgLogTo xml_to
; // Where is XML output to be sent?
429 static void process_option (Clo_Mode mode
,
430 HChar
*arg
, struct process_option_state
*pos
)
432 const HChar
* tmp_str
; // Used in a couple of places.
433 Int toolname_len
= VG_(strlen
)(VG_(clo_toolname
));
437 /* Constants for parsing PX control flags. */
438 const HChar
* pxStrings
[5]
439 = { "sp-at-mem-access", "unwindregs-at-mem-access",
440 "allregs-at-mem-access", "allregs-at-each-insn", NULL
};
441 const VexRegisterUpdates pxVals
[5]
442 = { VexRegUpdSpAtMemAccess
, VexRegUpdUnwindregsAtMemAccess
,
443 VexRegUpdAllregsAtMemAccess
, VexRegUpdAllregsAtEachInsn
, 0/*inval*/ };
445 VG_(set_Clo_Mode
) (mode
);
447 // Look for a colon in the option name.
448 while (*colon
&& *colon
!= ':' && *colon
!= '=')
451 // Does it have the form "--toolname:foo"? We have to do it at the start
452 // in case someone has combined a prefix with a core-specific option,
453 // eg. "--memcheck:verbose".
455 if (VG_STREQN(2, arg
, "--") &&
456 VG_STREQN(toolname_len
, arg
+2, VG_(clo_toolname
)) &&
457 VG_STREQN(1, arg
+2+toolname_len
, ":")) {
458 // Prefix matches, convert "--toolname:foo" to "--foo".
459 // Two things to note:
460 // - We cannot modify the option in-place. If we did, and then
461 // a child was spawned with --trace-children=yes, the
462 // now-non-prefixed option would be passed and could screw up
464 // - We create copies, and never free them. Why? Non-prefixed
465 // options hang around forever, so tools need not make copies
466 // of strings within them. We need to have the same behaviour
467 // for prefixed options. The pointer to the copy will be lost
468 // once we leave this function (although a tool may keep a
469 // pointer into it), but the space wasted is insignificant.
470 // (In bug #142197, the copies were being freed, which caused
471 // problems for tools that reasonably assumed that arguments
472 // wouldn't disappear on them.)
474 VG_(printf
)("tool-specific arg: %s\n", arg
);
475 arg
= VG_(strdup
)("main.mpclo.1", arg
+ toolname_len
+ 1);
480 // prefix doesn't match, declare it as recognised and skip this arg
481 VG_(set_Clo_Recognised
) ();
486 if VG_XACT_CLOM(cloE
, arg
, "--version", pos
->need_version
, 1) {}
487 else if (VG_STREQ_CLOM(cloED
, arg
, "-v") ||
488 VG_STREQ_CLOM(cloED
, arg
, "--verbose"))
489 VG_(clo_verbosity
)++;
490 else if (VG_STREQ_CLOM(cloED
, arg
, "-q") ||
491 VG_STREQ_CLOM(cloED
, arg
, "--quiet"))
492 VG_(clo_verbosity
)--;
493 else if VG_XACT_CLOM(cloE
, arg
, "--help-dyn-options", pos
->need_help
, 1) {}
494 else if VG_XACT_CLOM(cloE
, arg
, "-h", pos
->need_help
, 2) {}
495 else if VG_XACT_CLOM(cloE
, arg
, "--help", pos
->need_help
, 2) {}
496 else if VG_XACT_CLOM(cloE
, arg
, "--help-debug", pos
->need_help
, 3) {}
498 // The tool has already been determined, but we need to know the name
500 else if VG_STR_CLOM(cloE
, arg
, "--tool", VG_(clo_toolname
)) {}
502 // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
503 // These are needed by VG_(ii_create_image), which happens
504 // before main_process_cmd_line_options().
505 else if VG_INT_CLOM(cloE
, arg
, "--max-stackframe", VG_(clo_max_stackframe
)) {}
506 else if VG_INT_CLOM(cloE
, arg
, "--main-stacksize", VG_(clo_main_stacksize
)) {}
508 // Set up VG_(clo_max_threads); needed for VG_(tl_pre_clo_init)
509 else if VG_INT_CLOM(cloE
, arg
, "--max-threads", VG_(clo_max_threads
)) {}
511 // Set up VG_(clo_sim_hints). This is needed a.o. for an inner
512 // running in an outer, to have "no-inner-prefix" enabled
513 // as early as possible.
514 else if VG_USETX_CLOM (cloE
, arg
, "--sim-hints",
515 "lax-ioctls,lax-doors,fuse-compatible,"
516 "enable-outer,no-inner-prefix,"
517 "no-nptl-pthread-stackcache,fallback-llsc",
518 VG_(clo_sim_hints
)) {}
520 else if VG_STREQN_CLOM(0, 20, arg
, "--command-line-only=") {} // m_commandline.c
521 else if VG_STREQ(arg
, "--") {}
522 else if VG_STREQ_CLOM(cloD
, arg
, "-d") // pre-early + Dynamic
523 VG_(debugLog_startup
) (VG_(debugLog_getLevel
)() + 1,
524 "dynamic option change");
525 else if VG_STREQN_CLOM(0, 15, arg
, "--profile-heap=") {} // pre-early
526 else if VG_STREQN_CLOM(0, 20, arg
, "--core-redzone-size=") {} // pre-early
527 else if VG_STREQN_CLOM(0, 15, arg
, "--redzone-size=") {} // pre-early
528 else if VG_STREQN_CLOM(0, 17, arg
, "--aspace-minaddr=") {} // pre-early
530 else if VG_BINT_CLOM(cloE
, arg
, "--valgrind-stacksize",
531 VG_(clo_valgrind_stacksize
),
532 2*VKI_PAGE_SIZE
, 10*VG_DEFAULT_STACK_ACTIVE_SZB
)
533 VG_(clo_valgrind_stacksize
) = VG_PGROUNDUP(VG_(clo_valgrind_stacksize
));
535 /* Obsolete options. Report an error and exit */
536 else if VG_STREQN(34, arg
, "--vex-iropt-precise-memory-exns=no") {
539 "--vex-iropt-precise-memory-exns is obsolete\n"
540 "Use --vex-iropt-register-updates=unwindregs-at-mem-access instead\n");
542 else if VG_STREQN(35, arg
, "--vex-iropt-precise-memory-exns=yes") {
545 "--vex-iropt-precise-memory-exns is obsolete\n"
546 "Use --vex-iropt-register-updates=allregs-at-mem-access instead\n"
547 " (or --vex-iropt-register-updates=allregs-at-each-insn)\n");
550 /* These options are new, not yet handled by
551 early_process_cmd_line_options. */
552 else if VG_BOOL_CLO(arg
, "--sigill-diagnostics", VG_(clo_sigill_diag
))
553 pos
->sigill_diag_set
= True
;
555 else if VG_BOOL_CLOM(cloPD
, arg
, "--stats", VG_(clo_stats
)) {}
556 else if VG_BOOL_CLO(arg
, "--xml", VG_(clo_xml
))
557 VG_(debugLog_setXml
)(VG_(clo_xml
));
559 else if VG_XACT_CLOM(cloPD
, arg
, "--vgdb=no", VG_(clo_vgdb
), Vg_VgdbNo
) {}
560 else if VG_XACT_CLOM(cloPD
, arg
, "--vgdb=yes", VG_(clo_vgdb
), Vg_VgdbYes
) {}
561 else if VG_XACT_CLOM(cloPD
, arg
, "--vgdb=full", VG_(clo_vgdb
), Vg_VgdbFull
) {
562 /* automatically updates register values at each insn
564 VG_(clo_vex_control
).iropt_register_updates_default
565 = VG_(clo_px_file_backed
)
566 = VexRegUpdAllregsAtEachInsn
;
568 else if VG_INT_CLOM (cloPD
, arg
, "--vgdb-poll", VG_(clo_vgdb_poll
)) {}
569 else if VG_INT_CLOM (cloPD
, arg
, "--vgdb-error", VG_(clo_vgdb_error
)) {}
570 /* --launched-with-multi is an internal option used by vgdb to suppress
571 some output that valgrind normally shows when using --vgdb-error. */
572 else if VG_BOOL_CLO (arg
, "--launched-with-multi",
573 VG_(clo_launched_with_multi
)) {}
574 else if VG_USET_CLOM (cloPD
, arg
, "--vgdb-stop-at",
575 "startup,exit,abexit,valgrindabexit",
576 VG_(clo_vgdb_stop_at
)) {}
577 else if VG_STR_CLO (arg
, "--vgdb-prefix", VG_(clo_vgdb_prefix
)) {
578 VG_(arg_vgdb_prefix
) = arg
;
580 else if VG_BOOL_CLO(arg
, "--vgdb-shadow-registers",
581 VG_(clo_vgdb_shadow_registers
)) {}
582 else if VG_BOOL_CLO(arg
, "--demangle", VG_(clo_demangle
)) {}
583 else if VG_STR_CLO (arg
, "--soname-synonyms",VG_(clo_soname_synonyms
)) {}
584 else if VG_BOOL_CLO(arg
, "--error-limit", VG_(clo_error_limit
)) {}
585 else if VG_BOOL_CLO(arg
, "--exit-on-first-error", VG_(clo_exit_on_first_error
)) {}
586 else if VG_INT_CLO (arg
, "--error-exitcode", VG_(clo_error_exitcode
)) {}
587 else if VG_STR_CLOM (cloPD
, arg
, "--error-markers", tmp_str
) {
589 const HChar
*startpos
= tmp_str
;
590 const HChar
*nextpos
;
592 VG_(Clo_Mode
)() != cloE
593 && m
< sizeof(VG_(clo_error_markers
))
594 /sizeof(VG_(clo_error_markers
)[0]);
596 /* Release previous value if clo given multiple times. */
597 VG_(free
)(VG_(clo_error_markers
)[m
]);
598 VG_(clo_error_markers
)[m
] = NULL
;
600 nextpos
= VG_(strchr
)(startpos
, ',');
602 nextpos
= startpos
+ VG_(strlen
)(startpos
);
603 if (startpos
!= nextpos
) {
604 VG_(clo_error_markers
)[m
]
605 = VG_(malloc
)("main.mpclo.2", nextpos
- startpos
+ 1);
606 VG_(memcpy
)(VG_(clo_error_markers
)[m
], startpos
,
608 VG_(clo_error_markers
)[m
][nextpos
- startpos
] = '\0';
610 startpos
= *nextpos
? nextpos
+ 1 : nextpos
;
613 else if VG_STR_CLOM(cloPD
, arg
, "--show-error-list", tmp_str
) {
614 if (VG_(strcmp
)(tmp_str
, "yes") == 0)
615 VG_(clo_show_error_list
) = 1;
616 else if (VG_(strcmp
)(tmp_str
, "all") == 0)
617 VG_(clo_show_error_list
) = 2;
618 else if (VG_(strcmp
)(tmp_str
, "no") == 0)
619 VG_(clo_show_error_list
) = 0;
621 VG_(fmsg_bad_option
)(arg
,
622 "Bad argument, should be 'yes', 'all' or 'no'\n");
623 pos
->show_error_list_set
= True
; }
624 else if (VG_STREQ_CLOM(cloPD
, arg
, "-s")) {
625 VG_(clo_show_error_list
) = 1;
626 pos
->show_error_list_set
= True
;
628 else if VG_BOOL_CLO(arg
, "--show-emwarns", VG_(clo_show_emwarns
)) {}
630 else if VG_BOOL_CLO(arg
, "--run-libc-freeres", VG_(clo_run_libc_freeres
)) {}
631 else if VG_BOOL_CLO(arg
, "--run-cxx-freeres", VG_(clo_run_cxx_freeres
)) {}
632 else if VG_BOOL_CLOM(cloPD
, arg
, "--show-below-main", VG_(clo_show_below_main
)) {}
633 else if VG_BOOL_CLO(arg
, "--keep-debuginfo", VG_(clo_keep_debuginfo
)) {}
634 #if defined(VGO_linux)
635 else if VG_BOOL_CLO(arg
, "--enable-debuginfod", VG_(clo_enable_debuginfod
)) {}
637 else if VG_BOOL_CLOM(cloPD
, arg
, "--time-stamp", VG_(clo_time_stamp
)) {}
638 else if VG_STR_CLO(arg
, "--track-fds", tmp_str
) {
639 if (VG_(strcmp
)(tmp_str
, "yes") == 0)
640 VG_(clo_track_fds
) = 1;
641 else if (VG_(strcmp
)(tmp_str
, "all") == 0)
642 VG_(clo_track_fds
) = 2;
643 else if (VG_(strcmp
)(tmp_str
, "no") == 0)
644 VG_(clo_track_fds
) = 0;
646 VG_(fmsg_bad_option
)(arg
,
647 "Bad argument, should be 'yes', 'all' or 'no'\n");
649 else if VG_BOOL_CLOM(cloPD
, arg
, "--trace-children", VG_(clo_trace_children
)) {}
650 else if VG_BOOL_CLOM(cloPD
, arg
, "--child-silent-after-fork",
651 VG_(clo_child_silent_after_fork
)) {}
652 else if VG_INT_CLOM(cloPD
, arg
, "--scheduling-quantum",
653 VG_(clo_scheduling_quantum
)) {}
654 else if VG_STR_CLO(arg
, "--fair-sched", tmp_str
) {
655 if (VG_(Clo_Mode
)() != cloP
)
657 else if (VG_(strcmp
)(tmp_str
, "yes") == 0)
658 VG_(clo_fair_sched
) = enable_fair_sched
;
659 else if (VG_(strcmp
)(tmp_str
, "try") == 0)
660 VG_(clo_fair_sched
) = try_fair_sched
;
661 else if (VG_(strcmp
)(tmp_str
, "no") == 0)
662 VG_(clo_fair_sched
) = disable_fair_sched
;
664 VG_(fmsg_bad_option
)(arg
,
665 "Bad argument, should be 'yes', 'try' or 'no'\n");
667 else if VG_BOOL_CLOM(cloPD
, arg
, "--trace-sched", VG_(clo_trace_sched
)) {}
668 else if VG_BOOL_CLOM(cloPD
, arg
, "--trace-signals", VG_(clo_trace_signals
)) {}
669 else if VG_BOOL_CLOM(cloPD
, arg
, "--trace-symtab", VG_(clo_trace_symtab
)) {}
670 else if VG_STR_CLO (arg
, "--trace-symtab-patt", VG_(clo_trace_symtab_patt
)) {}
671 else if VG_BOOL_CLOM(cloPD
, arg
, "--trace-cfi", VG_(clo_trace_cfi
)) {}
672 else if VG_XACT_CLOM(cloPD
, arg
, "--debug-dump=syms", VG_(clo_debug_dump_syms
),
674 else if VG_XACT_CLOM(cloPD
, arg
, "--debug-dump=line", VG_(clo_debug_dump_line
),
676 else if VG_XACT_CLOM(cloPD
, arg
, "--debug-dump=frames",
677 VG_(clo_debug_dump_frames
), True
) {}
678 else if VG_BOOL_CLOM(cloPD
, arg
, "--trace-redir", VG_(clo_trace_redir
)) {}
680 else if VG_BOOL_CLOM(cloPD
, arg
, "--trace-syscalls", VG_(clo_trace_syscalls
)) {}
681 else if VG_BOOL_CLOM(cloE
, arg
, "--wait-for-gdb", VG_(clo_wait_for_gdb
)) {
682 //--------------------------------------------------------------
685 //--------------------------------------------------------------
686 /* Hook to delay things long enough so we can get the pid and
687 attach GDB in another shell. */
688 if (VG_(clo_wait_for_gdb
)) {
689 const int ms
= 8000; // milliseconds
690 VG_(debugLog
)(1, "main", "Wait for GDB during %d ms\n", ms
);
691 VG_(printf
)("pid=%d, entering delay %d ms loop\n", VG_(getpid
)(), ms
);
692 VG_(poll
)(NULL
, 0, ms
);
696 else if VG_BOOL_CLOM(cloPD
, arg
, "--sym-offsets", VG_(clo_sym_offsets
)) {}
697 else if VG_BUINT_CLOM(cloPD
, arg
, "--progress-interval",
698 VG_(clo_progress_interval
), 3600) {}
699 else if VG_BOOL_CLO(arg
, "--read-inline-info", VG_(clo_read_inline_info
)) {}
700 else if VG_BOOL_CLO(arg
, "--read-var-info", VG_(clo_read_var_info
)) {}
702 else if VG_INT_CLO (arg
, "--dump-error", VG_(clo_dump_error
)) {}
703 else if VG_INT_CLO (arg
, "--input-fd", VG_(clo_input_fd
)) {}
704 else if VG_INT_CLO (arg
, "--sanity-level", VG_(clo_sanity_level
)) {}
705 else if VG_BINT_CLO(arg
, "--num-callers", VG_(clo_backtrace_size
), 1,
706 VG_DEEPEST_BACKTRACE
) {}
707 else if VG_BINT_CLO(arg
, "--num-transtab-sectors",
708 VG_(clo_num_transtab_sectors
),
709 MIN_N_SECTORS
, MAX_N_SECTORS
) {}
710 else if VG_BINT_CLO(arg
, "--avg-transtab-entry-size",
711 VG_(clo_avg_transtab_entry_size
),
713 else if VG_BINT_CLOM(cloPD
, arg
, "--merge-recursive-frames",
714 VG_(clo_merge_recursive_frames
), 0,
715 VG_DEEPEST_BACKTRACE
) {}
717 else if VG_XACT_CLO(arg
, "--smc-check=none",
718 VG_(clo_smc_check
), Vg_SmcNone
) {}
719 else if VG_XACT_CLO(arg
, "--smc-check=stack",
720 VG_(clo_smc_check
), Vg_SmcStack
) {}
721 else if VG_XACT_CLO(arg
, "--smc-check=all",
722 VG_(clo_smc_check
), Vg_SmcAll
) {}
723 else if VG_XACT_CLO(arg
, "--smc-check=all-non-file",
724 VG_(clo_smc_check
), Vg_SmcAllNonFile
) {}
726 else if VG_USETX_CLO (arg
, "--kernel-variant",
729 "android-gpu-sgx5xx,"
730 "android-gpu-adreno3xx",
731 VG_(clo_kernel_variant
)) {}
733 else if VG_BOOL_CLO(arg
, "--dsymutil", VG_(clo_dsymutil
)) {}
735 else if VG_STR_CLO (arg
, "--trace-children-skip",
736 VG_(clo_trace_children_skip
)) {}
737 else if VG_STR_CLO (arg
, "--trace-children-skip-by-arg",
738 VG_(clo_trace_children_skip_by_arg
)) {}
740 else if VG_BINT_CLOM(cloPD
, arg
, "--vex-iropt-verbosity",
741 VG_(clo_vex_control
).iropt_verbosity
, 0, 10) {}
742 else if VG_BINT_CLO(arg
, "--vex-iropt-level",
743 VG_(clo_vex_control
).iropt_level
, 0, 2) {}
744 else if VG_BINT_CLO(arg
, "--vex-regalloc-version",
745 VG_(clo_vex_control
).regalloc_version
, 2, 3) {}
747 else if (VG_STRINDEX_CLO(arg
, "--vex-iropt-register-updates",
749 || VG_STRINDEX_CLO(arg
, "--px-default", pxStrings
, ix
))
750 // NB: --px-default is an alias for the hard-to-remember
751 // --vex-iropt-register-updates, hence the same logic.
754 vg_assert(pxVals
[ix
] >= VexRegUpdSpAtMemAccess
);
755 vg_assert(pxVals
[ix
] <= VexRegUpdAllregsAtEachInsn
);
756 VG_(clo_vex_control
).iropt_register_updates_default
= pxVals
[ix
];
759 else if VG_STRINDEX_CLO(arg
, "--px-file-backed", pxStrings
, ix
) {
760 // Whereas --px-file-backed isn't
761 // the same flag as --vex-iropt-register-updates.
763 vg_assert(pxVals
[ix
] >= VexRegUpdSpAtMemAccess
);
764 vg_assert(pxVals
[ix
] <= VexRegUpdAllregsAtEachInsn
);
765 VG_(clo_px_file_backed
) = pxVals
[ix
];
768 else if VG_BINT_CLO(arg
, "--vex-iropt-unroll-thresh",
769 VG_(clo_vex_control
).iropt_unroll_thresh
, 0, 400) {}
770 else if VG_BINT_CLO(arg
, "--vex-guest-max-insns",
771 VG_(clo_vex_control
).guest_max_insns
, 1, 100) {}
772 else if VG_BOOL_CLO(arg
, "--vex-guest-chase",
773 VG_(clo_vex_control
).guest_chase
) {}
775 else if VG_INT_CLO(arg
, "--log-fd", pos
->tmp_log_fd
) {
776 pos
->log_to
= VgLogTo_Fd
;
777 VG_(clo_log_fname_unexpanded
) = NULL
;
779 else if VG_INT_CLO(arg
, "--xml-fd", pos
->tmp_xml_fd
) {
780 pos
->xml_to
= VgLogTo_Fd
;
781 VG_(clo_xml_fname_unexpanded
) = NULL
;
784 else if VG_STR_CLO(arg
, "--log-file", VG_(clo_log_fname_unexpanded
)) {
785 pos
->log_to
= VgLogTo_File
;
787 else if VG_STR_CLO(arg
, "--xml-file", VG_(clo_xml_fname_unexpanded
)) {
788 pos
->xml_to
= VgLogTo_File
;
791 else if VG_STR_CLO(arg
, "--log-socket", VG_(clo_log_fname_unexpanded
)) {
792 pos
->log_to
= VgLogTo_Socket
;
794 else if VG_STR_CLO(arg
, "--xml-socket", VG_(clo_xml_fname_unexpanded
)) {
795 pos
->xml_to
= VgLogTo_Socket
;
798 else if VG_STR_CLO(arg
, "--debuginfo-server",
799 VG_(clo_debuginfo_server
)) {}
801 else if VG_BOOL_CLO(arg
, "--allow-mismatched-debuginfo",
802 VG_(clo_allow_mismatched_debuginfo
)) {}
804 else if VG_STR_CLO(arg
, "--xml-user-comment",
805 VG_(clo_xml_user_comment
)) {}
807 else if VG_BOOL_CLO(arg
, "--default-suppressions",
808 VG_(clo_default_supp
)) {}
810 else if VG_STR_CLOM(cloPD
, arg
, "--suppressions", tmp_str
) {
811 VG_(add_suppression_file
)(tmp_str
);
814 else if VG_STR_CLO (arg
, "--fullpath-after", tmp_str
) {
815 VG_(addToXA
)(VG_(clo_fullpath_after
), &tmp_str
);
818 else if VG_STR_CLO (arg
, "--extra-debuginfo-path",
819 VG_(clo_extra_debuginfo_path
)) {}
821 else if VG_STR_CLO(arg
, "--require-text-symbol", tmp_str
) {
822 /* String needs to be of the form C?*C?*, where C is any
823 character, but is the same both times. Having it in this
824 form facilitates finding the boundary between the sopatt
825 and the fnpatt just by looking for the second occurrence
826 of C, without hardwiring any assumption about what C
830 ok
= tmp_str
&& VG_(strlen
)(tmp_str
) > 0;
832 patt
[0] = patt
[3] = tmp_str
[0];
833 patt
[1] = patt
[4] = '?';
834 patt
[2] = patt
[5] = '*';
836 ok
= VG_(string_match
)(patt
, tmp_str
);
839 VG_(fmsg_bad_option
)(arg
,
840 "Invalid --require-text-symbol= specification.\n");
842 VG_(addToXA
)(VG_(clo_req_tsyms
), &tmp_str
);
845 /* "stuvwxyz" --> stuvwxyz (binary) */
846 else if VG_STR_CLOM(cloPD
, arg
, "--trace-flags", tmp_str
) {
848 if (8 != VG_(strlen
)(tmp_str
)) {
849 VG_(fmsg_bad_option
)(arg
,
850 "--trace-flags argument must have 8 digits\n");
852 for (j
= 0; j
< 8; j
++) {
853 if ('0' == tmp_str
[j
]) { /* do nothing */ }
854 else if ('1' == tmp_str
[j
]) VG_(clo_trace_flags
) |= (1 << (7-j
));
856 VG_(fmsg_bad_option
)(arg
,
857 "--trace-flags argument can only contain 0s and 1s\n");
862 else if VG_INT_CLOM (cloPD
, arg
, "--trace-notbelow", VG_(clo_trace_notbelow
)) {}
864 else if VG_INT_CLOM (cloPD
, arg
, "--trace-notabove", VG_(clo_trace_notabove
)) {}
866 /* "stuvwxyz" --> stuvwxyz (binary) */
867 else if VG_STR_CLOM(cloPD
, arg
, "--profile-flags", tmp_str
) {
869 if (8 != VG_(strlen
)(tmp_str
)) {
870 VG_(fmsg_bad_option
)(arg
,
871 "--profile-flags argument must have 8 digits\n");
873 for (j
= 0; j
< 8; j
++) {
874 if ('0' == tmp_str
[j
]) { /* do nothing */ }
875 else if ('1' == tmp_str
[j
]) VG_(clo_profyle_flags
) |= (1 << (7-j
));
877 VG_(fmsg_bad_option
)(arg
,
878 "--profile-flags argument can only contain 0s and 1s\n");
881 VG_(clo_profyle_sbs
) = True
;
884 else if VG_INT_CLO (arg
, "--profile-interval",
885 VG_(clo_profyle_interval
)) {}
887 else if VG_XACT_CLOM(cloPD
, arg
, "--gen-suppressions=no",
888 VG_(clo_gen_suppressions
), 0) {}
889 else if VG_XACT_CLOM(cloPD
, arg
, "--gen-suppressions=yes",
890 VG_(clo_gen_suppressions
), 1) {}
891 else if VG_XACT_CLOM(cloPD
, arg
, "--gen-suppressions=all",
892 VG_(clo_gen_suppressions
), 2) {}
894 else if VG_BINT_CLO(arg
, "--unw-stack-scan-thresh",
895 VG_(clo_unw_stack_scan_thresh
), 0, 100) {}
896 else if VG_BINT_CLO(arg
, "--unw-stack-scan-frames",
897 VG_(clo_unw_stack_scan_frames
), 0, 32) {}
899 else if VG_XACT_CLO(arg
, "--resync-filter=no",
900 VG_(clo_resync_filter
), 0) {}
901 else if VG_XACT_CLO(arg
, "--resync-filter=yes",
902 VG_(clo_resync_filter
), 1) {}
903 else if VG_XACT_CLO(arg
, "--resync-filter=verbose",
904 VG_(clo_resync_filter
), 2) {}
906 else if ( VG_(Clo_Mode
)() != cloE
// tool does not have Early options
907 && !VG_(Clo_Recognised
) ()
908 && (! VG_(needs
).command_line_options
909 || ! VG_TDICT_CALL(tool_process_cmd_line_option
, arg
) )) {
910 if (VG_(Clo_Mode
)() == cloH
)
912 else if (VG_(Clo_Mode
)() == cloP
&& !VG_(Clo_Recognised
) ())
913 VG_(fmsg_unknown_option
)(arg
);
914 else if (VG_(Clo_Mode
)() == cloD
&& !VG_(Clo_Recognised
) ())
915 VG_(umsg
)("Ignoring dynamic change to unrecognised option %s\n", arg
);
919 void VG_(process_dynamic_option
) (Clo_Mode mode
, HChar
*value
)
921 struct process_option_state dummy
;
922 process_option (mode
, value
, &dummy
);
923 // No need to handle a process_option_state once valgrind has started.
926 /* Peer at previously set up VG_(args_for_valgrind) and do some
927 minimal command line processing that must happen early on:
929 - show the version string, if requested (-v)
930 - extract any request for help (-h --help, --help-dyn-options, --help-debug)
931 - set VG_(toolname) (--tool=)
932 - set VG_(clo_max_stackframe) (--max-stackframe=)
933 - set VG_(clo_main_stacksize) (--main-stacksize=)
934 - set VG_(clo_sim_hints) (--sim-hints=)
935 - set VG_(clo_max_threads) (--max-threads)
937 That's all it does. The main command line processing is done below
938 by main_process_cmd_line_options. Note that
939 main_process_cmd_line_options has to handle but ignore the ones we
942 static void early_process_cmd_line_options ( /*OUT*/Int
* need_help
)
946 struct process_option_state pos
947 = {0, 0, False
, False
, VgLogTo_Fd
, VgLogTo_Fd
, 2, -1};
949 vg_assert( VG_(args_for_valgrind
) );
951 /* parse the options we have (only the options we care about now) */
952 for (i
= 0; i
< VG_(sizeXA
)( VG_(args_for_valgrind
) ); i
++) {
954 str
= * (HChar
**) VG_(indexXA
)( VG_(args_for_valgrind
), i
);
956 process_option (cloE
, str
, &pos
);
959 if (pos
.need_version
) {
960 // Nb: the version string goes to stdout.
961 VG_(log_output_sink
).fd
= 1;
962 VG_(log_output_sink
).type
= VgLogTo_Fd
;
963 if (VG_(clo_verbosity
) <= 1)
964 VG_(printf
)("valgrind-" VERSION
"\n");
966 VG_(printf
)("valgrind-" VERSION
"-" VGGIT
"\n");
970 *need_help
= pos
.need_help
;
972 /* For convenience */
973 VG_N_THREADS
= VG_(clo_max_threads
);
975 # if defined(VGO_solaris) || defined(VGO_darwin)
976 /* Sim hint no-nptl-pthread-stackcache should be ignored. */
977 VG_(clo_sim_hints
) &= ~SimHint2S(SimHint_no_nptl_pthread_stackcache
);
981 /* The main processing for command line options. See comments above
982 on early_process_cmd_line_options. */
984 void main_process_cmd_line_options( void )
987 struct process_option_state pos
988 = {0, 0, False
, False
, VgLogTo_Fd
, VgLogTo_Fd
, 2, -1};
990 /* Check for sane path in ./configure --prefix=... */
991 if (VG_LIBDIR
[0] != '/')
992 VG_(err_config_error
)("Please use absolute paths in "
993 "./configure --prefix=... or --libdir=...\n");
995 vg_assert( VG_(args_for_valgrind
) );
997 VG_(clo_suppressions
) = VG_(newXA
)(VG_(malloc
), "main.mpclo.4",
998 VG_(free
), sizeof(HChar
*));
999 VG_(clo_fullpath_after
) = VG_(newXA
)(VG_(malloc
), "main.mpclo.5",
1000 VG_(free
), sizeof(HChar
*));
1001 VG_(clo_req_tsyms
) = VG_(newXA
)(VG_(malloc
), "main.mpclo.6",
1002 VG_(free
), sizeof(HChar
*));
1004 /* BEGIN command-line processing loop */
1006 for (i
= 0; i
< VG_(sizeXA
)( VG_(args_for_valgrind
) ); i
++) {
1007 HChar
* arg
= * (HChar
**) VG_(indexXA
)( VG_(args_for_valgrind
), i
);
1008 process_option (cloP
, arg
, &pos
);
1011 /* END command-line processing loop. From now on, only dynamically
1012 changeable options will have an effect. */
1013 VG_(set_Clo_Mode
)(cloD
);
1015 /* Notify about deprecated features here. */
1017 /* Determine the path prefix for vgdb */
1018 if (VG_(clo_vgdb_prefix
) == NULL
)
1019 VG_(clo_vgdb_prefix
) = VG_(vgdb_prefix_default
)();
1021 /* Check various option values */
1023 if (VG_(clo_verbosity
) < 0)
1024 VG_(clo_verbosity
) = 0;
1026 if (!pos
.sigill_diag_set
)
1027 VG_(clo_sigill_diag
) = (VG_(clo_verbosity
) > 0);
1029 if (!pos
.show_error_list_set
) {
1031 VG_(clo_show_error_list
) = VG_(clo_verbosity
) >= 1;
1033 VG_(clo_show_error_list
) = VG_(clo_verbosity
) >= 2;
1036 if (VG_(clo_trace_notbelow
) == -1) {
1037 if (VG_(clo_trace_notabove
) == -1) {
1039 VG_(clo_trace_notbelow
) = 2147483647;
1040 VG_(clo_trace_notabove
) = 0;
1042 /* [0 .. notabove] */
1043 VG_(clo_trace_notbelow
) = 0;
1046 if (VG_(clo_trace_notabove
) == -1) {
1047 /* [notbelow .. ] */
1048 VG_(clo_trace_notabove
) = 2147483647;
1050 /* [notbelow .. notabove] */
1054 if (VG_(clo_gen_suppressions
) > 0 &&
1055 !VG_(needs
).core_errors
&& !VG_(needs
).tool_errors
) {
1056 VG_(fmsg_bad_option
)("--gen-suppressions=yes",
1057 "Can't use --gen-suppressions= with %s\n"
1058 "because it doesn't generate errors.\n", VG_(details
).name
);
1060 if ((VG_(clo_exit_on_first_error
)) &&
1061 (VG_(clo_error_exitcode
)==0)) {
1062 VG_(fmsg_bad_option
)("--exit-on-first-error=yes",
1063 "You must define a non nul exit error code, with --error-exitcode=...\n");
1066 # if !defined(VGO_darwin)
1067 if (VG_(clo_resync_filter
) != 0) {
1068 VG_(fmsg_bad_option
)("--resync-filter=yes or =verbose",
1069 "--resync-filter= is only available on MacOS X.\n");
1074 /* If XML output is requested, check that the tool actually
1076 if (VG_(clo_xml
) && !VG_(needs
).xml_output
) {
1077 VG_(clo_xml
) = False
;
1078 VG_(fmsg_bad_option
)("--xml=yes",
1079 "%s does not support XML output.\n", VG_(details
).name
);
1083 vg_assert( VG_(clo_gen_suppressions
) >= 0 );
1084 vg_assert( VG_(clo_gen_suppressions
) <= 2 );
1086 /* If we've been asked to emit XML, mash around various other
1087 options so as to constrain the output somewhat, and to remove
1088 any need for user input during the run.
1092 /* We can't allow --gen-suppressions=yes, since that requires us
1093 to print the error and then ask the user if she wants a
1094 suppression for it, but in XML mode we won't print it until
1095 we know whether we also need to print a suppression. Hence a
1096 circular dependency. So disallow this.
1097 (--gen-suppressions=all is still OK since we don't need any
1098 user interaction in this case.) */
1099 if (VG_(clo_gen_suppressions
) == 1) {
1100 VG_(fmsg_bad_option
)(
1101 "--xml=yes together with --gen-suppressions=yes",
1102 "When --xml=yes is specified, --gen-suppressions=no\n"
1103 "or --gen-suppressions=all is allowed, but not "
1104 "--gen-suppressions=yes.\n");
1107 /* Disallow dump_error in XML mode; sounds like a recipe for
1108 chaos. No big deal; dump_error is a flag for debugging V
1110 if (VG_(clo_dump_error
) > 0) {
1111 VG_(fmsg_bad_option
)("--xml=yes",
1112 "Cannot be used together with --dump-error");
1115 /* Disable error limits (this might be a bad idea!) */
1116 VG_(clo_error_limit
) = False
;
1117 /* Disable emulation warnings */
1119 /* Also, we want to set options for the leak checker, but that
1120 will have to be done in Memcheck's flag-handling code, not
1124 #if defined(VGO_freebsd)
1125 if (VG_(clo_sanity_level
) >= 3) {
1126 VG_(debugLog
)(0, "main", "Warning: due to transparent memory mappings with MAP_STACK\n");
1127 VG_(debugLog
)(0, "main", "--sanity-level=3 and above may give spurious errors.\n");
1131 /* All non-logging-related options have been checked. If the logging
1132 option specified is ok, we can switch to it, as we know we won't
1133 have to generate any other command-line-related error messages.
1134 (So far we should be still attached to stderr, so we can show on
1135 the terminal any problems to do with processing command line
1137 VG_(init_log_xml_sinks
)(pos
.log_to
, pos
.xml_to
,
1138 pos
.tmp_log_fd
, pos
.tmp_xml_fd
);
1140 /* Register child at-fork handler which will take care of handling
1141 --child-silent-after-fork clo and also reopening output sinks for forked
1142 children, if requested via --log|xml-file= options. */
1143 VG_(atfork
)(NULL
, NULL
, VG_(logging_atfork_child
));
1145 // Suppressions related stuff
1147 if (VG_(clo_default_supp
) &&
1148 (VG_(needs
).core_errors
|| VG_(needs
).tool_errors
)) {
1149 /* If loading default is enabled, add it to the supp list. */
1150 static const HChar default_supp
[] = "default.supp";
1151 Int len
= VG_(strlen
)(VG_(libdir
)) + 1 + sizeof(default_supp
);
1152 HChar
*buf
= VG_(malloc
)("main.mpclo.3", len
);
1153 VG_(sprintf
)(buf
, "%s/%s", VG_(libdir
), default_supp
);
1154 VG_(add_suppression_file
)(buf
);
1160 /*====================================================================*/
1161 /*=== File descriptor setup ===*/
1162 /*====================================================================*/
1164 /* Number of file descriptors that Valgrind tries to reserve for
1165 its own use - just a small constant. */
1166 #define N_RESERVED_FDS (12)
1168 static void setup_file_descriptors(void)
1170 struct vki_rlimit rl
;
1173 /* Get the current file descriptor limits. */
1174 if (VG_(getrlimit
)(VKI_RLIMIT_NOFILE
, &rl
) < 0) {
1179 # if defined(VGO_darwin)
1180 /* Darwin lies. It reports file max as RLIM_INFINITY but
1181 silently disallows anything bigger than 10240. */
1182 if (rl
.rlim_cur
>= 10240 && rl
.rlim_max
== 0x7fffffffffffffffULL
) {
1183 rl
.rlim_max
= 10240;
1188 VG_(printf
)("fd limits: host, before: cur %llu max %llu\n",
1189 (ULong
)rl
.rlim_cur
, (ULong
)rl
.rlim_max
);
1191 /* Work out where to move the soft limit to. */
1192 if (rl
.rlim_cur
+ N_RESERVED_FDS
<= rl
.rlim_max
) {
1193 rl
.rlim_cur
= rl
.rlim_cur
+ N_RESERVED_FDS
;
1195 rl
.rlim_cur
= rl
.rlim_max
;
1198 /* Reserve some file descriptors for our use. */
1199 VG_(fd_soft_limit
) = rl
.rlim_cur
- N_RESERVED_FDS
;
1200 VG_(fd_hard_limit
) = rl
.rlim_cur
- N_RESERVED_FDS
;
1202 /* Update the soft limit. */
1203 VG_(setrlimit
)(VKI_RLIMIT_NOFILE
, &rl
);
1206 VG_(printf
)("fd limits: host, after: cur %lu max %lu\n",
1207 (UWord
)rl
.rlim_cur
, (UWord
)rl
.rlim_max
);
1208 VG_(printf
)("fd limits: guest : cur %d max %d\n",
1209 VG_(fd_soft_limit
), VG_(fd_hard_limit
));
1212 if (VG_(cl_exec_fd
) != -1)
1213 VG_(cl_exec_fd
) = VG_(safe_fd
)( VG_(cl_exec_fd
) );
1217 /*====================================================================*/
1219 /*====================================================================*/
1221 /* When main() is entered, we should be on the following stack, not
1222 the one the kernel gave us. We will run on this stack until
1223 simulation of the root thread is started, at which point a transfer
1224 is made to a dynamically allocated stack. This is for the sake of
1225 uniform overflow detection for all Valgrind threads. This is
1226 marked global even though it isn't, because assembly code below
1227 needs to reference the name. */
1230 HChar bytes
[VG_STACK_GUARD_SZB
+ VG_DEFAULT_STACK_ACTIVE_SZB
+ VG_STACK_GUARD_SZB
];
1231 } VG_(interim_stack
);
1233 /* These are the structures used to hold info for creating the initial
1236 'iicii' mostly holds important register state present at system
1237 startup (_start_valgrind). valgrind_main() then fills in the rest
1238 of it and passes it to VG_(ii_create_image)(). That produces
1239 'iifii', which is later handed to VG_(ii_finalise_image). */
1241 /* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1242 This should get some address inside the stack on which we gained
1243 control (eg, it could be the SP at startup). It doesn't matter
1244 exactly where in the stack it is. This value is passed to the
1245 address space manager at startup. On Linux, aspacem then uses it
1246 to identify the initial stack segment and hence the upper end of
1247 the usable address space. */
1249 static IICreateImageInfo the_iicii
;
1250 static IIFinaliseImageInfo the_iifii
;
1253 /* A simple pair structure, used for conveying debuginfo handles to
1254 calls to VG_TRACK(new_mem_startup, ...). */
1255 typedef struct { Addr a
; ULong ull
; } Addr_n_ULong
;
1258 /* --- Forwards decls to do with shutdown --- */
1260 static void final_tidyup(ThreadId tid
);
1262 /* Do everything which needs doing when the last thread exits */
1264 void shutdown_actions_NORETURN( ThreadId tid
,
1265 VgSchedReturnCode tids_schedretcode
);
1267 /* --- end of Forwards decls to do with shutdown --- */
1270 /* By the time we get to valgrind_main, the_iicii should already have
1271 been filled in with any important details as required by whatever
1272 OS we have been built for.
1275 Int
valgrind_main ( Int argc
, HChar
**argv
, HChar
**envp
)
1278 ThreadId tid_main
= VG_INVALID_THREADID
;
1280 XArray
* addr2dihandle
= NULL
;
1282 //============================================================
1284 // Nb: startup is complex. Prerequisites are shown at every step.
1285 // *** Be very careful when messing with the order ***
1287 // The first order of business is to get debug logging, the address
1288 // space manager and the dynamic memory manager up and running.
1289 // Once that's done, we can relax a bit.
1291 //============================================================
1293 /* This is needed to make VG_(getenv) usable early. */
1294 VG_(client_envp
) = (HChar
**)envp
;
1296 //--------------------------------------------------------------
1297 // Start up Mach kernel interface, if any
1299 //--------------------------------------------------------------
1300 # if defined(VGO_darwin)
1304 //--------------------------------------------------------------
1305 // Start up the logging mechanism
1307 //--------------------------------------------------------------
1308 /* Start the debugging-log system ASAP. First find out how many
1309 "-d"s were specified. This is a pre-scan of the command line. Also
1310 get --profile-heap=yes, --core-redzone-size, --redzone-size
1311 --aspace-minaddr which are needed by the time we start up dynamic
1312 memory management. */
1314 for (i
= 1; i
< argc
; i
++) {
1315 const HChar
* tmp_str
;
1316 if (argv
[i
][0] != '-') break;
1317 if VG_STREQ(argv
[i
], "--") break;
1318 if VG_STREQ(argv
[i
], "-d") loglevel
++;
1319 if VG_BOOL_CLOM(cloE
, argv
[i
], "--profile-heap", VG_(clo_profile_heap
)) {}
1320 if VG_BINT_CLOM(cloE
, argv
[i
], "--core-redzone-size", VG_(clo_core_redzone_size
),
1321 0, MAX_CLO_REDZONE_SZB
) {}
1322 if VG_BINT_CLOM(cloE
, argv
[i
], "--redzone-size", VG_(clo_redzone_size
),
1323 0, MAX_CLO_REDZONE_SZB
) {}
1324 if VG_STR_CLOM(cloE
, argv
[i
], "--aspace-minaddr", tmp_str
) {
1325 Bool ok
= VG_(parse_Addr
) (&tmp_str
, &VG_(clo_aspacem_minAddr
));
1327 VG_(fmsg_bad_option
)(argv
[i
], "Invalid address\n");
1328 const HChar
*errmsg
;
1329 if (!VG_(am_is_valid_for_aspacem_minAddr
)(VG_(clo_aspacem_minAddr
),
1331 VG_(fmsg_bad_option
)(argv
[i
], "%s\n", errmsg
);
1335 /* ... and start the debug logger. Now we can safely emit logging
1336 messages all through startup. */
1337 VG_(debugLog_startup
)(loglevel
, "Stage 2 (main)");
1338 VG_(debugLog
)(1, "main", "Welcome to Valgrind version "
1339 VERSION
" debug logging\n");
1341 //--------------------------------------------------------------
1342 // Ensure we're on a plausible stack.
1344 //--------------------------------------------------------------
1345 VG_(debugLog
)(1, "main", "Checking current stack is plausible\n");
1346 { HChar
* limLo
= (HChar
*)(&VG_(interim_stack
).bytes
[0]);
1347 HChar
* limHi
= limLo
+ sizeof(VG_(interim_stack
));
1349 aLocal
= (HChar
*)&limLo
; /* any auto local will do */
1350 /* Re "volatile": Apple clang version 4.0
1351 (tags/Apple/clang-421.0.57) (based on LLVM 3.1svn)" appeared
1352 to miscompile the following check, causing run to abort at
1353 this point (in 64-bit mode) even though aLocal is within limLo
1354 .. limHi. But in fact clang is within its rights to do
1355 strange things here. "The reason is that the comparisons
1356 aLocal < limLo and aLocal >= limHi cause undefined behaviour
1357 (according to c99 6.5.8) because they compare pointers that do
1358 not point into the same aggregate." Adding "volatile" appears
1359 to fix it because "The compiler would have to prove that there
1360 is undefined behavior in order to exploit it. But as a
1361 volatile variable can change its value in ways invisible to
1362 the compiler, the compiler must make the conservative
1363 assumption that it points into the same aggregate as the other
1364 pointer its compared against. I.e. the behaviour is possibly
1365 defined." (Analysis by Florian Krohm). */
1366 if (aLocal
< limLo
|| aLocal
>= limHi
) {
1367 /* something's wrong. Stop. */
1368 VG_(debugLog
)(0, "main", "Root stack %p to %p, a local %p\n",
1369 limLo
, limHi
, aLocal
);
1370 VG_(debugLog
)(0, "main", "Valgrind: FATAL: "
1371 "Initial stack switched failed.\n");
1372 VG_(debugLog
)(0, "main", " Cannot continue. Sorry.\n");
1377 //--------------------------------------------------------------
1378 // Ensure we have a plausible pointer to the stack on which
1379 // we gained control (not the current stack!)
1381 //--------------------------------------------------------------
1382 VG_(debugLog
)(1, "main", "Checking initial stack was noted\n");
1383 if (the_iicii
.sp_at_startup
== 0) {
1384 VG_(debugLog
)(0, "main", "Valgrind: FATAL: "
1385 "Initial stack was not noted.\n");
1386 VG_(debugLog
)(0, "main", " Cannot continue. Sorry.\n");
1390 #if defined(VGO_freebsd)
1392 SizeT len
= sizeof(val
);
1393 //--------------------------------------------------------------
1394 // FreeBSD check security.bsd.unprivileged_proc_debug sysctl
1395 // This needs to be done before aspacemgr starts, otherwise that
1396 // will fail with mysterious error codes
1397 //--------------------------------------------------------------
1398 Int error
= VG_(sysctlbyname
)("security.bsd.unprivileged_proc_debug", &val
, &len
, 0, 0);
1399 if (error
!= -1 && val
!= 1) {
1400 VG_(debugLog
)(0, "main", "Valgrind: FATAL:\n");
1401 VG_(debugLog
)(0, "main", "security.bsd.unprivileged_proc_debug sysctl is 0.\n");
1402 VG_(debugLog
)(0, "main", " Set this sysctl with\n");
1403 VG_(debugLog
)(0, "main", " 'sysctl security.bsd.unprivileged_proc_debug=1'.\n");
1404 VG_(debugLog
)(0, "main", " Cannot continue.\n");
1411 //--------------------------------------------------------------
1412 // Start up the address space manager, and determine the
1413 // approximate location of the client's stack
1414 // p: logging, plausible-stack
1415 //--------------------------------------------------------------
1416 VG_(debugLog
)(1, "main", "Starting the address space manager\n");
1417 vg_assert(VKI_PAGE_SIZE
== 4096 || VKI_PAGE_SIZE
== 8192
1418 || VKI_PAGE_SIZE
== 16384 || VKI_PAGE_SIZE
== 32768
1419 || VKI_PAGE_SIZE
== 65536);
1420 vg_assert(VKI_MAX_PAGE_SIZE
== 4096 || VKI_MAX_PAGE_SIZE
== 8192
1421 || VKI_MAX_PAGE_SIZE
== 16384 || VKI_MAX_PAGE_SIZE
== 32768
1422 || VKI_MAX_PAGE_SIZE
== 65536);
1423 vg_assert(VKI_PAGE_SIZE
<= VKI_MAX_PAGE_SIZE
);
1424 vg_assert(VKI_PAGE_SIZE
== (1 << VKI_PAGE_SHIFT
));
1425 vg_assert(VKI_MAX_PAGE_SIZE
== (1 << VKI_MAX_PAGE_SHIFT
));
1426 the_iicii
.clstack_end
= VG_(am_startup
)( the_iicii
.sp_at_startup
);
1427 VG_(debugLog
)(1, "main", "Address space manager is running\n");
1429 //--------------------------------------------------------------
1430 // Start up the dynamic memory manager
1431 // p: address space management
1432 // p: getting --profile-heap,--core-redzone-size,--redzone-size
1433 // In fact m_mallocfree is self-initialising, so there's no
1434 // initialisation call to do. Instead, try a simple malloc/
1435 // free pair right now to check that nothing is broken.
1436 //--------------------------------------------------------------
1437 VG_(debugLog
)(1, "main", "Starting the dynamic memory manager\n");
1438 { void* p
= VG_(malloc
)( "main.vm.1", 12345 );
1441 VG_(debugLog
)(1, "main", "Dynamic memory manager is running\n");
1443 //============================================================
1445 // Dynamic memory management is now available.
1447 //============================================================
1449 //--------------------------------------------------------------
1450 // Initialise m_debuginfo
1451 // p: dynamic memory allocation
1452 VG_(debugLog
)(1, "main", "Initialise m_debuginfo\n");
1453 VG_(di_initialise
)();
1455 //--------------------------------------------------------------
1456 // Look for alternative libdir
1457 { HChar
*cp
= VG_(getenv
)(VALGRIND_LIB
);
1460 VG_(debugLog
)(1, "main", "VG_(libdir) = %s\n", VG_(libdir
));
1463 //--------------------------------------------------------------
1464 // Extract the launcher name from the environment.
1465 VG_(debugLog
)(1, "main", "Getting launcher's name ...\n");
1466 VG_(name_of_launcher
) = VG_(getenv
)(VALGRIND_LAUNCHER
);
1467 if (VG_(name_of_launcher
) == NULL
) {
1468 VG_(printf
)("valgrind: You cannot run '%s' directly.\n", argv
[0]);
1469 VG_(printf
)("valgrind: You should use $prefix/bin/valgrind.\n");
1472 VG_(debugLog
)(1, "main", "... %s\n", VG_(name_of_launcher
));
1474 //--------------------------------------------------------------
1475 // We used to set the process datasize rlimit to zero to prevent
1476 // any internal use of brk() from having any effect. But later
1477 // linux kernels redefine RLIMIT_DATA as the size of any data
1478 // areas, including some dynamic mmap memory allocations.
1479 // See bug #357833 for the commit that went into linux 4.5
1480 // changing the definition of RLIMIT_DATA. So don't mess with
1481 // RLIMIT_DATA here now anymore. Just remember it for use in
1482 // the syscall wrappers.
1483 VG_(getrlimit
)(VKI_RLIMIT_DATA
, &VG_(client_rlimit_data
));
1485 // Get the current process stack rlimit.
1486 VG_(getrlimit
)(VKI_RLIMIT_STACK
, &VG_(client_rlimit_stack
));
1488 //--------------------------------------------------------------
1489 // Figure out what sort of CPU we're on, and whether it is
1491 /* The vex_archinfo structure is passed down later to the client
1492 * to verify the HW info settings are consistent.
1494 VexArchInfo vex_archinfo
;
1495 VG_(debugLog
)(1, "main", "Get hardware capabilities ...\n");
1497 Bool ok
= VG_(machine_get_hwcaps
)();
1500 VG_(printf
)("valgrind: fatal error: unsupported CPU.\n");
1501 VG_(printf
)(" Supported CPUs are:\n");
1502 VG_(printf
)(" * x86 (practically any; Pentium-I or above), "
1503 "AMD Athlon or above)\n");
1504 VG_(printf
)(" * AMD Athlon64/Opteron\n");
1505 VG_(printf
)(" * ARM (armv7)\n");
1506 VG_(printf
)(" * MIPS (mips32 and above; mips64 and above)\n");
1507 VG_(printf
)(" * PowerPC (most; ppc405 and above)\n");
1508 VG_(printf
)(" * System z (64bit only - s390x; z990 and above)\n");
1512 VG_(machine_get_VexArchInfo
)( &vex_arch
, &vex_archinfo
);
1514 1, "main", "... arch = %s, hwcaps = %s\n",
1515 LibVEX_ppVexArch ( vex_arch
),
1516 LibVEX_ppVexHwCaps ( vex_arch
, vex_archinfo
.hwcaps
)
1520 //--------------------------------------------------------------
1521 // Record the working directory at startup
1523 VG_(debugLog
)(1, "main", "Getting the working directory at startup\n");
1524 VG_(record_startup_wd
)();
1525 const HChar
*wd
= VG_(get_startup_wd
)();
1526 VG_(debugLog
)(1, "main", "... %s\n", wd
!= NULL
? wd
: "<NO CWD>" );
1528 //============================================================
1529 // Command line argument handling order:
1530 // * If --help/--help-debug are present, show usage message
1531 // (including the tool-specific usage)
1532 // * (If no --tool option given, default to Memcheck)
1533 // * Then, if client is missing, abort with error msg
1534 // * Then, if any cmdline args are bad, abort with error msg
1535 //============================================================
1537 //--------------------------------------------------------------
1538 // Split up argv into: C args, V args, V extra args, and exename.
1539 // p: dynamic memory allocation
1540 //--------------------------------------------------------------
1541 VG_(debugLog
)(1, "main", "Split up command line\n");
1542 VG_(split_up_argv
)( argc
, argv
);
1543 vg_assert( VG_(args_for_valgrind
) );
1544 vg_assert( VG_(args_for_client
) );
1546 for (i
= 0; i
< VG_(sizeXA
)( VG_(args_for_valgrind
) ); i
++)
1549 * (HChar
**) VG_(indexXA
)( VG_(args_for_valgrind
), i
)
1551 VG_(printf
)(" exe %s\n", VG_(args_the_exename
));
1552 for (i
= 0; i
< VG_(sizeXA
)( VG_(args_for_client
) ); i
++)
1555 * (HChar
**) VG_(indexXA
)( VG_(args_for_client
), i
)
1559 //--------------------------------------------------------------
1560 // Extract tool name and whether help has been requested.
1561 // Note we can't print the help message yet, even if requested,
1562 // because the tool has not been initialised.
1563 // p: split_up_argv [for VG_(args_for_valgrind)]
1564 //--------------------------------------------------------------
1565 VG_(debugLog
)(1, "main",
1566 "(early_) Process Valgrind's command line options\n");
1567 early_process_cmd_line_options(&need_help
);
1570 // When changing the logic for the VG_(clo_read_inline_info) default,
1571 // the manual and --help output have to be changed accordingly.
1572 vg_assert(VG_(clo_toolname
) != NULL
);
1573 vg_assert(VG_(clo_read_inline_info
) == False
);
1574 # if !defined(VGO_darwin)
1575 if (0 == VG_(strcmp
)(VG_(clo_toolname
), "memcheck")
1576 || 0 == VG_(strcmp
)(VG_(clo_toolname
), "helgrind")
1577 || 0 == VG_(strcmp
)(VG_(clo_toolname
), "drd")
1578 || 0 == VG_(strcmp
)(VG_(clo_toolname
), "massif")
1579 || 0 == VG_(strcmp
)(VG_(clo_toolname
), "dhat")) {
1580 /* Change the default setting. Later on (just below)
1581 main_process_cmd_line_options should pick up any
1582 user-supplied setting for it and will override the default
1584 VG_(clo_read_inline_info
) = True
;
1589 // Set default vex control params.
1590 LibVEX_default_VexControl(& VG_(clo_vex_control
));
1592 //--------------------------------------------------------------
1593 // Load client executable, finding in $PATH if necessary
1594 // p: early_process_cmd_line_options() [for 'exec', 'need_help',
1595 // clo_max_stackframe,
1596 // clo_main_stacksize]
1597 // p: layout_remaining_space [so there's space]
1599 // Set up client's environment
1600 // p: set-libdir [for VG_(libdir)]
1601 // p: early_process_cmd_line_options [for VG_(clo_toolname)]
1603 // Setup client stack, eip, and VG_(client_arg[cv])
1604 // p: load_client() [for 'info']
1605 // p: fix_environment() [for 'env']
1607 // Setup client data (brk) segment. Initially a 1-page segment
1608 // which abuts a shrinkable reservation.
1609 // p: load_client() [for 'info' and hence VG_(brk_base)]
1611 // p: _start_in_C (for zeroing out the_iicii and putting some
1612 // initial values into it)
1613 //--------------------------------------------------------------
1615 VG_(debugLog
)(1, "main", "Create initial image\n");
1617 # if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd)
1618 the_iicii
.argv
= argv
;
1619 the_iicii
.envp
= envp
;
1620 the_iicii
.toolname
= VG_(clo_toolname
);
1622 # error "Unknown platform"
1625 /* NOTE: this call reads VG_(clo_main_stacksize). */
1626 the_iifii
= VG_(ii_create_image
)( the_iicii
, &vex_archinfo
);
1629 //==============================================================
1631 // Finished loading/setting up the client address space.
1633 //==============================================================
1635 //--------------------------------------------------------------
1636 // setup file descriptors
1638 //--------------------------------------------------------------
1639 VG_(debugLog
)(1, "main", "Setup file descriptors\n");
1640 setup_file_descriptors();
1642 //--------------------------------------------------------------
1643 // create fake /proc/<pid>/cmdline and /proc/<pid>/auxv files
1644 // and then unlink them, but hold onto the fds, so we can handr
1645 // them out to the client when it tries to open
1646 // /proc/<pid>/cmdline or /proc/<pid>/auxv for itself.
1647 // p: setup file descriptors
1648 // p: ii_create_image for VG_(client_auxv) setup.
1649 //--------------------------------------------------------------
1650 VG_(cl_cmdline_fd
) = -1;
1651 VG_(cl_auxv_fd
) = -1;
1652 #if defined(VGO_solaris)
1653 VG_(cl_psinfo_fd
) = -1;
1656 #if defined(VGO_linux) || defined(VGO_solaris)
1658 HChar buf
[50]; // large enough
1659 HChar buf2
[VG_(mkstemp_fullname_bufsz
)(sizeof buf
- 1)];
1662 #if defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE)
1663 /* Fake /proc/<pid>/cmdline only on Linux and Solaris if supported. */
1665 const HChar
* exename
;
1667 VG_(debugLog
)(1, "main", "Create fake /proc/<pid>/cmdline\n");
1669 VG_(sprintf
)(buf
, "proc_%d_cmdline", VG_(getpid
)());
1670 fd
= VG_(mkstemp
)( buf
, buf2
);
1672 VG_(err_config_error
)("Can't create client cmdline file in %s\n", buf2
);
1675 exename
= VG_(args_the_exename
);
1676 VG_(write
)(fd
, exename
, VG_(strlen
)( exename
));
1677 VG_(write
)(fd
, nul
, 1);
1679 for (i
= 0; i
< VG_(sizeXA
)( VG_(args_for_client
) ); i
++) {
1680 HChar
* arg
= * (HChar
**) VG_(indexXA
)( VG_(args_for_client
), i
);
1681 VG_(write
)(fd
, arg
, VG_(strlen
)( arg
));
1682 VG_(write
)(fd
, nul
, 1);
1685 /* Don't bother to seek the file back to the start; instead do
1686 it every time a copy of it is given out (by PRE(sys_open) or
1687 PRE(sys_openat)). That is probably more robust across fork() etc. */
1689 /* Now delete it, but hang on to the fd. */
1690 r
= VG_(unlink
)( buf2
);
1692 VG_(err_config_error
)("Can't delete client cmdline file in %s\n", buf2
);
1694 VG_(cl_cmdline_fd
) = fd
;
1695 #endif // defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE)
1697 /* Fake /proc/<pid>/auxv on both Linux and Solaris. */
1698 VG_(debugLog
)(1, "main", "Create fake /proc/<pid>/auxv\n");
1700 VG_(sprintf
)(buf
, "proc_%d_auxv", VG_(getpid
)());
1701 fd
= VG_(mkstemp
)( buf
, buf2
);
1703 VG_(err_config_error
)("Can't create client auxv file in %s\n", buf2
);
1705 UWord
*client_auxv
= VG_(client_auxv
);
1706 unsigned int client_auxv_len
= 0;
1707 while (*client_auxv
!= 0) {
1710 client_auxv_len
+= 2 * sizeof(UWord
);
1712 client_auxv_len
+= 2 * sizeof(UWord
);
1714 VG_(write
)(fd
, VG_(client_auxv
), client_auxv_len
);
1716 /* Don't bother to seek the file back to the start; instead do
1717 it every time a copy of it is given out (by PRE(sys_open)).
1718 That is probably more robust across fork() etc. */
1720 /* Now delete it, but hang on to the fd. */
1721 r
= VG_(unlink
)( buf2
);
1723 VG_(err_config_error
)("Can't delete client auxv file in %s\n", buf2
);
1725 VG_(cl_auxv_fd
) = fd
;
1727 #if defined(VGO_solaris)
1728 /* Fake /proc/<pid>/psinfo on Solaris.
1729 * Contents will be fetched and partially faked later on the fly. */
1730 VG_(debugLog
)(1, "main", "Create fake /proc/<pid>/psinfo\n");
1732 VG_(sprintf
)(buf
, "proc_%d_psinfo", VG_(getpid
)());
1733 fd
= VG_(mkstemp
)( buf
, buf2
);
1735 VG_(err_config_error
)("Can't create client psinfo file in %s\n", buf2
);
1737 /* Now delete it, but hang on to the fd. */
1738 r
= VG_(unlink
)( buf2
);
1740 VG_(err_config_error
)("Can't delete client psinfo file in %s\n", buf2
);
1742 VG_(cl_psinfo_fd
) = fd
;
1743 #endif /* VGO_solaris */
1747 #if defined(VGO_freebsd)
1748 /* On FreeBSD /proc is optional
1749 * Most functionality is accessed through sysctl instead */
1751 struct vg_stat statbuf
;
1752 SysRes statres
= VG_(stat
)("/proc", &statbuf
);
1753 if (!sr_isError(statres
) || VKI_S_ISLNK(statbuf
.mode
)) {
1754 VG_(have_slash_proc
) = True
;
1756 // each directory contains the following that might get read
1757 // file - a symlink to the exe
1758 // cmdline - null separate command line
1759 // etype - the executable type e.g., FreeBSD ELF64 (same for guest and host)
1760 // map - a memory map, tricky to synthesize
1761 // rlimit - list of process limits
1762 // status - process, pid, ppid pts cty uid gid and some other stuff
1766 //--------------------------------------------------------------
1767 // Init tool part 1: pre_clo_init
1768 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1769 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1770 //--------------------------------------------------------------
1771 VG_(debugLog
)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
1772 VG_(tl_pre_clo_init
)();
1773 // Activate var info readers, if the tool asked for it:
1774 if (VG_(needs
).var_info
)
1775 VG_(clo_read_var_info
) = True
;
1777 //--------------------------------------------------------------
1778 // If --tool and --help/--help-debug was given, now give the core+tool
1780 // p: early_process_cmd_line_options() [for 'need_help']
1781 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
1782 //--------------------------------------------------------------
1783 VG_(debugLog
)(1, "main", "Print help and quit, if requested\n");
1785 usage_NORETURN(need_help
);
1788 //--------------------------------------------------------------
1789 // Process command line options to Valgrind + tool
1790 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1791 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1792 //--------------------------------------------------------------
1793 VG_(debugLog
)(1, "main",
1794 "(main_) Process Valgrind's command line options, "
1796 main_process_cmd_line_options();
1798 //--------------------------------------------------------------
1799 // Zeroise the millisecond counter by doing a first read of it.
1801 //--------------------------------------------------------------
1802 (void) VG_(read_millisecond_timer
)();
1804 //--------------------------------------------------------------
1805 // Print the preamble
1806 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
1807 // p: main_process_cmd_line_options()
1808 // [for VG_(clo_verbosity), VG_(clo_xml)]
1809 //--------------------------------------------------------------
1810 VG_(debugLog
)(1, "main", "Print the preamble...\n");
1811 VG_(print_preamble
)(VG_(log_output_sink
).type
!= VgLogTo_File
);
1812 VG_(debugLog
)(1, "main", "...finished the preamble\n");
1814 //--------------------------------------------------------------
1815 // Init tool part 2: post_clo_init
1816 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1817 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1818 // p: print_preamble() [so any warnings printed in post_clo_init
1819 // are shown after the preamble]
1820 //--------------------------------------------------------------
1821 VG_(debugLog
)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
1822 VG_TDICT_CALL(tool_post_clo_init
);
1824 /* The tool's "needs" will by now be finalised, since it has no
1825 further opportunity to specify them. So now sanity check
1826 and finish initialising the needs. */
1829 ok
= VG_(finish_needs_init
)( &s
);
1835 //--------------------------------------------------------------
1836 // Initialise translation table and translation cache
1838 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
1839 //--------------------------------------------------------------
1840 VG_(debugLog
)(1, "main", "Initialise TT/TC\n");
1843 //--------------------------------------------------------------
1844 // Initialise the redirect table.
1845 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
1846 // p: aspacem [so can change ownership of sysinfo pages]
1847 //--------------------------------------------------------------
1848 VG_(debugLog
)(1, "main", "Initialise redirects\n");
1849 VG_(redir_initialise
)();
1851 //--------------------------------------------------------------
1852 // Search for file descriptors that are inherited from our parent
1853 // p: main_process_cmd_line_options [for VG_(clo_track_fds)]
1854 //--------------------------------------------------------------
1855 if (VG_(clo_track_fds
)) {
1856 VG_(debugLog
)(1, "main", "Init preopened fds\n");
1857 VG_(init_preopened_fds
)();
1860 #if defined(VGO_solaris)
1861 VG_(syswrap_init
)();
1864 //--------------------------------------------------------------
1865 // Load debug info for the existing segments.
1866 // p: setup_code_redirect_table [so that redirs can be recorded]
1868 // p: probably: setup fds and process CLOs, so that logging works
1869 // p: initialise m_debuginfo
1871 // While doing this, make a note of the debuginfo-handles that
1872 // come back from VG_(di_notify_mmap).
1873 // Later, in "Tell the tool about the initial client memory permissions"
1874 // (just below) we can then hand these handles off to the tool in
1875 // calls to VG_TRACK(new_mem_startup, ...). This gives the tool the
1876 // opportunity to make further queries to m_debuginfo before the
1877 // client is started, if it wants. We put this information into an
1878 // XArray, each handle along with the associated segment start address,
1879 // and search the XArray for the handles later, when calling
1880 // VG_TRACK(new_mem_startup, ...).
1881 //--------------------------------------------------------------
1882 VG_(debugLog
)(1, "main", "Load initial debug info\n");
1884 vg_assert(!addr2dihandle
);
1885 addr2dihandle
= VG_(newXA
)( VG_(malloc
), "main.vm.2",
1886 VG_(free
), sizeof(Addr_n_ULong
) );
1888 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
1893 seg_starts
= VG_(get_segment_starts
)( SkFileC
| SkFileV
, &n_seg_starts
);
1894 vg_assert(seg_starts
&& n_seg_starts
>= 0);
1896 /* show them all to the debug info reader. allow_SkFileV has to
1897 be True here so that we read info from the valgrind executable
1899 for (i
= 0; i
< n_seg_starts
; i
++) {
1900 anu
.ull
= VG_(di_notify_mmap
)( seg_starts
[i
], True
/*allow_SkFileV*/,
1901 -1/*Don't use_fd*/);
1902 /* anu.ull holds the debuginfo handle returned by di_notify_mmap,
1905 anu
.a
= seg_starts
[i
];
1906 VG_(addToXA
)( addr2dihandle
, &anu
);
1910 VG_(free
)( seg_starts
);
1912 # elif defined(VGO_darwin)
1915 seg_starts
= VG_(get_segment_starts
)( SkFileC
, &n_seg_starts
);
1916 vg_assert(seg_starts
&& n_seg_starts
>= 0);
1918 /* show them all to the debug info reader.
1919 Don't read from V segments (unlike Linux) */
1920 // GrP fixme really?
1921 for (i
= 0; i
< n_seg_starts
; i
++) {
1922 VG_(di_notify_mmap
)( seg_starts
[i
], False
/*don't allow_SkFileV*/,
1923 -1/*don't use_fd*/);
1926 VG_(free
)( seg_starts
);
1932 //--------------------------------------------------------------
1933 // Tell aspacem of ownership change of the asm helpers, so that
1934 // m_translate allows them to be translated. However, only do this
1935 // after the initial debug info read, since making a hole in the
1936 // address range for the stage2 binary confuses the debug info reader.
1938 //--------------------------------------------------------------
1939 { Bool change_ownership_v_c_OK
;
1940 Addr co_start
= VG_PGROUNDDN( (Addr
)&VG_(trampoline_stuff_start
) );
1941 Addr co_endPlus
= VG_PGROUNDUP( (Addr
)&VG_(trampoline_stuff_end
) );
1942 VG_(debugLog
)(1,"redir",
1943 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
1944 (ULong
)co_start
, (ULong
)co_endPlus
-1 );
1946 change_ownership_v_c_OK
1947 = VG_(am_change_ownership_v_to_c
)( co_start
, co_endPlus
- co_start
);
1948 vg_assert(change_ownership_v_c_OK
);
1952 HChar buf
[50]; // large enough
1953 VG_(elapsed_wallclock_time
)(buf
, sizeof buf
);
1954 VG_(printf_xml
)( "<status>\n"
1955 " <state>RUNNING</state>\n"
1956 " <time>%pS</time>\n"
1959 VG_(printf_xml
)( "\n" );
1962 VG_(init_Threads
)();
1964 //--------------------------------------------------------------
1965 // Initialise the scheduler (phase 1) [generates tid_main]
1967 //--------------------------------------------------------------
1968 VG_(debugLog
)(1, "main", "Initialise scheduler (phase 1)\n");
1969 tid_main
= VG_(scheduler_init_phase1
)();
1970 vg_assert(tid_main
< VG_N_THREADS
1971 && tid_main
!= VG_INVALID_THREADID
);
1972 /* Tell the tool about tid_main */
1973 VG_TRACK( pre_thread_ll_create
, VG_INVALID_THREADID
, tid_main
);
1975 //--------------------------------------------------------------
1976 // Tell the tool about the initial client memory permissions
1979 // p: setup_client_stack
1980 // p: setup_client_dataseg
1982 // For each segment we tell the client about, look up in
1983 // addr2dihandle as created above, to see if there's a debuginfo
1984 // handle associated with the segment, that we can hand along
1985 // to the tool, to be helpful.
1986 //--------------------------------------------------------------
1987 VG_(debugLog
)(1, "main", "Tell tool about initial permissions\n");
1991 vg_assert(addr2dihandle
);
1993 /* Mark the main thread as running while we tell the tool about
1994 the client memory so that the tool can associate that memory
1995 with the main thread. */
1996 vg_assert(VG_(running_tid
) == VG_INVALID_THREADID
);
1997 VG_(running_tid
) = tid_main
;
1999 seg_starts
= VG_(get_segment_starts
)( SkFileC
| SkAnonC
| SkShmC
,
2001 vg_assert(seg_starts
&& n_seg_starts
>= 0);
2003 /* Show client segments to the tool */
2004 for (i
= 0; i
< n_seg_starts
; i
++) {
2007 = VG_(am_find_nsegment
)( seg_starts
[i
] );
2009 vg_assert(seg
->kind
== SkFileC
|| seg
->kind
== SkAnonC
||
2010 seg
->kind
== SkShmC
);
2011 vg_assert(seg
->start
== seg_starts
[i
]);
2013 VG_(debugLog
)(2, "main",
2014 "tell tool about %010lx-%010lx %c%c%c\n",
2015 seg
->start
, seg
->end
,
2016 seg
->hasR
? 'r' : '-',
2017 seg
->hasW
? 'w' : '-',
2018 seg
->hasX
? 'x' : '-' );
2019 /* search addr2dihandle to see if we have an entry
2020 matching seg->start. */
2021 n
= VG_(sizeXA
)( addr2dihandle
);
2022 for (j
= 0; j
< n
; j
++) {
2023 Addr_n_ULong
* anl
= VG_(indexXA
)( addr2dihandle
, j
);
2024 if (anl
->a
== seg
->start
) {
2025 vg_assert(anl
->ull
> 0); /* check it's a valid handle */
2029 vg_assert(j
>= 0 && j
<= n
);
2030 VG_TRACK( new_mem_startup
, seg
->start
, seg
->end
+1-seg
->start
,
2031 seg
->hasR
, seg
->hasW
, seg
->hasX
,
2032 /* and the retrieved debuginfo handle, if any */
2034 ? ((Addr_n_ULong
*)VG_(indexXA
)( addr2dihandle
, j
))->ull
2039 VG_(free
)( seg_starts
);
2040 VG_(deleteXA
)( addr2dihandle
);
2042 /* Also do the initial stack permissions. */
2044 SSizeT inaccessible_len
;
2046 = VG_(am_find_nsegment
)( the_iifii
.initial_client_SP
);
2048 vg_assert(seg
->kind
== SkAnonC
);
2049 vg_assert(the_iifii
.initial_client_SP
>= seg
->start
);
2050 vg_assert(the_iifii
.initial_client_SP
<= seg
->end
);
2052 /* Stuff below the initial SP is unaddressable. Take into
2053 account any ABI-mandated space below the stack pointer that
2054 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
2055 will have allocated an extra page if a red zone is required,
2056 to be on the safe side. */
2057 inaccessible_len
= the_iifii
.initial_client_SP
- VG_STACK_REDZONE_SZB
2059 vg_assert(inaccessible_len
>= 0);
2060 if (inaccessible_len
> 0)
2061 VG_TRACK( die_mem_stack
,
2064 VG_(debugLog
)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
2066 the_iifii
.initial_client_SP
-1 - VG_STACK_REDZONE_SZB
);
2069 /* Also the assembly helpers. */
2070 VG_TRACK( new_mem_startup
,
2071 (Addr
)&VG_(trampoline_stuff_start
),
2072 (Addr
)&VG_(trampoline_stuff_end
)
2073 - (Addr
)&VG_(trampoline_stuff_start
),
2074 False
, /* readable? */
2075 False
, /* writable? */
2076 True
/* executable? */,
2077 0 /* di_handle: no associated debug info */ );
2079 /* Darwin only: tell the tools where the client's kernel commpage
2080 is. It would be better to do this by telling aspacemgr about
2081 it -- see the now disused record_system_memory() in
2082 initimg-darwin.c -- but that causes the sync checker to fail,
2083 since the mapping doesn't appear in the kernel-supplied
2084 process map. So do it here instead. */
2085 # if defined(VGP_amd64_darwin)
2086 VG_TRACK( new_mem_startup
,
2087 0x7fffffe00000, 0x7ffffffff000-0x7fffffe00000,
2088 True
, False
, True
, /* r-x */
2089 0 /* di_handle: no associated debug info */ );
2090 # elif defined(VGP_x86_darwin)
2091 VG_TRACK( new_mem_startup
,
2092 0xfffec000, 0xfffff000-0xfffec000,
2093 True
, False
, True
, /* r-x */
2094 0 /* di_handle: no associated debug info */ );
2097 /* Clear the running thread indicator */
2098 VG_(running_tid
) = VG_INVALID_THREADID
;
2099 vg_assert(VG_(running_tid
) == VG_INVALID_THREADID
);
2102 //--------------------------------------------------------------
2103 // Initialise the scheduler (phase 2)
2104 // p: Initialise the scheduler (phase 1) [for tid_main]
2105 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
2106 // p: setup_client_stack
2107 //--------------------------------------------------------------
2108 VG_(debugLog
)(1, "main", "Initialise scheduler (phase 2)\n");
2109 { NSegment
const* seg
2110 = VG_(am_find_nsegment
)( the_iifii
.initial_client_SP
);
2112 vg_assert(seg
->kind
== SkAnonC
);
2113 vg_assert(the_iifii
.initial_client_SP
>= seg
->start
);
2114 vg_assert(the_iifii
.initial_client_SP
<= seg
->end
);
2115 VG_(scheduler_init_phase2
)( tid_main
,
2116 seg
->end
, the_iifii
.clstack_max_size
);
2119 //--------------------------------------------------------------
2120 // Set up state for the root thread
2122 // setup_scheduler() [for sched-specific thread 1 stuff]
2123 // VG_(ii_create_image) [for 'the_iicii' initial info]
2124 //--------------------------------------------------------------
2125 VG_(debugLog
)(1, "main", "Finalise initial image\n");
2126 { /* Mark the main thread as running while we tell the tool about
2127 the client memory which could be tracked during initial image
2128 finalisation. So the tool can associate that memory with the
2130 vg_assert(VG_(running_tid
) == VG_INVALID_THREADID
);
2131 VG_(running_tid
) = tid_main
;
2133 VG_(ii_finalise_image
)( the_iifii
);
2135 /* Clear the running thread indicator */
2136 VG_(running_tid
) = VG_INVALID_THREADID
;
2137 vg_assert(VG_(running_tid
) == VG_INVALID_THREADID
);
2140 //--------------------------------------------------------------
2141 // Initialise the signal handling subsystem
2143 //--------------------------------------------------------------
2144 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
2145 VG_(debugLog
)(1, "main", "Initialise signal management\n");
2146 /* Check that the kernel-interface signal definitions look sane */
2147 VG_(vki_do_initial_consistency_checks
)();
2148 /* .. and go on to use them. */
2149 VG_(sigstartup_actions
)();
2151 //--------------------------------------------------------------
2152 // Read suppression file
2153 // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
2154 //--------------------------------------------------------------
2155 if (VG_(needs
).core_errors
|| VG_(needs
).tool_errors
) {
2156 VG_(debugLog
)(1, "main", "Load suppressions\n");
2157 VG_(load_suppressions
)();
2160 //--------------------------------------------------------------
2161 // register client stack
2162 //--------------------------------------------------------------
2163 VG_(clstk_id
) = VG_(register_stack
)(VG_(clstk_start_base
), VG_(clstk_end
));
2165 //--------------------------------------------------------------
2166 // Show the address space state so far
2167 //--------------------------------------------------------------
2168 VG_(debugLog
)(1, "main", "\n");
2169 VG_(debugLog
)(1, "main", "\n");
2170 VG_(am_show_nsegments
)(1,"Memory layout at client startup");
2171 VG_(debugLog
)(1, "main", "\n");
2172 VG_(debugLog
)(1, "main", "\n");
2174 //--------------------------------------------------------------
2176 //--------------------------------------------------------------
2177 VG_(debugLog
)(1, "main", "Running thread 1\n");
2179 /* As a result of the following call, the last thread standing
2180 eventually winds up running shutdown_actions_NORETURN
2181 just below. Unfortunately, simply exporting said function
2182 causes m_main to be part of a module cycle, which is pretty
2183 nonsensical. So instead of doing that, the address of said
2184 function is stored in a global variable 'owned' by m_syswrap,
2185 and it uses that function pointer to get back here when it needs
2188 /* Set continuation address. */
2189 VG_(address_of_m_main_shutdown_actions_NORETURN
)
2190 = & shutdown_actions_NORETURN
;
2192 /* Run the first thread, eventually ending up at the continuation
2194 VG_(main_thread_wrapper_NORETURN
)(1);
2200 /* Return the exit code to use when tid exits, depending on the tid os_state
2201 exit code and the clo options controlling valgrind exit code. */
2203 Int
tid_exit_code (ThreadId tid
)
2205 if (VG_(clo_error_exitcode
) > 0 && VG_(get_n_errs_found
)() > 0)
2206 /* Change the application return code to user's return code,
2207 if an error was found */
2208 return VG_(clo_error_exitcode
);
2210 /* otherwise, return the client's exit code, in the normal
2212 return VG_(threads
)[tid
].os_state
.exitcode
;
2215 /* Do everything which needs doing when the last thread exits or when
2216 a thread exits requesting a complete process exit.
2218 We enter here holding The Lock. For the case VgSrc_ExitProcess we
2219 must never release it, because to do so would allow other threads
2220 to continue after the system is ostensibly shut down. So we must
2221 go to our grave, so to speak, holding the lock.
2223 In fact, there is never any point in releasing the lock at this
2224 point - we have it, we're shutting down the entire system, and
2225 for the case VgSrc_ExitProcess doing so positively causes trouble.
2228 The final_tidyup call makes a bit of a nonsense of the ExitProcess
2229 case, since it will run __gnu_cxx::__freeres and libc_freeres functions,
2230 thus allowing other lurking threads to run again. Hmm. */
2233 void shutdown_actions_NORETURN( ThreadId tid
,
2234 VgSchedReturnCode tids_schedretcode
)
2236 VG_(debugLog
)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
2237 VG_(am_show_nsegments
)(1,"Memory layout at client shutdown");
2239 vg_assert(VG_(is_running_thread
)(tid
));
2240 vg_assert(tids_schedretcode
== VgSrc_ExitThread
2241 || tids_schedretcode
== VgSrc_ExitProcess
2242 || tids_schedretcode
== VgSrc_FatalSig
);
2244 /* Try to do final tidyup on "normal" exit, not on FatalSig. */
2245 if (tids_schedretcode
== VgSrc_ExitThread
) {
2247 // We are the last surviving thread. Right?
2248 vg_assert( VG_(count_living_threads
)() == 1 );
2250 // Wait for all other threads to exit.
2251 // jrs: Huh? but they surely are already gone
2252 VG_(reap_threads
)(tid
);
2254 // Clean the client up before the final report.
2255 // This causes __gnu_cxx::__freeres and libc_freeres functions to run.
2259 vg_assert(VG_(is_running_thread
)(tid
));
2260 vg_assert(VG_(count_living_threads
)() == 1);
2262 } else if (tids_schedretcode
== VgSrc_ExitProcess
) {
2264 // We may not be the last surviving thread. However, we
2265 // want to shut down the entire process. We hold the lock
2266 // and we need to keep hold of it all the way out, in order
2267 // that none of the other threads ever run again.
2268 vg_assert( VG_(count_living_threads
)() >= 1 );
2270 // Clean the client up before the final report.
2271 // This causes __gnu_cxx::__freeres and libc_freeres functions to run.
2272 // Perhaps this is unsafe, as per comment above.
2276 vg_assert(VG_(is_running_thread
)(tid
));
2277 vg_assert(VG_(count_living_threads
)() >= 1);
2280 /* Final call to gdbserver, if requested. */
2281 if (VG_(gdbserver_stop_at
) (VgdbStopAt_Abexit
)
2282 && tid_exit_code (tid
) != 0) {
2283 if (!(VG_(clo_launched_with_multi
)))
2284 VG_(umsg
)("(action at abexit, exit code %d) vgdb me ... \n",
2285 tid_exit_code (tid
));
2286 VG_(gdbserver
) (tid
);
2287 } else if (VG_(gdbserver_stop_at
) (VgdbStopAt_Exit
)) {
2288 if (!(VG_(clo_launched_with_multi
)))
2289 VG_(umsg
)("(action at exit, exit code %d) vgdb me ... \n",
2290 tid_exit_code (tid
));
2291 VG_(gdbserver
) (tid
);
2293 VG_(threads
)[tid
].status
= VgTs_Empty
;
2295 //--------------------------------------------------------------
2296 // Finalisation: cleanup, messages, etc. Order not so important, only
2297 // affects what order the messages come.
2298 //--------------------------------------------------------------
2299 // First thing in the post-amble is a blank line.
2301 VG_(printf_xml
)("\n");
2302 else if (VG_(clo_verbosity
) > 0)
2303 VG_(message
)(Vg_UserMsg
, "\n");
2306 HChar buf
[50]; // large enough
2307 VG_(elapsed_wallclock_time
)(buf
, sizeof buf
);
2308 VG_(printf_xml
)( "<status>\n"
2309 " <state>FINISHED</state>\n"
2310 " <time>%pS</time>\n"
2316 /* Print out file descriptor summary and stats. */
2317 if (VG_(clo_track_fds
))
2318 VG_(show_open_fds
)("at exit");
2320 /* Call the tool's finalisation function. This makes Memcheck's
2321 leak checker run, and possibly chuck a bunch of leak errors into
2322 the error management machinery. */
2323 VG_TDICT_CALL(tool_fini
, 0/*exitcode*/);
2325 if ((VG_(needs
).core_errors
&& VG_(found_or_suppressed_errs
)())
2326 || VG_(needs
).tool_errors
) {
2327 if (VG_(clo_verbosity
) == 1
2329 && !VG_(clo_show_error_list
))
2330 VG_(message
)(Vg_UserMsg
,
2331 "For lists of detected and suppressed errors,"
2332 " rerun with: -s\n");
2334 /* Show the error counts. */
2336 VG_(show_error_counts_as_XML
)();
2339 /* In XML mode, this merely prints the used suppressions. */
2340 VG_(show_all_errors
)(VG_(clo_verbosity
), VG_(clo_xml
), VG_(clo_show_error_list
));
2344 VG_(printf_xml
)("\n");
2345 VG_(printf_xml
)("</valgrindoutput>\n");
2346 VG_(printf_xml
)("\n");
2349 VG_(sanity_check_general
)( True
/*include expensive checks*/ );
2352 VG_(print_all_stats
)(VG_(clo_verbosity
) >= 1, /* Memory stats */
2353 False
/* tool prints stats in the tool fini */);
2355 /* Show a profile of the heap(s) at shutdown. Optionally, first
2356 throw away all the debug info, as that makes it easy to spot
2357 leaks in the debuginfo reader. */
2358 if (VG_(clo_profile_heap
)) {
2359 if (0) VG_(di_discard_ALL_debuginfo
)();
2360 VG_(print_arena_cc_analysis
)();
2363 /* If profiling has been requested, but with zero interval, it
2364 means "profile at the end of the run only". In which case we
2365 need to dump the profile now. */
2366 if (VG_(clo_profyle_sbs
) && VG_(clo_profyle_interval
) == 0) {
2367 VG_(get_and_show_SB_profile
)(0/*denoting end-of-run*/);
2370 /* Print Vex storage stats */
2372 LibVEX_ShowAllocStats();
2374 /* Flush any output cached by previous calls to VG_(message). */
2375 VG_(message_flush
)();
2377 /* Terminate gdbserver if ever it was started. We terminate it here
2378 so that it get the output above if output was redirected to
2380 VG_(gdbserver_exit
) (tid
, tids_schedretcode
);
2382 /* Ok, finally exit in the os-specific way, according to the scheduler's
2383 return code. In short, if the (last) thread exited by calling
2384 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2385 signal, terminate the entire system with that same fatal signal. */
2386 VG_(debugLog
)(1, "core_os",
2387 "VG_(terminate_NORETURN)(tid=%u) schedretcode %s"
2388 " os_state.exit_code %ld fatalsig %d\n",
2389 tid
, VG_(name_of_VgSchedReturnCode
)(tids_schedretcode
),
2390 VG_(threads
)[tid
].os_state
.exitcode
,
2391 VG_(threads
)[tid
].os_state
.fatalsig
);
2393 switch (tids_schedretcode
) {
2394 case VgSrc_ExitThread
: /* the normal way out (Linux, Solaris) */
2395 case VgSrc_ExitProcess
: /* the normal way out (Darwin) */
2396 VG_(client_exit
)(tid_exit_code (tid
));
2397 /* NOT ALIVE HERE! */
2398 VG_(core_panic
)("entered the afterlife in main() -- ExitT/P");
2399 break; /* what the hell :) */
2401 case VgSrc_FatalSig
:
2402 /* We were killed by a fatal signal, so replicate the effect */
2403 vg_assert(VG_(threads
)[tid
].os_state
.fatalsig
!= 0);
2404 VG_(kill_self
)(VG_(threads
)[tid
].os_state
.fatalsig
);
2405 /* we shouldn't be alive at this point. But VG_(kill_self)
2406 sometimes fails with EPERM on Darwin, for unclear reasons. */
2407 # if defined(VGO_darwin)
2408 VG_(debugLog
)(0, "main", "VG_(kill_self) failed. Exiting normally.\n");
2409 VG_(exit
)(0); /* bogus, but we really need to exit now */
2410 /* fall through .. */
2412 VG_(core_panic
)("main(): signal was supposed to be fatal");
2416 VG_(core_panic
)("main(): unexpected scheduler return code");
2420 /* -------------------- */
2422 /* Final clean-up before terminating the process.
2423 Clean up the client by calling __gnu_cxx::__freeres() (if requested)
2424 and __libc_freeres() (if requested).
2426 static void final_tidyup(ThreadId tid
)
2428 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
2429 Addr freeres_wrapper
= VG_(client_freeres_wrapper
);
2431 vg_assert(VG_(is_running_thread
)(tid
));
2433 if (freeres_wrapper
== 0) {
2434 return; /* can't do it */
2437 Vg_FreeresToRun to_run
= 0;
2438 if (VG_(needs
).cxx_freeres
&& VG_(clo_run_cxx_freeres
)) {
2439 to_run
|= VG_RUN__GNU_CXX__FREERES
;
2442 if (VG_(needs
).libc_freeres
&& VG_(clo_run_libc_freeres
)) {
2443 to_run
|= VG_RUN__LIBC_FREERES
;
2447 return; /* won't do it */
2450 # if defined(VGP_ppc64be_linux)
2451 Addr r2
= VG_(get_tocptr
)(VG_(current_DiEpoch
)(),
2454 VG_(message
)(Vg_UserMsg
,
2455 "Caught __NR_exit, but can't run __gnu_cxx::__freeres()\n");
2456 VG_(message
)(Vg_UserMsg
,
2457 " or __libc_freeres() since cannot establish TOC pointer "
2463 if (VG_(clo_verbosity
) > 2 ||
2464 VG_(clo_trace_syscalls
) ||
2465 VG_(clo_trace_sched
)) {
2467 vg_assert(to_run
> 0);
2468 vg_assert(to_run
<= (VG_RUN__GNU_CXX__FREERES
| VG_RUN__LIBC_FREERES
));
2470 const HChar
*msgs
[] = {"__gnu_cxx::__freeres()", "__libc_freeres()",
2471 "__gnu_cxx::__freeres and __libc_freeres()"};
2472 VG_(message
)(Vg_DebugMsg
,
2473 "Caught __NR_exit; running %s wrapper\n", msgs
[to_run
- 1]);
2476 /* Set thread context to point to freeres_wrapper.
2477 ppc64be-linux note: freeres_wrapper gives us the real
2478 function entry point, not a fn descriptor, so can use it
2479 directly. However, we need to set R2 (the toc pointer)
2481 VG_(set_IP
)(tid
, freeres_wrapper
);
2483 # if defined(VGP_ppc64be_linux)
2484 VG_(threads
)[tid
].arch
.vex
.guest_GPR2
= r2
;
2485 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2486 offsetof(VexGuestPPC64State
, guest_GPR2
),
2487 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_GPR2
));
2488 # elif defined(VGP_ppc64le_linux)
2489 /* setting GPR2 but not really needed, GPR12 is needed */
2490 VG_(threads
)[tid
].arch
.vex
.guest_GPR2
= freeres_wrapper
;
2491 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2492 offsetof(VexGuestPPC64State
, guest_GPR2
),
2493 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_GPR2
));
2494 VG_(threads
)[tid
].arch
.vex
.guest_GPR12
= freeres_wrapper
;
2495 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2496 offsetof(VexGuestPPC64State
, guest_GPR12
),
2497 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_GPR12
));
2499 /* mips-linux note: we need to set t9 */
2500 # if defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)
2501 VG_(threads
)[tid
].arch
.vex
.guest_r25
= freeres_wrapper
;
2502 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2503 offsetof(VexGuestMIPS32State
, guest_r25
),
2504 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_r25
));
2505 # elif defined(VGP_mips64_linux)
2506 VG_(threads
)[tid
].arch
.vex
.guest_r25
= freeres_wrapper
;
2507 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2508 offsetof(VexGuestMIPS64State
, guest_r25
),
2509 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_r25
));
2512 /* Pass a parameter to freeres_wrapper(). */
2513 # if defined(VGA_x86)
2514 Addr sp
= VG_(threads
)[tid
].arch
.vex
.guest_ESP
;
2515 *((UWord
*) sp
) = to_run
;
2516 VG_TRACK(post_mem_write
, Vg_CoreClientReq
, tid
, sp
, sizeof(UWord
));
2517 sp
= sp
- sizeof(UWord
);
2518 VG_(threads
)[tid
].arch
.vex
.guest_ESP
= sp
;
2519 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2520 offsetof(VexGuestX86State
, guest_ESP
),
2521 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_ESP
));
2522 # elif defined(VGA_amd64)
2523 VG_(threads
)[tid
].arch
.vex
.guest_RDI
= to_run
;
2524 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2525 offsetof(VexGuestAMD64State
, guest_RDI
),
2526 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_RDI
));
2527 # elif defined(VGA_arm)
2528 VG_(threads
)[tid
].arch
.vex
.guest_R0
= to_run
;
2529 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2530 offsetof(VexGuestARMState
, guest_R0
),
2531 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_R0
));
2532 # elif defined(VGA_arm64)
2533 VG_(threads
)[tid
].arch
.vex
.guest_X0
= to_run
;
2534 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2535 offsetof(VexGuestARM64State
, guest_X0
),
2536 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_X0
));
2537 # elif defined(VGA_mips32) || defined(VGA_nanomips)
2538 VG_(threads
)[tid
].arch
.vex
.guest_r4
= to_run
;
2539 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2540 offsetof(VexGuestMIPS32State
, guest_r4
),
2541 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_r4
));
2542 # elif defined(VGA_mips64)
2543 VG_(threads
)[tid
].arch
.vex
.guest_r4
= to_run
;
2544 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2545 offsetof(VexGuestMIPS64State
, guest_r4
),
2546 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_r4
));
2547 # elif defined(VGA_ppc32)
2548 VG_(threads
)[tid
].arch
.vex
.guest_GPR3
= to_run
;
2549 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2550 offsetof(VexGuestPPC32State
, guest_GPR3
),
2551 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_GPR3
));
2552 # elif defined(VGA_ppc64be) || defined(VGA_ppc64le)
2553 VG_(threads
)[tid
].arch
.vex
.guest_GPR3
= to_run
;
2554 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2555 offsetof(VexGuestPPC64State
, guest_GPR3
),
2556 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_GPR3
));
2557 # elif defined(VGA_s390x)
2558 VG_(threads
)[tid
].arch
.vex
.guest_r2
= to_run
;
2559 VG_TRACK(post_reg_write
, Vg_CoreClientReq
, tid
,
2560 offsetof(VexGuestS390XState
, guest_r2
),
2561 sizeof(VG_(threads
)[tid
].arch
.vex
.guest_r2
));
2563 I_die_here
: architecture missing in m_main
.c
2566 /* Block all blockable signals by copying the real block state into
2567 the thread's block state */
2568 VG_(sigprocmask
)(VKI_SIG_BLOCK
, NULL
, &VG_(threads
)[tid
].sig_mask
);
2569 VG_(threads
)[tid
].tmp_sig_mask
= VG_(threads
)[tid
].sig_mask
;
2571 /* and restore handlers to default. */
2572 VG_(set_default_handler
)(VKI_SIGSEGV
);
2573 VG_(set_default_handler
)(VKI_SIGBUS
);
2574 VG_(set_default_handler
)(VKI_SIGILL
);
2575 VG_(set_default_handler
)(VKI_SIGFPE
);
2576 VG_(set_default_handler
)(VKI_SIGSYS
);
2578 // We were exiting, so assert that...
2579 vg_assert(VG_(is_exiting
)(tid
));
2580 // ...but now we're not again.
2581 VG_(threads
)[tid
].exitreason
= VgSrc_None
;
2583 // Run until client thread exits - ideally with FREERES_DONE,
2584 // but exit/exitgroup/signal will do.
2585 VG_(scheduler
)(tid
);
2587 vg_assert(VG_(is_exiting
)(tid
));
2592 /*====================================================================*/
2593 /*=== Getting to main() alive: LINUX ===*/
2594 /*====================================================================*/
2596 #if defined(VGO_linux)
2598 /* If linking of the final executables is done with glibc present,
2599 then Valgrind starts at main() above as usual, and all of the
2600 following code is irrelevant.
2602 However, this is not the intended mode of use. The plan is to
2603 avoid linking against glibc, by giving gcc the flags
2604 -nodefaultlibs -lgcc -nostartfiles at startup.
2606 From this derive two requirements:
2608 1. gcc may emit calls to memcpy, memmove and memset to deal with
2609 structure assignments etc. Since we have chosen to ignore all the
2610 "normal" supporting libraries, we have to provide our own
2611 implementations of them. No problem.
2613 2. We have to provide a symbol "_start", to which the kernel
2614 hands control at startup. Hence the code below.
2617 /* ---------------- Requirement 1 ---------------- */
2619 void* memcpy(void *dest
, const void *src
, SizeT n
);
2620 void* memcpy(void *dest
, const void *src
, SizeT n
) {
2621 return VG_(memcpy
)(dest
,src
,n
);
2623 void* memmove(void *dest
, const void *src
, SizeT n
);
2624 void* memmove(void *dest
, const void *src
, SizeT n
) {
2625 return VG_(memmove
)(dest
,src
,n
);
2627 void* memset(void *s
, int c
, SizeT n
);
2628 void* memset(void *s
, int c
, SizeT n
) {
2629 return VG_(memset
)(s
,c
,n
);
2632 /* BVA: abort() for those platforms that need it (PPC and ARM). */
2635 VG_(printf
)("Something called raise().\n");
2639 /* EAZG: ARM's EABI will call floating point exception handlers in
2640 libgcc which boil down to an abort or raise, that's usually defined
2641 in libc. Instead, define them here. */
2642 #if defined(VGP_arm_linux)
2646 VG_(printf
)("Something called raise().\n");
2650 void __aeabi_unwind_cpp_pr0(void);
2651 void __aeabi_unwind_cpp_pr0(void){
2652 VG_(printf
)("Something called __aeabi_unwind_cpp_pr0()\n");
2656 void __aeabi_unwind_cpp_pr1(void);
2657 void __aeabi_unwind_cpp_pr1(void){
2658 VG_(printf
)("Something called __aeabi_unwind_cpp_pr1()\n");
2662 #endif /* defined(VGP_arm_linux) */
2664 /* Some Android helpers. See bug 368529. */
2665 #if defined(__clang__) \
2666 && (defined(VGPV_arm_linux_android) \
2667 || defined(VGPV_x86_linux_android) \
2668 || defined(VGPV_mips32_linux_android) \
2669 || defined(VGPV_arm64_linux_android))
2671 /* Replace __aeabi_memcpy* functions with vgPlain_memcpy. */
2672 void *__aeabi_memcpy(void *dest
, const void *src
, SizeT n
);
2673 void *__aeabi_memcpy(void *dest
, const void *src
, SizeT n
)
2675 return VG_(memcpy
)(dest
, src
, n
);
2678 void *__aeabi_memcpy4(void *dest
, const void *src
, SizeT n
);
2679 void *__aeabi_memcpy4(void *dest
, const void *src
, SizeT n
)
2681 return VG_(memcpy
)(dest
, src
, n
);
2684 void *__aeabi_memcpy8(void *dest
, const void *src
, SizeT n
);
2685 void *__aeabi_memcpy8(void *dest
, const void *src
, SizeT n
)
2687 return VG_(memcpy
)(dest
, src
, n
);
2690 /* Replace __aeabi_memclr* functions with vgPlain_memset. */
2691 void *__aeabi_memclr(void *dest
, SizeT n
);
2692 void *__aeabi_memclr(void *dest
, SizeT n
)
2694 return VG_(memset
)(dest
, 0, n
);
2697 void *__aeabi_memclr4(void *dest
, SizeT n
);
2698 void *__aeabi_memclr4(void *dest
, SizeT n
)
2700 return VG_(memset
)(dest
, 0, n
);
2703 void *__aeabi_memclr8(void *dest
, SizeT n
);
2704 void *__aeabi_memclr8(void *dest
, SizeT n
)
2706 return VG_(memset
)(dest
, 0, n
);
2708 #endif /* clang and android, basically */
2710 /* ---------------- Requirement 2 ---------------- */
2712 /* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2713 comment, which explains how the stack looks right at process start
2714 (when _start is jumped to). Hence _start passes %esp to
2715 _start_in_C_linux, which extracts argc/argv/envp and starts up
2718 /* This is the canonical entry point, usually the first thing in the text
2719 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2720 point runs, most registers' values are unspecified, except for:
2722 %edx Contains a function pointer to be registered with `atexit'.
2723 This is how the dynamic linker arranges to have DT_FINI
2724 functions called for shared libraries that have been loaded
2725 before this code runs.
2727 %esp The stack contains the arguments and environment:
2732 (4*(argc+1))(%esp) envp[0]
2737 /* The kernel hands control to _start, which extracts the initial
2738 stack pointer and calls onwards to _start_in_C_linux. This also switches
2740 #if defined(VGP_x86_linux)
2744 "\t.type _start,@function\n"
2746 /* set up the new stack in %eax */
2747 "\tmovl $vgPlain_interim_stack, %eax\n"
2748 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB
)", %eax\n"
2749 "\taddl $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)", %eax\n"
2750 /* allocate at least 16 bytes on the new stack, and aligned */
2751 "\tsubl $16, %eax\n"
2752 "\tandl $~15, %eax\n"
2753 /* install it, and collect the original one */
2754 "\txchgl %eax, %esp\n"
2755 /* call _start_in_C_linux, passing it the startup %esp */
2756 "\tmovl %eax, (%esp)\n"
2757 "\tcall _start_in_C_linux\n"
2761 #elif defined(VGP_amd64_linux)
2765 "\t.type _start,@function\n"
2767 /* set up the new stack in %rdi */
2768 "\tmovq $vgPlain_interim_stack, %rdi\n"
2769 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB
)", %rdi\n"
2770 "\taddq $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)", %rdi\n"
2771 "\tandq $~15, %rdi\n"
2772 /* install it, and collect the original one */
2773 "\txchgq %rdi, %rsp\n"
2774 /* call _start_in_C_linux, passing it the startup %rsp */
2775 "\tcall _start_in_C_linux\n"
2779 #elif defined(VGP_ppc32_linux)
2783 "\t.type _start,@function\n"
2785 /* set up the new stack in r16 */
2786 "\tlis 16,vgPlain_interim_stack@ha\n"
2787 "\tla 16,vgPlain_interim_stack@l(16)\n"
2788 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB
)" >> 16)\n"
2789 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB
)" & 0xFFFF)\n"
2790 "\tlis 18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)" >> 16)\n"
2791 "\tori 18,18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)" & 0xFFFF)\n"
2794 "\trlwinm 16,16,0,0,27\n"
2795 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2796 VG_DEFAULT_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2797 boundary. And r1 is the original SP. Set the SP to r16 and
2798 call _start_in_C_linux, passing it the initial SP. */
2801 "\tbl _start_in_C_linux\n"
2805 #elif defined(VGP_ppc64be_linux)
2807 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2808 So we must have one, and that is what goes into the .opd section. */
2810 "\t.global _start\n"
2811 "\t.section \".opd\",\"aw\"\n"
2814 "\t.quad ._start,.TOC.@tocbase,0\n"
2816 "\t.type ._start,@function\n"
2817 "\t.global ._start\n"
2819 /* set up the new stack in r16 */
2820 "\tlis 16, vgPlain_interim_stack@highest\n"
2821 "\tori 16,16,vgPlain_interim_stack@higher\n"
2823 "\toris 16,16,vgPlain_interim_stack@h\n"
2824 "\tori 16,16,vgPlain_interim_stack@l\n"
2826 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB
)" >> 16)\n"
2827 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB
)" & 0xFFFF)\n"
2829 "\tlis 18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)" >> 16)\n"
2830 "\tori 18,18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)" & 0xFFFF)\n"
2833 "\trldicr 16,16,0,59\n"
2834 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2835 VG_DEFAULT_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2836 boundary. And r1 is the original SP. Set the SP to r16 and
2837 call _start_in_C_linux, passing it the initial SP. */
2840 "\tlis 14, _start_in_C_linux@highest\n"
2841 "\tori 14,14,_start_in_C_linux@higher\n"
2843 "\toris 14,14,_start_in_C_linux@h\n"
2844 "\tori 14,14,_start_in_C_linux@l\n"
2851 #elif defined(VGP_ppc64le_linux)
2852 /* Little Endian uses ELF version 2 but in the future may also
2853 * support other ELF versions.
2857 "\t.global _start\n"
2858 "\t.type _start,@function\n"
2860 "#if _CALL_ELF == 2 \n"
2861 "0: addis 2,12,.TOC.-0b@ha\n"
2862 " addi 2,2,.TOC.-0b@l\n"
2863 " .localentry _start, .-_start\n"
2865 /* set up the new stack in r16 */
2866 "\tlis 16, vgPlain_interim_stack@highest\n"
2867 "\tori 16,16,vgPlain_interim_stack@higher\n"
2869 "\toris 16,16,vgPlain_interim_stack@h\n"
2870 "\tori 16,16,vgPlain_interim_stack@l\n"
2872 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB
)" >> 16)\n"
2873 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB
)" & 0xFFFF)\n"
2875 "\tlis 18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)" >> 16)\n"
2876 "\tori 18,18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)" & 0xFFFF)\n"
2879 "\trldicr 16,16,0,59\n"
2880 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2881 VG_DEFAULT_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2882 boundary. And r1 is the original SP. Set the SP to r16 and
2883 call _start_in_C_linux, passing it the initial SP. */
2886 "\tlis 14, _start_in_C_linux@highest\n"
2887 "\tori 14,14,_start_in_C_linux@higher\n"
2889 "\toris 14,14,_start_in_C_linux@h\n"
2890 "\tori 14,14,_start_in_C_linux@l\n"
2896 #elif defined(VGP_s390x_linux)
2898 This is the canonical entry point, usually the first thing in the text
2899 segment. Most registers' values are unspecified, except for:
2901 %r14 Contains a function pointer to be registered with `atexit'.
2902 This is how the dynamic linker arranges to have DT_FINI
2903 functions called for shared libraries that have been loaded
2904 before this code runs.
2906 %r15 The stack contains the arguments and environment:
2911 (8*(argc+1))(%r15) envp[0]
2918 ".type _start,@function\n\t"
2920 /* set up the new stack in %r1 */
2921 "larl %r1, vgPlain_interim_stack\n\t"
2923 "ag %r1, 0(%r5)\n\t"
2924 "ag %r1, 2f-1f(%r5)\n\t"
2925 "nill %r1, 0xFFF0\n\t"
2926 /* install it, and collect the original one */
2929 /* call _start_in_C_linux, passing it the startup %r15 */
2930 "brasl %r14, _start_in_C_linux\n\t"
2931 /* trigger execution of an invalid opcode -> halt machine */
2933 "1: .quad "VG_STRINGIFY(VG_STACK_GUARD_SZB
)"\n\t"
2934 "2: .quad "VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)"\n\t"
2937 #elif defined(VGP_arm_linux)
2941 "\t.type _start,#function\n"
2942 "\t.global _start\n"
2944 "\tldr r0, [pc, #36]\n"
2945 "\tldr r1, [pc, #36]\n"
2946 "\tadd r0, r1, r0\n"
2947 "\tldr r1, [pc, #32]\n"
2948 "\tadd r0, r1, r0\n"
2950 "\tand r0, r0, r1\n"
2954 "\tb _start_in_C_linux\n"
2955 "\t.word vgPlain_interim_stack\n"
2956 "\t.word "VG_STRINGIFY(VG_STACK_GUARD_SZB
)"\n"
2957 "\t.word "VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)"\n"
2959 #elif defined(VGP_arm64_linux)
2963 "\t.type _start,#function\n"
2964 "\t.global _start\n"
2966 "\tadrp x0, vgPlain_interim_stack\n"
2967 "\tadd x0, x0, :lo12:vgPlain_interim_stack\n"
2968 // The next 2 assume that VG_STACK_GUARD_SZB fits in 32 bits
2969 "\tmov x1, (("VG_STRINGIFY(VG_STACK_GUARD_SZB
)") >> 0) & 0xFFFF\n"
2970 "\tmovk x1, (("VG_STRINGIFY(VG_STACK_GUARD_SZB
)") >> 16) & 0xFFFF,"
2972 "\tadd x0, x0, x1\n"
2973 // The next 2 assume that VG_DEFAULT_STACK_ACTIVE_SZB fits in 32 bits
2974 "\tmov x1, (("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)") >> 0) & 0xFFFF\n"
2975 "\tmovk x1, (("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)") >> 16) & 0xFFFF,"
2977 "\tadd x0, x0, x1\n"
2978 "\tand x0, x0, -16\n"
2982 "\tb _start_in_C_linux\n"
2984 #elif defined(VGP_mips32_linux)
2986 "\t.type _gp_disp,@object\n"
2988 "\t.globl __start\n"
2989 "\t.type __start,@function\n"
2997 "\tlui $28, %hi(_gp_disp)\n"
2998 "\taddiu $28, $28, %lo(_gp_disp)\n"
2999 "\taddu $28, $28, $31\n"
3000 /* t1/$9 <- Addr(interim_stack) */
3001 "\tlui $9, %hi(vgPlain_interim_stack)\n"
3002 /* t1/$9 <- Addr(interim_stack) */
3003 "\taddiu $9, %lo(vgPlain_interim_stack)\n"
3006 "\tli $10, "VG_STRINGIFY(VG_STACK_GUARD_SZB
)"\n"
3007 "\tli $11, "VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)"\n"
3009 "\taddu $9, $9, $10\n"
3010 "\taddu $9, $9, $11\n"
3011 "\tli $12, 0xFFFFFFF0\n"
3012 "\tand $9, $9, $12\n"
3013 /* now t1/$9 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
3014 VG_DEFAULT_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
3015 boundary. And $29 is the original SP. Set the SP to t1 and
3016 call _start_in_C, passing it the initial SP. */
3018 "\tmove $4, $29\n" // a0 <- $sp (_start_in_C first arg)
3019 "\tmove $29, $9\n" // $sp <- t1 (new sp)
3021 "\tlui $25, %hi(_start_in_C_linux)\n"
3022 "\taddiu $25, %lo(_start_in_C_linux)\n"
3024 "\tbal _start_in_C_linux\n"
3028 #elif defined(VGP_mips64_linux)
3032 ".type __start,@function\n"
3034 "\t.set noreorder\n"
3038 "\tlui $9, %hi(vgPlain_interim_stack)\n"
3039 /* t1/$9 <- Addr(interim_stack) */
3040 "\tdaddiu $9, %lo(vgPlain_interim_stack)\n"
3042 "\tli $10, "VG_STRINGIFY(VG_STACK_GUARD_SZB
)"\n"
3043 "\tli $11, "VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)"\n"
3045 "\tdaddu $9, $9, $10\n"
3046 "\tdaddu $9, $9, $11\n"
3047 "\tli $12, 0xFFFFFF00\n"
3048 "\tand $9, $9, $12\n"
3049 /* now t1/$9 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
3050 VG_DEFAULT_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
3051 boundary. And $29 is the original SP. Set the SP to t1 and
3052 call _start_in_C, passing it the initial SP. */
3054 "\tmove $4, $29\n" // a0 <- $sp (_start_in_C first arg)
3055 "\tmove $29, $9\n" // $sp <- t1 (new sp)
3057 "\tlui $9, %highest(_start_in_C_linux)\n"
3058 "\tori $9, %higher(_start_in_C_linux)\n"
3059 "\tdsll32 $9, $9, 0x0\n"
3060 "\tlui $10, %hi(_start_in_C_linux)\n"
3061 "\tdaddiu $10, %lo(_start_in_C_linux)\n"
3062 "\tdaddu $25, $9, $10\n"
3067 #elif defined(VGP_nanomips_linux)
3070 ".globl __start \n\t"
3071 ".type __start,@function \n\t"
3074 ".set noreorder \n\t"
3075 "li $t1, vgPlain_interim_stack \n\t"
3076 "li $t0, "VG_STRINGIFY(VG_STACK_GUARD_SZB
)" \n\t"
3077 "addu $t1, $t1, $t0 \n\t"
3078 "li $t0, "VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)"\n\t"
3079 "addu $t1, $t1, $t0 \n\t"
3080 "li $t0, 0xFFFFFF00 \n\t"
3081 "and $t1, $t1, $t0 \n\t"
3082 "move $a0, $sp \n\t"
3083 "move $sp, $t1 \n\t"
3084 "li $t0, _start_in_C_linux \n\t"
3091 # error "Unknown platform"
3094 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
3096 #define _FILE_OFFSET_BITS 64
3097 /* This is in order to get AT_NULL and AT_PAGESIZE. */
3099 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
3101 /* Avoid compiler warnings: this fn _is_ used, but labelling it
3102 'static' causes gcc to complain it isn't.
3103 attribute 'used' also ensures the code is not eliminated at link
3105 __attribute__ ((used
))
3106 void _start_in_C_linux ( UWord
* pArgc
);
3107 __attribute__ ((used
))
3108 void _start_in_C_linux ( UWord
* pArgc
)
3111 Word argc
= pArgc
[0];
3112 HChar
** argv
= (HChar
**)&pArgc
[1];
3113 HChar
** envp
= (HChar
**)&pArgc
[1+argc
+1];
3115 // For an inner Valgrind, register the interim stack asap.
3116 // This is needed to allow the outer valgrind to do stacktraces during init.
3117 // Note that this stack is not unregistered when the main thread
3118 // is switching to the (real) stack. Unregistering this would imply
3119 // to save the stack id in a global variable, and have a "if"
3120 // in run_a_thread_NORETURN to do the unregistration only for the
3121 // main thread. This unregistration is not worth this complexity.
3123 ((void) VALGRIND_STACK_REGISTER
3124 (&VG_(interim_stack
).bytes
[0],
3125 &VG_(interim_stack
).bytes
[0] + sizeof(VG_(interim_stack
))));
3127 VG_(memset
)( &the_iicii
, 0, sizeof(the_iicii
) );
3128 VG_(memset
)( &the_iifii
, 0, sizeof(the_iifii
) );
3130 the_iicii
.sp_at_startup
= (Addr
)pArgc
;
3132 # if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
3133 || defined(VGP_ppc64le_linux) || defined(VGP_arm64_linux) \
3134 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
3135 || defined(VGP_nanomips_linux)
3137 /* ppc32/ppc64, arm64, mips32/64 can be configured with different
3138 page sizes. Determine this early. This is an ugly hack and really
3139 should be moved into valgrind_main. */
3140 UWord
*sp
= &pArgc
[1+argc
+1];
3143 for (; *sp
!= AT_NULL
&& *sp
!= AT_PAGESZ
; sp
+= 2);
3144 if (*sp
== AT_PAGESZ
) {
3145 VKI_PAGE_SIZE
= sp
[1];
3146 for (VKI_PAGE_SHIFT
= 12;
3147 VKI_PAGE_SHIFT
<= VKI_MAX_PAGE_SHIFT
; VKI_PAGE_SHIFT
++)
3148 if (VKI_PAGE_SIZE
== (1UL << VKI_PAGE_SHIFT
))
3154 r
= valgrind_main( (Int
)argc
, argv
, envp
);
3160 /*====================================================================*/
3161 /*=== Getting to main() alive: darwin ===*/
3162 /*====================================================================*/
3164 #elif defined(VGO_darwin)
3167 Memory layout established by kernel:
3178 executable name (presumably, a pointer to it)
3181 Ditto in the 64-bit case, except all offsets from SP are obviously
3185 /* The kernel hands control to _start, which extracts the initial
3186 stack pointer and calls onwards to _start_in_C_darwin. This also
3187 switches to the new stack. */
3188 #if defined(VGP_x86_darwin)
3192 "\t.globl __start\n"
3194 /* set up the new stack in %eax */
3195 "\tmovl $_vgPlain_interim_stack, %eax\n"
3196 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB
)", %eax\n"
3197 "\taddl $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)", %eax\n"
3198 "\tsubl $16, %eax\n"
3199 "\tandl $~15, %eax\n"
3200 /* install it, and collect the original one */
3201 "\txchgl %eax, %esp\n"
3202 "\tsubl $12, %esp\n" // keep stack 16 aligned; see #295428
3203 /* call _start_in_C_darwin, passing it the startup %esp */
3205 "\tcall __start_in_C_darwin\n"
3209 #elif defined(VGP_amd64_darwin)
3212 "\t.globl __start\n"
3215 /* set up the new stack in %rdi */
3216 "\tmovabsq $_vgPlain_interim_stack, %rdi\n"
3217 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB
)", %rdi\n"
3218 "\taddq $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)", %rdi\n"
3219 "\tandq $~15, %rdi\n"
3220 /* install it, and collect the original one */
3221 "\txchgq %rdi, %rsp\n"
3222 /* call _start_in_C_darwin, passing it the startup %rsp */
3223 "\tcall __start_in_C_darwin\n"
3229 void* __memcpy_chk(void *dest
, const void *src
, SizeT n
, SizeT n2
);
3230 void* __memcpy_chk(void *dest
, const void *src
, SizeT n
, SizeT n2
) {
3232 return VG_(memcpy
)(dest
,src
,n
);
3234 void* __memset_chk(void *s
, int c
, SizeT n
, SizeT n2
);
3235 void* __memset_chk(void *s
, int c
, SizeT n
, SizeT n2
) {
3237 return VG_(memset
)(s
,c
,n
);
3239 void __bzero(void* s
, UWord n
);
3240 void __bzero(void* s
, UWord n
) {
3241 (void)VG_(memset
)(s
,0,n
);
3243 void bzero(void *s
, SizeT n
);
3244 void bzero(void *s
, SizeT n
) {
3248 void* memcpy(void *dest
, const void *src
, SizeT n
);
3249 void* memcpy(void *dest
, const void *src
, SizeT n
) {
3250 return VG_(memcpy
)(dest
,src
,n
);
3252 void* memset(void *s
, int c
, SizeT n
);
3253 void* memset(void *s
, int c
, SizeT n
) {
3254 return VG_(memset
)(s
,c
,n
);
3257 /* Avoid compiler warnings: this fn _is_ used, but labelling it
3258 'static' causes gcc to complain it isn't. */
3259 void _start_in_C_darwin ( UWord
* pArgc
);
3260 void _start_in_C_darwin ( UWord
* pArgc
)
3263 Int argc
= *(Int
*)pArgc
; // not pArgc[0] on LP64
3264 HChar
** argv
= (HChar
**)&pArgc
[1];
3265 HChar
** envp
= (HChar
**)&pArgc
[1+argc
+1];
3267 // See _start_in_C_linux
3269 ((void) VALGRIND_STACK_REGISTER
3270 (&VG_(interim_stack
).bytes
[0],
3271 &VG_(interim_stack
).bytes
[0] + sizeof(VG_(interim_stack
))));
3273 VG_(memset
)( &the_iicii
, 0, sizeof(the_iicii
) );
3274 VG_(memset
)( &the_iifii
, 0, sizeof(the_iifii
) );
3276 the_iicii
.sp_at_startup
= (Addr
)pArgc
;
3278 r
= valgrind_main( (Int
)argc
, argv
, envp
);
3283 /*====================================================================*/
3284 /*=== Getting to main() alive: Solaris ===*/
3285 /*====================================================================*/
3286 #elif defined(VGO_solaris)
3287 #if defined(VGP_x86_solaris)
3288 /* The kernel hands control to _start, which extracts the initial stack
3289 pointer and calls onwards to _start_in_C_solaris. This also switches to
3294 "\t.type _start, @function\n"
3296 /* Set up the new stack in %eax. */
3297 "\tmovl $vgPlain_interim_stack, %eax\n"
3298 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB
)", %eax\n"
3299 "\taddl $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)", %eax\n"
3300 "\tandl $~15, %eax\n"
3301 /* Install it, and collect the original one. */
3302 "\txchgl %eax, %esp\n"
3303 "\tsubl $12, %esp\n" /* Keep stack 16-byte aligned. */
3304 /* Call _start_in_C_solaris, passing it the startup %esp. */
3306 "\tcall _start_in_C_solaris\n"
3311 #elif defined(VGP_amd64_solaris)
3315 "\t.type _start, @function\n"
3317 /* Set up the new stack in %rdi. */
3318 "\tmovq $vgPlain_interim_stack, %rdi\n"
3319 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB
)", %rdi\n"
3320 "\taddq $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)", %rdi\n"
3321 "\tandq $~15, %rdi\n"
3322 /* Install it, and collect the original one. */
3323 "\txchgq %rdi, %rsp\n"
3324 /* Call _start_in_C_solaris, passing it the startup %rsp. */
3325 "\tcall _start_in_C_solaris\n"
3331 # error "Unknown Solaris platform"
3334 void *memcpy(void *dest
, const void *src
, size_t n
);
3335 void *memcpy(void *dest
, const void *src
, size_t n
) {
3336 return VG_(memcpy
)(dest
, src
, n
);
3339 __attribute__ ((used
))
3340 void _start_in_C_solaris ( UWord
* pArgc
);
3341 __attribute__ ((used
))
3342 void _start_in_C_solaris ( UWord
* pArgc
)
3345 Word argc
= pArgc
[0];
3346 HChar
** argv
= (HChar
**)&pArgc
[1];
3347 HChar
** envp
= (HChar
**)&pArgc
[1 + argc
+ 1];
3349 VG_(memset
)( &the_iicii
, 0, sizeof(the_iicii
) );
3350 VG_(memset
)( &the_iifii
, 0, sizeof(the_iifii
) );
3352 the_iicii
.sp_at_startup
= (Addr
)pArgc
;
3354 r
= valgrind_main((Int
)argc
, argv
, envp
);
3359 /*====================================================================*/
3360 /*=== Getting to main() alive: FreeBSD ===*/
3361 /*====================================================================*/
3362 #elif defined(VGO_freebsd)
3365 * Could probably extract __FreeBSD_version at configure time
3367 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
3368 #include <sys/param.h> /* __FreeBSD_version */
3369 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
3372 * We need to add two elf notes in order for image activator to parse
3373 * additional binary properites.
3374 * First note declares the ABI, second is the feature note.
3375 * This is primarly used to turn off W^X policy for all valgrind tools,
3376 * as they don't work with it enabled.
3379 /* Based on FreeBSD sources: lib/csu/common/crtbrand.S */
3381 ".section .note.tag,\"aG\",%note,.freebsd.noteG,comdat\n"
3385 ".4byte "VG_STRINGIFY(VKI_NT_FREEBSD_ABI_TAG
)"\n"
3386 "1: .asciz \"FreeBSD\"\n"
3388 "3: .4byte "VG_STRINGIFY(__FreeBSD_version
)"\n"
3392 /* Based on FreeBSD sources: lib/csu/common/feature_note.S */
3394 ".section .note.tag,\"a\",%note\n"
3398 ".4byte "VG_STRINGIFY(VKI_NT_FREEBSD_FEATURE_CTL
)"\n"
3399 "1: .asciz \"FreeBSD\"\n"
3401 "3: .4byte "VG_STRINGIFY(VKI_NT_FREEBSD_FCTL_WXNEEDED
)"\n"
3405 #if defined(VGP_x86_freebsd)
3409 "\t.type _start,@function\n"
3411 /* set up the new stack in %eax */
3412 "\tmovl $vgPlain_interim_stack, %eax\n"
3413 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB
)", %eax\n"
3414 "\taddl $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)", %eax\n"
3415 /* allocate at least 16 bytes on the new stack, and aligned */
3416 "\tsubl $16, %eax\n"
3417 "\tandl $~15, %eax\n"
3418 /* install it, and collect the original one */
3419 "\txchgl %eax, %esp\n"
3420 "\tsubl $12, %esp\n" /* Keep stack 16-byte aligned. */
3421 /* call _start_in_C_freebsd, passing it the startup %esp */
3423 "\tcall _start_in_C_freebsd\n"
3427 #elif defined(VGP_amd64_freebsd)
3429 // @todo PJF I don't really understand why this is done this way
3430 // other amd64 platforms just put the new stack address in rdi
3431 // then do an exchange so that the stack pointer points to the
3432 // new stack and rdi (which is the 1st argument in the amd64 sysv abi)
3433 // contains the old stack
3435 // instead for amd64 the same thing is done for rsi, the second
3436 // function argument and rdi is unchanged
3438 // In gdb I see the initial rdp is 8+rsp
3440 // rdi 0x7fffffffe3b0
3441 // rsp 0x7fffffffe3a8
3443 // Maybe on FreeBSD the pointer to argc is 16byte aligned and can be 8 bytes above the
3444 // start of the stack?
3446 // Some answers to this mystery here
3447 // https://forums.freebsd.org/threads/stack-alignment-argc-location-in-assembled-binaries.89302/#post-613119
3449 // https://github.com/freebsd/freebsd-src/blob/releng/5.1/sys/amd64/amd64/machdep.c#LL487C1-L488C42
3454 "\t.type _start,@function\n"
3456 /* set up the new stack in %rsi */
3457 "\tmovq $vgPlain_interim_stack, %rsi\n"
3458 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB
)", %rsi\n"
3459 "\taddq $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)", %rsi\n"
3460 "\tandq $~15, %rsi\n"
3461 /* install it, and collect the original one */
3462 "\txchgq %rsi, %rsp\n"
3463 /* call _start_in_C_freebsd, passing it the startup %rsp */
3464 "\tcall _start_in_C_freebsd\n"
3469 #elif defined(VGP_arm64_freebsd)
3473 // x0 contains a pointer to argc
3474 // sp contains a pointer either to the same address
3475 // or 8 below it depending on whether the stack pointer
3476 // was 16byte aligned
3478 // before calling we want
3479 // x0 to contain a pointer to argc - just leave it alone
3480 // x1 to contain a pointer to the original stack in case we need it like amd64
3481 // sp to contain a pointer to the end of VG_(interim_stack)
3485 "\t.type _start,#function\n"
3486 "\t.global _start\n"
3488 "\tadrp x2, vgPlain_interim_stack\n"
3489 "\tadd x2, x2, :lo12:vgPlain_interim_stack\n"
3490 "\tldr x3, ="VG_STRINGIFY(VG_STACK_GUARD_SZB
)"\n"
3491 "\tadd x2, x2, x3\n"
3492 "\tldr x3, ="VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB
)"\n"
3493 "\tadd x2, x2, x3\n"
3494 "\tand x2, x2, -16\n"
3497 "\tb _start_in_C_freebsd\n"
3501 void *memcpy(void *dest
, const void *src
, size_t n
);
3502 void *memcpy(void *dest
, const void *src
, size_t n
) {
3503 return VG_(memcpy
)(dest
, src
, n
);
3505 void* memmove(void *dest
, const void *src
, SizeT n
);
3506 void* memmove(void *dest
, const void *src
, SizeT n
) {
3507 return VG_(memmove
)(dest
,src
,n
);
3509 void* memset(void *s
, int c
, SizeT n
);
3510 void* memset(void *s
, int c
, SizeT n
) {
3511 return VG_(memset
)(s
,c
,n
);
3514 __attribute__ ((used
))
3515 void _start_in_C_freebsd ( UWord
* pArgc
, UWord
*initial_sp
);
3516 __attribute__ ((used
))
3517 void _start_in_C_freebsd ( UWord
* pArgc
, UWord
*initial_sp
)
3520 Word argc
= pArgc
[0];
3521 HChar
** argv
= (HChar
**)&pArgc
[1];
3522 HChar
** envp
= (HChar
**)&pArgc
[1+argc
+1];
3525 ((void) VALGRIND_STACK_REGISTER
3526 (&VG_(interim_stack
).bytes
[0],
3527 &VG_(interim_stack
).bytes
[0] + sizeof(VG_(interim_stack
))));
3529 VG_(memset
)( &the_iicii
, 0, sizeof(the_iicii
) );
3530 VG_(memset
)( &the_iifii
, 0, sizeof(the_iifii
) );
3532 #if defined(VGP_amd64_freebsd) || defined(VGP_arm64_freebsd)
3533 the_iicii
.sp_at_startup
= (Addr
)initial_sp
;
3535 the_iicii
.sp_at_startup
= (Addr
)pArgc
;
3538 r
= valgrind_main( (Int
)argc
, argv
, envp
);
3544 # error "Unknown OS"
3547 SizeT
VG_(get_client_stack_max_size
)(void)
3549 return the_iifii
.clstack_max_size
;
3552 Addr
VG_(get_initial_client_SP
)( void )
3554 return the_iifii
.initial_client_SP
;
3557 /*====================================================================*/
3558 /*=== {u,}{div,mod}di3 replacements ===*/
3559 /*====================================================================*/
3561 /* For static linking on x86-darwin, we need to supply our own 64-bit
3562 integer division code, else the link dies thusly:
3564 ld_classic: Undefined symbols:
3568 #if defined(VGP_x86_darwin)
3570 /* Routines for doing signed/unsigned 64 x 64 ==> 64 div and mod
3571 (udivdi3, umoddi3, divdi3, moddi3) using only 32 x 32 ==> 32
3572 division. Cobbled together from
3574 http://www.hackersdelight.org/HDcode/divlu.c
3575 http://www.hackersdelight.org/HDcode/divls.c
3576 http://www.hackersdelight.org/HDcode/newCode/divDouble.c
3578 The code from those three files is covered by the following license,
3581 http://www.hackersdelight.org/permissions.htm
3583 You are free to use, copy, and distribute any of the code on
3584 this web site, whether modified by you or not. You need not give
3585 attribution. This includes the algorithms (some of which appear
3586 in Hacker's Delight), the Hacker's Assistant, and any code
3587 submitted by readers. Submitters implicitly agree to this.
3590 /* Long division, unsigned (64/32 ==> 32).
3591 This procedure performs unsigned "long division" i.e., division of a
3592 64-bit unsigned dividend by a 32-bit unsigned divisor, producing a
3593 32-bit quotient. In the overflow cases (divide by 0, or quotient
3594 exceeds 32 bits), it returns a remainder of 0xFFFFFFFF (an impossible
3596 The dividend is u1 and u0, with u1 being the most significant word.
3597 The divisor is parameter v. The value returned is the quotient.
3598 Max line length is 57, to fit in hacker.book. */
3600 static Int
nlz32(UInt x
)
3603 if (x
== 0) return(32);
3605 if (x
<= 0x0000FFFF) {n
= n
+16; x
= x
<<16;}
3606 if (x
<= 0x00FFFFFF) {n
= n
+ 8; x
= x
<< 8;}
3607 if (x
<= 0x0FFFFFFF) {n
= n
+ 4; x
= x
<< 4;}
3608 if (x
<= 0x3FFFFFFF) {n
= n
+ 2; x
= x
<< 2;}
3609 if (x
<= 0x7FFFFFFF) {n
= n
+ 1;}
3613 /* 64 x 32 ==> 32 unsigned division, using only 32 x 32 ==> 32
3614 division as a primitive. */
3615 static UInt
divlu2(UInt u1
, UInt u0
, UInt v
, UInt
*r
)
3617 const UInt b
= 65536; // Number base (16 bits).
3618 UInt un1
, un0
, // Norm. dividend LSD's.
3619 vn1
, vn0
, // Norm. divisor digits.
3620 q1
, q0
, // Quotient digits.
3621 un32
, un21
, un10
, // Dividend digit pairs.
3622 rhat
; // A remainder.
3623 Int s
; // Shift amount for norm.
3625 if (u1
>= v
) { // If overflow, set rem.
3626 if (r
!= NULL
) // to an impossible value,
3627 *r
= 0xFFFFFFFF; // and return the largest
3628 return 0xFFFFFFFF;} // possible quotient.
3630 s
= nlz32(v
); // 0 <= s <= 31.
3631 v
= v
<< s
; // Normalize divisor.
3632 vn1
= v
>> 16; // Break divisor up into
3633 vn0
= v
& 0xFFFF; // two 16-bit digits.
3635 un32
= (u1
<< s
) | ((u0
>> (32 - s
)) & (-s
>> 31));
3636 un10
= u0
<< s
; // Shift dividend left.
3638 un1
= un10
>> 16; // Break right half of
3639 un0
= un10
& 0xFFFF; // dividend into two digits.
3641 q1
= un32
/vn1
; // Compute the first
3642 rhat
= un32
- q1
*vn1
; // quotient digit, q1.
3644 if (q1
>= b
|| q1
*vn0
> b
*rhat
+ un1
) {
3647 if (rhat
< b
) goto again1
;}
3649 un21
= un32
*b
+ un1
- q1
*v
; // Multiply and subtract.
3651 q0
= un21
/vn1
; // Compute the second
3652 rhat
= un21
- q0
*vn1
; // quotient digit, q0.
3654 if (q0
>= b
|| q0
*vn0
> b
*rhat
+ un0
) {
3657 if (rhat
< b
) goto again2
;}
3659 if (r
!= NULL
) // If remainder is wanted,
3660 *r
= (un21
*b
+ un0
- q0
*v
) >> s
; // return it.
3665 /* 64 x 32 ==> 32 signed division, using only 32 x 32 ==> 32 division
3667 static Int
divls(Int u1
, UInt u0
, Int v
, Int
*r
)
3669 Int q
, uneg
, vneg
, diff
, borrow
;
3671 uneg
= u1
>> 31; // -1 if u < 0.
3672 if (uneg
) { // Compute the absolute
3673 u0
= -u0
; // value of the dividend u.
3677 vneg
= v
>> 31; // -1 if v < 0.
3678 v
= (v
^ vneg
) - vneg
; // Absolute value of v.
3680 if ((UInt
)u1
>= (UInt
)v
) goto overflow
;
3682 q
= divlu2(u1
, u0
, v
, (UInt
*)r
);
3684 diff
= uneg
^ vneg
; // Negate q if signs of
3685 q
= (q
^ diff
) - diff
; // u and v differed.
3686 if (uneg
&& r
!= NULL
)
3689 if ((diff
^ q
) < 0 && q
!= 0) { // If overflow,
3690 overflow
: // set remainder
3691 if (r
!= NULL
) // to an impossible value,
3692 *r
= 0x80000000; // and return the largest
3693 q
= 0x80000000;} // possible neg. quotient.
3699 /* This file contains a program for doing 64/64 ==> 64 division, on a
3700 machine that does not have that instruction but that does have
3701 instructions for "long division" (64/32 ==> 32). Code for unsigned
3702 division is given first, followed by a simple program for doing the
3703 signed version by using the unsigned version.
3704 These programs are useful in implementing "long long" (64-bit)
3705 arithmetic on a machine that has the long division instruction. It will
3706 work on 64- and 32-bit machines, provided the compiler implements long
3707 long's (64-bit integers). It is desirable that the machine have the
3708 Count Leading Zeros instruction.
3709 In the GNU world, these programs are known as __divdi3 and __udivdi3,
3710 and similar names are used here.
3711 This material is not in HD, but may be in a future edition.
3712 Max line length is 57, to fit in hacker.book. */
3715 static Int
nlz64(ULong x
)
3718 if (x
== 0) return(64);
3720 if (x
<= 0x00000000FFFFFFFFULL
) {n
= n
+ 32; x
= x
<< 32;}
3721 if (x
<= 0x0000FFFFFFFFFFFFULL
) {n
= n
+ 16; x
= x
<< 16;}
3722 if (x
<= 0x00FFFFFFFFFFFFFFULL
) {n
= n
+ 8; x
= x
<< 8;}
3723 if (x
<= 0x0FFFFFFFFFFFFFFFULL
) {n
= n
+ 4; x
= x
<< 4;}
3724 if (x
<= 0x3FFFFFFFFFFFFFFFULL
) {n
= n
+ 2; x
= x
<< 2;}
3725 if (x
<= 0x7FFFFFFFFFFFFFFFULL
) {n
= n
+ 1;}
3729 // ---------------------------- udivdi3 --------------------------------
3731 /* The variables u0, u1, etc. take on only 32-bit values, but they
3732 are declared long long to avoid some compiler warning messages and to
3733 avoid some unnecessary EXTRs that the compiler would put in, to
3734 convert long longs to ints.
3736 First the procedure takes care of the case in which the divisor is a
3737 32-bit quantity. There are two subcases: (1) If the left half of the
3738 dividend is less than the divisor, one execution of DIVU is all that
3739 is required (overflow is not possible). (2) Otherwise it does two
3740 divisions, using the grade school method, with variables used as
3750 /* These macros must be used with arguments of the appropriate type
3751 (unsigned long long for DIVU and long long for DIVS. They are
3752 simulations of the presumed machines ops. I.e., they look at only the
3753 low-order 32 bits of the divisor, they return garbage if the division
3754 overflows, and they return garbage in the high-order half of the
3755 quotient doubleword.
3756 In practice, these would be replaced with uses of the machine's DIVU
3757 and DIVS instructions (e.g., by using the GNU "asm" facility). */
3759 static UInt
DIVU ( ULong u
, UInt v
)
3761 UInt uHi
= (UInt
)(u
>> 32);
3763 return divlu2(uHi
, uLo
, v
, NULL
);
3766 static Int
DIVS ( Long u
, Int v
)
3768 Int uHi
= (Int
)(u
>> 32);
3770 return divls(uHi
, uLo
, v
, NULL
);
3773 /* 64 x 64 ==> 64 unsigned division, using only 32 x 32 ==> 32
3774 division as a primitive. */
3775 static ULong
udivdi3(ULong u
, ULong v
)
3777 ULong u0
, u1
, v1
, q0
, q1
, k
, n
;
3779 if (v
>> 32 == 0) { // If v < 2**32:
3780 if (u
>> 32 < v
) // If u/v cannot overflow,
3781 return DIVU(u
, v
) // just do one division.
3783 else { // If u/v would overflow:
3784 u1
= u
>> 32; // Break u up into two
3785 u0
= u
& 0xFFFFFFFF; // halves.
3786 q1
= DIVU(u1
, v
) // First quotient digit.
3788 k
= u1
- q1
*v
; // First remainder, < v.
3789 q0
= DIVU((k
<< 32) + u0
, v
) // 2nd quot. digit.
3791 return (q1
<< 32) + q0
;
3795 n
= nlz64(v
); // 0 <= n <= 31.
3796 v1
= (v
<< n
) >> 32; // Normalize the divisor
3798 u1
= u
>> 1; // To ensure no overflow.
3799 q1
= DIVU(u1
, v1
) // Get quotient from
3800 & 0xFFFFFFFF; // divide unsigned insn.
3801 q0
= (q1
<< n
) >> 31; // Undo normalization and
3802 // division of u by 2.
3803 if (q0
!= 0) // Make q0 correct or
3804 q0
= q0
- 1; // too small by 1.
3805 if ((u
- q0
*v
) >= v
)
3806 q0
= q0
+ 1; // Now q0 is correct.
3811 // ----------------------------- divdi3 --------------------------------
3813 /* This routine presumes that smallish cases (those which can be done in
3814 one execution of DIVS) are common. If this is not the case, the test for
3815 this case should be deleted.
3816 Note that the test for when DIVS can be used is not entirely
3817 accurate. For example, DIVS is not used if v = 0xFFFFFFFF8000000,
3818 whereas if could be (if u is sufficiently small in magnitude). */
3820 // ------------------------------ cut ----------------------------------
3822 static ULong
my_llabs ( Long x
)
3828 /* 64 x 64 ==> 64 signed division, using only 32 x 32 ==> 32 division
3830 static Long
divdi3(Long u
, Long v
)
3836 if (av
>> 31 == 0) { // If |v| < 2**31 and
3837 // if (v << 32 >> 32 == v) { // If v is in range and
3838 if (au
< av
<< 31) { // |u|/|v| cannot
3839 q
= DIVS(u
, v
); // overflow, use DIVS.
3840 return (q
<< 32) >> 32;
3843 q
= udivdi3(au
,av
); // Invoke udivdi3.
3844 t
= (u
^ v
) >> 63; // If u, v have different
3845 return (q
^ t
) - t
; // signs, negate q.
3848 // ---------------------------- end cut --------------------------------
3850 ULong
__udivdi3 (ULong u
, ULong v
);
3851 ULong
__udivdi3 (ULong u
, ULong v
)
3853 return udivdi3(u
,v
);
3856 Long
__divdi3 (Long u
, Long v
);
3857 Long
__divdi3 (Long u
, Long v
)
3862 ULong
__umoddi3 (ULong u
, ULong v
);
3863 ULong
__umoddi3 (ULong u
, ULong v
)
3865 ULong q
= __udivdi3(u
, v
);
3866 ULong r
= u
- q
* v
;
3870 Long
__moddi3 (Long u
, Long v
);
3871 Long
__moddi3 (Long u
, Long v
)
3873 Long q
= __divdi3(u
, v
);
3878 /* ------------------------------------------------
3879 ld_classic: Undefined symbols:
3881 ------------------------------------------------
3884 /* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------===
3886 * The LLVM Compiler Infrastructure
3888 * This file is dual licensed under the MIT and the University of Illinois Open
3889 * Source Licenses. See LICENSE.TXT for details.
3891 * ===----------------------------------------------------------------------===
3893 * This file implements __fixunsdfdi for the compiler_rt library.
3895 * ===----------------------------------------------------------------------===
3898 /* As per http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses,
3900 the "NCSA/University of Illinois Open Source License" is compatible
3901 with the GPL (both version 2 and 3). What is claimed to be
3904 http://www.opensource.org/licenses/UoI-NCSA.php
3906 and the LLVM documentation at
3908 http://www.llvm.org/docs/DeveloperPolicy.html#license
3910 says all the code in LLVM is available under the University of
3911 Illinois/NCSA Open Source License, at this URL
3913 http://www.opensource.org/licenses/UoI-NCSA.php
3915 viz, the same one that the FSF pages claim is compatible. So I
3916 think it's OK to include it.
3919 /* Returns: convert a to a unsigned long long, rounding toward zero.
3920 * Negative values all become zero.
3923 /* Assumption: double is a IEEE 64 bit floating point type
3924 * du_int is a 64 bit integral type
3925 * value in double is representable in du_int or is negative
3926 * (no range checking performed)
3929 /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
3931 typedef unsigned long long du_int
;
3932 typedef unsigned su_int
;
3945 #endif /* VG_LITTLEENDIAN */
3955 du_int
__fixunsdfdi(double a
);
3958 __fixunsdfdi(double a
)
3962 int e
= ((fb
.u
.s
.high
& 0x7FF00000) >> 20) - 1023;
3963 if (e
< 0 || (fb
.u
.s
.high
& 0x80000000))
3966 r
.s
.high
= (fb
.u
.s
.high
& 0x000FFFFF) | 0x00100000;
3967 r
.s
.low
= fb
.u
.s
.low
;
3979 /*====================================================================*/
3980 /*=== Dummy _voucher_mach_msg_set for OSX 10.10 ===*/
3981 /*====================================================================*/
3983 #if defined(VGO_darwin) && DARWIN_VERS >= DARWIN_10_10
3985 /* Builds on MacOSX 10.10+ seem to need this for some reason. */
3986 /* extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg)
3987 __attribute__((weak_import));
3988 I haven't a clue what the return value means, so just return 0.
3989 Looks like none of the generated uses in the tree look at the
3990 return value anyway.
3992 UWord
voucher_mach_msg_set ( UWord arg1
);
3993 UWord
voucher_mach_msg_set ( UWord arg1
)
4000 #if defined(VGO_freebsd)
4001 Word
VG_(get_usrstack
)(void)
4003 return VG_PGROUNDDN(the_iicii
.clstack_end
) + VKI_PAGE_SIZE
;
4009 /*--------------------------------------------------------------------*/
4011 /*--------------------------------------------------------------------*/