blob: bbda855895590a6aed93d13819a95cad70199b8a [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
sewardj03f8d3f2012-08-05 15:46:46 +000010 Copyright (C) 2000-2012 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"
sewardj45f4e7c2005-09-27 19:20:21 +000052#include "pub_core_syscall.h" // VG_(strerror)
njnf76d27a2009-05-28 01:53:07 +000053#include "pub_core_mach.h"
njnf536bbb2005-06-13 04:21:38 +000054#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +000055#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000056#include "pub_core_options.h"
sewardjfdf91b42005-09-28 00:53:09 +000057#include "pub_core_debuginfo.h"
njnd1af0032005-05-29 17:01:48 +000058#include "pub_core_redir.h"
njnc7561b92005-06-19 01:24:32 +000059#include "pub_core_scheduler.h"
sewardjf9ebc392010-05-09 22:30:43 +000060#include "pub_core_seqmatch.h" // For VG_(string_match)
njn0c246472005-05-31 01:00:08 +000061#include "pub_core_signals.h"
njn2025cf92005-06-26 20:44:48 +000062#include "pub_core_stacks.h" // For VG_(register_stack)
njnc1b01812005-06-17 22:19:06 +000063#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +000064#include "pub_core_tooliface.h"
sewardj17c11042006-10-15 01:26:40 +000065#include "pub_core_translate.h" // For VG_(translate)
njna7598f62005-06-18 03:27:58 +000066#include "pub_core_trampoline.h"
njn8bddf582005-05-13 23:40:55 +000067#include "pub_core_transtab.h"
philippe14711e82012-06-14 22:18:50 +000068#include "pub_tool_inner.h"
69#if defined(ENABLE_INNER_CLIENT_REQUEST)
70#include "valgrind.h"
71#endif
sewardj17c11042006-10-15 01:26:40 +000072
sewardjb5f6f512005-03-10 23:59:00 +000073
nethercote71980f02004-01-24 18:18:54 +000074/*====================================================================*/
75/*=== Counters, for profiling purposes only ===*/
76/*====================================================================*/
sewardjde4a1d02002-03-22 01:27:54 +000077
nethercote3a42fb82004-08-03 18:08:50 +000078static void print_all_stats ( void )
nethercote71980f02004-01-24 18:18:54 +000079{
njn42c83552005-12-05 20:45:59 +000080 VG_(print_translation_stats)();
nethercote92e7b7f2004-08-07 17:52:25 +000081 VG_(print_tt_tc_stats)();
nethercote844e7122004-08-02 15:27:22 +000082 VG_(print_scheduler_stats)();
njn9271cbc2005-03-13 05:38:25 +000083 VG_(print_ExeContext_stats)();
sewardj12ab7652006-10-17 02:10:42 +000084 VG_(print_errormgr_stats)();
njn9271cbc2005-03-13 05:38:25 +000085
nethercote3a42fb82004-08-03 18:08:50 +000086 // Memory stats
nethercote885dd912004-08-03 23:14:00 +000087 if (VG_(clo_verbosity) > 2) {
sewardj738856f2009-07-15 14:48:32 +000088 VG_(message)(Vg_DebugMsg, "\n");
nethercote3a42fb82004-08-03 18:08:50 +000089 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +000090 "------ Valgrind's internal memory use stats follow ------\n" );
nethercote885dd912004-08-03 23:14:00 +000091 VG_(sanity_check_malloc_all)();
sewardj738856f2009-07-15 14:48:32 +000092 VG_(message)(Vg_DebugMsg, "------\n" );
nethercote3a42fb82004-08-03 18:08:50 +000093 VG_(print_all_arena_stats)();
sewardj738856f2009-07-15 14:48:32 +000094 VG_(message)(Vg_DebugMsg, "\n");
nethercote3a42fb82004-08-03 18:08:50 +000095 }
nethercote71980f02004-01-24 18:18:54 +000096}
97
98
99/*====================================================================*/
sewardj71bc3cb2005-05-19 00:25:45 +0000100/*=== Command-line: variables, processing, etc ===*/
101/*====================================================================*/
102
103// See pub_{core,tool}_options.h for explanations of all these.
104
sewardj45f4e7c2005-09-27 19:20:21 +0000105static void usage_NORETURN ( Bool debug_help )
njn7cf0bd32002-06-08 13:36:03 +0000106{
florian95a128b2011-09-29 14:26:38 +0000107 /* 'usage1' contains a %s
108 - for the name of the GDB executable
109 - for the name of vgdb's path prefix
110 which must be supplied when they are VG_(printf)'d. */
floriane543f302012-10-21 19:43:43 +0000111 const HChar usage1[] =
njn00cfcfc2005-11-12 18:53:50 +0000112"usage: valgrind [options] prog-and-args\n"
njn25e49d8e72002-09-23 09:36:25 +0000113"\n"
njn97db7612009-08-04 02:32:55 +0000114" tool-selection option, with default in [ ]:\n"
sewardjb5f6f512005-03-10 23:59:00 +0000115" --tool=<name> use the Valgrind tool named <name> [memcheck]\n"
njn97db7612009-08-04 02:32:55 +0000116"\n"
117" basic user options for all Valgrind tools, with defaults in [ ]:\n"
nethercotea76368b2004-06-16 11:56:29 +0000118" -h --help show this message\n"
nethercote6c999f22004-01-31 22:55:15 +0000119" --help-debug show this message, plus debugging options\n"
njn25e49d8e72002-09-23 09:36:25 +0000120" --version show version\n"
njn25e49d8e72002-09-23 09:36:25 +0000121" -q --quiet run silently; only print error msgs\n"
sewardj2d9e8742009-08-07 15:46:56 +0000122" -v --verbose be more verbose -- show misc extra info\n"
sewardj6e31f802007-11-17 22:29:25 +0000123" --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]\n"
sewardj06421272009-11-05 08:55:13 +0000124" --trace-children-skip=patt1,patt2,... specifies a list of executables\n"
125" that --trace-children=yes should not trace into\n"
sewardj9ab64a42010-12-06 11:40:04 +0000126" --trace-children-skip-by-arg=patt1,patt2,... same as --trace-children-skip=\n"
127" but check the argv[] entries for children, rather\n"
128" than the exe name, to make a follow/no-follow decision\n"
njn97db7612009-08-04 02:32:55 +0000129" --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n"
sewardj3b290482011-05-06 21:02:55 +0000130" --vgdb=no|yes|full activate gdbserver? [yes]\n"
131" full is slower but provides precise watchpoint/step\n"
sewardj1568e172011-06-18 08:28:04 +0000132" --vgdb-error=<number> invoke gdbserver after <number> errors [%d]\n"
133" to get started quickly, use --vgdb-error=0\n"
134" and follow the on-screen directions\n"
nethercote0d588502004-06-21 13:27:11 +0000135" --track-fds=no|yes track open file descriptors? [no]\n"
thughes6233a382004-08-21 11:10:44 +0000136" --time-stamp=no|yes add timestamps to log messages? [no]\n"
njnce545552005-07-25 22:36:52 +0000137" --log-fd=<number> log messages to file descriptor [2=stderr]\n"
njn374a36d2007-11-23 01:41:32 +0000138" --log-file=<file> log messages to <file>\n"
njnce545552005-07-25 22:36:52 +0000139" --log-socket=ipaddr:port log messages to socket ipaddr:port\n"
nethercote2b0793f2003-12-02 10:41:18 +0000140"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000141" user options for Valgrind tools that report errors:\n"
sewardj738856f2009-07-15 14:48:32 +0000142" --xml=yes emit error output in XML (some tools only)\n"
143" --xml-fd=<number> XML output to file descriptor\n"
144" --xml-file=<file> XML output to <file>\n"
145" --xml-socket=ipaddr:port XML output to socket ipaddr:port\n"
146" --xml-user-comment=STR copy STR verbatim into XML output\n"
nethercote2b0793f2003-12-02 10:41:18 +0000147" --demangle=no|yes automatically demangle C++ names? [yes]\n"
njn20b4a152005-10-19 22:39:40 +0000148" --num-callers=<number> show <number> callers in stack traces [12]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000149" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
sewardjb9779082006-05-12 23:50:15 +0000150" --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000151" --show-below-main=no|yes continue stack traces below main() [no]\n"
152" --suppressions=<filename> suppress errors described in <filename>\n"
sewardjd153fae2005-01-10 17:24:47 +0000153" --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000154" --db-attach=no|yes start debugger when errors detected? [no]\n"
sewardj7839d112007-11-20 19:45:03 +0000155" --db-command=<command> command to start debugger [%s -nw %%f %%p]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000156" --input-fd=<number> file descriptor for input [0=stdin]\n"
njn97db7612009-08-04 02:32:55 +0000157" --dsymutil=no|yes run dsymutil on Mac OS X when helpful? [no]\n"
sewardj97724e52005-04-02 23:40:59 +0000158" --max-stackframe=<number> assume stack switch for SP changes larger\n"
159" than <number> bytes [2000000]\n"
sewardj95d86c02007-12-18 01:49:23 +0000160" --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
161" [use current 'ulimit' value]\n"
njn97db7612009-08-04 02:32:55 +0000162"\n"
163" user options for Valgrind tools that replace malloc:\n"
philipped99c26a2012-07-31 22:17:28 +0000164" --alignment=<number> set minimum alignment of heap allocations [%s]\n"
165" --redzone-size=<number> set minimum size of redzones added before/after\n"
166" heap blocks (in bytes). [%s]\n"
njn97db7612009-08-04 02:32:55 +0000167"\n"
168" uncommon user options for all Valgrind tools:\n"
sewardj14cdbf82010-10-12 00:44:05 +0000169" --fullpath-after= (with nothing after the '=')\n"
170" show full source paths in call stacks\n"
171" --fullpath-after=string like --fullpath-after=, but only show the\n"
172" part of the path after 'string'. Allows removal\n"
173" of path prefixes. Use this flag multiple times\n"
174" to specify a set of prefixes to remove.\n"
sewardj8b6573d2012-12-05 22:15:14 +0000175" --extra-debuginfo-path=path absolute path to search for additional\n"
176" debug symbols, in addition to existing default\n"
177" well known search paths.\n"
sewardj6dbcc632011-06-07 21:39:28 +0000178" --smc-check=none|stack|all|all-non-file [stack]\n"
179" checks for self-modifying code: none, only for\n"
180" code found in stacks, for all code, or for all\n"
181" code except that from file-backed mappings\n"
njn97db7612009-08-04 02:32:55 +0000182" --read-var-info=yes|no read debug info on stack and global variables\n"
183" and use it to print better error messages in\n"
184" tools that make use of it (Memcheck, Helgrind,\n"
bartf6122a02010-03-27 07:38:39 +0000185" DRD) [no]\n"
sewardj3b290482011-05-06 21:02:55 +0000186" --vgdb-poll=<number> gdbserver poll max every <number> basic blocks [%d] \n"
187" --vgdb-shadow-registers=no|yes let gdb see the shadow registers [no]\n"
188" --vgdb-prefix=<prefix> prefix for vgdb FIFOs [%s]\n"
njn97db7612009-08-04 02:32:55 +0000189" --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
190" --sim-hints=hint1,hint2,... known hints:\n"
sewardjcc3de2d2011-08-18 15:08:20 +0000191" lax-ioctls, enable-outer, fuse-compatible [none]\n"
bart78bfc712011-12-08 16:14:59 +0000192" --fair-sched=no|yes|try schedule threads fairly on multicore systems [no]\n"
njn97db7612009-08-04 02:32:55 +0000193" --kernel-variant=variant1,variant2,... known variants: bproc [none]\n"
194" handle non-standard kernel variants\n"
195" --show-emwarns=no|yes show warnings about emulation limits? [no]\n"
sewardjf9ebc392010-05-09 22:30:43 +0000196" --require-text-symbol=:sonamepattern:symbolpattern abort run if the\n"
197" stated shared object doesn't have the stated\n"
198" text symbol. Patterns can contain ? and *.\n"
philippe1e470b52012-05-11 19:33:46 +0000199" --soname-synonyms=syn1=pattern1,syn2=pattern2,... synonym soname\n"
sewardj260c6482012-08-07 14:46:34 +0000200" specify patterns for function wrapping or replacement.\n"
201" To use a non-libc malloc library that is\n"
202" in the main exe: --soname-synonyms=somalloc=NONE\n"
203" in libxyzzy.so: --soname-synonyms=somalloc=libxyzzy.so\n"
sewardjc30cd9b2012-12-06 18:08:54 +0000204" --sigill-diagnostics=yes|no warn about illegal instructions? [yes]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000205"\n";
njn7cf0bd32002-06-08 13:36:03 +0000206
floriane543f302012-10-21 19:43:43 +0000207 const HChar usage2[] =
njn25e49d8e72002-09-23 09:36:25 +0000208"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000209" debugging options for all Valgrind tools:\n"
njn97db7612009-08-04 02:32:55 +0000210" -d show verbose debugging output\n"
njnb1cc5d62010-07-06 04:05:23 +0000211" --stats=no|yes show tool and core statistics [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000212" --sanity-level=<number> level of sanity checking to do [1]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000213" --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
214" --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
sewardj33afdb52006-01-17 02:36:40 +0000215" --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
florian29e022d2012-07-02 21:13:34 +0000216" --trace-notabove=<number> only show BBs below <number> [0]\n"
njn25e49d8e72002-09-23 09:36:25 +0000217" --trace-syscalls=no|yes show all system calls? [no]\n"
218" --trace-signals=no|yes show signal handling details? [no]\n"
219" --trace-symtab=no|yes show symbol table details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000220" --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
sewardjce058b02005-05-01 08:55:38 +0000221" --trace-cfi=no|yes show call-frame-info details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000222" --debug-dump=syms mimic /usr/bin/readelf --syms\n"
223" --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
224" --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
sewardj0ec07f32006-01-12 12:32:32 +0000225" --trace-redir=no|yes show redirection details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000226" --trace-sched=no|yes show thread scheduler details? [no]\n"
sewardj9c606bd2008-09-18 18:12:50 +0000227" --profile-heap=no|yes profile Valgrind's own space use\n"
philippe06444372012-10-12 21:46:55 +0000228" --core-redzone-size=<number> set minimum size of redzones added before/after\n"
philipped99c26a2012-07-31 22:17:28 +0000229" heap blocks allocated for Valgrind internal use (in bytes) [4]\n"
jsgf855d93d2003-10-13 22:26:55 +0000230" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
sewardj17c11042006-10-15 01:26:40 +0000231" --sym-offsets=yes|no show syms in form 'name+offset' ? [no]\n"
sewardjb5f6f512005-03-10 23:59:00 +0000232" --command-line-only=no|yes only use command line options [no]\n"
njn613812e2005-03-11 04:57:30 +0000233"\n"
njn97db7612009-08-04 02:32:55 +0000234" Vex options for all Valgrind tools:\n"
235" --vex-iropt-verbosity=<0..9> [0]\n"
236" --vex-iropt-level=<0..2> [2]\n"
philippe5b240c22012-08-14 22:28:31 +0000237" --vex-iropt-register-updates=sp-at-mem-access\n"
238" |unwindregs-at-mem-access\n"
philippe0c0291a2012-08-01 22:03:12 +0000239" |allregs-at-mem-access\n"
240" |allregs-at-each-insn [unwindregs-at-mem-access]\n"
njn97db7612009-08-04 02:32:55 +0000241" --vex-iropt-unroll-thresh=<0..400> [120]\n"
242" --vex-guest-max-insns=<1..100> [50]\n"
243" --vex-guest-chase-thresh=<0..99> [10]\n"
sewardj540cc4a2010-01-15 10:57:57 +0000244" --vex-guest-chase-cond=no|yes [no]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000245" --trace-flags and --profile-flags values (omit the middle space):\n"
sewardj2a99cf62004-11-24 10:44:19 +0000246" 1000 0000 show conversion into IR\n"
247" 0100 0000 show after initial opt\n"
248" 0010 0000 show after instrumentation\n"
249" 0001 0000 show after second opt\n"
250" 0000 1000 show after tree building\n"
251" 0000 0100 show selecting insns\n"
252" 0000 0010 show after reg-alloc\n"
253" 0000 0001 show final assembly\n"
florian29e022d2012-07-02 21:13:34 +0000254" (Nb: you need --trace-notbelow and/or --trace-notabove with --trace-flags for full details)\n"
sewardj2a99cf62004-11-24 10:44:19 +0000255"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000256" debugging options for Valgrind tools that report errors\n"
257" --dump-error=<number> show translation for basic block associated\n"
258" with <number>'th error context [0=show none]\n"
njn97db7612009-08-04 02:32:55 +0000259"\n"
260" debugging options for Valgrind tools that replace malloc:\n"
261" --trace-malloc=no|yes show client malloc details? [no]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000262"\n";
njn3e884182003-04-15 13:03:23 +0000263
floriane543f302012-10-21 19:43:43 +0000264 const HChar usage3[] =
njn3e884182003-04-15 13:03:23 +0000265"\n"
nethercote71980f02004-01-24 18:18:54 +0000266" Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
njn25e49d8e72002-09-23 09:36:25 +0000267"\n"
njn10b9aea2009-07-14 06:55:05 +0000268" %s is %s\n"
sewardj03f8d3f2012-08-05 15:46:46 +0000269" Valgrind is Copyright (C) 2000-2012, and GNU GPL'd, by Julian Seward et al.\n"
270" LibVEX is Copyright (C) 2004-2012, and GNU GPL'd, by OpenWorks LLP et al.\n"
njnd04b7c62002-10-03 14:05:52 +0000271"\n"
njn10b9aea2009-07-14 06:55:05 +0000272" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
njn25e49d8e72002-09-23 09:36:25 +0000273"\n";
njn7cf0bd32002-06-08 13:36:03 +0000274
floriane6a4ed12012-10-21 02:30:18 +0000275 const HChar* gdb_path = GDB_PATH;
florian19f91bb2012-11-10 22:29:54 +0000276 HChar default_alignment[30];
277 HChar default_redzone_size[30];
sewardj12373b12007-11-20 21:38:14 +0000278
njnbe9b47b2005-05-15 16:22:58 +0000279 // Ensure the message goes to stdout
sewardj738856f2009-07-15 14:48:32 +0000280 VG_(log_output_sink).fd = 1;
281 VG_(log_output_sink).is_socket = False;
njnbe9b47b2005-05-15 16:22:58 +0000282
philipped99c26a2012-07-31 22:17:28 +0000283 if (VG_(needs).malloc_replacement) {
284 VG_(sprintf)(default_alignment, "%d", VG_MIN_MALLOC_SZB);
285 VG_(sprintf)(default_redzone_size, "%lu", VG_(tdict).tool_client_redzone_szB);
286 } else {
287 VG_(strcpy)(default_alignment, "not used by this tool");
288 VG_(strcpy)(default_redzone_size, "not used by this tool");
289 }
290 /* 'usage1' a type as described after each arg. */
sewardj3b290482011-05-06 21:02:55 +0000291 VG_(printf)(usage1,
philipped99c26a2012-07-31 22:17:28 +0000292 VG_(clo_vgdb_error) /* int */,
293 gdb_path /* char* */,
294 default_alignment /* char* */,
295 default_redzone_size /* char* */,
296 VG_(clo_vgdb_poll) /* int */,
297 VG_(vgdb_prefix_default)() /* char* */
298 );
fitzhardinge98abfc72003-12-16 02:05:15 +0000299 if (VG_(details).name) {
300 VG_(printf)(" user options for %s:\n", VG_(details).name);
fitzhardinge98abfc72003-12-16 02:05:15 +0000301 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000302 VG_TDICT_CALL(tool_print_usage);
fitzhardinge98abfc72003-12-16 02:05:15 +0000303 else
304 VG_(printf)(" (none)\n");
305 }
nethercote6c999f22004-01-31 22:55:15 +0000306 if (debug_help) {
sewardjbbaef872008-11-01 23:55:32 +0000307 VG_(printf)("%s", usage2);
fitzhardinge98abfc72003-12-16 02:05:15 +0000308
nethercote6c999f22004-01-31 22:55:15 +0000309 if (VG_(details).name) {
310 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
311
312 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000313 VG_TDICT_CALL(tool_print_debug_usage);
nethercote6c999f22004-01-31 22:55:15 +0000314 else
315 VG_(printf)(" (none)\n");
316 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000317 }
njn10b9aea2009-07-14 06:55:05 +0000318 VG_(printf)(usage3, VG_(details).name, VG_(details).copyright_author,
319 VG_BUGS_TO);
nethercotef4928da2004-06-15 10:54:40 +0000320 VG_(exit)(0);
njn7cf0bd32002-06-08 13:36:03 +0000321}
sewardjde4a1d02002-03-22 01:27:54 +0000322
sewardjde4a1d02002-03-22 01:27:54 +0000323
sewardj95d86c02007-12-18 01:49:23 +0000324/* Peer at previously set up VG_(args_for_valgrind) and do some
325 minimal command line processing that must happen early on:
sewardj45f4e7c2005-09-27 19:20:21 +0000326
sewardj95d86c02007-12-18 01:49:23 +0000327 - show the version string, if requested (-v)
328 - extract any request for help (--help, -h, --help-debug)
329 - get the toolname (--tool=)
330 - set VG_(clo_max_stackframe) (--max-stackframe=)
331 - set VG_(clo_main_stacksize) (--main-stacksize=)
philippe72faf102012-03-11 22:24:03 +0000332 - set VG_(clo_sim_hints) (--sim-hints=)
sewardj95d86c02007-12-18 01:49:23 +0000333
334 That's all it does. The main command line processing is done below
335 by main_process_cmd_line_options. Note that
336 main_process_cmd_line_options has to handle but ignore the ones we
337 have handled here.
338*/
339static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
florian19f91bb2012-11-10 22:29:54 +0000340 /*OUT*/const HChar** tool )
sewardj45f4e7c2005-09-27 19:20:21 +0000341{
342 UInt i;
343 HChar* str;
sewardj8b635a42004-11-22 19:01:47 +0000344
sewardj14c7cc52007-02-25 15:08:24 +0000345 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000346
sewardj14c7cc52007-02-25 15:08:24 +0000347 /* parse the options we have (only the options we care about now) */
348 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
349
350 str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000351 vg_assert(str);
nethercote71980f02004-01-24 18:18:54 +0000352
njn83df0b62009-02-25 01:01:05 +0000353 // Nb: the version string goes to stdout.
sewardj738856f2009-07-15 14:48:32 +0000354 if VG_XACT_CLO(str, "--version", VG_(log_output_sink).fd, 1) {
355 VG_(log_output_sink).is_socket = False;
sewardj45f4e7c2005-09-27 19:20:21 +0000356 VG_(printf)("valgrind-" VERSION "\n");
357 VG_(exit)(0);
njn83df0b62009-02-25 01:01:05 +0000358 }
njncce38e62010-07-06 04:25:12 +0000359 else if VG_XACT_CLO(str, "--help", *need_help, *need_help+1) {}
360 else if VG_XACT_CLO(str, "-h", *need_help, *need_help+1) {}
sewardj45f4e7c2005-09-27 19:20:21 +0000361
njncce38e62010-07-06 04:25:12 +0000362 else if VG_XACT_CLO(str, "--help-debug", *need_help, *need_help+2) {}
nethercote71980f02004-01-24 18:18:54 +0000363
sewardj45f4e7c2005-09-27 19:20:21 +0000364 // The tool has already been determined, but we need to know the name
365 // here.
njn83df0b62009-02-25 01:01:05 +0000366 else if VG_STR_CLO(str, "--tool", *tool) {}
sewardj5bdfbd22007-12-15 22:13:05 +0000367
sewardj95d86c02007-12-18 01:49:23 +0000368 // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
369 // These are needed by VG_(ii_create_image), which happens
370 // before main_process_cmd_line_options().
njn83df0b62009-02-25 01:01:05 +0000371 else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
372 else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
philippe72faf102012-03-11 22:24:03 +0000373
374 // Set up VG_(clo_sim_hints). This is needed a.o. for an inner
375 // running in an outer, to have "no-inner-prefix" enabled
376 // as early as possible.
377 else if VG_STR_CLO (str, "--sim-hints", VG_(clo_sim_hints)) {}
nethercote71980f02004-01-24 18:18:54 +0000378 }
nethercote71980f02004-01-24 18:18:54 +0000379}
380
sewardj95d86c02007-12-18 01:49:23 +0000381/* The main processing for command line options. See comments above
sewardj738856f2009-07-15 14:48:32 +0000382 on early_process_cmd_line_options.
383
384 Comments on how the logging options are handled:
385
386 User can specify:
387 --log-fd= for a fd to write to (default setting, fd = 2)
388 --log-file= for a file name to write to
389 --log-socket= for a socket to write to
390
391 As a result of examining these and doing relevant socket/file
392 opening, a final fd is established. This is stored in
393 VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
394 specified, then STR, after expansion of %p and %q templates within
395 it, is stored in VG_(clo_log_fname_expanded), in m_options, just in
396 case anybody wants to know what it is.
397
398 When printing, VG_(log_output_sink) is consulted to find the
399 fd to send output to.
400
401 Exactly analogous actions are undertaken for the XML output
402 channel, with the one difference that the default fd is -1, meaning
403 the channel is disabled by default.
sewardj95d86c02007-12-18 01:49:23 +0000404*/
sewardj738856f2009-07-15 14:48:32 +0000405static
406void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
florian19f91bb2012-11-10 22:29:54 +0000407 /*OUT*/HChar** xml_fname_unexpanded,
sewardj738856f2009-07-15 14:48:32 +0000408 const HChar* toolname )
nethercote71980f02004-01-24 18:18:54 +0000409{
njnda033f52005-12-19 21:27:58 +0000410 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
411 // and we cannot change it until we know what we are changing it to is
412 // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
sewardj92645592005-07-23 09:18:34 +0000413 SysRes sres;
sewardj738856f2009-07-15 14:48:32 +0000414 Int i, tmp_log_fd, tmp_xml_fd;
sewardj92645592005-07-23 09:18:34 +0000415 Int toolname_len = VG_(strlen)(toolname);
florian19f91bb2012-11-10 22:29:54 +0000416 const HChar* tmp_str; // Used in a couple of places.
njnbe9b47b2005-05-15 16:22:58 +0000417 enum {
418 VgLogTo_Fd,
419 VgLogTo_File,
njnbe9b47b2005-05-15 16:22:58 +0000420 VgLogTo_Socket
sewardj738856f2009-07-15 14:48:32 +0000421 } log_to = VgLogTo_Fd, // Where is logging output to be sent?
422 xml_to = VgLogTo_Fd; // Where is XML output to be sent?
sewardjde4a1d02002-03-22 01:27:54 +0000423
sewardj738856f2009-07-15 14:48:32 +0000424 /* Temporarily holds the string STR specified with
425 --{log,xml}-{name,socket}=STR. 'fs' stands for
426 file-or-socket. */
florian19f91bb2012-11-10 22:29:54 +0000427 const HChar* log_fsname_unexpanded = NULL;
428 const HChar* xml_fsname_unexpanded = NULL;
sewardj738856f2009-07-15 14:48:32 +0000429
sewardjc30cd9b2012-12-06 18:08:54 +0000430 /* Whether the user has explicitly provided --sigill-diagnostics.
431 If not explicitly given depends on general verbosity setting. */
432 Bool sigill_diag_set = False;
433
sewardj738856f2009-07-15 14:48:32 +0000434 /* Log to stderr by default, but usage message goes to stdout. XML
435 output is initially disabled. */
njnda033f52005-12-19 21:27:58 +0000436 tmp_log_fd = 2;
sewardj738856f2009-07-15 14:48:32 +0000437 tmp_xml_fd = -1;
438
sewardj19d81412002-06-03 01:10:40 +0000439 /* Check for sane path in ./configure --prefix=... */
fitzhardinge98abfc72003-12-16 02:05:15 +0000440 if (VG_LIBDIR[0] != '/')
sewardj17c11042006-10-15 01:26:40 +0000441 VG_(err_config_error)("Please use absolute paths in "
florian1763e812011-07-12 19:07:05 +0000442 "./configure --prefix=... or --libdir=...\n");
sewardj38170912002-05-10 21:07:22 +0000443
sewardj14c7cc52007-02-25 15:08:24 +0000444 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000445
sewardj738856f2009-07-15 14:48:32 +0000446 /* BEGIN command-line processing loop */
447
sewardj14c7cc52007-02-25 15:08:24 +0000448 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
449
450 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000451 HChar* colon = arg;
nethercote71980f02004-01-24 18:18:54 +0000452
njn1274d242007-03-26 23:38:42 +0000453 // Look for a colon in the option name.
thughes3bfd5a02004-07-18 08:05:44 +0000454 while (*colon && *colon != ':' && *colon != '=')
455 colon++;
nethercote71980f02004-01-24 18:18:54 +0000456
njn1274d242007-03-26 23:38:42 +0000457 // Does it have the form "--toolname:foo"? We have to do it at the start
458 // in case someone has combined a prefix with a core-specific option,
459 // eg. "--memcheck:verbose".
thughes3bfd5a02004-07-18 08:05:44 +0000460 if (*colon == ':') {
njn83df0b62009-02-25 01:01:05 +0000461 if (VG_STREQN(2, arg, "--") &&
462 VG_STREQN(toolname_len, arg+2, toolname) &&
463 VG_STREQN(1, arg+2+toolname_len, ":"))
nethercote71980f02004-01-24 18:18:54 +0000464 {
njn1274d242007-03-26 23:38:42 +0000465 // Prefix matches, convert "--toolname:foo" to "--foo".
466 // Two things to note:
467 // - We cannot modify the option in-place. If we did, and then
468 // a child was spawned with --trace-children=yes, the
469 // now-non-prefixed option would be passed and could screw up
470 // the child.
471 // - We create copies, and never free them. Why? Non-prefixed
472 // options hang around forever, so tools need not make copies
473 // of strings within them. We need to have the same behaviour
474 // for prefixed options. The pointer to the copy will be lost
475 // once we leave this function (although a tool may keep a
476 // pointer into it), but the space wasted is insignificant.
477 // (In bug #142197, the copies were being freed, which caused
478 // problems for tools that reasonably assumed that arguments
479 // wouldn't disappear on them.)
nethercote71980f02004-01-24 18:18:54 +0000480 if (0)
481 VG_(printf)("tool-specific arg: %s\n", arg);
sewardj9c606bd2008-09-18 18:12:50 +0000482 arg = VG_(strdup)("main.mpclo.1", arg + toolname_len + 1);
nethercote71980f02004-01-24 18:18:54 +0000483 arg[0] = '-';
484 arg[1] = '-';
485
486 } else {
487 // prefix doesn't match, skip to next arg
488 continue;
489 }
490 }
491
fitzhardinge98abfc72003-12-16 02:05:15 +0000492 /* Ignore these options - they've already been handled */
njn83df0b62009-02-25 01:01:05 +0000493 if VG_STREQN( 7, arg, "--tool=") {}
494 else if VG_STREQN(20, arg, "--command-line-only=") {}
495 else if VG_STREQ( arg, "--") {}
496 else if VG_STREQ( arg, "-d") {}
philippe06444372012-10-12 21:46:55 +0000497 else if VG_STREQN(17, arg, "--max-stackframe=") {}
498 else if VG_STREQN(17, arg, "--main-stacksize=") {}
499 else if VG_STREQN(12, arg, "--sim-hints=") {}
500 else if VG_STREQN(15, arg, "--profile-heap=") {}
501 else if VG_STREQN(20, arg, "--core-redzone-size=") {}
502 else if VG_STREQN(15, arg, "--redzone-size=") {}
nethercote27fec902004-06-16 21:26:32 +0000503
philippe0c0291a2012-08-01 22:03:12 +0000504 /* Obsolete options. Report an error and exit */
505 else if VG_STREQN(34, arg, "--vex-iropt-precise-memory-exns=no") {
506 VG_(fmsg_bad_option)
507 (arg,
508 "--vex-iropt-precise-memory-exns is obsolete\n"
509 "Use --vex-iropt-register-updates=unwindregs-at-mem-access instead\n");
510 }
511 else if VG_STREQN(35, arg, "--vex-iropt-precise-memory-exns=yes") {
512 VG_(fmsg_bad_option)
513 (arg,
514 "--vex-iropt-precise-memory-exns is obsolete\n"
515 "Use --vex-iropt-register-updates=allregs-at-mem-access instead\n"
516 " (or --vex-iropt-register-updates=allregs-at-each-insn)\n");
517 }
518
njn83df0b62009-02-25 01:01:05 +0000519 // These options are new.
520 else if (VG_STREQ(arg, "-v") ||
521 VG_STREQ(arg, "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000522 VG_(clo_verbosity)++;
nethercote27fec902004-06-16 21:26:32 +0000523
njn83df0b62009-02-25 01:01:05 +0000524 else if (VG_STREQ(arg, "-q") ||
525 VG_STREQ(arg, "--quiet"))
sewardjde4a1d02002-03-22 01:27:54 +0000526 VG_(clo_verbosity)--;
527
sewardjc30cd9b2012-12-06 18:08:54 +0000528 else if VG_BOOL_CLO(arg, "--sigill-diagnostics", VG_(clo_sigill_diag))
529 sigill_diag_set = True;
530
sewardj2d9e8742009-08-07 15:46:56 +0000531 else if VG_BOOL_CLO(arg, "--stats", VG_(clo_stats)) {}
bartdb4384e2011-10-11 18:49:35 +0000532 else if VG_BOOL_CLO(arg, "--xml", VG_(clo_xml))
533 VG_(debugLog_setXml)(VG_(clo_xml));
534
sewardj3b290482011-05-06 21:02:55 +0000535 else if VG_XACT_CLO(arg, "--vgdb=no", VG_(clo_vgdb), Vg_VgdbNo) {}
536 else if VG_XACT_CLO(arg, "--vgdb=yes", VG_(clo_vgdb), Vg_VgdbYes) {}
philippe0c0291a2012-08-01 22:03:12 +0000537 else if VG_XACT_CLO(arg, "--vgdb=full", VG_(clo_vgdb), Vg_VgdbFull) {
538 /* automatically updates register values at each insn
539 with --vgdb=full */
540 VG_(clo_vex_control).iropt_register_updates
541 = VexRegUpdAllregsAtEachInsn;
542 }
sewardj3b290482011-05-06 21:02:55 +0000543 else if VG_INT_CLO (arg, "--vgdb-poll", VG_(clo_vgdb_poll)) {}
544 else if VG_INT_CLO (arg, "--vgdb-error", VG_(clo_vgdb_error)) {}
545 else if VG_STR_CLO (arg, "--vgdb-prefix", VG_(clo_vgdb_prefix)) {}
546 else if VG_BOOL_CLO(arg, "--vgdb-shadow-registers",
547 VG_(clo_vgdb_shadow_registers)) {}
njn83df0b62009-02-25 01:01:05 +0000548 else if VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach)) {}
549 else if VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle)) {}
philippe1e470b52012-05-11 19:33:46 +0000550 else if VG_STR_CLO (arg, "--soname-synonyms",VG_(clo_soname_synonyms)) {}
njn83df0b62009-02-25 01:01:05 +0000551 else if VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit)) {}
552 else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
553 else if VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns)) {}
sewardj95d86c02007-12-18 01:49:23 +0000554
njn83df0b62009-02-25 01:01:05 +0000555 else if VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres)) {}
556 else if VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main)) {}
557 else if VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp)) {}
558 else if VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds)) {}
559 else if VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children)) {}
560 else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
561 VG_(clo_child_silent_after_fork)) {}
bart78bfc712011-12-08 16:14:59 +0000562 else if VG_STR_CLO(arg, "--fair-sched", tmp_str) {
563 if (VG_(strcmp)(tmp_str, "yes") == 0)
564 VG_(clo_fair_sched) = enable_fair_sched;
565 else if (VG_(strcmp)(tmp_str, "try") == 0)
566 VG_(clo_fair_sched) = try_fair_sched;
567 else if (VG_(strcmp)(tmp_str, "no") == 0)
568 VG_(clo_fair_sched) = disable_fair_sched;
569 else
570 VG_(fmsg_bad_option)(arg, "");
571
572 }
njn83df0b62009-02-25 01:01:05 +0000573 else if VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched)) {}
574 else if VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals)) {}
575 else if VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab)) {}
576 else if VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt)) {}
577 else if VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi)) {}
578 else if VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms),
579 True) {}
580 else if VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line),
581 True) {}
582 else if VG_XACT_CLO(arg, "--debug-dump=frames",
583 VG_(clo_debug_dump_frames), True) {}
584 else if VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir)) {}
sewardj95d86c02007-12-18 01:49:23 +0000585
njn83df0b62009-02-25 01:01:05 +0000586 else if VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls)) {}
587 else if VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb)) {}
588 else if VG_STR_CLO (arg, "--db-command", VG_(clo_db_command)) {}
njn83df0b62009-02-25 01:01:05 +0000589 else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
590 else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
sewardjf767d962007-02-12 17:47:14 +0000591
njn83df0b62009-02-25 01:01:05 +0000592 else if VG_INT_CLO (arg, "--dump-error", VG_(clo_dump_error)) {}
593 else if VG_INT_CLO (arg, "--input-fd", VG_(clo_input_fd)) {}
594 else if VG_INT_CLO (arg, "--sanity-level", VG_(clo_sanity_level)) {}
595 else if VG_BINT_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
596 VG_DEEPEST_BACKTRACE) {}
sewardjde4a1d02002-03-22 01:27:54 +0000597
njn83df0b62009-02-25 01:01:05 +0000598 else if VG_XACT_CLO(arg, "--smc-check=none", VG_(clo_smc_check),
599 Vg_SmcNone);
600 else if VG_XACT_CLO(arg, "--smc-check=stack", VG_(clo_smc_check),
601 Vg_SmcStack);
602 else if VG_XACT_CLO(arg, "--smc-check=all", VG_(clo_smc_check),
603 Vg_SmcAll);
sewardj6dbcc632011-06-07 21:39:28 +0000604 else if VG_XACT_CLO(arg, "--smc-check=all-non-file",
605 VG_(clo_smc_check),
606 Vg_SmcAllNonFile);
sewardjde4a1d02002-03-22 01:27:54 +0000607
njn97db7612009-08-04 02:32:55 +0000608 else if VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant)) {}
sewardj26412bd2005-07-07 10:05:05 +0000609
njn97db7612009-08-04 02:32:55 +0000610 else if VG_BOOL_CLO(arg, "--dsymutil", VG_(clo_dsymutil)) {}
njnf76d27a2009-05-28 01:53:07 +0000611
sewardj9ab64a42010-12-06 11:40:04 +0000612 else if VG_STR_CLO (arg, "--trace-children-skip",
613 VG_(clo_trace_children_skip)) {}
614 else if VG_STR_CLO (arg, "--trace-children-skip-by-arg",
615 VG_(clo_trace_children_skip_by_arg)) {}
sewardj06421272009-11-05 08:55:13 +0000616
njn83df0b62009-02-25 01:01:05 +0000617 else if VG_BINT_CLO(arg, "--vex-iropt-verbosity",
618 VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
619 else if VG_BINT_CLO(arg, "--vex-iropt-level",
620 VG_(clo_vex_control).iropt_level, 0, 2) {}
philippe0c0291a2012-08-01 22:03:12 +0000621 else if VG_XACT_CLO(arg,
philippe5b240c22012-08-14 22:28:31 +0000622 "--vex-iropt-register-updates=sp-at-mem-access",
623 VG_(clo_vex_control).iropt_register_updates,
624 VexRegUpdSpAtMemAccess);
625 else if VG_XACT_CLO(arg,
philippe0c0291a2012-08-01 22:03:12 +0000626 "--vex-iropt-register-updates=unwindregs-at-mem-access",
627 VG_(clo_vex_control).iropt_register_updates,
628 VexRegUpdUnwindregsAtMemAccess);
629 else if VG_XACT_CLO(arg,
630 "--vex-iropt-register-updates=allregs-at-mem-access",
631 VG_(clo_vex_control).iropt_register_updates,
632 VexRegUpdAllregsAtMemAccess);
633 else if VG_XACT_CLO(arg,
634 "--vex-iropt-register-updates=allregs-at-each-insn",
635 VG_(clo_vex_control).iropt_register_updates,
636 VexRegUpdAllregsAtEachInsn);
njn83df0b62009-02-25 01:01:05 +0000637 else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
638 VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
639 else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
640 VG_(clo_vex_control).guest_max_insns, 1, 100) {}
641 else if VG_BINT_CLO(arg, "--vex-guest-chase-thresh",
642 VG_(clo_vex_control).guest_chase_thresh, 0, 99) {}
sewardj540cc4a2010-01-15 10:57:57 +0000643 else if VG_BOOL_CLO(arg, "--vex-guest-chase-cond",
644 VG_(clo_vex_control).guest_chase_cond) {}
sewardj94c8eb42008-09-19 20:13:39 +0000645
njn83df0b62009-02-25 01:01:05 +0000646 else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
647 log_to = VgLogTo_Fd;
sewardj738856f2009-07-15 14:48:32 +0000648 log_fsname_unexpanded = NULL;
649 }
650 else if VG_INT_CLO(arg, "--xml-fd", tmp_xml_fd) {
651 xml_to = VgLogTo_Fd;
652 xml_fsname_unexpanded = NULL;
sewardj4cf05692002-10-27 20:28:29 +0000653 }
654
sewardj738856f2009-07-15 14:48:32 +0000655 else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000656 log_to = VgLogTo_File;
sewardj4cf05692002-10-27 20:28:29 +0000657 }
sewardj738856f2009-07-15 14:48:32 +0000658 else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) {
659 xml_to = VgLogTo_File;
660 }
661
662 else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000663 log_to = VgLogTo_Socket;
sewardj73cf3bc2002-11-03 03:20:15 +0000664 }
sewardj738856f2009-07-15 14:48:32 +0000665 else if VG_STR_CLO(arg, "--xml-socket", xml_fsname_unexpanded) {
666 xml_to = VgLogTo_Socket;
667 }
sewardj73cf3bc2002-11-03 03:20:15 +0000668
njn83df0b62009-02-25 01:01:05 +0000669 else if VG_STR_CLO(arg, "--xml-user-comment",
670 VG_(clo_xml_user_comment)) {}
sewardj768db0e2005-07-19 14:18:56 +0000671
njn83df0b62009-02-25 01:01:05 +0000672 else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
sewardjde4a1d02002-03-22 01:27:54 +0000673 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njnb1cc5d62010-07-06 04:05:23 +0000674 VG_(fmsg_bad_option)(arg,
675 "Too many suppression files specified.\n"
676 "Increase VG_CLO_MAX_SFILES and recompile.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000677 }
njn83df0b62009-02-25 01:01:05 +0000678 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = tmp_str;
sewardjde4a1d02002-03-22 01:27:54 +0000679 VG_(clo_n_suppressions)++;
680 }
sewardjde4a1d02002-03-22 01:27:54 +0000681
sewardj14cdbf82010-10-12 00:44:05 +0000682 else if VG_STR_CLO (arg, "--fullpath-after", tmp_str) {
683 if (VG_(clo_n_fullpath_after) >= VG_CLO_MAX_FULLPATH_AFTER) {
684 VG_(fmsg_bad_option)(arg,
685 "Too many --fullpath-after= specifications.\n"
686 "Increase VG_CLO_MAX_FULLPATH_AFTER and recompile.\n");
687 }
688 VG_(clo_fullpath_after)[VG_(clo_n_fullpath_after)] = tmp_str;
689 VG_(clo_n_fullpath_after)++;
690 }
691
sewardj8b6573d2012-12-05 22:15:14 +0000692 else if VG_STR_CLO (arg, "--extra-debuginfo-path",
693 VG_(clo_extra_debuginfo_path)) {}
694
sewardjf9ebc392010-05-09 22:30:43 +0000695 else if VG_STR_CLO(arg, "--require-text-symbol", tmp_str) {
696 if (VG_(clo_n_req_tsyms) >= VG_CLO_MAX_REQ_TSYMS) {
njnb1cc5d62010-07-06 04:05:23 +0000697 VG_(fmsg_bad_option)(arg,
698 "Too many --require-text-symbol= specifications.\n"
699 "Increase VG_CLO_MAX_REQ_TSYMS and recompile.\n");
sewardjf9ebc392010-05-09 22:30:43 +0000700 }
701 /* String needs to be of the form C?*C?*, where C is any
702 character, but is the same both times. Having it in this
703 form facilitates finding the boundary between the sopatt
704 and the fnpatt just by looking for the second occurrence
705 of C, without hardwiring any assumption about what C
706 is. */
florian19f91bb2012-11-10 22:29:54 +0000707 HChar patt[7];
sewardjf9ebc392010-05-09 22:30:43 +0000708 Bool ok = True;
709 ok = tmp_str && VG_(strlen)(tmp_str) > 0;
710 if (ok) {
711 patt[0] = patt[3] = tmp_str[0];
712 patt[1] = patt[4] = '?';
713 patt[2] = patt[5] = '*';
714 patt[6] = 0;
715 ok = VG_(string_match)(patt, tmp_str);
716 }
717 if (!ok) {
njnb1cc5d62010-07-06 04:05:23 +0000718 VG_(fmsg_bad_option)(arg,
719 "Invalid --require-text-symbol= specification.\n");
sewardjf9ebc392010-05-09 22:30:43 +0000720 }
721 VG_(clo_req_tsyms)[VG_(clo_n_req_tsyms)] = tmp_str;
722 VG_(clo_n_req_tsyms)++;
723 }
724
sewardjfa8ec112005-01-19 11:55:34 +0000725 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000726 else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
sewardjfa8ec112005-01-19 11:55:34 +0000727 Int j;
sewardjfa8ec112005-01-19 11:55:34 +0000728
njn83df0b62009-02-25 01:01:05 +0000729 if (8 != VG_(strlen)(tmp_str)) {
njnb1cc5d62010-07-06 04:05:23 +0000730 VG_(fmsg_bad_option)(arg,
731 "--trace-flags argument must have 8 digits\n");
sewardjfa8ec112005-01-19 11:55:34 +0000732 }
733 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000734 if ('0' == tmp_str[j]) { /* do nothing */ }
735 else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
sewardjfa8ec112005-01-19 11:55:34 +0000736 else {
njnb1cc5d62010-07-06 04:05:23 +0000737 VG_(fmsg_bad_option)(arg,
738 "--trace-flags argument can only contain 0s and 1s\n");
sewardjfa8ec112005-01-19 11:55:34 +0000739 }
740 }
741 }
742
743 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000744 else if VG_STR_CLO(arg, "--profile-flags", tmp_str) {
njn25e49d8e72002-09-23 09:36:25 +0000745 Int j;
njn25e49d8e72002-09-23 09:36:25 +0000746
njn83df0b62009-02-25 01:01:05 +0000747 if (8 != VG_(strlen)(tmp_str)) {
njnb1cc5d62010-07-06 04:05:23 +0000748 VG_(fmsg_bad_option)(arg,
749 "--profile-flags argument must have 8 digits\n");
njn25e49d8e72002-09-23 09:36:25 +0000750 }
sewardj8b635a42004-11-22 19:01:47 +0000751 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000752 if ('0' == tmp_str[j]) { /* do nothing */ }
753 else if ('1' == tmp_str[j]) VG_(clo_profile_flags) |= (1 << (7-j));
njn25e49d8e72002-09-23 09:36:25 +0000754 else {
njnb1cc5d62010-07-06 04:05:23 +0000755 VG_(fmsg_bad_option)(arg,
756 "--profile-flags argument can only contain 0s and 1s\n");
njn25e49d8e72002-09-23 09:36:25 +0000757 }
758 }
759 }
sewardjde4a1d02002-03-22 01:27:54 +0000760
njn83df0b62009-02-25 01:01:05 +0000761 else if VG_INT_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow)) {}
sewardjc771b292004-11-30 18:55:21 +0000762
florian29e022d2012-07-02 21:13:34 +0000763 else if VG_INT_CLO (arg, "--trace-notabove", VG_(clo_trace_notabove)) {}
764
njn83df0b62009-02-25 01:01:05 +0000765 else if VG_XACT_CLO(arg, "--gen-suppressions=no",
766 VG_(clo_gen_suppressions), 0) {}
767 else if VG_XACT_CLO(arg, "--gen-suppressions=yes",
768 VG_(clo_gen_suppressions), 1) {}
769 else if VG_XACT_CLO(arg, "--gen-suppressions=all",
770 VG_(clo_gen_suppressions), 2) {}
sewardjd153fae2005-01-10 17:24:47 +0000771
nethercote71980f02004-01-24 18:18:54 +0000772 else if ( ! VG_(needs).command_line_options
njn51d827b2005-05-09 01:02:08 +0000773 || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
njnb1cc5d62010-07-06 04:05:23 +0000774 VG_(fmsg_bad_option)(arg, "");
njn25e49d8e72002-09-23 09:36:25 +0000775 }
sewardjde4a1d02002-03-22 01:27:54 +0000776 }
777
sewardj738856f2009-07-15 14:48:32 +0000778 /* END command-line processing loop */
779
florianb985e2d2011-09-29 03:03:45 +0000780 /* Determine the path prefix for vgdb */
781 if (VG_(clo_vgdb_prefix) == NULL)
782 VG_(clo_vgdb_prefix) = VG_(vgdb_prefix_default)();
783
sewardj998d40d2004-12-06 14:24:52 +0000784 /* Make VEX control parameters sane */
785
786 if (VG_(clo_vex_control).guest_chase_thresh
787 >= VG_(clo_vex_control).guest_max_insns)
788 VG_(clo_vex_control).guest_chase_thresh
789 = VG_(clo_vex_control).guest_max_insns - 1;
790
791 if (VG_(clo_vex_control).guest_chase_thresh < 0)
792 VG_(clo_vex_control).guest_chase_thresh = 0;
793
794 /* Check various option values */
nethercote27fec902004-06-16 21:26:32 +0000795
njnf9ebf672003-05-12 21:41:30 +0000796 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +0000797 VG_(clo_verbosity) = 0;
798
sewardjc30cd9b2012-12-06 18:08:54 +0000799 if (!sigill_diag_set)
800 VG_(clo_sigill_diag) = (VG_(clo_verbosity) > 0);
801
florian29e022d2012-07-02 21:13:34 +0000802 if (VG_(clo_trace_notbelow) == -1) {
803 if (VG_(clo_trace_notabove) == -1) {
804 /* [] */
805 VG_(clo_trace_notbelow) = 2147483647;
806 VG_(clo_trace_notabove) = 0;
807 } else {
808 /* [0 .. notabove] */
809 VG_(clo_trace_notbelow) = 0;
810 }
811 } else {
812 if (VG_(clo_trace_notabove) == -1) {
813 /* [notbelow .. ] */
814 VG_(clo_trace_notabove) = 2147483647;
815 } else {
816 /* [notbelow .. notabove] */
817 }
818 }
819
sewardj3b290482011-05-06 21:02:55 +0000820 VG_(dyn_vgdb_error) = VG_(clo_vgdb_error);
821
njnbe9b47b2005-05-15 16:22:58 +0000822 if (VG_(clo_gen_suppressions) > 0 &&
823 !VG_(needs).core_errors && !VG_(needs).tool_errors) {
njnb1cc5d62010-07-06 04:05:23 +0000824 VG_(fmsg_bad_option)("--gen-suppressions=yes",
825 "Can't use --gen-suppressions= with %s\n"
826 "because it doesn't generate errors.\n", VG_(details).name);
njnbe9b47b2005-05-15 16:22:58 +0000827 }
828
sewardj738856f2009-07-15 14:48:32 +0000829 /* If XML output is requested, check that the tool actually
830 supports it. */
831 if (VG_(clo_xml) && !VG_(needs).xml_output) {
832 VG_(clo_xml) = False;
njnb1cc5d62010-07-06 04:05:23 +0000833 VG_(fmsg_bad_option)("--xml=yes",
sewardj738856f2009-07-15 14:48:32 +0000834 "%s does not support XML output.\n", VG_(details).name);
sewardj738856f2009-07-15 14:48:32 +0000835 /*NOTREACHED*/
836 }
837
838 vg_assert( VG_(clo_gen_suppressions) >= 0 );
839 vg_assert( VG_(clo_gen_suppressions) <= 2 );
840
sewardj71bc3cb2005-05-19 00:25:45 +0000841 /* If we've been asked to emit XML, mash around various other
842 options so as to constrain the output somewhat, and to remove
sewardj738856f2009-07-15 14:48:32 +0000843 any need for user input during the run.
844 */
sewardj71bc3cb2005-05-19 00:25:45 +0000845 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +0000846
847 /* We can't allow --gen-suppressions=yes, since that requires us
848 to print the error and then ask the user if she wants a
849 suppression for it, but in XML mode we won't print it until
850 we know whether we also need to print a suppression. Hence a
851 circular dependency. So disallow this.
852 (--gen-suppressions=all is still OK since we don't need any
853 user interaction in this case.) */
854 if (VG_(clo_gen_suppressions) == 1) {
njnb1cc5d62010-07-06 04:05:23 +0000855 VG_(fmsg_bad_option)(
856 "--xml=yes together with --gen-suppressions=yes",
857 "When --xml=yes is specified, --gen-suppressions=no\n"
858 "or --gen-suppressions=all is allowed, but not "
sewardj738856f2009-07-15 14:48:32 +0000859 "--gen-suppressions=yes.\n");
sewardj738856f2009-07-15 14:48:32 +0000860 }
861
862 /* We can't allow DB attaching (or we maybe could, but results
863 could be chaotic ..) since it requires user input. Hence
864 disallow. */
865 if (VG_(clo_db_attach)) {
njnb1cc5d62010-07-06 04:05:23 +0000866 VG_(fmsg_bad_option)(
867 "--xml=yes together with --db-attach=yes",
868 "--db-attach=yes is not allowed with --xml=yes\n"
869 "because it would require user input.\n");
sewardj738856f2009-07-15 14:48:32 +0000870 }
871
872 /* Disallow dump_error in XML mode; sounds like a recipe for
873 chaos. No big deal; dump_error is a flag for debugging V
874 itself. */
875 if (VG_(clo_dump_error) > 0) {
njnb1cc5d62010-07-06 04:05:23 +0000876 VG_(fmsg_bad_option)("--xml=yes together with --dump-error", "");
sewardj738856f2009-07-15 14:48:32 +0000877 }
878
sewardj71bc3cb2005-05-19 00:25:45 +0000879 /* Disable error limits (this might be a bad idea!) */
880 VG_(clo_error_limit) = False;
881 /* Disable emulation warnings */
sewardj738856f2009-07-15 14:48:32 +0000882
sewardj71bc3cb2005-05-19 00:25:45 +0000883 /* Also, we want to set options for the leak checker, but that
884 will have to be done in Memcheck's flag-handling code, not
885 here. */
886 }
887
njnbe9b47b2005-05-15 16:22:58 +0000888 /* All non-logging-related options have been checked. If the logging
889 option specified is ok, we can switch to it, as we know we won't
890 have to generate any other command-line-related error messages.
891 (So far we should be still attached to stderr, so we can show on
892 the terminal any problems to do with processing command line
893 opts.)
894
sewardj738856f2009-07-15 14:48:32 +0000895 So set up logging now. After this is done, VG_(log_output_sink)
896 and (if relevant) VG_(xml_output_sink) should be connected to
897 whatever sink has been selected, and we indiscriminately chuck
898 stuff into it without worrying what the nature of it is. Oh the
899 wonder of Unix streams. */
sewardj4cf05692002-10-27 20:28:29 +0000900
sewardj738856f2009-07-15 14:48:32 +0000901 vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
902 vg_assert(VG_(log_output_sink).is_socket == False);
903 vg_assert(VG_(clo_log_fname_expanded) == NULL);
904
905 vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
906 vg_assert(VG_(xml_output_sink).is_socket == False);
907 vg_assert(VG_(clo_xml_fname_expanded) == NULL);
908
909 /* --- set up the normal text output channel --- */
sewardj4cf05692002-10-27 20:28:29 +0000910
njnbe9b47b2005-05-15 16:22:58 +0000911 switch (log_to) {
sewardj73cf3bc2002-11-03 03:20:15 +0000912
sewardj4cf05692002-10-27 20:28:29 +0000913 case VgLogTo_Fd:
sewardj738856f2009-07-15 14:48:32 +0000914 vg_assert(log_fsname_unexpanded == NULL);
sewardj4cf05692002-10-27 20:28:29 +0000915 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000916
sewardj4cf05692002-10-27 20:28:29 +0000917 case VgLogTo_File: {
florian19f91bb2012-11-10 22:29:54 +0000918 HChar* logfilename;
jsgff3c3f1a2003-10-14 22:13:28 +0000919
sewardj738856f2009-07-15 14:48:32 +0000920 vg_assert(log_fsname_unexpanded != NULL);
921 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +0000922
njn374a36d2007-11-23 01:41:32 +0000923 // Nb: we overwrite an existing file of this name without asking
924 // any questions.
sewardj738856f2009-07-15 14:48:32 +0000925 logfilename = VG_(expand_file_name)("--log-file",
926 log_fsname_unexpanded);
njn374a36d2007-11-23 01:41:32 +0000927 sres = VG_(open)(logfilename,
njnda033f52005-12-19 21:27:58 +0000928 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
929 VKI_S_IRUSR|VKI_S_IWUSR);
njncda2f0f2009-05-18 02:12:08 +0000930 if (!sr_isError(sres)) {
931 tmp_log_fd = sr_Res(sres);
sewardj738856f2009-07-15 14:48:32 +0000932 VG_(clo_log_fname_expanded) = logfilename;
njnbe9b47b2005-05-15 16:22:58 +0000933 } else {
njnb1cc5d62010-07-06 04:05:23 +0000934 VG_(fmsg)("can't create log file '%s': %s\n",
935 logfilename, VG_(strerror)(sr_Err(sres)));
936 VG_(exit)(1);
sewardj603d4102005-01-11 14:01:02 +0000937 /*NOTREACHED*/
njn374a36d2007-11-23 01:41:32 +0000938 }
sewardj738856f2009-07-15 14:48:32 +0000939 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000940 }
941
942 case VgLogTo_Socket: {
sewardj738856f2009-07-15 14:48:32 +0000943 vg_assert(log_fsname_unexpanded != NULL);
944 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
945 tmp_log_fd = VG_(connect_via_socket)( log_fsname_unexpanded );
njnda033f52005-12-19 21:27:58 +0000946 if (tmp_log_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +0000947 VG_(fmsg)("Invalid --log-socket spec of '%s'\n",
948 log_fsname_unexpanded);
949 VG_(exit)(1);
njnbe9b47b2005-05-15 16:22:58 +0000950 /*NOTREACHED*/
sewardj4cf05692002-10-27 20:28:29 +0000951 }
njnda033f52005-12-19 21:27:58 +0000952 if (tmp_log_fd == -2) {
njnb1cc5d62010-07-06 04:05:23 +0000953 VG_(umsg)("failed to connect to logging server '%s'.\n"
954 "Log messages will sent to stderr instead.\n",
955 log_fsname_unexpanded );
956
sewardj570f8902002-11-03 11:44:36 +0000957 /* We don't change anything here. */
sewardj738856f2009-07-15 14:48:32 +0000958 vg_assert(VG_(log_output_sink).fd == 2);
njnda033f52005-12-19 21:27:58 +0000959 tmp_log_fd = 2;
sewardj570f8902002-11-03 11:44:36 +0000960 } else {
njnda033f52005-12-19 21:27:58 +0000961 vg_assert(tmp_log_fd > 0);
sewardj738856f2009-07-15 14:48:32 +0000962 VG_(log_output_sink).is_socket = True;
sewardj570f8902002-11-03 11:44:36 +0000963 }
sewardj73cf3bc2002-11-03 03:20:15 +0000964 break;
965 }
sewardj4cf05692002-10-27 20:28:29 +0000966 }
967
sewardj738856f2009-07-15 14:48:32 +0000968 /* --- set up the XML output channel --- */
sewardj71bc3cb2005-05-19 00:25:45 +0000969
sewardj738856f2009-07-15 14:48:32 +0000970 switch (xml_to) {
971
972 case VgLogTo_Fd:
973 vg_assert(xml_fsname_unexpanded == NULL);
974 break;
975
976 case VgLogTo_File: {
florian19f91bb2012-11-10 22:29:54 +0000977 HChar* xmlfilename;
sewardj738856f2009-07-15 14:48:32 +0000978
979 vg_assert(xml_fsname_unexpanded != NULL);
980 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
981
982 // Nb: we overwrite an existing file of this name without asking
983 // any questions.
984 xmlfilename = VG_(expand_file_name)("--xml-file",
985 xml_fsname_unexpanded);
986 sres = VG_(open)(xmlfilename,
987 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
988 VKI_S_IRUSR|VKI_S_IWUSR);
989 if (!sr_isError(sres)) {
990 tmp_xml_fd = sr_Res(sres);
991 VG_(clo_xml_fname_expanded) = xmlfilename;
992 /* strdup here is probably paranoid overkill, but ... */
993 *xml_fname_unexpanded = VG_(strdup)( "main.mpclo.2",
994 xml_fsname_unexpanded );
995 } else {
njnb1cc5d62010-07-06 04:05:23 +0000996 VG_(fmsg)("can't create XML file '%s': %s\n",
997 xmlfilename, VG_(strerror)(sr_Err(sres)));
998 VG_(exit)(1);
sewardj738856f2009-07-15 14:48:32 +0000999 /*NOTREACHED*/
1000 }
1001 break;
1002 }
1003
1004 case VgLogTo_Socket: {
1005 vg_assert(xml_fsname_unexpanded != NULL);
1006 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
1007 tmp_xml_fd = VG_(connect_via_socket)( xml_fsname_unexpanded );
1008 if (tmp_xml_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +00001009 VG_(fmsg)("Invalid --xml-socket spec of '%s'\n",
1010 xml_fsname_unexpanded );
1011 VG_(exit)(1);
sewardj738856f2009-07-15 14:48:32 +00001012 /*NOTREACHED*/
1013 }
1014 if (tmp_xml_fd == -2) {
njnb1cc5d62010-07-06 04:05:23 +00001015 VG_(umsg)("failed to connect to XML logging server '%s'.\n"
1016 "XML output will sent to stderr instead.\n",
1017 xml_fsname_unexpanded);
sewardj738856f2009-07-15 14:48:32 +00001018 /* We don't change anything here. */
1019 vg_assert(VG_(xml_output_sink).fd == 2);
1020 tmp_xml_fd = 2;
1021 } else {
1022 vg_assert(tmp_xml_fd > 0);
1023 VG_(xml_output_sink).is_socket = True;
1024 }
1025 break;
1026 }
sewardj71bc3cb2005-05-19 00:25:45 +00001027 }
1028
sewardj738856f2009-07-15 14:48:32 +00001029 /* If we've got this far, and XML mode was requested, but no XML
1030 output channel appears to have been specified, just stop. We
1031 could continue, and XML output will simply vanish into nowhere,
1032 but that is likely to confuse the hell out of users, which is
1033 distinctly Ungood. */
1034 if (VG_(clo_xml) && tmp_xml_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +00001035 VG_(fmsg_bad_option)(
1036 "--xml=yes, but no XML destination specified",
sewardj738856f2009-07-15 14:48:32 +00001037 "--xml=yes has been specified, but there is no XML output\n"
1038 "destination. You must specify an XML output destination\n"
njnb1cc5d62010-07-06 04:05:23 +00001039 "using --xml-fd, --xml-file or --xml-socket.\n"
1040 );
sewardj738856f2009-07-15 14:48:32 +00001041 }
1042
1043 // Finalise the output fds: the log fd ..
1044
njnda033f52005-12-19 21:27:58 +00001045 if (tmp_log_fd >= 0) {
sewardj738856f2009-07-15 14:48:32 +00001046 // Move log_fd into the safe range, so it doesn't conflict with
1047 // any app fds.
njnda033f52005-12-19 21:27:58 +00001048 tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
1049 if (tmp_log_fd < 0) {
sewardj738856f2009-07-15 14:48:32 +00001050 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd "
1051 "into safe range, using stderr\n");
1052 VG_(log_output_sink).fd = 2; // stderr
1053 VG_(log_output_sink).is_socket = False;
njnda033f52005-12-19 21:27:58 +00001054 } else {
sewardj738856f2009-07-15 14:48:32 +00001055 VG_(log_output_sink).fd = tmp_log_fd;
1056 VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
njnda033f52005-12-19 21:27:58 +00001057 }
1058 } else {
1059 // If they said --log-fd=-1, don't print anything. Plausible for use in
1060 // regression testing suites that use client requests to count errors.
sewardj738856f2009-07-15 14:48:32 +00001061 VG_(log_output_sink).fd = -1;
1062 VG_(log_output_sink).is_socket = False;
jsgf855d93d2003-10-13 22:26:55 +00001063 }
1064
sewardj738856f2009-07-15 14:48:32 +00001065 // Finalise the output fds: and the XML fd ..
1066
1067 if (tmp_xml_fd >= 0) {
1068 // Move xml_fd into the safe range, so it doesn't conflict with
1069 // any app fds.
1070 tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
1071 if (tmp_xml_fd < 0) {
1072 VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd "
1073 "into safe range, using stderr\n");
1074 VG_(xml_output_sink).fd = 2; // stderr
1075 VG_(xml_output_sink).is_socket = False;
1076 } else {
1077 VG_(xml_output_sink).fd = tmp_xml_fd;
1078 VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
1079 }
1080 } else {
1081 // If they said --xml-fd=-1, don't print anything. Plausible for use in
1082 // regression testing suites that use client requests to count errors.
1083 VG_(xml_output_sink).fd = -1;
1084 VG_(xml_output_sink).is_socket = False;
1085 }
1086
1087 // Suppressions related stuff
1088
sewardj45f4e7c2005-09-27 19:20:21 +00001089 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
1090 (VG_(needs).core_errors || VG_(needs).tool_errors)) {
1091 /* If we haven't reached the max number of suppressions, load
1092 the default one. */
floriane6a4ed12012-10-21 02:30:18 +00001093 static const HChar default_supp[] = "default.supp";
sewardj45f4e7c2005-09-27 19:20:21 +00001094 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
florian19f91bb2012-11-10 22:29:54 +00001095 HChar *buf = VG_(arena_malloc)(VG_AR_CORE, "main.mpclo.3", len);
sewardj45f4e7c2005-09-27 19:20:21 +00001096 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
1097 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
1098 VG_(clo_n_suppressions)++;
1099 }
sewardjde4a1d02002-03-22 01:27:54 +00001100
sewardj738856f2009-07-15 14:48:32 +00001101 *logging_to_fd = log_to == VgLogTo_Fd || log_to == VgLogTo_Socket;
sewardj45f4e7c2005-09-27 19:20:21 +00001102}
1103
sewardj4efbaa72008-06-04 06:51:58 +00001104// Write the name and value of log file qualifiers to the xml file.
florian19f91bb2012-11-10 22:29:54 +00001105static void print_file_vars(HChar* format)
sewardj4efbaa72008-06-04 06:51:58 +00001106{
1107 Int i = 0;
1108
1109 while (format[i]) {
1110 if (format[i] == '%') {
1111 // We saw a '%'. What's next...
1112 i++;
1113 if ('q' == format[i]) {
1114 i++;
1115 if ('{' == format[i]) {
1116 // Get the env var name, print its contents.
florian19f91bb2012-11-10 22:29:54 +00001117 HChar* qualname;
1118 HChar* qual;
sewardj4efbaa72008-06-04 06:51:58 +00001119 i++;
1120 qualname = &format[i];
1121 while (True) {
1122 if ('}' == format[i]) {
1123 // Temporarily replace the '}' with NUL to extract var
1124 // name.
1125 format[i] = 0;
1126 qual = VG_(getenv)(qualname);
1127 break;
1128 }
1129 i++;
1130 }
1131
bartb3af9cf2011-10-06 19:08:37 +00001132 VG_(printf_xml)(
1133 "<logfilequalifier> <var>%pS</var> "
1134 "<value>%pS</value> </logfilequalifier>\n",
sewardj7ca100d2009-08-15 23:05:34 +00001135 qualname,qual
1136 );
sewardj4efbaa72008-06-04 06:51:58 +00001137 format[i] = '}';
1138 i++;
1139 }
1140 }
1141 } else {
1142 i++;
1143 }
1144 }
1145}
1146
sewardj45f4e7c2005-09-27 19:20:21 +00001147
1148/*====================================================================*/
1149/*=== Printing the preamble ===*/
1150/*====================================================================*/
1151
barta92677a2011-10-22 08:24:32 +00001152// Print the argument, escaping any chars that require it.
florian19f91bb2012-11-10 22:29:54 +00001153static void umsg_arg(const HChar* arg)
njnf8a11cf2009-08-02 23:03:06 +00001154{
1155 SizeT len = VG_(strlen)(arg);
floriane6a4ed12012-10-21 02:30:18 +00001156 const HChar* special = " \\<>";
njnf8a11cf2009-08-02 23:03:06 +00001157 Int i;
1158 for (i = 0; i < len; i++) {
1159 if (VG_(strchr)(special, arg[i])) {
barta92677a2011-10-22 08:24:32 +00001160 VG_(umsg)("\\"); // escape with a backslash if necessary
njnf8a11cf2009-08-02 23:03:06 +00001161 }
barta92677a2011-10-22 08:24:32 +00001162 VG_(umsg)("%c", arg[i]);
njnf8a11cf2009-08-02 23:03:06 +00001163 }
1164}
1165
barta92677a2011-10-22 08:24:32 +00001166// Send output to the XML-stream and escape any XML meta-characters.
florian19f91bb2012-11-10 22:29:54 +00001167static void xml_arg(const HChar* arg)
barta92677a2011-10-22 08:24:32 +00001168{
1169 VG_(printf_xml)("%pS", arg);
1170}
1171
sewardj45f4e7c2005-09-27 19:20:21 +00001172/* Ok, the logging sink is running now. Print a suitable preamble.
1173 If logging to file or a socket, write details of parent PID and
1174 command line args, to help people trying to interpret the
1175 results of a run which encompasses multiple processes. */
sewardj738856f2009-07-15 14:48:32 +00001176static void print_preamble ( Bool logging_to_fd,
florian19f91bb2012-11-10 22:29:54 +00001177 HChar* xml_fname_unexpanded,
sewardj738856f2009-07-15 14:48:32 +00001178 const HChar* toolname )
sewardj45f4e7c2005-09-27 19:20:21 +00001179{
sewardj738856f2009-07-15 14:48:32 +00001180 Int i;
florian6bd9dc12012-11-23 16:17:43 +00001181 const HChar* xpre = VG_(clo_xml) ? " <line>" : "";
1182 const HChar* xpost = VG_(clo_xml) ? "</line>" : "";
sewardj738856f2009-07-15 14:48:32 +00001183 UInt (*umsg_or_xml)( const HChar*, ... )
1184 = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
tom60a4b0b2005-10-12 10:45:27 +00001185
florian19f91bb2012-11-10 22:29:54 +00001186 void (*umsg_or_xml_arg)( const HChar* )
barta92677a2011-10-22 08:24:32 +00001187 = VG_(clo_xml) ? xml_arg : umsg_arg;
1188
sewardj14c7cc52007-02-25 15:08:24 +00001189 vg_assert( VG_(args_for_client) );
1190 vg_assert( VG_(args_for_valgrind) );
sewardj99a2ceb2007-11-09 12:30:36 +00001191 vg_assert( toolname );
sewardj14c7cc52007-02-25 15:08:24 +00001192
sewardj71bc3cb2005-05-19 00:25:45 +00001193 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001194 VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
1195 VG_(printf_xml)("\n");
1196 VG_(printf_xml)("<valgrindoutput>\n");
1197 VG_(printf_xml)("\n");
1198 VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
1199 VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", toolname);
1200 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001201 }
1202
sewardj738856f2009-07-15 14:48:32 +00001203 if (VG_(clo_xml) || VG_(clo_verbosity > 0)) {
sewardjd7bddad2005-06-13 16:48:32 +00001204
1205 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001206 VG_(printf_xml)("<preamble>\n");
sewardjd7bddad2005-06-13 16:48:32 +00001207
nethercote996901a2004-08-03 13:29:09 +00001208 /* Tool details */
bartb3af9cf2011-10-06 19:08:37 +00001209 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 +00001210 xpre,
njnd04b7c62002-10-03 14:05:52 +00001211 VG_(details).name,
njnb9c427c2004-12-01 14:14:42 +00001212 NULL == VG_(details).version ? "" : "-",
njnd04b7c62002-10-03 14:05:52 +00001213 NULL == VG_(details).version
floriane6a4ed12012-10-21 02:30:18 +00001214 ? "" : VG_(details).version,
sewardj71bc3cb2005-05-19 00:25:45 +00001215 VG_(details).description,
sewardj738856f2009-07-15 14:48:32 +00001216 xpost );
sewardj99a2ceb2007-11-09 12:30:36 +00001217
njn10b9aea2009-07-14 06:55:05 +00001218 if (VG_(strlen)(toolname) >= 4 && VG_STREQN(4, toolname, "exp-")) {
sewardj738856f2009-07-15 14:48:32 +00001219 umsg_or_xml(
njnb6267bd2009-08-12 00:14:16 +00001220 "%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
sewardj99a2ceb2007-11-09 12:30:36 +00001221 xpre, xpost
1222 );
1223 }
1224
bartb3af9cf2011-10-06 19:08:37 +00001225 umsg_or_xml( VG_(clo_xml) ? "%s%pS%s\n" : "%s%s%s\n",
sewardj743a2082010-07-23 17:03:22 +00001226 xpre, VG_(details).copyright_author, xpost );
sewardj3b2736a2002-03-24 12:18:35 +00001227
njnd04b7c62002-10-03 14:05:52 +00001228 /* Core details */
sewardj738856f2009-07-15 14:48:32 +00001229 umsg_or_xml(
njnf73d87f2009-07-24 04:47:04 +00001230 "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
1231 xpre, VERSION, xpost
sewardj738856f2009-07-15 14:48:32 +00001232 );
sewardj45f4e7c2005-09-27 19:20:21 +00001233
njnf3977a32009-08-04 00:27:56 +00001234 // Print the command line. At one point we wrapped at 80 chars and
1235 // printed a '\' as a line joiner, but that makes it hard to cut and
1236 // paste the command line (because of the "==pid==" prefixes), so we now
1237 // favour utility and simplicity over aesthetics.
1238 umsg_or_xml("%sCommand: ", xpre);
njn53162bf2009-07-29 23:34:49 +00001239 if (VG_(args_the_exename))
barta92677a2011-10-22 08:24:32 +00001240 umsg_or_xml_arg(VG_(args_the_exename));
1241
njn53162bf2009-07-29 23:34:49 +00001242 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1243 HChar* s = *(HChar**)VG_(indexXA)( VG_(args_for_client), i );
njnf8a11cf2009-08-02 23:03:06 +00001244 umsg_or_xml(" ");
barta92677a2011-10-22 08:24:32 +00001245 umsg_or_xml_arg(s);
njn53162bf2009-07-29 23:34:49 +00001246 }
njnf3977a32009-08-04 00:27:56 +00001247 umsg_or_xml("%s\n", xpost);
njn53162bf2009-07-29 23:34:49 +00001248
sewardjd7bddad2005-06-13 16:48:32 +00001249 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001250 VG_(printf_xml)("</preamble>\n");
njnd04b7c62002-10-03 14:05:52 +00001251 }
1252
njnb6267bd2009-08-12 00:14:16 +00001253 // Print the parent PID, and other stuff, if necessary.
sewardj45f4e7c2005-09-27 19:20:21 +00001254 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
njn305dc002009-07-30 23:36:43 +00001255 VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
sewardj4cf05692002-10-27 20:28:29 +00001256 }
sewardj71bc3cb2005-05-19 00:25:45 +00001257 else
1258 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001259 VG_(printf_xml)("\n");
1260 VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
1261 VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
bartb3af9cf2011-10-06 19:08:37 +00001262 VG_(printf_xml)("<tool>%pS</tool>\n", toolname);
sewardj738856f2009-07-15 14:48:32 +00001263 if (xml_fname_unexpanded)
1264 print_file_vars(xml_fname_unexpanded);
sewardj768db0e2005-07-19 14:18:56 +00001265 if (VG_(clo_xml_user_comment)) {
1266 /* Note: the user comment itself is XML and is therefore to
1267 be passed through verbatim (%s) rather than escaped
bartb3af9cf2011-10-06 19:08:37 +00001268 (%pS). */
sewardj738856f2009-07-15 14:48:32 +00001269 VG_(printf_xml)("<usercomment>%s</usercomment>\n",
1270 VG_(clo_xml_user_comment));
sewardj768db0e2005-07-19 14:18:56 +00001271 }
sewardj738856f2009-07-15 14:48:32 +00001272 VG_(printf_xml)("\n");
1273 VG_(printf_xml)("<args>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001274
sewardj738856f2009-07-15 14:48:32 +00001275 VG_(printf_xml)(" <vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001276 if (VG_(name_of_launcher))
bartb3af9cf2011-10-06 19:08:37 +00001277 VG_(printf_xml)(" <exe>%pS</exe>\n",
sewardj738856f2009-07-15 14:48:32 +00001278 VG_(name_of_launcher));
sewardj125fd4f2007-03-08 19:56:14 +00001279 else
bartb3af9cf2011-10-06 19:08:37 +00001280 VG_(printf_xml)(" <exe>%pS</exe>\n",
njnb1cc5d62010-07-06 04:05:23 +00001281 "(launcher name unknown)");
sewardj14c7cc52007-02-25 15:08:24 +00001282 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
bartb3af9cf2011-10-06 19:08:37 +00001283 VG_(printf_xml)(
1284 " <arg>%pS</arg>\n",
sewardj738856f2009-07-15 14:48:32 +00001285 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1286 );
sewardjb8a3dac2005-07-19 12:39:11 +00001287 }
sewardj738856f2009-07-15 14:48:32 +00001288 VG_(printf_xml)(" </vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001289
sewardj738856f2009-07-15 14:48:32 +00001290 VG_(printf_xml)(" <argv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001291 if (VG_(args_the_exename))
bartb3af9cf2011-10-06 19:08:37 +00001292 VG_(printf_xml)(" <exe>%pS</exe>\n",
sewardj738856f2009-07-15 14:48:32 +00001293 VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001294 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
bartb3af9cf2011-10-06 19:08:37 +00001295 VG_(printf_xml)(
1296 " <arg>%pS</arg>\n",
sewardj738856f2009-07-15 14:48:32 +00001297 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1298 );
sewardj8665d8e2005-06-01 17:35:23 +00001299 }
sewardj738856f2009-07-15 14:48:32 +00001300 VG_(printf_xml)(" </argv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001301
sewardj738856f2009-07-15 14:48:32 +00001302 VG_(printf_xml)("</args>\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001303 }
sewardj4cf05692002-10-27 20:28:29 +00001304
njnb6267bd2009-08-12 00:14:16 +00001305 // Last thing in the preamble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00001306 if (VG_(clo_xml))
1307 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00001308 else if (VG_(clo_verbosity) > 0)
1309 VG_(umsg)("\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001310
sewardjae284e52012-08-02 18:25:04 +00001311# if defined(VGO_darwin) && DARWIN_VERS == DARWIN_10_8
1312 /* Uh, this doesn't play nice with XML output. */
1313 umsg_or_xml( "WARNING: Support on MacOS 10.8 is experimental and mostly broken.\n");
1314 umsg_or_xml( "WARNING: Expect incorrect results, assertions and crashes.\n");
1315 umsg_or_xml( "WARNING: In particular, Memcheck on 32-bit programs will fail to\n");
1316 umsg_or_xml( "WARNING: detect any errors associated with heap-allocated data.\n");
1317 umsg_or_xml( "\n" );
1318# endif
1319
sewardjde4a1d02002-03-22 01:27:54 +00001320 if (VG_(clo_verbosity) > 1) {
sewardj92645592005-07-23 09:18:34 +00001321 SysRes fd;
sewardj1f0bbc72005-11-16 03:51:02 +00001322 VexArch vex_arch;
1323 VexArchInfo vex_archinfo;
sewardj45f4e7c2005-09-27 19:20:21 +00001324 if (!logging_to_fd)
sewardj738856f2009-07-15 14:48:32 +00001325 VG_(message)(Vg_DebugMsg, "\n");
njna3311642009-08-10 01:29:14 +00001326 VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
sewardj14c7cc52007-02-25 15:08:24 +00001327 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
1328 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001329 " %s\n",
sewardj14c7cc52007-02-25 15:08:24 +00001330 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjde4a1d02002-03-22 01:27:54 +00001331 }
nethercotea70f7352004-04-18 12:08:46 +00001332
sewardj738856f2009-07-15 14:48:32 +00001333 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
nethercotea70f7352004-04-18 12:08:46 +00001334 fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
njncda2f0f2009-05-18 02:12:08 +00001335 if (sr_isError(fd)) {
sewardj738856f2009-07-15 14:48:32 +00001336 VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
nethercotea70f7352004-04-18 12:08:46 +00001337 } else {
sewardj71bc3cb2005-05-19 00:25:45 +00001338# define BUF_LEN 256
florian19f91bb2012-11-10 22:29:54 +00001339 HChar version_buf[BUF_LEN];
njnf3977a32009-08-04 00:27:56 +00001340 Int n = VG_(read) ( sr_Res(fd), version_buf, BUF_LEN );
1341 vg_assert(n <= BUF_LEN);
1342 if (n > 0) {
1343 version_buf[n-1] = '\0';
sewardj738856f2009-07-15 14:48:32 +00001344 VG_(message)(Vg_DebugMsg, " %s\n", version_buf);
nethercotea70f7352004-04-18 12:08:46 +00001345 } else {
sewardj738856f2009-07-15 14:48:32 +00001346 VG_(message)(Vg_DebugMsg, " (empty?)\n");
nethercotea70f7352004-04-18 12:08:46 +00001347 }
njncda2f0f2009-05-18 02:12:08 +00001348 VG_(close)(sr_Res(fd));
sewardj71bc3cb2005-05-19 00:25:45 +00001349# undef BUF_LEN
nethercotea70f7352004-04-18 12:08:46 +00001350 }
sewardj1f0bbc72005-11-16 03:51:02 +00001351
1352 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001353 VG_(message)(
1354 Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001355 "Arch and hwcaps: %s, %s\n",
sewardje3121f32006-01-27 21:23:23 +00001356 LibVEX_ppVexArch ( vex_arch ),
1357 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1358 );
sewardje66f2e02006-12-30 17:45:08 +00001359 VG_(message)(
1360 Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001361 "Page sizes: currently %d, max supported %d\n",
sewardje66f2e02006-12-30 17:45:08 +00001362 (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
1363 );
sewardj738856f2009-07-15 14:48:32 +00001364 VG_(message)(Vg_DebugMsg,
1365 "Valgrind library directory: %s\n", VG_(libdir));
sewardjde4a1d02002-03-22 01:27:54 +00001366 }
nethercotef6a1d502004-08-09 12:21:57 +00001367}
1368
sewardjde4a1d02002-03-22 01:27:54 +00001369
nethercote71980f02004-01-24 18:18:54 +00001370/*====================================================================*/
1371/*=== File descriptor setup ===*/
1372/*====================================================================*/
1373
sewardj5f229e22005-09-28 01:36:01 +00001374/* Number of file descriptors that Valgrind tries to reserve for
1375 it's own use - just a small constant. */
1376#define N_RESERVED_FDS (10)
1377
nethercote71980f02004-01-24 18:18:54 +00001378static void setup_file_descriptors(void)
1379{
1380 struct vki_rlimit rl;
sewardj17c11042006-10-15 01:26:40 +00001381 Bool show = False;
nethercote71980f02004-01-24 18:18:54 +00001382
1383 /* Get the current file descriptor limits. */
1384 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
1385 rl.rlim_cur = 1024;
1386 rl.rlim_max = 1024;
1387 }
1388
njnf76d27a2009-05-28 01:53:07 +00001389# if defined(VGO_darwin)
1390 /* Darwin lies. It reports file max as RLIM_INFINITY but
1391 silently disallows anything bigger than 10240. */
1392 if (rl.rlim_cur >= 10240 && rl.rlim_max == 0x7fffffffffffffffULL) {
1393 rl.rlim_max = 10240;
1394 }
1395# endif
1396
sewardj17c11042006-10-15 01:26:40 +00001397 if (show)
njn8a7b41b2007-09-23 00:51:24 +00001398 VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001399 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001400
nethercote71980f02004-01-24 18:18:54 +00001401 /* Work out where to move the soft limit to. */
njn14319cc2005-03-13 06:26:22 +00001402 if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
1403 rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001404 } else {
1405 rl.rlim_cur = rl.rlim_max;
1406 }
1407
1408 /* Reserve some file descriptors for our use. */
njn14319cc2005-03-13 06:26:22 +00001409 VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
1410 VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001411
1412 /* Update the soft limit. */
1413 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
1414
sewardj17c11042006-10-15 01:26:40 +00001415 if (show) {
njn8a7b41b2007-09-23 00:51:24 +00001416 VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001417 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001418 VG_(printf)("fd limits: guest : cur %u max %u\n",
1419 VG_(fd_soft_limit), VG_(fd_hard_limit));
1420 }
1421
sewardj45f4e7c2005-09-27 19:20:21 +00001422 if (VG_(cl_exec_fd) != -1)
1423 VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
nethercote71980f02004-01-24 18:18:54 +00001424}
1425
sewardjde4a1d02002-03-22 01:27:54 +00001426
njn2da73352005-06-18 01:35:16 +00001427/*====================================================================*/
njn2025cf92005-06-26 20:44:48 +00001428/*=== BB profiling ===*/
1429/*====================================================================*/
1430
1431static
1432void show_BB_profile ( BBProfEntry tops[], UInt n_tops, ULong score_total )
1433{
1434 ULong score_cumul, score_here;
floriandbb35842012-10-27 18:39:11 +00001435 HChar buf_cumul[10], buf_here[10];
florian19f91bb2012-11-10 22:29:54 +00001436 HChar name[64];
njn2025cf92005-06-26 20:44:48 +00001437 Int r;
1438
1439 VG_(printf)("\n");
1440 VG_(printf)("-----------------------------------------------------------\n");
1441 VG_(printf)("--- BEGIN BB Profile (summary of scores) ---\n");
1442 VG_(printf)("-----------------------------------------------------------\n");
1443 VG_(printf)("\n");
1444
1445 VG_(printf)("Total score = %lld\n\n", score_total);
1446
1447 score_cumul = 0;
1448 for (r = 0; r < n_tops; r++) {
1449 if (tops[r].addr == 0)
1450 continue;
1451 name[0] = 0;
1452 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1453 name[63] = 0;
1454 score_here = tops[r].score;
1455 score_cumul += score_here;
1456 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1457 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1458 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1459 r,
1460 score_cumul, buf_cumul,
1461 score_here, buf_here, tops[r].addr, name );
1462 }
1463
1464 VG_(printf)("\n");
1465 VG_(printf)("-----------------------------------------------------------\n");
1466 VG_(printf)("--- BB Profile (BB details) ---\n");
1467 VG_(printf)("-----------------------------------------------------------\n");
1468 VG_(printf)("\n");
1469
1470 score_cumul = 0;
1471 for (r = 0; r < n_tops; r++) {
1472 if (tops[r].addr == 0)
1473 continue;
1474 name[0] = 0;
1475 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1476 name[63] = 0;
1477 score_here = tops[r].score;
1478 score_cumul += score_here;
1479 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1480 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1481 VG_(printf)("\n");
1482 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin BB rank %d "
1483 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1484 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1485 r,
1486 score_cumul, buf_cumul,
1487 score_here, buf_here, tops[r].addr, name );
1488 VG_(printf)("\n");
sewardjbcccbc02007-04-09 22:24:57 +00001489 VG_(discard_translations)(tops[r].addr, 1, "bb profile");
sewardj0ec07f32006-01-12 12:32:32 +00001490 VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0, True);
njn2025cf92005-06-26 20:44:48 +00001491 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= end BB rank %d "
1492 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1493 }
1494
1495 VG_(printf)("\n");
1496 VG_(printf)("-----------------------------------------------------------\n");
1497 VG_(printf)("--- END BB Profile ---\n");
1498 VG_(printf)("-----------------------------------------------------------\n");
1499 VG_(printf)("\n");
1500}
1501
1502
1503/*====================================================================*/
nethercote71980f02004-01-24 18:18:54 +00001504/*=== main() ===*/
1505/*====================================================================*/
1506
sewardjfdf91b42005-09-28 00:53:09 +00001507/* When main() is entered, we should be on the following stack, not
1508 the one the kernel gave us. We will run on this stack until
1509 simulation of the root thread is started, at which point a transfer
1510 is made to a dynamically allocated stack. This is for the sake of
1511 uniform overflow detection for all Valgrind threads. This is
1512 marked global even though it isn't, because assembly code below
1513 needs to reference the name. */
1514
1515/*static*/ VgStack VG_(interim_stack);
1516
sewardjf9d2f9b2006-11-17 20:00:57 +00001517/* These are the structures used to hold info for creating the initial
1518 client image.
1519
1520 'iicii' mostly holds important register state present at system
1521 startup (_start_valgrind). valgrind_main() then fills in the rest
1522 of it and passes it to VG_(ii_create_image)(). That produces
1523 'iifii', which is later handed to VG_(ii_finalise_image). */
1524
1525/* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1526 This should get some address inside the stack on which we gained
sewardjfdf91b42005-09-28 00:53:09 +00001527 control (eg, it could be the SP at startup). It doesn't matter
1528 exactly where in the stack it is. This value is passed to the
sewardjf9d2f9b2006-11-17 20:00:57 +00001529 address space manager at startup. On Linux, aspacem then uses it
1530 to identify the initial stack segment and hence the upper end of
1531 the usable address space. */
sewardjfdf91b42005-09-28 00:53:09 +00001532
sewardjf9d2f9b2006-11-17 20:00:57 +00001533static IICreateImageInfo the_iicii;
1534static IIFinaliseImageInfo the_iifii;
1535
sewardjfdf91b42005-09-28 00:53:09 +00001536
sewardj9c606bd2008-09-18 18:12:50 +00001537/* A simple pair structure, used for conveying debuginfo handles to
1538 calls to VG_TRACK(new_mem_startup, ...). */
1539typedef struct { Addr a; ULong ull; } Addr_n_ULong;
1540
1541
sewardj1ae3f3a2005-09-28 10:47:38 +00001542/* --- Forwards decls to do with shutdown --- */
1543
1544static void final_tidyup(ThreadId tid);
1545
1546/* Do everything which needs doing when the last thread exits */
1547static
1548void shutdown_actions_NORETURN( ThreadId tid,
1549 VgSchedReturnCode tids_schedretcode );
1550
1551/* --- end of Forwards decls to do with shutdown --- */
sewardjfdf91b42005-09-28 00:53:09 +00001552
1553
sewardjf9d2f9b2006-11-17 20:00:57 +00001554/* By the time we get to valgrind_main, the_iicii should already have
1555 been filled in with any important details as required by whatever
1556 OS we have been built for.
1557*/
sewardj17c11042006-10-15 01:26:40 +00001558static
sewardjf9d2f9b2006-11-17 20:00:57 +00001559Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
nethercote71980f02004-01-24 18:18:54 +00001560{
florian19f91bb2012-11-10 22:29:54 +00001561 const HChar* toolname = "memcheck"; // default to Memcheck
sewardj13247ca2005-12-30 22:52:20 +00001562 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
sewardjde764e82007-11-09 23:13:22 +00001563 ThreadId tid_main = VG_INVALID_THREADID;
sewardj738856f2009-07-15 14:48:32 +00001564 Bool logging_to_fd = False;
florian19f91bb2012-11-10 22:29:54 +00001565 HChar* xml_fname_unexpanded = NULL;
sewardj45f4e7c2005-09-27 19:20:21 +00001566 Int loglevel, i;
nethercote73b526f2004-10-31 18:48:21 +00001567 struct vki_rlimit zero = { 0, 0 };
sewardj9c606bd2008-09-18 18:12:50 +00001568 XArray* addr2dihandle = NULL;
sewardj17c11042006-10-15 01:26:40 +00001569
philippe14711e82012-06-14 22:18:50 +00001570 // For an inner Valgrind, register the interim stack asap.
1571 // This is needed to allow the outer valgrind to do stacktraces during init.
1572 // Note that this stack is not unregistered when the main thread
1573 // is switching to the (real) stack. Unregistering this would imply
1574 // to save the stack id in a global variable, and have a "if"
1575 // in run_a_thread_NORETURN to do the unregistration only for the
1576 // main thread. This unregistration is not worth this complexity.
1577 INNER_REQUEST
1578 ((void) VALGRIND_STACK_REGISTER
1579 (&VG_(interim_stack).bytes[0],
1580 &VG_(interim_stack).bytes[0] + sizeof(VG_(interim_stack))));
1581
1582
nethercote71980f02004-01-24 18:18:54 +00001583 //============================================================
nethercote71980f02004-01-24 18:18:54 +00001584 //
sewardj45f4e7c2005-09-27 19:20:21 +00001585 // Nb: startup is complex. Prerequisites are shown at every step.
nethercote71980f02004-01-24 18:18:54 +00001586 // *** Be very careful when messing with the order ***
sewardj45f4e7c2005-09-27 19:20:21 +00001587 //
1588 // The first order of business is to get debug logging, the address
1589 // space manager and the dynamic memory manager up and running.
1590 // Once that's done, we can relax a bit.
1591 //
nethercote71980f02004-01-24 18:18:54 +00001592 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001593
1594 /* This is needed to make VG_(getenv) usable early. */
florian19f91bb2012-11-10 22:29:54 +00001595 VG_(client_envp) = (HChar**)envp;
nethercote71980f02004-01-24 18:18:54 +00001596
sewardj1cf558c2005-04-25 01:36:56 +00001597 //--------------------------------------------------------------
njnf76d27a2009-05-28 01:53:07 +00001598 // Start up Mach kernel interface, if any
1599 // p: none
1600 //--------------------------------------------------------------
1601# if defined(VGO_darwin)
1602 VG_(mach_init)();
1603# endif
1604
1605 //--------------------------------------------------------------
sewardj1cf558c2005-04-25 01:36:56 +00001606 // Start up the logging mechanism
1607 // p: none
1608 //--------------------------------------------------------------
1609 /* Start the debugging-log system ASAP. First find out how many
njn83df0b62009-02-25 01:01:05 +00001610 "-d"s were specified. This is a pre-scan of the command line. Also
philipped99c26a2012-07-31 22:17:28 +00001611 get --profile-heap=yes, --core-redzone-size, --redzone-size which are
1612 needed by the time we start up dynamic memory management. */
sewardj1cf558c2005-04-25 01:36:56 +00001613 loglevel = 0;
1614 for (i = 1; i < argc; i++) {
njn83df0b62009-02-25 01:01:05 +00001615 if (argv[i][0] != '-') break;
1616 if VG_STREQ(argv[i], "--") break;
1617 if VG_STREQ(argv[i], "-d") loglevel++;
1618 if VG_BOOL_CLO(argv[i], "--profile-heap", VG_(clo_profile_heap)) {}
philipped99c26a2012-07-31 22:17:28 +00001619 if VG_BINT_CLO(argv[i], "--core-redzone-size", VG_(clo_core_redzone_size),
1620 0, MAX_CLO_REDZONE_SZB) {}
1621 if VG_BINT_CLO(argv[i], "--redzone-size", VG_(clo_redzone_size),
1622 0, MAX_CLO_REDZONE_SZB) {}
sewardj1cf558c2005-04-25 01:36:56 +00001623 }
1624
1625 /* ... and start the debug logger. Now we can safely emit logging
1626 messages all through startup. */
sewardj10759312005-05-30 23:52:47 +00001627 VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
sewardj45f4e7c2005-09-27 19:20:21 +00001628 VG_(debugLog)(1, "main", "Welcome to Valgrind version "
1629 VERSION " debug logging\n");
1630
1631 //--------------------------------------------------------------
1632 // Ensure we're on a plausible stack.
1633 // p: logging
1634 //--------------------------------------------------------------
1635 VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
sewardjfdf91b42005-09-28 00:53:09 +00001636 { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
1637 HChar* limHi = limLo + sizeof(VG_(interim_stack));
sewardjed8b0f62012-09-02 21:17:36 +00001638 HChar* volatile
1639 aLocal = (HChar*)&limLo; /* any auto local will do */
1640 /* Re "volatile": Apple clang version 4.0
1641 (tags/Apple/clang-421.0.57) (based on LLVM 3.1svn)" appeared
1642 to miscompile the following check, causing run to abort at
1643 this point (in 64-bit mode) even though aLocal is within limLo
1644 .. limHi. But in fact clang is within its rights to do
1645 strange things here. "The reason is that the comparisons
1646 aLocal < limLo and aLocal >= limHi cause undefined behaviour
1647 (according to c99 6.5.8) because they compare pointers that do
1648 not point into the same aggregate." Adding "volatile" appears
1649 to fix it because "The compiler would have to prove that there
1650 is undefined behavior in order to exploit it. But as a
1651 volatile variable can change its value in ways invisible to
1652 the compiler, the compiler must make the conservative
1653 assumption that it points into the same aggregate as the other
1654 pointer its compared against. I.e. the behaviour is possibly
1655 defined." (Analysis by Florian Krohm). */
sewardj45f4e7c2005-09-27 19:20:21 +00001656 if (aLocal < limLo || aLocal >= limHi) {
1657 /* something's wrong. Stop. */
1658 VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
1659 limLo, limHi, aLocal );
1660 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1661 "Initial stack switched failed.\n");
1662 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1663 VG_(exit)(1);
1664 }
1665 }
1666
1667 //--------------------------------------------------------------
1668 // Ensure we have a plausible pointer to the stack on which
1669 // we gained control (not the current stack!)
1670 // p: logging
1671 //--------------------------------------------------------------
1672 VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
sewardjf9d2f9b2006-11-17 20:00:57 +00001673 if (the_iicii.sp_at_startup == 0) {
sewardj45f4e7c2005-09-27 19:20:21 +00001674 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1675 "Initial stack was not noted.\n");
1676 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1677 VG_(exit)(1);
1678 }
1679
1680 //--------------------------------------------------------------
1681 // Start up the address space manager, and determine the
1682 // approximate location of the client's stack
njnea2d6fd2010-07-01 00:20:20 +00001683 // p: logging, plausible-stack
sewardj45f4e7c2005-09-27 19:20:21 +00001684 //--------------------------------------------------------------
1685 VG_(debugLog)(1, "main", "Starting the address space manager\n");
sewardj5db15402012-06-07 09:13:21 +00001686 vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536
1687 || VKI_PAGE_SIZE == 16384);
1688 vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536
1689 || VKI_MAX_PAGE_SIZE == 16384);
sewardje66f2e02006-12-30 17:45:08 +00001690 vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
1691 vg_assert(VKI_PAGE_SIZE == (1 << VKI_PAGE_SHIFT));
1692 vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
sewardjf9d2f9b2006-11-17 20:00:57 +00001693 the_iicii.clstack_top = VG_(am_startup)( the_iicii.sp_at_startup );
sewardj45f4e7c2005-09-27 19:20:21 +00001694 VG_(debugLog)(1, "main", "Address space manager is running\n");
1695
1696 //--------------------------------------------------------------
1697 // Start up the dynamic memory manager
1698 // p: address space management
philipped99c26a2012-07-31 22:17:28 +00001699 // p: getting --profile-heap,--core-redzone-size,--redzone-size
sewardj45f4e7c2005-09-27 19:20:21 +00001700 // In fact m_mallocfree is self-initialising, so there's no
1701 // initialisation call to do. Instead, try a simple malloc/
1702 // free pair right now to check that nothing is broken.
1703 //--------------------------------------------------------------
1704 VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
sewardj9c606bd2008-09-18 18:12:50 +00001705 { void* p = VG_(malloc)( "main.vm.1", 12345 );
sewardj45f4e7c2005-09-27 19:20:21 +00001706 if (p) VG_(free)( p );
1707 }
1708 VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
sewardj1cf558c2005-04-25 01:36:56 +00001709
nethercotef4928da2004-06-15 10:54:40 +00001710 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001711 //
1712 // Dynamic memory management is now available.
1713 //
nethercotef4928da2004-06-15 10:54:40 +00001714 //============================================================
1715
sewardj45f4e7c2005-09-27 19:20:21 +00001716 //--------------------------------------------------------------
sewardjf98e1c02008-10-25 16:22:41 +00001717 // Initialise m_debuginfo
1718 // p: dynamic memory allocation
1719 VG_(debugLog)(1, "main", "Initialise m_debuginfo\n");
1720 VG_(di_initialise)();
1721
1722 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001723 // Look for alternative libdir
1724 { HChar *cp = VG_(getenv)(VALGRIND_LIB);
1725 if (cp != NULL)
1726 VG_(libdir) = cp;
njncde90d32009-07-22 22:41:38 +00001727 VG_(debugLog)(1, "main", "VG_(libdir) = %s\n", VG_(libdir));
sewardj45f4e7c2005-09-27 19:20:21 +00001728 }
1729
1730 //--------------------------------------------------------------
1731 // Extract the launcher name from the environment.
njna842d792009-05-21 01:15:18 +00001732 VG_(debugLog)(1, "main", "Getting launcher's name ...\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001733 VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
1734 if (VG_(name_of_launcher) == NULL) {
1735 VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
1736 VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
1737 VG_(exit)(1);
1738 }
njna842d792009-05-21 01:15:18 +00001739 VG_(debugLog)(1, "main", "... %s\n", VG_(name_of_launcher));
sewardj45f4e7c2005-09-27 19:20:21 +00001740
1741 //--------------------------------------------------------------
fitzhardingeb50068f2004-02-24 23:42:55 +00001742 // Get the current process datasize rlimit, and set it to zero.
1743 // This prevents any internal uses of brk() from having any effect.
1744 // We remember the old value so we can restore it on exec, so that
1745 // child processes will have a reasonable brk value.
1746 VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1747 zero.rlim_max = VG_(client_rlimit_data).rlim_max;
1748 VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
thughesc37184f2004-09-11 14:16:57 +00001749
1750 // Get the current process stack rlimit.
1751 VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
1752
sewardje2d1e672005-11-12 23:10:48 +00001753 //--------------------------------------------------------------
1754 // Figure out what sort of CPU we're on, and whether it is
1755 // able to run V.
1756 VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
1757 { VexArch vex_arch;
1758 VexArchInfo vex_archinfo;
1759 Bool ok = VG_(machine_get_hwcaps)();
1760 if (!ok) {
1761 VG_(printf)("\n");
1762 VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
1763 VG_(printf)(" Supported CPUs are:\n");
1764 VG_(printf)(" * x86 (practically any; Pentium-I or above), "
1765 "AMD Athlon or above)\n");
1766 VG_(printf)(" * AMD Athlon64/Opteron\n");
1767 VG_(printf)(" * PowerPC (most; ppc405 and above)\n");
sewardjb5b87402011-03-07 16:05:35 +00001768 VG_(printf)(" * System z (64bit only - s390x; z900 and above)\n");
sewardje2d1e672005-11-12 23:10:48 +00001769 VG_(printf)("\n");
1770 VG_(exit)(1);
1771 }
1772 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001773 VG_(debugLog)(
1774 1, "main", "... arch = %s, hwcaps = %s\n",
1775 LibVEX_ppVexArch ( vex_arch ),
1776 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1777 );
sewardje2d1e672005-11-12 23:10:48 +00001778 }
1779
sewardj198f34f2007-07-09 23:13:07 +00001780 //--------------------------------------------------------------
1781 // Record the working directory at startup
sewardj6e9de462011-06-28 07:25:29 +00001782 // p: none
sewardj198f34f2007-07-09 23:13:07 +00001783 VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
1784 { Bool ok = VG_(record_startup_wd)();
1785 if (!ok)
1786 VG_(err_config_error)( "Can't establish current working "
florian1763e812011-07-12 19:07:05 +00001787 "directory at startup\n");
sewardj198f34f2007-07-09 23:13:07 +00001788 }
florian19f91bb2012-11-10 22:29:54 +00001789 { HChar buf[VKI_PATH_MAX+1];
sewardj198f34f2007-07-09 23:13:07 +00001790 Bool ok = VG_(get_startup_wd)( buf, sizeof(buf) );
1791 vg_assert(ok);
1792 buf[VKI_PATH_MAX] = 0;
1793 VG_(debugLog)(1, "main", "... %s\n", buf );
1794 }
1795
sewardj45f4e7c2005-09-27 19:20:21 +00001796 //============================================================
1797 // Command line argument handling order:
1798 // * If --help/--help-debug are present, show usage message
1799 // (including the tool-specific usage)
1800 // * (If no --tool option given, default to Memcheck)
1801 // * Then, if client is missing, abort with error msg
1802 // * Then, if any cmdline args are bad, abort with error msg
1803 //============================================================
1804
1805 //--------------------------------------------------------------
1806 // Split up argv into: C args, V args, V extra args, and exename.
1807 // p: dynamic memory allocation
1808 //--------------------------------------------------------------
1809 VG_(debugLog)(1, "main", "Split up command line\n");
1810 VG_(split_up_argv)( argc, argv );
sewardj14c7cc52007-02-25 15:08:24 +00001811 vg_assert( VG_(args_for_valgrind) );
1812 vg_assert( VG_(args_for_client) );
sewardj45f4e7c2005-09-27 19:20:21 +00001813 if (0) {
sewardj14c7cc52007-02-25 15:08:24 +00001814 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
1815 VG_(printf)(
1816 "varg %s\n",
1817 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1818 );
sewardj45f4e7c2005-09-27 19:20:21 +00001819 VG_(printf)(" exe %s\n", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001820 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
1821 VG_(printf)(
1822 "carg %s\n",
1823 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1824 );
nethercote71980f02004-01-24 18:18:54 +00001825 }
1826
1827 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001828 // Extract tool name and whether help has been requested.
1829 // Note we can't print the help message yet, even if requested,
1830 // because the tool has not been initialised.
1831 // p: split_up_argv [for VG_(args_for_valgrind)]
nethercote71980f02004-01-24 18:18:54 +00001832 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001833 VG_(debugLog)(1, "main",
1834 "(early_) Process Valgrind's command line options\n");
1835 early_process_cmd_line_options(&need_help, &toolname);
nethercote71980f02004-01-24 18:18:54 +00001836
sewardj45f4e7c2005-09-27 19:20:21 +00001837 // Set default vex control params
1838 LibVEX_default_VexControl(& VG_(clo_vex_control));
nethercote71980f02004-01-24 18:18:54 +00001839
1840 //--------------------------------------------------------------
1841 // Load client executable, finding in $PATH if necessary
njn83df0b62009-02-25 01:01:05 +00001842 // p: early_process_cmd_line_options() [for 'exec', 'need_help',
1843 // clo_max_stackframe,
1844 // clo_main_stacksize]
sewardj95d86c02007-12-18 01:49:23 +00001845 // p: layout_remaining_space [so there's space]
sewardj17c11042006-10-15 01:26:40 +00001846 //
nethercote71980f02004-01-24 18:18:54 +00001847 // Set up client's environment
sewardj95d86c02007-12-18 01:49:23 +00001848 // p: set-libdir [for VG_(libdir)]
1849 // p: early_process_cmd_line_options [for toolname]
sewardj17c11042006-10-15 01:26:40 +00001850 //
nethercote5ee67ca2004-06-22 14:00:09 +00001851 // Setup client stack, eip, and VG_(client_arg[cv])
nethercote71980f02004-01-24 18:18:54 +00001852 // p: load_client() [for 'info']
1853 // p: fix_environment() [for 'env']
sewardj17c11042006-10-15 01:26:40 +00001854 //
sewardj45f4e7c2005-09-27 19:20:21 +00001855 // Setup client data (brk) segment. Initially a 1-page segment
1856 // which abuts a shrinkable reservation.
1857 // p: load_client() [for 'info' and hence VG_(brk_base)]
sewardjf9d2f9b2006-11-17 20:00:57 +00001858 //
1859 // p: _start_in_C (for zeroing out the_iicii and putting some
1860 // initial values into it)
sewardj45f4e7c2005-09-27 19:20:21 +00001861 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001862 if (!need_help) {
sewardjf9d2f9b2006-11-17 20:00:57 +00001863 VG_(debugLog)(1, "main", "Create initial image\n");
1864
njnf76d27a2009-05-28 01:53:07 +00001865# if defined(VGO_linux) || defined(VGO_darwin)
sewardjf9d2f9b2006-11-17 20:00:57 +00001866 the_iicii.argv = argv;
1867 the_iicii.envp = envp;
1868 the_iicii.toolname = toolname;
sewardjf9d2f9b2006-11-17 20:00:57 +00001869# else
njna842d792009-05-21 01:15:18 +00001870# error "Unknown platform"
sewardjf9d2f9b2006-11-17 20:00:57 +00001871# endif
1872
sewardjdc2f79e2007-12-22 14:14:04 +00001873 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001874 the_iifii = VG_(ii_create_image)( the_iicii );
sewardj45f4e7c2005-09-27 19:20:21 +00001875 }
nethercote71980f02004-01-24 18:18:54 +00001876
1877 //==============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001878 //
1879 // Finished loading/setting up the client address space.
1880 //
nethercote71980f02004-01-24 18:18:54 +00001881 //==============================================================
1882
1883 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001884 // setup file descriptors
1885 // p: n/a
1886 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001887 VG_(debugLog)(1, "main", "Setup file descriptors\n");
nethercote71980f02004-01-24 18:18:54 +00001888 setup_file_descriptors();
1889
1890 //--------------------------------------------------------------
tom41ad7e72012-10-04 20:27:38 +00001891 // create fake /proc/<pid>/cmdline and /proc/<pid>/auxv files
1892 // and then unlink them, but hold onto the fds, so we can handr
1893 // them out to the client when it tries to open
1894 // /proc/<pid>/cmdline or /proc/<pid>/auxv for itself.
sewardj45f4e7c2005-09-27 19:20:21 +00001895 // p: setup file descriptors
tom41ad7e72012-10-04 20:27:38 +00001896 // p: ii_create_image for VG_(client_auxv) setup.
nethercotec314eba2004-07-15 12:59:41 +00001897 //--------------------------------------------------------------
bart9b533f82009-08-25 20:15:41 +00001898#if !defined(VGO_linux)
1899 // client shouldn't be using /proc!
1900 VG_(cl_cmdline_fd) = -1;
tom41ad7e72012-10-04 20:27:38 +00001901 VG_(cl_auxv_fd) = -1;
bart9b533f82009-08-25 20:15:41 +00001902#else
1903 if (!need_help) {
1904 HChar buf[50], buf2[50+64];
1905 HChar nul[1];
1906 Int fd, r;
barta3054f52010-06-14 18:12:56 +00001907 const HChar* exename;
nethercotec314eba2004-07-15 12:59:41 +00001908
bart9b533f82009-08-25 20:15:41 +00001909 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001910
bart9b533f82009-08-25 20:15:41 +00001911 VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
1912 fd = VG_(mkstemp)( buf, buf2 );
1913 if (fd == -1)
florian1763e812011-07-12 19:07:05 +00001914 VG_(err_config_error)("Can't create client cmdline file in %s\n", buf2);
sewardj45f4e7c2005-09-27 19:20:21 +00001915
bart9b533f82009-08-25 20:15:41 +00001916 nul[0] = 0;
1917 exename = VG_(args_the_exename) ? VG_(args_the_exename)
1918 : "unknown_exename";
sewardjc7ffc942011-03-28 16:26:42 +00001919 VG_(write)(fd, exename, VG_(strlen)( exename ));
bart9b533f82009-08-25 20:15:41 +00001920 VG_(write)(fd, nul, 1);
1921
1922 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1923 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
1924 VG_(write)(fd, arg, VG_(strlen)( arg ));
sewardj45f4e7c2005-09-27 19:20:21 +00001925 VG_(write)(fd, nul, 1);
1926 }
bart9b533f82009-08-25 20:15:41 +00001927
1928 /* Don't bother to seek the file back to the start; instead do
1929 it every time a copy of it is given out (by PRE(sys_open)).
1930 That is probably more robust across fork() etc. */
1931
1932 /* Now delete it, but hang on to the fd. */
1933 r = VG_(unlink)( buf2 );
1934 if (r)
florian1763e812011-07-12 19:07:05 +00001935 VG_(err_config_error)("Can't delete client cmdline file in %s\n", buf2);
bart9b533f82009-08-25 20:15:41 +00001936
1937 VG_(cl_cmdline_fd) = fd;
tom41ad7e72012-10-04 20:27:38 +00001938
1939 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/auxv\n");
1940
1941 VG_(sprintf)(buf, "proc_%d_auxv", VG_(getpid)());
1942 fd = VG_(mkstemp)( buf, buf2 );
1943 if (fd == -1)
1944 VG_(err_config_error)("Can't create client auxv file in %s\n", buf2);
1945
1946 UWord *client_auxv = VG_(client_auxv);
1947 unsigned int client_auxv_len = 0;
1948 while (*client_auxv != 0) {
1949 client_auxv++;
1950 client_auxv++;
1951 client_auxv_len += 2 * sizeof(UWord);
1952 }
1953 client_auxv_len += 2 * sizeof(UWord);
1954
1955 VG_(write)(fd, VG_(client_auxv), client_auxv_len);
1956
1957 /* Don't bother to seek the file back to the start; instead do
1958 it every time a copy of it is given out (by PRE(sys_open)).
1959 That is probably more robust across fork() etc. */
1960
1961 /* Now delete it, but hang on to the fd. */
1962 r = VG_(unlink)( buf2 );
1963 if (r)
1964 VG_(err_config_error)("Can't delete client auxv file in %s\n", buf2);
1965
1966 VG_(cl_auxv_fd) = fd;
sewardj45f4e7c2005-09-27 19:20:21 +00001967 }
bart9b533f82009-08-25 20:15:41 +00001968#endif
nethercotec314eba2004-07-15 12:59:41 +00001969
1970 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001971 // Init tool part 1: pre_clo_init
nethercotec314eba2004-07-15 12:59:41 +00001972 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
nethercotec314eba2004-07-15 12:59:41 +00001973 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
nethercote71980f02004-01-24 18:18:54 +00001974 //--------------------------------------------------------------
sewardj7cf4e6b2008-05-01 20:24:26 +00001975 VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
njn08ce7b32009-02-27 03:38:28 +00001976 VG_(tl_pre_clo_init)();
nethercote71980f02004-01-24 18:18:54 +00001977
sewardj45f4e7c2005-09-27 19:20:21 +00001978 //--------------------------------------------------------------
nethercotef4928da2004-06-15 10:54:40 +00001979 // If --tool and --help/--help-debug was given, now give the core+tool
1980 // help message
sewardj95d86c02007-12-18 01:49:23 +00001981 // p: early_process_cmd_line_options() [for 'need_help']
1982 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
sewardj45f4e7c2005-09-27 19:20:21 +00001983 //--------------------------------------------------------------
1984 VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
nethercotef4928da2004-06-15 10:54:40 +00001985 if (need_help) {
njncce38e62010-07-06 04:25:12 +00001986 usage_NORETURN(/*--help-debug?*/need_help >= 2);
nethercotef4928da2004-06-15 10:54:40 +00001987 }
nethercotec314eba2004-07-15 12:59:41 +00001988
sewardj45f4e7c2005-09-27 19:20:21 +00001989 //--------------------------------------------------------------
1990 // Process command line options to Valgrind + tool
1991 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1992 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1993 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001994 VG_(debugLog)(1, "main",
1995 "(main_) Process Valgrind's command line options, "
1996 "setup logging\n");
sewardj738856f2009-07-15 14:48:32 +00001997 main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded,
1998 toolname );
sewardj45f4e7c2005-09-27 19:20:21 +00001999
2000 //--------------------------------------------------------------
sewardj592ae092005-11-08 19:01:44 +00002001 // Zeroise the millisecond counter by doing a first read of it.
2002 // p: none
2003 //--------------------------------------------------------------
2004 (void) VG_(read_millisecond_timer)();
2005
2006 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002007 // Print the preamble
2008 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
sewardj738856f2009-07-15 14:48:32 +00002009 // p: main_process_cmd_line_options()
2010 // [for VG_(clo_verbosity), VG_(clo_xml),
2011 // logging_to_fd, xml_fname_unexpanded]
sewardj45f4e7c2005-09-27 19:20:21 +00002012 //--------------------------------------------------------------
2013 VG_(debugLog)(1, "main", "Print the preamble...\n");
sewardj738856f2009-07-15 14:48:32 +00002014 print_preamble(logging_to_fd, xml_fname_unexpanded, toolname);
sewardj45f4e7c2005-09-27 19:20:21 +00002015 VG_(debugLog)(1, "main", "...finished the preamble\n");
2016
2017 //--------------------------------------------------------------
2018 // Init tool part 2: post_clo_init
2019 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
2020 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
2021 // p: print_preamble() [so any warnings printed in post_clo_init
2022 // are shown after the preamble]
2023 //--------------------------------------------------------------
2024 VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
njn51d827b2005-05-09 01:02:08 +00002025 VG_TDICT_CALL(tool_post_clo_init);
sewardj7cf4e6b2008-05-01 20:24:26 +00002026 {
2027 /* The tool's "needs" will by now be finalised, since it has no
2028 further opportunity to specify them. So now sanity check
2029 them. */
floriane6a4ed12012-10-21 02:30:18 +00002030 const HChar* s;
sewardj7cf4e6b2008-05-01 20:24:26 +00002031 Bool ok;
2032 ok = VG_(sanity_check_needs)( &s );
2033 if (!ok) {
2034 VG_(tool_panic)(s);
2035 }
2036 }
nethercotef4928da2004-06-15 10:54:40 +00002037
2038 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002039 // Initialise translation table and translation cache
2040 // p: aspacem [??]
2041 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
nethercote71980f02004-01-24 18:18:54 +00002042 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002043 VG_(debugLog)(1, "main", "Initialise TT/TC\n");
2044 VG_(init_tt_tc)();
sewardjb5f6f512005-03-10 23:59:00 +00002045
sewardj45f4e7c2005-09-27 19:20:21 +00002046 //--------------------------------------------------------------
2047 // Initialise the redirect table.
2048 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
2049 // p: aspacem [so can change ownership of sysinfo pages]
2050 //--------------------------------------------------------------
2051 VG_(debugLog)(1, "main", "Initialise redirects\n");
sewardj0ec07f32006-01-12 12:32:32 +00002052 VG_(redir_initialise)();
nethercote71980f02004-01-24 18:18:54 +00002053
2054 //--------------------------------------------------------------
2055 // Allow GDB attach
sewardj95d86c02007-12-18 01:49:23 +00002056 // p: main_process_cmd_line_options() [for VG_(clo_wait_for_gdb)]
nethercote71980f02004-01-24 18:18:54 +00002057 //--------------------------------------------------------------
2058 /* Hook to delay things long enough so we can get the pid and
2059 attach GDB in another shell. */
2060 if (VG_(clo_wait_for_gdb)) {
sewardj87cd71c2011-07-05 09:13:41 +00002061 ULong iters, q;
sewardj1fbc1a52005-04-25 02:05:54 +00002062 VG_(debugLog)(1, "main", "Wait for GDB\n");
sewardj93ab8572005-02-06 14:10:40 +00002063 VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
sewardj8211a572005-06-23 21:37:47 +00002064
2065# if defined(VGP_x86_linux)
sewardj291849f2012-04-20 23:58:55 +00002066 iters = 10;
sewardj2c48c7b2005-11-29 13:05:56 +00002067# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
sewardj8211a572005-06-23 21:37:47 +00002068 iters = 10;
2069# elif defined(VGP_ppc32_linux)
sewardjd714d2e2005-07-08 18:24:04 +00002070 iters = 5;
sewardj59570ff2010-01-01 11:59:33 +00002071# elif defined(VGP_arm_linux)
sewardj291849f2012-04-20 23:58:55 +00002072 iters = 5;
sewardjb5b87402011-03-07 16:05:35 +00002073# elif defined(VGP_s390x_linux)
2074 iters = 10;
sewardj5db15402012-06-07 09:13:21 +00002075# elif defined(VGP_mips32_linux)
2076 iters = 10;
njnf76d27a2009-05-28 01:53:07 +00002077# elif defined(VGO_darwin)
2078 iters = 3;
sewardj8211a572005-06-23 21:37:47 +00002079# else
sewardj17c11042006-10-15 01:26:40 +00002080# error "Unknown plat"
sewardj8211a572005-06-23 21:37:47 +00002081# endif
2082
sewardj87cd71c2011-07-05 09:13:41 +00002083 iters *= 1000ULL * 1000 * 1000;
sewardj8211a572005-06-23 21:37:47 +00002084 for (q = 0; q < iters; q++)
sewardj87cd71c2011-07-05 09:13:41 +00002085 __asm__ __volatile__("" ::: "memory","cc");
nethercote71980f02004-01-24 18:18:54 +00002086 }
2087
sewardjb5d320c2005-03-13 18:57:15 +00002088 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002089 // Search for file descriptors that are inherited from our parent
sewardj95d86c02007-12-18 01:49:23 +00002090 // p: main_process_cmd_line_options [for VG_(clo_track_fds)]
nethercote71980f02004-01-24 18:18:54 +00002091 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00002092 if (VG_(clo_track_fds)) {
2093 VG_(debugLog)(1, "main", "Init preopened fds\n");
nethercote71980f02004-01-24 18:18:54 +00002094 VG_(init_preopened_fds)();
sewardj1fbc1a52005-04-25 02:05:54 +00002095 }
nethercote71980f02004-01-24 18:18:54 +00002096
2097 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002098 // Load debug info for the existing segments.
2099 // p: setup_code_redirect_table [so that redirs can be recorded]
2100 // p: mallocfree
2101 // p: probably: setup fds and process CLOs, so that logging works
sewardjf98e1c02008-10-25 16:22:41 +00002102 // p: initialise m_debuginfo
sewardj9c606bd2008-09-18 18:12:50 +00002103 //
2104 // While doing this, make a note of the debuginfo-handles that
sewardj6e9de462011-06-28 07:25:29 +00002105 // come back from VG_(di_notify_mmap).
sewardj9c606bd2008-09-18 18:12:50 +00002106 // Later, in "Tell the tool about the initial client memory permissions"
2107 // (just below) we can then hand these handles off to the tool in
2108 // calls to VG_TRACK(new_mem_startup, ...). This gives the tool the
2109 // opportunity to make further queries to m_debuginfo before the
2110 // client is started, if it wants. We put this information into an
2111 // XArray, each handle along with the associated segment start address,
2112 // and search the XArray for the handles later, when calling
2113 // VG_TRACK(new_mem_startup, ...).
sewardj45f4e7c2005-09-27 19:20:21 +00002114 //--------------------------------------------------------------
2115 VG_(debugLog)(1, "main", "Load initial debug info\n");
sewardj9c606bd2008-09-18 18:12:50 +00002116
2117 tl_assert(!addr2dihandle);
2118 addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2",
2119 VG_(free), sizeof(Addr_n_ULong) );
2120 tl_assert(addr2dihandle);
2121
sewardj17c11042006-10-15 01:26:40 +00002122# if defined(VGO_linux)
sewardj45f4e7c2005-09-27 19:20:21 +00002123 { Addr* seg_starts;
2124 Int n_seg_starts;
sewardj9c606bd2008-09-18 18:12:50 +00002125 Addr_n_ULong anu;
sewardj45f4e7c2005-09-27 19:20:21 +00002126
njnac1e0332009-05-08 00:39:31 +00002127 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00002128 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00002129
sewardjf72cced2005-11-08 00:45:47 +00002130 /* show them all to the debug info reader. allow_SkFileV has to
2131 be True here so that we read info from the valgrind executable
2132 itself. */
sewardj9c606bd2008-09-18 18:12:50 +00002133 for (i = 0; i < n_seg_starts; i++) {
sewardj5f2dcad2011-10-24 08:53:03 +00002134 anu.ull = VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/,
2135 -1/*Don't use_fd*/);
sewardj9c606bd2008-09-18 18:12:50 +00002136 /* anu.ull holds the debuginfo handle returned by di_notify_mmap,
2137 if any. */
2138 if (anu.ull > 0) {
2139 anu.a = seg_starts[i];
2140 VG_(addToXA)( addr2dihandle, &anu );
2141 }
2142 }
sewardj45f4e7c2005-09-27 19:20:21 +00002143
2144 VG_(free)( seg_starts );
2145 }
njnf76d27a2009-05-28 01:53:07 +00002146# elif defined(VGO_darwin)
2147 { Addr* seg_starts;
2148 Int n_seg_starts;
2149 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
2150 vg_assert(seg_starts && n_seg_starts >= 0);
2151
2152 /* show them all to the debug info reader.
2153 Don't read from V segments (unlike Linux) */
2154 // GrP fixme really?
sewardj5f2dcad2011-10-24 08:53:03 +00002155 for (i = 0; i < n_seg_starts; i++) {
2156 VG_(di_notify_mmap)( seg_starts[i], False/*don't allow_SkFileV*/,
2157 -1/*don't use_fd*/);
2158 }
njnf76d27a2009-05-28 01:53:07 +00002159
2160 VG_(free)( seg_starts );
2161 }
sewardj17c11042006-10-15 01:26:40 +00002162# else
2163# error Unknown OS
2164# endif
sewardj45f4e7c2005-09-27 19:20:21 +00002165
2166 //--------------------------------------------------------------
2167 // Tell aspacem of ownership change of the asm helpers, so that
2168 // m_translate allows them to be translated. However, only do this
2169 // after the initial debug info read, since making a hole in the
2170 // address range for the stage2 binary confuses the debug info reader.
2171 // p: aspacem
2172 //--------------------------------------------------------------
2173 { Bool change_ownership_v_c_OK;
sewardj1a85f4f2006-01-12 21:15:35 +00002174 Addr co_start = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
2175 Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
sewardj45f4e7c2005-09-27 19:20:21 +00002176 VG_(debugLog)(1,"redir",
2177 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
2178 (ULong)co_start, (ULong)co_endPlus-1 );
2179
2180 change_ownership_v_c_OK
2181 = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
2182 vg_assert(change_ownership_v_c_OK);
2183 }
2184
bart6c63f5c2011-10-11 18:50:14 +00002185 if (VG_(clo_xml)) {
2186 HChar buf[50];
2187 VG_(elapsed_wallclock_time)(buf);
2188 VG_(printf_xml)( "<status>\n"
2189 " <state>RUNNING</state>\n"
2190 " <time>%pS</time>\n"
2191 "</status>\n",
2192 buf );
2193 VG_(printf_xml)( "\n" );
2194 }
2195
bart27233e92012-03-08 14:59:25 +00002196 VG_(init_Threads)();
2197
sewardj45f4e7c2005-09-27 19:20:21 +00002198 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002199 // Initialise the scheduler (phase 1) [generates tid_main]
2200 // p: none, afaics
2201 //--------------------------------------------------------------
2202 VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
2203 tid_main = VG_(scheduler_init_phase1)();
2204 vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
2205 && tid_main != VG_INVALID_THREADID);
2206 /* Tell the tool about tid_main */
2207 VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
2208
2209 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002210 // Tell the tool about the initial client memory permissions
2211 // p: aspacem
2212 // p: mallocfree
2213 // p: setup_client_stack
2214 // p: setup_client_dataseg
sewardj9c606bd2008-09-18 18:12:50 +00002215 //
2216 // For each segment we tell the client about, look up in
2217 // addr2dihandle as created above, to see if there's a debuginfo
2218 // handle associated with the segment, that we can hand along
2219 // to the tool, to be helpful.
sewardj45f4e7c2005-09-27 19:20:21 +00002220 //--------------------------------------------------------------
2221 VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
2222 { Addr* seg_starts;
2223 Int n_seg_starts;
sewardj45f4e7c2005-09-27 19:20:21 +00002224
sewardj9c606bd2008-09-18 18:12:50 +00002225 tl_assert(addr2dihandle);
2226
tom7c1a19a2008-01-02 10:13:04 +00002227 /* Mark the main thread as running while we tell the tool about
2228 the client memory so that the tool can associate that memory
2229 with the main thread. */
2230 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
2231 VG_(running_tid) = tid_main;
2232
njnac1e0332009-05-08 00:39:31 +00002233 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00002234 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00002235
2236 /* show interesting ones to the tool */
2237 for (i = 0; i < n_seg_starts; i++) {
sewardj9c606bd2008-09-18 18:12:50 +00002238 Word j, n;
sewardj12ab7652006-10-17 02:10:42 +00002239 NSegment const* seg
sewardj17c11042006-10-15 01:26:40 +00002240 = VG_(am_find_nsegment)( seg_starts[i] );
sewardj45f4e7c2005-09-27 19:20:21 +00002241 vg_assert(seg);
2242 if (seg->kind == SkFileC || seg->kind == SkAnonC) {
sewardjc6d86a32009-01-31 15:08:08 +00002243 /* This next assertion is tricky. If it is placed
2244 immediately before this 'if', it very occasionally fails.
2245 Why? Because previous iterations of the loop may have
2246 caused tools (via the new_mem_startup calls) to do
2247 dynamic memory allocation, and that may affect the mapped
2248 segments; in particular it may cause segment merging to
2249 happen. Hence we cannot assume that seg_starts[i], which
2250 reflects the state of the world before we started this
2251 loop, is the same as seg->start, as the latter reflects
2252 the state of the world (viz, mappings) at this particular
2253 iteration of the loop.
2254
2255 Why does moving it inside the 'if' make it safe? Because
2256 any dynamic memory allocation done by the tools will
2257 affect only the state of Valgrind-owned segments, not of
2258 Client-owned segments. And the 'if' guards against that
2259 -- we only get in here for Client-owned segments.
2260
2261 In other words: the loop may change the state of
2262 Valgrind-owned segments as it proceeds. But it should
2263 not cause the Client-owned segments to change. */
2264 vg_assert(seg->start == seg_starts[i]);
sewardj45f4e7c2005-09-27 19:20:21 +00002265 VG_(debugLog)(2, "main",
2266 "tell tool about %010lx-%010lx %c%c%c\n",
2267 seg->start, seg->end,
2268 seg->hasR ? 'r' : '-',
2269 seg->hasW ? 'w' : '-',
2270 seg->hasX ? 'x' : '-' );
sewardj9c606bd2008-09-18 18:12:50 +00002271 /* search addr2dihandle to see if we have an entry
2272 matching seg->start. */
2273 n = VG_(sizeXA)( addr2dihandle );
2274 for (j = 0; j < n; j++) {
2275 Addr_n_ULong* anl = VG_(indexXA)( addr2dihandle, j );
2276 if (anl->a == seg->start) {
2277 tl_assert(anl->ull > 0); /* check it's a valid handle */
2278 break;
2279 }
2280 }
2281 vg_assert(j >= 0 && j <= n);
sewardj45f4e7c2005-09-27 19:20:21 +00002282 VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
sewardj9c606bd2008-09-18 18:12:50 +00002283 seg->hasR, seg->hasW, seg->hasX,
2284 /* and the retrieved debuginfo handle, if any */
2285 j < n
2286 ? ((Addr_n_ULong*)VG_(indexXA)( addr2dihandle, j ))->ull
2287 : 0 );
sewardj45f4e7c2005-09-27 19:20:21 +00002288 }
2289 }
2290
2291 VG_(free)( seg_starts );
sewardj9c606bd2008-09-18 18:12:50 +00002292 VG_(deleteXA)( addr2dihandle );
sewardj45f4e7c2005-09-27 19:20:21 +00002293
2294 /* Also do the initial stack permissions. */
barte05b3a42010-09-07 16:32:53 +00002295 {
2296 SSizeT inaccessible_len;
2297 NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002298 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj17c11042006-10-15 01:26:40 +00002299 vg_assert(seg);
2300 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002301 vg_assert(the_iifii.initial_client_SP >= seg->start);
2302 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardj45f4e7c2005-09-27 19:20:21 +00002303
sewardj17c11042006-10-15 01:26:40 +00002304 /* Stuff below the initial SP is unaddressable. Take into
2305 account any ABI-mandated space below the stack pointer that
2306 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
2307 will have allocated an extra page if a red zone is required,
2308 to be on the safe side. */
barte05b3a42010-09-07 16:32:53 +00002309 inaccessible_len = the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
2310 - seg->start;
2311 vg_assert(inaccessible_len >= 0);
2312 if (inaccessible_len > 0)
2313 VG_TRACK( die_mem_stack,
2314 seg->start,
2315 inaccessible_len );
sewardj17c11042006-10-15 01:26:40 +00002316 VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
2317 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00002318 the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
sewardj17c11042006-10-15 01:26:40 +00002319 }
sewardj45f4e7c2005-09-27 19:20:21 +00002320
2321 /* Also the assembly helpers. */
2322 VG_TRACK( new_mem_startup,
2323 (Addr)&VG_(trampoline_stuff_start),
sewardjc6527d62006-02-13 17:54:31 +00002324 (Addr)&VG_(trampoline_stuff_end)
2325 - (Addr)&VG_(trampoline_stuff_start),
sewardj45f4e7c2005-09-27 19:20:21 +00002326 False, /* readable? */
2327 False, /* writable? */
sewardj9c606bd2008-09-18 18:12:50 +00002328 True /* executable? */,
2329 0 /* di_handle: no associated debug info */ );
tom7c1a19a2008-01-02 10:13:04 +00002330
2331 /* Clear the running thread indicator */
2332 VG_(running_tid) = VG_INVALID_THREADID;
2333 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
sewardj45f4e7c2005-09-27 19:20:21 +00002334 }
2335
2336 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002337 // Initialise the scheduler (phase 2)
2338 // p: Initialise the scheduler (phase 1) [for tid_main]
nethercote71980f02004-01-24 18:18:54 +00002339 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
sewardj45f4e7c2005-09-27 19:20:21 +00002340 // p: setup_client_stack
nethercote71980f02004-01-24 18:18:54 +00002341 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002342 VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
sewardj12ab7652006-10-17 02:10:42 +00002343 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002344 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj45f4e7c2005-09-27 19:20:21 +00002345 vg_assert(seg);
2346 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002347 vg_assert(the_iifii.initial_client_SP >= seg->start);
2348 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardjde764e82007-11-09 23:13:22 +00002349 VG_(scheduler_init_phase2)( tid_main,
2350 seg->end, the_iifii.clstack_max_size );
sewardj45f4e7c2005-09-27 19:20:21 +00002351 }
nethercote71980f02004-01-24 18:18:54 +00002352
2353 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00002354 // Set up state for the root thread
sewardjb5f6f512005-03-10 23:59:00 +00002355 // p: ?
sewardj17c11042006-10-15 01:26:40 +00002356 // setup_scheduler() [for sched-specific thread 1 stuff]
sewardjf9d2f9b2006-11-17 20:00:57 +00002357 // VG_(ii_create_image) [for 'the_iicii' initial info]
sewardj2a99cf62004-11-24 10:44:19 +00002358 //--------------------------------------------------------------
sewardjf9d2f9b2006-11-17 20:00:57 +00002359 VG_(debugLog)(1, "main", "Finalise initial image\n");
2360 VG_(ii_finalise_image)( the_iifii );
njnea4b28c2004-11-30 16:04:58 +00002361
sewardj2a99cf62004-11-24 10:44:19 +00002362 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002363 // Initialise the signal handling subsystem
sewardjb5f6f512005-03-10 23:59:00 +00002364 // p: n/a
nethercote71980f02004-01-24 18:18:54 +00002365 //--------------------------------------------------------------
2366 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
sewardj1fbc1a52005-04-25 02:05:54 +00002367 VG_(debugLog)(1, "main", "Initialise signal management\n");
njncda2f0f2009-05-18 02:12:08 +00002368 /* Check that the kernel-interface signal definitions look sane */
2369 VG_(vki_do_initial_consistency_checks)();
2370 /* .. and go on to use them. */
nethercote71980f02004-01-24 18:18:54 +00002371 VG_(sigstartup_actions)();
2372
2373 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002374 // Read suppression file
sewardj95d86c02007-12-18 01:49:23 +00002375 // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
nethercote71980f02004-01-24 18:18:54 +00002376 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00002377 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
2378 VG_(debugLog)(1, "main", "Load suppressions\n");
nethercote71980f02004-01-24 18:18:54 +00002379 VG_(load_suppressions)();
sewardj1fbc1a52005-04-25 02:05:54 +00002380 }
nethercote71980f02004-01-24 18:18:54 +00002381
2382 //--------------------------------------------------------------
rjwalsh0140af52005-06-04 20:42:33 +00002383 // register client stack
2384 //--------------------------------------------------------------
njn945ed2e2005-06-24 03:28:30 +00002385 VG_(clstk_id) = VG_(register_stack)(VG_(clstk_base), VG_(clstk_end));
rjwalsh0140af52005-06-04 20:42:33 +00002386
2387 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002388 // Show the address space state so far
2389 //--------------------------------------------------------------
2390 VG_(debugLog)(1, "main", "\n");
2391 VG_(debugLog)(1, "main", "\n");
2392 VG_(am_show_nsegments)(1,"Memory layout at client startup");
2393 VG_(debugLog)(1, "main", "\n");
2394 VG_(debugLog)(1, "main", "\n");
2395
2396 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002397 // Run!
2398 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00002399 VG_(debugLog)(1, "main", "Running thread 1\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002400
sewardj1d887112005-05-30 21:44:08 +00002401 /* As a result of the following call, the last thread standing
sewardj1ae3f3a2005-09-28 10:47:38 +00002402 eventually winds up running shutdown_actions_NORETURN
2403 just below. Unfortunately, simply exporting said function
2404 causes m_main to be part of a module cycle, which is pretty
2405 nonsensical. So instead of doing that, the address of said
2406 function is stored in a global variable 'owned' by m_syswrap,
2407 and it uses that function pointer to get back here when it needs
2408 to. */
2409
2410 /* Set continuation address. */
2411 VG_(address_of_m_main_shutdown_actions_NORETURN)
2412 = & shutdown_actions_NORETURN;
2413
2414 /* Run the first thread, eventually ending up at the continuation
2415 address. */
njnaf839f52005-06-23 03:27:57 +00002416 VG_(main_thread_wrapper_NORETURN)(1);
nethercote71980f02004-01-24 18:18:54 +00002417
sewardj1d887112005-05-30 21:44:08 +00002418 /*NOTREACHED*/
2419 vg_assert(0);
sewardjb5f6f512005-03-10 23:59:00 +00002420}
2421
sewardj17c11042006-10-15 01:26:40 +00002422/* Do everything which needs doing when the last thread exits or when
sewardj6e9de462011-06-28 07:25:29 +00002423 a thread exits requesting a complete process exit.
sewardj17c11042006-10-15 01:26:40 +00002424
2425 We enter here holding The Lock. For the case VgSrc_ExitProcess we
2426 must never release it, because to do so would allow other threads
2427 to continue after the system is ostensibly shut down. So we must
2428 go to our grave, so to speak, holding the lock.
2429
2430 In fact, there is never any point in releasing the lock at this
2431 point - we have it, we're shutting down the entire system, and
2432 for the case VgSrc_ExitProcess doing so positively causes trouble.
2433 So don't.
2434
2435 The final_tidyup call makes a bit of a nonsense of the ExitProcess
2436 case, since it will run the libc_freeres function, thus allowing
2437 other lurking threads to run again. Hmm. */
sewardjb5f6f512005-03-10 23:59:00 +00002438
sewardj1ae3f3a2005-09-28 10:47:38 +00002439static
2440void shutdown_actions_NORETURN( ThreadId tid,
2441 VgSchedReturnCode tids_schedretcode )
sewardjb5f6f512005-03-10 23:59:00 +00002442{
sewardj1d887112005-05-30 21:44:08 +00002443 VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
sewardj17c11042006-10-15 01:26:40 +00002444 VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
sewardj1d887112005-05-30 21:44:08 +00002445
sewardjb5f6f512005-03-10 23:59:00 +00002446 vg_assert(VG_(is_running_thread)(tid));
2447
sewardj12ab7652006-10-17 02:10:42 +00002448 vg_assert(tids_schedretcode == VgSrc_ExitThread
2449 || tids_schedretcode == VgSrc_ExitProcess
2450 || tids_schedretcode == VgSrc_FatalSig );
sewardjb5f6f512005-03-10 23:59:00 +00002451
sewardj12ab7652006-10-17 02:10:42 +00002452 if (tids_schedretcode == VgSrc_ExitThread) {
sewardjb5f6f512005-03-10 23:59:00 +00002453
sewardj17c11042006-10-15 01:26:40 +00002454 // We are the last surviving thread. Right?
2455 vg_assert( VG_(count_living_threads)() == 1 );
sewardjb5f6f512005-03-10 23:59:00 +00002456
sewardj17c11042006-10-15 01:26:40 +00002457 // Wait for all other threads to exit.
2458 // jrs: Huh? but they surely are already gone
2459 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002460
sewardj17c11042006-10-15 01:26:40 +00002461 // Clean the client up before the final report
2462 // this causes the libc_freeres function to run
2463 final_tidyup(tid);
2464
2465 /* be paranoid */
2466 vg_assert(VG_(is_running_thread)(tid));
2467 vg_assert(VG_(count_living_threads)() == 1);
2468
2469 } else {
2470
2471 // We may not be the last surviving thread. However, we
2472 // want to shut down the entire process. We hold the lock
2473 // and we need to keep hold of it all the way out, in order
2474 // that none of the other threads ever run again.
2475 vg_assert( VG_(count_living_threads)() >= 1 );
2476
sewardj17c11042006-10-15 01:26:40 +00002477 // Clean the client up before the final report
2478 // this causes the libc_freeres function to run
2479 // perhaps this is unsafe, as per comment above
2480 final_tidyup(tid);
2481
2482 /* be paranoid */
2483 vg_assert(VG_(is_running_thread)(tid));
2484 vg_assert(VG_(count_living_threads)() >= 1);
2485 }
sewardjb5f6f512005-03-10 23:59:00 +00002486
2487 VG_(threads)[tid].status = VgTs_Empty;
nethercote71980f02004-01-24 18:18:54 +00002488 //--------------------------------------------------------------
sewardj738856f2009-07-15 14:48:32 +00002489 // Finalisation: cleanup, messages, etc. Order not so important, only
nethercote71980f02004-01-24 18:18:54 +00002490 // affects what order the messages come.
2491 //--------------------------------------------------------------
njnb6267bd2009-08-12 00:14:16 +00002492 // First thing in the post-amble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00002493 if (VG_(clo_xml))
2494 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00002495 else if (VG_(clo_verbosity) > 0)
2496 VG_(message)(Vg_UserMsg, "\n");
nethercote71980f02004-01-24 18:18:54 +00002497
sewardj71bc3cb2005-05-19 00:25:45 +00002498 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002499 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00002500 VG_(elapsed_wallclock_time)(buf);
bartb3af9cf2011-10-06 19:08:37 +00002501 VG_(printf_xml)( "<status>\n"
sewardj738856f2009-07-15 14:48:32 +00002502 " <state>FINISHED</state>\n"
bartb3af9cf2011-10-06 19:08:37 +00002503 " <time>%pS</time>\n"
njnb6267bd2009-08-12 00:14:16 +00002504 "</status>\n"
2505 "\n",
sewardj738856f2009-07-15 14:48:32 +00002506 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00002507 }
2508
nethercote71980f02004-01-24 18:18:54 +00002509 /* Print out file descriptor summary and stats. */
2510 if (VG_(clo_track_fds))
philippec3360382012-10-21 14:37:14 +00002511 VG_(show_open_fds)("at exit");
nethercote71980f02004-01-24 18:18:54 +00002512
sewardj2d9e8742009-08-07 15:46:56 +00002513 /* Call the tool's finalisation function. This makes Memcheck's
2514 leak checker run, and possibly chuck a bunch of leak errors into
2515 the error management machinery. */
2516 VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
nethercote71980f02004-01-24 18:18:54 +00002517
sewardj2d9e8742009-08-07 15:46:56 +00002518 /* Show the error counts. */
sewardj7ca100d2009-08-15 23:05:34 +00002519 if (VG_(clo_xml)
2520 && (VG_(needs).core_errors || VG_(needs).tool_errors)) {
sewardj2d9e8742009-08-07 15:46:56 +00002521 VG_(show_error_counts_as_XML)();
sewardj738856f2009-07-15 14:48:32 +00002522 }
sewardj2d9e8742009-08-07 15:46:56 +00002523
2524 /* In XML mode, this merely prints the used suppressions. */
2525 if (VG_(needs).core_errors || VG_(needs).tool_errors)
sewardj3b290482011-05-06 21:02:55 +00002526 VG_(show_all_errors)(VG_(clo_verbosity), VG_(clo_xml));
nethercote71980f02004-01-24 18:18:54 +00002527
sewardj71bc3cb2005-05-19 00:25:45 +00002528 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00002529 VG_(printf_xml)("\n");
2530 VG_(printf_xml)("</valgrindoutput>\n");
2531 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00002532 }
2533
nethercote885dd912004-08-03 23:14:00 +00002534 VG_(sanity_check_general)( True /*include expensive checks*/ );
nethercote71980f02004-01-24 18:18:54 +00002535
sewardj2d9e8742009-08-07 15:46:56 +00002536 if (VG_(clo_stats))
nethercote3a42fb82004-08-03 18:08:50 +00002537 print_all_stats();
nethercote71980f02004-01-24 18:18:54 +00002538
sewardj9c606bd2008-09-18 18:12:50 +00002539 /* Show a profile of the heap(s) at shutdown. Optionally, first
2540 throw away all the debug info, as that makes it easy to spot
2541 leaks in the debuginfo reader. */
2542 if (VG_(clo_profile_heap)) {
2543 if (0) VG_(di_discard_ALL_debuginfo)();
2544 VG_(print_arena_cc_analysis)();
2545 }
2546
njn2025cf92005-06-26 20:44:48 +00002547 if (VG_(clo_profile_flags) > 0) {
sewardj5471ec62006-10-17 13:58:17 +00002548 #define N_MAX 200
njn2025cf92005-06-26 20:44:48 +00002549 BBProfEntry tops[N_MAX];
2550 ULong score_total = VG_(get_BB_profile) (tops, N_MAX);
2551 show_BB_profile(tops, N_MAX, score_total);
2552 }
sewardjfa8ec112005-01-19 11:55:34 +00002553
sewardj8b635a42004-11-22 19:01:47 +00002554 /* Print Vex storage stats */
sewardjbf426512005-01-17 18:35:30 +00002555 if (0)
2556 LibVEX_ShowAllocStats();
sewardj1d887112005-05-30 21:44:08 +00002557
sewardj738856f2009-07-15 14:48:32 +00002558 /* Flush any output cached by previous calls to VG_(message). */
2559 VG_(message_flush)();
2560
sewardj3b290482011-05-06 21:02:55 +00002561 /* terminate gdbserver if ever it was started. We terminate it here so that it get
2562 the output above if output was redirected to gdb */
philippe0447bbd2012-10-17 21:32:03 +00002563 VG_(gdbserver_exit) (tid, tids_schedretcode);
sewardj3b290482011-05-06 21:02:55 +00002564
njn8aa35852005-06-10 22:59:56 +00002565 /* Ok, finally exit in the os-specific way, according to the scheduler's
2566 return code. In short, if the (last) thread exited by calling
2567 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2568 signal, terminate the entire system with that same fatal signal. */
2569 VG_(debugLog)(1, "core_os",
njn7b85dd52005-06-12 17:26:29 +00002570 "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
njn8aa35852005-06-10 22:59:56 +00002571
njn8aa35852005-06-10 22:59:56 +00002572 switch (tids_schedretcode) {
sewardj12ab7652006-10-17 02:10:42 +00002573 case VgSrc_ExitThread: /* the normal way out (Linux) */
sewardj6e9de462011-06-28 07:25:29 +00002574 case VgSrc_ExitProcess: /* the normal way out (AIX) -- still needed? */
sewardjb9779082006-05-12 23:50:15 +00002575 /* Change the application return code to user's return code,
2576 if an error was found */
2577 if (VG_(clo_error_exitcode) > 0
2578 && VG_(get_n_errs_found)() > 0) {
2579 VG_(exit)( VG_(clo_error_exitcode) );
2580 } else {
2581 /* otherwise, return the client's exit code, in the normal
2582 way. */
2583 VG_(exit)( VG_(threads)[tid].os_state.exitcode );
2584 }
njn8aa35852005-06-10 22:59:56 +00002585 /* NOT ALIVE HERE! */
sewardj17c11042006-10-15 01:26:40 +00002586 VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
njn8aa35852005-06-10 22:59:56 +00002587 break; /* what the hell :) */
2588
2589 case VgSrc_FatalSig:
2590 /* We were killed by a fatal signal, so replicate the effect */
2591 vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
2592 VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
njnf76d27a2009-05-28 01:53:07 +00002593 /* we shouldn't be alive at this point. But VG_(kill_self)
2594 sometimes fails with EPERM on Darwin, for unclear reasons. */
2595# if defined(VGO_darwin)
2596 VG_(debugLog)(0, "main", "VG_(kill_self) failed. Exiting normally.\n");
2597 VG_(exit)(0); /* bogus, but we really need to exit now */
2598 /* fall through .. */
2599# endif
njn8aa35852005-06-10 22:59:56 +00002600 VG_(core_panic)("main(): signal was supposed to be fatal");
2601 break;
2602
2603 default:
2604 VG_(core_panic)("main(): unexpected scheduler return code");
2605 }
njne96be672005-05-08 19:08:54 +00002606}
sewardj8b635a42004-11-22 19:01:47 +00002607
sewardj1ae3f3a2005-09-28 10:47:38 +00002608/* -------------------- */
2609
2610/* Final clean-up before terminating the process.
2611 Clean up the client by calling __libc_freeres() (if requested)
2612 This is Linux-specific?
njnf76d27a2009-05-28 01:53:07 +00002613 GrP fixme glibc-specific, anyway
sewardj1ae3f3a2005-09-28 10:47:38 +00002614*/
2615static void final_tidyup(ThreadId tid)
2616{
njnf76d27a2009-05-28 01:53:07 +00002617#if !defined(VGO_darwin)
sewardjcf951812006-01-17 02:22:21 +00002618# if defined(VGP_ppc64_linux)
2619 Addr r2;
2620# endif
sewardj0ec07f32006-01-12 12:32:32 +00002621 Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
sewardj1ae3f3a2005-09-28 10:47:38 +00002622
2623 vg_assert(VG_(is_running_thread)(tid));
2624
2625 if ( !VG_(needs).libc_freeres ||
2626 !VG_(clo_run_libc_freeres) ||
sewardj0ec07f32006-01-12 12:32:32 +00002627 0 == __libc_freeres_wrapper )
sewardj1ae3f3a2005-09-28 10:47:38 +00002628 return; /* can't/won't do it */
2629
sewardjcf951812006-01-17 02:22:21 +00002630# if defined(VGP_ppc64_linux)
2631 r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
2632 if (r2 == 0) {
2633 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002634 "Caught __NR_exit, but can't run __libc_freeres()\n");
sewardjcf951812006-01-17 02:22:21 +00002635 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002636 " since cannot establish TOC pointer for it.\n");
sewardjcf951812006-01-17 02:22:21 +00002637 return;
2638 }
2639# endif
2640
sewardj1ae3f3a2005-09-28 10:47:38 +00002641 if (VG_(clo_verbosity) > 2 ||
2642 VG_(clo_trace_syscalls) ||
2643 VG_(clo_trace_sched))
2644 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00002645 "Caught __NR_exit; running __libc_freeres()\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002646
sewardj0ec07f32006-01-12 12:32:32 +00002647 /* set thread context to point to libc_freeres_wrapper */
sewardj1a85f4f2006-01-12 21:15:35 +00002648 /* ppc64-linux note: __libc_freeres_wrapper gives us the real
2649 function entry point, not a fn descriptor, so can use it
2650 directly. However, we need to set R2 (the toc pointer)
2651 appropriately. */
sewardj1ae3f3a2005-09-28 10:47:38 +00002652 VG_(set_IP)(tid, __libc_freeres_wrapper);
sewardjcf951812006-01-17 02:22:21 +00002653# if defined(VGP_ppc64_linux)
2654 VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
2655# endif
sewardj5db15402012-06-07 09:13:21 +00002656 /* mips-linux note: we need to set t9 */
2657# if defined(VGP_mips32_linux)
2658 VG_(threads)[tid].arch.vex.guest_r25 = __libc_freeres_wrapper;
2659# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002660
2661 /* Block all blockable signals by copying the real block state into
2662 the thread's block state*/
2663 VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
2664 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
2665
2666 /* and restore handlers to default */
2667 VG_(set_default_handler)(VKI_SIGSEGV);
2668 VG_(set_default_handler)(VKI_SIGBUS);
2669 VG_(set_default_handler)(VKI_SIGILL);
2670 VG_(set_default_handler)(VKI_SIGFPE);
2671
2672 // We were exiting, so assert that...
2673 vg_assert(VG_(is_exiting)(tid));
2674 // ...but now we're not again
2675 VG_(threads)[tid].exitreason = VgSrc_None;
2676
2677 // run until client thread exits - ideally with LIBC_FREERES_DONE,
2678 // but exit/exitgroup/signal will do
2679 VG_(scheduler)(tid);
2680
2681 vg_assert(VG_(is_exiting)(tid));
njnf76d27a2009-05-28 01:53:07 +00002682#endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002683}
2684
sewardj45f4e7c2005-09-27 19:20:21 +00002685
2686/*====================================================================*/
njn49f80e82009-05-21 01:25:43 +00002687/*=== Getting to main() alive: LINUX ===*/
sewardj45f4e7c2005-09-27 19:20:21 +00002688/*====================================================================*/
2689
sewardj17c11042006-10-15 01:26:40 +00002690#if defined(VGO_linux)
2691
sewardj45f4e7c2005-09-27 19:20:21 +00002692/* If linking of the final executables is done with glibc present,
2693 then Valgrind starts at main() above as usual, and all of the
2694 following code is irrelevant.
2695
2696 However, this is not the intended mode of use. The plan is to
2697 avoid linking against glibc, by giving gcc the flags
2698 -nodefaultlibs -lgcc -nostartfiles at startup.
2699
2700 From this derive two requirements:
2701
2702 1. gcc may emit calls to memcpy and memset to deal with structure
2703 assignments etc. Since we have chosen to ignore all the
2704 "normal" supporting libraries, we have to provide our own
2705 implementations of them. No problem.
2706
2707 2. We have to provide a symbol "_start", to which the kernel
2708 hands control at startup. Hence the code below.
2709*/
2710
2711/* ---------------- Requirement 1 ---------------- */
2712
sewardj17c11042006-10-15 01:26:40 +00002713void* memcpy(void *dest, const void *src, SizeT n);
2714void* memcpy(void *dest, const void *src, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002715 return VG_(memcpy)(dest,src,n);
2716}
sewardj17c11042006-10-15 01:26:40 +00002717void* memset(void *s, int c, SizeT n);
2718void* memset(void *s, int c, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002719 return VG_(memset)(s,c,n);
2720}
2721
bart82616e12010-06-13 13:46:24 +00002722/* BVA: abort() for those platforms that need it (PPC and ARM). */
2723void abort(void);
2724void abort(void){
2725 VG_(printf)("Something called raise().\n");
2726 vg_assert(0);
2727}
2728
sewardj59570ff2010-01-01 11:59:33 +00002729/* EAZG: ARM's EABI will call floating point exception handlers in
2730 libgcc which boil down to an abort or raise, that's usually defined
2731 in libc. Instead, define them here. */
2732#if defined(VGP_arm_linux)
2733void raise(void);
2734void raise(void){
2735 VG_(printf)("Something called raise().\n");
2736 vg_assert(0);
2737}
2738
sewardj59570ff2010-01-01 11:59:33 +00002739void __aeabi_unwind_cpp_pr0(void);
2740void __aeabi_unwind_cpp_pr0(void){
2741 VG_(printf)("Something called __aeabi_unwind_cpp_pr0()\n");
2742 vg_assert(0);
2743}
sewardj38efe4b2010-08-22 12:23:01 +00002744
2745void __aeabi_unwind_cpp_pr1(void);
2746void __aeabi_unwind_cpp_pr1(void){
2747 VG_(printf)("Something called __aeabi_unwind_cpp_pr1()\n");
2748 vg_assert(0);
2749}
sewardj59570ff2010-01-01 11:59:33 +00002750#endif
2751
sewardj45f4e7c2005-09-27 19:20:21 +00002752/* ---------------- Requirement 2 ---------------- */
2753
2754/* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2755 comment, which explains how the stack looks right at process start
2756 (when _start is jumped to). Hence _start passes %esp to
sewardj17c11042006-10-15 01:26:40 +00002757 _start_in_C_linux, which extracts argc/argv/envp and starts up
sewardj45f4e7c2005-09-27 19:20:21 +00002758 correctly. */
2759
2760/* This is the canonical entry point, usually the first thing in the text
2761 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2762 point runs, most registers' values are unspecified, except for:
2763
2764 %edx Contains a function pointer to be registered with `atexit'.
2765 This is how the dynamic linker arranges to have DT_FINI
2766 functions called for shared libraries that have been loaded
2767 before this code runs.
2768
2769 %esp The stack contains the arguments and environment:
2770 0(%esp) argc
2771 4(%esp) argv[0]
2772 ...
2773 (4*argc)(%esp) NULL
2774 (4*(argc+1))(%esp) envp[0]
2775 ...
2776 NULL
2777*/
2778
2779/* The kernel hands control to _start, which extracts the initial
sewardj17c11042006-10-15 01:26:40 +00002780 stack pointer and calls onwards to _start_in_C_linux. This also switches
sewardja48a4932005-09-29 11:09:56 +00002781 the new stack. */
sewardj45f4e7c2005-09-27 19:20:21 +00002782#if defined(VGP_x86_linux)
2783asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002784 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002785 "\t.globl _start\n"
2786 "\t.type _start,@function\n"
2787 "_start:\n"
2788 /* set up the new stack in %eax */
sewardjfdf91b42005-09-28 00:53:09 +00002789 "\tmovl $vgPlain_interim_stack, %eax\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002790 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2791 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2792 "\tsubl $16, %eax\n"
2793 "\tandl $~15, %eax\n"
2794 /* install it, and collect the original one */
2795 "\txchgl %eax, %esp\n"
sewardj17c11042006-10-15 01:26:40 +00002796 /* call _start_in_C_linux, passing it the startup %esp */
sewardj45f4e7c2005-09-27 19:20:21 +00002797 "\tpushl %eax\n"
sewardj17c11042006-10-15 01:26:40 +00002798 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002799 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002800 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002801);
2802#elif defined(VGP_amd64_linux)
2803asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002804 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002805 "\t.globl _start\n"
2806 "\t.type _start,@function\n"
2807 "_start:\n"
2808 /* set up the new stack in %rdi */
sewardjfdf91b42005-09-28 00:53:09 +00002809 "\tmovq $vgPlain_interim_stack, %rdi\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002810 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2811 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2812 "\tandq $~15, %rdi\n"
2813 /* install it, and collect the original one */
2814 "\txchgq %rdi, %rsp\n"
sewardj17c11042006-10-15 01:26:40 +00002815 /* call _start_in_C_linux, passing it the startup %rsp */
2816 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002817 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002818 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002819);
sewardja48a4932005-09-29 11:09:56 +00002820#elif defined(VGP_ppc32_linux)
2821asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002822 ".text\n"
sewardja48a4932005-09-29 11:09:56 +00002823 "\t.globl _start\n"
2824 "\t.type _start,@function\n"
2825 "_start:\n"
2826 /* set up the new stack in r16 */
2827 "\tlis 16,vgPlain_interim_stack@ha\n"
2828 "\tla 16,vgPlain_interim_stack@l(16)\n"
2829 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2830 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2831 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2832 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2833 "\tadd 16,17,16\n"
2834 "\tadd 16,18,16\n"
2835 "\trlwinm 16,16,0,0,27\n"
2836 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2837 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2838 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002839 call _start_in_C_linux, passing it the initial SP. */
sewardja48a4932005-09-29 11:09:56 +00002840 "\tmr 3,1\n"
2841 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002842 "\tbl _start_in_C_linux\n"
sewardja48a4932005-09-29 11:09:56 +00002843 "\ttrap\n"
sewardj2fedc642005-11-19 02:02:57 +00002844 ".previous\n"
sewardja48a4932005-09-29 11:09:56 +00002845);
sewardj2c48c7b2005-11-29 13:05:56 +00002846#elif defined(VGP_ppc64_linux)
2847asm("\n"
cerion21082042005-12-06 19:07:08 +00002848 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2849 So we must have one, and that is what goes into the .opd section. */
cerion297c88f2005-12-22 15:53:12 +00002850 "\t.align 2\n"
cerion21082042005-12-06 19:07:08 +00002851 "\t.global _start\n"
2852 "\t.section \".opd\",\"aw\"\n"
2853 "\t.align 3\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002854 "_start:\n"
cerion21082042005-12-06 19:07:08 +00002855 "\t.quad ._start,.TOC.@tocbase,0\n"
2856 "\t.previous\n"
2857 "\t.type ._start,@function\n"
2858 "\t.global ._start\n"
2859 "._start:\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002860 /* set up the new stack in r16 */
2861 "\tlis 16, vgPlain_interim_stack@highest\n"
2862 "\tori 16,16,vgPlain_interim_stack@higher\n"
2863 "\tsldi 16,16,32\n"
2864 "\toris 16,16,vgPlain_interim_stack@h\n"
2865 "\tori 16,16,vgPlain_interim_stack@l\n"
2866 "\txor 17,17,17\n"
2867 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2868 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2869 "\txor 18,18,18\n"
2870 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2871 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2872 "\tadd 16,17,16\n"
2873 "\tadd 16,18,16\n"
2874 "\trldicr 16,16,0,59\n"
2875 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2876 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2877 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002878 call _start_in_C_linux, passing it the initial SP. */
sewardj2c48c7b2005-11-29 13:05:56 +00002879 "\tmr 3,1\n"
2880 "\tmr 1,16\n"
sewardj5e21d442012-07-21 10:08:29 +00002881 "\tlis 14, _start_in_C_linux@highest\n"
2882 "\tori 14,14,_start_in_C_linux@higher\n"
2883 "\tsldi 14,14,32\n"
2884 "\toris 14,14,_start_in_C_linux@h\n"
2885 "\tori 14,14,_start_in_C_linux@l\n"
2886 "\tld 14,0(14)\n"
2887 "\tmtctr 14\n"
2888 "\tbctrl\n"
cerion21082042005-12-06 19:07:08 +00002889 "\tnop\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002890 "\ttrap\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002891);
sewardjb5b87402011-03-07 16:05:35 +00002892#elif defined(VGP_s390x_linux)
2893/*
2894 This is the canonical entry point, usually the first thing in the text
2895 segment. Most registers' values are unspecified, except for:
2896
2897 %r14 Contains a function pointer to be registered with `atexit'.
2898 This is how the dynamic linker arranges to have DT_FINI
2899 functions called for shared libraries that have been loaded
2900 before this code runs.
2901
2902 %r15 The stack contains the arguments and environment:
2903 0(%r15) argc
2904 8(%r15) argv[0]
2905 ...
2906 (8*argc)(%r15) NULL
2907 (8*(argc+1))(%r15) envp[0]
2908 ...
2909 NULL
2910*/
2911asm("\n\t"
2912 ".text\n\t"
2913 ".globl _start\n\t"
2914 ".type _start,@function\n\t"
2915 "_start:\n\t"
2916 /* set up the new stack in %r1 */
2917 "larl %r1, vgPlain_interim_stack\n\t"
2918 "larl %r5, 1f\n\t"
2919 "ag %r1, 0(%r5)\n\t"
2920 "ag %r1, 2f-1f(%r5)\n\t"
2921 "nill %r1, 0xFFF0\n\t"
2922 /* install it, and collect the original one */
2923 "lgr %r2, %r15\n\t"
2924 "lgr %r15, %r1\n\t"
2925 /* call _start_in_C_linux, passing it the startup %r15 */
2926 "brasl %r14, _start_in_C_linux\n\t"
2927 /* trigger execution of an invalid opcode -> halt machine */
2928 "j .+2\n\t"
2929 "1: .quad "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n\t"
2930 "2: .quad "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n\t"
2931 ".previous\n"
2932);
sewardj59570ff2010-01-01 11:59:33 +00002933#elif defined(VGP_arm_linux)
2934asm("\n"
sewardjb51c9262011-05-03 14:24:11 +00002935 "\t.text\n"
2936 "\t.align 4\n"
2937 "\t.type _start,#function\n"
sewardj59570ff2010-01-01 11:59:33 +00002938 "\t.global _start\n"
2939 "_start:\n"
2940 "\tldr r0, [pc, #36]\n"
2941 "\tldr r1, [pc, #36]\n"
2942 "\tadd r0, r1, r0\n"
2943 "\tldr r1, [pc, #32]\n"
2944 "\tadd r0, r1, r0\n"
2945 "\tmvn r1, #15\n"
2946 "\tand r0, r0, r1\n"
2947 "\tmov r1, sp\n"
2948 "\tmov sp, r0\n"
2949 "\tmov r0, r1\n"
2950 "\tb _start_in_C_linux\n"
2951 "\t.word vgPlain_interim_stack\n"
2952 "\t.word "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
2953 "\t.word "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
2954);
sewardj5db15402012-06-07 09:13:21 +00002955#elif defined(VGP_mips32_linux)
2956asm("\n"
2957 "\t.type _gp_disp,@object\n"
2958 ".text\n"
2959 "\t.globl __start\n"
2960 "\t.type __start,@function\n"
2961 "__start:\n"
2962
2963 "\tbal 1f\n"
2964 "\tnop\n"
2965
2966 "1:\n"
2967
2968 "\tlui $28, %hi(_gp_disp)\n"
2969 "\taddiu $28, $28, %lo(_gp_disp)\n"
2970 "\taddu $28, $28, $31\n"
2971 /* t1/$9 <- Addr(interim_stack) */
2972 "\tlui $9, %hi(vgPlain_interim_stack)\n"
2973 /* t1/$9 <- Addr(interim_stack) */
2974 "\taddiu $9, %lo(vgPlain_interim_stack)\n"
2975
2976
2977 "\tli $10, "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
2978 "\tli $11, "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
2979
2980 "\taddu $9, $9, $10\n"
2981 "\taddu $9, $9, $11\n"
2982 "\tli $12, 0xFFFFFFF0\n"
2983 "\tand $9, $9, $12\n"
2984 /* now t1/$9 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2985 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2986 boundary. And $29 is the original SP. Set the SP to t1 and
2987 call _start_in_C, passing it the initial SP. */
2988
2989 "\tmove $4, $29\n" // a0 <- $sp (_start_in_C first arg)
2990 "\tmove $29, $9\n" // $sp <- t1 (new sp)
2991
2992 "\tlui $25, %hi(_start_in_C_linux)\n"
2993 "\taddiu $25, %lo(_start_in_C_linux)\n"
2994
2995 "\tbal _start_in_C_linux\n"
2996 "\tbreak 0x7\n"
2997 ".previous\n"
2998);
sewardj45f4e7c2005-09-27 19:20:21 +00002999#else
njn49f80e82009-05-21 01:25:43 +00003000# error "Unknown linux platform"
sewardj45f4e7c2005-09-27 19:20:21 +00003001#endif
3002
sewardje66f2e02006-12-30 17:45:08 +00003003/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
3004#define _GNU_SOURCE
3005#define _FILE_OFFSET_BITS 64
3006/* This is in order to get AT_NULL and AT_PAGESIZE. */
3007#include <elf.h>
3008/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
3009
sewardj45f4e7c2005-09-27 19:20:21 +00003010/* Avoid compiler warnings: this fn _is_ used, but labelling it
philippe9fdca562012-04-16 22:06:47 +00003011 'static' causes gcc to complain it isn't.
3012 attribute 'used' also ensures the code is not eliminated at link
3013 time */
3014__attribute__ ((used))
sewardj17c11042006-10-15 01:26:40 +00003015void _start_in_C_linux ( UWord* pArgc );
philippe9fdca562012-04-16 22:06:47 +00003016__attribute__ ((used))
sewardj17c11042006-10-15 01:26:40 +00003017void _start_in_C_linux ( UWord* pArgc )
sewardj45f4e7c2005-09-27 19:20:21 +00003018{
3019 Int r;
3020 Word argc = pArgc[0];
3021 HChar** argv = (HChar**)&pArgc[1];
3022 HChar** envp = (HChar**)&pArgc[1+argc+1];
sewardjf9d2f9b2006-11-17 20:00:57 +00003023
3024 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
3025 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
3026
3027 the_iicii.sp_at_startup = (Addr)pArgc;
3028
sewardje66f2e02006-12-30 17:45:08 +00003029# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
3030 {
3031 /* ppc/ppc64 can be configured with different page sizes.
3032 Determine this early. This is an ugly hack and really should
3033 be moved into valgrind_main. */
3034 UWord *sp = &pArgc[1+argc+1];
3035 while (*sp++ != 0)
3036 ;
3037 for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
3038 if (*sp == AT_PAGESZ) {
3039 VKI_PAGE_SIZE = sp[1];
3040 for (VKI_PAGE_SHIFT = 12;
3041 VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
3042 if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
3043 break;
3044 }
3045 }
3046# endif
3047
sewardjf9d2f9b2006-11-17 20:00:57 +00003048 r = valgrind_main( (Int)argc, argv, envp );
sewardj17c11042006-10-15 01:26:40 +00003049 /* NOTREACHED */
sewardj45f4e7c2005-09-27 19:20:21 +00003050 VG_(exit)(r);
3051}
3052
sewardj17c11042006-10-15 01:26:40 +00003053
3054/*====================================================================*/
njnf76d27a2009-05-28 01:53:07 +00003055/*=== Getting to main() alive: darwin ===*/
3056/*====================================================================*/
3057
3058#elif defined(VGO_darwin)
3059
njnea2d6fd2010-07-01 00:20:20 +00003060/*
3061 Memory layout established by kernel:
3062
3063 0(%esp) argc
3064 4(%esp) argv[0]
3065 ...
3066 argv[argc-1]
3067 NULL
3068 envp[0]
3069 ...
3070 envp[n]
3071 NULL
3072 executable name (presumably, a pointer to it)
3073 NULL
3074
3075 Ditto in the 64-bit case, except all offsets from SP are obviously
3076 twice as large.
3077*/
3078
3079/* The kernel hands control to _start, which extracts the initial
3080 stack pointer and calls onwards to _start_in_C_darwin. This also
3081 switches to the new stack. */
3082#if defined(VGP_x86_darwin)
3083asm("\n"
3084 ".text\n"
3085 ".align 2,0x90\n"
3086 "\t.globl __start\n"
3087 "__start:\n"
3088 /* set up the new stack in %eax */
3089 "\tmovl $_vgPlain_interim_stack, %eax\n"
3090 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
3091 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
3092 "\tsubl $16, %eax\n"
3093 "\tandl $~15, %eax\n"
3094 /* install it, and collect the original one */
3095 "\txchgl %eax, %esp\n"
sewardj69197362012-03-07 16:38:12 +00003096 "\tsubl $12, %esp\n" // keep stack 16 aligned; see #295428
njnea2d6fd2010-07-01 00:20:20 +00003097 /* call _start_in_C_darwin, passing it the startup %esp */
3098 "\tpushl %eax\n"
3099 "\tcall __start_in_C_darwin\n"
3100 "\tint $3\n"
3101 "\tint $3\n"
3102);
3103#elif defined(VGP_amd64_darwin)
3104asm("\n"
3105 ".text\n"
3106 "\t.globl __start\n"
3107 ".align 3,0x90\n"
3108 "__start:\n"
3109 /* set up the new stack in %rdi */
3110 "\tmovabsq $_vgPlain_interim_stack, %rdi\n"
3111 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
3112 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
3113 "\tandq $~15, %rdi\n"
3114 /* install it, and collect the original one */
3115 "\txchgq %rdi, %rsp\n"
3116 /* call _start_in_C_darwin, passing it the startup %rsp */
3117 "\tcall __start_in_C_darwin\n"
3118 "\tint $3\n"
3119 "\tint $3\n"
3120);
3121#endif
3122
njnf76d27a2009-05-28 01:53:07 +00003123void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2);
3124void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2) {
3125 // skip check
3126 return VG_(memcpy)(dest,src,n);
3127}
3128void* __memset_chk(void *s, int c, SizeT n, SizeT n2);
3129void* __memset_chk(void *s, int c, SizeT n, SizeT n2) {
3130 // skip check
3131 return VG_(memset)(s,c,n);
3132}
3133void bzero(void *s, SizeT n);
3134void bzero(void *s, SizeT n) {
3135 VG_(memset)(s,0,n);
3136}
3137
3138void* memcpy(void *dest, const void *src, SizeT n);
3139void* memcpy(void *dest, const void *src, SizeT n) {
3140 return VG_(memcpy)(dest,src,n);
3141}
3142void* memset(void *s, int c, SizeT n);
3143void* memset(void *s, int c, SizeT n) {
3144 return VG_(memset)(s,c,n);
3145}
3146
njnf76d27a2009-05-28 01:53:07 +00003147/* Avoid compiler warnings: this fn _is_ used, but labelling it
3148 'static' causes gcc to complain it isn't. */
3149void _start_in_C_darwin ( UWord* pArgc );
3150void _start_in_C_darwin ( UWord* pArgc )
3151{
3152 Int r;
njnea2d6fd2010-07-01 00:20:20 +00003153 Int argc = *(Int *)pArgc; // not pArgc[0] on LP64
njnf76d27a2009-05-28 01:53:07 +00003154 HChar** argv = (HChar**)&pArgc[1];
3155 HChar** envp = (HChar**)&pArgc[1+argc+1];
3156
3157 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
3158 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
3159
3160 the_iicii.sp_at_startup = (Addr)pArgc;
3161
3162 r = valgrind_main( (Int)argc, argv, envp );
3163 /* NOTREACHED */
3164 VG_(exit)(r);
3165}
3166
3167
njn49f80e82009-05-21 01:25:43 +00003168#else
3169
3170# error "Unknown OS"
3171#endif
sewardj17c11042006-10-15 01:26:40 +00003172
3173
sewardj0af71bb2010-07-01 14:50:30 +00003174/*====================================================================*/
3175/*=== {u,}{div,mod}di3 replacements ===*/
3176/*====================================================================*/
njnea2d6fd2010-07-01 00:20:20 +00003177
3178/* For static linking on x86-darwin, we need to supply our own 64-bit
3179 integer division code, else the link dies thusly:
3180
3181 ld_classic: Undefined symbols:
3182 ___udivdi3
3183 ___umoddi3
3184*/
3185#if defined(VGP_x86_darwin)
3186
3187/* Routines for doing signed/unsigned 64 x 64 ==> 64 div and mod
3188 (udivdi3, umoddi3, divdi3, moddi3) using only 32 x 32 ==> 32
3189 division. Cobbled together from
3190
3191 http://www.hackersdelight.org/HDcode/divlu.c
3192 http://www.hackersdelight.org/HDcode/divls.c
3193 http://www.hackersdelight.org/HDcode/newCode/divDouble.c
3194
3195 The code from those three files is covered by the following license,
3196 as it appears at:
3197
3198 http://www.hackersdelight.org/permissions.htm
3199
3200 You are free to use, copy, and distribute any of the code on
3201 this web site, whether modified by you or not. You need not give
3202 attribution. This includes the algorithms (some of which appear
3203 in Hacker's Delight), the Hacker's Assistant, and any code
3204 submitted by readers. Submitters implicitly agree to this.
3205*/
3206
3207/* Long division, unsigned (64/32 ==> 32).
3208 This procedure performs unsigned "long division" i.e., division of a
320964-bit unsigned dividend by a 32-bit unsigned divisor, producing a
321032-bit quotient. In the overflow cases (divide by 0, or quotient
3211exceeds 32 bits), it returns a remainder of 0xFFFFFFFF (an impossible
3212value).
3213 The dividend is u1 and u0, with u1 being the most significant word.
3214The divisor is parameter v. The value returned is the quotient.
3215 Max line length is 57, to fit in hacker.book. */
3216
3217static Int nlz32(UInt x)
3218{
3219 Int n;
3220 if (x == 0) return(32);
3221 n = 0;
3222 if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
3223 if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
3224 if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
3225 if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
3226 if (x <= 0x7FFFFFFF) {n = n + 1;}
3227 return n;
3228}
3229
3230/* 64 x 32 ==> 32 unsigned division, using only 32 x 32 ==> 32
3231 division as a primitive. */
3232static UInt divlu2(UInt u1, UInt u0, UInt v, UInt *r)
3233{
3234 const UInt b = 65536; // Number base (16 bits).
3235 UInt un1, un0, // Norm. dividend LSD's.
3236 vn1, vn0, // Norm. divisor digits.
3237 q1, q0, // Quotient digits.
3238 un32, un21, un10, // Dividend digit pairs.
3239 rhat; // A remainder.
3240 Int s; // Shift amount for norm.
3241
3242 if (u1 >= v) { // If overflow, set rem.
3243 if (r != NULL) // to an impossible value,
3244 *r = 0xFFFFFFFF; // and return the largest
3245 return 0xFFFFFFFF;} // possible quotient.
3246
3247 s = nlz32(v); // 0 <= s <= 31.
3248 v = v << s; // Normalize divisor.
3249 vn1 = v >> 16; // Break divisor up into
3250 vn0 = v & 0xFFFF; // two 16-bit digits.
3251
3252 un32 = (u1 << s) | ((u0 >> (32 - s)) & (-s >> 31));
3253 un10 = u0 << s; // Shift dividend left.
3254
3255 un1 = un10 >> 16; // Break right half of
3256 un0 = un10 & 0xFFFF; // dividend into two digits.
3257
3258 q1 = un32/vn1; // Compute the first
3259 rhat = un32 - q1*vn1; // quotient digit, q1.
3260 again1:
3261 if (q1 >= b || q1*vn0 > b*rhat + un1) {
3262 q1 = q1 - 1;
3263 rhat = rhat + vn1;
3264 if (rhat < b) goto again1;}
3265
3266 un21 = un32*b + un1 - q1*v; // Multiply and subtract.
3267
3268 q0 = un21/vn1; // Compute the second
3269 rhat = un21 - q0*vn1; // quotient digit, q0.
3270 again2:
3271 if (q0 >= b || q0*vn0 > b*rhat + un0) {
3272 q0 = q0 - 1;
3273 rhat = rhat + vn1;
3274 if (rhat < b) goto again2;}
3275
3276 if (r != NULL) // If remainder is wanted,
3277 *r = (un21*b + un0 - q0*v) >> s; // return it.
3278 return q1*b + q0;
3279}
3280
3281
3282/* 64 x 32 ==> 32 signed division, using only 32 x 32 ==> 32 division
3283 as a primitive. */
3284static Int divls(Int u1, UInt u0, Int v, Int *r)
3285{
3286 Int q, uneg, vneg, diff, borrow;
3287
3288 uneg = u1 >> 31; // -1 if u < 0.
3289 if (uneg) { // Compute the absolute
3290 u0 = -u0; // value of the dividend u.
3291 borrow = (u0 != 0);
3292 u1 = -u1 - borrow;}
3293
3294 vneg = v >> 31; // -1 if v < 0.
3295 v = (v ^ vneg) - vneg; // Absolute value of v.
3296
3297 if ((UInt)u1 >= (UInt)v) goto overflow;
3298
3299 q = divlu2(u1, u0, v, (UInt *)r);
3300
3301 diff = uneg ^ vneg; // Negate q if signs of
3302 q = (q ^ diff) - diff; // u and v differed.
3303 if (uneg && r != NULL)
3304 *r = -*r;
3305
3306 if ((diff ^ q) < 0 && q != 0) { // If overflow,
3307 overflow: // set remainder
3308 if (r != NULL) // to an impossible value,
3309 *r = 0x80000000; // and return the largest
3310 q = 0x80000000;} // possible neg. quotient.
3311 return q;
3312}
3313
3314
3315
3316/* This file contains a program for doing 64/64 ==> 64 division, on a
3317machine that does not have that instruction but that does have
3318instructions for "long division" (64/32 ==> 32). Code for unsigned
3319division is given first, followed by a simple program for doing the
3320signed version by using the unsigned version.
3321 These programs are useful in implementing "long long" (64-bit)
3322arithmetic on a machine that has the long division instruction. It will
3323work on 64- and 32-bit machines, provided the compiler implements long
3324long's (64-bit integers). It is desirable that the machine have the
3325Count Leading Zeros instruction.
3326 In the GNU world, these programs are known as __divdi3 and __udivdi3,
3327and similar names are used here.
3328 This material is not in HD, but may be in a future edition.
3329Max line length is 57, to fit in hacker.book. */
3330
3331
3332static Int nlz64(ULong x)
3333{
3334 Int n;
3335 if (x == 0) return(64);
3336 n = 0;
3337 if (x <= 0x00000000FFFFFFFFULL) {n = n + 32; x = x << 32;}
3338 if (x <= 0x0000FFFFFFFFFFFFULL) {n = n + 16; x = x << 16;}
3339 if (x <= 0x00FFFFFFFFFFFFFFULL) {n = n + 8; x = x << 8;}
3340 if (x <= 0x0FFFFFFFFFFFFFFFULL) {n = n + 4; x = x << 4;}
3341 if (x <= 0x3FFFFFFFFFFFFFFFULL) {n = n + 2; x = x << 2;}
3342 if (x <= 0x7FFFFFFFFFFFFFFFULL) {n = n + 1;}
3343 return n;
3344}
3345
3346// ---------------------------- udivdi3 --------------------------------
3347
3348 /* The variables u0, u1, etc. take on only 32-bit values, but they
3349 are declared long long to avoid some compiler warning messages and to
3350 avoid some unnecessary EXTRs that the compiler would put in, to
3351 convert long longs to ints.
3352
3353 First the procedure takes care of the case in which the divisor is a
3354 32-bit quantity. There are two subcases: (1) If the left half of the
3355 dividend is less than the divisor, one execution of DIVU is all that
3356 is required (overflow is not possible). (2) Otherwise it does two
3357 divisions, using the grade school method, with variables used as
3358 suggested below.
3359
3360 q1 q0
3361 ________
3362 v) u1 u0
3363 q1*v
3364 ____
3365 k u0 */
3366
3367/* These macros must be used with arguments of the appropriate type
3368(unsigned long long for DIVU and long long for DIVS. They are
3369simulations of the presumed machines ops. I.e., they look at only the
3370low-order 32 bits of the divisor, they return garbage if the division
3371overflows, and they return garbage in the high-order half of the
3372quotient doubleword.
3373 In practice, these would be replaced with uses of the machine's DIVU
3374and DIVS instructions (e.g., by using the GNU "asm" facility). */
3375
3376static UInt DIVU ( ULong u, UInt v )
3377{
3378 UInt uHi = (UInt)(u >> 32);
3379 UInt uLo = (UInt)u;
3380 return divlu2(uHi, uLo, v, NULL);
3381}
3382
3383static Int DIVS ( Long u, Int v )
3384{
3385 Int uHi = (Int)(u >> 32);
3386 UInt uLo = (UInt)u;
3387 return divls(uHi, uLo, v, NULL);
3388}
3389
3390/* 64 x 64 ==> 64 unsigned division, using only 32 x 32 ==> 32
3391 division as a primitive. */
3392static ULong udivdi3(ULong u, ULong v)
3393{
3394 ULong u0, u1, v1, q0, q1, k, n;
3395
3396 if (v >> 32 == 0) { // If v < 2**32:
3397 if (u >> 32 < v) // If u/v cannot overflow,
3398 return DIVU(u, v) // just do one division.
3399 & 0xFFFFFFFF;
3400 else { // If u/v would overflow:
3401 u1 = u >> 32; // Break u up into two
3402 u0 = u & 0xFFFFFFFF; // halves.
3403 q1 = DIVU(u1, v) // First quotient digit.
3404 & 0xFFFFFFFF;
3405 k = u1 - q1*v; // First remainder, < v.
3406 q0 = DIVU((k << 32) + u0, v) // 2nd quot. digit.
3407 & 0xFFFFFFFF;
3408 return (q1 << 32) + q0;
3409 }
3410 }
3411 // Here v >= 2**32.
3412 n = nlz64(v); // 0 <= n <= 31.
3413 v1 = (v << n) >> 32; // Normalize the divisor
3414 // so its MSB is 1.
3415 u1 = u >> 1; // To ensure no overflow.
3416 q1 = DIVU(u1, v1) // Get quotient from
3417 & 0xFFFFFFFF; // divide unsigned insn.
3418 q0 = (q1 << n) >> 31; // Undo normalization and
3419 // division of u by 2.
3420 if (q0 != 0) // Make q0 correct or
3421 q0 = q0 - 1; // too small by 1.
3422 if ((u - q0*v) >= v)
3423 q0 = q0 + 1; // Now q0 is correct.
3424 return q0;
3425}
3426
3427
3428// ----------------------------- divdi3 --------------------------------
3429
3430/* This routine presumes that smallish cases (those which can be done in
3431one execution of DIVS) are common. If this is not the case, the test for
3432this case should be deleted.
3433 Note that the test for when DIVS can be used is not entirely
3434accurate. For example, DIVS is not used if v = 0xFFFFFFFF8000000,
3435whereas if could be (if u is sufficiently small in magnitude). */
3436
3437// ------------------------------ cut ----------------------------------
3438
3439static ULong my_llabs ( Long x )
3440{
3441 ULong t = x >> 63;
3442 return (x ^ t) - t;
3443}
3444
3445/* 64 x 64 ==> 64 signed division, using only 32 x 32 ==> 32 division
3446 as a primitive. */
3447static Long divdi3(Long u, Long v)
3448{
3449 ULong au, av;
3450 Long q, t;
3451 au = my_llabs(u);
3452 av = my_llabs(v);
3453 if (av >> 31 == 0) { // If |v| < 2**31 and
3454 // if (v << 32 >> 32 == v) { // If v is in range and
3455 if (au < av << 31) { // |u|/|v| cannot
3456 q = DIVS(u, v); // overflow, use DIVS.
3457 return (q << 32) >> 32;
3458 }
3459 }
3460 q = udivdi3(au,av); // Invoke udivdi3.
3461 t = (u ^ v) >> 63; // If u, v have different
3462 return (q ^ t) - t; // signs, negate q.
3463}
3464
3465// ---------------------------- end cut --------------------------------
3466
sewardj0af71bb2010-07-01 14:50:30 +00003467ULong __udivdi3 (ULong u, ULong v);
njnea2d6fd2010-07-01 00:20:20 +00003468ULong __udivdi3 (ULong u, ULong v)
3469{
3470 return udivdi3(u,v);
3471}
3472
sewardj0af71bb2010-07-01 14:50:30 +00003473Long __divdi3 (Long u, Long v);
njnea2d6fd2010-07-01 00:20:20 +00003474Long __divdi3 (Long u, Long v)
3475{
3476 return divdi3(u,v);
3477}
3478
sewardj0af71bb2010-07-01 14:50:30 +00003479ULong __umoddi3 (ULong u, ULong v);
njnea2d6fd2010-07-01 00:20:20 +00003480ULong __umoddi3 (ULong u, ULong v)
3481{
3482 ULong q = __udivdi3(u, v);
3483 ULong r = u - q * v;
3484 return r;
3485}
3486
sewardj0af71bb2010-07-01 14:50:30 +00003487Long __moddi3 (Long u, Long v);
njnea2d6fd2010-07-01 00:20:20 +00003488Long __moddi3 (Long u, Long v)
3489{
3490 Long q = __divdi3(u, v);
3491 Long r = u - q * v;
3492 return r;
3493}
3494
sewardj70d71c72011-08-23 07:35:42 +00003495/* ------------------------------------------------
3496 ld_classic: Undefined symbols:
3497 ___fixunsdfdi
3498 ------------------------------------------------
3499*/
3500
3501/* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------===
3502 *
3503 * The LLVM Compiler Infrastructure
3504 *
3505 * This file is dual licensed under the MIT and the University of Illinois Open
3506 * Source Licenses. See LICENSE.TXT for details.
3507 *
3508 * ===----------------------------------------------------------------------===
3509 *
3510 * This file implements __fixunsdfdi for the compiler_rt library.
3511 *
3512 * ===----------------------------------------------------------------------===
3513 */
3514
3515/* As per http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses,
3516
3517 the "NCSA/University of Illinois Open Source License" is compatible
3518 with the GPL (both version 2 and 3). What is claimed to be
3519 compatible is this
3520
3521 http://www.opensource.org/licenses/UoI-NCSA.php
3522
3523 and the LLVM documentation at
3524
3525 http://www.llvm.org/docs/DeveloperPolicy.html#license
3526
3527 says all the code in LLVM is available under the University of
3528 Illinois/NCSA Open Source License, at this URL
3529
3530 http://www.opensource.org/licenses/UoI-NCSA.php
3531
3532 viz, the same one that the FSF pages claim is compatible. So I
3533 think it's OK to include it.
3534*/
3535
3536/* Returns: convert a to a unsigned long long, rounding toward zero.
3537 * Negative values all become zero.
3538 */
3539
3540/* Assumption: double is a IEEE 64 bit floating point type
3541 * du_int is a 64 bit integral type
3542 * value in double is representable in du_int or is negative
3543 * (no range checking performed)
3544 */
3545
3546/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
3547
3548typedef unsigned long long du_int;
3549typedef unsigned su_int;
3550
3551typedef union
3552{
3553 du_int all;
3554 struct
3555 {
3556#if VG_LITTLEENDIAN
3557 su_int low;
3558 su_int high;
3559#else
3560 su_int high;
3561 su_int low;
3562#endif /* VG_LITTLEENDIAN */
3563 }s;
3564} udwords;
3565
3566typedef union
3567{
3568 udwords u;
3569 double f;
3570} double_bits;
3571
3572du_int __fixunsdfdi(double a);
3573
3574du_int
3575__fixunsdfdi(double a)
3576{
3577 double_bits fb;
3578 fb.f = a;
3579 int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
3580 if (e < 0 || (fb.u.s.high & 0x80000000))
3581 return 0;
3582 udwords r;
3583 r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
3584 r.s.low = fb.u.s.low;
3585 if (e > 52)
3586 r.all <<= (e - 52);
3587 else
3588 r.all >>= (52 - e);
3589 return r.all;
3590}
3591
3592
njnea2d6fd2010-07-01 00:20:20 +00003593#endif
3594
3595
sewardjde4a1d02002-03-22 01:27:54 +00003596/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00003597/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00003598/*--------------------------------------------------------------------*/