blob: ca82eb473b5ca7a69d556893a7f26aea2cdf3caf [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
sewardj9eecbbb2010-05-03 21:37:12 +000010 Copyright (C) 2000-2010 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"
sewardj17c11042006-10-15 01:26:40 +000068
sewardjb5f6f512005-03-10 23:59:00 +000069
nethercote71980f02004-01-24 18:18:54 +000070/*====================================================================*/
71/*=== Counters, for profiling purposes only ===*/
72/*====================================================================*/
sewardjde4a1d02002-03-22 01:27:54 +000073
nethercote3a42fb82004-08-03 18:08:50 +000074static void print_all_stats ( void )
nethercote71980f02004-01-24 18:18:54 +000075{
njn42c83552005-12-05 20:45:59 +000076 VG_(print_translation_stats)();
nethercote92e7b7f2004-08-07 17:52:25 +000077 VG_(print_tt_tc_stats)();
nethercote844e7122004-08-02 15:27:22 +000078 VG_(print_scheduler_stats)();
njn9271cbc2005-03-13 05:38:25 +000079 VG_(print_ExeContext_stats)();
sewardj12ab7652006-10-17 02:10:42 +000080 VG_(print_errormgr_stats)();
njn9271cbc2005-03-13 05:38:25 +000081
nethercote3a42fb82004-08-03 18:08:50 +000082 // Memory stats
nethercote885dd912004-08-03 23:14:00 +000083 if (VG_(clo_verbosity) > 2) {
sewardj738856f2009-07-15 14:48:32 +000084 VG_(message)(Vg_DebugMsg, "\n");
nethercote3a42fb82004-08-03 18:08:50 +000085 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +000086 "------ Valgrind's internal memory use stats follow ------\n" );
nethercote885dd912004-08-03 23:14:00 +000087 VG_(sanity_check_malloc_all)();
sewardj738856f2009-07-15 14:48:32 +000088 VG_(message)(Vg_DebugMsg, "------\n" );
nethercote3a42fb82004-08-03 18:08:50 +000089 VG_(print_all_arena_stats)();
sewardj738856f2009-07-15 14:48:32 +000090 VG_(message)(Vg_DebugMsg, "\n");
nethercote3a42fb82004-08-03 18:08:50 +000091 }
nethercote71980f02004-01-24 18:18:54 +000092}
93
94
95/*====================================================================*/
sewardj71bc3cb2005-05-19 00:25:45 +000096/*=== Command-line: variables, processing, etc ===*/
97/*====================================================================*/
98
99// See pub_{core,tool}_options.h for explanations of all these.
100
sewardj45f4e7c2005-09-27 19:20:21 +0000101static void usage_NORETURN ( Bool debug_help )
njn7cf0bd32002-06-08 13:36:03 +0000102{
sewardj7839d112007-11-20 19:45:03 +0000103 /* 'usage1' contains a %s for the name of the GDB executable, which
104 must be supplied when it is VG_(printf)'d. */
njn25e49d8e72002-09-23 09:36:25 +0000105 Char* usage1 =
njn00cfcfc2005-11-12 18:53:50 +0000106"usage: valgrind [options] prog-and-args\n"
njn25e49d8e72002-09-23 09:36:25 +0000107"\n"
njn97db7612009-08-04 02:32:55 +0000108" tool-selection option, with default in [ ]:\n"
sewardjb5f6f512005-03-10 23:59:00 +0000109" --tool=<name> use the Valgrind tool named <name> [memcheck]\n"
njn97db7612009-08-04 02:32:55 +0000110"\n"
111" basic user options for all Valgrind tools, with defaults in [ ]:\n"
nethercotea76368b2004-06-16 11:56:29 +0000112" -h --help show this message\n"
nethercote6c999f22004-01-31 22:55:15 +0000113" --help-debug show this message, plus debugging options\n"
njn25e49d8e72002-09-23 09:36:25 +0000114" --version show version\n"
njn25e49d8e72002-09-23 09:36:25 +0000115" -q --quiet run silently; only print error msgs\n"
sewardj2d9e8742009-08-07 15:46:56 +0000116" -v --verbose be more verbose -- show misc extra info\n"
sewardj6e31f802007-11-17 22:29:25 +0000117" --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]\n"
sewardj06421272009-11-05 08:55:13 +0000118" --trace-children-skip=patt1,patt2,... specifies a list of executables\n"
119" that --trace-children=yes should not trace into\n"
sewardj9ab64a42010-12-06 11:40:04 +0000120" --trace-children-skip-by-arg=patt1,patt2,... same as --trace-children-skip=\n"
121" but check the argv[] entries for children, rather\n"
122" than the exe name, to make a follow/no-follow decision\n"
njn97db7612009-08-04 02:32:55 +0000123" --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n"
sewardj3b290482011-05-06 21:02:55 +0000124" --vgdb=no|yes|full activate gdbserver? [yes]\n"
125" full is slower but provides precise watchpoint/step\n"
sewardj1568e172011-06-18 08:28:04 +0000126" --vgdb-error=<number> invoke gdbserver after <number> errors [%d]\n"
127" to get started quickly, use --vgdb-error=0\n"
128" and follow the on-screen directions\n"
nethercote0d588502004-06-21 13:27:11 +0000129" --track-fds=no|yes track open file descriptors? [no]\n"
thughes6233a382004-08-21 11:10:44 +0000130" --time-stamp=no|yes add timestamps to log messages? [no]\n"
njnce545552005-07-25 22:36:52 +0000131" --log-fd=<number> log messages to file descriptor [2=stderr]\n"
njn374a36d2007-11-23 01:41:32 +0000132" --log-file=<file> log messages to <file>\n"
njnce545552005-07-25 22:36:52 +0000133" --log-socket=ipaddr:port log messages to socket ipaddr:port\n"
nethercote2b0793f2003-12-02 10:41:18 +0000134"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000135" user options for Valgrind tools that report errors:\n"
sewardj738856f2009-07-15 14:48:32 +0000136" --xml=yes emit error output in XML (some tools only)\n"
137" --xml-fd=<number> XML output to file descriptor\n"
138" --xml-file=<file> XML output to <file>\n"
139" --xml-socket=ipaddr:port XML output to socket ipaddr:port\n"
140" --xml-user-comment=STR copy STR verbatim into XML output\n"
nethercote2b0793f2003-12-02 10:41:18 +0000141" --demangle=no|yes automatically demangle C++ names? [yes]\n"
njn20b4a152005-10-19 22:39:40 +0000142" --num-callers=<number> show <number> callers in stack traces [12]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000143" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
sewardjb9779082006-05-12 23:50:15 +0000144" --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000145" --show-below-main=no|yes continue stack traces below main() [no]\n"
146" --suppressions=<filename> suppress errors described in <filename>\n"
sewardjd153fae2005-01-10 17:24:47 +0000147" --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000148" --db-attach=no|yes start debugger when errors detected? [no]\n"
sewardj7839d112007-11-20 19:45:03 +0000149" --db-command=<command> command to start debugger [%s -nw %%f %%p]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000150" --input-fd=<number> file descriptor for input [0=stdin]\n"
njn97db7612009-08-04 02:32:55 +0000151" --dsymutil=no|yes run dsymutil on Mac OS X when helpful? [no]\n"
sewardj97724e52005-04-02 23:40:59 +0000152" --max-stackframe=<number> assume stack switch for SP changes larger\n"
153" than <number> bytes [2000000]\n"
sewardj95d86c02007-12-18 01:49:23 +0000154" --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
155" [use current 'ulimit' value]\n"
njn97db7612009-08-04 02:32:55 +0000156"\n"
157" user options for Valgrind tools that replace malloc:\n"
158" --alignment=<number> set minimum alignment of heap allocations [%ld]\n"
159"\n"
160" uncommon user options for all Valgrind tools:\n"
sewardj14cdbf82010-10-12 00:44:05 +0000161" --fullpath-after= (with nothing after the '=')\n"
162" show full source paths in call stacks\n"
163" --fullpath-after=string like --fullpath-after=, but only show the\n"
164" part of the path after 'string'. Allows removal\n"
165" of path prefixes. Use this flag multiple times\n"
166" to specify a set of prefixes to remove.\n"
sewardj6dbcc632011-06-07 21:39:28 +0000167" --smc-check=none|stack|all|all-non-file [stack]\n"
168" checks for self-modifying code: none, only for\n"
169" code found in stacks, for all code, or for all\n"
170" code except that from file-backed mappings\n"
njn97db7612009-08-04 02:32:55 +0000171" --read-var-info=yes|no read debug info on stack and global variables\n"
172" and use it to print better error messages in\n"
173" tools that make use of it (Memcheck, Helgrind,\n"
bartf6122a02010-03-27 07:38:39 +0000174" DRD) [no]\n"
sewardj3b290482011-05-06 21:02:55 +0000175" --vgdb-poll=<number> gdbserver poll max every <number> basic blocks [%d] \n"
176" --vgdb-shadow-registers=no|yes let gdb see the shadow registers [no]\n"
177" --vgdb-prefix=<prefix> prefix for vgdb FIFOs [%s]\n"
njn97db7612009-08-04 02:32:55 +0000178" --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
179" --sim-hints=hint1,hint2,... known hints:\n"
sewardjcc3de2d2011-08-18 15:08:20 +0000180" lax-ioctls, enable-outer, fuse-compatible [none]\n"
njn97db7612009-08-04 02:32:55 +0000181" --kernel-variant=variant1,variant2,... known variants: bproc [none]\n"
182" handle non-standard kernel variants\n"
183" --show-emwarns=no|yes show warnings about emulation limits? [no]\n"
sewardjf9ebc392010-05-09 22:30:43 +0000184" --require-text-symbol=:sonamepattern:symbolpattern abort run if the\n"
185" stated shared object doesn't have the stated\n"
186" text symbol. Patterns can contain ? and *.\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000187"\n";
njn7cf0bd32002-06-08 13:36:03 +0000188
njn25e49d8e72002-09-23 09:36:25 +0000189 Char* usage2 =
190"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000191" debugging options for all Valgrind tools:\n"
njn97db7612009-08-04 02:32:55 +0000192" -d show verbose debugging output\n"
njnb1cc5d62010-07-06 04:05:23 +0000193" --stats=no|yes show tool and core statistics [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000194" --sanity-level=<number> level of sanity checking to do [1]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000195" --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
196" --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
sewardj33afdb52006-01-17 02:36:40 +0000197" --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
njn25e49d8e72002-09-23 09:36:25 +0000198" --trace-syscalls=no|yes show all system calls? [no]\n"
199" --trace-signals=no|yes show signal handling details? [no]\n"
200" --trace-symtab=no|yes show symbol table details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000201" --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
sewardjce058b02005-05-01 08:55:38 +0000202" --trace-cfi=no|yes show call-frame-info details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000203" --debug-dump=syms mimic /usr/bin/readelf --syms\n"
204" --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
205" --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
sewardj0ec07f32006-01-12 12:32:32 +0000206" --trace-redir=no|yes show redirection details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000207" --trace-sched=no|yes show thread scheduler details? [no]\n"
sewardj9c606bd2008-09-18 18:12:50 +0000208" --profile-heap=no|yes profile Valgrind's own space use\n"
jsgf855d93d2003-10-13 22:26:55 +0000209" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
sewardj17c11042006-10-15 01:26:40 +0000210" --sym-offsets=yes|no show syms in form 'name+offset' ? [no]\n"
sewardjb5f6f512005-03-10 23:59:00 +0000211" --command-line-only=no|yes only use command line options [no]\n"
njn613812e2005-03-11 04:57:30 +0000212"\n"
njn97db7612009-08-04 02:32:55 +0000213" Vex options for all Valgrind tools:\n"
214" --vex-iropt-verbosity=<0..9> [0]\n"
215" --vex-iropt-level=<0..2> [2]\n"
216" --vex-iropt-precise-memory-exns=no|yes [no]\n"
217" --vex-iropt-unroll-thresh=<0..400> [120]\n"
218" --vex-guest-max-insns=<1..100> [50]\n"
219" --vex-guest-chase-thresh=<0..99> [10]\n"
sewardj540cc4a2010-01-15 10:57:57 +0000220" --vex-guest-chase-cond=no|yes [no]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000221" --trace-flags and --profile-flags values (omit the middle space):\n"
sewardj2a99cf62004-11-24 10:44:19 +0000222" 1000 0000 show conversion into IR\n"
223" 0100 0000 show after initial opt\n"
224" 0010 0000 show after instrumentation\n"
225" 0001 0000 show after second opt\n"
226" 0000 1000 show after tree building\n"
227" 0000 0100 show selecting insns\n"
228" 0000 0010 show after reg-alloc\n"
229" 0000 0001 show final assembly\n"
njn33dbfce2006-06-02 22:58:34 +0000230" (Nb: you need --trace-notbelow with --trace-flags for full details)\n"
sewardj2a99cf62004-11-24 10:44:19 +0000231"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000232" debugging options for Valgrind tools that report errors\n"
233" --dump-error=<number> show translation for basic block associated\n"
234" with <number>'th error context [0=show none]\n"
njn97db7612009-08-04 02:32:55 +0000235"\n"
236" debugging options for Valgrind tools that replace malloc:\n"
237" --trace-malloc=no|yes show client malloc details? [no]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000238"\n";
njn3e884182003-04-15 13:03:23 +0000239
240 Char* usage3 =
241"\n"
nethercote71980f02004-01-24 18:18:54 +0000242" Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
njn25e49d8e72002-09-23 09:36:25 +0000243"\n"
njn10b9aea2009-07-14 06:55:05 +0000244" %s is %s\n"
sewardj9eecbbb2010-05-03 21:37:12 +0000245" Valgrind is Copyright (C) 2000-2010, and GNU GPL'd, by Julian Seward et al.\n"
sewardje089f012010-10-13 21:47:29 +0000246" LibVEX is Copyright (C) 2004-2010, and GNU GPL'd, by OpenWorks LLP et al.\n"
njnd04b7c62002-10-03 14:05:52 +0000247"\n"
njn10b9aea2009-07-14 06:55:05 +0000248" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
njn25e49d8e72002-09-23 09:36:25 +0000249"\n";
njn7cf0bd32002-06-08 13:36:03 +0000250
sewardj12373b12007-11-20 21:38:14 +0000251 Char* gdb_path = GDB_PATH;
sewardj12373b12007-11-20 21:38:14 +0000252
njnbe9b47b2005-05-15 16:22:58 +0000253 // Ensure the message goes to stdout
sewardj738856f2009-07-15 14:48:32 +0000254 VG_(log_output_sink).fd = 1;
255 VG_(log_output_sink).is_socket = False;
njnbe9b47b2005-05-15 16:22:58 +0000256
sewardj3b290482011-05-06 21:02:55 +0000257 /* 'usage1' expects two int, two char* argument, and one SizeT argument. */
258 VG_(printf)(usage1,
259 VG_(clo_vgdb_error), gdb_path, VG_MIN_MALLOC_SZB,
260 VG_(clo_vgdb_poll), VG_(clo_vgdb_prefix));
fitzhardinge98abfc72003-12-16 02:05:15 +0000261 if (VG_(details).name) {
262 VG_(printf)(" user options for %s:\n", VG_(details).name);
fitzhardinge98abfc72003-12-16 02:05:15 +0000263 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000264 VG_TDICT_CALL(tool_print_usage);
fitzhardinge98abfc72003-12-16 02:05:15 +0000265 else
266 VG_(printf)(" (none)\n");
267 }
nethercote6c999f22004-01-31 22:55:15 +0000268 if (debug_help) {
sewardjbbaef872008-11-01 23:55:32 +0000269 VG_(printf)("%s", usage2);
fitzhardinge98abfc72003-12-16 02:05:15 +0000270
nethercote6c999f22004-01-31 22:55:15 +0000271 if (VG_(details).name) {
272 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
273
274 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000275 VG_TDICT_CALL(tool_print_debug_usage);
nethercote6c999f22004-01-31 22:55:15 +0000276 else
277 VG_(printf)(" (none)\n");
278 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000279 }
njn10b9aea2009-07-14 06:55:05 +0000280 VG_(printf)(usage3, VG_(details).name, VG_(details).copyright_author,
281 VG_BUGS_TO);
nethercotef4928da2004-06-15 10:54:40 +0000282 VG_(exit)(0);
njn7cf0bd32002-06-08 13:36:03 +0000283}
sewardjde4a1d02002-03-22 01:27:54 +0000284
sewardjde4a1d02002-03-22 01:27:54 +0000285
sewardj95d86c02007-12-18 01:49:23 +0000286/* Peer at previously set up VG_(args_for_valgrind) and do some
287 minimal command line processing that must happen early on:
sewardj45f4e7c2005-09-27 19:20:21 +0000288
sewardj95d86c02007-12-18 01:49:23 +0000289 - show the version string, if requested (-v)
290 - extract any request for help (--help, -h, --help-debug)
291 - get the toolname (--tool=)
292 - set VG_(clo_max_stackframe) (--max-stackframe=)
293 - set VG_(clo_main_stacksize) (--main-stacksize=)
294
295 That's all it does. The main command line processing is done below
296 by main_process_cmd_line_options. Note that
297 main_process_cmd_line_options has to handle but ignore the ones we
298 have handled here.
299*/
300static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
301 /*OUT*/HChar** tool )
sewardj45f4e7c2005-09-27 19:20:21 +0000302{
303 UInt i;
304 HChar* str;
sewardj8b635a42004-11-22 19:01:47 +0000305
sewardj14c7cc52007-02-25 15:08:24 +0000306 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000307
sewardj14c7cc52007-02-25 15:08:24 +0000308 /* parse the options we have (only the options we care about now) */
309 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
310
311 str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000312 vg_assert(str);
nethercote71980f02004-01-24 18:18:54 +0000313
njn83df0b62009-02-25 01:01:05 +0000314 // Nb: the version string goes to stdout.
sewardj738856f2009-07-15 14:48:32 +0000315 if VG_XACT_CLO(str, "--version", VG_(log_output_sink).fd, 1) {
316 VG_(log_output_sink).is_socket = False;
sewardj45f4e7c2005-09-27 19:20:21 +0000317 VG_(printf)("valgrind-" VERSION "\n");
318 VG_(exit)(0);
njn83df0b62009-02-25 01:01:05 +0000319 }
njncce38e62010-07-06 04:25:12 +0000320 else if VG_XACT_CLO(str, "--help", *need_help, *need_help+1) {}
321 else if VG_XACT_CLO(str, "-h", *need_help, *need_help+1) {}
sewardj45f4e7c2005-09-27 19:20:21 +0000322
njncce38e62010-07-06 04:25:12 +0000323 else if VG_XACT_CLO(str, "--help-debug", *need_help, *need_help+2) {}
nethercote71980f02004-01-24 18:18:54 +0000324
sewardj45f4e7c2005-09-27 19:20:21 +0000325 // The tool has already been determined, but we need to know the name
326 // here.
njn83df0b62009-02-25 01:01:05 +0000327 else if VG_STR_CLO(str, "--tool", *tool) {}
sewardj5bdfbd22007-12-15 22:13:05 +0000328
sewardj95d86c02007-12-18 01:49:23 +0000329 // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
330 // These are needed by VG_(ii_create_image), which happens
331 // before main_process_cmd_line_options().
njn83df0b62009-02-25 01:01:05 +0000332 else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
333 else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
nethercote71980f02004-01-24 18:18:54 +0000334 }
nethercote71980f02004-01-24 18:18:54 +0000335}
336
sewardj95d86c02007-12-18 01:49:23 +0000337/* The main processing for command line options. See comments above
sewardj738856f2009-07-15 14:48:32 +0000338 on early_process_cmd_line_options.
339
340 Comments on how the logging options are handled:
341
342 User can specify:
343 --log-fd= for a fd to write to (default setting, fd = 2)
344 --log-file= for a file name to write to
345 --log-socket= for a socket to write to
346
347 As a result of examining these and doing relevant socket/file
348 opening, a final fd is established. This is stored in
349 VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
350 specified, then STR, after expansion of %p and %q templates within
351 it, is stored in VG_(clo_log_fname_expanded), in m_options, just in
352 case anybody wants to know what it is.
353
354 When printing, VG_(log_output_sink) is consulted to find the
355 fd to send output to.
356
357 Exactly analogous actions are undertaken for the XML output
358 channel, with the one difference that the default fd is -1, meaning
359 the channel is disabled by default.
sewardj95d86c02007-12-18 01:49:23 +0000360*/
sewardj738856f2009-07-15 14:48:32 +0000361static
362void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
363 /*OUT*/Char** xml_fname_unexpanded,
364 const HChar* toolname )
nethercote71980f02004-01-24 18:18:54 +0000365{
njnda033f52005-12-19 21:27:58 +0000366 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
367 // and we cannot change it until we know what we are changing it to is
368 // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
sewardj92645592005-07-23 09:18:34 +0000369 SysRes sres;
sewardj738856f2009-07-15 14:48:32 +0000370 Int i, tmp_log_fd, tmp_xml_fd;
sewardj92645592005-07-23 09:18:34 +0000371 Int toolname_len = VG_(strlen)(toolname);
njn83df0b62009-02-25 01:01:05 +0000372 Char* tmp_str; // Used in a couple of places.
njnbe9b47b2005-05-15 16:22:58 +0000373 enum {
374 VgLogTo_Fd,
375 VgLogTo_File,
njnbe9b47b2005-05-15 16:22:58 +0000376 VgLogTo_Socket
sewardj738856f2009-07-15 14:48:32 +0000377 } log_to = VgLogTo_Fd, // Where is logging output to be sent?
378 xml_to = VgLogTo_Fd; // Where is XML output to be sent?
sewardjde4a1d02002-03-22 01:27:54 +0000379
sewardj738856f2009-07-15 14:48:32 +0000380 /* Temporarily holds the string STR specified with
381 --{log,xml}-{name,socket}=STR. 'fs' stands for
382 file-or-socket. */
383 Char* log_fsname_unexpanded = NULL;
384 Char* xml_fsname_unexpanded = NULL;
385
386 /* Log to stderr by default, but usage message goes to stdout. XML
387 output is initially disabled. */
njnda033f52005-12-19 21:27:58 +0000388 tmp_log_fd = 2;
sewardj738856f2009-07-15 14:48:32 +0000389 tmp_xml_fd = -1;
390
sewardj19d81412002-06-03 01:10:40 +0000391 /* Check for sane path in ./configure --prefix=... */
fitzhardinge98abfc72003-12-16 02:05:15 +0000392 if (VG_LIBDIR[0] != '/')
sewardj17c11042006-10-15 01:26:40 +0000393 VG_(err_config_error)("Please use absolute paths in "
florian1763e812011-07-12 19:07:05 +0000394 "./configure --prefix=... or --libdir=...\n");
sewardj38170912002-05-10 21:07:22 +0000395
sewardj14c7cc52007-02-25 15:08:24 +0000396 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000397
sewardj738856f2009-07-15 14:48:32 +0000398 /* BEGIN command-line processing loop */
399
sewardj14c7cc52007-02-25 15:08:24 +0000400 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
401
402 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000403 HChar* colon = arg;
nethercote71980f02004-01-24 18:18:54 +0000404
njn1274d242007-03-26 23:38:42 +0000405 // Look for a colon in the option name.
thughes3bfd5a02004-07-18 08:05:44 +0000406 while (*colon && *colon != ':' && *colon != '=')
407 colon++;
nethercote71980f02004-01-24 18:18:54 +0000408
njn1274d242007-03-26 23:38:42 +0000409 // Does it have the form "--toolname:foo"? We have to do it at the start
410 // in case someone has combined a prefix with a core-specific option,
411 // eg. "--memcheck:verbose".
thughes3bfd5a02004-07-18 08:05:44 +0000412 if (*colon == ':') {
njn83df0b62009-02-25 01:01:05 +0000413 if (VG_STREQN(2, arg, "--") &&
414 VG_STREQN(toolname_len, arg+2, toolname) &&
415 VG_STREQN(1, arg+2+toolname_len, ":"))
nethercote71980f02004-01-24 18:18:54 +0000416 {
njn1274d242007-03-26 23:38:42 +0000417 // Prefix matches, convert "--toolname:foo" to "--foo".
418 // Two things to note:
419 // - We cannot modify the option in-place. If we did, and then
420 // a child was spawned with --trace-children=yes, the
421 // now-non-prefixed option would be passed and could screw up
422 // the child.
423 // - We create copies, and never free them. Why? Non-prefixed
424 // options hang around forever, so tools need not make copies
425 // of strings within them. We need to have the same behaviour
426 // for prefixed options. The pointer to the copy will be lost
427 // once we leave this function (although a tool may keep a
428 // pointer into it), but the space wasted is insignificant.
429 // (In bug #142197, the copies were being freed, which caused
430 // problems for tools that reasonably assumed that arguments
431 // wouldn't disappear on them.)
nethercote71980f02004-01-24 18:18:54 +0000432 if (0)
433 VG_(printf)("tool-specific arg: %s\n", arg);
sewardj9c606bd2008-09-18 18:12:50 +0000434 arg = VG_(strdup)("main.mpclo.1", arg + toolname_len + 1);
nethercote71980f02004-01-24 18:18:54 +0000435 arg[0] = '-';
436 arg[1] = '-';
437
438 } else {
439 // prefix doesn't match, skip to next arg
440 continue;
441 }
442 }
443
fitzhardinge98abfc72003-12-16 02:05:15 +0000444 /* Ignore these options - they've already been handled */
njn83df0b62009-02-25 01:01:05 +0000445 if VG_STREQN( 7, arg, "--tool=") {}
446 else if VG_STREQN(20, arg, "--command-line-only=") {}
447 else if VG_STREQ( arg, "--") {}
448 else if VG_STREQ( arg, "-d") {}
449 else if VG_STREQN(16, arg, "--max-stackframe") {}
450 else if VG_STREQN(16, arg, "--main-stacksize") {}
451 else if VG_STREQN(14, arg, "--profile-heap") {}
nethercote27fec902004-06-16 21:26:32 +0000452
njn83df0b62009-02-25 01:01:05 +0000453 // These options are new.
454 else if (VG_STREQ(arg, "-v") ||
455 VG_STREQ(arg, "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000456 VG_(clo_verbosity)++;
nethercote27fec902004-06-16 21:26:32 +0000457
njn83df0b62009-02-25 01:01:05 +0000458 else if (VG_STREQ(arg, "-q") ||
459 VG_STREQ(arg, "--quiet"))
sewardjde4a1d02002-03-22 01:27:54 +0000460 VG_(clo_verbosity)--;
461
sewardj2d9e8742009-08-07 15:46:56 +0000462 else if VG_BOOL_CLO(arg, "--stats", VG_(clo_stats)) {}
njn83df0b62009-02-25 01:01:05 +0000463 else if VG_BOOL_CLO(arg, "--xml", VG_(clo_xml)) {}
sewardj3b290482011-05-06 21:02:55 +0000464 else if VG_XACT_CLO(arg, "--vgdb=no", VG_(clo_vgdb), Vg_VgdbNo) {}
465 else if VG_XACT_CLO(arg, "--vgdb=yes", VG_(clo_vgdb), Vg_VgdbYes) {}
466 else if VG_XACT_CLO(arg, "--vgdb=full", VG_(clo_vgdb), Vg_VgdbFull) {}
467 else if VG_INT_CLO (arg, "--vgdb-poll", VG_(clo_vgdb_poll)) {}
468 else if VG_INT_CLO (arg, "--vgdb-error", VG_(clo_vgdb_error)) {}
469 else if VG_STR_CLO (arg, "--vgdb-prefix", VG_(clo_vgdb_prefix)) {}
470 else if VG_BOOL_CLO(arg, "--vgdb-shadow-registers",
471 VG_(clo_vgdb_shadow_registers)) {}
njn83df0b62009-02-25 01:01:05 +0000472 else if VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach)) {}
473 else if VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle)) {}
474 else if VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit)) {}
475 else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
476 else if VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns)) {}
sewardj95d86c02007-12-18 01:49:23 +0000477
njn83df0b62009-02-25 01:01:05 +0000478 else if VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres)) {}
479 else if VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main)) {}
480 else if VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp)) {}
481 else if VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds)) {}
482 else if VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children)) {}
483 else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
484 VG_(clo_child_silent_after_fork)) {}
485 else if VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched)) {}
486 else if VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals)) {}
487 else if VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab)) {}
488 else if VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt)) {}
489 else if VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi)) {}
490 else if VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms),
491 True) {}
492 else if VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line),
493 True) {}
494 else if VG_XACT_CLO(arg, "--debug-dump=frames",
495 VG_(clo_debug_dump_frames), True) {}
496 else if VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir)) {}
sewardj95d86c02007-12-18 01:49:23 +0000497
njn83df0b62009-02-25 01:01:05 +0000498 else if VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls)) {}
499 else if VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb)) {}
500 else if VG_STR_CLO (arg, "--db-command", VG_(clo_db_command)) {}
501 else if VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints)) {}
502 else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
503 else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
sewardjf767d962007-02-12 17:47:14 +0000504
njn83df0b62009-02-25 01:01:05 +0000505 else if VG_INT_CLO (arg, "--dump-error", VG_(clo_dump_error)) {}
506 else if VG_INT_CLO (arg, "--input-fd", VG_(clo_input_fd)) {}
507 else if VG_INT_CLO (arg, "--sanity-level", VG_(clo_sanity_level)) {}
508 else if VG_BINT_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
509 VG_DEEPEST_BACKTRACE) {}
sewardjde4a1d02002-03-22 01:27:54 +0000510
njn83df0b62009-02-25 01:01:05 +0000511 else if VG_XACT_CLO(arg, "--smc-check=none", VG_(clo_smc_check),
512 Vg_SmcNone);
513 else if VG_XACT_CLO(arg, "--smc-check=stack", VG_(clo_smc_check),
514 Vg_SmcStack);
515 else if VG_XACT_CLO(arg, "--smc-check=all", VG_(clo_smc_check),
516 Vg_SmcAll);
sewardj6dbcc632011-06-07 21:39:28 +0000517 else if VG_XACT_CLO(arg, "--smc-check=all-non-file",
518 VG_(clo_smc_check),
519 Vg_SmcAllNonFile);
sewardjde4a1d02002-03-22 01:27:54 +0000520
njn97db7612009-08-04 02:32:55 +0000521 else if VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant)) {}
sewardj26412bd2005-07-07 10:05:05 +0000522
njn97db7612009-08-04 02:32:55 +0000523 else if VG_BOOL_CLO(arg, "--dsymutil", VG_(clo_dsymutil)) {}
njnf76d27a2009-05-28 01:53:07 +0000524
sewardj9ab64a42010-12-06 11:40:04 +0000525 else if VG_STR_CLO (arg, "--trace-children-skip",
526 VG_(clo_trace_children_skip)) {}
527 else if VG_STR_CLO (arg, "--trace-children-skip-by-arg",
528 VG_(clo_trace_children_skip_by_arg)) {}
sewardj06421272009-11-05 08:55:13 +0000529
njn83df0b62009-02-25 01:01:05 +0000530 else if VG_BINT_CLO(arg, "--vex-iropt-verbosity",
531 VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
532 else if VG_BINT_CLO(arg, "--vex-iropt-level",
533 VG_(clo_vex_control).iropt_level, 0, 2) {}
534 else if VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
535 VG_(clo_vex_control).iropt_precise_memory_exns) {}
536 else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
537 VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
538 else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
539 VG_(clo_vex_control).guest_max_insns, 1, 100) {}
540 else if VG_BINT_CLO(arg, "--vex-guest-chase-thresh",
541 VG_(clo_vex_control).guest_chase_thresh, 0, 99) {}
sewardj540cc4a2010-01-15 10:57:57 +0000542 else if VG_BOOL_CLO(arg, "--vex-guest-chase-cond",
543 VG_(clo_vex_control).guest_chase_cond) {}
sewardj94c8eb42008-09-19 20:13:39 +0000544
njn83df0b62009-02-25 01:01:05 +0000545 else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
546 log_to = VgLogTo_Fd;
sewardj738856f2009-07-15 14:48:32 +0000547 log_fsname_unexpanded = NULL;
548 }
549 else if VG_INT_CLO(arg, "--xml-fd", tmp_xml_fd) {
550 xml_to = VgLogTo_Fd;
551 xml_fsname_unexpanded = NULL;
sewardj4cf05692002-10-27 20:28:29 +0000552 }
553
sewardj738856f2009-07-15 14:48:32 +0000554 else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000555 log_to = VgLogTo_File;
sewardj4cf05692002-10-27 20:28:29 +0000556 }
sewardj738856f2009-07-15 14:48:32 +0000557 else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) {
558 xml_to = VgLogTo_File;
559 }
560
561 else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000562 log_to = VgLogTo_Socket;
sewardj73cf3bc2002-11-03 03:20:15 +0000563 }
sewardj738856f2009-07-15 14:48:32 +0000564 else if VG_STR_CLO(arg, "--xml-socket", xml_fsname_unexpanded) {
565 xml_to = VgLogTo_Socket;
566 }
sewardj73cf3bc2002-11-03 03:20:15 +0000567
njn83df0b62009-02-25 01:01:05 +0000568 else if VG_STR_CLO(arg, "--xml-user-comment",
569 VG_(clo_xml_user_comment)) {}
sewardj768db0e2005-07-19 14:18:56 +0000570
njn83df0b62009-02-25 01:01:05 +0000571 else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
sewardjde4a1d02002-03-22 01:27:54 +0000572 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njnb1cc5d62010-07-06 04:05:23 +0000573 VG_(fmsg_bad_option)(arg,
574 "Too many suppression files specified.\n"
575 "Increase VG_CLO_MAX_SFILES and recompile.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000576 }
njn83df0b62009-02-25 01:01:05 +0000577 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = tmp_str;
sewardjde4a1d02002-03-22 01:27:54 +0000578 VG_(clo_n_suppressions)++;
579 }
sewardjde4a1d02002-03-22 01:27:54 +0000580
sewardj14cdbf82010-10-12 00:44:05 +0000581 else if VG_STR_CLO (arg, "--fullpath-after", tmp_str) {
582 if (VG_(clo_n_fullpath_after) >= VG_CLO_MAX_FULLPATH_AFTER) {
583 VG_(fmsg_bad_option)(arg,
584 "Too many --fullpath-after= specifications.\n"
585 "Increase VG_CLO_MAX_FULLPATH_AFTER and recompile.\n");
586 }
587 VG_(clo_fullpath_after)[VG_(clo_n_fullpath_after)] = tmp_str;
588 VG_(clo_n_fullpath_after)++;
589 }
590
sewardjf9ebc392010-05-09 22:30:43 +0000591 else if VG_STR_CLO(arg, "--require-text-symbol", tmp_str) {
592 if (VG_(clo_n_req_tsyms) >= VG_CLO_MAX_REQ_TSYMS) {
njnb1cc5d62010-07-06 04:05:23 +0000593 VG_(fmsg_bad_option)(arg,
594 "Too many --require-text-symbol= specifications.\n"
595 "Increase VG_CLO_MAX_REQ_TSYMS and recompile.\n");
sewardjf9ebc392010-05-09 22:30:43 +0000596 }
597 /* String needs to be of the form C?*C?*, where C is any
598 character, but is the same both times. Having it in this
599 form facilitates finding the boundary between the sopatt
600 and the fnpatt just by looking for the second occurrence
601 of C, without hardwiring any assumption about what C
602 is. */
603 Char patt[7];
604 Bool ok = True;
605 ok = tmp_str && VG_(strlen)(tmp_str) > 0;
606 if (ok) {
607 patt[0] = patt[3] = tmp_str[0];
608 patt[1] = patt[4] = '?';
609 patt[2] = patt[5] = '*';
610 patt[6] = 0;
611 ok = VG_(string_match)(patt, tmp_str);
612 }
613 if (!ok) {
njnb1cc5d62010-07-06 04:05:23 +0000614 VG_(fmsg_bad_option)(arg,
615 "Invalid --require-text-symbol= specification.\n");
sewardjf9ebc392010-05-09 22:30:43 +0000616 }
617 VG_(clo_req_tsyms)[VG_(clo_n_req_tsyms)] = tmp_str;
618 VG_(clo_n_req_tsyms)++;
619 }
620
sewardjfa8ec112005-01-19 11:55:34 +0000621 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000622 else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
sewardjfa8ec112005-01-19 11:55:34 +0000623 Int j;
sewardjfa8ec112005-01-19 11:55:34 +0000624
njn83df0b62009-02-25 01:01:05 +0000625 if (8 != VG_(strlen)(tmp_str)) {
njnb1cc5d62010-07-06 04:05:23 +0000626 VG_(fmsg_bad_option)(arg,
627 "--trace-flags argument must have 8 digits\n");
sewardjfa8ec112005-01-19 11:55:34 +0000628 }
629 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000630 if ('0' == tmp_str[j]) { /* do nothing */ }
631 else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
sewardjfa8ec112005-01-19 11:55:34 +0000632 else {
njnb1cc5d62010-07-06 04:05:23 +0000633 VG_(fmsg_bad_option)(arg,
634 "--trace-flags argument can only contain 0s and 1s\n");
sewardjfa8ec112005-01-19 11:55:34 +0000635 }
636 }
637 }
638
639 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000640 else if VG_STR_CLO(arg, "--profile-flags", tmp_str) {
njn25e49d8e72002-09-23 09:36:25 +0000641 Int j;
njn25e49d8e72002-09-23 09:36:25 +0000642
njn83df0b62009-02-25 01:01:05 +0000643 if (8 != VG_(strlen)(tmp_str)) {
njnb1cc5d62010-07-06 04:05:23 +0000644 VG_(fmsg_bad_option)(arg,
645 "--profile-flags argument must have 8 digits\n");
njn25e49d8e72002-09-23 09:36:25 +0000646 }
sewardj8b635a42004-11-22 19:01:47 +0000647 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000648 if ('0' == tmp_str[j]) { /* do nothing */ }
649 else if ('1' == tmp_str[j]) VG_(clo_profile_flags) |= (1 << (7-j));
njn25e49d8e72002-09-23 09:36:25 +0000650 else {
njnb1cc5d62010-07-06 04:05:23 +0000651 VG_(fmsg_bad_option)(arg,
652 "--profile-flags argument can only contain 0s and 1s\n");
njn25e49d8e72002-09-23 09:36:25 +0000653 }
654 }
655 }
sewardjde4a1d02002-03-22 01:27:54 +0000656
njn83df0b62009-02-25 01:01:05 +0000657 else if VG_INT_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow)) {}
sewardjc771b292004-11-30 18:55:21 +0000658
njn83df0b62009-02-25 01:01:05 +0000659 else if VG_XACT_CLO(arg, "--gen-suppressions=no",
660 VG_(clo_gen_suppressions), 0) {}
661 else if VG_XACT_CLO(arg, "--gen-suppressions=yes",
662 VG_(clo_gen_suppressions), 1) {}
663 else if VG_XACT_CLO(arg, "--gen-suppressions=all",
664 VG_(clo_gen_suppressions), 2) {}
sewardjd153fae2005-01-10 17:24:47 +0000665
nethercote71980f02004-01-24 18:18:54 +0000666 else if ( ! VG_(needs).command_line_options
njn51d827b2005-05-09 01:02:08 +0000667 || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
njnb1cc5d62010-07-06 04:05:23 +0000668 VG_(fmsg_bad_option)(arg, "");
njn25e49d8e72002-09-23 09:36:25 +0000669 }
sewardjde4a1d02002-03-22 01:27:54 +0000670 }
671
sewardj738856f2009-07-15 14:48:32 +0000672 /* END command-line processing loop */
673
sewardj998d40d2004-12-06 14:24:52 +0000674 /* Make VEX control parameters sane */
675
676 if (VG_(clo_vex_control).guest_chase_thresh
677 >= VG_(clo_vex_control).guest_max_insns)
678 VG_(clo_vex_control).guest_chase_thresh
679 = VG_(clo_vex_control).guest_max_insns - 1;
680
681 if (VG_(clo_vex_control).guest_chase_thresh < 0)
682 VG_(clo_vex_control).guest_chase_thresh = 0;
683
684 /* Check various option values */
nethercote27fec902004-06-16 21:26:32 +0000685
njnf9ebf672003-05-12 21:41:30 +0000686 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +0000687 VG_(clo_verbosity) = 0;
688
sewardj3b290482011-05-06 21:02:55 +0000689 VG_(dyn_vgdb_error) = VG_(clo_vgdb_error);
690
njnbe9b47b2005-05-15 16:22:58 +0000691 if (VG_(clo_gen_suppressions) > 0 &&
692 !VG_(needs).core_errors && !VG_(needs).tool_errors) {
njnb1cc5d62010-07-06 04:05:23 +0000693 VG_(fmsg_bad_option)("--gen-suppressions=yes",
694 "Can't use --gen-suppressions= with %s\n"
695 "because it doesn't generate errors.\n", VG_(details).name);
njnbe9b47b2005-05-15 16:22:58 +0000696 }
697
sewardj738856f2009-07-15 14:48:32 +0000698 /* If XML output is requested, check that the tool actually
699 supports it. */
700 if (VG_(clo_xml) && !VG_(needs).xml_output) {
701 VG_(clo_xml) = False;
njnb1cc5d62010-07-06 04:05:23 +0000702 VG_(fmsg_bad_option)("--xml=yes",
sewardj738856f2009-07-15 14:48:32 +0000703 "%s does not support XML output.\n", VG_(details).name);
sewardj738856f2009-07-15 14:48:32 +0000704 /*NOTREACHED*/
705 }
706
707 vg_assert( VG_(clo_gen_suppressions) >= 0 );
708 vg_assert( VG_(clo_gen_suppressions) <= 2 );
709
sewardj71bc3cb2005-05-19 00:25:45 +0000710 /* If we've been asked to emit XML, mash around various other
711 options so as to constrain the output somewhat, and to remove
sewardj738856f2009-07-15 14:48:32 +0000712 any need for user input during the run.
713 */
sewardj71bc3cb2005-05-19 00:25:45 +0000714 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +0000715
716 /* We can't allow --gen-suppressions=yes, since that requires us
717 to print the error and then ask the user if she wants a
718 suppression for it, but in XML mode we won't print it until
719 we know whether we also need to print a suppression. Hence a
720 circular dependency. So disallow this.
721 (--gen-suppressions=all is still OK since we don't need any
722 user interaction in this case.) */
723 if (VG_(clo_gen_suppressions) == 1) {
njnb1cc5d62010-07-06 04:05:23 +0000724 VG_(fmsg_bad_option)(
725 "--xml=yes together with --gen-suppressions=yes",
726 "When --xml=yes is specified, --gen-suppressions=no\n"
727 "or --gen-suppressions=all is allowed, but not "
sewardj738856f2009-07-15 14:48:32 +0000728 "--gen-suppressions=yes.\n");
sewardj738856f2009-07-15 14:48:32 +0000729 }
730
731 /* We can't allow DB attaching (or we maybe could, but results
732 could be chaotic ..) since it requires user input. Hence
733 disallow. */
734 if (VG_(clo_db_attach)) {
njnb1cc5d62010-07-06 04:05:23 +0000735 VG_(fmsg_bad_option)(
736 "--xml=yes together with --db-attach=yes",
737 "--db-attach=yes is not allowed with --xml=yes\n"
738 "because it would require user input.\n");
sewardj738856f2009-07-15 14:48:32 +0000739 }
740
741 /* Disallow dump_error in XML mode; sounds like a recipe for
742 chaos. No big deal; dump_error is a flag for debugging V
743 itself. */
744 if (VG_(clo_dump_error) > 0) {
njnb1cc5d62010-07-06 04:05:23 +0000745 VG_(fmsg_bad_option)("--xml=yes together with --dump-error", "");
sewardj738856f2009-07-15 14:48:32 +0000746 }
747
sewardj71bc3cb2005-05-19 00:25:45 +0000748 /* Disable error limits (this might be a bad idea!) */
749 VG_(clo_error_limit) = False;
750 /* Disable emulation warnings */
sewardj738856f2009-07-15 14:48:32 +0000751
sewardj71bc3cb2005-05-19 00:25:45 +0000752 /* Also, we want to set options for the leak checker, but that
753 will have to be done in Memcheck's flag-handling code, not
754 here. */
755 }
756
njnbe9b47b2005-05-15 16:22:58 +0000757 /* All non-logging-related options have been checked. If the logging
758 option specified is ok, we can switch to it, as we know we won't
759 have to generate any other command-line-related error messages.
760 (So far we should be still attached to stderr, so we can show on
761 the terminal any problems to do with processing command line
762 opts.)
763
sewardj738856f2009-07-15 14:48:32 +0000764 So set up logging now. After this is done, VG_(log_output_sink)
765 and (if relevant) VG_(xml_output_sink) should be connected to
766 whatever sink has been selected, and we indiscriminately chuck
767 stuff into it without worrying what the nature of it is. Oh the
768 wonder of Unix streams. */
sewardj4cf05692002-10-27 20:28:29 +0000769
sewardj738856f2009-07-15 14:48:32 +0000770 vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
771 vg_assert(VG_(log_output_sink).is_socket == False);
772 vg_assert(VG_(clo_log_fname_expanded) == NULL);
773
774 vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
775 vg_assert(VG_(xml_output_sink).is_socket == False);
776 vg_assert(VG_(clo_xml_fname_expanded) == NULL);
777
778 /* --- set up the normal text output channel --- */
sewardj4cf05692002-10-27 20:28:29 +0000779
njnbe9b47b2005-05-15 16:22:58 +0000780 switch (log_to) {
sewardj73cf3bc2002-11-03 03:20:15 +0000781
sewardj4cf05692002-10-27 20:28:29 +0000782 case VgLogTo_Fd:
sewardj738856f2009-07-15 14:48:32 +0000783 vg_assert(log_fsname_unexpanded == NULL);
sewardj4cf05692002-10-27 20:28:29 +0000784 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000785
sewardj4cf05692002-10-27 20:28:29 +0000786 case VgLogTo_File: {
njn374a36d2007-11-23 01:41:32 +0000787 Char* logfilename;
jsgff3c3f1a2003-10-14 22:13:28 +0000788
sewardj738856f2009-07-15 14:48:32 +0000789 vg_assert(log_fsname_unexpanded != NULL);
790 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +0000791
njn374a36d2007-11-23 01:41:32 +0000792 // Nb: we overwrite an existing file of this name without asking
793 // any questions.
sewardj738856f2009-07-15 14:48:32 +0000794 logfilename = VG_(expand_file_name)("--log-file",
795 log_fsname_unexpanded);
njn374a36d2007-11-23 01:41:32 +0000796 sres = VG_(open)(logfilename,
njnda033f52005-12-19 21:27:58 +0000797 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
798 VKI_S_IRUSR|VKI_S_IWUSR);
njncda2f0f2009-05-18 02:12:08 +0000799 if (!sr_isError(sres)) {
800 tmp_log_fd = sr_Res(sres);
sewardj738856f2009-07-15 14:48:32 +0000801 VG_(clo_log_fname_expanded) = logfilename;
njnbe9b47b2005-05-15 16:22:58 +0000802 } else {
njnb1cc5d62010-07-06 04:05:23 +0000803 VG_(fmsg)("can't create log file '%s': %s\n",
804 logfilename, VG_(strerror)(sr_Err(sres)));
805 VG_(exit)(1);
sewardj603d4102005-01-11 14:01:02 +0000806 /*NOTREACHED*/
njn374a36d2007-11-23 01:41:32 +0000807 }
sewardj738856f2009-07-15 14:48:32 +0000808 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000809 }
810
811 case VgLogTo_Socket: {
sewardj738856f2009-07-15 14:48:32 +0000812 vg_assert(log_fsname_unexpanded != NULL);
813 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
814 tmp_log_fd = VG_(connect_via_socket)( log_fsname_unexpanded );
njnda033f52005-12-19 21:27:58 +0000815 if (tmp_log_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +0000816 VG_(fmsg)("Invalid --log-socket spec of '%s'\n",
817 log_fsname_unexpanded);
818 VG_(exit)(1);
njnbe9b47b2005-05-15 16:22:58 +0000819 /*NOTREACHED*/
sewardj4cf05692002-10-27 20:28:29 +0000820 }
njnda033f52005-12-19 21:27:58 +0000821 if (tmp_log_fd == -2) {
njnb1cc5d62010-07-06 04:05:23 +0000822 VG_(umsg)("failed to connect to logging server '%s'.\n"
823 "Log messages will sent to stderr instead.\n",
824 log_fsname_unexpanded );
825
sewardj570f8902002-11-03 11:44:36 +0000826 /* We don't change anything here. */
sewardj738856f2009-07-15 14:48:32 +0000827 vg_assert(VG_(log_output_sink).fd == 2);
njnda033f52005-12-19 21:27:58 +0000828 tmp_log_fd = 2;
sewardj570f8902002-11-03 11:44:36 +0000829 } else {
njnda033f52005-12-19 21:27:58 +0000830 vg_assert(tmp_log_fd > 0);
sewardj738856f2009-07-15 14:48:32 +0000831 VG_(log_output_sink).is_socket = True;
sewardj570f8902002-11-03 11:44:36 +0000832 }
sewardj73cf3bc2002-11-03 03:20:15 +0000833 break;
834 }
sewardj4cf05692002-10-27 20:28:29 +0000835 }
836
sewardj738856f2009-07-15 14:48:32 +0000837 /* --- set up the XML output channel --- */
sewardj71bc3cb2005-05-19 00:25:45 +0000838
sewardj738856f2009-07-15 14:48:32 +0000839 switch (xml_to) {
840
841 case VgLogTo_Fd:
842 vg_assert(xml_fsname_unexpanded == NULL);
843 break;
844
845 case VgLogTo_File: {
846 Char* xmlfilename;
847
848 vg_assert(xml_fsname_unexpanded != NULL);
849 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
850
851 // Nb: we overwrite an existing file of this name without asking
852 // any questions.
853 xmlfilename = VG_(expand_file_name)("--xml-file",
854 xml_fsname_unexpanded);
855 sres = VG_(open)(xmlfilename,
856 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
857 VKI_S_IRUSR|VKI_S_IWUSR);
858 if (!sr_isError(sres)) {
859 tmp_xml_fd = sr_Res(sres);
860 VG_(clo_xml_fname_expanded) = xmlfilename;
861 /* strdup here is probably paranoid overkill, but ... */
862 *xml_fname_unexpanded = VG_(strdup)( "main.mpclo.2",
863 xml_fsname_unexpanded );
864 } else {
njnb1cc5d62010-07-06 04:05:23 +0000865 VG_(fmsg)("can't create XML file '%s': %s\n",
866 xmlfilename, VG_(strerror)(sr_Err(sres)));
867 VG_(exit)(1);
sewardj738856f2009-07-15 14:48:32 +0000868 /*NOTREACHED*/
869 }
870 break;
871 }
872
873 case VgLogTo_Socket: {
874 vg_assert(xml_fsname_unexpanded != NULL);
875 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
876 tmp_xml_fd = VG_(connect_via_socket)( xml_fsname_unexpanded );
877 if (tmp_xml_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +0000878 VG_(fmsg)("Invalid --xml-socket spec of '%s'\n",
879 xml_fsname_unexpanded );
880 VG_(exit)(1);
sewardj738856f2009-07-15 14:48:32 +0000881 /*NOTREACHED*/
882 }
883 if (tmp_xml_fd == -2) {
njnb1cc5d62010-07-06 04:05:23 +0000884 VG_(umsg)("failed to connect to XML logging server '%s'.\n"
885 "XML output will sent to stderr instead.\n",
886 xml_fsname_unexpanded);
sewardj738856f2009-07-15 14:48:32 +0000887 /* We don't change anything here. */
888 vg_assert(VG_(xml_output_sink).fd == 2);
889 tmp_xml_fd = 2;
890 } else {
891 vg_assert(tmp_xml_fd > 0);
892 VG_(xml_output_sink).is_socket = True;
893 }
894 break;
895 }
sewardj71bc3cb2005-05-19 00:25:45 +0000896 }
897
sewardj738856f2009-07-15 14:48:32 +0000898 /* If we've got this far, and XML mode was requested, but no XML
899 output channel appears to have been specified, just stop. We
900 could continue, and XML output will simply vanish into nowhere,
901 but that is likely to confuse the hell out of users, which is
902 distinctly Ungood. */
903 if (VG_(clo_xml) && tmp_xml_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +0000904 VG_(fmsg_bad_option)(
905 "--xml=yes, but no XML destination specified",
sewardj738856f2009-07-15 14:48:32 +0000906 "--xml=yes has been specified, but there is no XML output\n"
907 "destination. You must specify an XML output destination\n"
njnb1cc5d62010-07-06 04:05:23 +0000908 "using --xml-fd, --xml-file or --xml-socket.\n"
909 );
sewardj738856f2009-07-15 14:48:32 +0000910 }
911
912 // Finalise the output fds: the log fd ..
913
njnda033f52005-12-19 21:27:58 +0000914 if (tmp_log_fd >= 0) {
sewardj738856f2009-07-15 14:48:32 +0000915 // Move log_fd into the safe range, so it doesn't conflict with
916 // any app fds.
njnda033f52005-12-19 21:27:58 +0000917 tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
918 if (tmp_log_fd < 0) {
sewardj738856f2009-07-15 14:48:32 +0000919 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd "
920 "into safe range, using stderr\n");
921 VG_(log_output_sink).fd = 2; // stderr
922 VG_(log_output_sink).is_socket = False;
njnda033f52005-12-19 21:27:58 +0000923 } else {
sewardj738856f2009-07-15 14:48:32 +0000924 VG_(log_output_sink).fd = tmp_log_fd;
925 VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
njnda033f52005-12-19 21:27:58 +0000926 }
927 } else {
928 // If they said --log-fd=-1, don't print anything. Plausible for use in
929 // regression testing suites that use client requests to count errors.
sewardj738856f2009-07-15 14:48:32 +0000930 VG_(log_output_sink).fd = -1;
931 VG_(log_output_sink).is_socket = False;
jsgf855d93d2003-10-13 22:26:55 +0000932 }
933
sewardj738856f2009-07-15 14:48:32 +0000934 // Finalise the output fds: and the XML fd ..
935
936 if (tmp_xml_fd >= 0) {
937 // Move xml_fd into the safe range, so it doesn't conflict with
938 // any app fds.
939 tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
940 if (tmp_xml_fd < 0) {
941 VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd "
942 "into safe range, using stderr\n");
943 VG_(xml_output_sink).fd = 2; // stderr
944 VG_(xml_output_sink).is_socket = False;
945 } else {
946 VG_(xml_output_sink).fd = tmp_xml_fd;
947 VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
948 }
949 } else {
950 // If they said --xml-fd=-1, don't print anything. Plausible for use in
951 // regression testing suites that use client requests to count errors.
952 VG_(xml_output_sink).fd = -1;
953 VG_(xml_output_sink).is_socket = False;
954 }
955
956 // Suppressions related stuff
957
sewardj45f4e7c2005-09-27 19:20:21 +0000958 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
959 (VG_(needs).core_errors || VG_(needs).tool_errors)) {
960 /* If we haven't reached the max number of suppressions, load
961 the default one. */
962 static const Char default_supp[] = "default.supp";
963 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
sewardj738856f2009-07-15 14:48:32 +0000964 Char *buf = VG_(arena_malloc)(VG_AR_CORE, "main.mpclo.3", len);
sewardj45f4e7c2005-09-27 19:20:21 +0000965 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
966 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
967 VG_(clo_n_suppressions)++;
968 }
sewardjde4a1d02002-03-22 01:27:54 +0000969
sewardj738856f2009-07-15 14:48:32 +0000970 *logging_to_fd = log_to == VgLogTo_Fd || log_to == VgLogTo_Socket;
sewardj45f4e7c2005-09-27 19:20:21 +0000971}
972
sewardj4efbaa72008-06-04 06:51:58 +0000973// Write the name and value of log file qualifiers to the xml file.
974static void print_file_vars(Char* format)
975{
976 Int i = 0;
977
978 while (format[i]) {
979 if (format[i] == '%') {
980 // We saw a '%'. What's next...
981 i++;
982 if ('q' == format[i]) {
983 i++;
984 if ('{' == format[i]) {
985 // Get the env var name, print its contents.
986 Char* qualname;
987 Char* qual;
988 i++;
989 qualname = &format[i];
990 while (True) {
991 if ('}' == format[i]) {
992 // Temporarily replace the '}' with NUL to extract var
993 // name.
994 format[i] = 0;
995 qual = VG_(getenv)(qualname);
996 break;
997 }
998 i++;
999 }
1000
sewardj7ca100d2009-08-15 23:05:34 +00001001 VG_(printf_xml_no_f_c)(
1002 "<logfilequalifier> <var>%t</var> "
1003 "<value>%t</value> </logfilequalifier>\n",
1004 qualname,qual
1005 );
sewardj4efbaa72008-06-04 06:51:58 +00001006 format[i] = '}';
1007 i++;
1008 }
1009 }
1010 } else {
1011 i++;
1012 }
1013 }
1014}
1015
sewardj45f4e7c2005-09-27 19:20:21 +00001016
1017/*====================================================================*/
1018/*=== Printing the preamble ===*/
1019/*====================================================================*/
1020
njnf8a11cf2009-08-02 23:03:06 +00001021// Print the command, escaping any chars that require it.
barta3054f52010-06-14 18:12:56 +00001022static void umsg_or_xml_arg(const Char* arg,
njnf8a11cf2009-08-02 23:03:06 +00001023 UInt (*umsg_or_xml)( const HChar*, ... ) )
1024{
1025 SizeT len = VG_(strlen)(arg);
1026 Char* special = " \\<>";
1027 Int i;
1028 for (i = 0; i < len; i++) {
1029 if (VG_(strchr)(special, arg[i])) {
1030 umsg_or_xml("\\"); // escape with a backslash if necessary
1031 }
1032 umsg_or_xml("%c", arg[i]);
1033 }
1034}
1035
sewardj45f4e7c2005-09-27 19:20:21 +00001036/* Ok, the logging sink is running now. Print a suitable preamble.
1037 If logging to file or a socket, write details of parent PID and
1038 command line args, to help people trying to interpret the
1039 results of a run which encompasses multiple processes. */
sewardj738856f2009-07-15 14:48:32 +00001040static void print_preamble ( Bool logging_to_fd,
1041 Char* xml_fname_unexpanded,
1042 const HChar* toolname )
sewardj45f4e7c2005-09-27 19:20:21 +00001043{
sewardj738856f2009-07-15 14:48:32 +00001044 Int i;
tom60a4b0b2005-10-12 10:45:27 +00001045 HChar* xpre = VG_(clo_xml) ? " <line>" : "";
1046 HChar* xpost = VG_(clo_xml) ? "</line>" : "";
sewardj738856f2009-07-15 14:48:32 +00001047 UInt (*umsg_or_xml)( const HChar*, ... )
1048 = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
tom60a4b0b2005-10-12 10:45:27 +00001049
sewardj14c7cc52007-02-25 15:08:24 +00001050 vg_assert( VG_(args_for_client) );
1051 vg_assert( VG_(args_for_valgrind) );
sewardj99a2ceb2007-11-09 12:30:36 +00001052 vg_assert( toolname );
sewardj14c7cc52007-02-25 15:08:24 +00001053
sewardj71bc3cb2005-05-19 00:25:45 +00001054 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001055 VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
1056 VG_(printf_xml)("\n");
1057 VG_(printf_xml)("<valgrindoutput>\n");
1058 VG_(printf_xml)("\n");
1059 VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
1060 VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", toolname);
1061 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001062 }
1063
sewardj738856f2009-07-15 14:48:32 +00001064 if (VG_(clo_xml) || VG_(clo_verbosity > 0)) {
sewardjd7bddad2005-06-13 16:48:32 +00001065
1066 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001067 VG_(printf_xml)("<preamble>\n");
sewardjd7bddad2005-06-13 16:48:32 +00001068
nethercote996901a2004-08-03 13:29:09 +00001069 /* Tool details */
sewardj743a2082010-07-23 17:03:22 +00001070 umsg_or_xml( VG_(clo_xml) ? "%s%t%t%t, %t%s\n" : "%s%s%s%s, %s%s\n",
sewardj71bc3cb2005-05-19 00:25:45 +00001071 xpre,
njnd04b7c62002-10-03 14:05:52 +00001072 VG_(details).name,
njnb9c427c2004-12-01 14:14:42 +00001073 NULL == VG_(details).version ? "" : "-",
njnd04b7c62002-10-03 14:05:52 +00001074 NULL == VG_(details).version
1075 ? (Char*)"" : VG_(details).version,
sewardj71bc3cb2005-05-19 00:25:45 +00001076 VG_(details).description,
sewardj738856f2009-07-15 14:48:32 +00001077 xpost );
sewardj99a2ceb2007-11-09 12:30:36 +00001078
njn10b9aea2009-07-14 06:55:05 +00001079 if (VG_(strlen)(toolname) >= 4 && VG_STREQN(4, toolname, "exp-")) {
sewardj738856f2009-07-15 14:48:32 +00001080 umsg_or_xml(
njnb6267bd2009-08-12 00:14:16 +00001081 "%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
sewardj99a2ceb2007-11-09 12:30:36 +00001082 xpre, xpost
1083 );
1084 }
1085
sewardj743a2082010-07-23 17:03:22 +00001086 umsg_or_xml( VG_(clo_xml) ? "%s%t%s\n" : "%s%s%s\n",
1087 xpre, VG_(details).copyright_author, xpost );
sewardj3b2736a2002-03-24 12:18:35 +00001088
njnd04b7c62002-10-03 14:05:52 +00001089 /* Core details */
sewardj738856f2009-07-15 14:48:32 +00001090 umsg_or_xml(
njnf73d87f2009-07-24 04:47:04 +00001091 "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
1092 xpre, VERSION, xpost
sewardj738856f2009-07-15 14:48:32 +00001093 );
sewardj45f4e7c2005-09-27 19:20:21 +00001094
njnf3977a32009-08-04 00:27:56 +00001095 // Print the command line. At one point we wrapped at 80 chars and
1096 // printed a '\' as a line joiner, but that makes it hard to cut and
1097 // paste the command line (because of the "==pid==" prefixes), so we now
1098 // favour utility and simplicity over aesthetics.
1099 umsg_or_xml("%sCommand: ", xpre);
njn53162bf2009-07-29 23:34:49 +00001100 if (VG_(args_the_exename))
njnf8a11cf2009-08-02 23:03:06 +00001101 umsg_or_xml_arg(VG_(args_the_exename), umsg_or_xml);
njn53162bf2009-07-29 23:34:49 +00001102 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1103 HChar* s = *(HChar**)VG_(indexXA)( VG_(args_for_client), i );
njnf8a11cf2009-08-02 23:03:06 +00001104 umsg_or_xml(" ");
1105 umsg_or_xml_arg(s, umsg_or_xml);
njn53162bf2009-07-29 23:34:49 +00001106 }
njnf3977a32009-08-04 00:27:56 +00001107 umsg_or_xml("%s\n", xpost);
njn53162bf2009-07-29 23:34:49 +00001108
sewardjd7bddad2005-06-13 16:48:32 +00001109 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001110 VG_(printf_xml)("</preamble>\n");
njnd04b7c62002-10-03 14:05:52 +00001111 }
1112
njnb6267bd2009-08-12 00:14:16 +00001113 // Print the parent PID, and other stuff, if necessary.
sewardj45f4e7c2005-09-27 19:20:21 +00001114 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
njn305dc002009-07-30 23:36:43 +00001115 VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
sewardj4cf05692002-10-27 20:28:29 +00001116 }
sewardj71bc3cb2005-05-19 00:25:45 +00001117 else
1118 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001119 VG_(printf_xml)("\n");
1120 VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
1121 VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
1122 VG_(printf_xml_no_f_c)("<tool>%t</tool>\n", toolname);
1123 if (xml_fname_unexpanded)
1124 print_file_vars(xml_fname_unexpanded);
sewardj768db0e2005-07-19 14:18:56 +00001125 if (VG_(clo_xml_user_comment)) {
1126 /* Note: the user comment itself is XML and is therefore to
1127 be passed through verbatim (%s) rather than escaped
1128 (%t). */
sewardj738856f2009-07-15 14:48:32 +00001129 VG_(printf_xml)("<usercomment>%s</usercomment>\n",
1130 VG_(clo_xml_user_comment));
sewardj768db0e2005-07-19 14:18:56 +00001131 }
sewardj738856f2009-07-15 14:48:32 +00001132 VG_(printf_xml)("\n");
1133 VG_(printf_xml)("<args>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001134
sewardj738856f2009-07-15 14:48:32 +00001135 VG_(printf_xml)(" <vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001136 if (VG_(name_of_launcher))
sewardj738856f2009-07-15 14:48:32 +00001137 VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
1138 VG_(name_of_launcher));
sewardj125fd4f2007-03-08 19:56:14 +00001139 else
njnb1cc5d62010-07-06 04:05:23 +00001140 VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
1141 "(launcher name unknown)");
sewardj14c7cc52007-02-25 15:08:24 +00001142 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
sewardj738856f2009-07-15 14:48:32 +00001143 VG_(printf_xml_no_f_c)(
1144 " <arg>%t</arg>\n",
1145 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1146 );
sewardjb8a3dac2005-07-19 12:39:11 +00001147 }
sewardj738856f2009-07-15 14:48:32 +00001148 VG_(printf_xml)(" </vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001149
sewardj738856f2009-07-15 14:48:32 +00001150 VG_(printf_xml)(" <argv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001151 if (VG_(args_the_exename))
sewardj738856f2009-07-15 14:48:32 +00001152 VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
1153 VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001154 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
sewardj738856f2009-07-15 14:48:32 +00001155 VG_(printf_xml_no_f_c)(
1156 " <arg>%t</arg>\n",
1157 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1158 );
sewardj8665d8e2005-06-01 17:35:23 +00001159 }
sewardj738856f2009-07-15 14:48:32 +00001160 VG_(printf_xml)(" </argv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001161
sewardj738856f2009-07-15 14:48:32 +00001162 VG_(printf_xml)("</args>\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001163 }
sewardj4cf05692002-10-27 20:28:29 +00001164
njnb6267bd2009-08-12 00:14:16 +00001165 // Last thing in the preamble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00001166 if (VG_(clo_xml))
1167 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00001168 else if (VG_(clo_verbosity) > 0)
1169 VG_(umsg)("\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001170
sewardjde4a1d02002-03-22 01:27:54 +00001171 if (VG_(clo_verbosity) > 1) {
sewardj92645592005-07-23 09:18:34 +00001172 SysRes fd;
sewardj1f0bbc72005-11-16 03:51:02 +00001173 VexArch vex_arch;
1174 VexArchInfo vex_archinfo;
sewardj45f4e7c2005-09-27 19:20:21 +00001175 if (!logging_to_fd)
sewardj738856f2009-07-15 14:48:32 +00001176 VG_(message)(Vg_DebugMsg, "\n");
njna3311642009-08-10 01:29:14 +00001177 VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
sewardj14c7cc52007-02-25 15:08:24 +00001178 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
1179 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001180 " %s\n",
sewardj14c7cc52007-02-25 15:08:24 +00001181 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjde4a1d02002-03-22 01:27:54 +00001182 }
nethercotea70f7352004-04-18 12:08:46 +00001183
sewardj738856f2009-07-15 14:48:32 +00001184 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
nethercotea70f7352004-04-18 12:08:46 +00001185 fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
njncda2f0f2009-05-18 02:12:08 +00001186 if (sr_isError(fd)) {
sewardj738856f2009-07-15 14:48:32 +00001187 VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
nethercotea70f7352004-04-18 12:08:46 +00001188 } else {
sewardj71bc3cb2005-05-19 00:25:45 +00001189# define BUF_LEN 256
nethercotea70f7352004-04-18 12:08:46 +00001190 Char version_buf[BUF_LEN];
njnf3977a32009-08-04 00:27:56 +00001191 Int n = VG_(read) ( sr_Res(fd), version_buf, BUF_LEN );
1192 vg_assert(n <= BUF_LEN);
1193 if (n > 0) {
1194 version_buf[n-1] = '\0';
sewardj738856f2009-07-15 14:48:32 +00001195 VG_(message)(Vg_DebugMsg, " %s\n", version_buf);
nethercotea70f7352004-04-18 12:08:46 +00001196 } else {
sewardj738856f2009-07-15 14:48:32 +00001197 VG_(message)(Vg_DebugMsg, " (empty?)\n");
nethercotea70f7352004-04-18 12:08:46 +00001198 }
njncda2f0f2009-05-18 02:12:08 +00001199 VG_(close)(sr_Res(fd));
sewardj71bc3cb2005-05-19 00:25:45 +00001200# undef BUF_LEN
nethercotea70f7352004-04-18 12:08:46 +00001201 }
sewardj1f0bbc72005-11-16 03:51:02 +00001202
1203 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001204 VG_(message)(
1205 Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001206 "Arch and hwcaps: %s, %s\n",
sewardje3121f32006-01-27 21:23:23 +00001207 LibVEX_ppVexArch ( vex_arch ),
1208 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1209 );
sewardje66f2e02006-12-30 17:45:08 +00001210 VG_(message)(
1211 Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001212 "Page sizes: currently %d, max supported %d\n",
sewardje66f2e02006-12-30 17:45:08 +00001213 (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
1214 );
sewardj738856f2009-07-15 14:48:32 +00001215 VG_(message)(Vg_DebugMsg,
1216 "Valgrind library directory: %s\n", VG_(libdir));
sewardjde4a1d02002-03-22 01:27:54 +00001217 }
nethercotef6a1d502004-08-09 12:21:57 +00001218}
1219
sewardjde4a1d02002-03-22 01:27:54 +00001220
nethercote71980f02004-01-24 18:18:54 +00001221/*====================================================================*/
1222/*=== File descriptor setup ===*/
1223/*====================================================================*/
1224
sewardj5f229e22005-09-28 01:36:01 +00001225/* Number of file descriptors that Valgrind tries to reserve for
1226 it's own use - just a small constant. */
1227#define N_RESERVED_FDS (10)
1228
nethercote71980f02004-01-24 18:18:54 +00001229static void setup_file_descriptors(void)
1230{
1231 struct vki_rlimit rl;
sewardj17c11042006-10-15 01:26:40 +00001232 Bool show = False;
nethercote71980f02004-01-24 18:18:54 +00001233
1234 /* Get the current file descriptor limits. */
1235 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
1236 rl.rlim_cur = 1024;
1237 rl.rlim_max = 1024;
1238 }
1239
njnf76d27a2009-05-28 01:53:07 +00001240# if defined(VGO_darwin)
1241 /* Darwin lies. It reports file max as RLIM_INFINITY but
1242 silently disallows anything bigger than 10240. */
1243 if (rl.rlim_cur >= 10240 && rl.rlim_max == 0x7fffffffffffffffULL) {
1244 rl.rlim_max = 10240;
1245 }
1246# endif
1247
sewardj17c11042006-10-15 01:26:40 +00001248 if (show)
njn8a7b41b2007-09-23 00:51:24 +00001249 VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001250 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001251
nethercote71980f02004-01-24 18:18:54 +00001252 /* Work out where to move the soft limit to. */
njn14319cc2005-03-13 06:26:22 +00001253 if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
1254 rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001255 } else {
1256 rl.rlim_cur = rl.rlim_max;
1257 }
1258
1259 /* Reserve some file descriptors for our use. */
njn14319cc2005-03-13 06:26:22 +00001260 VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
1261 VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001262
1263 /* Update the soft limit. */
1264 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
1265
sewardj17c11042006-10-15 01:26:40 +00001266 if (show) {
njn8a7b41b2007-09-23 00:51:24 +00001267 VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001268 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001269 VG_(printf)("fd limits: guest : cur %u max %u\n",
1270 VG_(fd_soft_limit), VG_(fd_hard_limit));
1271 }
1272
sewardj45f4e7c2005-09-27 19:20:21 +00001273 if (VG_(cl_exec_fd) != -1)
1274 VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
nethercote71980f02004-01-24 18:18:54 +00001275}
1276
sewardjde4a1d02002-03-22 01:27:54 +00001277
njn2da73352005-06-18 01:35:16 +00001278/*====================================================================*/
njn2025cf92005-06-26 20:44:48 +00001279/*=== BB profiling ===*/
1280/*====================================================================*/
1281
1282static
1283void show_BB_profile ( BBProfEntry tops[], UInt n_tops, ULong score_total )
1284{
1285 ULong score_cumul, score_here;
1286 Char buf_cumul[10], buf_here[10];
1287 Char name[64];
1288 Int r;
1289
1290 VG_(printf)("\n");
1291 VG_(printf)("-----------------------------------------------------------\n");
1292 VG_(printf)("--- BEGIN BB Profile (summary of scores) ---\n");
1293 VG_(printf)("-----------------------------------------------------------\n");
1294 VG_(printf)("\n");
1295
1296 VG_(printf)("Total score = %lld\n\n", score_total);
1297
1298 score_cumul = 0;
1299 for (r = 0; r < n_tops; r++) {
1300 if (tops[r].addr == 0)
1301 continue;
1302 name[0] = 0;
1303 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1304 name[63] = 0;
1305 score_here = tops[r].score;
1306 score_cumul += score_here;
1307 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1308 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1309 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1310 r,
1311 score_cumul, buf_cumul,
1312 score_here, buf_here, tops[r].addr, name );
1313 }
1314
1315 VG_(printf)("\n");
1316 VG_(printf)("-----------------------------------------------------------\n");
1317 VG_(printf)("--- BB Profile (BB details) ---\n");
1318 VG_(printf)("-----------------------------------------------------------\n");
1319 VG_(printf)("\n");
1320
1321 score_cumul = 0;
1322 for (r = 0; r < n_tops; r++) {
1323 if (tops[r].addr == 0)
1324 continue;
1325 name[0] = 0;
1326 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1327 name[63] = 0;
1328 score_here = tops[r].score;
1329 score_cumul += score_here;
1330 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1331 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1332 VG_(printf)("\n");
1333 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin BB rank %d "
1334 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1335 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1336 r,
1337 score_cumul, buf_cumul,
1338 score_here, buf_here, tops[r].addr, name );
1339 VG_(printf)("\n");
sewardjbcccbc02007-04-09 22:24:57 +00001340 VG_(discard_translations)(tops[r].addr, 1, "bb profile");
sewardj0ec07f32006-01-12 12:32:32 +00001341 VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0, True);
njn2025cf92005-06-26 20:44:48 +00001342 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= end BB rank %d "
1343 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1344 }
1345
1346 VG_(printf)("\n");
1347 VG_(printf)("-----------------------------------------------------------\n");
1348 VG_(printf)("--- END BB Profile ---\n");
1349 VG_(printf)("-----------------------------------------------------------\n");
1350 VG_(printf)("\n");
1351}
1352
1353
1354/*====================================================================*/
nethercote71980f02004-01-24 18:18:54 +00001355/*=== main() ===*/
1356/*====================================================================*/
1357
sewardjfdf91b42005-09-28 00:53:09 +00001358/* When main() is entered, we should be on the following stack, not
1359 the one the kernel gave us. We will run on this stack until
1360 simulation of the root thread is started, at which point a transfer
1361 is made to a dynamically allocated stack. This is for the sake of
1362 uniform overflow detection for all Valgrind threads. This is
1363 marked global even though it isn't, because assembly code below
1364 needs to reference the name. */
1365
1366/*static*/ VgStack VG_(interim_stack);
1367
sewardjf9d2f9b2006-11-17 20:00:57 +00001368/* These are the structures used to hold info for creating the initial
1369 client image.
1370
1371 'iicii' mostly holds important register state present at system
1372 startup (_start_valgrind). valgrind_main() then fills in the rest
1373 of it and passes it to VG_(ii_create_image)(). That produces
1374 'iifii', which is later handed to VG_(ii_finalise_image). */
1375
1376/* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1377 This should get some address inside the stack on which we gained
sewardjfdf91b42005-09-28 00:53:09 +00001378 control (eg, it could be the SP at startup). It doesn't matter
1379 exactly where in the stack it is. This value is passed to the
sewardjf9d2f9b2006-11-17 20:00:57 +00001380 address space manager at startup. On Linux, aspacem then uses it
1381 to identify the initial stack segment and hence the upper end of
1382 the usable address space. */
sewardjfdf91b42005-09-28 00:53:09 +00001383
sewardjf9d2f9b2006-11-17 20:00:57 +00001384static IICreateImageInfo the_iicii;
1385static IIFinaliseImageInfo the_iifii;
1386
sewardjfdf91b42005-09-28 00:53:09 +00001387
sewardj9c606bd2008-09-18 18:12:50 +00001388/* A simple pair structure, used for conveying debuginfo handles to
1389 calls to VG_TRACK(new_mem_startup, ...). */
1390typedef struct { Addr a; ULong ull; } Addr_n_ULong;
1391
1392
sewardj1ae3f3a2005-09-28 10:47:38 +00001393/* --- Forwards decls to do with shutdown --- */
1394
1395static void final_tidyup(ThreadId tid);
1396
1397/* Do everything which needs doing when the last thread exits */
1398static
1399void shutdown_actions_NORETURN( ThreadId tid,
1400 VgSchedReturnCode tids_schedretcode );
1401
1402/* --- end of Forwards decls to do with shutdown --- */
sewardjfdf91b42005-09-28 00:53:09 +00001403
1404
sewardjf9d2f9b2006-11-17 20:00:57 +00001405/* By the time we get to valgrind_main, the_iicii should already have
1406 been filled in with any important details as required by whatever
1407 OS we have been built for.
1408*/
sewardj17c11042006-10-15 01:26:40 +00001409static
sewardjf9d2f9b2006-11-17 20:00:57 +00001410Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
nethercote71980f02004-01-24 18:18:54 +00001411{
sewardj13247ca2005-12-30 22:52:20 +00001412 HChar* toolname = "memcheck"; // default to Memcheck
sewardj13247ca2005-12-30 22:52:20 +00001413 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
sewardjde764e82007-11-09 23:13:22 +00001414 ThreadId tid_main = VG_INVALID_THREADID;
sewardj738856f2009-07-15 14:48:32 +00001415 Bool logging_to_fd = False;
1416 Char* xml_fname_unexpanded = NULL;
sewardj45f4e7c2005-09-27 19:20:21 +00001417 Int loglevel, i;
nethercote73b526f2004-10-31 18:48:21 +00001418 struct vki_rlimit zero = { 0, 0 };
sewardj9c606bd2008-09-18 18:12:50 +00001419 XArray* addr2dihandle = NULL;
sewardj17c11042006-10-15 01:26:40 +00001420
nethercote71980f02004-01-24 18:18:54 +00001421 //============================================================
nethercote71980f02004-01-24 18:18:54 +00001422 //
sewardj45f4e7c2005-09-27 19:20:21 +00001423 // Nb: startup is complex. Prerequisites are shown at every step.
nethercote71980f02004-01-24 18:18:54 +00001424 // *** Be very careful when messing with the order ***
sewardj45f4e7c2005-09-27 19:20:21 +00001425 //
1426 // The first order of business is to get debug logging, the address
1427 // space manager and the dynamic memory manager up and running.
1428 // Once that's done, we can relax a bit.
1429 //
nethercote71980f02004-01-24 18:18:54 +00001430 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001431
1432 /* This is needed to make VG_(getenv) usable early. */
1433 VG_(client_envp) = (Char**)envp;
nethercote71980f02004-01-24 18:18:54 +00001434
sewardj1cf558c2005-04-25 01:36:56 +00001435 //--------------------------------------------------------------
njnf76d27a2009-05-28 01:53:07 +00001436 // Start up Mach kernel interface, if any
1437 // p: none
1438 //--------------------------------------------------------------
1439# if defined(VGO_darwin)
1440 VG_(mach_init)();
1441# endif
1442
1443 //--------------------------------------------------------------
sewardj1cf558c2005-04-25 01:36:56 +00001444 // Start up the logging mechanism
1445 // p: none
1446 //--------------------------------------------------------------
1447 /* Start the debugging-log system ASAP. First find out how many
njn83df0b62009-02-25 01:01:05 +00001448 "-d"s were specified. This is a pre-scan of the command line. Also
1449 get --profile-heap=yes which is needed by the time we start up dynamic
1450 memory management. */
sewardj1cf558c2005-04-25 01:36:56 +00001451 loglevel = 0;
1452 for (i = 1; i < argc; i++) {
njn83df0b62009-02-25 01:01:05 +00001453 if (argv[i][0] != '-') break;
1454 if VG_STREQ(argv[i], "--") break;
1455 if VG_STREQ(argv[i], "-d") loglevel++;
1456 if VG_BOOL_CLO(argv[i], "--profile-heap", VG_(clo_profile_heap)) {}
sewardj1cf558c2005-04-25 01:36:56 +00001457 }
1458
1459 /* ... and start the debug logger. Now we can safely emit logging
1460 messages all through startup. */
sewardj10759312005-05-30 23:52:47 +00001461 VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
sewardj45f4e7c2005-09-27 19:20:21 +00001462 VG_(debugLog)(1, "main", "Welcome to Valgrind version "
1463 VERSION " debug logging\n");
1464
1465 //--------------------------------------------------------------
1466 // Ensure we're on a plausible stack.
1467 // p: logging
1468 //--------------------------------------------------------------
1469 VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
sewardjfdf91b42005-09-28 00:53:09 +00001470 { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
1471 HChar* limHi = limLo + sizeof(VG_(interim_stack));
sewardj45f4e7c2005-09-27 19:20:21 +00001472 HChar* aLocal = (HChar*)&zero; /* any auto local will do */
1473 if (aLocal < limLo || aLocal >= limHi) {
1474 /* something's wrong. Stop. */
1475 VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
1476 limLo, limHi, aLocal );
1477 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1478 "Initial stack switched failed.\n");
1479 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1480 VG_(exit)(1);
1481 }
1482 }
1483
1484 //--------------------------------------------------------------
1485 // Ensure we have a plausible pointer to the stack on which
1486 // we gained control (not the current stack!)
1487 // p: logging
1488 //--------------------------------------------------------------
1489 VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
sewardjf9d2f9b2006-11-17 20:00:57 +00001490 if (the_iicii.sp_at_startup == 0) {
sewardj45f4e7c2005-09-27 19:20:21 +00001491 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1492 "Initial stack was not noted.\n");
1493 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1494 VG_(exit)(1);
1495 }
1496
1497 //--------------------------------------------------------------
1498 // Start up the address space manager, and determine the
1499 // approximate location of the client's stack
njnea2d6fd2010-07-01 00:20:20 +00001500 // p: logging, plausible-stack
sewardj45f4e7c2005-09-27 19:20:21 +00001501 //--------------------------------------------------------------
1502 VG_(debugLog)(1, "main", "Starting the address space manager\n");
sewardje66f2e02006-12-30 17:45:08 +00001503 vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536);
1504 vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536);
1505 vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
1506 vg_assert(VKI_PAGE_SIZE == (1 << VKI_PAGE_SHIFT));
1507 vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
sewardjf9d2f9b2006-11-17 20:00:57 +00001508 the_iicii.clstack_top = VG_(am_startup)( the_iicii.sp_at_startup );
sewardj45f4e7c2005-09-27 19:20:21 +00001509 VG_(debugLog)(1, "main", "Address space manager is running\n");
1510
1511 //--------------------------------------------------------------
1512 // Start up the dynamic memory manager
1513 // p: address space management
njn83df0b62009-02-25 01:01:05 +00001514 // p: getting --profile-heap
sewardj45f4e7c2005-09-27 19:20:21 +00001515 // In fact m_mallocfree is self-initialising, so there's no
1516 // initialisation call to do. Instead, try a simple malloc/
1517 // free pair right now to check that nothing is broken.
1518 //--------------------------------------------------------------
1519 VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
sewardj9c606bd2008-09-18 18:12:50 +00001520 { void* p = VG_(malloc)( "main.vm.1", 12345 );
sewardj45f4e7c2005-09-27 19:20:21 +00001521 if (p) VG_(free)( p );
1522 }
1523 VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
sewardj1cf558c2005-04-25 01:36:56 +00001524
nethercotef4928da2004-06-15 10:54:40 +00001525 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001526 //
1527 // Dynamic memory management is now available.
1528 //
nethercotef4928da2004-06-15 10:54:40 +00001529 //============================================================
1530
sewardj45f4e7c2005-09-27 19:20:21 +00001531 //--------------------------------------------------------------
sewardjf98e1c02008-10-25 16:22:41 +00001532 // Initialise m_debuginfo
1533 // p: dynamic memory allocation
1534 VG_(debugLog)(1, "main", "Initialise m_debuginfo\n");
1535 VG_(di_initialise)();
1536
1537 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001538 // Look for alternative libdir
1539 { HChar *cp = VG_(getenv)(VALGRIND_LIB);
1540 if (cp != NULL)
1541 VG_(libdir) = cp;
njncde90d32009-07-22 22:41:38 +00001542 VG_(debugLog)(1, "main", "VG_(libdir) = %s\n", VG_(libdir));
sewardj45f4e7c2005-09-27 19:20:21 +00001543 }
1544
1545 //--------------------------------------------------------------
1546 // Extract the launcher name from the environment.
njna842d792009-05-21 01:15:18 +00001547 VG_(debugLog)(1, "main", "Getting launcher's name ...\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001548 VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
1549 if (VG_(name_of_launcher) == NULL) {
1550 VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
1551 VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
1552 VG_(exit)(1);
1553 }
njna842d792009-05-21 01:15:18 +00001554 VG_(debugLog)(1, "main", "... %s\n", VG_(name_of_launcher));
sewardj45f4e7c2005-09-27 19:20:21 +00001555
1556 //--------------------------------------------------------------
fitzhardingeb50068f2004-02-24 23:42:55 +00001557 // Get the current process datasize rlimit, and set it to zero.
1558 // This prevents any internal uses of brk() from having any effect.
1559 // We remember the old value so we can restore it on exec, so that
1560 // child processes will have a reasonable brk value.
1561 VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1562 zero.rlim_max = VG_(client_rlimit_data).rlim_max;
1563 VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
thughesc37184f2004-09-11 14:16:57 +00001564
1565 // Get the current process stack rlimit.
1566 VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
1567
sewardje2d1e672005-11-12 23:10:48 +00001568 //--------------------------------------------------------------
1569 // Figure out what sort of CPU we're on, and whether it is
1570 // able to run V.
1571 VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
1572 { VexArch vex_arch;
1573 VexArchInfo vex_archinfo;
1574 Bool ok = VG_(machine_get_hwcaps)();
1575 if (!ok) {
1576 VG_(printf)("\n");
1577 VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
1578 VG_(printf)(" Supported CPUs are:\n");
1579 VG_(printf)(" * x86 (practically any; Pentium-I or above), "
1580 "AMD Athlon or above)\n");
1581 VG_(printf)(" * AMD Athlon64/Opteron\n");
1582 VG_(printf)(" * PowerPC (most; ppc405 and above)\n");
sewardjb5b87402011-03-07 16:05:35 +00001583 VG_(printf)(" * System z (64bit only - s390x; z900 and above)\n");
sewardje2d1e672005-11-12 23:10:48 +00001584 VG_(printf)("\n");
1585 VG_(exit)(1);
1586 }
1587 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001588 VG_(debugLog)(
1589 1, "main", "... arch = %s, hwcaps = %s\n",
1590 LibVEX_ppVexArch ( vex_arch ),
1591 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1592 );
sewardje2d1e672005-11-12 23:10:48 +00001593 }
1594
sewardj198f34f2007-07-09 23:13:07 +00001595 //--------------------------------------------------------------
1596 // Record the working directory at startup
sewardj6e9de462011-06-28 07:25:29 +00001597 // p: none
sewardj198f34f2007-07-09 23:13:07 +00001598 VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
1599 { Bool ok = VG_(record_startup_wd)();
1600 if (!ok)
1601 VG_(err_config_error)( "Can't establish current working "
florian1763e812011-07-12 19:07:05 +00001602 "directory at startup\n");
sewardj198f34f2007-07-09 23:13:07 +00001603 }
1604 { Char buf[VKI_PATH_MAX+1];
1605 Bool ok = VG_(get_startup_wd)( buf, sizeof(buf) );
1606 vg_assert(ok);
1607 buf[VKI_PATH_MAX] = 0;
1608 VG_(debugLog)(1, "main", "... %s\n", buf );
1609 }
1610
sewardj45f4e7c2005-09-27 19:20:21 +00001611 //============================================================
1612 // Command line argument handling order:
1613 // * If --help/--help-debug are present, show usage message
1614 // (including the tool-specific usage)
1615 // * (If no --tool option given, default to Memcheck)
1616 // * Then, if client is missing, abort with error msg
1617 // * Then, if any cmdline args are bad, abort with error msg
1618 //============================================================
1619
1620 //--------------------------------------------------------------
1621 // Split up argv into: C args, V args, V extra args, and exename.
1622 // p: dynamic memory allocation
1623 //--------------------------------------------------------------
1624 VG_(debugLog)(1, "main", "Split up command line\n");
1625 VG_(split_up_argv)( argc, argv );
sewardj14c7cc52007-02-25 15:08:24 +00001626 vg_assert( VG_(args_for_valgrind) );
1627 vg_assert( VG_(args_for_client) );
sewardj45f4e7c2005-09-27 19:20:21 +00001628 if (0) {
sewardj14c7cc52007-02-25 15:08:24 +00001629 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
1630 VG_(printf)(
1631 "varg %s\n",
1632 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1633 );
sewardj45f4e7c2005-09-27 19:20:21 +00001634 VG_(printf)(" exe %s\n", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001635 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
1636 VG_(printf)(
1637 "carg %s\n",
1638 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1639 );
nethercote71980f02004-01-24 18:18:54 +00001640 }
1641
1642 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001643 // Extract tool name and whether help has been requested.
1644 // Note we can't print the help message yet, even if requested,
1645 // because the tool has not been initialised.
1646 // p: split_up_argv [for VG_(args_for_valgrind)]
nethercote71980f02004-01-24 18:18:54 +00001647 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001648 VG_(debugLog)(1, "main",
1649 "(early_) Process Valgrind's command line options\n");
1650 early_process_cmd_line_options(&need_help, &toolname);
nethercote71980f02004-01-24 18:18:54 +00001651
sewardj45f4e7c2005-09-27 19:20:21 +00001652 // Set default vex control params
1653 LibVEX_default_VexControl(& VG_(clo_vex_control));
nethercote71980f02004-01-24 18:18:54 +00001654
1655 //--------------------------------------------------------------
1656 // Load client executable, finding in $PATH if necessary
njn83df0b62009-02-25 01:01:05 +00001657 // p: early_process_cmd_line_options() [for 'exec', 'need_help',
1658 // clo_max_stackframe,
1659 // clo_main_stacksize]
sewardj95d86c02007-12-18 01:49:23 +00001660 // p: layout_remaining_space [so there's space]
sewardj17c11042006-10-15 01:26:40 +00001661 //
nethercote71980f02004-01-24 18:18:54 +00001662 // Set up client's environment
sewardj95d86c02007-12-18 01:49:23 +00001663 // p: set-libdir [for VG_(libdir)]
1664 // p: early_process_cmd_line_options [for toolname]
sewardj17c11042006-10-15 01:26:40 +00001665 //
nethercote5ee67ca2004-06-22 14:00:09 +00001666 // Setup client stack, eip, and VG_(client_arg[cv])
nethercote71980f02004-01-24 18:18:54 +00001667 // p: load_client() [for 'info']
1668 // p: fix_environment() [for 'env']
sewardj17c11042006-10-15 01:26:40 +00001669 //
sewardj45f4e7c2005-09-27 19:20:21 +00001670 // Setup client data (brk) segment. Initially a 1-page segment
1671 // which abuts a shrinkable reservation.
1672 // p: load_client() [for 'info' and hence VG_(brk_base)]
sewardjf9d2f9b2006-11-17 20:00:57 +00001673 //
1674 // p: _start_in_C (for zeroing out the_iicii and putting some
1675 // initial values into it)
sewardj45f4e7c2005-09-27 19:20:21 +00001676 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001677 if (!need_help) {
sewardjf9d2f9b2006-11-17 20:00:57 +00001678 VG_(debugLog)(1, "main", "Create initial image\n");
1679
njnf76d27a2009-05-28 01:53:07 +00001680# if defined(VGO_linux) || defined(VGO_darwin)
sewardjf9d2f9b2006-11-17 20:00:57 +00001681 the_iicii.argv = argv;
1682 the_iicii.envp = envp;
1683 the_iicii.toolname = toolname;
sewardjf9d2f9b2006-11-17 20:00:57 +00001684# else
njna842d792009-05-21 01:15:18 +00001685# error "Unknown platform"
sewardjf9d2f9b2006-11-17 20:00:57 +00001686# endif
1687
sewardjdc2f79e2007-12-22 14:14:04 +00001688 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001689 the_iifii = VG_(ii_create_image)( the_iicii );
sewardj45f4e7c2005-09-27 19:20:21 +00001690 }
nethercote71980f02004-01-24 18:18:54 +00001691
1692 //==============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001693 //
1694 // Finished loading/setting up the client address space.
1695 //
nethercote71980f02004-01-24 18:18:54 +00001696 //==============================================================
1697
1698 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001699 // setup file descriptors
1700 // p: n/a
1701 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001702 VG_(debugLog)(1, "main", "Setup file descriptors\n");
nethercote71980f02004-01-24 18:18:54 +00001703 setup_file_descriptors();
1704
1705 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001706 // create the fake /proc/<pid>/cmdline file and then unlink it,
1707 // but hold onto the fd, so we can hand it out to the client
1708 // when it tries to open /proc/<pid>/cmdline for itself.
1709 // p: setup file descriptors
nethercotec314eba2004-07-15 12:59:41 +00001710 //--------------------------------------------------------------
bart9b533f82009-08-25 20:15:41 +00001711#if !defined(VGO_linux)
1712 // client shouldn't be using /proc!
1713 VG_(cl_cmdline_fd) = -1;
1714#else
1715 if (!need_help) {
1716 HChar buf[50], buf2[50+64];
1717 HChar nul[1];
1718 Int fd, r;
barta3054f52010-06-14 18:12:56 +00001719 const HChar* exename;
nethercotec314eba2004-07-15 12:59:41 +00001720
bart9b533f82009-08-25 20:15:41 +00001721 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001722
bart9b533f82009-08-25 20:15:41 +00001723 VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
1724 fd = VG_(mkstemp)( buf, buf2 );
1725 if (fd == -1)
florian1763e812011-07-12 19:07:05 +00001726 VG_(err_config_error)("Can't create client cmdline file in %s\n", buf2);
sewardj45f4e7c2005-09-27 19:20:21 +00001727
bart9b533f82009-08-25 20:15:41 +00001728 nul[0] = 0;
1729 exename = VG_(args_the_exename) ? VG_(args_the_exename)
1730 : "unknown_exename";
sewardjc7ffc942011-03-28 16:26:42 +00001731 VG_(write)(fd, exename, VG_(strlen)( exename ));
bart9b533f82009-08-25 20:15:41 +00001732 VG_(write)(fd, nul, 1);
1733
1734 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1735 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
1736 VG_(write)(fd, arg, VG_(strlen)( arg ));
sewardj45f4e7c2005-09-27 19:20:21 +00001737 VG_(write)(fd, nul, 1);
1738 }
bart9b533f82009-08-25 20:15:41 +00001739
1740 /* Don't bother to seek the file back to the start; instead do
1741 it every time a copy of it is given out (by PRE(sys_open)).
1742 That is probably more robust across fork() etc. */
1743
1744 /* Now delete it, but hang on to the fd. */
1745 r = VG_(unlink)( buf2 );
1746 if (r)
florian1763e812011-07-12 19:07:05 +00001747 VG_(err_config_error)("Can't delete client cmdline file in %s\n", buf2);
bart9b533f82009-08-25 20:15:41 +00001748
1749 VG_(cl_cmdline_fd) = fd;
sewardj45f4e7c2005-09-27 19:20:21 +00001750 }
bart9b533f82009-08-25 20:15:41 +00001751#endif
nethercotec314eba2004-07-15 12:59:41 +00001752
1753 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001754 // Init tool part 1: pre_clo_init
nethercotec314eba2004-07-15 12:59:41 +00001755 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
nethercotec314eba2004-07-15 12:59:41 +00001756 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
nethercote71980f02004-01-24 18:18:54 +00001757 //--------------------------------------------------------------
sewardj7cf4e6b2008-05-01 20:24:26 +00001758 VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
njn08ce7b32009-02-27 03:38:28 +00001759 VG_(tl_pre_clo_init)();
nethercote71980f02004-01-24 18:18:54 +00001760
sewardj45f4e7c2005-09-27 19:20:21 +00001761 //--------------------------------------------------------------
nethercotef4928da2004-06-15 10:54:40 +00001762 // If --tool and --help/--help-debug was given, now give the core+tool
1763 // help message
sewardj95d86c02007-12-18 01:49:23 +00001764 // p: early_process_cmd_line_options() [for 'need_help']
1765 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
sewardj45f4e7c2005-09-27 19:20:21 +00001766 //--------------------------------------------------------------
1767 VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
nethercotef4928da2004-06-15 10:54:40 +00001768 if (need_help) {
njncce38e62010-07-06 04:25:12 +00001769 usage_NORETURN(/*--help-debug?*/need_help >= 2);
nethercotef4928da2004-06-15 10:54:40 +00001770 }
nethercotec314eba2004-07-15 12:59:41 +00001771
sewardj45f4e7c2005-09-27 19:20:21 +00001772 //--------------------------------------------------------------
1773 // Process command line options to Valgrind + tool
1774 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1775 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1776 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001777 VG_(debugLog)(1, "main",
1778 "(main_) Process Valgrind's command line options, "
1779 "setup logging\n");
sewardj738856f2009-07-15 14:48:32 +00001780 main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded,
1781 toolname );
sewardj45f4e7c2005-09-27 19:20:21 +00001782
1783 //--------------------------------------------------------------
sewardj592ae092005-11-08 19:01:44 +00001784 // Zeroise the millisecond counter by doing a first read of it.
1785 // p: none
1786 //--------------------------------------------------------------
1787 (void) VG_(read_millisecond_timer)();
1788
1789 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001790 // Print the preamble
1791 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
sewardj738856f2009-07-15 14:48:32 +00001792 // p: main_process_cmd_line_options()
1793 // [for VG_(clo_verbosity), VG_(clo_xml),
1794 // logging_to_fd, xml_fname_unexpanded]
sewardj45f4e7c2005-09-27 19:20:21 +00001795 //--------------------------------------------------------------
1796 VG_(debugLog)(1, "main", "Print the preamble...\n");
sewardj738856f2009-07-15 14:48:32 +00001797 print_preamble(logging_to_fd, xml_fname_unexpanded, toolname);
sewardj45f4e7c2005-09-27 19:20:21 +00001798 VG_(debugLog)(1, "main", "...finished the preamble\n");
1799
1800 //--------------------------------------------------------------
1801 // Init tool part 2: post_clo_init
1802 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1803 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1804 // p: print_preamble() [so any warnings printed in post_clo_init
1805 // are shown after the preamble]
1806 //--------------------------------------------------------------
1807 VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
njn51d827b2005-05-09 01:02:08 +00001808 VG_TDICT_CALL(tool_post_clo_init);
sewardj7cf4e6b2008-05-01 20:24:26 +00001809 {
1810 /* The tool's "needs" will by now be finalised, since it has no
1811 further opportunity to specify them. So now sanity check
1812 them. */
1813 Char* s;
1814 Bool ok;
1815 ok = VG_(sanity_check_needs)( &s );
1816 if (!ok) {
1817 VG_(tool_panic)(s);
1818 }
1819 }
nethercotef4928da2004-06-15 10:54:40 +00001820
1821 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001822 // Initialise translation table and translation cache
1823 // p: aspacem [??]
1824 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
nethercote71980f02004-01-24 18:18:54 +00001825 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001826 VG_(debugLog)(1, "main", "Initialise TT/TC\n");
1827 VG_(init_tt_tc)();
sewardjb5f6f512005-03-10 23:59:00 +00001828
sewardj45f4e7c2005-09-27 19:20:21 +00001829 //--------------------------------------------------------------
1830 // Initialise the redirect table.
1831 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
1832 // p: aspacem [so can change ownership of sysinfo pages]
1833 //--------------------------------------------------------------
1834 VG_(debugLog)(1, "main", "Initialise redirects\n");
sewardj0ec07f32006-01-12 12:32:32 +00001835 VG_(redir_initialise)();
nethercote71980f02004-01-24 18:18:54 +00001836
1837 //--------------------------------------------------------------
1838 // Allow GDB attach
sewardj95d86c02007-12-18 01:49:23 +00001839 // p: main_process_cmd_line_options() [for VG_(clo_wait_for_gdb)]
nethercote71980f02004-01-24 18:18:54 +00001840 //--------------------------------------------------------------
1841 /* Hook to delay things long enough so we can get the pid and
1842 attach GDB in another shell. */
1843 if (VG_(clo_wait_for_gdb)) {
sewardj87cd71c2011-07-05 09:13:41 +00001844 ULong iters, q;
sewardj1fbc1a52005-04-25 02:05:54 +00001845 VG_(debugLog)(1, "main", "Wait for GDB\n");
sewardj93ab8572005-02-06 14:10:40 +00001846 VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
sewardj8211a572005-06-23 21:37:47 +00001847
1848# if defined(VGP_x86_linux)
1849 iters = 5;
sewardj2c48c7b2005-11-29 13:05:56 +00001850# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
sewardj8211a572005-06-23 21:37:47 +00001851 iters = 10;
1852# elif defined(VGP_ppc32_linux)
sewardjd714d2e2005-07-08 18:24:04 +00001853 iters = 5;
sewardj59570ff2010-01-01 11:59:33 +00001854# elif defined(VGP_arm_linux)
1855 iters = 1;
sewardjb5b87402011-03-07 16:05:35 +00001856# elif defined(VGP_s390x_linux)
1857 iters = 10;
njnf76d27a2009-05-28 01:53:07 +00001858# elif defined(VGO_darwin)
1859 iters = 3;
sewardj8211a572005-06-23 21:37:47 +00001860# else
sewardj17c11042006-10-15 01:26:40 +00001861# error "Unknown plat"
sewardj8211a572005-06-23 21:37:47 +00001862# endif
1863
sewardj87cd71c2011-07-05 09:13:41 +00001864 iters *= 1000ULL * 1000 * 1000;
sewardj8211a572005-06-23 21:37:47 +00001865 for (q = 0; q < iters; q++)
sewardj87cd71c2011-07-05 09:13:41 +00001866 __asm__ __volatile__("" ::: "memory","cc");
nethercote71980f02004-01-24 18:18:54 +00001867 }
1868
sewardjb5d320c2005-03-13 18:57:15 +00001869 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001870 // Search for file descriptors that are inherited from our parent
sewardj95d86c02007-12-18 01:49:23 +00001871 // p: main_process_cmd_line_options [for VG_(clo_track_fds)]
nethercote71980f02004-01-24 18:18:54 +00001872 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001873 if (VG_(clo_track_fds)) {
1874 VG_(debugLog)(1, "main", "Init preopened fds\n");
nethercote71980f02004-01-24 18:18:54 +00001875 VG_(init_preopened_fds)();
sewardj1fbc1a52005-04-25 02:05:54 +00001876 }
nethercote71980f02004-01-24 18:18:54 +00001877
1878 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001879 // Load debug info for the existing segments.
1880 // p: setup_code_redirect_table [so that redirs can be recorded]
1881 // p: mallocfree
1882 // p: probably: setup fds and process CLOs, so that logging works
sewardjf98e1c02008-10-25 16:22:41 +00001883 // p: initialise m_debuginfo
sewardj9c606bd2008-09-18 18:12:50 +00001884 //
1885 // While doing this, make a note of the debuginfo-handles that
sewardj6e9de462011-06-28 07:25:29 +00001886 // come back from VG_(di_notify_mmap).
sewardj9c606bd2008-09-18 18:12:50 +00001887 // Later, in "Tell the tool about the initial client memory permissions"
1888 // (just below) we can then hand these handles off to the tool in
1889 // calls to VG_TRACK(new_mem_startup, ...). This gives the tool the
1890 // opportunity to make further queries to m_debuginfo before the
1891 // client is started, if it wants. We put this information into an
1892 // XArray, each handle along with the associated segment start address,
1893 // and search the XArray for the handles later, when calling
1894 // VG_TRACK(new_mem_startup, ...).
sewardj45f4e7c2005-09-27 19:20:21 +00001895 //--------------------------------------------------------------
1896 VG_(debugLog)(1, "main", "Load initial debug info\n");
sewardj9c606bd2008-09-18 18:12:50 +00001897
1898 tl_assert(!addr2dihandle);
1899 addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2",
1900 VG_(free), sizeof(Addr_n_ULong) );
1901 tl_assert(addr2dihandle);
1902
sewardj17c11042006-10-15 01:26:40 +00001903# if defined(VGO_linux)
sewardj45f4e7c2005-09-27 19:20:21 +00001904 { Addr* seg_starts;
1905 Int n_seg_starts;
sewardj9c606bd2008-09-18 18:12:50 +00001906 Addr_n_ULong anu;
sewardj45f4e7c2005-09-27 19:20:21 +00001907
njnac1e0332009-05-08 00:39:31 +00001908 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001909 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00001910
sewardjf72cced2005-11-08 00:45:47 +00001911 /* show them all to the debug info reader. allow_SkFileV has to
1912 be True here so that we read info from the valgrind executable
1913 itself. */
sewardj9c606bd2008-09-18 18:12:50 +00001914 for (i = 0; i < n_seg_starts; i++) {
1915 anu.ull = VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/ );
1916 /* anu.ull holds the debuginfo handle returned by di_notify_mmap,
1917 if any. */
1918 if (anu.ull > 0) {
1919 anu.a = seg_starts[i];
1920 VG_(addToXA)( addr2dihandle, &anu );
1921 }
1922 }
sewardj45f4e7c2005-09-27 19:20:21 +00001923
1924 VG_(free)( seg_starts );
1925 }
njnf76d27a2009-05-28 01:53:07 +00001926# elif defined(VGO_darwin)
1927 { Addr* seg_starts;
1928 Int n_seg_starts;
1929 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
1930 vg_assert(seg_starts && n_seg_starts >= 0);
1931
1932 /* show them all to the debug info reader.
1933 Don't read from V segments (unlike Linux) */
1934 // GrP fixme really?
1935 for (i = 0; i < n_seg_starts; i++)
1936 VG_(di_notify_mmap)( seg_starts[i], False/*don't allow_SkFileV*/ );
1937
1938 VG_(free)( seg_starts );
1939 }
sewardj17c11042006-10-15 01:26:40 +00001940# else
1941# error Unknown OS
1942# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001943
1944 //--------------------------------------------------------------
1945 // Tell aspacem of ownership change of the asm helpers, so that
1946 // m_translate allows them to be translated. However, only do this
1947 // after the initial debug info read, since making a hole in the
1948 // address range for the stage2 binary confuses the debug info reader.
1949 // p: aspacem
1950 //--------------------------------------------------------------
1951 { Bool change_ownership_v_c_OK;
sewardj1a85f4f2006-01-12 21:15:35 +00001952 Addr co_start = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
1953 Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
sewardj45f4e7c2005-09-27 19:20:21 +00001954 VG_(debugLog)(1,"redir",
1955 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
1956 (ULong)co_start, (ULong)co_endPlus-1 );
1957
1958 change_ownership_v_c_OK
1959 = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
1960 vg_assert(change_ownership_v_c_OK);
1961 }
1962
1963 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001964 // Initialise the scheduler (phase 1) [generates tid_main]
1965 // p: none, afaics
1966 //--------------------------------------------------------------
1967 VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
1968 tid_main = VG_(scheduler_init_phase1)();
1969 vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
1970 && tid_main != VG_INVALID_THREADID);
1971 /* Tell the tool about tid_main */
1972 VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
1973
1974 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001975 // Tell the tool about the initial client memory permissions
1976 // p: aspacem
1977 // p: mallocfree
1978 // p: setup_client_stack
1979 // p: setup_client_dataseg
sewardj9c606bd2008-09-18 18:12:50 +00001980 //
1981 // For each segment we tell the client about, look up in
1982 // addr2dihandle as created above, to see if there's a debuginfo
1983 // handle associated with the segment, that we can hand along
1984 // to the tool, to be helpful.
sewardj45f4e7c2005-09-27 19:20:21 +00001985 //--------------------------------------------------------------
1986 VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
1987 { Addr* seg_starts;
1988 Int n_seg_starts;
sewardj45f4e7c2005-09-27 19:20:21 +00001989
sewardj9c606bd2008-09-18 18:12:50 +00001990 tl_assert(addr2dihandle);
1991
tom7c1a19a2008-01-02 10:13:04 +00001992 /* Mark the main thread as running while we tell the tool about
1993 the client memory so that the tool can associate that memory
1994 with the main thread. */
1995 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
1996 VG_(running_tid) = tid_main;
1997
njnac1e0332009-05-08 00:39:31 +00001998 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001999 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00002000
2001 /* show interesting ones to the tool */
2002 for (i = 0; i < n_seg_starts; i++) {
sewardj9c606bd2008-09-18 18:12:50 +00002003 Word j, n;
sewardj12ab7652006-10-17 02:10:42 +00002004 NSegment const* seg
sewardj17c11042006-10-15 01:26:40 +00002005 = VG_(am_find_nsegment)( seg_starts[i] );
sewardj45f4e7c2005-09-27 19:20:21 +00002006 vg_assert(seg);
2007 if (seg->kind == SkFileC || seg->kind == SkAnonC) {
sewardjc6d86a32009-01-31 15:08:08 +00002008 /* This next assertion is tricky. If it is placed
2009 immediately before this 'if', it very occasionally fails.
2010 Why? Because previous iterations of the loop may have
2011 caused tools (via the new_mem_startup calls) to do
2012 dynamic memory allocation, and that may affect the mapped
2013 segments; in particular it may cause segment merging to
2014 happen. Hence we cannot assume that seg_starts[i], which
2015 reflects the state of the world before we started this
2016 loop, is the same as seg->start, as the latter reflects
2017 the state of the world (viz, mappings) at this particular
2018 iteration of the loop.
2019
2020 Why does moving it inside the 'if' make it safe? Because
2021 any dynamic memory allocation done by the tools will
2022 affect only the state of Valgrind-owned segments, not of
2023 Client-owned segments. And the 'if' guards against that
2024 -- we only get in here for Client-owned segments.
2025
2026 In other words: the loop may change the state of
2027 Valgrind-owned segments as it proceeds. But it should
2028 not cause the Client-owned segments to change. */
2029 vg_assert(seg->start == seg_starts[i]);
sewardj45f4e7c2005-09-27 19:20:21 +00002030 VG_(debugLog)(2, "main",
2031 "tell tool about %010lx-%010lx %c%c%c\n",
2032 seg->start, seg->end,
2033 seg->hasR ? 'r' : '-',
2034 seg->hasW ? 'w' : '-',
2035 seg->hasX ? 'x' : '-' );
sewardj9c606bd2008-09-18 18:12:50 +00002036 /* search addr2dihandle to see if we have an entry
2037 matching seg->start. */
2038 n = VG_(sizeXA)( addr2dihandle );
2039 for (j = 0; j < n; j++) {
2040 Addr_n_ULong* anl = VG_(indexXA)( addr2dihandle, j );
2041 if (anl->a == seg->start) {
2042 tl_assert(anl->ull > 0); /* check it's a valid handle */
2043 break;
2044 }
2045 }
2046 vg_assert(j >= 0 && j <= n);
sewardj45f4e7c2005-09-27 19:20:21 +00002047 VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
sewardj9c606bd2008-09-18 18:12:50 +00002048 seg->hasR, seg->hasW, seg->hasX,
2049 /* and the retrieved debuginfo handle, if any */
2050 j < n
2051 ? ((Addr_n_ULong*)VG_(indexXA)( addr2dihandle, j ))->ull
2052 : 0 );
sewardj45f4e7c2005-09-27 19:20:21 +00002053 }
2054 }
2055
2056 VG_(free)( seg_starts );
sewardj9c606bd2008-09-18 18:12:50 +00002057 VG_(deleteXA)( addr2dihandle );
sewardj45f4e7c2005-09-27 19:20:21 +00002058
2059 /* Also do the initial stack permissions. */
barte05b3a42010-09-07 16:32:53 +00002060 {
2061 SSizeT inaccessible_len;
2062 NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002063 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj17c11042006-10-15 01:26:40 +00002064 vg_assert(seg);
2065 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002066 vg_assert(the_iifii.initial_client_SP >= seg->start);
2067 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardj45f4e7c2005-09-27 19:20:21 +00002068
sewardj17c11042006-10-15 01:26:40 +00002069 /* Stuff below the initial SP is unaddressable. Take into
2070 account any ABI-mandated space below the stack pointer that
2071 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
2072 will have allocated an extra page if a red zone is required,
2073 to be on the safe side. */
barte05b3a42010-09-07 16:32:53 +00002074 inaccessible_len = the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
2075 - seg->start;
2076 vg_assert(inaccessible_len >= 0);
2077 if (inaccessible_len > 0)
2078 VG_TRACK( die_mem_stack,
2079 seg->start,
2080 inaccessible_len );
sewardj17c11042006-10-15 01:26:40 +00002081 VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
2082 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00002083 the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
sewardj17c11042006-10-15 01:26:40 +00002084 }
sewardj45f4e7c2005-09-27 19:20:21 +00002085
2086 /* Also the assembly helpers. */
2087 VG_TRACK( new_mem_startup,
2088 (Addr)&VG_(trampoline_stuff_start),
sewardjc6527d62006-02-13 17:54:31 +00002089 (Addr)&VG_(trampoline_stuff_end)
2090 - (Addr)&VG_(trampoline_stuff_start),
sewardj45f4e7c2005-09-27 19:20:21 +00002091 False, /* readable? */
2092 False, /* writable? */
sewardj9c606bd2008-09-18 18:12:50 +00002093 True /* executable? */,
2094 0 /* di_handle: no associated debug info */ );
tom7c1a19a2008-01-02 10:13:04 +00002095
2096 /* Clear the running thread indicator */
2097 VG_(running_tid) = VG_INVALID_THREADID;
2098 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
sewardj45f4e7c2005-09-27 19:20:21 +00002099 }
2100
2101 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002102 // Initialise the scheduler (phase 2)
2103 // p: Initialise the scheduler (phase 1) [for tid_main]
nethercote71980f02004-01-24 18:18:54 +00002104 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
sewardj45f4e7c2005-09-27 19:20:21 +00002105 // p: setup_client_stack
nethercote71980f02004-01-24 18:18:54 +00002106 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002107 VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
sewardj12ab7652006-10-17 02:10:42 +00002108 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002109 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj45f4e7c2005-09-27 19:20:21 +00002110 vg_assert(seg);
2111 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002112 vg_assert(the_iifii.initial_client_SP >= seg->start);
2113 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardjde764e82007-11-09 23:13:22 +00002114 VG_(scheduler_init_phase2)( tid_main,
2115 seg->end, the_iifii.clstack_max_size );
sewardj45f4e7c2005-09-27 19:20:21 +00002116 }
nethercote71980f02004-01-24 18:18:54 +00002117
2118 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00002119 // Set up state for the root thread
sewardjb5f6f512005-03-10 23:59:00 +00002120 // p: ?
sewardj17c11042006-10-15 01:26:40 +00002121 // setup_scheduler() [for sched-specific thread 1 stuff]
sewardjf9d2f9b2006-11-17 20:00:57 +00002122 // VG_(ii_create_image) [for 'the_iicii' initial info]
sewardj2a99cf62004-11-24 10:44:19 +00002123 //--------------------------------------------------------------
sewardjf9d2f9b2006-11-17 20:00:57 +00002124 VG_(debugLog)(1, "main", "Finalise initial image\n");
2125 VG_(ii_finalise_image)( the_iifii );
njnea4b28c2004-11-30 16:04:58 +00002126
sewardj2a99cf62004-11-24 10:44:19 +00002127 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002128 // Initialise the signal handling subsystem
sewardjb5f6f512005-03-10 23:59:00 +00002129 // p: n/a
nethercote71980f02004-01-24 18:18:54 +00002130 //--------------------------------------------------------------
2131 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
sewardj1fbc1a52005-04-25 02:05:54 +00002132 VG_(debugLog)(1, "main", "Initialise signal management\n");
njncda2f0f2009-05-18 02:12:08 +00002133 /* Check that the kernel-interface signal definitions look sane */
2134 VG_(vki_do_initial_consistency_checks)();
2135 /* .. and go on to use them. */
nethercote71980f02004-01-24 18:18:54 +00002136 VG_(sigstartup_actions)();
2137
2138 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002139 // Read suppression file
sewardj95d86c02007-12-18 01:49:23 +00002140 // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
nethercote71980f02004-01-24 18:18:54 +00002141 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00002142 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
2143 VG_(debugLog)(1, "main", "Load suppressions\n");
nethercote71980f02004-01-24 18:18:54 +00002144 VG_(load_suppressions)();
sewardj1fbc1a52005-04-25 02:05:54 +00002145 }
nethercote71980f02004-01-24 18:18:54 +00002146
2147 //--------------------------------------------------------------
rjwalsh0140af52005-06-04 20:42:33 +00002148 // register client stack
2149 //--------------------------------------------------------------
njn945ed2e2005-06-24 03:28:30 +00002150 VG_(clstk_id) = VG_(register_stack)(VG_(clstk_base), VG_(clstk_end));
rjwalsh0140af52005-06-04 20:42:33 +00002151
2152 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002153 // Show the address space state so far
2154 //--------------------------------------------------------------
2155 VG_(debugLog)(1, "main", "\n");
2156 VG_(debugLog)(1, "main", "\n");
2157 VG_(am_show_nsegments)(1,"Memory layout at client startup");
2158 VG_(debugLog)(1, "main", "\n");
2159 VG_(debugLog)(1, "main", "\n");
2160
2161 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002162 // Run!
2163 //--------------------------------------------------------------
sewardj71bc3cb2005-05-19 00:25:45 +00002164 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002165 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00002166 VG_(elapsed_wallclock_time)(buf);
sewardj738856f2009-07-15 14:48:32 +00002167 VG_(printf_xml_no_f_c)( "<status>\n"
2168 " <state>RUNNING</state>\n"
2169 " <time>%t</time>\n"
2170 "</status>\n",
2171 buf );
2172 VG_(printf_xml_no_f_c)( "\n" );
sewardj71bc3cb2005-05-19 00:25:45 +00002173 }
2174
sewardj1fbc1a52005-04-25 02:05:54 +00002175 VG_(debugLog)(1, "main", "Running thread 1\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002176
sewardj1d887112005-05-30 21:44:08 +00002177 /* As a result of the following call, the last thread standing
sewardj1ae3f3a2005-09-28 10:47:38 +00002178 eventually winds up running shutdown_actions_NORETURN
2179 just below. Unfortunately, simply exporting said function
2180 causes m_main to be part of a module cycle, which is pretty
2181 nonsensical. So instead of doing that, the address of said
2182 function is stored in a global variable 'owned' by m_syswrap,
2183 and it uses that function pointer to get back here when it needs
2184 to. */
2185
2186 /* Set continuation address. */
2187 VG_(address_of_m_main_shutdown_actions_NORETURN)
2188 = & shutdown_actions_NORETURN;
2189
2190 /* Run the first thread, eventually ending up at the continuation
2191 address. */
njnaf839f52005-06-23 03:27:57 +00002192 VG_(main_thread_wrapper_NORETURN)(1);
nethercote71980f02004-01-24 18:18:54 +00002193
sewardj1d887112005-05-30 21:44:08 +00002194 /*NOTREACHED*/
2195 vg_assert(0);
sewardjb5f6f512005-03-10 23:59:00 +00002196}
2197
sewardj17c11042006-10-15 01:26:40 +00002198/* Do everything which needs doing when the last thread exits or when
sewardj6e9de462011-06-28 07:25:29 +00002199 a thread exits requesting a complete process exit.
sewardj17c11042006-10-15 01:26:40 +00002200
2201 We enter here holding The Lock. For the case VgSrc_ExitProcess we
2202 must never release it, because to do so would allow other threads
2203 to continue after the system is ostensibly shut down. So we must
2204 go to our grave, so to speak, holding the lock.
2205
2206 In fact, there is never any point in releasing the lock at this
2207 point - we have it, we're shutting down the entire system, and
2208 for the case VgSrc_ExitProcess doing so positively causes trouble.
2209 So don't.
2210
2211 The final_tidyup call makes a bit of a nonsense of the ExitProcess
2212 case, since it will run the libc_freeres function, thus allowing
2213 other lurking threads to run again. Hmm. */
sewardjb5f6f512005-03-10 23:59:00 +00002214
sewardj1ae3f3a2005-09-28 10:47:38 +00002215static
2216void shutdown_actions_NORETURN( ThreadId tid,
2217 VgSchedReturnCode tids_schedretcode )
sewardjb5f6f512005-03-10 23:59:00 +00002218{
sewardj1d887112005-05-30 21:44:08 +00002219 VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
sewardj17c11042006-10-15 01:26:40 +00002220 VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
sewardj1d887112005-05-30 21:44:08 +00002221
sewardjb5f6f512005-03-10 23:59:00 +00002222 vg_assert(VG_(is_running_thread)(tid));
2223
sewardj12ab7652006-10-17 02:10:42 +00002224 vg_assert(tids_schedretcode == VgSrc_ExitThread
2225 || tids_schedretcode == VgSrc_ExitProcess
2226 || tids_schedretcode == VgSrc_FatalSig );
sewardjb5f6f512005-03-10 23:59:00 +00002227
sewardj12ab7652006-10-17 02:10:42 +00002228 if (tids_schedretcode == VgSrc_ExitThread) {
sewardjb5f6f512005-03-10 23:59:00 +00002229
sewardj17c11042006-10-15 01:26:40 +00002230 // We are the last surviving thread. Right?
2231 vg_assert( VG_(count_living_threads)() == 1 );
sewardjb5f6f512005-03-10 23:59:00 +00002232
sewardj17c11042006-10-15 01:26:40 +00002233 // Wait for all other threads to exit.
2234 // jrs: Huh? but they surely are already gone
2235 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002236
sewardj17c11042006-10-15 01:26:40 +00002237 // Clean the client up before the final report
2238 // this causes the libc_freeres function to run
2239 final_tidyup(tid);
2240
2241 /* be paranoid */
2242 vg_assert(VG_(is_running_thread)(tid));
2243 vg_assert(VG_(count_living_threads)() == 1);
2244
2245 } else {
2246
2247 // We may not be the last surviving thread. However, we
2248 // want to shut down the entire process. We hold the lock
2249 // and we need to keep hold of it all the way out, in order
2250 // that none of the other threads ever run again.
2251 vg_assert( VG_(count_living_threads)() >= 1 );
2252
sewardj17c11042006-10-15 01:26:40 +00002253 // Clean the client up before the final report
2254 // this causes the libc_freeres function to run
2255 // perhaps this is unsafe, as per comment above
2256 final_tidyup(tid);
2257
2258 /* be paranoid */
2259 vg_assert(VG_(is_running_thread)(tid));
2260 vg_assert(VG_(count_living_threads)() >= 1);
2261 }
sewardjb5f6f512005-03-10 23:59:00 +00002262
2263 VG_(threads)[tid].status = VgTs_Empty;
nethercote71980f02004-01-24 18:18:54 +00002264 //--------------------------------------------------------------
sewardj738856f2009-07-15 14:48:32 +00002265 // Finalisation: cleanup, messages, etc. Order not so important, only
nethercote71980f02004-01-24 18:18:54 +00002266 // affects what order the messages come.
2267 //--------------------------------------------------------------
njnb6267bd2009-08-12 00:14:16 +00002268 // First thing in the post-amble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00002269 if (VG_(clo_xml))
2270 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00002271 else if (VG_(clo_verbosity) > 0)
2272 VG_(message)(Vg_UserMsg, "\n");
nethercote71980f02004-01-24 18:18:54 +00002273
sewardj71bc3cb2005-05-19 00:25:45 +00002274 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002275 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00002276 VG_(elapsed_wallclock_time)(buf);
sewardj738856f2009-07-15 14:48:32 +00002277 VG_(printf_xml_no_f_c)( "<status>\n"
2278 " <state>FINISHED</state>\n"
2279 " <time>%t</time>\n"
njnb6267bd2009-08-12 00:14:16 +00002280 "</status>\n"
2281 "\n",
sewardj738856f2009-07-15 14:48:32 +00002282 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00002283 }
2284
nethercote71980f02004-01-24 18:18:54 +00002285 /* Print out file descriptor summary and stats. */
2286 if (VG_(clo_track_fds))
nethercote3a42fb82004-08-03 18:08:50 +00002287 VG_(show_open_fds)();
nethercote71980f02004-01-24 18:18:54 +00002288
sewardj2d9e8742009-08-07 15:46:56 +00002289 /* Call the tool's finalisation function. This makes Memcheck's
2290 leak checker run, and possibly chuck a bunch of leak errors into
2291 the error management machinery. */
2292 VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
nethercote71980f02004-01-24 18:18:54 +00002293
sewardj2d9e8742009-08-07 15:46:56 +00002294 /* Show the error counts. */
sewardj7ca100d2009-08-15 23:05:34 +00002295 if (VG_(clo_xml)
2296 && (VG_(needs).core_errors || VG_(needs).tool_errors)) {
sewardj2d9e8742009-08-07 15:46:56 +00002297 VG_(show_error_counts_as_XML)();
sewardj738856f2009-07-15 14:48:32 +00002298 }
sewardj2d9e8742009-08-07 15:46:56 +00002299
2300 /* In XML mode, this merely prints the used suppressions. */
2301 if (VG_(needs).core_errors || VG_(needs).tool_errors)
sewardj3b290482011-05-06 21:02:55 +00002302 VG_(show_all_errors)(VG_(clo_verbosity), VG_(clo_xml));
nethercote71980f02004-01-24 18:18:54 +00002303
sewardj71bc3cb2005-05-19 00:25:45 +00002304 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00002305 VG_(printf_xml)("\n");
2306 VG_(printf_xml)("</valgrindoutput>\n");
2307 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00002308 }
2309
nethercote885dd912004-08-03 23:14:00 +00002310 VG_(sanity_check_general)( True /*include expensive checks*/ );
nethercote71980f02004-01-24 18:18:54 +00002311
sewardj2d9e8742009-08-07 15:46:56 +00002312 if (VG_(clo_stats))
nethercote3a42fb82004-08-03 18:08:50 +00002313 print_all_stats();
nethercote71980f02004-01-24 18:18:54 +00002314
sewardj9c606bd2008-09-18 18:12:50 +00002315 /* Show a profile of the heap(s) at shutdown. Optionally, first
2316 throw away all the debug info, as that makes it easy to spot
2317 leaks in the debuginfo reader. */
2318 if (VG_(clo_profile_heap)) {
2319 if (0) VG_(di_discard_ALL_debuginfo)();
2320 VG_(print_arena_cc_analysis)();
2321 }
2322
njn2025cf92005-06-26 20:44:48 +00002323 if (VG_(clo_profile_flags) > 0) {
sewardj5471ec62006-10-17 13:58:17 +00002324 #define N_MAX 200
njn2025cf92005-06-26 20:44:48 +00002325 BBProfEntry tops[N_MAX];
2326 ULong score_total = VG_(get_BB_profile) (tops, N_MAX);
2327 show_BB_profile(tops, N_MAX, score_total);
2328 }
sewardjfa8ec112005-01-19 11:55:34 +00002329
sewardj8b635a42004-11-22 19:01:47 +00002330 /* Print Vex storage stats */
sewardjbf426512005-01-17 18:35:30 +00002331 if (0)
2332 LibVEX_ShowAllocStats();
sewardj1d887112005-05-30 21:44:08 +00002333
sewardj738856f2009-07-15 14:48:32 +00002334 /* Flush any output cached by previous calls to VG_(message). */
2335 VG_(message_flush)();
2336
sewardj3b290482011-05-06 21:02:55 +00002337 /* terminate gdbserver if ever it was started. We terminate it here so that it get
2338 the output above if output was redirected to gdb */
2339 VG_(gdbserver) (0);
2340
njn8aa35852005-06-10 22:59:56 +00002341 /* Ok, finally exit in the os-specific way, according to the scheduler's
2342 return code. In short, if the (last) thread exited by calling
2343 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2344 signal, terminate the entire system with that same fatal signal. */
2345 VG_(debugLog)(1, "core_os",
njn7b85dd52005-06-12 17:26:29 +00002346 "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
njn8aa35852005-06-10 22:59:56 +00002347
njn8aa35852005-06-10 22:59:56 +00002348 switch (tids_schedretcode) {
sewardj12ab7652006-10-17 02:10:42 +00002349 case VgSrc_ExitThread: /* the normal way out (Linux) */
sewardj6e9de462011-06-28 07:25:29 +00002350 case VgSrc_ExitProcess: /* the normal way out (AIX) -- still needed? */
sewardjb9779082006-05-12 23:50:15 +00002351 /* Change the application return code to user's return code,
2352 if an error was found */
2353 if (VG_(clo_error_exitcode) > 0
2354 && VG_(get_n_errs_found)() > 0) {
2355 VG_(exit)( VG_(clo_error_exitcode) );
2356 } else {
2357 /* otherwise, return the client's exit code, in the normal
2358 way. */
2359 VG_(exit)( VG_(threads)[tid].os_state.exitcode );
2360 }
njn8aa35852005-06-10 22:59:56 +00002361 /* NOT ALIVE HERE! */
sewardj17c11042006-10-15 01:26:40 +00002362 VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
njn8aa35852005-06-10 22:59:56 +00002363 break; /* what the hell :) */
2364
2365 case VgSrc_FatalSig:
2366 /* We were killed by a fatal signal, so replicate the effect */
2367 vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
2368 VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
njnf76d27a2009-05-28 01:53:07 +00002369 /* we shouldn't be alive at this point. But VG_(kill_self)
2370 sometimes fails with EPERM on Darwin, for unclear reasons. */
2371# if defined(VGO_darwin)
2372 VG_(debugLog)(0, "main", "VG_(kill_self) failed. Exiting normally.\n");
2373 VG_(exit)(0); /* bogus, but we really need to exit now */
2374 /* fall through .. */
2375# endif
njn8aa35852005-06-10 22:59:56 +00002376 VG_(core_panic)("main(): signal was supposed to be fatal");
2377 break;
2378
2379 default:
2380 VG_(core_panic)("main(): unexpected scheduler return code");
2381 }
njne96be672005-05-08 19:08:54 +00002382}
sewardj8b635a42004-11-22 19:01:47 +00002383
sewardj1ae3f3a2005-09-28 10:47:38 +00002384/* -------------------- */
2385
2386/* Final clean-up before terminating the process.
2387 Clean up the client by calling __libc_freeres() (if requested)
2388 This is Linux-specific?
njnf76d27a2009-05-28 01:53:07 +00002389 GrP fixme glibc-specific, anyway
sewardj1ae3f3a2005-09-28 10:47:38 +00002390*/
2391static void final_tidyup(ThreadId tid)
2392{
njnf76d27a2009-05-28 01:53:07 +00002393#if !defined(VGO_darwin)
sewardjcf951812006-01-17 02:22:21 +00002394# if defined(VGP_ppc64_linux)
2395 Addr r2;
2396# endif
sewardj0ec07f32006-01-12 12:32:32 +00002397 Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
sewardj1ae3f3a2005-09-28 10:47:38 +00002398
2399 vg_assert(VG_(is_running_thread)(tid));
2400
2401 if ( !VG_(needs).libc_freeres ||
2402 !VG_(clo_run_libc_freeres) ||
sewardj0ec07f32006-01-12 12:32:32 +00002403 0 == __libc_freeres_wrapper )
sewardj1ae3f3a2005-09-28 10:47:38 +00002404 return; /* can't/won't do it */
2405
sewardjcf951812006-01-17 02:22:21 +00002406# if defined(VGP_ppc64_linux)
2407 r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
2408 if (r2 == 0) {
2409 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002410 "Caught __NR_exit, but can't run __libc_freeres()\n");
sewardjcf951812006-01-17 02:22:21 +00002411 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002412 " since cannot establish TOC pointer for it.\n");
sewardjcf951812006-01-17 02:22:21 +00002413 return;
2414 }
2415# endif
2416
sewardj1ae3f3a2005-09-28 10:47:38 +00002417 if (VG_(clo_verbosity) > 2 ||
2418 VG_(clo_trace_syscalls) ||
2419 VG_(clo_trace_sched))
2420 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00002421 "Caught __NR_exit; running __libc_freeres()\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002422
sewardj0ec07f32006-01-12 12:32:32 +00002423 /* set thread context to point to libc_freeres_wrapper */
sewardj1a85f4f2006-01-12 21:15:35 +00002424 /* ppc64-linux note: __libc_freeres_wrapper gives us the real
2425 function entry point, not a fn descriptor, so can use it
2426 directly. However, we need to set R2 (the toc pointer)
2427 appropriately. */
sewardj1ae3f3a2005-09-28 10:47:38 +00002428 VG_(set_IP)(tid, __libc_freeres_wrapper);
sewardjcf951812006-01-17 02:22:21 +00002429# if defined(VGP_ppc64_linux)
2430 VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
2431# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002432
2433 /* Block all blockable signals by copying the real block state into
2434 the thread's block state*/
2435 VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
2436 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
2437
2438 /* and restore handlers to default */
2439 VG_(set_default_handler)(VKI_SIGSEGV);
2440 VG_(set_default_handler)(VKI_SIGBUS);
2441 VG_(set_default_handler)(VKI_SIGILL);
2442 VG_(set_default_handler)(VKI_SIGFPE);
2443
2444 // We were exiting, so assert that...
2445 vg_assert(VG_(is_exiting)(tid));
2446 // ...but now we're not again
2447 VG_(threads)[tid].exitreason = VgSrc_None;
2448
2449 // run until client thread exits - ideally with LIBC_FREERES_DONE,
2450 // but exit/exitgroup/signal will do
2451 VG_(scheduler)(tid);
2452
2453 vg_assert(VG_(is_exiting)(tid));
njnf76d27a2009-05-28 01:53:07 +00002454#endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002455}
2456
sewardj45f4e7c2005-09-27 19:20:21 +00002457
2458/*====================================================================*/
njn49f80e82009-05-21 01:25:43 +00002459/*=== Getting to main() alive: LINUX ===*/
sewardj45f4e7c2005-09-27 19:20:21 +00002460/*====================================================================*/
2461
sewardj17c11042006-10-15 01:26:40 +00002462#if defined(VGO_linux)
2463
sewardj45f4e7c2005-09-27 19:20:21 +00002464/* If linking of the final executables is done with glibc present,
2465 then Valgrind starts at main() above as usual, and all of the
2466 following code is irrelevant.
2467
2468 However, this is not the intended mode of use. The plan is to
2469 avoid linking against glibc, by giving gcc the flags
2470 -nodefaultlibs -lgcc -nostartfiles at startup.
2471
2472 From this derive two requirements:
2473
2474 1. gcc may emit calls to memcpy and memset to deal with structure
2475 assignments etc. Since we have chosen to ignore all the
2476 "normal" supporting libraries, we have to provide our own
2477 implementations of them. No problem.
2478
2479 2. We have to provide a symbol "_start", to which the kernel
2480 hands control at startup. Hence the code below.
2481*/
2482
2483/* ---------------- Requirement 1 ---------------- */
2484
sewardj17c11042006-10-15 01:26:40 +00002485void* memcpy(void *dest, const void *src, SizeT n);
2486void* memcpy(void *dest, const void *src, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002487 return VG_(memcpy)(dest,src,n);
2488}
sewardj17c11042006-10-15 01:26:40 +00002489void* memset(void *s, int c, SizeT n);
2490void* memset(void *s, int c, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002491 return VG_(memset)(s,c,n);
2492}
2493
bart82616e12010-06-13 13:46:24 +00002494/* BVA: abort() for those platforms that need it (PPC and ARM). */
2495void abort(void);
2496void abort(void){
2497 VG_(printf)("Something called raise().\n");
2498 vg_assert(0);
2499}
2500
sewardj59570ff2010-01-01 11:59:33 +00002501/* EAZG: ARM's EABI will call floating point exception handlers in
2502 libgcc which boil down to an abort or raise, that's usually defined
2503 in libc. Instead, define them here. */
2504#if defined(VGP_arm_linux)
2505void raise(void);
2506void raise(void){
2507 VG_(printf)("Something called raise().\n");
2508 vg_assert(0);
2509}
2510
sewardj59570ff2010-01-01 11:59:33 +00002511void __aeabi_unwind_cpp_pr0(void);
2512void __aeabi_unwind_cpp_pr0(void){
2513 VG_(printf)("Something called __aeabi_unwind_cpp_pr0()\n");
2514 vg_assert(0);
2515}
sewardj38efe4b2010-08-22 12:23:01 +00002516
2517void __aeabi_unwind_cpp_pr1(void);
2518void __aeabi_unwind_cpp_pr1(void){
2519 VG_(printf)("Something called __aeabi_unwind_cpp_pr1()\n");
2520 vg_assert(0);
2521}
sewardj59570ff2010-01-01 11:59:33 +00002522#endif
2523
sewardj45f4e7c2005-09-27 19:20:21 +00002524/* ---------------- Requirement 2 ---------------- */
2525
2526/* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2527 comment, which explains how the stack looks right at process start
2528 (when _start is jumped to). Hence _start passes %esp to
sewardj17c11042006-10-15 01:26:40 +00002529 _start_in_C_linux, which extracts argc/argv/envp and starts up
sewardj45f4e7c2005-09-27 19:20:21 +00002530 correctly. */
2531
2532/* This is the canonical entry point, usually the first thing in the text
2533 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2534 point runs, most registers' values are unspecified, except for:
2535
2536 %edx Contains a function pointer to be registered with `atexit'.
2537 This is how the dynamic linker arranges to have DT_FINI
2538 functions called for shared libraries that have been loaded
2539 before this code runs.
2540
2541 %esp The stack contains the arguments and environment:
2542 0(%esp) argc
2543 4(%esp) argv[0]
2544 ...
2545 (4*argc)(%esp) NULL
2546 (4*(argc+1))(%esp) envp[0]
2547 ...
2548 NULL
2549*/
2550
2551/* The kernel hands control to _start, which extracts the initial
sewardj17c11042006-10-15 01:26:40 +00002552 stack pointer and calls onwards to _start_in_C_linux. This also switches
sewardja48a4932005-09-29 11:09:56 +00002553 the new stack. */
sewardj45f4e7c2005-09-27 19:20:21 +00002554#if defined(VGP_x86_linux)
2555asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002556 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002557 "\t.globl _start\n"
2558 "\t.type _start,@function\n"
2559 "_start:\n"
2560 /* set up the new stack in %eax */
sewardjfdf91b42005-09-28 00:53:09 +00002561 "\tmovl $vgPlain_interim_stack, %eax\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002562 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2563 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2564 "\tsubl $16, %eax\n"
2565 "\tandl $~15, %eax\n"
2566 /* install it, and collect the original one */
2567 "\txchgl %eax, %esp\n"
sewardj17c11042006-10-15 01:26:40 +00002568 /* call _start_in_C_linux, passing it the startup %esp */
sewardj45f4e7c2005-09-27 19:20:21 +00002569 "\tpushl %eax\n"
sewardj17c11042006-10-15 01:26:40 +00002570 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002571 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002572 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002573);
2574#elif defined(VGP_amd64_linux)
2575asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002576 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002577 "\t.globl _start\n"
2578 "\t.type _start,@function\n"
2579 "_start:\n"
2580 /* set up the new stack in %rdi */
sewardjfdf91b42005-09-28 00:53:09 +00002581 "\tmovq $vgPlain_interim_stack, %rdi\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002582 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2583 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2584 "\tandq $~15, %rdi\n"
2585 /* install it, and collect the original one */
2586 "\txchgq %rdi, %rsp\n"
sewardj17c11042006-10-15 01:26:40 +00002587 /* call _start_in_C_linux, passing it the startup %rsp */
2588 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002589 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002590 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002591);
sewardja48a4932005-09-29 11:09:56 +00002592#elif defined(VGP_ppc32_linux)
2593asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002594 ".text\n"
sewardja48a4932005-09-29 11:09:56 +00002595 "\t.globl _start\n"
2596 "\t.type _start,@function\n"
2597 "_start:\n"
2598 /* set up the new stack in r16 */
2599 "\tlis 16,vgPlain_interim_stack@ha\n"
2600 "\tla 16,vgPlain_interim_stack@l(16)\n"
2601 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2602 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2603 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2604 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2605 "\tadd 16,17,16\n"
2606 "\tadd 16,18,16\n"
2607 "\trlwinm 16,16,0,0,27\n"
2608 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2609 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2610 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002611 call _start_in_C_linux, passing it the initial SP. */
sewardja48a4932005-09-29 11:09:56 +00002612 "\tmr 3,1\n"
2613 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002614 "\tbl _start_in_C_linux\n"
sewardja48a4932005-09-29 11:09:56 +00002615 "\ttrap\n"
sewardj2fedc642005-11-19 02:02:57 +00002616 ".previous\n"
sewardja48a4932005-09-29 11:09:56 +00002617);
sewardj2c48c7b2005-11-29 13:05:56 +00002618#elif defined(VGP_ppc64_linux)
2619asm("\n"
cerion21082042005-12-06 19:07:08 +00002620 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2621 So we must have one, and that is what goes into the .opd section. */
cerion297c88f2005-12-22 15:53:12 +00002622 "\t.align 2\n"
cerion21082042005-12-06 19:07:08 +00002623 "\t.global _start\n"
2624 "\t.section \".opd\",\"aw\"\n"
2625 "\t.align 3\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002626 "_start:\n"
cerion21082042005-12-06 19:07:08 +00002627 "\t.quad ._start,.TOC.@tocbase,0\n"
2628 "\t.previous\n"
2629 "\t.type ._start,@function\n"
2630 "\t.global ._start\n"
2631 "._start:\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002632 /* set up the new stack in r16 */
2633 "\tlis 16, vgPlain_interim_stack@highest\n"
2634 "\tori 16,16,vgPlain_interim_stack@higher\n"
2635 "\tsldi 16,16,32\n"
2636 "\toris 16,16,vgPlain_interim_stack@h\n"
2637 "\tori 16,16,vgPlain_interim_stack@l\n"
2638 "\txor 17,17,17\n"
2639 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2640 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2641 "\txor 18,18,18\n"
2642 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2643 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2644 "\tadd 16,17,16\n"
2645 "\tadd 16,18,16\n"
2646 "\trldicr 16,16,0,59\n"
2647 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2648 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2649 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002650 call _start_in_C_linux, passing it the initial SP. */
sewardj2c48c7b2005-11-29 13:05:56 +00002651 "\tmr 3,1\n"
2652 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002653 "\tbl ._start_in_C_linux\n"
cerion21082042005-12-06 19:07:08 +00002654 "\tnop\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002655 "\ttrap\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002656);
sewardjb5b87402011-03-07 16:05:35 +00002657#elif defined(VGP_s390x_linux)
2658/*
2659 This is the canonical entry point, usually the first thing in the text
2660 segment. Most registers' values are unspecified, except for:
2661
2662 %r14 Contains a function pointer to be registered with `atexit'.
2663 This is how the dynamic linker arranges to have DT_FINI
2664 functions called for shared libraries that have been loaded
2665 before this code runs.
2666
2667 %r15 The stack contains the arguments and environment:
2668 0(%r15) argc
2669 8(%r15) argv[0]
2670 ...
2671 (8*argc)(%r15) NULL
2672 (8*(argc+1))(%r15) envp[0]
2673 ...
2674 NULL
2675*/
2676asm("\n\t"
2677 ".text\n\t"
2678 ".globl _start\n\t"
2679 ".type _start,@function\n\t"
2680 "_start:\n\t"
2681 /* set up the new stack in %r1 */
2682 "larl %r1, vgPlain_interim_stack\n\t"
2683 "larl %r5, 1f\n\t"
2684 "ag %r1, 0(%r5)\n\t"
2685 "ag %r1, 2f-1f(%r5)\n\t"
2686 "nill %r1, 0xFFF0\n\t"
2687 /* install it, and collect the original one */
2688 "lgr %r2, %r15\n\t"
2689 "lgr %r15, %r1\n\t"
2690 /* call _start_in_C_linux, passing it the startup %r15 */
2691 "brasl %r14, _start_in_C_linux\n\t"
2692 /* trigger execution of an invalid opcode -> halt machine */
2693 "j .+2\n\t"
2694 "1: .quad "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n\t"
2695 "2: .quad "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n\t"
2696 ".previous\n"
2697);
sewardj59570ff2010-01-01 11:59:33 +00002698#elif defined(VGP_arm_linux)
2699asm("\n"
sewardjb51c9262011-05-03 14:24:11 +00002700 "\t.text\n"
2701 "\t.align 4\n"
2702 "\t.type _start,#function\n"
sewardj59570ff2010-01-01 11:59:33 +00002703 "\t.global _start\n"
2704 "_start:\n"
2705 "\tldr r0, [pc, #36]\n"
2706 "\tldr r1, [pc, #36]\n"
2707 "\tadd r0, r1, r0\n"
2708 "\tldr r1, [pc, #32]\n"
2709 "\tadd r0, r1, r0\n"
2710 "\tmvn r1, #15\n"
2711 "\tand r0, r0, r1\n"
2712 "\tmov r1, sp\n"
2713 "\tmov sp, r0\n"
2714 "\tmov r0, r1\n"
2715 "\tb _start_in_C_linux\n"
2716 "\t.word vgPlain_interim_stack\n"
2717 "\t.word "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
2718 "\t.word "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
2719);
sewardj45f4e7c2005-09-27 19:20:21 +00002720#else
njn49f80e82009-05-21 01:25:43 +00002721# error "Unknown linux platform"
sewardj45f4e7c2005-09-27 19:20:21 +00002722#endif
2723
sewardje66f2e02006-12-30 17:45:08 +00002724/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
2725#define _GNU_SOURCE
2726#define _FILE_OFFSET_BITS 64
2727/* This is in order to get AT_NULL and AT_PAGESIZE. */
2728#include <elf.h>
2729/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
2730
sewardj45f4e7c2005-09-27 19:20:21 +00002731/* Avoid compiler warnings: this fn _is_ used, but labelling it
2732 'static' causes gcc to complain it isn't. */
sewardj17c11042006-10-15 01:26:40 +00002733void _start_in_C_linux ( UWord* pArgc );
2734void _start_in_C_linux ( UWord* pArgc )
sewardj45f4e7c2005-09-27 19:20:21 +00002735{
2736 Int r;
2737 Word argc = pArgc[0];
2738 HChar** argv = (HChar**)&pArgc[1];
2739 HChar** envp = (HChar**)&pArgc[1+argc+1];
sewardjf9d2f9b2006-11-17 20:00:57 +00002740
2741 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2742 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2743
2744 the_iicii.sp_at_startup = (Addr)pArgc;
2745
sewardje66f2e02006-12-30 17:45:08 +00002746# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
2747 {
2748 /* ppc/ppc64 can be configured with different page sizes.
2749 Determine this early. This is an ugly hack and really should
2750 be moved into valgrind_main. */
2751 UWord *sp = &pArgc[1+argc+1];
2752 while (*sp++ != 0)
2753 ;
2754 for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
2755 if (*sp == AT_PAGESZ) {
2756 VKI_PAGE_SIZE = sp[1];
2757 for (VKI_PAGE_SHIFT = 12;
2758 VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
2759 if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
2760 break;
2761 }
2762 }
2763# endif
2764
sewardjf9d2f9b2006-11-17 20:00:57 +00002765 r = valgrind_main( (Int)argc, argv, envp );
sewardj17c11042006-10-15 01:26:40 +00002766 /* NOTREACHED */
sewardj45f4e7c2005-09-27 19:20:21 +00002767 VG_(exit)(r);
2768}
2769
sewardj17c11042006-10-15 01:26:40 +00002770
2771/*====================================================================*/
njnf76d27a2009-05-28 01:53:07 +00002772/*=== Getting to main() alive: darwin ===*/
2773/*====================================================================*/
2774
2775#elif defined(VGO_darwin)
2776
njnea2d6fd2010-07-01 00:20:20 +00002777/*
2778 Memory layout established by kernel:
2779
2780 0(%esp) argc
2781 4(%esp) argv[0]
2782 ...
2783 argv[argc-1]
2784 NULL
2785 envp[0]
2786 ...
2787 envp[n]
2788 NULL
2789 executable name (presumably, a pointer to it)
2790 NULL
2791
2792 Ditto in the 64-bit case, except all offsets from SP are obviously
2793 twice as large.
2794*/
2795
2796/* The kernel hands control to _start, which extracts the initial
2797 stack pointer and calls onwards to _start_in_C_darwin. This also
2798 switches to the new stack. */
2799#if defined(VGP_x86_darwin)
2800asm("\n"
2801 ".text\n"
2802 ".align 2,0x90\n"
2803 "\t.globl __start\n"
2804 "__start:\n"
2805 /* set up the new stack in %eax */
2806 "\tmovl $_vgPlain_interim_stack, %eax\n"
2807 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2808 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2809 "\tsubl $16, %eax\n"
2810 "\tandl $~15, %eax\n"
2811 /* install it, and collect the original one */
2812 "\txchgl %eax, %esp\n"
2813 /* call _start_in_C_darwin, passing it the startup %esp */
2814 "\tpushl %eax\n"
2815 "\tcall __start_in_C_darwin\n"
2816 "\tint $3\n"
2817 "\tint $3\n"
2818);
2819#elif defined(VGP_amd64_darwin)
2820asm("\n"
2821 ".text\n"
2822 "\t.globl __start\n"
2823 ".align 3,0x90\n"
2824 "__start:\n"
2825 /* set up the new stack in %rdi */
2826 "\tmovabsq $_vgPlain_interim_stack, %rdi\n"
2827 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2828 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2829 "\tandq $~15, %rdi\n"
2830 /* install it, and collect the original one */
2831 "\txchgq %rdi, %rsp\n"
2832 /* call _start_in_C_darwin, passing it the startup %rsp */
2833 "\tcall __start_in_C_darwin\n"
2834 "\tint $3\n"
2835 "\tint $3\n"
2836);
2837#endif
2838
njnf76d27a2009-05-28 01:53:07 +00002839void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2);
2840void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2) {
2841 // skip check
2842 return VG_(memcpy)(dest,src,n);
2843}
2844void* __memset_chk(void *s, int c, SizeT n, SizeT n2);
2845void* __memset_chk(void *s, int c, SizeT n, SizeT n2) {
2846 // skip check
2847 return VG_(memset)(s,c,n);
2848}
2849void bzero(void *s, SizeT n);
2850void bzero(void *s, SizeT n) {
2851 VG_(memset)(s,0,n);
2852}
2853
2854void* memcpy(void *dest, const void *src, SizeT n);
2855void* memcpy(void *dest, const void *src, SizeT n) {
2856 return VG_(memcpy)(dest,src,n);
2857}
2858void* memset(void *s, int c, SizeT n);
2859void* memset(void *s, int c, SizeT n) {
2860 return VG_(memset)(s,c,n);
2861}
2862
njnf76d27a2009-05-28 01:53:07 +00002863/* Avoid compiler warnings: this fn _is_ used, but labelling it
2864 'static' causes gcc to complain it isn't. */
2865void _start_in_C_darwin ( UWord* pArgc );
2866void _start_in_C_darwin ( UWord* pArgc )
2867{
2868 Int r;
njnea2d6fd2010-07-01 00:20:20 +00002869 Int argc = *(Int *)pArgc; // not pArgc[0] on LP64
njnf76d27a2009-05-28 01:53:07 +00002870 HChar** argv = (HChar**)&pArgc[1];
2871 HChar** envp = (HChar**)&pArgc[1+argc+1];
2872
2873 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2874 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2875
2876 the_iicii.sp_at_startup = (Addr)pArgc;
2877
2878 r = valgrind_main( (Int)argc, argv, envp );
2879 /* NOTREACHED */
2880 VG_(exit)(r);
2881}
2882
2883
njn49f80e82009-05-21 01:25:43 +00002884#else
2885
2886# error "Unknown OS"
2887#endif
sewardj17c11042006-10-15 01:26:40 +00002888
2889
sewardj0af71bb2010-07-01 14:50:30 +00002890/*====================================================================*/
2891/*=== {u,}{div,mod}di3 replacements ===*/
2892/*====================================================================*/
njnea2d6fd2010-07-01 00:20:20 +00002893
2894/* For static linking on x86-darwin, we need to supply our own 64-bit
2895 integer division code, else the link dies thusly:
2896
2897 ld_classic: Undefined symbols:
2898 ___udivdi3
2899 ___umoddi3
2900*/
2901#if defined(VGP_x86_darwin)
2902
2903/* Routines for doing signed/unsigned 64 x 64 ==> 64 div and mod
2904 (udivdi3, umoddi3, divdi3, moddi3) using only 32 x 32 ==> 32
2905 division. Cobbled together from
2906
2907 http://www.hackersdelight.org/HDcode/divlu.c
2908 http://www.hackersdelight.org/HDcode/divls.c
2909 http://www.hackersdelight.org/HDcode/newCode/divDouble.c
2910
2911 The code from those three files is covered by the following license,
2912 as it appears at:
2913
2914 http://www.hackersdelight.org/permissions.htm
2915
2916 You are free to use, copy, and distribute any of the code on
2917 this web site, whether modified by you or not. You need not give
2918 attribution. This includes the algorithms (some of which appear
2919 in Hacker's Delight), the Hacker's Assistant, and any code
2920 submitted by readers. Submitters implicitly agree to this.
2921*/
2922
2923/* Long division, unsigned (64/32 ==> 32).
2924 This procedure performs unsigned "long division" i.e., division of a
292564-bit unsigned dividend by a 32-bit unsigned divisor, producing a
292632-bit quotient. In the overflow cases (divide by 0, or quotient
2927exceeds 32 bits), it returns a remainder of 0xFFFFFFFF (an impossible
2928value).
2929 The dividend is u1 and u0, with u1 being the most significant word.
2930The divisor is parameter v. The value returned is the quotient.
2931 Max line length is 57, to fit in hacker.book. */
2932
2933static Int nlz32(UInt x)
2934{
2935 Int n;
2936 if (x == 0) return(32);
2937 n = 0;
2938 if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
2939 if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
2940 if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
2941 if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
2942 if (x <= 0x7FFFFFFF) {n = n + 1;}
2943 return n;
2944}
2945
2946/* 64 x 32 ==> 32 unsigned division, using only 32 x 32 ==> 32
2947 division as a primitive. */
2948static UInt divlu2(UInt u1, UInt u0, UInt v, UInt *r)
2949{
2950 const UInt b = 65536; // Number base (16 bits).
2951 UInt un1, un0, // Norm. dividend LSD's.
2952 vn1, vn0, // Norm. divisor digits.
2953 q1, q0, // Quotient digits.
2954 un32, un21, un10, // Dividend digit pairs.
2955 rhat; // A remainder.
2956 Int s; // Shift amount for norm.
2957
2958 if (u1 >= v) { // If overflow, set rem.
2959 if (r != NULL) // to an impossible value,
2960 *r = 0xFFFFFFFF; // and return the largest
2961 return 0xFFFFFFFF;} // possible quotient.
2962
2963 s = nlz32(v); // 0 <= s <= 31.
2964 v = v << s; // Normalize divisor.
2965 vn1 = v >> 16; // Break divisor up into
2966 vn0 = v & 0xFFFF; // two 16-bit digits.
2967
2968 un32 = (u1 << s) | ((u0 >> (32 - s)) & (-s >> 31));
2969 un10 = u0 << s; // Shift dividend left.
2970
2971 un1 = un10 >> 16; // Break right half of
2972 un0 = un10 & 0xFFFF; // dividend into two digits.
2973
2974 q1 = un32/vn1; // Compute the first
2975 rhat = un32 - q1*vn1; // quotient digit, q1.
2976 again1:
2977 if (q1 >= b || q1*vn0 > b*rhat + un1) {
2978 q1 = q1 - 1;
2979 rhat = rhat + vn1;
2980 if (rhat < b) goto again1;}
2981
2982 un21 = un32*b + un1 - q1*v; // Multiply and subtract.
2983
2984 q0 = un21/vn1; // Compute the second
2985 rhat = un21 - q0*vn1; // quotient digit, q0.
2986 again2:
2987 if (q0 >= b || q0*vn0 > b*rhat + un0) {
2988 q0 = q0 - 1;
2989 rhat = rhat + vn1;
2990 if (rhat < b) goto again2;}
2991
2992 if (r != NULL) // If remainder is wanted,
2993 *r = (un21*b + un0 - q0*v) >> s; // return it.
2994 return q1*b + q0;
2995}
2996
2997
2998/* 64 x 32 ==> 32 signed division, using only 32 x 32 ==> 32 division
2999 as a primitive. */
3000static Int divls(Int u1, UInt u0, Int v, Int *r)
3001{
3002 Int q, uneg, vneg, diff, borrow;
3003
3004 uneg = u1 >> 31; // -1 if u < 0.
3005 if (uneg) { // Compute the absolute
3006 u0 = -u0; // value of the dividend u.
3007 borrow = (u0 != 0);
3008 u1 = -u1 - borrow;}
3009
3010 vneg = v >> 31; // -1 if v < 0.
3011 v = (v ^ vneg) - vneg; // Absolute value of v.
3012
3013 if ((UInt)u1 >= (UInt)v) goto overflow;
3014
3015 q = divlu2(u1, u0, v, (UInt *)r);
3016
3017 diff = uneg ^ vneg; // Negate q if signs of
3018 q = (q ^ diff) - diff; // u and v differed.
3019 if (uneg && r != NULL)
3020 *r = -*r;
3021
3022 if ((diff ^ q) < 0 && q != 0) { // If overflow,
3023 overflow: // set remainder
3024 if (r != NULL) // to an impossible value,
3025 *r = 0x80000000; // and return the largest
3026 q = 0x80000000;} // possible neg. quotient.
3027 return q;
3028}
3029
3030
3031
3032/* This file contains a program for doing 64/64 ==> 64 division, on a
3033machine that does not have that instruction but that does have
3034instructions for "long division" (64/32 ==> 32). Code for unsigned
3035division is given first, followed by a simple program for doing the
3036signed version by using the unsigned version.
3037 These programs are useful in implementing "long long" (64-bit)
3038arithmetic on a machine that has the long division instruction. It will
3039work on 64- and 32-bit machines, provided the compiler implements long
3040long's (64-bit integers). It is desirable that the machine have the
3041Count Leading Zeros instruction.
3042 In the GNU world, these programs are known as __divdi3 and __udivdi3,
3043and similar names are used here.
3044 This material is not in HD, but may be in a future edition.
3045Max line length is 57, to fit in hacker.book. */
3046
3047
3048static Int nlz64(ULong x)
3049{
3050 Int n;
3051 if (x == 0) return(64);
3052 n = 0;
3053 if (x <= 0x00000000FFFFFFFFULL) {n = n + 32; x = x << 32;}
3054 if (x <= 0x0000FFFFFFFFFFFFULL) {n = n + 16; x = x << 16;}
3055 if (x <= 0x00FFFFFFFFFFFFFFULL) {n = n + 8; x = x << 8;}
3056 if (x <= 0x0FFFFFFFFFFFFFFFULL) {n = n + 4; x = x << 4;}
3057 if (x <= 0x3FFFFFFFFFFFFFFFULL) {n = n + 2; x = x << 2;}
3058 if (x <= 0x7FFFFFFFFFFFFFFFULL) {n = n + 1;}
3059 return n;
3060}
3061
3062// ---------------------------- udivdi3 --------------------------------
3063
3064 /* The variables u0, u1, etc. take on only 32-bit values, but they
3065 are declared long long to avoid some compiler warning messages and to
3066 avoid some unnecessary EXTRs that the compiler would put in, to
3067 convert long longs to ints.
3068
3069 First the procedure takes care of the case in which the divisor is a
3070 32-bit quantity. There are two subcases: (1) If the left half of the
3071 dividend is less than the divisor, one execution of DIVU is all that
3072 is required (overflow is not possible). (2) Otherwise it does two
3073 divisions, using the grade school method, with variables used as
3074 suggested below.
3075
3076 q1 q0
3077 ________
3078 v) u1 u0
3079 q1*v
3080 ____
3081 k u0 */
3082
3083/* These macros must be used with arguments of the appropriate type
3084(unsigned long long for DIVU and long long for DIVS. They are
3085simulations of the presumed machines ops. I.e., they look at only the
3086low-order 32 bits of the divisor, they return garbage if the division
3087overflows, and they return garbage in the high-order half of the
3088quotient doubleword.
3089 In practice, these would be replaced with uses of the machine's DIVU
3090and DIVS instructions (e.g., by using the GNU "asm" facility). */
3091
3092static UInt DIVU ( ULong u, UInt v )
3093{
3094 UInt uHi = (UInt)(u >> 32);
3095 UInt uLo = (UInt)u;
3096 return divlu2(uHi, uLo, v, NULL);
3097}
3098
3099static Int DIVS ( Long u, Int v )
3100{
3101 Int uHi = (Int)(u >> 32);
3102 UInt uLo = (UInt)u;
3103 return divls(uHi, uLo, v, NULL);
3104}
3105
3106/* 64 x 64 ==> 64 unsigned division, using only 32 x 32 ==> 32
3107 division as a primitive. */
3108static ULong udivdi3(ULong u, ULong v)
3109{
3110 ULong u0, u1, v1, q0, q1, k, n;
3111
3112 if (v >> 32 == 0) { // If v < 2**32:
3113 if (u >> 32 < v) // If u/v cannot overflow,
3114 return DIVU(u, v) // just do one division.
3115 & 0xFFFFFFFF;
3116 else { // If u/v would overflow:
3117 u1 = u >> 32; // Break u up into two
3118 u0 = u & 0xFFFFFFFF; // halves.
3119 q1 = DIVU(u1, v) // First quotient digit.
3120 & 0xFFFFFFFF;
3121 k = u1 - q1*v; // First remainder, < v.
3122 q0 = DIVU((k << 32) + u0, v) // 2nd quot. digit.
3123 & 0xFFFFFFFF;
3124 return (q1 << 32) + q0;
3125 }
3126 }
3127 // Here v >= 2**32.
3128 n = nlz64(v); // 0 <= n <= 31.
3129 v1 = (v << n) >> 32; // Normalize the divisor
3130 // so its MSB is 1.
3131 u1 = u >> 1; // To ensure no overflow.
3132 q1 = DIVU(u1, v1) // Get quotient from
3133 & 0xFFFFFFFF; // divide unsigned insn.
3134 q0 = (q1 << n) >> 31; // Undo normalization and
3135 // division of u by 2.
3136 if (q0 != 0) // Make q0 correct or
3137 q0 = q0 - 1; // too small by 1.
3138 if ((u - q0*v) >= v)
3139 q0 = q0 + 1; // Now q0 is correct.
3140 return q0;
3141}
3142
3143
3144// ----------------------------- divdi3 --------------------------------
3145
3146/* This routine presumes that smallish cases (those which can be done in
3147one execution of DIVS) are common. If this is not the case, the test for
3148this case should be deleted.
3149 Note that the test for when DIVS can be used is not entirely
3150accurate. For example, DIVS is not used if v = 0xFFFFFFFF8000000,
3151whereas if could be (if u is sufficiently small in magnitude). */
3152
3153// ------------------------------ cut ----------------------------------
3154
3155static ULong my_llabs ( Long x )
3156{
3157 ULong t = x >> 63;
3158 return (x ^ t) - t;
3159}
3160
3161/* 64 x 64 ==> 64 signed division, using only 32 x 32 ==> 32 division
3162 as a primitive. */
3163static Long divdi3(Long u, Long v)
3164{
3165 ULong au, av;
3166 Long q, t;
3167 au = my_llabs(u);
3168 av = my_llabs(v);
3169 if (av >> 31 == 0) { // If |v| < 2**31 and
3170 // if (v << 32 >> 32 == v) { // If v is in range and
3171 if (au < av << 31) { // |u|/|v| cannot
3172 q = DIVS(u, v); // overflow, use DIVS.
3173 return (q << 32) >> 32;
3174 }
3175 }
3176 q = udivdi3(au,av); // Invoke udivdi3.
3177 t = (u ^ v) >> 63; // If u, v have different
3178 return (q ^ t) - t; // signs, negate q.
3179}
3180
3181// ---------------------------- end cut --------------------------------
3182
sewardj0af71bb2010-07-01 14:50:30 +00003183ULong __udivdi3 (ULong u, ULong v);
njnea2d6fd2010-07-01 00:20:20 +00003184ULong __udivdi3 (ULong u, ULong v)
3185{
3186 return udivdi3(u,v);
3187}
3188
sewardj0af71bb2010-07-01 14:50:30 +00003189Long __divdi3 (Long u, Long v);
njnea2d6fd2010-07-01 00:20:20 +00003190Long __divdi3 (Long u, Long v)
3191{
3192 return divdi3(u,v);
3193}
3194
sewardj0af71bb2010-07-01 14:50:30 +00003195ULong __umoddi3 (ULong u, ULong v);
njnea2d6fd2010-07-01 00:20:20 +00003196ULong __umoddi3 (ULong u, ULong v)
3197{
3198 ULong q = __udivdi3(u, v);
3199 ULong r = u - q * v;
3200 return r;
3201}
3202
sewardj0af71bb2010-07-01 14:50:30 +00003203Long __moddi3 (Long u, Long v);
njnea2d6fd2010-07-01 00:20:20 +00003204Long __moddi3 (Long u, Long v)
3205{
3206 Long q = __divdi3(u, v);
3207 Long r = u - q * v;
3208 return r;
3209}
3210
sewardj70d71c72011-08-23 07:35:42 +00003211/* ------------------------------------------------
3212 ld_classic: Undefined symbols:
3213 ___fixunsdfdi
3214 ------------------------------------------------
3215*/
3216
3217/* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------===
3218 *
3219 * The LLVM Compiler Infrastructure
3220 *
3221 * This file is dual licensed under the MIT and the University of Illinois Open
3222 * Source Licenses. See LICENSE.TXT for details.
3223 *
3224 * ===----------------------------------------------------------------------===
3225 *
3226 * This file implements __fixunsdfdi for the compiler_rt library.
3227 *
3228 * ===----------------------------------------------------------------------===
3229 */
3230
3231/* As per http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses,
3232
3233 the "NCSA/University of Illinois Open Source License" is compatible
3234 with the GPL (both version 2 and 3). What is claimed to be
3235 compatible is this
3236
3237 http://www.opensource.org/licenses/UoI-NCSA.php
3238
3239 and the LLVM documentation at
3240
3241 http://www.llvm.org/docs/DeveloperPolicy.html#license
3242
3243 says all the code in LLVM is available under the University of
3244 Illinois/NCSA Open Source License, at this URL
3245
3246 http://www.opensource.org/licenses/UoI-NCSA.php
3247
3248 viz, the same one that the FSF pages claim is compatible. So I
3249 think it's OK to include it.
3250*/
3251
3252/* Returns: convert a to a unsigned long long, rounding toward zero.
3253 * Negative values all become zero.
3254 */
3255
3256/* Assumption: double is a IEEE 64 bit floating point type
3257 * du_int is a 64 bit integral type
3258 * value in double is representable in du_int or is negative
3259 * (no range checking performed)
3260 */
3261
3262/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
3263
3264typedef unsigned long long du_int;
3265typedef unsigned su_int;
3266
3267typedef union
3268{
3269 du_int all;
3270 struct
3271 {
3272#if VG_LITTLEENDIAN
3273 su_int low;
3274 su_int high;
3275#else
3276 su_int high;
3277 su_int low;
3278#endif /* VG_LITTLEENDIAN */
3279 }s;
3280} udwords;
3281
3282typedef union
3283{
3284 udwords u;
3285 double f;
3286} double_bits;
3287
3288du_int __fixunsdfdi(double a);
3289
3290du_int
3291__fixunsdfdi(double a)
3292{
3293 double_bits fb;
3294 fb.f = a;
3295 int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
3296 if (e < 0 || (fb.u.s.high & 0x80000000))
3297 return 0;
3298 udwords r;
3299 r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
3300 r.s.low = fb.u.s.low;
3301 if (e > 52)
3302 r.all <<= (e - 52);
3303 else
3304 r.all >>= (52 - e);
3305 return r.all;
3306}
3307
3308
njnea2d6fd2010-07-01 00:20:20 +00003309#endif
3310
3311
sewardjde4a1d02002-03-22 01:27:54 +00003312/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00003313/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00003314/*--------------------------------------------------------------------*/