blob: 1499c8ab355542225ddb94d5a2cd7bc9bbc0d510 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00003/*--- Startup: the real stuff m_main.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00004/*--------------------------------------------------------------------*/
5
6/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjde4a1d02002-03-22 01:27:54 +00009
sewardj0f157dd2013-10-18 14:27:36 +000010 Copyright (C) 2000-2013 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
njn25e49d8e72002-09-23 09:36:25 +000028 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000029*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000032#include "pub_core_vki.h"
sewardj17c11042006-10-15 01:26:40 +000033#include "pub_core_vkiscnums.h"
sewardj6c591e12011-04-11 16:17:51 +000034#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
njnc7561b92005-06-19 01:24:32 +000035#include "pub_core_threadstate.h"
sewardj14c7cc52007-02-25 15:08:24 +000036#include "pub_core_xarray.h"
sewardj45f4e7c2005-09-27 19:20:21 +000037#include "pub_core_clientstate.h"
sewardj55f9d1a2005-04-25 11:11:44 +000038#include "pub_core_aspacemgr.h"
njnac1e0332009-05-08 00:39:31 +000039#include "pub_core_aspacehl.h"
sewardj45f4e7c2005-09-27 19:20:21 +000040#include "pub_core_commandline.h"
njn2521d322005-05-08 14:45:13 +000041#include "pub_core_debuglog.h"
42#include "pub_core_errormgr.h"
43#include "pub_core_execontext.h"
sewardj3b290482011-05-06 21:02:55 +000044#include "pub_core_gdbserver.h"
sewardj17c11042006-10-15 01:26:40 +000045#include "pub_core_initimg.h"
njn97405b22005-06-02 03:39:33 +000046#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000047#include "pub_core_libcassert.h"
njneb8896b2005-06-04 20:03:55 +000048#include "pub_core_libcfile.h"
njn36a20fa2005-06-03 03:08:39 +000049#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000050#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +000051#include "pub_core_libcsignal.h"
sewardj17c5e2e2012-12-28 09:12:14 +000052#include "pub_core_sbprofile.h"
sewardj45f4e7c2005-09-27 19:20:21 +000053#include "pub_core_syscall.h" // VG_(strerror)
njnf76d27a2009-05-28 01:53:07 +000054#include "pub_core_mach.h"
njnf536bbb2005-06-13 04:21:38 +000055#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +000056#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000057#include "pub_core_options.h"
sewardjfdf91b42005-09-28 00:53:09 +000058#include "pub_core_debuginfo.h"
njnd1af0032005-05-29 17:01:48 +000059#include "pub_core_redir.h"
njnc7561b92005-06-19 01:24:32 +000060#include "pub_core_scheduler.h"
sewardjf9ebc392010-05-09 22:30:43 +000061#include "pub_core_seqmatch.h" // For VG_(string_match)
njn0c246472005-05-31 01:00:08 +000062#include "pub_core_signals.h"
njn2025cf92005-06-26 20:44:48 +000063#include "pub_core_stacks.h" // For VG_(register_stack)
njnc1b01812005-06-17 22:19:06 +000064#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +000065#include "pub_core_tooliface.h"
sewardj17c11042006-10-15 01:26:40 +000066#include "pub_core_translate.h" // For VG_(translate)
njna7598f62005-06-18 03:27:58 +000067#include "pub_core_trampoline.h"
njn8bddf582005-05-13 23:40:55 +000068#include "pub_core_transtab.h"
florianc91f5842013-09-15 10:42:26 +000069#include "pub_core_inner.h"
philippe14711e82012-06-14 22:18:50 +000070#if defined(ENABLE_INNER_CLIENT_REQUEST)
florian1a046d52013-09-16 20:56:35 +000071#include "pub_core_clreq.h"
philippe14711e82012-06-14 22:18:50 +000072#endif
sewardj17c11042006-10-15 01:26:40 +000073
sewardjb5f6f512005-03-10 23:59:00 +000074
nethercote71980f02004-01-24 18:18:54 +000075/*====================================================================*/
sewardj71bc3cb2005-05-19 00:25:45 +000076/*=== Command-line: variables, processing, etc ===*/
77/*====================================================================*/
78
79// See pub_{core,tool}_options.h for explanations of all these.
80
sewardj45f4e7c2005-09-27 19:20:21 +000081static void usage_NORETURN ( Bool debug_help )
njn7cf0bd32002-06-08 13:36:03 +000082{
florian95a128b2011-09-29 14:26:38 +000083 /* 'usage1' contains a %s
84 - for the name of the GDB executable
85 - for the name of vgdb's path prefix
86 which must be supplied when they are VG_(printf)'d. */
floriane543f302012-10-21 19:43:43 +000087 const HChar usage1[] =
njn00cfcfc2005-11-12 18:53:50 +000088"usage: valgrind [options] prog-and-args\n"
njn25e49d8e72002-09-23 09:36:25 +000089"\n"
njn97db7612009-08-04 02:32:55 +000090" tool-selection option, with default in [ ]:\n"
sewardjb5f6f512005-03-10 23:59:00 +000091" --tool=<name> use the Valgrind tool named <name> [memcheck]\n"
njn97db7612009-08-04 02:32:55 +000092"\n"
93" basic user options for all Valgrind tools, with defaults in [ ]:\n"
nethercotea76368b2004-06-16 11:56:29 +000094" -h --help show this message\n"
nethercote6c999f22004-01-31 22:55:15 +000095" --help-debug show this message, plus debugging options\n"
njn25e49d8e72002-09-23 09:36:25 +000096" --version show version\n"
njn25e49d8e72002-09-23 09:36:25 +000097" -q --quiet run silently; only print error msgs\n"
sewardj2d9e8742009-08-07 15:46:56 +000098" -v --verbose be more verbose -- show misc extra info\n"
sewardj6e31f802007-11-17 22:29:25 +000099" --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]\n"
sewardj06421272009-11-05 08:55:13 +0000100" --trace-children-skip=patt1,patt2,... specifies a list of executables\n"
101" that --trace-children=yes should not trace into\n"
sewardj9ab64a42010-12-06 11:40:04 +0000102" --trace-children-skip-by-arg=patt1,patt2,... same as --trace-children-skip=\n"
103" but check the argv[] entries for children, rather\n"
104" than the exe name, to make a follow/no-follow decision\n"
njn97db7612009-08-04 02:32:55 +0000105" --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n"
sewardj3b290482011-05-06 21:02:55 +0000106" --vgdb=no|yes|full activate gdbserver? [yes]\n"
107" full is slower but provides precise watchpoint/step\n"
sewardj1568e172011-06-18 08:28:04 +0000108" --vgdb-error=<number> invoke gdbserver after <number> errors [%d]\n"
109" to get started quickly, use --vgdb-error=0\n"
110" and follow the on-screen directions\n"
philippe180a7502014-04-20 13:41:10 +0000111" --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none]\n"
sewardj122f6af2014-09-03 21:58:54 +0000112" where event is one of:\n"
113" startup exit valgrindabexit all none\n"
nethercote0d588502004-06-21 13:27:11 +0000114" --track-fds=no|yes track open file descriptors? [no]\n"
thughes6233a382004-08-21 11:10:44 +0000115" --time-stamp=no|yes add timestamps to log messages? [no]\n"
njnce545552005-07-25 22:36:52 +0000116" --log-fd=<number> log messages to file descriptor [2=stderr]\n"
njn374a36d2007-11-23 01:41:32 +0000117" --log-file=<file> log messages to <file>\n"
njnce545552005-07-25 22:36:52 +0000118" --log-socket=ipaddr:port log messages to socket ipaddr:port\n"
nethercote2b0793f2003-12-02 10:41:18 +0000119"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000120" user options for Valgrind tools that report errors:\n"
sewardj738856f2009-07-15 14:48:32 +0000121" --xml=yes emit error output in XML (some tools only)\n"
122" --xml-fd=<number> XML output to file descriptor\n"
123" --xml-file=<file> XML output to <file>\n"
124" --xml-socket=ipaddr:port XML output to socket ipaddr:port\n"
125" --xml-user-comment=STR copy STR verbatim into XML output\n"
nethercote2b0793f2003-12-02 10:41:18 +0000126" --demangle=no|yes automatically demangle C++ names? [yes]\n"
njn20b4a152005-10-19 22:39:40 +0000127" --num-callers=<number> show <number> callers in stack traces [12]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000128" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
sewardjb9779082006-05-12 23:50:15 +0000129" --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000130" --show-below-main=no|yes continue stack traces below main() [no]\n"
barta6efdfa2014-06-24 05:08:21 +0000131" --default-suppressions=yes|no\n"
132" load default suppressions [yes]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000133" --suppressions=<filename> suppress errors described in <filename>\n"
sewardjd153fae2005-01-10 17:24:47 +0000134" --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000135" --db-attach=no|yes start debugger when errors detected? [no]\n"
florian882038d2014-09-01 06:37:07 +0000136" Note: deprecated feature\n"
sewardj7839d112007-11-20 19:45:03 +0000137" --db-command=<command> command to start debugger [%s -nw %%f %%p]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000138" --input-fd=<number> file descriptor for input [0=stdin]\n"
njn97db7612009-08-04 02:32:55 +0000139" --dsymutil=no|yes run dsymutil on Mac OS X when helpful? [no]\n"
sewardj97724e52005-04-02 23:40:59 +0000140" --max-stackframe=<number> assume stack switch for SP changes larger\n"
141" than <number> bytes [2000000]\n"
sewardj95d86c02007-12-18 01:49:23 +0000142" --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
philippe3bcd51d2013-06-12 21:45:39 +0000143" [min(max(current 'ulimit' value,1MB),16MB)]\n"
njn97db7612009-08-04 02:32:55 +0000144"\n"
145" user options for Valgrind tools that replace malloc:\n"
philipped99c26a2012-07-31 22:17:28 +0000146" --alignment=<number> set minimum alignment of heap allocations [%s]\n"
147" --redzone-size=<number> set minimum size of redzones added before/after\n"
148" heap blocks (in bytes). [%s]\n"
njn97db7612009-08-04 02:32:55 +0000149"\n"
150" uncommon user options for all Valgrind tools:\n"
sewardj14cdbf82010-10-12 00:44:05 +0000151" --fullpath-after= (with nothing after the '=')\n"
152" show full source paths in call stacks\n"
153" --fullpath-after=string like --fullpath-after=, but only show the\n"
154" part of the path after 'string'. Allows removal\n"
155" of path prefixes. Use this flag multiple times\n"
156" to specify a set of prefixes to remove.\n"
sewardj8b6573d2012-12-05 22:15:14 +0000157" --extra-debuginfo-path=path absolute path to search for additional\n"
158" debug symbols, in addition to existing default\n"
159" well known search paths.\n"
sewardj5d616df2013-07-02 08:07:15 +0000160" --debuginfo-server=ipaddr:port also query this server\n"
161" (valgrind-di-server) for debug symbols\n"
162" --allow-mismatched-debuginfo=no|yes [no]\n"
163" for the above two flags only, accept debuginfo\n"
164" objects that don't \"match\" the main object\n"
sewardj6dbcc632011-06-07 21:39:28 +0000165" --smc-check=none|stack|all|all-non-file [stack]\n"
166" checks for self-modifying code: none, only for\n"
167" code found in stacks, for all code, or for all\n"
168" code except that from file-backed mappings\n"
philippea0a73932014-06-15 15:42:20 +0000169" --read-inline-info=yes|no read debug info about inlined function calls\n"
sewardj47c6d142014-09-12 09:22:36 +0000170" and use it to do better stack traces. [yes]\n"
171" on Linux/Android for Memcheck/Helgrind/DRD\n"
172" only. [no] for all other tools and platforms.\n"
njn97db7612009-08-04 02:32:55 +0000173" --read-var-info=yes|no read debug info on stack and global variables\n"
174" and use it to print better error messages in\n"
175" tools that make use of it (Memcheck, Helgrind,\n"
bartf6122a02010-03-27 07:38:39 +0000176" DRD) [no]\n"
sewardj3b290482011-05-06 21:02:55 +0000177" --vgdb-poll=<number> gdbserver poll max every <number> basic blocks [%d] \n"
178" --vgdb-shadow-registers=no|yes let gdb see the shadow registers [no]\n"
179" --vgdb-prefix=<prefix> prefix for vgdb FIFOs [%s]\n"
njn97db7612009-08-04 02:32:55 +0000180" --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
philippeec905f72014-08-17 20:03:51 +0000181" --sim-hints=hint1,hint2,... activate unusual sim behaviours [none] \n"
sewardj122f6af2014-09-03 21:58:54 +0000182" where hint is one of:\n"
183" lax-ioctls fuse-compatible enable-outer\n"
philippe98486902014-08-19 22:46:44 +0000184" no-inner-prefix no-nptl-pthread-stackcache none\n"
bart78bfc712011-12-08 16:14:59 +0000185" --fair-sched=no|yes|try schedule threads fairly on multicore systems [no]\n"
sewardj4450a0e2014-09-03 15:19:25 +0000186" --kernel-variant=variant1,variant2,...\n"
187" handle non-standard kernel variants [none]\n"
188" where variant is one of:\n"
sewardj124e56d2014-09-06 14:45:12 +0000189" bproc android-no-hw-tls\n"
sewardj4450a0e2014-09-03 15:19:25 +0000190" android-gpu-sgx5xx android-gpu-adreno3xx none\n"
philippe46207652013-01-20 17:11:58 +0000191" --merge-recursive-frames=<number> merge frames between identical\n"
192" program counters in max <number> frames) [0]\n"
philippe8e1bee42013-10-18 00:08:20 +0000193" --num-transtab-sectors=<number> size of translated code cache [%d]\n"
sewardja11ec172013-10-18 11:18:45 +0000194" more sectors may increase performance, but use more memory.\n"
philippee4d78122014-04-20 14:20:37 +0000195" --aspace-minaddr=0xPP avoid mapping memory below 0xPP [guessed]\n"
njn97db7612009-08-04 02:32:55 +0000196" --show-emwarns=no|yes show warnings about emulation limits? [no]\n"
sewardjf9ebc392010-05-09 22:30:43 +0000197" --require-text-symbol=:sonamepattern:symbolpattern abort run if the\n"
198" stated shared object doesn't have the stated\n"
199" text symbol. Patterns can contain ? and *.\n"
philippe1e470b52012-05-11 19:33:46 +0000200" --soname-synonyms=syn1=pattern1,syn2=pattern2,... synonym soname\n"
sewardj260c6482012-08-07 14:46:34 +0000201" specify patterns for function wrapping or replacement.\n"
202" To use a non-libc malloc library that is\n"
203" in the main exe: --soname-synonyms=somalloc=NONE\n"
204" in libxyzzy.so: --soname-synonyms=somalloc=libxyzzy.so\n"
sewardjc30cd9b2012-12-06 18:08:54 +0000205" --sigill-diagnostics=yes|no warn about illegal instructions? [yes]\n"
sewardj49984ea2013-10-18 13:21:26 +0000206" --unw-stack-scan-thresh=<number> Enable stack-scan unwind if fewer\n"
207" than <number> good frames found [0, meaning \"disabled\"]\n"
208" NOTE: stack scanning is only available on arm-linux.\n"
209" --unw-stack-scan-frames=<number> Max number of frames that can be\n"
210" recovered by stack scanning [5]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000211"\n";
njn7cf0bd32002-06-08 13:36:03 +0000212
floriane543f302012-10-21 19:43:43 +0000213 const HChar usage2[] =
njn25e49d8e72002-09-23 09:36:25 +0000214"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000215" debugging options for all Valgrind tools:\n"
njn97db7612009-08-04 02:32:55 +0000216" -d show verbose debugging output\n"
njnb1cc5d62010-07-06 04:05:23 +0000217" --stats=no|yes show tool and core statistics [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000218" --sanity-level=<number> level of sanity checking to do [1]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000219" --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
220" --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
sewardj17c5e2e2012-12-28 09:12:14 +0000221" --profile-interval=<number> show profile every <number> event checks\n"
222" [0, meaning only at the end of the run]\n"
sewardj33afdb52006-01-17 02:36:40 +0000223" --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
florian29e022d2012-07-02 21:13:34 +0000224" --trace-notabove=<number> only show BBs below <number> [0]\n"
njn25e49d8e72002-09-23 09:36:25 +0000225" --trace-syscalls=no|yes show all system calls? [no]\n"
226" --trace-signals=no|yes show signal handling details? [no]\n"
227" --trace-symtab=no|yes show symbol table details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000228" --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
sewardjce058b02005-05-01 08:55:38 +0000229" --trace-cfi=no|yes show call-frame-info details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000230" --debug-dump=syms mimic /usr/bin/readelf --syms\n"
231" --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
232" --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
sewardj0ec07f32006-01-12 12:32:32 +0000233" --trace-redir=no|yes show redirection details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000234" --trace-sched=no|yes show thread scheduler details? [no]\n"
sewardj9c606bd2008-09-18 18:12:50 +0000235" --profile-heap=no|yes profile Valgrind's own space use\n"
philippe06444372012-10-12 21:46:55 +0000236" --core-redzone-size=<number> set minimum size of redzones added before/after\n"
philipped99c26a2012-07-31 22:17:28 +0000237" heap blocks allocated for Valgrind internal use (in bytes) [4]\n"
jsgf855d93d2003-10-13 22:26:55 +0000238" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
sewardj17c11042006-10-15 01:26:40 +0000239" --sym-offsets=yes|no show syms in form 'name+offset' ? [no]\n"
sewardjb5f6f512005-03-10 23:59:00 +0000240" --command-line-only=no|yes only use command line options [no]\n"
njn613812e2005-03-11 04:57:30 +0000241"\n"
njn97db7612009-08-04 02:32:55 +0000242" Vex options for all Valgrind tools:\n"
243" --vex-iropt-verbosity=<0..9> [0]\n"
244" --vex-iropt-level=<0..2> [2]\n"
philippe5b240c22012-08-14 22:28:31 +0000245" --vex-iropt-register-updates=sp-at-mem-access\n"
246" |unwindregs-at-mem-access\n"
philippe0c0291a2012-08-01 22:03:12 +0000247" |allregs-at-mem-access\n"
248" |allregs-at-each-insn [unwindregs-at-mem-access]\n"
njn97db7612009-08-04 02:32:55 +0000249" --vex-iropt-unroll-thresh=<0..400> [120]\n"
250" --vex-guest-max-insns=<1..100> [50]\n"
251" --vex-guest-chase-thresh=<0..99> [10]\n"
sewardj540cc4a2010-01-15 10:57:57 +0000252" --vex-guest-chase-cond=no|yes [no]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000253" --trace-flags and --profile-flags values (omit the middle space):\n"
sewardj2a99cf62004-11-24 10:44:19 +0000254" 1000 0000 show conversion into IR\n"
255" 0100 0000 show after initial opt\n"
256" 0010 0000 show after instrumentation\n"
257" 0001 0000 show after second opt\n"
258" 0000 1000 show after tree building\n"
259" 0000 0100 show selecting insns\n"
260" 0000 0010 show after reg-alloc\n"
261" 0000 0001 show final assembly\n"
sewardj17c5e2e2012-12-28 09:12:14 +0000262" 0000 0000 show summary profile only\n"
sewardj5d616df2013-07-02 08:07:15 +0000263" (Nb: you need --trace-notbelow and/or --trace-notabove\n"
sewardj17c5e2e2012-12-28 09:12:14 +0000264" with --trace-flags for full details)\n"
sewardj2a99cf62004-11-24 10:44:19 +0000265"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000266" debugging options for Valgrind tools that report errors\n"
267" --dump-error=<number> show translation for basic block associated\n"
268" with <number>'th error context [0=show none]\n"
njn97db7612009-08-04 02:32:55 +0000269"\n"
270" debugging options for Valgrind tools that replace malloc:\n"
271" --trace-malloc=no|yes show client malloc details? [no]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000272"\n";
njn3e884182003-04-15 13:03:23 +0000273
floriane543f302012-10-21 19:43:43 +0000274 const HChar usage3[] =
njn3e884182003-04-15 13:03:23 +0000275"\n"
nethercote71980f02004-01-24 18:18:54 +0000276" Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
njn25e49d8e72002-09-23 09:36:25 +0000277"\n"
njn10b9aea2009-07-14 06:55:05 +0000278" %s is %s\n"
sewardj0f157dd2013-10-18 14:27:36 +0000279" Valgrind is Copyright (C) 2000-2013, and GNU GPL'd, by Julian Seward et al.\n"
280" LibVEX is Copyright (C) 2004-2013, and GNU GPL'd, by OpenWorks LLP et al.\n"
njnd04b7c62002-10-03 14:05:52 +0000281"\n"
njn10b9aea2009-07-14 06:55:05 +0000282" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
njn25e49d8e72002-09-23 09:36:25 +0000283"\n";
njn7cf0bd32002-06-08 13:36:03 +0000284
floriane6a4ed12012-10-21 02:30:18 +0000285 const HChar* gdb_path = GDB_PATH;
florian19f91bb2012-11-10 22:29:54 +0000286 HChar default_alignment[30];
287 HChar default_redzone_size[30];
sewardj12373b12007-11-20 21:38:14 +0000288
njnbe9b47b2005-05-15 16:22:58 +0000289 // Ensure the message goes to stdout
sewardj738856f2009-07-15 14:48:32 +0000290 VG_(log_output_sink).fd = 1;
291 VG_(log_output_sink).is_socket = False;
njnbe9b47b2005-05-15 16:22:58 +0000292
philipped99c26a2012-07-31 22:17:28 +0000293 if (VG_(needs).malloc_replacement) {
294 VG_(sprintf)(default_alignment, "%d", VG_MIN_MALLOC_SZB);
295 VG_(sprintf)(default_redzone_size, "%lu", VG_(tdict).tool_client_redzone_szB);
296 } else {
297 VG_(strcpy)(default_alignment, "not used by this tool");
298 VG_(strcpy)(default_redzone_size, "not used by this tool");
299 }
300 /* 'usage1' a type as described after each arg. */
sewardj3b290482011-05-06 21:02:55 +0000301 VG_(printf)(usage1,
philipped99c26a2012-07-31 22:17:28 +0000302 VG_(clo_vgdb_error) /* int */,
303 gdb_path /* char* */,
304 default_alignment /* char* */,
305 default_redzone_size /* char* */,
306 VG_(clo_vgdb_poll) /* int */,
philippe8e1bee42013-10-18 00:08:20 +0000307 VG_(vgdb_prefix_default)() /* char* */,
308 N_SECTORS_DEFAULT /* int */
philipped99c26a2012-07-31 22:17:28 +0000309 );
fitzhardinge98abfc72003-12-16 02:05:15 +0000310 if (VG_(details).name) {
311 VG_(printf)(" user options for %s:\n", VG_(details).name);
fitzhardinge98abfc72003-12-16 02:05:15 +0000312 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000313 VG_TDICT_CALL(tool_print_usage);
fitzhardinge98abfc72003-12-16 02:05:15 +0000314 else
315 VG_(printf)(" (none)\n");
316 }
nethercote6c999f22004-01-31 22:55:15 +0000317 if (debug_help) {
sewardjbbaef872008-11-01 23:55:32 +0000318 VG_(printf)("%s", usage2);
fitzhardinge98abfc72003-12-16 02:05:15 +0000319
nethercote6c999f22004-01-31 22:55:15 +0000320 if (VG_(details).name) {
321 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
322
323 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000324 VG_TDICT_CALL(tool_print_debug_usage);
nethercote6c999f22004-01-31 22:55:15 +0000325 else
326 VG_(printf)(" (none)\n");
327 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000328 }
njn10b9aea2009-07-14 06:55:05 +0000329 VG_(printf)(usage3, VG_(details).name, VG_(details).copyright_author,
330 VG_BUGS_TO);
nethercotef4928da2004-06-15 10:54:40 +0000331 VG_(exit)(0);
njn7cf0bd32002-06-08 13:36:03 +0000332}
sewardjde4a1d02002-03-22 01:27:54 +0000333
sewardjde4a1d02002-03-22 01:27:54 +0000334
sewardj95d86c02007-12-18 01:49:23 +0000335/* Peer at previously set up VG_(args_for_valgrind) and do some
336 minimal command line processing that must happen early on:
sewardj45f4e7c2005-09-27 19:20:21 +0000337
sewardj95d86c02007-12-18 01:49:23 +0000338 - show the version string, if requested (-v)
339 - extract any request for help (--help, -h, --help-debug)
340 - get the toolname (--tool=)
341 - set VG_(clo_max_stackframe) (--max-stackframe=)
342 - set VG_(clo_main_stacksize) (--main-stacksize=)
philippe72faf102012-03-11 22:24:03 +0000343 - set VG_(clo_sim_hints) (--sim-hints=)
sewardj95d86c02007-12-18 01:49:23 +0000344
345 That's all it does. The main command line processing is done below
346 by main_process_cmd_line_options. Note that
347 main_process_cmd_line_options has to handle but ignore the ones we
348 have handled here.
349*/
350static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
florian19f91bb2012-11-10 22:29:54 +0000351 /*OUT*/const HChar** tool )
sewardj45f4e7c2005-09-27 19:20:21 +0000352{
353 UInt i;
354 HChar* str;
sewardj8b635a42004-11-22 19:01:47 +0000355
sewardj14c7cc52007-02-25 15:08:24 +0000356 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000357
sewardj14c7cc52007-02-25 15:08:24 +0000358 /* parse the options we have (only the options we care about now) */
359 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
360
361 str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000362 vg_assert(str);
nethercote71980f02004-01-24 18:18:54 +0000363
njn83df0b62009-02-25 01:01:05 +0000364 // Nb: the version string goes to stdout.
sewardj738856f2009-07-15 14:48:32 +0000365 if VG_XACT_CLO(str, "--version", VG_(log_output_sink).fd, 1) {
366 VG_(log_output_sink).is_socket = False;
sewardj45f4e7c2005-09-27 19:20:21 +0000367 VG_(printf)("valgrind-" VERSION "\n");
368 VG_(exit)(0);
njn83df0b62009-02-25 01:01:05 +0000369 }
njncce38e62010-07-06 04:25:12 +0000370 else if VG_XACT_CLO(str, "--help", *need_help, *need_help+1) {}
371 else if VG_XACT_CLO(str, "-h", *need_help, *need_help+1) {}
sewardj45f4e7c2005-09-27 19:20:21 +0000372
njncce38e62010-07-06 04:25:12 +0000373 else if VG_XACT_CLO(str, "--help-debug", *need_help, *need_help+2) {}
nethercote71980f02004-01-24 18:18:54 +0000374
sewardj45f4e7c2005-09-27 19:20:21 +0000375 // The tool has already been determined, but we need to know the name
376 // here.
njn83df0b62009-02-25 01:01:05 +0000377 else if VG_STR_CLO(str, "--tool", *tool) {}
sewardj5bdfbd22007-12-15 22:13:05 +0000378
sewardj95d86c02007-12-18 01:49:23 +0000379 // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
380 // These are needed by VG_(ii_create_image), which happens
381 // before main_process_cmd_line_options().
njn83df0b62009-02-25 01:01:05 +0000382 else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
383 else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
philippe72faf102012-03-11 22:24:03 +0000384
385 // Set up VG_(clo_sim_hints). This is needed a.o. for an inner
386 // running in an outer, to have "no-inner-prefix" enabled
387 // as early as possible.
philippeec905f72014-08-17 20:03:51 +0000388 else if VG_USETX_CLO (str, "--sim-hints",
philippeb071b712014-08-24 11:24:10 +0000389 "lax-ioctls,fuse-compatible,"
390 "enable-outer,no-inner-prefix,"
philippe98486902014-08-19 22:46:44 +0000391 "no-nptl-pthread-stackcache",
philippeec905f72014-08-17 20:03:51 +0000392 VG_(clo_sim_hints)) {}
nethercote71980f02004-01-24 18:18:54 +0000393 }
nethercote71980f02004-01-24 18:18:54 +0000394}
395
sewardj95d86c02007-12-18 01:49:23 +0000396/* The main processing for command line options. See comments above
sewardj738856f2009-07-15 14:48:32 +0000397 on early_process_cmd_line_options.
398
399 Comments on how the logging options are handled:
400
401 User can specify:
402 --log-fd= for a fd to write to (default setting, fd = 2)
403 --log-file= for a file name to write to
404 --log-socket= for a socket to write to
405
406 As a result of examining these and doing relevant socket/file
407 opening, a final fd is established. This is stored in
408 VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
409 specified, then STR, after expansion of %p and %q templates within
410 it, is stored in VG_(clo_log_fname_expanded), in m_options, just in
411 case anybody wants to know what it is.
412
413 When printing, VG_(log_output_sink) is consulted to find the
414 fd to send output to.
415
416 Exactly analogous actions are undertaken for the XML output
417 channel, with the one difference that the default fd is -1, meaning
418 the channel is disabled by default.
sewardj95d86c02007-12-18 01:49:23 +0000419*/
sewardj738856f2009-07-15 14:48:32 +0000420static
421void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
florian19f91bb2012-11-10 22:29:54 +0000422 /*OUT*/HChar** xml_fname_unexpanded,
sewardj738856f2009-07-15 14:48:32 +0000423 const HChar* toolname )
nethercote71980f02004-01-24 18:18:54 +0000424{
njnda033f52005-12-19 21:27:58 +0000425 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
426 // and we cannot change it until we know what we are changing it to is
427 // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
sewardj92645592005-07-23 09:18:34 +0000428 SysRes sres;
sewardj738856f2009-07-15 14:48:32 +0000429 Int i, tmp_log_fd, tmp_xml_fd;
sewardj92645592005-07-23 09:18:34 +0000430 Int toolname_len = VG_(strlen)(toolname);
florian19f91bb2012-11-10 22:29:54 +0000431 const HChar* tmp_str; // Used in a couple of places.
njnbe9b47b2005-05-15 16:22:58 +0000432 enum {
433 VgLogTo_Fd,
434 VgLogTo_File,
njnbe9b47b2005-05-15 16:22:58 +0000435 VgLogTo_Socket
sewardj738856f2009-07-15 14:48:32 +0000436 } log_to = VgLogTo_Fd, // Where is logging output to be sent?
437 xml_to = VgLogTo_Fd; // Where is XML output to be sent?
sewardjde4a1d02002-03-22 01:27:54 +0000438
sewardj738856f2009-07-15 14:48:32 +0000439 /* Temporarily holds the string STR specified with
440 --{log,xml}-{name,socket}=STR. 'fs' stands for
441 file-or-socket. */
florian19f91bb2012-11-10 22:29:54 +0000442 const HChar* log_fsname_unexpanded = NULL;
443 const HChar* xml_fsname_unexpanded = NULL;
sewardj738856f2009-07-15 14:48:32 +0000444
sewardjc30cd9b2012-12-06 18:08:54 +0000445 /* Whether the user has explicitly provided --sigill-diagnostics.
446 If not explicitly given depends on general verbosity setting. */
447 Bool sigill_diag_set = False;
448
sewardj738856f2009-07-15 14:48:32 +0000449 /* Log to stderr by default, but usage message goes to stdout. XML
450 output is initially disabled. */
njnda033f52005-12-19 21:27:58 +0000451 tmp_log_fd = 2;
sewardj738856f2009-07-15 14:48:32 +0000452 tmp_xml_fd = -1;
453
sewardj19d81412002-06-03 01:10:40 +0000454 /* Check for sane path in ./configure --prefix=... */
fitzhardinge98abfc72003-12-16 02:05:15 +0000455 if (VG_LIBDIR[0] != '/')
sewardj17c11042006-10-15 01:26:40 +0000456 VG_(err_config_error)("Please use absolute paths in "
florian1763e812011-07-12 19:07:05 +0000457 "./configure --prefix=... or --libdir=...\n");
sewardj38170912002-05-10 21:07:22 +0000458
sewardj14c7cc52007-02-25 15:08:24 +0000459 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000460
sewardj738856f2009-07-15 14:48:32 +0000461 /* BEGIN command-line processing loop */
462
sewardj14c7cc52007-02-25 15:08:24 +0000463 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
464
465 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000466 HChar* colon = arg;
nethercote71980f02004-01-24 18:18:54 +0000467
njn1274d242007-03-26 23:38:42 +0000468 // Look for a colon in the option name.
thughes3bfd5a02004-07-18 08:05:44 +0000469 while (*colon && *colon != ':' && *colon != '=')
470 colon++;
nethercote71980f02004-01-24 18:18:54 +0000471
njn1274d242007-03-26 23:38:42 +0000472 // Does it have the form "--toolname:foo"? We have to do it at the start
473 // in case someone has combined a prefix with a core-specific option,
474 // eg. "--memcheck:verbose".
thughes3bfd5a02004-07-18 08:05:44 +0000475 if (*colon == ':') {
njn83df0b62009-02-25 01:01:05 +0000476 if (VG_STREQN(2, arg, "--") &&
477 VG_STREQN(toolname_len, arg+2, toolname) &&
478 VG_STREQN(1, arg+2+toolname_len, ":"))
nethercote71980f02004-01-24 18:18:54 +0000479 {
njn1274d242007-03-26 23:38:42 +0000480 // Prefix matches, convert "--toolname:foo" to "--foo".
481 // Two things to note:
482 // - We cannot modify the option in-place. If we did, and then
483 // a child was spawned with --trace-children=yes, the
484 // now-non-prefixed option would be passed and could screw up
485 // the child.
486 // - We create copies, and never free them. Why? Non-prefixed
487 // options hang around forever, so tools need not make copies
488 // of strings within them. We need to have the same behaviour
489 // for prefixed options. The pointer to the copy will be lost
490 // once we leave this function (although a tool may keep a
491 // pointer into it), but the space wasted is insignificant.
492 // (In bug #142197, the copies were being freed, which caused
493 // problems for tools that reasonably assumed that arguments
494 // wouldn't disappear on them.)
nethercote71980f02004-01-24 18:18:54 +0000495 if (0)
496 VG_(printf)("tool-specific arg: %s\n", arg);
sewardj9c606bd2008-09-18 18:12:50 +0000497 arg = VG_(strdup)("main.mpclo.1", arg + toolname_len + 1);
nethercote71980f02004-01-24 18:18:54 +0000498 arg[0] = '-';
499 arg[1] = '-';
500
501 } else {
502 // prefix doesn't match, skip to next arg
503 continue;
504 }
505 }
506
fitzhardinge98abfc72003-12-16 02:05:15 +0000507 /* Ignore these options - they've already been handled */
njn83df0b62009-02-25 01:01:05 +0000508 if VG_STREQN( 7, arg, "--tool=") {}
509 else if VG_STREQN(20, arg, "--command-line-only=") {}
510 else if VG_STREQ( arg, "--") {}
511 else if VG_STREQ( arg, "-d") {}
philippe06444372012-10-12 21:46:55 +0000512 else if VG_STREQN(17, arg, "--max-stackframe=") {}
513 else if VG_STREQN(17, arg, "--main-stacksize=") {}
philippee4d78122014-04-20 14:20:37 +0000514 else if VG_STREQN(12, arg, "--sim-hints=") {}
philippe06444372012-10-12 21:46:55 +0000515 else if VG_STREQN(15, arg, "--profile-heap=") {}
516 else if VG_STREQN(20, arg, "--core-redzone-size=") {}
517 else if VG_STREQN(15, arg, "--redzone-size=") {}
philippee4d78122014-04-20 14:20:37 +0000518 else if VG_STREQN(17, arg, "--aspace-minaddr=") {}
nethercote27fec902004-06-16 21:26:32 +0000519
philippe0c0291a2012-08-01 22:03:12 +0000520 /* Obsolete options. Report an error and exit */
521 else if VG_STREQN(34, arg, "--vex-iropt-precise-memory-exns=no") {
522 VG_(fmsg_bad_option)
523 (arg,
524 "--vex-iropt-precise-memory-exns is obsolete\n"
525 "Use --vex-iropt-register-updates=unwindregs-at-mem-access instead\n");
526 }
527 else if VG_STREQN(35, arg, "--vex-iropt-precise-memory-exns=yes") {
528 VG_(fmsg_bad_option)
529 (arg,
530 "--vex-iropt-precise-memory-exns is obsolete\n"
531 "Use --vex-iropt-register-updates=allregs-at-mem-access instead\n"
532 " (or --vex-iropt-register-updates=allregs-at-each-insn)\n");
533 }
534
njn83df0b62009-02-25 01:01:05 +0000535 // These options are new.
536 else if (VG_STREQ(arg, "-v") ||
537 VG_STREQ(arg, "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000538 VG_(clo_verbosity)++;
nethercote27fec902004-06-16 21:26:32 +0000539
njn83df0b62009-02-25 01:01:05 +0000540 else if (VG_STREQ(arg, "-q") ||
541 VG_STREQ(arg, "--quiet"))
sewardjde4a1d02002-03-22 01:27:54 +0000542 VG_(clo_verbosity)--;
543
sewardjc30cd9b2012-12-06 18:08:54 +0000544 else if VG_BOOL_CLO(arg, "--sigill-diagnostics", VG_(clo_sigill_diag))
545 sigill_diag_set = True;
546
sewardj2d9e8742009-08-07 15:46:56 +0000547 else if VG_BOOL_CLO(arg, "--stats", VG_(clo_stats)) {}
bartdb4384e2011-10-11 18:49:35 +0000548 else if VG_BOOL_CLO(arg, "--xml", VG_(clo_xml))
549 VG_(debugLog_setXml)(VG_(clo_xml));
550
sewardj3b290482011-05-06 21:02:55 +0000551 else if VG_XACT_CLO(arg, "--vgdb=no", VG_(clo_vgdb), Vg_VgdbNo) {}
552 else if VG_XACT_CLO(arg, "--vgdb=yes", VG_(clo_vgdb), Vg_VgdbYes) {}
philippe0c0291a2012-08-01 22:03:12 +0000553 else if VG_XACT_CLO(arg, "--vgdb=full", VG_(clo_vgdb), Vg_VgdbFull) {
554 /* automatically updates register values at each insn
555 with --vgdb=full */
556 VG_(clo_vex_control).iropt_register_updates
557 = VexRegUpdAllregsAtEachInsn;
558 }
sewardj3b290482011-05-06 21:02:55 +0000559 else if VG_INT_CLO (arg, "--vgdb-poll", VG_(clo_vgdb_poll)) {}
560 else if VG_INT_CLO (arg, "--vgdb-error", VG_(clo_vgdb_error)) {}
philippeec905f72014-08-17 20:03:51 +0000561 else if VG_USET_CLO (arg, "--vgdb-stop-at",
562 "startup,exit,valgrindabexit",
563 VG_(clo_vgdb_stop_at)) {}
philippecffe2a52014-01-11 13:56:48 +0000564 else if VG_STR_CLO (arg, "--vgdb-prefix", VG_(clo_vgdb_prefix)) {
565 VG_(arg_vgdb_prefix) = arg;
566 }
sewardj3b290482011-05-06 21:02:55 +0000567 else if VG_BOOL_CLO(arg, "--vgdb-shadow-registers",
568 VG_(clo_vgdb_shadow_registers)) {}
njn83df0b62009-02-25 01:01:05 +0000569 else if VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach)) {}
570 else if VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle)) {}
philippe1e470b52012-05-11 19:33:46 +0000571 else if VG_STR_CLO (arg, "--soname-synonyms",VG_(clo_soname_synonyms)) {}
njn83df0b62009-02-25 01:01:05 +0000572 else if VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit)) {}
573 else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
574 else if VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns)) {}
sewardj95d86c02007-12-18 01:49:23 +0000575
njn83df0b62009-02-25 01:01:05 +0000576 else if VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres)) {}
577 else if VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main)) {}
578 else if VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp)) {}
579 else if VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds)) {}
580 else if VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children)) {}
581 else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
582 VG_(clo_child_silent_after_fork)) {}
bart78bfc712011-12-08 16:14:59 +0000583 else if VG_STR_CLO(arg, "--fair-sched", tmp_str) {
584 if (VG_(strcmp)(tmp_str, "yes") == 0)
585 VG_(clo_fair_sched) = enable_fair_sched;
586 else if (VG_(strcmp)(tmp_str, "try") == 0)
587 VG_(clo_fair_sched) = try_fair_sched;
588 else if (VG_(strcmp)(tmp_str, "no") == 0)
589 VG_(clo_fair_sched) = disable_fair_sched;
590 else
mjwd898bf02014-05-16 22:38:46 +0000591 VG_(fmsg_bad_option)(arg, "");
592
bart78bfc712011-12-08 16:14:59 +0000593 }
njn83df0b62009-02-25 01:01:05 +0000594 else if VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched)) {}
595 else if VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals)) {}
596 else if VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab)) {}
597 else if VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt)) {}
598 else if VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi)) {}
599 else if VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms),
600 True) {}
601 else if VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line),
602 True) {}
603 else if VG_XACT_CLO(arg, "--debug-dump=frames",
604 VG_(clo_debug_dump_frames), True) {}
605 else if VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir)) {}
sewardj95d86c02007-12-18 01:49:23 +0000606
njn83df0b62009-02-25 01:01:05 +0000607 else if VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls)) {}
608 else if VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb)) {}
609 else if VG_STR_CLO (arg, "--db-command", VG_(clo_db_command)) {}
njn83df0b62009-02-25 01:01:05 +0000610 else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
philippea0a73932014-06-15 15:42:20 +0000611 else if VG_BOOL_CLO(arg, "--read-inline-info", VG_(clo_read_inline_info)) {}
njn83df0b62009-02-25 01:01:05 +0000612 else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
sewardjf767d962007-02-12 17:47:14 +0000613
njn83df0b62009-02-25 01:01:05 +0000614 else if VG_INT_CLO (arg, "--dump-error", VG_(clo_dump_error)) {}
615 else if VG_INT_CLO (arg, "--input-fd", VG_(clo_input_fd)) {}
616 else if VG_INT_CLO (arg, "--sanity-level", VG_(clo_sanity_level)) {}
617 else if VG_BINT_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
618 VG_DEEPEST_BACKTRACE) {}
philippe8e1bee42013-10-18 00:08:20 +0000619 else if VG_BINT_CLO(arg, "--num-transtab-sectors",
620 VG_(clo_num_transtab_sectors),
621 MIN_N_SECTORS, MAX_N_SECTORS) {}
philippe46207652013-01-20 17:11:58 +0000622 else if VG_BINT_CLO(arg, "--merge-recursive-frames",
623 VG_(clo_merge_recursive_frames), 0,
624 VG_DEEPEST_BACKTRACE) {}
sewardjde4a1d02002-03-22 01:27:54 +0000625
njn83df0b62009-02-25 01:01:05 +0000626 else if VG_XACT_CLO(arg, "--smc-check=none", VG_(clo_smc_check),
627 Vg_SmcNone);
628 else if VG_XACT_CLO(arg, "--smc-check=stack", VG_(clo_smc_check),
629 Vg_SmcStack);
630 else if VG_XACT_CLO(arg, "--smc-check=all", VG_(clo_smc_check),
631 Vg_SmcAll);
sewardj6dbcc632011-06-07 21:39:28 +0000632 else if VG_XACT_CLO(arg, "--smc-check=all-non-file",
633 VG_(clo_smc_check),
634 Vg_SmcAllNonFile);
sewardjde4a1d02002-03-22 01:27:54 +0000635
sewardj4450a0e2014-09-03 15:19:25 +0000636 else if VG_USETX_CLO (arg, "--kernel-variant",
637 "bproc,"
sewardj124e56d2014-09-06 14:45:12 +0000638 "android-no-hw-tls,"
sewardj4450a0e2014-09-03 15:19:25 +0000639 "android-gpu-sgx5xx,"
640 "android-gpu-adreno3xx",
philippeec905f72014-08-17 20:03:51 +0000641 VG_(clo_kernel_variant)) {}
sewardj26412bd2005-07-07 10:05:05 +0000642
njn97db7612009-08-04 02:32:55 +0000643 else if VG_BOOL_CLO(arg, "--dsymutil", VG_(clo_dsymutil)) {}
njnf76d27a2009-05-28 01:53:07 +0000644
sewardj9ab64a42010-12-06 11:40:04 +0000645 else if VG_STR_CLO (arg, "--trace-children-skip",
646 VG_(clo_trace_children_skip)) {}
647 else if VG_STR_CLO (arg, "--trace-children-skip-by-arg",
648 VG_(clo_trace_children_skip_by_arg)) {}
sewardj06421272009-11-05 08:55:13 +0000649
njn83df0b62009-02-25 01:01:05 +0000650 else if VG_BINT_CLO(arg, "--vex-iropt-verbosity",
651 VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
652 else if VG_BINT_CLO(arg, "--vex-iropt-level",
653 VG_(clo_vex_control).iropt_level, 0, 2) {}
philippe0c0291a2012-08-01 22:03:12 +0000654 else if VG_XACT_CLO(arg,
philippe5b240c22012-08-14 22:28:31 +0000655 "--vex-iropt-register-updates=sp-at-mem-access",
656 VG_(clo_vex_control).iropt_register_updates,
657 VexRegUpdSpAtMemAccess);
658 else if VG_XACT_CLO(arg,
philippe0c0291a2012-08-01 22:03:12 +0000659 "--vex-iropt-register-updates=unwindregs-at-mem-access",
660 VG_(clo_vex_control).iropt_register_updates,
661 VexRegUpdUnwindregsAtMemAccess);
662 else if VG_XACT_CLO(arg,
663 "--vex-iropt-register-updates=allregs-at-mem-access",
664 VG_(clo_vex_control).iropt_register_updates,
665 VexRegUpdAllregsAtMemAccess);
666 else if VG_XACT_CLO(arg,
667 "--vex-iropt-register-updates=allregs-at-each-insn",
668 VG_(clo_vex_control).iropt_register_updates,
669 VexRegUpdAllregsAtEachInsn);
njn83df0b62009-02-25 01:01:05 +0000670 else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
671 VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
672 else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
673 VG_(clo_vex_control).guest_max_insns, 1, 100) {}
674 else if VG_BINT_CLO(arg, "--vex-guest-chase-thresh",
675 VG_(clo_vex_control).guest_chase_thresh, 0, 99) {}
sewardj540cc4a2010-01-15 10:57:57 +0000676 else if VG_BOOL_CLO(arg, "--vex-guest-chase-cond",
677 VG_(clo_vex_control).guest_chase_cond) {}
sewardj94c8eb42008-09-19 20:13:39 +0000678
njn83df0b62009-02-25 01:01:05 +0000679 else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
680 log_to = VgLogTo_Fd;
sewardj738856f2009-07-15 14:48:32 +0000681 log_fsname_unexpanded = NULL;
682 }
683 else if VG_INT_CLO(arg, "--xml-fd", tmp_xml_fd) {
684 xml_to = VgLogTo_Fd;
685 xml_fsname_unexpanded = NULL;
sewardj4cf05692002-10-27 20:28:29 +0000686 }
687
sewardj738856f2009-07-15 14:48:32 +0000688 else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000689 log_to = VgLogTo_File;
sewardj4cf05692002-10-27 20:28:29 +0000690 }
sewardj738856f2009-07-15 14:48:32 +0000691 else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) {
692 xml_to = VgLogTo_File;
693 }
694
695 else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000696 log_to = VgLogTo_Socket;
sewardj73cf3bc2002-11-03 03:20:15 +0000697 }
sewardj738856f2009-07-15 14:48:32 +0000698 else if VG_STR_CLO(arg, "--xml-socket", xml_fsname_unexpanded) {
699 xml_to = VgLogTo_Socket;
700 }
sewardj73cf3bc2002-11-03 03:20:15 +0000701
sewardj5d616df2013-07-02 08:07:15 +0000702 else if VG_STR_CLO(arg, "--debuginfo-server",
703 VG_(clo_debuginfo_server)) {}
704
705 else if VG_BOOL_CLO(arg, "--allow-mismatched-debuginfo",
706 VG_(clo_allow_mismatched_debuginfo)) {}
707
njn83df0b62009-02-25 01:01:05 +0000708 else if VG_STR_CLO(arg, "--xml-user-comment",
709 VG_(clo_xml_user_comment)) {}
sewardj768db0e2005-07-19 14:18:56 +0000710
barta6efdfa2014-06-24 05:08:21 +0000711 else if VG_BOOL_CLO(arg, "--default-suppressions",
712 VG_(clo_default_supp)) { }
bart2c68e3e2014-06-22 10:11:59 +0000713
njn83df0b62009-02-25 01:01:05 +0000714 else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
sewardjde4a1d02002-03-22 01:27:54 +0000715 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njnb1cc5d62010-07-06 04:05:23 +0000716 VG_(fmsg_bad_option)(arg,
717 "Too many suppression files specified.\n"
718 "Increase VG_CLO_MAX_SFILES and recompile.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000719 }
njn83df0b62009-02-25 01:01:05 +0000720 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = tmp_str;
sewardjde4a1d02002-03-22 01:27:54 +0000721 VG_(clo_n_suppressions)++;
722 }
sewardjde4a1d02002-03-22 01:27:54 +0000723
sewardj14cdbf82010-10-12 00:44:05 +0000724 else if VG_STR_CLO (arg, "--fullpath-after", tmp_str) {
725 if (VG_(clo_n_fullpath_after) >= VG_CLO_MAX_FULLPATH_AFTER) {
726 VG_(fmsg_bad_option)(arg,
727 "Too many --fullpath-after= specifications.\n"
728 "Increase VG_CLO_MAX_FULLPATH_AFTER and recompile.\n");
729 }
730 VG_(clo_fullpath_after)[VG_(clo_n_fullpath_after)] = tmp_str;
731 VG_(clo_n_fullpath_after)++;
732 }
733
sewardj8b6573d2012-12-05 22:15:14 +0000734 else if VG_STR_CLO (arg, "--extra-debuginfo-path",
735 VG_(clo_extra_debuginfo_path)) {}
736
sewardjf9ebc392010-05-09 22:30:43 +0000737 else if VG_STR_CLO(arg, "--require-text-symbol", tmp_str) {
738 if (VG_(clo_n_req_tsyms) >= VG_CLO_MAX_REQ_TSYMS) {
njnb1cc5d62010-07-06 04:05:23 +0000739 VG_(fmsg_bad_option)(arg,
740 "Too many --require-text-symbol= specifications.\n"
741 "Increase VG_CLO_MAX_REQ_TSYMS and recompile.\n");
sewardjf9ebc392010-05-09 22:30:43 +0000742 }
743 /* String needs to be of the form C?*C?*, where C is any
744 character, but is the same both times. Having it in this
745 form facilitates finding the boundary between the sopatt
746 and the fnpatt just by looking for the second occurrence
747 of C, without hardwiring any assumption about what C
748 is. */
florian19f91bb2012-11-10 22:29:54 +0000749 HChar patt[7];
sewardjf9ebc392010-05-09 22:30:43 +0000750 Bool ok = True;
751 ok = tmp_str && VG_(strlen)(tmp_str) > 0;
752 if (ok) {
753 patt[0] = patt[3] = tmp_str[0];
754 patt[1] = patt[4] = '?';
755 patt[2] = patt[5] = '*';
756 patt[6] = 0;
757 ok = VG_(string_match)(patt, tmp_str);
758 }
759 if (!ok) {
njnb1cc5d62010-07-06 04:05:23 +0000760 VG_(fmsg_bad_option)(arg,
761 "Invalid --require-text-symbol= specification.\n");
sewardjf9ebc392010-05-09 22:30:43 +0000762 }
763 VG_(clo_req_tsyms)[VG_(clo_n_req_tsyms)] = tmp_str;
764 VG_(clo_n_req_tsyms)++;
765 }
766
sewardjfa8ec112005-01-19 11:55:34 +0000767 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000768 else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
sewardjfa8ec112005-01-19 11:55:34 +0000769 Int j;
njn83df0b62009-02-25 01:01:05 +0000770 if (8 != VG_(strlen)(tmp_str)) {
njnb1cc5d62010-07-06 04:05:23 +0000771 VG_(fmsg_bad_option)(arg,
772 "--trace-flags argument must have 8 digits\n");
sewardjfa8ec112005-01-19 11:55:34 +0000773 }
774 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000775 if ('0' == tmp_str[j]) { /* do nothing */ }
776 else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
sewardjfa8ec112005-01-19 11:55:34 +0000777 else {
njnb1cc5d62010-07-06 04:05:23 +0000778 VG_(fmsg_bad_option)(arg,
779 "--trace-flags argument can only contain 0s and 1s\n");
sewardjfa8ec112005-01-19 11:55:34 +0000780 }
781 }
782 }
783
sewardj17c5e2e2012-12-28 09:12:14 +0000784 else if VG_INT_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow)) {}
785
786 else if VG_INT_CLO (arg, "--trace-notabove", VG_(clo_trace_notabove)) {}
787
sewardjfa8ec112005-01-19 11:55:34 +0000788 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000789 else if VG_STR_CLO(arg, "--profile-flags", tmp_str) {
njn25e49d8e72002-09-23 09:36:25 +0000790 Int j;
njn83df0b62009-02-25 01:01:05 +0000791 if (8 != VG_(strlen)(tmp_str)) {
njnb1cc5d62010-07-06 04:05:23 +0000792 VG_(fmsg_bad_option)(arg,
793 "--profile-flags argument must have 8 digits\n");
njn25e49d8e72002-09-23 09:36:25 +0000794 }
sewardj8b635a42004-11-22 19:01:47 +0000795 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000796 if ('0' == tmp_str[j]) { /* do nothing */ }
sewardj17c5e2e2012-12-28 09:12:14 +0000797 else if ('1' == tmp_str[j]) VG_(clo_profyle_flags) |= (1 << (7-j));
njn25e49d8e72002-09-23 09:36:25 +0000798 else {
njnb1cc5d62010-07-06 04:05:23 +0000799 VG_(fmsg_bad_option)(arg,
800 "--profile-flags argument can only contain 0s and 1s\n");
njn25e49d8e72002-09-23 09:36:25 +0000801 }
802 }
sewardj17c5e2e2012-12-28 09:12:14 +0000803 VG_(clo_profyle_sbs) = True;
njn25e49d8e72002-09-23 09:36:25 +0000804 }
sewardjde4a1d02002-03-22 01:27:54 +0000805
sewardj17c5e2e2012-12-28 09:12:14 +0000806 else if VG_INT_CLO (arg, "--profile-interval",
807 VG_(clo_profyle_interval)) {}
florian29e022d2012-07-02 21:13:34 +0000808
njn83df0b62009-02-25 01:01:05 +0000809 else if VG_XACT_CLO(arg, "--gen-suppressions=no",
810 VG_(clo_gen_suppressions), 0) {}
811 else if VG_XACT_CLO(arg, "--gen-suppressions=yes",
812 VG_(clo_gen_suppressions), 1) {}
813 else if VG_XACT_CLO(arg, "--gen-suppressions=all",
814 VG_(clo_gen_suppressions), 2) {}
sewardjd153fae2005-01-10 17:24:47 +0000815
sewardj49984ea2013-10-18 13:21:26 +0000816 else if VG_BINT_CLO(arg, "--unw-stack-scan-thresh",
817 VG_(clo_unw_stack_scan_thresh), 0, 100) {}
818 else if VG_BINT_CLO(arg, "--unw-stack-scan-frames",
819 VG_(clo_unw_stack_scan_frames), 0, 32) {}
820
nethercote71980f02004-01-24 18:18:54 +0000821 else if ( ! VG_(needs).command_line_options
njn51d827b2005-05-09 01:02:08 +0000822 || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
njnb1cc5d62010-07-06 04:05:23 +0000823 VG_(fmsg_bad_option)(arg, "");
njn25e49d8e72002-09-23 09:36:25 +0000824 }
sewardjde4a1d02002-03-22 01:27:54 +0000825 }
826
sewardj738856f2009-07-15 14:48:32 +0000827 /* END command-line processing loop */
828
florian882038d2014-09-01 06:37:07 +0000829 /* Notify about deprecated features */
830 if (VG_(clo_db_attach))
philippe574c2fd2014-09-01 20:47:55 +0000831 VG_(umsg)
832 ("\nWarning: --db-attach is a deprecated feature which will be\n"
833 " removed in the next release. Use --vgdb-error=1 instead\n\n");
florian882038d2014-09-01 06:37:07 +0000834
florianb985e2d2011-09-29 03:03:45 +0000835 /* Determine the path prefix for vgdb */
836 if (VG_(clo_vgdb_prefix) == NULL)
837 VG_(clo_vgdb_prefix) = VG_(vgdb_prefix_default)();
838
sewardj998d40d2004-12-06 14:24:52 +0000839 /* Make VEX control parameters sane */
840
841 if (VG_(clo_vex_control).guest_chase_thresh
842 >= VG_(clo_vex_control).guest_max_insns)
843 VG_(clo_vex_control).guest_chase_thresh
844 = VG_(clo_vex_control).guest_max_insns - 1;
845
846 if (VG_(clo_vex_control).guest_chase_thresh < 0)
847 VG_(clo_vex_control).guest_chase_thresh = 0;
848
849 /* Check various option values */
nethercote27fec902004-06-16 21:26:32 +0000850
njnf9ebf672003-05-12 21:41:30 +0000851 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +0000852 VG_(clo_verbosity) = 0;
853
sewardjc30cd9b2012-12-06 18:08:54 +0000854 if (!sigill_diag_set)
855 VG_(clo_sigill_diag) = (VG_(clo_verbosity) > 0);
856
florian29e022d2012-07-02 21:13:34 +0000857 if (VG_(clo_trace_notbelow) == -1) {
858 if (VG_(clo_trace_notabove) == -1) {
859 /* [] */
860 VG_(clo_trace_notbelow) = 2147483647;
861 VG_(clo_trace_notabove) = 0;
862 } else {
863 /* [0 .. notabove] */
864 VG_(clo_trace_notbelow) = 0;
865 }
866 } else {
867 if (VG_(clo_trace_notabove) == -1) {
868 /* [notbelow .. ] */
869 VG_(clo_trace_notabove) = 2147483647;
870 } else {
871 /* [notbelow .. notabove] */
872 }
873 }
874
sewardj3b290482011-05-06 21:02:55 +0000875 VG_(dyn_vgdb_error) = VG_(clo_vgdb_error);
876
njnbe9b47b2005-05-15 16:22:58 +0000877 if (VG_(clo_gen_suppressions) > 0 &&
878 !VG_(needs).core_errors && !VG_(needs).tool_errors) {
njnb1cc5d62010-07-06 04:05:23 +0000879 VG_(fmsg_bad_option)("--gen-suppressions=yes",
880 "Can't use --gen-suppressions= with %s\n"
881 "because it doesn't generate errors.\n", VG_(details).name);
njnbe9b47b2005-05-15 16:22:58 +0000882 }
883
sewardj738856f2009-07-15 14:48:32 +0000884 /* If XML output is requested, check that the tool actually
885 supports it. */
886 if (VG_(clo_xml) && !VG_(needs).xml_output) {
887 VG_(clo_xml) = False;
njnb1cc5d62010-07-06 04:05:23 +0000888 VG_(fmsg_bad_option)("--xml=yes",
sewardj738856f2009-07-15 14:48:32 +0000889 "%s does not support XML output.\n", VG_(details).name);
sewardj738856f2009-07-15 14:48:32 +0000890 /*NOTREACHED*/
891 }
892
893 vg_assert( VG_(clo_gen_suppressions) >= 0 );
894 vg_assert( VG_(clo_gen_suppressions) <= 2 );
895
sewardj71bc3cb2005-05-19 00:25:45 +0000896 /* If we've been asked to emit XML, mash around various other
897 options so as to constrain the output somewhat, and to remove
sewardj738856f2009-07-15 14:48:32 +0000898 any need for user input during the run.
899 */
sewardj71bc3cb2005-05-19 00:25:45 +0000900 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +0000901
902 /* We can't allow --gen-suppressions=yes, since that requires us
903 to print the error and then ask the user if she wants a
904 suppression for it, but in XML mode we won't print it until
905 we know whether we also need to print a suppression. Hence a
906 circular dependency. So disallow this.
907 (--gen-suppressions=all is still OK since we don't need any
908 user interaction in this case.) */
909 if (VG_(clo_gen_suppressions) == 1) {
njnb1cc5d62010-07-06 04:05:23 +0000910 VG_(fmsg_bad_option)(
911 "--xml=yes together with --gen-suppressions=yes",
912 "When --xml=yes is specified, --gen-suppressions=no\n"
913 "or --gen-suppressions=all is allowed, but not "
sewardj738856f2009-07-15 14:48:32 +0000914 "--gen-suppressions=yes.\n");
sewardj738856f2009-07-15 14:48:32 +0000915 }
916
917 /* We can't allow DB attaching (or we maybe could, but results
918 could be chaotic ..) since it requires user input. Hence
919 disallow. */
920 if (VG_(clo_db_attach)) {
njnb1cc5d62010-07-06 04:05:23 +0000921 VG_(fmsg_bad_option)(
922 "--xml=yes together with --db-attach=yes",
923 "--db-attach=yes is not allowed with --xml=yes\n"
924 "because it would require user input.\n");
sewardj738856f2009-07-15 14:48:32 +0000925 }
926
927 /* Disallow dump_error in XML mode; sounds like a recipe for
928 chaos. No big deal; dump_error is a flag for debugging V
929 itself. */
930 if (VG_(clo_dump_error) > 0) {
mjwd898bf02014-05-16 22:38:46 +0000931 VG_(fmsg_bad_option)("--xml=yes together with --dump-error", "");
sewardj738856f2009-07-15 14:48:32 +0000932 }
933
sewardj71bc3cb2005-05-19 00:25:45 +0000934 /* Disable error limits (this might be a bad idea!) */
935 VG_(clo_error_limit) = False;
936 /* Disable emulation warnings */
sewardj738856f2009-07-15 14:48:32 +0000937
sewardj71bc3cb2005-05-19 00:25:45 +0000938 /* Also, we want to set options for the leak checker, but that
939 will have to be done in Memcheck's flag-handling code, not
940 here. */
941 }
942
njnbe9b47b2005-05-15 16:22:58 +0000943 /* All non-logging-related options have been checked. If the logging
944 option specified is ok, we can switch to it, as we know we won't
945 have to generate any other command-line-related error messages.
946 (So far we should be still attached to stderr, so we can show on
947 the terminal any problems to do with processing command line
948 opts.)
949
sewardj738856f2009-07-15 14:48:32 +0000950 So set up logging now. After this is done, VG_(log_output_sink)
951 and (if relevant) VG_(xml_output_sink) should be connected to
952 whatever sink has been selected, and we indiscriminately chuck
953 stuff into it without worrying what the nature of it is. Oh the
954 wonder of Unix streams. */
sewardj4cf05692002-10-27 20:28:29 +0000955
sewardj738856f2009-07-15 14:48:32 +0000956 vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
957 vg_assert(VG_(log_output_sink).is_socket == False);
958 vg_assert(VG_(clo_log_fname_expanded) == NULL);
959
960 vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
961 vg_assert(VG_(xml_output_sink).is_socket == False);
962 vg_assert(VG_(clo_xml_fname_expanded) == NULL);
963
964 /* --- set up the normal text output channel --- */
sewardj4cf05692002-10-27 20:28:29 +0000965
njnbe9b47b2005-05-15 16:22:58 +0000966 switch (log_to) {
sewardj73cf3bc2002-11-03 03:20:15 +0000967
sewardj4cf05692002-10-27 20:28:29 +0000968 case VgLogTo_Fd:
sewardj738856f2009-07-15 14:48:32 +0000969 vg_assert(log_fsname_unexpanded == NULL);
sewardj4cf05692002-10-27 20:28:29 +0000970 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000971
sewardj4cf05692002-10-27 20:28:29 +0000972 case VgLogTo_File: {
florian19f91bb2012-11-10 22:29:54 +0000973 HChar* logfilename;
jsgff3c3f1a2003-10-14 22:13:28 +0000974
sewardj738856f2009-07-15 14:48:32 +0000975 vg_assert(log_fsname_unexpanded != NULL);
976 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +0000977
njn374a36d2007-11-23 01:41:32 +0000978 // Nb: we overwrite an existing file of this name without asking
979 // any questions.
sewardj738856f2009-07-15 14:48:32 +0000980 logfilename = VG_(expand_file_name)("--log-file",
981 log_fsname_unexpanded);
njn374a36d2007-11-23 01:41:32 +0000982 sres = VG_(open)(logfilename,
njnda033f52005-12-19 21:27:58 +0000983 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
984 VKI_S_IRUSR|VKI_S_IWUSR);
njncda2f0f2009-05-18 02:12:08 +0000985 if (!sr_isError(sres)) {
986 tmp_log_fd = sr_Res(sres);
sewardj738856f2009-07-15 14:48:32 +0000987 VG_(clo_log_fname_expanded) = logfilename;
njnbe9b47b2005-05-15 16:22:58 +0000988 } else {
njnb1cc5d62010-07-06 04:05:23 +0000989 VG_(fmsg)("can't create log file '%s': %s\n",
990 logfilename, VG_(strerror)(sr_Err(sres)));
991 VG_(exit)(1);
sewardj603d4102005-01-11 14:01:02 +0000992 /*NOTREACHED*/
njn374a36d2007-11-23 01:41:32 +0000993 }
sewardj738856f2009-07-15 14:48:32 +0000994 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000995 }
996
997 case VgLogTo_Socket: {
sewardj738856f2009-07-15 14:48:32 +0000998 vg_assert(log_fsname_unexpanded != NULL);
999 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
1000 tmp_log_fd = VG_(connect_via_socket)( log_fsname_unexpanded );
njnda033f52005-12-19 21:27:58 +00001001 if (tmp_log_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +00001002 VG_(fmsg)("Invalid --log-socket spec of '%s'\n",
1003 log_fsname_unexpanded);
1004 VG_(exit)(1);
njnbe9b47b2005-05-15 16:22:58 +00001005 /*NOTREACHED*/
sewardj4cf05692002-10-27 20:28:29 +00001006 }
njnda033f52005-12-19 21:27:58 +00001007 if (tmp_log_fd == -2) {
njnb1cc5d62010-07-06 04:05:23 +00001008 VG_(umsg)("failed to connect to logging server '%s'.\n"
1009 "Log messages will sent to stderr instead.\n",
1010 log_fsname_unexpanded );
1011
sewardj570f8902002-11-03 11:44:36 +00001012 /* We don't change anything here. */
sewardj738856f2009-07-15 14:48:32 +00001013 vg_assert(VG_(log_output_sink).fd == 2);
njnda033f52005-12-19 21:27:58 +00001014 tmp_log_fd = 2;
sewardj570f8902002-11-03 11:44:36 +00001015 } else {
njnda033f52005-12-19 21:27:58 +00001016 vg_assert(tmp_log_fd > 0);
sewardj738856f2009-07-15 14:48:32 +00001017 VG_(log_output_sink).is_socket = True;
sewardj570f8902002-11-03 11:44:36 +00001018 }
sewardj73cf3bc2002-11-03 03:20:15 +00001019 break;
1020 }
sewardj4cf05692002-10-27 20:28:29 +00001021 }
1022
sewardj738856f2009-07-15 14:48:32 +00001023 /* --- set up the XML output channel --- */
sewardj71bc3cb2005-05-19 00:25:45 +00001024
sewardj738856f2009-07-15 14:48:32 +00001025 switch (xml_to) {
1026
1027 case VgLogTo_Fd:
1028 vg_assert(xml_fsname_unexpanded == NULL);
1029 break;
1030
1031 case VgLogTo_File: {
florian19f91bb2012-11-10 22:29:54 +00001032 HChar* xmlfilename;
sewardj738856f2009-07-15 14:48:32 +00001033
1034 vg_assert(xml_fsname_unexpanded != NULL);
1035 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
1036
1037 // Nb: we overwrite an existing file of this name without asking
1038 // any questions.
1039 xmlfilename = VG_(expand_file_name)("--xml-file",
1040 xml_fsname_unexpanded);
1041 sres = VG_(open)(xmlfilename,
1042 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
1043 VKI_S_IRUSR|VKI_S_IWUSR);
1044 if (!sr_isError(sres)) {
1045 tmp_xml_fd = sr_Res(sres);
1046 VG_(clo_xml_fname_expanded) = xmlfilename;
1047 /* strdup here is probably paranoid overkill, but ... */
1048 *xml_fname_unexpanded = VG_(strdup)( "main.mpclo.2",
1049 xml_fsname_unexpanded );
1050 } else {
njnb1cc5d62010-07-06 04:05:23 +00001051 VG_(fmsg)("can't create XML file '%s': %s\n",
1052 xmlfilename, VG_(strerror)(sr_Err(sres)));
1053 VG_(exit)(1);
sewardj738856f2009-07-15 14:48:32 +00001054 /*NOTREACHED*/
1055 }
1056 break;
1057 }
1058
1059 case VgLogTo_Socket: {
1060 vg_assert(xml_fsname_unexpanded != NULL);
1061 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
1062 tmp_xml_fd = VG_(connect_via_socket)( xml_fsname_unexpanded );
1063 if (tmp_xml_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +00001064 VG_(fmsg)("Invalid --xml-socket spec of '%s'\n",
1065 xml_fsname_unexpanded );
1066 VG_(exit)(1);
sewardj738856f2009-07-15 14:48:32 +00001067 /*NOTREACHED*/
1068 }
1069 if (tmp_xml_fd == -2) {
njnb1cc5d62010-07-06 04:05:23 +00001070 VG_(umsg)("failed to connect to XML logging server '%s'.\n"
1071 "XML output will sent to stderr instead.\n",
1072 xml_fsname_unexpanded);
sewardj738856f2009-07-15 14:48:32 +00001073 /* We don't change anything here. */
1074 vg_assert(VG_(xml_output_sink).fd == 2);
1075 tmp_xml_fd = 2;
1076 } else {
1077 vg_assert(tmp_xml_fd > 0);
1078 VG_(xml_output_sink).is_socket = True;
1079 }
1080 break;
1081 }
sewardj71bc3cb2005-05-19 00:25:45 +00001082 }
1083
sewardj738856f2009-07-15 14:48:32 +00001084 /* If we've got this far, and XML mode was requested, but no XML
1085 output channel appears to have been specified, just stop. We
1086 could continue, and XML output will simply vanish into nowhere,
1087 but that is likely to confuse the hell out of users, which is
1088 distinctly Ungood. */
1089 if (VG_(clo_xml) && tmp_xml_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +00001090 VG_(fmsg_bad_option)(
1091 "--xml=yes, but no XML destination specified",
sewardj738856f2009-07-15 14:48:32 +00001092 "--xml=yes has been specified, but there is no XML output\n"
1093 "destination. You must specify an XML output destination\n"
njnb1cc5d62010-07-06 04:05:23 +00001094 "using --xml-fd, --xml-file or --xml-socket.\n"
1095 );
sewardj738856f2009-07-15 14:48:32 +00001096 }
1097
1098 // Finalise the output fds: the log fd ..
1099
njnda033f52005-12-19 21:27:58 +00001100 if (tmp_log_fd >= 0) {
sewardj738856f2009-07-15 14:48:32 +00001101 // Move log_fd into the safe range, so it doesn't conflict with
1102 // any app fds.
njnda033f52005-12-19 21:27:58 +00001103 tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
1104 if (tmp_log_fd < 0) {
sewardj738856f2009-07-15 14:48:32 +00001105 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd "
1106 "into safe range, using stderr\n");
1107 VG_(log_output_sink).fd = 2; // stderr
1108 VG_(log_output_sink).is_socket = False;
njnda033f52005-12-19 21:27:58 +00001109 } else {
sewardj738856f2009-07-15 14:48:32 +00001110 VG_(log_output_sink).fd = tmp_log_fd;
1111 VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
njnda033f52005-12-19 21:27:58 +00001112 }
1113 } else {
1114 // If they said --log-fd=-1, don't print anything. Plausible for use in
1115 // regression testing suites that use client requests to count errors.
sewardj738856f2009-07-15 14:48:32 +00001116 VG_(log_output_sink).fd = -1;
1117 VG_(log_output_sink).is_socket = False;
jsgf855d93d2003-10-13 22:26:55 +00001118 }
1119
sewardj738856f2009-07-15 14:48:32 +00001120 // Finalise the output fds: and the XML fd ..
1121
1122 if (tmp_xml_fd >= 0) {
1123 // Move xml_fd into the safe range, so it doesn't conflict with
1124 // any app fds.
1125 tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
1126 if (tmp_xml_fd < 0) {
1127 VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd "
1128 "into safe range, using stderr\n");
1129 VG_(xml_output_sink).fd = 2; // stderr
1130 VG_(xml_output_sink).is_socket = False;
1131 } else {
1132 VG_(xml_output_sink).fd = tmp_xml_fd;
1133 VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
1134 }
1135 } else {
1136 // If they said --xml-fd=-1, don't print anything. Plausible for use in
1137 // regression testing suites that use client requests to count errors.
1138 VG_(xml_output_sink).fd = -1;
1139 VG_(xml_output_sink).is_socket = False;
1140 }
1141
1142 // Suppressions related stuff
1143
bart2c68e3e2014-06-22 10:11:59 +00001144 if (VG_(clo_default_supp) &&
1145 VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
sewardj45f4e7c2005-09-27 19:20:21 +00001146 (VG_(needs).core_errors || VG_(needs).tool_errors)) {
1147 /* If we haven't reached the max number of suppressions, load
1148 the default one. */
floriane6a4ed12012-10-21 02:30:18 +00001149 static const HChar default_supp[] = "default.supp";
sewardj45f4e7c2005-09-27 19:20:21 +00001150 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
florian77eb20b2014-09-11 21:19:17 +00001151 HChar *buf = VG_(malloc)("main.mpclo.3", len);
sewardj45f4e7c2005-09-27 19:20:21 +00001152 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
1153 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
1154 VG_(clo_n_suppressions)++;
1155 }
sewardjde4a1d02002-03-22 01:27:54 +00001156
sewardj738856f2009-07-15 14:48:32 +00001157 *logging_to_fd = log_to == VgLogTo_Fd || log_to == VgLogTo_Socket;
sewardj45f4e7c2005-09-27 19:20:21 +00001158}
1159
sewardj4efbaa72008-06-04 06:51:58 +00001160// Write the name and value of log file qualifiers to the xml file.
florian19f91bb2012-11-10 22:29:54 +00001161static void print_file_vars(HChar* format)
sewardj4efbaa72008-06-04 06:51:58 +00001162{
1163 Int i = 0;
1164
1165 while (format[i]) {
1166 if (format[i] == '%') {
1167 // We saw a '%'. What's next...
1168 i++;
1169 if ('q' == format[i]) {
1170 i++;
1171 if ('{' == format[i]) {
1172 // Get the env var name, print its contents.
florian19f91bb2012-11-10 22:29:54 +00001173 HChar* qualname;
1174 HChar* qual;
sewardj4efbaa72008-06-04 06:51:58 +00001175 i++;
1176 qualname = &format[i];
1177 while (True) {
1178 if ('}' == format[i]) {
1179 // Temporarily replace the '}' with NUL to extract var
1180 // name.
1181 format[i] = 0;
1182 qual = VG_(getenv)(qualname);
1183 break;
1184 }
1185 i++;
1186 }
1187
bartb3af9cf2011-10-06 19:08:37 +00001188 VG_(printf_xml)(
1189 "<logfilequalifier> <var>%pS</var> "
1190 "<value>%pS</value> </logfilequalifier>\n",
sewardj7ca100d2009-08-15 23:05:34 +00001191 qualname,qual
1192 );
sewardj4efbaa72008-06-04 06:51:58 +00001193 format[i] = '}';
1194 i++;
1195 }
1196 }
1197 } else {
1198 i++;
1199 }
1200 }
1201}
1202
sewardj45f4e7c2005-09-27 19:20:21 +00001203
1204/*====================================================================*/
1205/*=== Printing the preamble ===*/
1206/*====================================================================*/
1207
barta92677a2011-10-22 08:24:32 +00001208// Print the argument, escaping any chars that require it.
florian19f91bb2012-11-10 22:29:54 +00001209static void umsg_arg(const HChar* arg)
njnf8a11cf2009-08-02 23:03:06 +00001210{
1211 SizeT len = VG_(strlen)(arg);
floriane6a4ed12012-10-21 02:30:18 +00001212 const HChar* special = " \\<>";
njnf8a11cf2009-08-02 23:03:06 +00001213 Int i;
1214 for (i = 0; i < len; i++) {
1215 if (VG_(strchr)(special, arg[i])) {
barta92677a2011-10-22 08:24:32 +00001216 VG_(umsg)("\\"); // escape with a backslash if necessary
njnf8a11cf2009-08-02 23:03:06 +00001217 }
barta92677a2011-10-22 08:24:32 +00001218 VG_(umsg)("%c", arg[i]);
njnf8a11cf2009-08-02 23:03:06 +00001219 }
1220}
1221
barta92677a2011-10-22 08:24:32 +00001222// Send output to the XML-stream and escape any XML meta-characters.
florian19f91bb2012-11-10 22:29:54 +00001223static void xml_arg(const HChar* arg)
barta92677a2011-10-22 08:24:32 +00001224{
1225 VG_(printf_xml)("%pS", arg);
1226}
1227
sewardj45f4e7c2005-09-27 19:20:21 +00001228/* Ok, the logging sink is running now. Print a suitable preamble.
1229 If logging to file or a socket, write details of parent PID and
1230 command line args, to help people trying to interpret the
1231 results of a run which encompasses multiple processes. */
sewardj738856f2009-07-15 14:48:32 +00001232static void print_preamble ( Bool logging_to_fd,
florian19f91bb2012-11-10 22:29:54 +00001233 HChar* xml_fname_unexpanded,
sewardj738856f2009-07-15 14:48:32 +00001234 const HChar* toolname )
sewardj45f4e7c2005-09-27 19:20:21 +00001235{
sewardj738856f2009-07-15 14:48:32 +00001236 Int i;
florian6bd9dc12012-11-23 16:17:43 +00001237 const HChar* xpre = VG_(clo_xml) ? " <line>" : "";
1238 const HChar* xpost = VG_(clo_xml) ? "</line>" : "";
sewardj738856f2009-07-15 14:48:32 +00001239 UInt (*umsg_or_xml)( const HChar*, ... )
1240 = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
tom60a4b0b2005-10-12 10:45:27 +00001241
florian19f91bb2012-11-10 22:29:54 +00001242 void (*umsg_or_xml_arg)( const HChar* )
barta92677a2011-10-22 08:24:32 +00001243 = VG_(clo_xml) ? xml_arg : umsg_arg;
1244
sewardj14c7cc52007-02-25 15:08:24 +00001245 vg_assert( VG_(args_for_client) );
1246 vg_assert( VG_(args_for_valgrind) );
sewardj99a2ceb2007-11-09 12:30:36 +00001247 vg_assert( toolname );
sewardj14c7cc52007-02-25 15:08:24 +00001248
sewardj71bc3cb2005-05-19 00:25:45 +00001249 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001250 VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
1251 VG_(printf_xml)("\n");
1252 VG_(printf_xml)("<valgrindoutput>\n");
1253 VG_(printf_xml)("\n");
1254 VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
1255 VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", toolname);
1256 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001257 }
1258
sewardj738856f2009-07-15 14:48:32 +00001259 if (VG_(clo_xml) || VG_(clo_verbosity > 0)) {
sewardjd7bddad2005-06-13 16:48:32 +00001260
1261 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001262 VG_(printf_xml)("<preamble>\n");
sewardjd7bddad2005-06-13 16:48:32 +00001263
nethercote996901a2004-08-03 13:29:09 +00001264 /* Tool details */
bartb3af9cf2011-10-06 19:08:37 +00001265 umsg_or_xml( VG_(clo_xml) ? "%s%pS%pS%pS, %pS%s\n" : "%s%s%s%s, %s%s\n",
sewardj71bc3cb2005-05-19 00:25:45 +00001266 xpre,
njnd04b7c62002-10-03 14:05:52 +00001267 VG_(details).name,
njnb9c427c2004-12-01 14:14:42 +00001268 NULL == VG_(details).version ? "" : "-",
njnd04b7c62002-10-03 14:05:52 +00001269 NULL == VG_(details).version
floriane6a4ed12012-10-21 02:30:18 +00001270 ? "" : VG_(details).version,
sewardj71bc3cb2005-05-19 00:25:45 +00001271 VG_(details).description,
sewardj738856f2009-07-15 14:48:32 +00001272 xpost );
sewardj99a2ceb2007-11-09 12:30:36 +00001273
njn10b9aea2009-07-14 06:55:05 +00001274 if (VG_(strlen)(toolname) >= 4 && VG_STREQN(4, toolname, "exp-")) {
sewardj738856f2009-07-15 14:48:32 +00001275 umsg_or_xml(
njnb6267bd2009-08-12 00:14:16 +00001276 "%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
sewardj99a2ceb2007-11-09 12:30:36 +00001277 xpre, xpost
1278 );
1279 }
1280
bartb3af9cf2011-10-06 19:08:37 +00001281 umsg_or_xml( VG_(clo_xml) ? "%s%pS%s\n" : "%s%s%s\n",
sewardj743a2082010-07-23 17:03:22 +00001282 xpre, VG_(details).copyright_author, xpost );
sewardj3b2736a2002-03-24 12:18:35 +00001283
njnd04b7c62002-10-03 14:05:52 +00001284 /* Core details */
sewardj738856f2009-07-15 14:48:32 +00001285 umsg_or_xml(
njnf73d87f2009-07-24 04:47:04 +00001286 "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
1287 xpre, VERSION, xpost
sewardj738856f2009-07-15 14:48:32 +00001288 );
sewardj45f4e7c2005-09-27 19:20:21 +00001289
njnf3977a32009-08-04 00:27:56 +00001290 // Print the command line. At one point we wrapped at 80 chars and
1291 // printed a '\' as a line joiner, but that makes it hard to cut and
1292 // paste the command line (because of the "==pid==" prefixes), so we now
1293 // favour utility and simplicity over aesthetics.
1294 umsg_or_xml("%sCommand: ", xpre);
florianb16609b2014-08-20 21:04:14 +00001295 umsg_or_xml_arg(VG_(args_the_exename));
barta92677a2011-10-22 08:24:32 +00001296
njn53162bf2009-07-29 23:34:49 +00001297 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1298 HChar* s = *(HChar**)VG_(indexXA)( VG_(args_for_client), i );
njnf8a11cf2009-08-02 23:03:06 +00001299 umsg_or_xml(" ");
barta92677a2011-10-22 08:24:32 +00001300 umsg_or_xml_arg(s);
njn53162bf2009-07-29 23:34:49 +00001301 }
njnf3977a32009-08-04 00:27:56 +00001302 umsg_or_xml("%s\n", xpost);
njn53162bf2009-07-29 23:34:49 +00001303
sewardjd7bddad2005-06-13 16:48:32 +00001304 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001305 VG_(printf_xml)("</preamble>\n");
njnd04b7c62002-10-03 14:05:52 +00001306 }
1307
njnb6267bd2009-08-12 00:14:16 +00001308 // Print the parent PID, and other stuff, if necessary.
sewardj45f4e7c2005-09-27 19:20:21 +00001309 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
njn305dc002009-07-30 23:36:43 +00001310 VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
sewardj4cf05692002-10-27 20:28:29 +00001311 }
sewardj71bc3cb2005-05-19 00:25:45 +00001312 else
1313 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001314 VG_(printf_xml)("\n");
1315 VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
1316 VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
bartb3af9cf2011-10-06 19:08:37 +00001317 VG_(printf_xml)("<tool>%pS</tool>\n", toolname);
sewardj738856f2009-07-15 14:48:32 +00001318 if (xml_fname_unexpanded)
1319 print_file_vars(xml_fname_unexpanded);
sewardj768db0e2005-07-19 14:18:56 +00001320 if (VG_(clo_xml_user_comment)) {
1321 /* Note: the user comment itself is XML and is therefore to
1322 be passed through verbatim (%s) rather than escaped
bartb3af9cf2011-10-06 19:08:37 +00001323 (%pS). */
sewardj738856f2009-07-15 14:48:32 +00001324 VG_(printf_xml)("<usercomment>%s</usercomment>\n",
1325 VG_(clo_xml_user_comment));
sewardj768db0e2005-07-19 14:18:56 +00001326 }
sewardj738856f2009-07-15 14:48:32 +00001327 VG_(printf_xml)("\n");
1328 VG_(printf_xml)("<args>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001329
sewardj738856f2009-07-15 14:48:32 +00001330 VG_(printf_xml)(" <vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001331 if (VG_(name_of_launcher))
bartb3af9cf2011-10-06 19:08:37 +00001332 VG_(printf_xml)(" <exe>%pS</exe>\n",
sewardj738856f2009-07-15 14:48:32 +00001333 VG_(name_of_launcher));
sewardj125fd4f2007-03-08 19:56:14 +00001334 else
bartb3af9cf2011-10-06 19:08:37 +00001335 VG_(printf_xml)(" <exe>%pS</exe>\n",
njnb1cc5d62010-07-06 04:05:23 +00001336 "(launcher name unknown)");
sewardj14c7cc52007-02-25 15:08:24 +00001337 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
bartb3af9cf2011-10-06 19:08:37 +00001338 VG_(printf_xml)(
1339 " <arg>%pS</arg>\n",
sewardj738856f2009-07-15 14:48:32 +00001340 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1341 );
sewardjb8a3dac2005-07-19 12:39:11 +00001342 }
sewardj738856f2009-07-15 14:48:32 +00001343 VG_(printf_xml)(" </vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001344
sewardj738856f2009-07-15 14:48:32 +00001345 VG_(printf_xml)(" <argv>\n");
florianb16609b2014-08-20 21:04:14 +00001346 VG_(printf_xml)(" <exe>%pS</exe>\n",
sewardj738856f2009-07-15 14:48:32 +00001347 VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001348 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
bartb3af9cf2011-10-06 19:08:37 +00001349 VG_(printf_xml)(
1350 " <arg>%pS</arg>\n",
sewardj738856f2009-07-15 14:48:32 +00001351 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1352 );
sewardj8665d8e2005-06-01 17:35:23 +00001353 }
sewardj738856f2009-07-15 14:48:32 +00001354 VG_(printf_xml)(" </argv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001355
sewardj738856f2009-07-15 14:48:32 +00001356 VG_(printf_xml)("</args>\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001357 }
sewardj4cf05692002-10-27 20:28:29 +00001358
njnb6267bd2009-08-12 00:14:16 +00001359 // Last thing in the preamble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00001360 if (VG_(clo_xml))
1361 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00001362 else if (VG_(clo_verbosity) > 0)
1363 VG_(umsg)("\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001364
sewardjde4a1d02002-03-22 01:27:54 +00001365 if (VG_(clo_verbosity) > 1) {
sewardj92645592005-07-23 09:18:34 +00001366 SysRes fd;
sewardj1f0bbc72005-11-16 03:51:02 +00001367 VexArch vex_arch;
1368 VexArchInfo vex_archinfo;
sewardj45f4e7c2005-09-27 19:20:21 +00001369 if (!logging_to_fd)
sewardj738856f2009-07-15 14:48:32 +00001370 VG_(message)(Vg_DebugMsg, "\n");
njna3311642009-08-10 01:29:14 +00001371 VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
sewardj14c7cc52007-02-25 15:08:24 +00001372 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
1373 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001374 " %s\n",
sewardj14c7cc52007-02-25 15:08:24 +00001375 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjde4a1d02002-03-22 01:27:54 +00001376 }
nethercotea70f7352004-04-18 12:08:46 +00001377
sewardj738856f2009-07-15 14:48:32 +00001378 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
nethercotea70f7352004-04-18 12:08:46 +00001379 fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
njncda2f0f2009-05-18 02:12:08 +00001380 if (sr_isError(fd)) {
sewardj738856f2009-07-15 14:48:32 +00001381 VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
nethercotea70f7352004-04-18 12:08:46 +00001382 } else {
sewardj71bc3cb2005-05-19 00:25:45 +00001383# define BUF_LEN 256
florian19f91bb2012-11-10 22:29:54 +00001384 HChar version_buf[BUF_LEN];
njnf3977a32009-08-04 00:27:56 +00001385 Int n = VG_(read) ( sr_Res(fd), version_buf, BUF_LEN );
1386 vg_assert(n <= BUF_LEN);
1387 if (n > 0) {
1388 version_buf[n-1] = '\0';
sewardj738856f2009-07-15 14:48:32 +00001389 VG_(message)(Vg_DebugMsg, " %s\n", version_buf);
nethercotea70f7352004-04-18 12:08:46 +00001390 } else {
sewardj738856f2009-07-15 14:48:32 +00001391 VG_(message)(Vg_DebugMsg, " (empty?)\n");
nethercotea70f7352004-04-18 12:08:46 +00001392 }
njncda2f0f2009-05-18 02:12:08 +00001393 VG_(close)(sr_Res(fd));
sewardj71bc3cb2005-05-19 00:25:45 +00001394# undef BUF_LEN
nethercotea70f7352004-04-18 12:08:46 +00001395 }
sewardj1f0bbc72005-11-16 03:51:02 +00001396
1397 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001398 VG_(message)(
1399 Vg_DebugMsg,
sewardj59731422014-07-24 12:45:24 +00001400 "Arch and hwcaps: %s, %s, %s\n",
1401 LibVEX_ppVexArch ( vex_arch ),
1402 LibVEX_ppVexEndness ( vex_archinfo.endness ),
1403 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
sewardje3121f32006-01-27 21:23:23 +00001404 );
sewardje66f2e02006-12-30 17:45:08 +00001405 VG_(message)(
1406 Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001407 "Page sizes: currently %d, max supported %d\n",
sewardje66f2e02006-12-30 17:45:08 +00001408 (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
1409 );
sewardj738856f2009-07-15 14:48:32 +00001410 VG_(message)(Vg_DebugMsg,
1411 "Valgrind library directory: %s\n", VG_(libdir));
sewardjde4a1d02002-03-22 01:27:54 +00001412 }
nethercotef6a1d502004-08-09 12:21:57 +00001413}
1414
sewardjde4a1d02002-03-22 01:27:54 +00001415
nethercote71980f02004-01-24 18:18:54 +00001416/*====================================================================*/
1417/*=== File descriptor setup ===*/
1418/*====================================================================*/
1419
sewardj5f229e22005-09-28 01:36:01 +00001420/* Number of file descriptors that Valgrind tries to reserve for
1421 it's own use - just a small constant. */
1422#define N_RESERVED_FDS (10)
1423
nethercote71980f02004-01-24 18:18:54 +00001424static void setup_file_descriptors(void)
1425{
1426 struct vki_rlimit rl;
sewardj17c11042006-10-15 01:26:40 +00001427 Bool show = False;
nethercote71980f02004-01-24 18:18:54 +00001428
1429 /* Get the current file descriptor limits. */
1430 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
1431 rl.rlim_cur = 1024;
1432 rl.rlim_max = 1024;
1433 }
1434
njnf76d27a2009-05-28 01:53:07 +00001435# if defined(VGO_darwin)
1436 /* Darwin lies. It reports file max as RLIM_INFINITY but
1437 silently disallows anything bigger than 10240. */
1438 if (rl.rlim_cur >= 10240 && rl.rlim_max == 0x7fffffffffffffffULL) {
1439 rl.rlim_max = 10240;
1440 }
1441# endif
1442
sewardj17c11042006-10-15 01:26:40 +00001443 if (show)
njn8a7b41b2007-09-23 00:51:24 +00001444 VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001445 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001446
nethercote71980f02004-01-24 18:18:54 +00001447 /* Work out where to move the soft limit to. */
njn14319cc2005-03-13 06:26:22 +00001448 if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
1449 rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001450 } else {
1451 rl.rlim_cur = rl.rlim_max;
1452 }
1453
1454 /* Reserve some file descriptors for our use. */
njn14319cc2005-03-13 06:26:22 +00001455 VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
1456 VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001457
1458 /* Update the soft limit. */
1459 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
1460
sewardj17c11042006-10-15 01:26:40 +00001461 if (show) {
njn8a7b41b2007-09-23 00:51:24 +00001462 VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001463 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001464 VG_(printf)("fd limits: guest : cur %u max %u\n",
1465 VG_(fd_soft_limit), VG_(fd_hard_limit));
1466 }
1467
sewardj45f4e7c2005-09-27 19:20:21 +00001468 if (VG_(cl_exec_fd) != -1)
1469 VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
nethercote71980f02004-01-24 18:18:54 +00001470}
1471
sewardjde4a1d02002-03-22 01:27:54 +00001472
njn2da73352005-06-18 01:35:16 +00001473/*====================================================================*/
nethercote71980f02004-01-24 18:18:54 +00001474/*=== main() ===*/
1475/*====================================================================*/
1476
sewardjfdf91b42005-09-28 00:53:09 +00001477/* When main() is entered, we should be on the following stack, not
1478 the one the kernel gave us. We will run on this stack until
1479 simulation of the root thread is started, at which point a transfer
1480 is made to a dynamically allocated stack. This is for the sake of
1481 uniform overflow detection for all Valgrind threads. This is
1482 marked global even though it isn't, because assembly code below
1483 needs to reference the name. */
1484
1485/*static*/ VgStack VG_(interim_stack);
1486
sewardjf9d2f9b2006-11-17 20:00:57 +00001487/* These are the structures used to hold info for creating the initial
1488 client image.
1489
1490 'iicii' mostly holds important register state present at system
1491 startup (_start_valgrind). valgrind_main() then fills in the rest
1492 of it and passes it to VG_(ii_create_image)(). That produces
1493 'iifii', which is later handed to VG_(ii_finalise_image). */
1494
1495/* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1496 This should get some address inside the stack on which we gained
sewardjfdf91b42005-09-28 00:53:09 +00001497 control (eg, it could be the SP at startup). It doesn't matter
1498 exactly where in the stack it is. This value is passed to the
sewardjf9d2f9b2006-11-17 20:00:57 +00001499 address space manager at startup. On Linux, aspacem then uses it
1500 to identify the initial stack segment and hence the upper end of
1501 the usable address space. */
sewardjfdf91b42005-09-28 00:53:09 +00001502
sewardjf9d2f9b2006-11-17 20:00:57 +00001503static IICreateImageInfo the_iicii;
1504static IIFinaliseImageInfo the_iifii;
1505
sewardjfdf91b42005-09-28 00:53:09 +00001506
sewardj9c606bd2008-09-18 18:12:50 +00001507/* A simple pair structure, used for conveying debuginfo handles to
1508 calls to VG_TRACK(new_mem_startup, ...). */
1509typedef struct { Addr a; ULong ull; } Addr_n_ULong;
1510
1511
sewardj1ae3f3a2005-09-28 10:47:38 +00001512/* --- Forwards decls to do with shutdown --- */
1513
1514static void final_tidyup(ThreadId tid);
1515
1516/* Do everything which needs doing when the last thread exits */
1517static
1518void shutdown_actions_NORETURN( ThreadId tid,
1519 VgSchedReturnCode tids_schedretcode );
1520
1521/* --- end of Forwards decls to do with shutdown --- */
sewardjfdf91b42005-09-28 00:53:09 +00001522
1523
sewardjf9d2f9b2006-11-17 20:00:57 +00001524/* By the time we get to valgrind_main, the_iicii should already have
1525 been filled in with any important details as required by whatever
1526 OS we have been built for.
1527*/
sewardj17c11042006-10-15 01:26:40 +00001528static
sewardjf9d2f9b2006-11-17 20:00:57 +00001529Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
nethercote71980f02004-01-24 18:18:54 +00001530{
florian19f91bb2012-11-10 22:29:54 +00001531 const HChar* toolname = "memcheck"; // default to Memcheck
sewardj13247ca2005-12-30 22:52:20 +00001532 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
sewardjde764e82007-11-09 23:13:22 +00001533 ThreadId tid_main = VG_INVALID_THREADID;
sewardj738856f2009-07-15 14:48:32 +00001534 Bool logging_to_fd = False;
florian19f91bb2012-11-10 22:29:54 +00001535 HChar* xml_fname_unexpanded = NULL;
sewardj45f4e7c2005-09-27 19:20:21 +00001536 Int loglevel, i;
nethercote73b526f2004-10-31 18:48:21 +00001537 struct vki_rlimit zero = { 0, 0 };
sewardj9c606bd2008-09-18 18:12:50 +00001538 XArray* addr2dihandle = NULL;
sewardj17c11042006-10-15 01:26:40 +00001539
nethercote71980f02004-01-24 18:18:54 +00001540 //============================================================
nethercote71980f02004-01-24 18:18:54 +00001541 //
sewardj45f4e7c2005-09-27 19:20:21 +00001542 // Nb: startup is complex. Prerequisites are shown at every step.
nethercote71980f02004-01-24 18:18:54 +00001543 // *** Be very careful when messing with the order ***
sewardj45f4e7c2005-09-27 19:20:21 +00001544 //
1545 // The first order of business is to get debug logging, the address
1546 // space manager and the dynamic memory manager up and running.
1547 // Once that's done, we can relax a bit.
1548 //
nethercote71980f02004-01-24 18:18:54 +00001549 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001550
1551 /* This is needed to make VG_(getenv) usable early. */
florian19f91bb2012-11-10 22:29:54 +00001552 VG_(client_envp) = (HChar**)envp;
nethercote71980f02004-01-24 18:18:54 +00001553
sewardj1cf558c2005-04-25 01:36:56 +00001554 //--------------------------------------------------------------
njnf76d27a2009-05-28 01:53:07 +00001555 // Start up Mach kernel interface, if any
1556 // p: none
1557 //--------------------------------------------------------------
1558# if defined(VGO_darwin)
1559 VG_(mach_init)();
1560# endif
1561
1562 //--------------------------------------------------------------
sewardj1cf558c2005-04-25 01:36:56 +00001563 // Start up the logging mechanism
1564 // p: none
1565 //--------------------------------------------------------------
1566 /* Start the debugging-log system ASAP. First find out how many
njn83df0b62009-02-25 01:01:05 +00001567 "-d"s were specified. This is a pre-scan of the command line. Also
philippee4d78122014-04-20 14:20:37 +00001568 get --profile-heap=yes, --core-redzone-size, --redzone-size
1569 --aspace-minaddr which are needed by the time we start up dynamic
1570 memory management. */
sewardj1cf558c2005-04-25 01:36:56 +00001571 loglevel = 0;
1572 for (i = 1; i < argc; i++) {
philippee4d78122014-04-20 14:20:37 +00001573 const HChar* tmp_str;
njn83df0b62009-02-25 01:01:05 +00001574 if (argv[i][0] != '-') break;
1575 if VG_STREQ(argv[i], "--") break;
1576 if VG_STREQ(argv[i], "-d") loglevel++;
1577 if VG_BOOL_CLO(argv[i], "--profile-heap", VG_(clo_profile_heap)) {}
philipped99c26a2012-07-31 22:17:28 +00001578 if VG_BINT_CLO(argv[i], "--core-redzone-size", VG_(clo_core_redzone_size),
1579 0, MAX_CLO_REDZONE_SZB) {}
1580 if VG_BINT_CLO(argv[i], "--redzone-size", VG_(clo_redzone_size),
1581 0, MAX_CLO_REDZONE_SZB) {}
philippee4d78122014-04-20 14:20:37 +00001582 if VG_STR_CLO(argv[i], "--aspace-minaddr", tmp_str) {
1583# if VG_WORDSIZE == 4
1584 const Addr max = (Addr) 0x40000000; // 1Gb
1585# else
1586 const Addr max = (Addr) 0x200000000; // 8Gb
1587# endif
1588 Bool ok = VG_(parse_Addr) (&tmp_str, &VG_(clo_aspacem_minAddr));
1589 if (!ok)
1590 VG_(fmsg_bad_option)(argv[i], "Invalid address\n");
1591
1592 if (!VG_IS_PAGE_ALIGNED(VG_(clo_aspacem_minAddr))
1593 || VG_(clo_aspacem_minAddr) < (Addr) 0x1000
1594 || VG_(clo_aspacem_minAddr) > max) // 1Gb
1595 VG_(fmsg_bad_option)(argv[i],
1596 "Must be a page aligned address between "
1597 "0x1000 and 0x%lx\n", max);
1598 }
sewardj1cf558c2005-04-25 01:36:56 +00001599 }
1600
1601 /* ... and start the debug logger. Now we can safely emit logging
1602 messages all through startup. */
sewardj10759312005-05-30 23:52:47 +00001603 VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
sewardj45f4e7c2005-09-27 19:20:21 +00001604 VG_(debugLog)(1, "main", "Welcome to Valgrind version "
1605 VERSION " debug logging\n");
1606
1607 //--------------------------------------------------------------
1608 // Ensure we're on a plausible stack.
1609 // p: logging
1610 //--------------------------------------------------------------
1611 VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
sewardjfdf91b42005-09-28 00:53:09 +00001612 { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
1613 HChar* limHi = limLo + sizeof(VG_(interim_stack));
sewardjed8b0f62012-09-02 21:17:36 +00001614 HChar* volatile
1615 aLocal = (HChar*)&limLo; /* any auto local will do */
1616 /* Re "volatile": Apple clang version 4.0
1617 (tags/Apple/clang-421.0.57) (based on LLVM 3.1svn)" appeared
1618 to miscompile the following check, causing run to abort at
1619 this point (in 64-bit mode) even though aLocal is within limLo
1620 .. limHi. But in fact clang is within its rights to do
1621 strange things here. "The reason is that the comparisons
1622 aLocal < limLo and aLocal >= limHi cause undefined behaviour
1623 (according to c99 6.5.8) because they compare pointers that do
1624 not point into the same aggregate." Adding "volatile" appears
1625 to fix it because "The compiler would have to prove that there
1626 is undefined behavior in order to exploit it. But as a
1627 volatile variable can change its value in ways invisible to
1628 the compiler, the compiler must make the conservative
1629 assumption that it points into the same aggregate as the other
1630 pointer its compared against. I.e. the behaviour is possibly
1631 defined." (Analysis by Florian Krohm). */
sewardj45f4e7c2005-09-27 19:20:21 +00001632 if (aLocal < limLo || aLocal >= limHi) {
1633 /* something's wrong. Stop. */
1634 VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
1635 limLo, limHi, aLocal );
1636 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1637 "Initial stack switched failed.\n");
1638 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1639 VG_(exit)(1);
1640 }
1641 }
1642
1643 //--------------------------------------------------------------
1644 // Ensure we have a plausible pointer to the stack on which
1645 // we gained control (not the current stack!)
1646 // p: logging
1647 //--------------------------------------------------------------
1648 VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
sewardjf9d2f9b2006-11-17 20:00:57 +00001649 if (the_iicii.sp_at_startup == 0) {
sewardj45f4e7c2005-09-27 19:20:21 +00001650 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1651 "Initial stack was not noted.\n");
1652 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1653 VG_(exit)(1);
1654 }
1655
1656 //--------------------------------------------------------------
1657 // Start up the address space manager, and determine the
1658 // approximate location of the client's stack
njnea2d6fd2010-07-01 00:20:20 +00001659 // p: logging, plausible-stack
sewardj45f4e7c2005-09-27 19:20:21 +00001660 //--------------------------------------------------------------
1661 VG_(debugLog)(1, "main", "Starting the address space manager\n");
sewardj5db15402012-06-07 09:13:21 +00001662 vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536
1663 || VKI_PAGE_SIZE == 16384);
1664 vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536
1665 || VKI_MAX_PAGE_SIZE == 16384);
sewardje66f2e02006-12-30 17:45:08 +00001666 vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
1667 vg_assert(VKI_PAGE_SIZE == (1 << VKI_PAGE_SHIFT));
1668 vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
philippe38a74d22014-08-29 22:53:19 +00001669 the_iicii.clstack_end = VG_(am_startup)( the_iicii.sp_at_startup );
sewardj45f4e7c2005-09-27 19:20:21 +00001670 VG_(debugLog)(1, "main", "Address space manager is running\n");
1671
1672 //--------------------------------------------------------------
1673 // Start up the dynamic memory manager
1674 // p: address space management
philipped99c26a2012-07-31 22:17:28 +00001675 // p: getting --profile-heap,--core-redzone-size,--redzone-size
sewardj45f4e7c2005-09-27 19:20:21 +00001676 // In fact m_mallocfree is self-initialising, so there's no
1677 // initialisation call to do. Instead, try a simple malloc/
1678 // free pair right now to check that nothing is broken.
1679 //--------------------------------------------------------------
1680 VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
sewardj9c606bd2008-09-18 18:12:50 +00001681 { void* p = VG_(malloc)( "main.vm.1", 12345 );
florianf5d8e652014-09-11 22:15:39 +00001682 VG_(free)( p );
sewardj45f4e7c2005-09-27 19:20:21 +00001683 }
1684 VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
sewardj1cf558c2005-04-25 01:36:56 +00001685
nethercotef4928da2004-06-15 10:54:40 +00001686 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001687 //
1688 // Dynamic memory management is now available.
1689 //
nethercotef4928da2004-06-15 10:54:40 +00001690 //============================================================
1691
sewardj45f4e7c2005-09-27 19:20:21 +00001692 //--------------------------------------------------------------
sewardjf98e1c02008-10-25 16:22:41 +00001693 // Initialise m_debuginfo
1694 // p: dynamic memory allocation
1695 VG_(debugLog)(1, "main", "Initialise m_debuginfo\n");
1696 VG_(di_initialise)();
1697
1698 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001699 // Look for alternative libdir
1700 { HChar *cp = VG_(getenv)(VALGRIND_LIB);
1701 if (cp != NULL)
1702 VG_(libdir) = cp;
njncde90d32009-07-22 22:41:38 +00001703 VG_(debugLog)(1, "main", "VG_(libdir) = %s\n", VG_(libdir));
sewardj45f4e7c2005-09-27 19:20:21 +00001704 }
1705
1706 //--------------------------------------------------------------
1707 // Extract the launcher name from the environment.
njna842d792009-05-21 01:15:18 +00001708 VG_(debugLog)(1, "main", "Getting launcher's name ...\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001709 VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
1710 if (VG_(name_of_launcher) == NULL) {
1711 VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
1712 VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
1713 VG_(exit)(1);
1714 }
njna842d792009-05-21 01:15:18 +00001715 VG_(debugLog)(1, "main", "... %s\n", VG_(name_of_launcher));
sewardj45f4e7c2005-09-27 19:20:21 +00001716
1717 //--------------------------------------------------------------
fitzhardingeb50068f2004-02-24 23:42:55 +00001718 // Get the current process datasize rlimit, and set it to zero.
1719 // This prevents any internal uses of brk() from having any effect.
1720 // We remember the old value so we can restore it on exec, so that
1721 // child processes will have a reasonable brk value.
1722 VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1723 zero.rlim_max = VG_(client_rlimit_data).rlim_max;
1724 VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
thughesc37184f2004-09-11 14:16:57 +00001725
1726 // Get the current process stack rlimit.
1727 VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
1728
sewardje2d1e672005-11-12 23:10:48 +00001729 //--------------------------------------------------------------
1730 // Figure out what sort of CPU we're on, and whether it is
1731 // able to run V.
1732 VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
1733 { VexArch vex_arch;
1734 VexArchInfo vex_archinfo;
1735 Bool ok = VG_(machine_get_hwcaps)();
1736 if (!ok) {
1737 VG_(printf)("\n");
1738 VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
1739 VG_(printf)(" Supported CPUs are:\n");
1740 VG_(printf)(" * x86 (practically any; Pentium-I or above), "
1741 "AMD Athlon or above)\n");
1742 VG_(printf)(" * AMD Athlon64/Opteron\n");
philippe3bcd51d2013-06-12 21:45:39 +00001743 VG_(printf)(" * ARM (armv7)\n");
sewardje2d1e672005-11-12 23:10:48 +00001744 VG_(printf)(" * PowerPC (most; ppc405 and above)\n");
sewardjb5b87402011-03-07 16:05:35 +00001745 VG_(printf)(" * System z (64bit only - s390x; z900 and above)\n");
sewardje2d1e672005-11-12 23:10:48 +00001746 VG_(printf)("\n");
1747 VG_(exit)(1);
1748 }
1749 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001750 VG_(debugLog)(
1751 1, "main", "... arch = %s, hwcaps = %s\n",
1752 LibVEX_ppVexArch ( vex_arch ),
1753 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1754 );
sewardje2d1e672005-11-12 23:10:48 +00001755 }
1756
sewardj198f34f2007-07-09 23:13:07 +00001757 //--------------------------------------------------------------
1758 // Record the working directory at startup
sewardj6e9de462011-06-28 07:25:29 +00001759 // p: none
sewardj198f34f2007-07-09 23:13:07 +00001760 VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
1761 { Bool ok = VG_(record_startup_wd)();
1762 if (!ok)
1763 VG_(err_config_error)( "Can't establish current working "
florian1763e812011-07-12 19:07:05 +00001764 "directory at startup\n");
sewardj198f34f2007-07-09 23:13:07 +00001765 }
florian29d82f62014-09-27 17:42:07 +00001766 VG_(debugLog)(1, "main", "... %s\n", VG_(get_startup_wd)() );
sewardj198f34f2007-07-09 23:13:07 +00001767
sewardj45f4e7c2005-09-27 19:20:21 +00001768 //============================================================
1769 // Command line argument handling order:
1770 // * If --help/--help-debug are present, show usage message
1771 // (including the tool-specific usage)
1772 // * (If no --tool option given, default to Memcheck)
1773 // * Then, if client is missing, abort with error msg
1774 // * Then, if any cmdline args are bad, abort with error msg
1775 //============================================================
1776
1777 //--------------------------------------------------------------
1778 // Split up argv into: C args, V args, V extra args, and exename.
1779 // p: dynamic memory allocation
1780 //--------------------------------------------------------------
1781 VG_(debugLog)(1, "main", "Split up command line\n");
1782 VG_(split_up_argv)( argc, argv );
sewardj14c7cc52007-02-25 15:08:24 +00001783 vg_assert( VG_(args_for_valgrind) );
1784 vg_assert( VG_(args_for_client) );
sewardj45f4e7c2005-09-27 19:20:21 +00001785 if (0) {
sewardj14c7cc52007-02-25 15:08:24 +00001786 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
1787 VG_(printf)(
1788 "varg %s\n",
1789 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1790 );
sewardj45f4e7c2005-09-27 19:20:21 +00001791 VG_(printf)(" exe %s\n", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001792 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
1793 VG_(printf)(
1794 "carg %s\n",
1795 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1796 );
nethercote71980f02004-01-24 18:18:54 +00001797 }
1798
1799 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001800 // Extract tool name and whether help has been requested.
1801 // Note we can't print the help message yet, even if requested,
1802 // because the tool has not been initialised.
1803 // p: split_up_argv [for VG_(args_for_valgrind)]
nethercote71980f02004-01-24 18:18:54 +00001804 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001805 VG_(debugLog)(1, "main",
1806 "(early_) Process Valgrind's command line options\n");
1807 early_process_cmd_line_options(&need_help, &toolname);
nethercote71980f02004-01-24 18:18:54 +00001808
sewardjdcd1ed42014-09-01 22:32:52 +00001809 // BEGIN HACK
1810 vg_assert(toolname != NULL);
1811 vg_assert(VG_(clo_read_inline_info) == False);
sewardj88f762e2014-09-07 19:53:41 +00001812# if !defined(VGO_darwin)
sewardjdcd1ed42014-09-01 22:32:52 +00001813 if (0 == VG_(strcmp)(toolname, "memcheck")
sewardj88f762e2014-09-07 19:53:41 +00001814 || 0 == VG_(strcmp)(toolname, "helgrind")
1815 || 0 == VG_(strcmp)(toolname, "drd")) {
sewardjdcd1ed42014-09-01 22:32:52 +00001816 /* Change the default setting. Later on (just below)
1817 main_process_cmd_line_options should pick up any
1818 user-supplied setting for it and will override the default
1819 set here. */
1820 VG_(clo_read_inline_info) = True;
1821 }
sewardj88f762e2014-09-07 19:53:41 +00001822# endif
sewardjdcd1ed42014-09-01 22:32:52 +00001823 // END HACK
1824
sewardj45f4e7c2005-09-27 19:20:21 +00001825 // Set default vex control params
1826 LibVEX_default_VexControl(& VG_(clo_vex_control));
nethercote71980f02004-01-24 18:18:54 +00001827
1828 //--------------------------------------------------------------
1829 // Load client executable, finding in $PATH if necessary
njn83df0b62009-02-25 01:01:05 +00001830 // p: early_process_cmd_line_options() [for 'exec', 'need_help',
1831 // clo_max_stackframe,
1832 // clo_main_stacksize]
sewardj95d86c02007-12-18 01:49:23 +00001833 // p: layout_remaining_space [so there's space]
sewardj17c11042006-10-15 01:26:40 +00001834 //
nethercote71980f02004-01-24 18:18:54 +00001835 // Set up client's environment
sewardj95d86c02007-12-18 01:49:23 +00001836 // p: set-libdir [for VG_(libdir)]
1837 // p: early_process_cmd_line_options [for toolname]
sewardj17c11042006-10-15 01:26:40 +00001838 //
nethercote5ee67ca2004-06-22 14:00:09 +00001839 // Setup client stack, eip, and VG_(client_arg[cv])
nethercote71980f02004-01-24 18:18:54 +00001840 // p: load_client() [for 'info']
1841 // p: fix_environment() [for 'env']
sewardj17c11042006-10-15 01:26:40 +00001842 //
sewardj45f4e7c2005-09-27 19:20:21 +00001843 // Setup client data (brk) segment. Initially a 1-page segment
1844 // which abuts a shrinkable reservation.
1845 // p: load_client() [for 'info' and hence VG_(brk_base)]
sewardjf9d2f9b2006-11-17 20:00:57 +00001846 //
1847 // p: _start_in_C (for zeroing out the_iicii and putting some
1848 // initial values into it)
sewardj45f4e7c2005-09-27 19:20:21 +00001849 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001850 if (!need_help) {
sewardjf9d2f9b2006-11-17 20:00:57 +00001851 VG_(debugLog)(1, "main", "Create initial image\n");
1852
njnf76d27a2009-05-28 01:53:07 +00001853# if defined(VGO_linux) || defined(VGO_darwin)
sewardjf9d2f9b2006-11-17 20:00:57 +00001854 the_iicii.argv = argv;
1855 the_iicii.envp = envp;
1856 the_iicii.toolname = toolname;
sewardjf9d2f9b2006-11-17 20:00:57 +00001857# else
njna842d792009-05-21 01:15:18 +00001858# error "Unknown platform"
sewardjf9d2f9b2006-11-17 20:00:57 +00001859# endif
1860
sewardjdc2f79e2007-12-22 14:14:04 +00001861 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001862 the_iifii = VG_(ii_create_image)( the_iicii );
sewardj45f4e7c2005-09-27 19:20:21 +00001863 }
nethercote71980f02004-01-24 18:18:54 +00001864
1865 //==============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001866 //
1867 // Finished loading/setting up the client address space.
1868 //
nethercote71980f02004-01-24 18:18:54 +00001869 //==============================================================
1870
1871 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001872 // setup file descriptors
1873 // p: n/a
1874 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001875 VG_(debugLog)(1, "main", "Setup file descriptors\n");
nethercote71980f02004-01-24 18:18:54 +00001876 setup_file_descriptors();
1877
1878 //--------------------------------------------------------------
tom41ad7e72012-10-04 20:27:38 +00001879 // create fake /proc/<pid>/cmdline and /proc/<pid>/auxv files
1880 // and then unlink them, but hold onto the fds, so we can handr
1881 // them out to the client when it tries to open
1882 // /proc/<pid>/cmdline or /proc/<pid>/auxv for itself.
sewardj45f4e7c2005-09-27 19:20:21 +00001883 // p: setup file descriptors
tom41ad7e72012-10-04 20:27:38 +00001884 // p: ii_create_image for VG_(client_auxv) setup.
nethercotec314eba2004-07-15 12:59:41 +00001885 //--------------------------------------------------------------
bart9b533f82009-08-25 20:15:41 +00001886#if !defined(VGO_linux)
1887 // client shouldn't be using /proc!
1888 VG_(cl_cmdline_fd) = -1;
tom41ad7e72012-10-04 20:27:38 +00001889 VG_(cl_auxv_fd) = -1;
bart9b533f82009-08-25 20:15:41 +00001890#else
1891 if (!need_help) {
philippecc648262013-05-26 21:09:20 +00001892 HChar buf[50], buf2[VG_(mkstemp_fullname_bufsz)(50-1)];
bart9b533f82009-08-25 20:15:41 +00001893 HChar nul[1];
1894 Int fd, r;
barta3054f52010-06-14 18:12:56 +00001895 const HChar* exename;
nethercotec314eba2004-07-15 12:59:41 +00001896
bart9b533f82009-08-25 20:15:41 +00001897 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001898
bart9b533f82009-08-25 20:15:41 +00001899 VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
1900 fd = VG_(mkstemp)( buf, buf2 );
1901 if (fd == -1)
florian1763e812011-07-12 19:07:05 +00001902 VG_(err_config_error)("Can't create client cmdline file in %s\n", buf2);
sewardj45f4e7c2005-09-27 19:20:21 +00001903
bart9b533f82009-08-25 20:15:41 +00001904 nul[0] = 0;
florianb16609b2014-08-20 21:04:14 +00001905 exename = VG_(args_the_exename);
sewardjc7ffc942011-03-28 16:26:42 +00001906 VG_(write)(fd, exename, VG_(strlen)( exename ));
bart9b533f82009-08-25 20:15:41 +00001907 VG_(write)(fd, nul, 1);
1908
1909 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1910 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
1911 VG_(write)(fd, arg, VG_(strlen)( arg ));
sewardj45f4e7c2005-09-27 19:20:21 +00001912 VG_(write)(fd, nul, 1);
1913 }
bart9b533f82009-08-25 20:15:41 +00001914
1915 /* Don't bother to seek the file back to the start; instead do
1916 it every time a copy of it is given out (by PRE(sys_open)).
1917 That is probably more robust across fork() etc. */
1918
1919 /* Now delete it, but hang on to the fd. */
1920 r = VG_(unlink)( buf2 );
1921 if (r)
florian1763e812011-07-12 19:07:05 +00001922 VG_(err_config_error)("Can't delete client cmdline file in %s\n", buf2);
bart9b533f82009-08-25 20:15:41 +00001923
1924 VG_(cl_cmdline_fd) = fd;
tom41ad7e72012-10-04 20:27:38 +00001925
1926 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/auxv\n");
1927
1928 VG_(sprintf)(buf, "proc_%d_auxv", VG_(getpid)());
1929 fd = VG_(mkstemp)( buf, buf2 );
1930 if (fd == -1)
1931 VG_(err_config_error)("Can't create client auxv file in %s\n", buf2);
1932
1933 UWord *client_auxv = VG_(client_auxv);
1934 unsigned int client_auxv_len = 0;
1935 while (*client_auxv != 0) {
1936 client_auxv++;
1937 client_auxv++;
1938 client_auxv_len += 2 * sizeof(UWord);
1939 }
1940 client_auxv_len += 2 * sizeof(UWord);
1941
1942 VG_(write)(fd, VG_(client_auxv), client_auxv_len);
1943
1944 /* Don't bother to seek the file back to the start; instead do
1945 it every time a copy of it is given out (by PRE(sys_open)).
1946 That is probably more robust across fork() etc. */
1947
1948 /* Now delete it, but hang on to the fd. */
1949 r = VG_(unlink)( buf2 );
1950 if (r)
1951 VG_(err_config_error)("Can't delete client auxv file in %s\n", buf2);
1952
1953 VG_(cl_auxv_fd) = fd;
sewardj45f4e7c2005-09-27 19:20:21 +00001954 }
bart9b533f82009-08-25 20:15:41 +00001955#endif
nethercotec314eba2004-07-15 12:59:41 +00001956
1957 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001958 // Init tool part 1: pre_clo_init
nethercotec314eba2004-07-15 12:59:41 +00001959 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
nethercotec314eba2004-07-15 12:59:41 +00001960 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
nethercote71980f02004-01-24 18:18:54 +00001961 //--------------------------------------------------------------
sewardj7cf4e6b2008-05-01 20:24:26 +00001962 VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
njn08ce7b32009-02-27 03:38:28 +00001963 VG_(tl_pre_clo_init)();
philippea0a73932014-06-15 15:42:20 +00001964 // Activate var info readers, if the tool asked for it:
1965 if (VG_(needs).var_info)
1966 VG_(clo_read_var_info) = True;
nethercote71980f02004-01-24 18:18:54 +00001967
sewardj45f4e7c2005-09-27 19:20:21 +00001968 //--------------------------------------------------------------
nethercotef4928da2004-06-15 10:54:40 +00001969 // If --tool and --help/--help-debug was given, now give the core+tool
1970 // help message
sewardj95d86c02007-12-18 01:49:23 +00001971 // p: early_process_cmd_line_options() [for 'need_help']
1972 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
sewardj45f4e7c2005-09-27 19:20:21 +00001973 //--------------------------------------------------------------
1974 VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
nethercotef4928da2004-06-15 10:54:40 +00001975 if (need_help) {
njncce38e62010-07-06 04:25:12 +00001976 usage_NORETURN(/*--help-debug?*/need_help >= 2);
nethercotef4928da2004-06-15 10:54:40 +00001977 }
nethercotec314eba2004-07-15 12:59:41 +00001978
sewardj45f4e7c2005-09-27 19:20:21 +00001979 //--------------------------------------------------------------
1980 // Process command line options to Valgrind + tool
1981 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1982 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1983 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001984 VG_(debugLog)(1, "main",
1985 "(main_) Process Valgrind's command line options, "
1986 "setup logging\n");
sewardj738856f2009-07-15 14:48:32 +00001987 main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded,
1988 toolname );
sewardj45f4e7c2005-09-27 19:20:21 +00001989
1990 //--------------------------------------------------------------
sewardj592ae092005-11-08 19:01:44 +00001991 // Zeroise the millisecond counter by doing a first read of it.
1992 // p: none
1993 //--------------------------------------------------------------
1994 (void) VG_(read_millisecond_timer)();
1995
1996 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001997 // Print the preamble
1998 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
sewardj738856f2009-07-15 14:48:32 +00001999 // p: main_process_cmd_line_options()
2000 // [for VG_(clo_verbosity), VG_(clo_xml),
2001 // logging_to_fd, xml_fname_unexpanded]
sewardj45f4e7c2005-09-27 19:20:21 +00002002 //--------------------------------------------------------------
2003 VG_(debugLog)(1, "main", "Print the preamble...\n");
sewardj738856f2009-07-15 14:48:32 +00002004 print_preamble(logging_to_fd, xml_fname_unexpanded, toolname);
sewardj45f4e7c2005-09-27 19:20:21 +00002005 VG_(debugLog)(1, "main", "...finished the preamble\n");
2006
2007 //--------------------------------------------------------------
2008 // Init tool part 2: post_clo_init
2009 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
2010 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
2011 // p: print_preamble() [so any warnings printed in post_clo_init
2012 // are shown after the preamble]
2013 //--------------------------------------------------------------
2014 VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
njn51d827b2005-05-09 01:02:08 +00002015 VG_TDICT_CALL(tool_post_clo_init);
sewardj7cf4e6b2008-05-01 20:24:26 +00002016 {
2017 /* The tool's "needs" will by now be finalised, since it has no
2018 further opportunity to specify them. So now sanity check
2019 them. */
floriane6a4ed12012-10-21 02:30:18 +00002020 const HChar* s;
sewardj7cf4e6b2008-05-01 20:24:26 +00002021 Bool ok;
2022 ok = VG_(sanity_check_needs)( &s );
2023 if (!ok) {
floriana4ca4fe2014-09-16 09:28:12 +00002024 VG_(core_panic)(s);
sewardj7cf4e6b2008-05-01 20:24:26 +00002025 }
2026 }
nethercotef4928da2004-06-15 10:54:40 +00002027
2028 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002029 // Initialise translation table and translation cache
2030 // p: aspacem [??]
2031 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
nethercote71980f02004-01-24 18:18:54 +00002032 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002033 VG_(debugLog)(1, "main", "Initialise TT/TC\n");
2034 VG_(init_tt_tc)();
sewardjb5f6f512005-03-10 23:59:00 +00002035
sewardj45f4e7c2005-09-27 19:20:21 +00002036 //--------------------------------------------------------------
2037 // Initialise the redirect table.
2038 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
2039 // p: aspacem [so can change ownership of sysinfo pages]
2040 //--------------------------------------------------------------
2041 VG_(debugLog)(1, "main", "Initialise redirects\n");
sewardj0ec07f32006-01-12 12:32:32 +00002042 VG_(redir_initialise)();
nethercote71980f02004-01-24 18:18:54 +00002043
2044 //--------------------------------------------------------------
2045 // Allow GDB attach
sewardj95d86c02007-12-18 01:49:23 +00002046 // p: main_process_cmd_line_options() [for VG_(clo_wait_for_gdb)]
nethercote71980f02004-01-24 18:18:54 +00002047 //--------------------------------------------------------------
2048 /* Hook to delay things long enough so we can get the pid and
2049 attach GDB in another shell. */
2050 if (VG_(clo_wait_for_gdb)) {
sewardj87cd71c2011-07-05 09:13:41 +00002051 ULong iters, q;
sewardj1fbc1a52005-04-25 02:05:54 +00002052 VG_(debugLog)(1, "main", "Wait for GDB\n");
sewardj93ab8572005-02-06 14:10:40 +00002053 VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
sewardj8211a572005-06-23 21:37:47 +00002054
2055# if defined(VGP_x86_linux)
sewardj291849f2012-04-20 23:58:55 +00002056 iters = 10;
carllcae0cc22014-08-07 23:17:29 +00002057# elif defined(VGP_amd64_linux) || defined(VGP_ppc64be_linux) \
2058 || defined(VGP_ppc64le_linux)
sewardj8211a572005-06-23 21:37:47 +00002059 iters = 10;
2060# elif defined(VGP_ppc32_linux)
sewardjd714d2e2005-07-08 18:24:04 +00002061 iters = 5;
sewardj59570ff2010-01-01 11:59:33 +00002062# elif defined(VGP_arm_linux)
sewardj291849f2012-04-20 23:58:55 +00002063 iters = 5;
sewardjf0c12502014-01-12 12:54:00 +00002064# elif defined(VGP_arm64_linux)
2065 iters = 5;
sewardjb5b87402011-03-07 16:05:35 +00002066# elif defined(VGP_s390x_linux)
2067 iters = 10;
petarj4df0bfc2013-02-27 23:17:33 +00002068# elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
sewardj5db15402012-06-07 09:13:21 +00002069 iters = 10;
njnf76d27a2009-05-28 01:53:07 +00002070# elif defined(VGO_darwin)
2071 iters = 3;
sewardj8211a572005-06-23 21:37:47 +00002072# else
sewardj17c11042006-10-15 01:26:40 +00002073# error "Unknown plat"
sewardj8211a572005-06-23 21:37:47 +00002074# endif
2075
sewardj87cd71c2011-07-05 09:13:41 +00002076 iters *= 1000ULL * 1000 * 1000;
sewardj8211a572005-06-23 21:37:47 +00002077 for (q = 0; q < iters; q++)
sewardj87cd71c2011-07-05 09:13:41 +00002078 __asm__ __volatile__("" ::: "memory","cc");
nethercote71980f02004-01-24 18:18:54 +00002079 }
2080
sewardjb5d320c2005-03-13 18:57:15 +00002081 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002082 // Search for file descriptors that are inherited from our parent
sewardj95d86c02007-12-18 01:49:23 +00002083 // p: main_process_cmd_line_options [for VG_(clo_track_fds)]
nethercote71980f02004-01-24 18:18:54 +00002084 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00002085 if (VG_(clo_track_fds)) {
2086 VG_(debugLog)(1, "main", "Init preopened fds\n");
nethercote71980f02004-01-24 18:18:54 +00002087 VG_(init_preopened_fds)();
sewardj1fbc1a52005-04-25 02:05:54 +00002088 }
nethercote71980f02004-01-24 18:18:54 +00002089
2090 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002091 // Load debug info for the existing segments.
2092 // p: setup_code_redirect_table [so that redirs can be recorded]
2093 // p: mallocfree
2094 // p: probably: setup fds and process CLOs, so that logging works
sewardjf98e1c02008-10-25 16:22:41 +00002095 // p: initialise m_debuginfo
sewardj9c606bd2008-09-18 18:12:50 +00002096 //
2097 // While doing this, make a note of the debuginfo-handles that
sewardj6e9de462011-06-28 07:25:29 +00002098 // come back from VG_(di_notify_mmap).
sewardj9c606bd2008-09-18 18:12:50 +00002099 // Later, in "Tell the tool about the initial client memory permissions"
2100 // (just below) we can then hand these handles off to the tool in
2101 // calls to VG_TRACK(new_mem_startup, ...). This gives the tool the
2102 // opportunity to make further queries to m_debuginfo before the
2103 // client is started, if it wants. We put this information into an
2104 // XArray, each handle along with the associated segment start address,
2105 // and search the XArray for the handles later, when calling
2106 // VG_TRACK(new_mem_startup, ...).
sewardj45f4e7c2005-09-27 19:20:21 +00002107 //--------------------------------------------------------------
2108 VG_(debugLog)(1, "main", "Load initial debug info\n");
sewardj9c606bd2008-09-18 18:12:50 +00002109
floriane2800c92014-09-15 20:57:45 +00002110 vg_assert(!addr2dihandle);
sewardj9c606bd2008-09-18 18:12:50 +00002111 addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2",
2112 VG_(free), sizeof(Addr_n_ULong) );
sewardj9c606bd2008-09-18 18:12:50 +00002113
sewardj17c11042006-10-15 01:26:40 +00002114# if defined(VGO_linux)
sewardj45f4e7c2005-09-27 19:20:21 +00002115 { Addr* seg_starts;
2116 Int n_seg_starts;
sewardj9c606bd2008-09-18 18:12:50 +00002117 Addr_n_ULong anu;
sewardj45f4e7c2005-09-27 19:20:21 +00002118
njnac1e0332009-05-08 00:39:31 +00002119 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00002120 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00002121
sewardjf72cced2005-11-08 00:45:47 +00002122 /* show them all to the debug info reader. allow_SkFileV has to
2123 be True here so that we read info from the valgrind executable
2124 itself. */
sewardj9c606bd2008-09-18 18:12:50 +00002125 for (i = 0; i < n_seg_starts; i++) {
sewardj5f2dcad2011-10-24 08:53:03 +00002126 anu.ull = VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/,
2127 -1/*Don't use_fd*/);
sewardj9c606bd2008-09-18 18:12:50 +00002128 /* anu.ull holds the debuginfo handle returned by di_notify_mmap,
2129 if any. */
2130 if (anu.ull > 0) {
2131 anu.a = seg_starts[i];
2132 VG_(addToXA)( addr2dihandle, &anu );
2133 }
2134 }
sewardj45f4e7c2005-09-27 19:20:21 +00002135
2136 VG_(free)( seg_starts );
2137 }
njnf76d27a2009-05-28 01:53:07 +00002138# elif defined(VGO_darwin)
2139 { Addr* seg_starts;
2140 Int n_seg_starts;
2141 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
2142 vg_assert(seg_starts && n_seg_starts >= 0);
2143
2144 /* show them all to the debug info reader.
2145 Don't read from V segments (unlike Linux) */
2146 // GrP fixme really?
sewardj5f2dcad2011-10-24 08:53:03 +00002147 for (i = 0; i < n_seg_starts; i++) {
2148 VG_(di_notify_mmap)( seg_starts[i], False/*don't allow_SkFileV*/,
2149 -1/*don't use_fd*/);
2150 }
njnf76d27a2009-05-28 01:53:07 +00002151
2152 VG_(free)( seg_starts );
2153 }
sewardj17c11042006-10-15 01:26:40 +00002154# else
2155# error Unknown OS
2156# endif
sewardj45f4e7c2005-09-27 19:20:21 +00002157
2158 //--------------------------------------------------------------
2159 // Tell aspacem of ownership change of the asm helpers, so that
2160 // m_translate allows them to be translated. However, only do this
2161 // after the initial debug info read, since making a hole in the
2162 // address range for the stage2 binary confuses the debug info reader.
2163 // p: aspacem
2164 //--------------------------------------------------------------
2165 { Bool change_ownership_v_c_OK;
sewardj1a85f4f2006-01-12 21:15:35 +00002166 Addr co_start = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
2167 Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
sewardj45f4e7c2005-09-27 19:20:21 +00002168 VG_(debugLog)(1,"redir",
2169 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
2170 (ULong)co_start, (ULong)co_endPlus-1 );
2171
2172 change_ownership_v_c_OK
2173 = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
2174 vg_assert(change_ownership_v_c_OK);
2175 }
2176
bart6c63f5c2011-10-11 18:50:14 +00002177 if (VG_(clo_xml)) {
2178 HChar buf[50];
2179 VG_(elapsed_wallclock_time)(buf);
2180 VG_(printf_xml)( "<status>\n"
2181 " <state>RUNNING</state>\n"
2182 " <time>%pS</time>\n"
2183 "</status>\n",
2184 buf );
2185 VG_(printf_xml)( "\n" );
2186 }
2187
bart27233e92012-03-08 14:59:25 +00002188 VG_(init_Threads)();
2189
sewardj45f4e7c2005-09-27 19:20:21 +00002190 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002191 // Initialise the scheduler (phase 1) [generates tid_main]
2192 // p: none, afaics
2193 //--------------------------------------------------------------
2194 VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
2195 tid_main = VG_(scheduler_init_phase1)();
2196 vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
2197 && tid_main != VG_INVALID_THREADID);
2198 /* Tell the tool about tid_main */
2199 VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
2200
2201 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002202 // Tell the tool about the initial client memory permissions
2203 // p: aspacem
2204 // p: mallocfree
2205 // p: setup_client_stack
2206 // p: setup_client_dataseg
sewardj9c606bd2008-09-18 18:12:50 +00002207 //
2208 // For each segment we tell the client about, look up in
2209 // addr2dihandle as created above, to see if there's a debuginfo
2210 // handle associated with the segment, that we can hand along
2211 // to the tool, to be helpful.
sewardj45f4e7c2005-09-27 19:20:21 +00002212 //--------------------------------------------------------------
2213 VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
2214 { Addr* seg_starts;
2215 Int n_seg_starts;
sewardj45f4e7c2005-09-27 19:20:21 +00002216
floriane2800c92014-09-15 20:57:45 +00002217 vg_assert(addr2dihandle);
sewardj9c606bd2008-09-18 18:12:50 +00002218
tom7c1a19a2008-01-02 10:13:04 +00002219 /* Mark the main thread as running while we tell the tool about
2220 the client memory so that the tool can associate that memory
2221 with the main thread. */
floriane2800c92014-09-15 20:57:45 +00002222 vg_assert(VG_(running_tid) == VG_INVALID_THREADID);
tom7c1a19a2008-01-02 10:13:04 +00002223 VG_(running_tid) = tid_main;
2224
njnac1e0332009-05-08 00:39:31 +00002225 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00002226 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00002227
2228 /* show interesting ones to the tool */
2229 for (i = 0; i < n_seg_starts; i++) {
sewardj9c606bd2008-09-18 18:12:50 +00002230 Word j, n;
sewardj12ab7652006-10-17 02:10:42 +00002231 NSegment const* seg
sewardj17c11042006-10-15 01:26:40 +00002232 = VG_(am_find_nsegment)( seg_starts[i] );
sewardj45f4e7c2005-09-27 19:20:21 +00002233 vg_assert(seg);
2234 if (seg->kind == SkFileC || seg->kind == SkAnonC) {
sewardjc6d86a32009-01-31 15:08:08 +00002235 /* This next assertion is tricky. If it is placed
2236 immediately before this 'if', it very occasionally fails.
2237 Why? Because previous iterations of the loop may have
2238 caused tools (via the new_mem_startup calls) to do
2239 dynamic memory allocation, and that may affect the mapped
2240 segments; in particular it may cause segment merging to
2241 happen. Hence we cannot assume that seg_starts[i], which
2242 reflects the state of the world before we started this
2243 loop, is the same as seg->start, as the latter reflects
2244 the state of the world (viz, mappings) at this particular
2245 iteration of the loop.
2246
2247 Why does moving it inside the 'if' make it safe? Because
2248 any dynamic memory allocation done by the tools will
2249 affect only the state of Valgrind-owned segments, not of
2250 Client-owned segments. And the 'if' guards against that
2251 -- we only get in here for Client-owned segments.
2252
2253 In other words: the loop may change the state of
2254 Valgrind-owned segments as it proceeds. But it should
2255 not cause the Client-owned segments to change. */
2256 vg_assert(seg->start == seg_starts[i]);
sewardj45f4e7c2005-09-27 19:20:21 +00002257 VG_(debugLog)(2, "main",
2258 "tell tool about %010lx-%010lx %c%c%c\n",
2259 seg->start, seg->end,
2260 seg->hasR ? 'r' : '-',
2261 seg->hasW ? 'w' : '-',
2262 seg->hasX ? 'x' : '-' );
sewardj9c606bd2008-09-18 18:12:50 +00002263 /* search addr2dihandle to see if we have an entry
2264 matching seg->start. */
2265 n = VG_(sizeXA)( addr2dihandle );
2266 for (j = 0; j < n; j++) {
2267 Addr_n_ULong* anl = VG_(indexXA)( addr2dihandle, j );
2268 if (anl->a == seg->start) {
floriane2800c92014-09-15 20:57:45 +00002269 vg_assert(anl->ull > 0); /* check it's a valid handle */
sewardj9c606bd2008-09-18 18:12:50 +00002270 break;
2271 }
2272 }
2273 vg_assert(j >= 0 && j <= n);
sewardj45f4e7c2005-09-27 19:20:21 +00002274 VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
sewardj9c606bd2008-09-18 18:12:50 +00002275 seg->hasR, seg->hasW, seg->hasX,
2276 /* and the retrieved debuginfo handle, if any */
2277 j < n
2278 ? ((Addr_n_ULong*)VG_(indexXA)( addr2dihandle, j ))->ull
2279 : 0 );
sewardj45f4e7c2005-09-27 19:20:21 +00002280 }
2281 }
2282
2283 VG_(free)( seg_starts );
sewardj9c606bd2008-09-18 18:12:50 +00002284 VG_(deleteXA)( addr2dihandle );
sewardj45f4e7c2005-09-27 19:20:21 +00002285
2286 /* Also do the initial stack permissions. */
barte05b3a42010-09-07 16:32:53 +00002287 {
2288 SSizeT inaccessible_len;
2289 NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002290 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj17c11042006-10-15 01:26:40 +00002291 vg_assert(seg);
2292 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002293 vg_assert(the_iifii.initial_client_SP >= seg->start);
2294 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardj45f4e7c2005-09-27 19:20:21 +00002295
sewardj17c11042006-10-15 01:26:40 +00002296 /* Stuff below the initial SP is unaddressable. Take into
2297 account any ABI-mandated space below the stack pointer that
2298 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
2299 will have allocated an extra page if a red zone is required,
2300 to be on the safe side. */
barte05b3a42010-09-07 16:32:53 +00002301 inaccessible_len = the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
2302 - seg->start;
2303 vg_assert(inaccessible_len >= 0);
2304 if (inaccessible_len > 0)
2305 VG_TRACK( die_mem_stack,
2306 seg->start,
2307 inaccessible_len );
sewardj17c11042006-10-15 01:26:40 +00002308 VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
2309 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00002310 the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
sewardj17c11042006-10-15 01:26:40 +00002311 }
sewardj45f4e7c2005-09-27 19:20:21 +00002312
2313 /* Also the assembly helpers. */
2314 VG_TRACK( new_mem_startup,
2315 (Addr)&VG_(trampoline_stuff_start),
sewardjc6527d62006-02-13 17:54:31 +00002316 (Addr)&VG_(trampoline_stuff_end)
2317 - (Addr)&VG_(trampoline_stuff_start),
sewardj45f4e7c2005-09-27 19:20:21 +00002318 False, /* readable? */
2319 False, /* writable? */
sewardj9c606bd2008-09-18 18:12:50 +00002320 True /* executable? */,
2321 0 /* di_handle: no associated debug info */ );
tom7c1a19a2008-01-02 10:13:04 +00002322
2323 /* Clear the running thread indicator */
2324 VG_(running_tid) = VG_INVALID_THREADID;
floriane2800c92014-09-15 20:57:45 +00002325 vg_assert(VG_(running_tid) == VG_INVALID_THREADID);
sewardj882a9ec2014-07-08 07:44:07 +00002326
2327 /* Darwin only: tell the tools where the client's kernel commpage
2328 is. It would be better to do this by telling aspacemgr about
2329 it -- see the now disused record_system_memory() in
2330 initimg-darwin.c -- but that causes the sync checker to fail,
2331 since the mapping doesn't appear in the kernel-supplied
2332 process map. So do it here instead. */
2333# if defined(VGP_amd64_darwin)
2334 VG_TRACK( new_mem_startup,
2335 0x7fffffe00000, 0x7ffffffff000-0x7fffffe00000,
2336 True, False, True, /* r-x */
2337 0 /* di_handle: no associated debug info */ );
2338# elif defined(VGP_x86_darwin)
2339 VG_TRACK( new_mem_startup,
2340 0xfffec000, 0xfffff000-0xfffec000,
2341 True, False, True, /* r-x */
2342 0 /* di_handle: no associated debug info */ );
2343# endif
sewardj45f4e7c2005-09-27 19:20:21 +00002344 }
2345
2346 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002347 // Initialise the scheduler (phase 2)
2348 // p: Initialise the scheduler (phase 1) [for tid_main]
nethercote71980f02004-01-24 18:18:54 +00002349 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
sewardj45f4e7c2005-09-27 19:20:21 +00002350 // p: setup_client_stack
nethercote71980f02004-01-24 18:18:54 +00002351 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002352 VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
sewardj12ab7652006-10-17 02:10:42 +00002353 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002354 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj45f4e7c2005-09-27 19:20:21 +00002355 vg_assert(seg);
2356 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002357 vg_assert(the_iifii.initial_client_SP >= seg->start);
2358 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardjde764e82007-11-09 23:13:22 +00002359 VG_(scheduler_init_phase2)( tid_main,
2360 seg->end, the_iifii.clstack_max_size );
sewardj45f4e7c2005-09-27 19:20:21 +00002361 }
nethercote71980f02004-01-24 18:18:54 +00002362
2363 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00002364 // Set up state for the root thread
sewardjb5f6f512005-03-10 23:59:00 +00002365 // p: ?
sewardj17c11042006-10-15 01:26:40 +00002366 // setup_scheduler() [for sched-specific thread 1 stuff]
sewardjf9d2f9b2006-11-17 20:00:57 +00002367 // VG_(ii_create_image) [for 'the_iicii' initial info]
sewardj2a99cf62004-11-24 10:44:19 +00002368 //--------------------------------------------------------------
sewardjf9d2f9b2006-11-17 20:00:57 +00002369 VG_(debugLog)(1, "main", "Finalise initial image\n");
2370 VG_(ii_finalise_image)( the_iifii );
njnea4b28c2004-11-30 16:04:58 +00002371
sewardj2a99cf62004-11-24 10:44:19 +00002372 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002373 // Initialise the signal handling subsystem
sewardjb5f6f512005-03-10 23:59:00 +00002374 // p: n/a
nethercote71980f02004-01-24 18:18:54 +00002375 //--------------------------------------------------------------
2376 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
sewardj1fbc1a52005-04-25 02:05:54 +00002377 VG_(debugLog)(1, "main", "Initialise signal management\n");
njncda2f0f2009-05-18 02:12:08 +00002378 /* Check that the kernel-interface signal definitions look sane */
2379 VG_(vki_do_initial_consistency_checks)();
2380 /* .. and go on to use them. */
nethercote71980f02004-01-24 18:18:54 +00002381 VG_(sigstartup_actions)();
2382
2383 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002384 // Read suppression file
sewardj95d86c02007-12-18 01:49:23 +00002385 // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
nethercote71980f02004-01-24 18:18:54 +00002386 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00002387 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
2388 VG_(debugLog)(1, "main", "Load suppressions\n");
nethercote71980f02004-01-24 18:18:54 +00002389 VG_(load_suppressions)();
sewardj1fbc1a52005-04-25 02:05:54 +00002390 }
nethercote71980f02004-01-24 18:18:54 +00002391
2392 //--------------------------------------------------------------
rjwalsh0140af52005-06-04 20:42:33 +00002393 // register client stack
2394 //--------------------------------------------------------------
philippe38a74d22014-08-29 22:53:19 +00002395 VG_(clstk_id) = VG_(register_stack)(VG_(clstk_start_base), VG_(clstk_end));
rjwalsh0140af52005-06-04 20:42:33 +00002396
2397 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002398 // Show the address space state so far
2399 //--------------------------------------------------------------
2400 VG_(debugLog)(1, "main", "\n");
2401 VG_(debugLog)(1, "main", "\n");
2402 VG_(am_show_nsegments)(1,"Memory layout at client startup");
2403 VG_(debugLog)(1, "main", "\n");
2404 VG_(debugLog)(1, "main", "\n");
2405
2406 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002407 // Run!
2408 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00002409 VG_(debugLog)(1, "main", "Running thread 1\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002410
sewardj1d887112005-05-30 21:44:08 +00002411 /* As a result of the following call, the last thread standing
sewardj1ae3f3a2005-09-28 10:47:38 +00002412 eventually winds up running shutdown_actions_NORETURN
2413 just below. Unfortunately, simply exporting said function
2414 causes m_main to be part of a module cycle, which is pretty
2415 nonsensical. So instead of doing that, the address of said
2416 function is stored in a global variable 'owned' by m_syswrap,
2417 and it uses that function pointer to get back here when it needs
2418 to. */
2419
2420 /* Set continuation address. */
2421 VG_(address_of_m_main_shutdown_actions_NORETURN)
2422 = & shutdown_actions_NORETURN;
2423
2424 /* Run the first thread, eventually ending up at the continuation
2425 address. */
njnaf839f52005-06-23 03:27:57 +00002426 VG_(main_thread_wrapper_NORETURN)(1);
nethercote71980f02004-01-24 18:18:54 +00002427
sewardj1d887112005-05-30 21:44:08 +00002428 /*NOTREACHED*/
2429 vg_assert(0);
sewardjb5f6f512005-03-10 23:59:00 +00002430}
2431
sewardj17c11042006-10-15 01:26:40 +00002432/* Do everything which needs doing when the last thread exits or when
sewardj6e9de462011-06-28 07:25:29 +00002433 a thread exits requesting a complete process exit.
sewardj17c11042006-10-15 01:26:40 +00002434
2435 We enter here holding The Lock. For the case VgSrc_ExitProcess we
2436 must never release it, because to do so would allow other threads
2437 to continue after the system is ostensibly shut down. So we must
2438 go to our grave, so to speak, holding the lock.
2439
2440 In fact, there is never any point in releasing the lock at this
2441 point - we have it, we're shutting down the entire system, and
2442 for the case VgSrc_ExitProcess doing so positively causes trouble.
2443 So don't.
2444
2445 The final_tidyup call makes a bit of a nonsense of the ExitProcess
2446 case, since it will run the libc_freeres function, thus allowing
2447 other lurking threads to run again. Hmm. */
sewardjb5f6f512005-03-10 23:59:00 +00002448
sewardj1ae3f3a2005-09-28 10:47:38 +00002449static
2450void shutdown_actions_NORETURN( ThreadId tid,
2451 VgSchedReturnCode tids_schedretcode )
sewardjb5f6f512005-03-10 23:59:00 +00002452{
sewardj1d887112005-05-30 21:44:08 +00002453 VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
sewardj17c11042006-10-15 01:26:40 +00002454 VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
sewardj1d887112005-05-30 21:44:08 +00002455
sewardjb5f6f512005-03-10 23:59:00 +00002456 vg_assert(VG_(is_running_thread)(tid));
2457
sewardj12ab7652006-10-17 02:10:42 +00002458 vg_assert(tids_schedretcode == VgSrc_ExitThread
2459 || tids_schedretcode == VgSrc_ExitProcess
2460 || tids_schedretcode == VgSrc_FatalSig );
sewardjb5f6f512005-03-10 23:59:00 +00002461
sewardj12ab7652006-10-17 02:10:42 +00002462 if (tids_schedretcode == VgSrc_ExitThread) {
sewardjb5f6f512005-03-10 23:59:00 +00002463
sewardj17c11042006-10-15 01:26:40 +00002464 // We are the last surviving thread. Right?
2465 vg_assert( VG_(count_living_threads)() == 1 );
sewardjb5f6f512005-03-10 23:59:00 +00002466
sewardj17c11042006-10-15 01:26:40 +00002467 // Wait for all other threads to exit.
2468 // jrs: Huh? but they surely are already gone
2469 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002470
sewardj17c11042006-10-15 01:26:40 +00002471 // Clean the client up before the final report
2472 // this causes the libc_freeres function to run
2473 final_tidyup(tid);
2474
2475 /* be paranoid */
2476 vg_assert(VG_(is_running_thread)(tid));
2477 vg_assert(VG_(count_living_threads)() == 1);
2478
2479 } else {
2480
2481 // We may not be the last surviving thread. However, we
2482 // want to shut down the entire process. We hold the lock
2483 // and we need to keep hold of it all the way out, in order
2484 // that none of the other threads ever run again.
2485 vg_assert( VG_(count_living_threads)() >= 1 );
2486
sewardj17c11042006-10-15 01:26:40 +00002487 // Clean the client up before the final report
2488 // this causes the libc_freeres function to run
2489 // perhaps this is unsafe, as per comment above
2490 final_tidyup(tid);
2491
2492 /* be paranoid */
2493 vg_assert(VG_(is_running_thread)(tid));
2494 vg_assert(VG_(count_living_threads)() >= 1);
2495 }
sewardjb5f6f512005-03-10 23:59:00 +00002496
philippe180a7502014-04-20 13:41:10 +00002497 /* Final call to gdbserver, if requested. */
2498 if (VG_(gdbserver_stop_at) (VgdbStopAt_Exit)) {
2499 VG_(umsg)("(action at exit) vgdb me ... \n");
2500 VG_(gdbserver) (tid);
2501 }
sewardjb5f6f512005-03-10 23:59:00 +00002502 VG_(threads)[tid].status = VgTs_Empty;
philippe180a7502014-04-20 13:41:10 +00002503
nethercote71980f02004-01-24 18:18:54 +00002504 //--------------------------------------------------------------
sewardj738856f2009-07-15 14:48:32 +00002505 // Finalisation: cleanup, messages, etc. Order not so important, only
nethercote71980f02004-01-24 18:18:54 +00002506 // affects what order the messages come.
2507 //--------------------------------------------------------------
njnb6267bd2009-08-12 00:14:16 +00002508 // First thing in the post-amble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00002509 if (VG_(clo_xml))
2510 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00002511 else if (VG_(clo_verbosity) > 0)
2512 VG_(message)(Vg_UserMsg, "\n");
nethercote71980f02004-01-24 18:18:54 +00002513
sewardj71bc3cb2005-05-19 00:25:45 +00002514 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002515 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00002516 VG_(elapsed_wallclock_time)(buf);
bartb3af9cf2011-10-06 19:08:37 +00002517 VG_(printf_xml)( "<status>\n"
sewardj738856f2009-07-15 14:48:32 +00002518 " <state>FINISHED</state>\n"
bartb3af9cf2011-10-06 19:08:37 +00002519 " <time>%pS</time>\n"
njnb6267bd2009-08-12 00:14:16 +00002520 "</status>\n"
2521 "\n",
sewardj738856f2009-07-15 14:48:32 +00002522 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00002523 }
2524
nethercote71980f02004-01-24 18:18:54 +00002525 /* Print out file descriptor summary and stats. */
2526 if (VG_(clo_track_fds))
philippec3360382012-10-21 14:37:14 +00002527 VG_(show_open_fds)("at exit");
nethercote71980f02004-01-24 18:18:54 +00002528
sewardj2d9e8742009-08-07 15:46:56 +00002529 /* Call the tool's finalisation function. This makes Memcheck's
2530 leak checker run, and possibly chuck a bunch of leak errors into
2531 the error management machinery. */
2532 VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
nethercote71980f02004-01-24 18:18:54 +00002533
sewardj2d9e8742009-08-07 15:46:56 +00002534 /* Show the error counts. */
sewardj7ca100d2009-08-15 23:05:34 +00002535 if (VG_(clo_xml)
2536 && (VG_(needs).core_errors || VG_(needs).tool_errors)) {
sewardj2d9e8742009-08-07 15:46:56 +00002537 VG_(show_error_counts_as_XML)();
sewardj738856f2009-07-15 14:48:32 +00002538 }
sewardj2d9e8742009-08-07 15:46:56 +00002539
2540 /* In XML mode, this merely prints the used suppressions. */
2541 if (VG_(needs).core_errors || VG_(needs).tool_errors)
sewardj3b290482011-05-06 21:02:55 +00002542 VG_(show_all_errors)(VG_(clo_verbosity), VG_(clo_xml));
nethercote71980f02004-01-24 18:18:54 +00002543
sewardj71bc3cb2005-05-19 00:25:45 +00002544 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00002545 VG_(printf_xml)("\n");
2546 VG_(printf_xml)("</valgrindoutput>\n");
2547 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00002548 }
2549
nethercote885dd912004-08-03 23:14:00 +00002550 VG_(sanity_check_general)( True /*include expensive checks*/ );
nethercote71980f02004-01-24 18:18:54 +00002551
sewardj2d9e8742009-08-07 15:46:56 +00002552 if (VG_(clo_stats))
philippe4f6f3362014-04-19 00:25:54 +00002553 VG_(print_all_stats)(VG_(clo_verbosity) > 2, /* Memory stats */
2554 False /* tool prints stats in the tool fini */);
nethercote71980f02004-01-24 18:18:54 +00002555
sewardj9c606bd2008-09-18 18:12:50 +00002556 /* Show a profile of the heap(s) at shutdown. Optionally, first
2557 throw away all the debug info, as that makes it easy to spot
2558 leaks in the debuginfo reader. */
2559 if (VG_(clo_profile_heap)) {
2560 if (0) VG_(di_discard_ALL_debuginfo)();
2561 VG_(print_arena_cc_analysis)();
2562 }
2563
sewardj17c5e2e2012-12-28 09:12:14 +00002564 /* If profiling has been requested, but with zero interval, it
2565 means "profile at the end of the run only". In which case we
2566 need to dump the profile now. */
2567 if (VG_(clo_profyle_sbs) && VG_(clo_profyle_interval) == 0) {
2568 VG_(get_and_show_SB_profile)(0/*denoting end-of-run*/);
njn2025cf92005-06-26 20:44:48 +00002569 }
sewardjfa8ec112005-01-19 11:55:34 +00002570
sewardj8b635a42004-11-22 19:01:47 +00002571 /* Print Vex storage stats */
sewardjbf426512005-01-17 18:35:30 +00002572 if (0)
2573 LibVEX_ShowAllocStats();
sewardj1d887112005-05-30 21:44:08 +00002574
sewardj738856f2009-07-15 14:48:32 +00002575 /* Flush any output cached by previous calls to VG_(message). */
2576 VG_(message_flush)();
2577
philippe180a7502014-04-20 13:41:10 +00002578 /* Terminate gdbserver if ever it was started. We terminate it here
sewardj17c5e2e2012-12-28 09:12:14 +00002579 so that it get the output above if output was redirected to
2580 gdb */
philippe0447bbd2012-10-17 21:32:03 +00002581 VG_(gdbserver_exit) (tid, tids_schedretcode);
sewardj3b290482011-05-06 21:02:55 +00002582
njn8aa35852005-06-10 22:59:56 +00002583 /* Ok, finally exit in the os-specific way, according to the scheduler's
2584 return code. In short, if the (last) thread exited by calling
2585 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2586 signal, terminate the entire system with that same fatal signal. */
2587 VG_(debugLog)(1, "core_os",
njn7b85dd52005-06-12 17:26:29 +00002588 "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
njn8aa35852005-06-10 22:59:56 +00002589
njn8aa35852005-06-10 22:59:56 +00002590 switch (tids_schedretcode) {
sewardj12ab7652006-10-17 02:10:42 +00002591 case VgSrc_ExitThread: /* the normal way out (Linux) */
sewardj6e9de462011-06-28 07:25:29 +00002592 case VgSrc_ExitProcess: /* the normal way out (AIX) -- still needed? */
sewardjb9779082006-05-12 23:50:15 +00002593 /* Change the application return code to user's return code,
2594 if an error was found */
2595 if (VG_(clo_error_exitcode) > 0
2596 && VG_(get_n_errs_found)() > 0) {
philippe180a7502014-04-20 13:41:10 +00002597 VG_(client_exit)( VG_(clo_error_exitcode) );
sewardjb9779082006-05-12 23:50:15 +00002598 } else {
2599 /* otherwise, return the client's exit code, in the normal
2600 way. */
philippe180a7502014-04-20 13:41:10 +00002601 VG_(client_exit)( VG_(threads)[tid].os_state.exitcode );
sewardjb9779082006-05-12 23:50:15 +00002602 }
njn8aa35852005-06-10 22:59:56 +00002603 /* NOT ALIVE HERE! */
sewardj17c11042006-10-15 01:26:40 +00002604 VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
njn8aa35852005-06-10 22:59:56 +00002605 break; /* what the hell :) */
2606
2607 case VgSrc_FatalSig:
2608 /* We were killed by a fatal signal, so replicate the effect */
2609 vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
2610 VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
njnf76d27a2009-05-28 01:53:07 +00002611 /* we shouldn't be alive at this point. But VG_(kill_self)
2612 sometimes fails with EPERM on Darwin, for unclear reasons. */
2613# if defined(VGO_darwin)
2614 VG_(debugLog)(0, "main", "VG_(kill_self) failed. Exiting normally.\n");
2615 VG_(exit)(0); /* bogus, but we really need to exit now */
2616 /* fall through .. */
2617# endif
njn8aa35852005-06-10 22:59:56 +00002618 VG_(core_panic)("main(): signal was supposed to be fatal");
2619 break;
2620
2621 default:
2622 VG_(core_panic)("main(): unexpected scheduler return code");
2623 }
njne96be672005-05-08 19:08:54 +00002624}
sewardj8b635a42004-11-22 19:01:47 +00002625
sewardj1ae3f3a2005-09-28 10:47:38 +00002626/* -------------------- */
2627
2628/* Final clean-up before terminating the process.
2629 Clean up the client by calling __libc_freeres() (if requested)
2630 This is Linux-specific?
njnf76d27a2009-05-28 01:53:07 +00002631 GrP fixme glibc-specific, anyway
sewardj1ae3f3a2005-09-28 10:47:38 +00002632*/
2633static void final_tidyup(ThreadId tid)
2634{
njnf76d27a2009-05-28 01:53:07 +00002635#if !defined(VGO_darwin)
carllcae0cc22014-08-07 23:17:29 +00002636# if defined(VGP_ppc64be_linux)
sewardjcf951812006-01-17 02:22:21 +00002637 Addr r2;
2638# endif
sewardj0ec07f32006-01-12 12:32:32 +00002639 Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
sewardj1ae3f3a2005-09-28 10:47:38 +00002640
2641 vg_assert(VG_(is_running_thread)(tid));
2642
2643 if ( !VG_(needs).libc_freeres ||
2644 !VG_(clo_run_libc_freeres) ||
sewardj0ec07f32006-01-12 12:32:32 +00002645 0 == __libc_freeres_wrapper )
sewardj1ae3f3a2005-09-28 10:47:38 +00002646 return; /* can't/won't do it */
2647
carllcae0cc22014-08-07 23:17:29 +00002648# if defined(VGP_ppc64be_linux)
sewardjcf951812006-01-17 02:22:21 +00002649 r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
2650 if (r2 == 0) {
2651 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002652 "Caught __NR_exit, but can't run __libc_freeres()\n");
sewardjcf951812006-01-17 02:22:21 +00002653 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002654 " since cannot establish TOC pointer for it.\n");
sewardjcf951812006-01-17 02:22:21 +00002655 return;
2656 }
2657# endif
2658
sewardj1ae3f3a2005-09-28 10:47:38 +00002659 if (VG_(clo_verbosity) > 2 ||
2660 VG_(clo_trace_syscalls) ||
2661 VG_(clo_trace_sched))
2662 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00002663 "Caught __NR_exit; running __libc_freeres()\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002664
sewardj0ec07f32006-01-12 12:32:32 +00002665 /* set thread context to point to libc_freeres_wrapper */
carllcae0cc22014-08-07 23:17:29 +00002666 /* ppc64be-linux note: __libc_freeres_wrapper gives us the real
sewardj1a85f4f2006-01-12 21:15:35 +00002667 function entry point, not a fn descriptor, so can use it
2668 directly. However, we need to set R2 (the toc pointer)
2669 appropriately. */
sewardj1ae3f3a2005-09-28 10:47:38 +00002670 VG_(set_IP)(tid, __libc_freeres_wrapper);
carllcae0cc22014-08-07 23:17:29 +00002671# if defined(VGP_ppc64be_linux)
sewardjcf951812006-01-17 02:22:21 +00002672 VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
carll582d5822014-08-07 23:35:54 +00002673# elif defined(VGP_ppc64le_linux)
2674 /* setting GPR2 but not really needed, GPR12 is needed */
2675 VG_(threads)[tid].arch.vex.guest_GPR2 = __libc_freeres_wrapper;
2676 VG_(threads)[tid].arch.vex.guest_GPR12 = __libc_freeres_wrapper;
sewardjcf951812006-01-17 02:22:21 +00002677# endif
sewardj5db15402012-06-07 09:13:21 +00002678 /* mips-linux note: we need to set t9 */
petarj4df0bfc2013-02-27 23:17:33 +00002679# if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
sewardj5db15402012-06-07 09:13:21 +00002680 VG_(threads)[tid].arch.vex.guest_r25 = __libc_freeres_wrapper;
2681# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002682
2683 /* Block all blockable signals by copying the real block state into
2684 the thread's block state*/
2685 VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
2686 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
2687
2688 /* and restore handlers to default */
2689 VG_(set_default_handler)(VKI_SIGSEGV);
2690 VG_(set_default_handler)(VKI_SIGBUS);
2691 VG_(set_default_handler)(VKI_SIGILL);
2692 VG_(set_default_handler)(VKI_SIGFPE);
2693
2694 // We were exiting, so assert that...
2695 vg_assert(VG_(is_exiting)(tid));
2696 // ...but now we're not again
2697 VG_(threads)[tid].exitreason = VgSrc_None;
2698
2699 // run until client thread exits - ideally with LIBC_FREERES_DONE,
2700 // but exit/exitgroup/signal will do
2701 VG_(scheduler)(tid);
2702
2703 vg_assert(VG_(is_exiting)(tid));
njnf76d27a2009-05-28 01:53:07 +00002704#endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002705}
2706
sewardj45f4e7c2005-09-27 19:20:21 +00002707
2708/*====================================================================*/
njn49f80e82009-05-21 01:25:43 +00002709/*=== Getting to main() alive: LINUX ===*/
sewardj45f4e7c2005-09-27 19:20:21 +00002710/*====================================================================*/
2711
sewardj17c11042006-10-15 01:26:40 +00002712#if defined(VGO_linux)
2713
sewardj45f4e7c2005-09-27 19:20:21 +00002714/* If linking of the final executables is done with glibc present,
2715 then Valgrind starts at main() above as usual, and all of the
2716 following code is irrelevant.
2717
2718 However, this is not the intended mode of use. The plan is to
2719 avoid linking against glibc, by giving gcc the flags
2720 -nodefaultlibs -lgcc -nostartfiles at startup.
2721
2722 From this derive two requirements:
2723
petarje70c45e2013-02-15 03:12:17 +00002724 1. gcc may emit calls to memcpy, memmove and memset to deal with
2725 structure assignments etc. Since we have chosen to ignore all the
sewardj45f4e7c2005-09-27 19:20:21 +00002726 "normal" supporting libraries, we have to provide our own
2727 implementations of them. No problem.
2728
2729 2. We have to provide a symbol "_start", to which the kernel
2730 hands control at startup. Hence the code below.
2731*/
2732
2733/* ---------------- Requirement 1 ---------------- */
2734
sewardj17c11042006-10-15 01:26:40 +00002735void* memcpy(void *dest, const void *src, SizeT n);
2736void* memcpy(void *dest, const void *src, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002737 return VG_(memcpy)(dest,src,n);
2738}
petarje70c45e2013-02-15 03:12:17 +00002739void* memmove(void *dest, const void *src, SizeT n);
2740void* memmove(void *dest, const void *src, SizeT n) {
2741 return VG_(memmove)(dest,src,n);
2742}
sewardj17c11042006-10-15 01:26:40 +00002743void* memset(void *s, int c, SizeT n);
2744void* memset(void *s, int c, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002745 return VG_(memset)(s,c,n);
2746}
2747
bart82616e12010-06-13 13:46:24 +00002748/* BVA: abort() for those platforms that need it (PPC and ARM). */
2749void abort(void);
2750void abort(void){
2751 VG_(printf)("Something called raise().\n");
2752 vg_assert(0);
2753}
2754
sewardj59570ff2010-01-01 11:59:33 +00002755/* EAZG: ARM's EABI will call floating point exception handlers in
2756 libgcc which boil down to an abort or raise, that's usually defined
2757 in libc. Instead, define them here. */
2758#if defined(VGP_arm_linux)
2759void raise(void);
2760void raise(void){
2761 VG_(printf)("Something called raise().\n");
2762 vg_assert(0);
2763}
2764
sewardj59570ff2010-01-01 11:59:33 +00002765void __aeabi_unwind_cpp_pr0(void);
2766void __aeabi_unwind_cpp_pr0(void){
2767 VG_(printf)("Something called __aeabi_unwind_cpp_pr0()\n");
2768 vg_assert(0);
2769}
sewardj38efe4b2010-08-22 12:23:01 +00002770
2771void __aeabi_unwind_cpp_pr1(void);
2772void __aeabi_unwind_cpp_pr1(void){
2773 VG_(printf)("Something called __aeabi_unwind_cpp_pr1()\n");
2774 vg_assert(0);
2775}
sewardj59570ff2010-01-01 11:59:33 +00002776#endif
2777
sewardj45f4e7c2005-09-27 19:20:21 +00002778/* ---------------- Requirement 2 ---------------- */
2779
2780/* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2781 comment, which explains how the stack looks right at process start
2782 (when _start is jumped to). Hence _start passes %esp to
sewardj17c11042006-10-15 01:26:40 +00002783 _start_in_C_linux, which extracts argc/argv/envp and starts up
sewardj45f4e7c2005-09-27 19:20:21 +00002784 correctly. */
2785
2786/* This is the canonical entry point, usually the first thing in the text
2787 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2788 point runs, most registers' values are unspecified, except for:
2789
2790 %edx Contains a function pointer to be registered with `atexit'.
2791 This is how the dynamic linker arranges to have DT_FINI
2792 functions called for shared libraries that have been loaded
2793 before this code runs.
2794
2795 %esp The stack contains the arguments and environment:
2796 0(%esp) argc
2797 4(%esp) argv[0]
2798 ...
2799 (4*argc)(%esp) NULL
2800 (4*(argc+1))(%esp) envp[0]
2801 ...
2802 NULL
2803*/
2804
2805/* The kernel hands control to _start, which extracts the initial
sewardj17c11042006-10-15 01:26:40 +00002806 stack pointer and calls onwards to _start_in_C_linux. This also switches
sewardja48a4932005-09-29 11:09:56 +00002807 the new stack. */
sewardj45f4e7c2005-09-27 19:20:21 +00002808#if defined(VGP_x86_linux)
2809asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002810 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002811 "\t.globl _start\n"
2812 "\t.type _start,@function\n"
2813 "_start:\n"
2814 /* set up the new stack in %eax */
sewardjfdf91b42005-09-28 00:53:09 +00002815 "\tmovl $vgPlain_interim_stack, %eax\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002816 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2817 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2818 "\tsubl $16, %eax\n"
2819 "\tandl $~15, %eax\n"
2820 /* install it, and collect the original one */
2821 "\txchgl %eax, %esp\n"
sewardj17c11042006-10-15 01:26:40 +00002822 /* call _start_in_C_linux, passing it the startup %esp */
sewardj45f4e7c2005-09-27 19:20:21 +00002823 "\tpushl %eax\n"
sewardj17c11042006-10-15 01:26:40 +00002824 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002825 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002826 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002827);
2828#elif defined(VGP_amd64_linux)
2829asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002830 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002831 "\t.globl _start\n"
2832 "\t.type _start,@function\n"
2833 "_start:\n"
2834 /* set up the new stack in %rdi */
sewardjfdf91b42005-09-28 00:53:09 +00002835 "\tmovq $vgPlain_interim_stack, %rdi\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002836 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2837 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2838 "\tandq $~15, %rdi\n"
2839 /* install it, and collect the original one */
2840 "\txchgq %rdi, %rsp\n"
sewardj17c11042006-10-15 01:26:40 +00002841 /* call _start_in_C_linux, passing it the startup %rsp */
2842 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002843 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002844 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002845);
sewardja48a4932005-09-29 11:09:56 +00002846#elif defined(VGP_ppc32_linux)
2847asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002848 ".text\n"
sewardja48a4932005-09-29 11:09:56 +00002849 "\t.globl _start\n"
2850 "\t.type _start,@function\n"
2851 "_start:\n"
2852 /* set up the new stack in r16 */
2853 "\tlis 16,vgPlain_interim_stack@ha\n"
2854 "\tla 16,vgPlain_interim_stack@l(16)\n"
2855 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2856 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2857 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2858 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2859 "\tadd 16,17,16\n"
2860 "\tadd 16,18,16\n"
2861 "\trlwinm 16,16,0,0,27\n"
2862 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2863 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2864 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002865 call _start_in_C_linux, passing it the initial SP. */
sewardja48a4932005-09-29 11:09:56 +00002866 "\tmr 3,1\n"
2867 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002868 "\tbl _start_in_C_linux\n"
sewardja48a4932005-09-29 11:09:56 +00002869 "\ttrap\n"
sewardj2fedc642005-11-19 02:02:57 +00002870 ".previous\n"
sewardja48a4932005-09-29 11:09:56 +00002871);
carllcae0cc22014-08-07 23:17:29 +00002872#elif defined(VGP_ppc64be_linux)
sewardj2c48c7b2005-11-29 13:05:56 +00002873asm("\n"
cerion21082042005-12-06 19:07:08 +00002874 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2875 So we must have one, and that is what goes into the .opd section. */
cerion297c88f2005-12-22 15:53:12 +00002876 "\t.align 2\n"
cerion21082042005-12-06 19:07:08 +00002877 "\t.global _start\n"
2878 "\t.section \".opd\",\"aw\"\n"
2879 "\t.align 3\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002880 "_start:\n"
cerion21082042005-12-06 19:07:08 +00002881 "\t.quad ._start,.TOC.@tocbase,0\n"
2882 "\t.previous\n"
2883 "\t.type ._start,@function\n"
2884 "\t.global ._start\n"
2885 "._start:\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002886 /* set up the new stack in r16 */
2887 "\tlis 16, vgPlain_interim_stack@highest\n"
2888 "\tori 16,16,vgPlain_interim_stack@higher\n"
2889 "\tsldi 16,16,32\n"
2890 "\toris 16,16,vgPlain_interim_stack@h\n"
2891 "\tori 16,16,vgPlain_interim_stack@l\n"
2892 "\txor 17,17,17\n"
2893 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2894 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2895 "\txor 18,18,18\n"
2896 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2897 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2898 "\tadd 16,17,16\n"
2899 "\tadd 16,18,16\n"
2900 "\trldicr 16,16,0,59\n"
2901 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2902 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2903 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002904 call _start_in_C_linux, passing it the initial SP. */
sewardj2c48c7b2005-11-29 13:05:56 +00002905 "\tmr 3,1\n"
2906 "\tmr 1,16\n"
sewardj5e21d442012-07-21 10:08:29 +00002907 "\tlis 14, _start_in_C_linux@highest\n"
2908 "\tori 14,14,_start_in_C_linux@higher\n"
2909 "\tsldi 14,14,32\n"
2910 "\toris 14,14,_start_in_C_linux@h\n"
2911 "\tori 14,14,_start_in_C_linux@l\n"
2912 "\tld 14,0(14)\n"
2913 "\tmtctr 14\n"
2914 "\tbctrl\n"
cerion21082042005-12-06 19:07:08 +00002915 "\tnop\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002916 "\ttrap\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002917);
carll582d5822014-08-07 23:35:54 +00002918#elif defined(VGP_ppc64le_linux)
2919/* Little Endian uses ELF version 2 but in the future may also
2920 * support other ELF versions.
2921 */
2922asm("\n"
2923 "\t.align 2\n"
2924 "\t.global _start\n"
2925 "\t.type _start,@function\n"
2926 "_start:\n"
2927 "#if _CALL_ELF == 2 \n"
2928 "0: addis 2,12,.TOC.-0b@ha\n"
2929 " addi 2,2,.TOC.-0b@l\n"
2930 " .localentry _start, .-_start\n"
2931 "#endif \n"
2932 /* set up the new stack in r16 */
2933 "\tlis 16, vgPlain_interim_stack@highest\n"
2934 "\tori 16,16,vgPlain_interim_stack@higher\n"
2935 "\tsldi 16,16,32\n"
2936 "\toris 16,16,vgPlain_interim_stack@h\n"
2937 "\tori 16,16,vgPlain_interim_stack@l\n"
2938 "\txor 17,17,17\n"
2939 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2940 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2941 "\txor 18,18,18\n"
2942 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2943 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2944 "\tadd 16,17,16\n"
2945 "\tadd 16,18,16\n"
2946 "\trldicr 16,16,0,59\n"
2947 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2948 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2949 boundary. And r1 is the original SP. Set the SP to r16 and
2950 call _start_in_C_linux, passing it the initial SP. */
2951 "\tmr 3,1\n"
2952 "\tmr 1,16\n"
2953 "\tlis 14, _start_in_C_linux@highest\n"
2954 "\tori 14,14,_start_in_C_linux@higher\n"
2955 "\tsldi 14,14,32\n"
2956 "\toris 14,14,_start_in_C_linux@h\n"
2957 "\tori 14,14,_start_in_C_linux@l\n"
2958 "\tmtctr 14\n"
2959 "\tbctrl\n"
2960 "\tnop\n"
2961 "\ttrap\n"
2962);
sewardjb5b87402011-03-07 16:05:35 +00002963#elif defined(VGP_s390x_linux)
2964/*
2965 This is the canonical entry point, usually the first thing in the text
2966 segment. Most registers' values are unspecified, except for:
2967
2968 %r14 Contains a function pointer to be registered with `atexit'.
2969 This is how the dynamic linker arranges to have DT_FINI
2970 functions called for shared libraries that have been loaded
2971 before this code runs.
2972
2973 %r15 The stack contains the arguments and environment:
2974 0(%r15) argc
2975 8(%r15) argv[0]
2976 ...
2977 (8*argc)(%r15) NULL
2978 (8*(argc+1))(%r15) envp[0]
2979 ...
2980 NULL
2981*/
2982asm("\n\t"
2983 ".text\n\t"
2984 ".globl _start\n\t"
2985 ".type _start,@function\n\t"
2986 "_start:\n\t"
2987 /* set up the new stack in %r1 */
2988 "larl %r1, vgPlain_interim_stack\n\t"
2989 "larl %r5, 1f\n\t"
2990 "ag %r1, 0(%r5)\n\t"
2991 "ag %r1, 2f-1f(%r5)\n\t"
2992 "nill %r1, 0xFFF0\n\t"
2993 /* install it, and collect the original one */
2994 "lgr %r2, %r15\n\t"
2995 "lgr %r15, %r1\n\t"
2996 /* call _start_in_C_linux, passing it the startup %r15 */
2997 "brasl %r14, _start_in_C_linux\n\t"
2998 /* trigger execution of an invalid opcode -> halt machine */
2999 "j .+2\n\t"
3000 "1: .quad "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n\t"
3001 "2: .quad "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n\t"
3002 ".previous\n"
3003);
sewardj59570ff2010-01-01 11:59:33 +00003004#elif defined(VGP_arm_linux)
3005asm("\n"
sewardjb51c9262011-05-03 14:24:11 +00003006 "\t.text\n"
3007 "\t.align 4\n"
3008 "\t.type _start,#function\n"
sewardj59570ff2010-01-01 11:59:33 +00003009 "\t.global _start\n"
3010 "_start:\n"
3011 "\tldr r0, [pc, #36]\n"
3012 "\tldr r1, [pc, #36]\n"
3013 "\tadd r0, r1, r0\n"
3014 "\tldr r1, [pc, #32]\n"
3015 "\tadd r0, r1, r0\n"
3016 "\tmvn r1, #15\n"
3017 "\tand r0, r0, r1\n"
3018 "\tmov r1, sp\n"
3019 "\tmov sp, r0\n"
3020 "\tmov r0, r1\n"
3021 "\tb _start_in_C_linux\n"
3022 "\t.word vgPlain_interim_stack\n"
3023 "\t.word "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
3024 "\t.word "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
3025);
sewardjf0c12502014-01-12 12:54:00 +00003026#elif defined(VGP_arm64_linux)
3027asm("\n"
3028 "\t.text\n"
3029 "\t.align 2\n"
3030 "\t.type _start,#function\n"
3031 "\t.global _start\n"
3032 "_start:\n"
3033 "\tadrp x0, vgPlain_interim_stack\n"
3034 "\tadd x0, x0, :lo12:vgPlain_interim_stack\n"
3035 // The next 2 assume that VG_STACK_GUARD_SZB fits in 32 bits
3036 "\tmov x1, (("VG_STRINGIFY(VG_STACK_GUARD_SZB)") >> 0) & 0xFFFF\n"
3037 "\tmovk x1, (("VG_STRINGIFY(VG_STACK_GUARD_SZB)") >> 16) & 0xFFFF,"
3038 " lsl 16\n"
3039 "\tadd x0, x0, x1\n"
3040 // The next 2 assume that VG_STACK_ACTIVE_SZB fits in 32 bits
3041 "\tmov x1, (("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)") >> 0) & 0xFFFF\n"
3042 "\tmovk x1, (("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)") >> 16) & 0xFFFF,"
3043 " lsl 16\n"
3044 "\tadd x0, x0, x1\n"
3045 "\tand x0, x0, -16\n"
3046 "\tmov x1, sp\n"
3047 "\tmov sp, x0\n"
3048 "\tmov x0, x1\n"
3049 "\tb _start_in_C_linux\n"
3050);
sewardj5db15402012-06-07 09:13:21 +00003051#elif defined(VGP_mips32_linux)
3052asm("\n"
3053 "\t.type _gp_disp,@object\n"
3054 ".text\n"
3055 "\t.globl __start\n"
3056 "\t.type __start,@function\n"
3057 "__start:\n"
3058
3059 "\tbal 1f\n"
3060 "\tnop\n"
3061
3062 "1:\n"
3063
3064 "\tlui $28, %hi(_gp_disp)\n"
3065 "\taddiu $28, $28, %lo(_gp_disp)\n"
3066 "\taddu $28, $28, $31\n"
3067 /* t1/$9 <- Addr(interim_stack) */
3068 "\tlui $9, %hi(vgPlain_interim_stack)\n"
3069 /* t1/$9 <- Addr(interim_stack) */
3070 "\taddiu $9, %lo(vgPlain_interim_stack)\n"
3071
3072
3073 "\tli $10, "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
3074 "\tli $11, "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
3075
3076 "\taddu $9, $9, $10\n"
3077 "\taddu $9, $9, $11\n"
3078 "\tli $12, 0xFFFFFFF0\n"
3079 "\tand $9, $9, $12\n"
3080 /* now t1/$9 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
3081 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
3082 boundary. And $29 is the original SP. Set the SP to t1 and
3083 call _start_in_C, passing it the initial SP. */
3084
3085 "\tmove $4, $29\n" // a0 <- $sp (_start_in_C first arg)
3086 "\tmove $29, $9\n" // $sp <- t1 (new sp)
3087
3088 "\tlui $25, %hi(_start_in_C_linux)\n"
3089 "\taddiu $25, %lo(_start_in_C_linux)\n"
3090
3091 "\tbal _start_in_C_linux\n"
3092 "\tbreak 0x7\n"
3093 ".previous\n"
3094);
petarj4df0bfc2013-02-27 23:17:33 +00003095#elif defined(VGP_mips64_linux)
3096asm(
3097".text\n"
3098".globl __start\n"
3099".type __start,@function\n"
3100"__start:\n"
3101 "\t.set noreorder\n"
3102 "\t.cpload $25\n"
3103 "\t.set reorder\n"
3104 "\t.cprestore 16\n"
3105 "\tlui $9, %hi(vgPlain_interim_stack)\n"
3106 /* t1/$9 <- Addr(interim_stack) */
3107 "\tdaddiu $9, %lo(vgPlain_interim_stack)\n"
3108
3109 "\tli $10, "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
3110 "\tli $11, "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
3111
3112 "\tdaddu $9, $9, $10\n"
3113 "\tdaddu $9, $9, $11\n"
3114 "\tli $12, 0xFFFFFF00\n"
3115 "\tand $9, $9, $12\n"
3116 /* now t1/$9 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
3117 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
3118 boundary. And $29 is the original SP. Set the SP to t1 and
3119 call _start_in_C, passing it the initial SP. */
3120
3121 "\tmove $4, $29\n" // a0 <- $sp (_start_in_C first arg)
3122 "\tmove $29, $9\n" // $sp <- t1 (new sp)
3123
3124 "\tlui $9, %highest(_start_in_C_linux)\n"
3125 "\tori $9, %higher(_start_in_C_linux)\n"
3126 "\tdsll32 $9, $9, 0x0\n"
3127 "\tlui $10, %hi(_start_in_C_linux)\n"
3128 "\tdaddiu $10, %lo(_start_in_C_linux)\n"
3129 "\tdaddu $25, $9, $10\n"
3130 "\tjalr $25\n"
3131 "\tnop\n"
dejanj124b9f22013-10-16 14:15:38 +00003132".previous\n"
petarj4df0bfc2013-02-27 23:17:33 +00003133);
sewardj45f4e7c2005-09-27 19:20:21 +00003134#else
njn49f80e82009-05-21 01:25:43 +00003135# error "Unknown linux platform"
sewardj45f4e7c2005-09-27 19:20:21 +00003136#endif
3137
sewardje66f2e02006-12-30 17:45:08 +00003138/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
3139#define _GNU_SOURCE
3140#define _FILE_OFFSET_BITS 64
3141/* This is in order to get AT_NULL and AT_PAGESIZE. */
3142#include <elf.h>
3143/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
3144
sewardj45f4e7c2005-09-27 19:20:21 +00003145/* Avoid compiler warnings: this fn _is_ used, but labelling it
philippe9fdca562012-04-16 22:06:47 +00003146 'static' causes gcc to complain it isn't.
3147 attribute 'used' also ensures the code is not eliminated at link
3148 time */
3149__attribute__ ((used))
sewardj17c11042006-10-15 01:26:40 +00003150void _start_in_C_linux ( UWord* pArgc );
philippe9fdca562012-04-16 22:06:47 +00003151__attribute__ ((used))
sewardj17c11042006-10-15 01:26:40 +00003152void _start_in_C_linux ( UWord* pArgc )
sewardj45f4e7c2005-09-27 19:20:21 +00003153{
3154 Int r;
3155 Word argc = pArgc[0];
3156 HChar** argv = (HChar**)&pArgc[1];
3157 HChar** envp = (HChar**)&pArgc[1+argc+1];
sewardjf9d2f9b2006-11-17 20:00:57 +00003158
philippe854be4c2013-10-22 21:20:14 +00003159 // For an inner Valgrind, register the interim stack asap.
3160 // This is needed to allow the outer valgrind to do stacktraces during init.
3161 // Note that this stack is not unregistered when the main thread
3162 // is switching to the (real) stack. Unregistering this would imply
3163 // to save the stack id in a global variable, and have a "if"
3164 // in run_a_thread_NORETURN to do the unregistration only for the
3165 // main thread. This unregistration is not worth this complexity.
3166 INNER_REQUEST
3167 ((void) VALGRIND_STACK_REGISTER
3168 (&VG_(interim_stack).bytes[0],
3169 &VG_(interim_stack).bytes[0] + sizeof(VG_(interim_stack))));
3170
sewardjf9d2f9b2006-11-17 20:00:57 +00003171 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
3172 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
3173
3174 the_iicii.sp_at_startup = (Addr)pArgc;
3175
carllcae0cc22014-08-07 23:17:29 +00003176# if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
3177 || defined(VGP_ppc64le_linux) || defined(VGP_arm64_linux)
sewardje66f2e02006-12-30 17:45:08 +00003178 {
carllcae0cc22014-08-07 23:17:29 +00003179 /* ppc32/ppc64 can be configured with different page sizes.
sewardje66f2e02006-12-30 17:45:08 +00003180 Determine this early. This is an ugly hack and really should
3181 be moved into valgrind_main. */
3182 UWord *sp = &pArgc[1+argc+1];
3183 while (*sp++ != 0)
3184 ;
3185 for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
3186 if (*sp == AT_PAGESZ) {
3187 VKI_PAGE_SIZE = sp[1];
3188 for (VKI_PAGE_SHIFT = 12;
3189 VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
3190 if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
3191 break;
3192 }
3193 }
3194# endif
3195
sewardjf9d2f9b2006-11-17 20:00:57 +00003196 r = valgrind_main( (Int)argc, argv, envp );
sewardj17c11042006-10-15 01:26:40 +00003197 /* NOTREACHED */
sewardj45f4e7c2005-09-27 19:20:21 +00003198 VG_(exit)(r);
3199}
3200
sewardj17c11042006-10-15 01:26:40 +00003201
3202/*====================================================================*/
njnf76d27a2009-05-28 01:53:07 +00003203/*=== Getting to main() alive: darwin ===*/
3204/*====================================================================*/
3205
3206#elif defined(VGO_darwin)
3207
njnea2d6fd2010-07-01 00:20:20 +00003208/*
3209 Memory layout established by kernel:
3210
3211 0(%esp) argc
3212 4(%esp) argv[0]
3213 ...
3214 argv[argc-1]
3215 NULL
3216 envp[0]
3217 ...
3218 envp[n]
3219 NULL
3220 executable name (presumably, a pointer to it)
3221 NULL
3222
3223 Ditto in the 64-bit case, except all offsets from SP are obviously
3224 twice as large.
3225*/
3226
3227/* The kernel hands control to _start, which extracts the initial
3228 stack pointer and calls onwards to _start_in_C_darwin. This also
3229 switches to the new stack. */
3230#if defined(VGP_x86_darwin)
3231asm("\n"
3232 ".text\n"
3233 ".align 2,0x90\n"
3234 "\t.globl __start\n"
3235 "__start:\n"
3236 /* set up the new stack in %eax */
3237 "\tmovl $_vgPlain_interim_stack, %eax\n"
3238 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
3239 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
3240 "\tsubl $16, %eax\n"
3241 "\tandl $~15, %eax\n"
3242 /* install it, and collect the original one */
3243 "\txchgl %eax, %esp\n"
sewardj69197362012-03-07 16:38:12 +00003244 "\tsubl $12, %esp\n" // keep stack 16 aligned; see #295428
njnea2d6fd2010-07-01 00:20:20 +00003245 /* call _start_in_C_darwin, passing it the startup %esp */
3246 "\tpushl %eax\n"
3247 "\tcall __start_in_C_darwin\n"
3248 "\tint $3\n"
3249 "\tint $3\n"
3250);
3251#elif defined(VGP_amd64_darwin)
3252asm("\n"
3253 ".text\n"
3254 "\t.globl __start\n"
3255 ".align 3,0x90\n"
3256 "__start:\n"
3257 /* set up the new stack in %rdi */
3258 "\tmovabsq $_vgPlain_interim_stack, %rdi\n"
3259 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
3260 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
3261 "\tandq $~15, %rdi\n"
3262 /* install it, and collect the original one */
3263 "\txchgq %rdi, %rsp\n"
3264 /* call _start_in_C_darwin, passing it the startup %rsp */
3265 "\tcall __start_in_C_darwin\n"
3266 "\tint $3\n"
3267 "\tint $3\n"
3268);
3269#endif
3270
njnf76d27a2009-05-28 01:53:07 +00003271void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2);
3272void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2) {
3273 // skip check
3274 return VG_(memcpy)(dest,src,n);
3275}
3276void* __memset_chk(void *s, int c, SizeT n, SizeT n2);
3277void* __memset_chk(void *s, int c, SizeT n, SizeT n2) {
3278 // skip check
3279 return VG_(memset)(s,c,n);
3280}
3281void bzero(void *s, SizeT n);
3282void bzero(void *s, SizeT n) {
3283 VG_(memset)(s,0,n);
3284}
3285
3286void* memcpy(void *dest, const void *src, SizeT n);
3287void* memcpy(void *dest, const void *src, SizeT n) {
3288 return VG_(memcpy)(dest,src,n);
3289}
3290void* memset(void *s, int c, SizeT n);
3291void* memset(void *s, int c, SizeT n) {
3292 return VG_(memset)(s,c,n);
3293}
3294
njnf76d27a2009-05-28 01:53:07 +00003295/* Avoid compiler warnings: this fn _is_ used, but labelling it
3296 'static' causes gcc to complain it isn't. */
3297void _start_in_C_darwin ( UWord* pArgc );
3298void _start_in_C_darwin ( UWord* pArgc )
3299{
3300 Int r;
njnea2d6fd2010-07-01 00:20:20 +00003301 Int argc = *(Int *)pArgc; // not pArgc[0] on LP64
njnf76d27a2009-05-28 01:53:07 +00003302 HChar** argv = (HChar**)&pArgc[1];
3303 HChar** envp = (HChar**)&pArgc[1+argc+1];
3304
philippe854be4c2013-10-22 21:20:14 +00003305 // See _start_in_C_linux
3306 INNER_REQUEST
3307 ((void) VALGRIND_STACK_REGISTER
3308 (&VG_(interim_stack).bytes[0],
3309 &VG_(interim_stack).bytes[0] + sizeof(VG_(interim_stack))));
3310
njnf76d27a2009-05-28 01:53:07 +00003311 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
3312 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
3313
3314 the_iicii.sp_at_startup = (Addr)pArgc;
3315
3316 r = valgrind_main( (Int)argc, argv, envp );
3317 /* NOTREACHED */
3318 VG_(exit)(r);
3319}
3320
3321
njn49f80e82009-05-21 01:25:43 +00003322#else
3323
3324# error "Unknown OS"
3325#endif
sewardj17c11042006-10-15 01:26:40 +00003326
3327
sewardj0af71bb2010-07-01 14:50:30 +00003328/*====================================================================*/
3329/*=== {u,}{div,mod}di3 replacements ===*/
3330/*====================================================================*/
njnea2d6fd2010-07-01 00:20:20 +00003331
3332/* For static linking on x86-darwin, we need to supply our own 64-bit
3333 integer division code, else the link dies thusly:
3334
3335 ld_classic: Undefined symbols:
3336 ___udivdi3
3337 ___umoddi3
3338*/
3339#if defined(VGP_x86_darwin)
3340
3341/* Routines for doing signed/unsigned 64 x 64 ==> 64 div and mod
3342 (udivdi3, umoddi3, divdi3, moddi3) using only 32 x 32 ==> 32
3343 division. Cobbled together from
3344
3345 http://www.hackersdelight.org/HDcode/divlu.c
3346 http://www.hackersdelight.org/HDcode/divls.c
3347 http://www.hackersdelight.org/HDcode/newCode/divDouble.c
3348
3349 The code from those three files is covered by the following license,
3350 as it appears at:
3351
3352 http://www.hackersdelight.org/permissions.htm
3353
3354 You are free to use, copy, and distribute any of the code on
3355 this web site, whether modified by you or not. You need not give
3356 attribution. This includes the algorithms (some of which appear
3357 in Hacker's Delight), the Hacker's Assistant, and any code
3358 submitted by readers. Submitters implicitly agree to this.
3359*/
3360
3361/* Long division, unsigned (64/32 ==> 32).
3362 This procedure performs unsigned "long division" i.e., division of a
336364-bit unsigned dividend by a 32-bit unsigned divisor, producing a
336432-bit quotient. In the overflow cases (divide by 0, or quotient
3365exceeds 32 bits), it returns a remainder of 0xFFFFFFFF (an impossible
3366value).
3367 The dividend is u1 and u0, with u1 being the most significant word.
3368The divisor is parameter v. The value returned is the quotient.
3369 Max line length is 57, to fit in hacker.book. */
3370
3371static Int nlz32(UInt x)
3372{
3373 Int n;
3374 if (x == 0) return(32);
3375 n = 0;
3376 if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
3377 if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
3378 if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
3379 if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
3380 if (x <= 0x7FFFFFFF) {n = n + 1;}
3381 return n;
3382}
3383
3384/* 64 x 32 ==> 32 unsigned division, using only 32 x 32 ==> 32
3385 division as a primitive. */
3386static UInt divlu2(UInt u1, UInt u0, UInt v, UInt *r)
3387{
3388 const UInt b = 65536; // Number base (16 bits).
3389 UInt un1, un0, // Norm. dividend LSD's.
3390 vn1, vn0, // Norm. divisor digits.
3391 q1, q0, // Quotient digits.
3392 un32, un21, un10, // Dividend digit pairs.
3393 rhat; // A remainder.
3394 Int s; // Shift amount for norm.
3395
3396 if (u1 >= v) { // If overflow, set rem.
3397 if (r != NULL) // to an impossible value,
3398 *r = 0xFFFFFFFF; // and return the largest
3399 return 0xFFFFFFFF;} // possible quotient.
3400
3401 s = nlz32(v); // 0 <= s <= 31.
3402 v = v << s; // Normalize divisor.
3403 vn1 = v >> 16; // Break divisor up into
3404 vn0 = v & 0xFFFF; // two 16-bit digits.
3405
3406 un32 = (u1 << s) | ((u0 >> (32 - s)) & (-s >> 31));
3407 un10 = u0 << s; // Shift dividend left.
3408
3409 un1 = un10 >> 16; // Break right half of
3410 un0 = un10 & 0xFFFF; // dividend into two digits.
3411
3412 q1 = un32/vn1; // Compute the first
3413 rhat = un32 - q1*vn1; // quotient digit, q1.
3414 again1:
3415 if (q1 >= b || q1*vn0 > b*rhat + un1) {
3416 q1 = q1 - 1;
3417 rhat = rhat + vn1;
3418 if (rhat < b) goto again1;}
3419
3420 un21 = un32*b + un1 - q1*v; // Multiply and subtract.
3421
3422 q0 = un21/vn1; // Compute the second
3423 rhat = un21 - q0*vn1; // quotient digit, q0.
3424 again2:
3425 if (q0 >= b || q0*vn0 > b*rhat + un0) {
3426 q0 = q0 - 1;
3427 rhat = rhat + vn1;
3428 if (rhat < b) goto again2;}
3429
3430 if (r != NULL) // If remainder is wanted,
3431 *r = (un21*b + un0 - q0*v) >> s; // return it.
3432 return q1*b + q0;
3433}
3434
3435
3436/* 64 x 32 ==> 32 signed division, using only 32 x 32 ==> 32 division
3437 as a primitive. */
3438static Int divls(Int u1, UInt u0, Int v, Int *r)
3439{
3440 Int q, uneg, vneg, diff, borrow;
3441
3442 uneg = u1 >> 31; // -1 if u < 0.
3443 if (uneg) { // Compute the absolute
3444 u0 = -u0; // value of the dividend u.
3445 borrow = (u0 != 0);
3446 u1 = -u1 - borrow;}
3447
3448 vneg = v >> 31; // -1 if v < 0.
3449 v = (v ^ vneg) - vneg; // Absolute value of v.
3450
3451 if ((UInt)u1 >= (UInt)v) goto overflow;
3452
3453 q = divlu2(u1, u0, v, (UInt *)r);
3454
3455 diff = uneg ^ vneg; // Negate q if signs of
3456 q = (q ^ diff) - diff; // u and v differed.
3457 if (uneg && r != NULL)
3458 *r = -*r;
3459
3460 if ((diff ^ q) < 0 && q != 0) { // If overflow,
3461 overflow: // set remainder
3462 if (r != NULL) // to an impossible value,
3463 *r = 0x80000000; // and return the largest
3464 q = 0x80000000;} // possible neg. quotient.
3465 return q;
3466}
3467
3468
3469
3470/* This file contains a program for doing 64/64 ==> 64 division, on a
3471machine that does not have that instruction but that does have
3472instructions for "long division" (64/32 ==> 32). Code for unsigned
3473division is given first, followed by a simple program for doing the
3474signed version by using the unsigned version.
3475 These programs are useful in implementing "long long" (64-bit)
3476arithmetic on a machine that has the long division instruction. It will
3477work on 64- and 32-bit machines, provided the compiler implements long
3478long's (64-bit integers). It is desirable that the machine have the
3479Count Leading Zeros instruction.
3480 In the GNU world, these programs are known as __divdi3 and __udivdi3,
3481and similar names are used here.
3482 This material is not in HD, but may be in a future edition.
3483Max line length is 57, to fit in hacker.book. */
3484
3485
3486static Int nlz64(ULong x)
3487{
3488 Int n;
3489 if (x == 0) return(64);
3490 n = 0;
3491 if (x <= 0x00000000FFFFFFFFULL) {n = n + 32; x = x << 32;}
3492 if (x <= 0x0000FFFFFFFFFFFFULL) {n = n + 16; x = x << 16;}
3493 if (x <= 0x00FFFFFFFFFFFFFFULL) {n = n + 8; x = x << 8;}
3494 if (x <= 0x0FFFFFFFFFFFFFFFULL) {n = n + 4; x = x << 4;}
3495 if (x <= 0x3FFFFFFFFFFFFFFFULL) {n = n + 2; x = x << 2;}
3496 if (x <= 0x7FFFFFFFFFFFFFFFULL) {n = n + 1;}
3497 return n;
3498}
3499
3500// ---------------------------- udivdi3 --------------------------------
3501
3502 /* The variables u0, u1, etc. take on only 32-bit values, but they
3503 are declared long long to avoid some compiler warning messages and to
3504 avoid some unnecessary EXTRs that the compiler would put in, to
3505 convert long longs to ints.
3506
3507 First the procedure takes care of the case in which the divisor is a
3508 32-bit quantity. There are two subcases: (1) If the left half of the
3509 dividend is less than the divisor, one execution of DIVU is all that
3510 is required (overflow is not possible). (2) Otherwise it does two
3511 divisions, using the grade school method, with variables used as
3512 suggested below.
3513
3514 q1 q0
3515 ________
3516 v) u1 u0
3517 q1*v
3518 ____
3519 k u0 */
3520
3521/* These macros must be used with arguments of the appropriate type
3522(unsigned long long for DIVU and long long for DIVS. They are
3523simulations of the presumed machines ops. I.e., they look at only the
3524low-order 32 bits of the divisor, they return garbage if the division
3525overflows, and they return garbage in the high-order half of the
3526quotient doubleword.
3527 In practice, these would be replaced with uses of the machine's DIVU
3528and DIVS instructions (e.g., by using the GNU "asm" facility). */
3529
3530static UInt DIVU ( ULong u, UInt v )
3531{
3532 UInt uHi = (UInt)(u >> 32);
3533 UInt uLo = (UInt)u;
3534 return divlu2(uHi, uLo, v, NULL);
3535}
3536
3537static Int DIVS ( Long u, Int v )
3538{
3539 Int uHi = (Int)(u >> 32);
3540 UInt uLo = (UInt)u;
3541 return divls(uHi, uLo, v, NULL);
3542}
3543
3544/* 64 x 64 ==> 64 unsigned division, using only 32 x 32 ==> 32
3545 division as a primitive. */
3546static ULong udivdi3(ULong u, ULong v)
3547{
3548 ULong u0, u1, v1, q0, q1, k, n;
3549
3550 if (v >> 32 == 0) { // If v < 2**32:
3551 if (u >> 32 < v) // If u/v cannot overflow,
3552 return DIVU(u, v) // just do one division.
3553 & 0xFFFFFFFF;
3554 else { // If u/v would overflow:
3555 u1 = u >> 32; // Break u up into two
3556 u0 = u & 0xFFFFFFFF; // halves.
3557 q1 = DIVU(u1, v) // First quotient digit.
3558 & 0xFFFFFFFF;
3559 k = u1 - q1*v; // First remainder, < v.
3560 q0 = DIVU((k << 32) + u0, v) // 2nd quot. digit.
3561 & 0xFFFFFFFF;
3562 return (q1 << 32) + q0;
3563 }
3564 }
3565 // Here v >= 2**32.
3566 n = nlz64(v); // 0 <= n <= 31.
3567 v1 = (v << n) >> 32; // Normalize the divisor
3568 // so its MSB is 1.
3569 u1 = u >> 1; // To ensure no overflow.
3570 q1 = DIVU(u1, v1) // Get quotient from
3571 & 0xFFFFFFFF; // divide unsigned insn.
3572 q0 = (q1 << n) >> 31; // Undo normalization and
3573 // division of u by 2.
3574 if (q0 != 0) // Make q0 correct or
3575 q0 = q0 - 1; // too small by 1.
3576 if ((u - q0*v) >= v)
3577 q0 = q0 + 1; // Now q0 is correct.
3578 return q0;
3579}
3580
3581
3582// ----------------------------- divdi3 --------------------------------
3583
3584/* This routine presumes that smallish cases (those which can be done in
3585one execution of DIVS) are common. If this is not the case, the test for
3586this case should be deleted.
3587 Note that the test for when DIVS can be used is not entirely
3588accurate. For example, DIVS is not used if v = 0xFFFFFFFF8000000,
3589whereas if could be (if u is sufficiently small in magnitude). */
3590
3591// ------------------------------ cut ----------------------------------
3592
3593static ULong my_llabs ( Long x )
3594{
3595 ULong t = x >> 63;
3596 return (x ^ t) - t;
3597}
3598
3599/* 64 x 64 ==> 64 signed division, using only 32 x 32 ==> 32 division
3600 as a primitive. */
3601static Long divdi3(Long u, Long v)
3602{
3603 ULong au, av;
3604 Long q, t;
3605 au = my_llabs(u);
3606 av = my_llabs(v);
3607 if (av >> 31 == 0) { // If |v| < 2**31 and
3608 // if (v << 32 >> 32 == v) { // If v is in range and
3609 if (au < av << 31) { // |u|/|v| cannot
3610 q = DIVS(u, v); // overflow, use DIVS.
3611 return (q << 32) >> 32;
3612 }
3613 }
3614 q = udivdi3(au,av); // Invoke udivdi3.
3615 t = (u ^ v) >> 63; // If u, v have different
3616 return (q ^ t) - t; // signs, negate q.
3617}
3618
3619// ---------------------------- end cut --------------------------------
3620
sewardj0af71bb2010-07-01 14:50:30 +00003621ULong __udivdi3 (ULong u, ULong v);
njnea2d6fd2010-07-01 00:20:20 +00003622ULong __udivdi3 (ULong u, ULong v)
3623{
3624 return udivdi3(u,v);
3625}
3626
sewardj0af71bb2010-07-01 14:50:30 +00003627Long __divdi3 (Long u, Long v);
njnea2d6fd2010-07-01 00:20:20 +00003628Long __divdi3 (Long u, Long v)
3629{
3630 return divdi3(u,v);
3631}
3632
sewardj0af71bb2010-07-01 14:50:30 +00003633ULong __umoddi3 (ULong u, ULong v);
njnea2d6fd2010-07-01 00:20:20 +00003634ULong __umoddi3 (ULong u, ULong v)
3635{
3636 ULong q = __udivdi3(u, v);
3637 ULong r = u - q * v;
3638 return r;
3639}
3640
sewardj0af71bb2010-07-01 14:50:30 +00003641Long __moddi3 (Long u, Long v);
njnea2d6fd2010-07-01 00:20:20 +00003642Long __moddi3 (Long u, Long v)
3643{
3644 Long q = __divdi3(u, v);
3645 Long r = u - q * v;
3646 return r;
3647}
3648
sewardj70d71c72011-08-23 07:35:42 +00003649/* ------------------------------------------------
3650 ld_classic: Undefined symbols:
3651 ___fixunsdfdi
3652 ------------------------------------------------
3653*/
3654
3655/* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------===
3656 *
3657 * The LLVM Compiler Infrastructure
3658 *
3659 * This file is dual licensed under the MIT and the University of Illinois Open
3660 * Source Licenses. See LICENSE.TXT for details.
3661 *
3662 * ===----------------------------------------------------------------------===
3663 *
3664 * This file implements __fixunsdfdi for the compiler_rt library.
3665 *
3666 * ===----------------------------------------------------------------------===
3667 */
3668
3669/* As per http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses,
3670
3671 the "NCSA/University of Illinois Open Source License" is compatible
3672 with the GPL (both version 2 and 3). What is claimed to be
3673 compatible is this
3674
3675 http://www.opensource.org/licenses/UoI-NCSA.php
3676
3677 and the LLVM documentation at
3678
3679 http://www.llvm.org/docs/DeveloperPolicy.html#license
3680
3681 says all the code in LLVM is available under the University of
3682 Illinois/NCSA Open Source License, at this URL
3683
3684 http://www.opensource.org/licenses/UoI-NCSA.php
3685
3686 viz, the same one that the FSF pages claim is compatible. So I
3687 think it's OK to include it.
3688*/
3689
3690/* Returns: convert a to a unsigned long long, rounding toward zero.
3691 * Negative values all become zero.
3692 */
3693
3694/* Assumption: double is a IEEE 64 bit floating point type
3695 * du_int is a 64 bit integral type
3696 * value in double is representable in du_int or is negative
3697 * (no range checking performed)
3698 */
3699
3700/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
3701
3702typedef unsigned long long du_int;
3703typedef unsigned su_int;
3704
3705typedef union
3706{
3707 du_int all;
3708 struct
3709 {
3710#if VG_LITTLEENDIAN
3711 su_int low;
3712 su_int high;
3713#else
3714 su_int high;
3715 su_int low;
3716#endif /* VG_LITTLEENDIAN */
3717 }s;
3718} udwords;
3719
3720typedef union
3721{
3722 udwords u;
3723 double f;
3724} double_bits;
3725
3726du_int __fixunsdfdi(double a);
3727
3728du_int
3729__fixunsdfdi(double a)
3730{
3731 double_bits fb;
3732 fb.f = a;
3733 int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
3734 if (e < 0 || (fb.u.s.high & 0x80000000))
3735 return 0;
3736 udwords r;
3737 r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
3738 r.s.low = fb.u.s.low;
3739 if (e > 52)
3740 r.all <<= (e - 52);
3741 else
3742 r.all >>= (52 - e);
3743 return r.all;
3744}
3745
3746
njnea2d6fd2010-07-01 00:20:20 +00003747#endif
3748
3749
sewardjde4a1d02002-03-22 01:27:54 +00003750/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00003751/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00003752/*--------------------------------------------------------------------*/