blob: e880e3c143ed054485d9e77e09e13e3ea8170ebb [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
njn9f207462009-03-10 22:02:09 +000010 Copyright (C) 2000-2009 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"
njnc7561b92005-06-19 01:24:32 +000034#include "pub_core_threadstate.h"
sewardj14c7cc52007-02-25 15:08:24 +000035#include "pub_core_xarray.h"
sewardj45f4e7c2005-09-27 19:20:21 +000036#include "pub_core_clientstate.h"
sewardj55f9d1a2005-04-25 11:11:44 +000037#include "pub_core_aspacemgr.h"
njnac1e0332009-05-08 00:39:31 +000038#include "pub_core_aspacehl.h"
sewardj45f4e7c2005-09-27 19:20:21 +000039#include "pub_core_commandline.h"
njn2521d322005-05-08 14:45:13 +000040#include "pub_core_debuglog.h"
41#include "pub_core_errormgr.h"
42#include "pub_core_execontext.h"
sewardj17c11042006-10-15 01:26:40 +000043#include "pub_core_initimg.h"
njn97405b22005-06-02 03:39:33 +000044#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000045#include "pub_core_libcassert.h"
njneb8896b2005-06-04 20:03:55 +000046#include "pub_core_libcfile.h"
njn36a20fa2005-06-03 03:08:39 +000047#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000048#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +000049#include "pub_core_libcsignal.h"
sewardj45f4e7c2005-09-27 19:20:21 +000050#include "pub_core_syscall.h" // VG_(strerror)
njnf536bbb2005-06-13 04:21:38 +000051#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +000052#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000053#include "pub_core_options.h"
sewardjfdf91b42005-09-28 00:53:09 +000054#include "pub_core_debuginfo.h"
njnd1af0032005-05-29 17:01:48 +000055#include "pub_core_redir.h"
njnc7561b92005-06-19 01:24:32 +000056#include "pub_core_scheduler.h"
njn0c246472005-05-31 01:00:08 +000057#include "pub_core_signals.h"
njn2025cf92005-06-26 20:44:48 +000058#include "pub_core_stacks.h" // For VG_(register_stack)
njnc1b01812005-06-17 22:19:06 +000059#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +000060#include "pub_core_tooliface.h"
sewardj17c11042006-10-15 01:26:40 +000061#include "pub_core_translate.h" // For VG_(translate)
njna7598f62005-06-18 03:27:58 +000062#include "pub_core_trampoline.h"
njn8bddf582005-05-13 23:40:55 +000063#include "pub_core_transtab.h"
sewardj17c11042006-10-15 01:26:40 +000064
65/* Stuff for reading AIX5 /proc/<pid>/sysent files */
66#if defined(VGO_aix5)
67 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
68# include <sys/procfs.h> /* prsysent_t */
69 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
70# define VG_AIX5_SYSENT_SIZE 100000
71 static UChar aix5_sysent_buf[VG_AIX5_SYSENT_SIZE];
72#endif
nethercote71980f02004-01-24 18:18:54 +000073
sewardjb5f6f512005-03-10 23:59:00 +000074
nethercote71980f02004-01-24 18:18:54 +000075/*====================================================================*/
76/*=== Counters, for profiling purposes only ===*/
77/*====================================================================*/
sewardjde4a1d02002-03-22 01:27:54 +000078
nethercote3a42fb82004-08-03 18:08:50 +000079static void print_all_stats ( void )
nethercote71980f02004-01-24 18:18:54 +000080{
njn42c83552005-12-05 20:45:59 +000081 VG_(print_translation_stats)();
nethercote92e7b7f2004-08-07 17:52:25 +000082 VG_(print_tt_tc_stats)();
nethercote844e7122004-08-02 15:27:22 +000083 VG_(print_scheduler_stats)();
njn9271cbc2005-03-13 05:38:25 +000084 VG_(print_ExeContext_stats)();
sewardj12ab7652006-10-17 02:10:42 +000085 VG_(print_errormgr_stats)();
njn9271cbc2005-03-13 05:38:25 +000086
nethercote3a42fb82004-08-03 18:08:50 +000087 // Memory stats
nethercote885dd912004-08-03 23:14:00 +000088 if (VG_(clo_verbosity) > 2) {
nethercote3a42fb82004-08-03 18:08:50 +000089 VG_(message)(Vg_DebugMsg, "");
90 VG_(message)(Vg_DebugMsg,
91 "------ Valgrind's internal memory use stats follow ------" );
nethercote885dd912004-08-03 23:14:00 +000092 VG_(sanity_check_malloc_all)();
njn11adeb22005-07-03 20:22:39 +000093 VG_(message)(Vg_DebugMsg, "------" );
nethercote3a42fb82004-08-03 18:08:50 +000094 VG_(print_all_arena_stats)();
nethercote885dd912004-08-03 23:14:00 +000095 VG_(message)(Vg_DebugMsg, "");
nethercote3a42fb82004-08-03 18:08:50 +000096 }
nethercote71980f02004-01-24 18:18:54 +000097}
98
99
100/*====================================================================*/
sewardj71bc3cb2005-05-19 00:25:45 +0000101/*=== Command-line: variables, processing, etc ===*/
102/*====================================================================*/
103
104// See pub_{core,tool}_options.h for explanations of all these.
105
sewardj45f4e7c2005-09-27 19:20:21 +0000106static void usage_NORETURN ( Bool debug_help )
njn7cf0bd32002-06-08 13:36:03 +0000107{
sewardj7839d112007-11-20 19:45:03 +0000108 /* 'usage1' contains a %s for the name of the GDB executable, which
109 must be supplied when it is VG_(printf)'d. */
njn25e49d8e72002-09-23 09:36:25 +0000110 Char* usage1 =
njn00cfcfc2005-11-12 18:53:50 +0000111"usage: valgrind [options] prog-and-args\n"
njn25e49d8e72002-09-23 09:36:25 +0000112"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000113" common user options for all Valgrind tools, with defaults in [ ]:\n"
sewardjb5f6f512005-03-10 23:59:00 +0000114" --tool=<name> use the Valgrind tool named <name> [memcheck]\n"
nethercotea76368b2004-06-16 11:56:29 +0000115" -h --help show this message\n"
nethercote6c999f22004-01-31 22:55:15 +0000116" --help-debug show this message, plus debugging options\n"
njn25e49d8e72002-09-23 09:36:25 +0000117" --version show version\n"
njn25e49d8e72002-09-23 09:36:25 +0000118" -q --quiet run silently; only print error msgs\n"
119" -v --verbose be more verbose, incl counts of errors\n"
sewardj6e31f802007-11-17 22:29:25 +0000120" --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]\n"
121" --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n"
nethercote0d588502004-06-21 13:27:11 +0000122" --track-fds=no|yes track open file descriptors? [no]\n"
thughes6233a382004-08-21 11:10:44 +0000123" --time-stamp=no|yes add timestamps to log messages? [no]\n"
njnce545552005-07-25 22:36:52 +0000124" --log-fd=<number> log messages to file descriptor [2=stderr]\n"
njn374a36d2007-11-23 01:41:32 +0000125" --log-file=<file> log messages to <file>\n"
njnce545552005-07-25 22:36:52 +0000126" --log-socket=ipaddr:port log messages to socket ipaddr:port\n"
nethercote2b0793f2003-12-02 10:41:18 +0000127"\n"
128" uncommon user options for all Valgrind tools:\n"
nethercote0d588502004-06-21 13:27:11 +0000129" --run-libc-freeres=no|yes free up glibc memory at exit? [yes]\n"
njn628add62005-11-12 18:21:40 +0000130" --sim-hints=hint1,hint2,... known hints:\n"
sewardj19617ae2005-10-20 01:09:57 +0000131" lax-ioctls, enable-outer [none]\n"
sewardjb1131a82005-03-19 15:12:21 +0000132" --show-emwarns=no|yes show warnings about emulation limits? [no]\n"
sewardj6c3a2192005-07-24 07:00:45 +0000133" --smc-check=none|stack|all checks for self-modifying code: none,\n"
134" only for code found in stacks, or all [stack]\n"
sewardj3c3f0c12005-11-08 15:52:36 +0000135" --kernel-variant=variant1,variant2,... known variants: bproc [none]\n"
136" handle non-standard kernel variants\n"
sewardj04eb1092008-12-21 10:45:55 +0000137" --read-var-info=yes|no read debug info on stack and global variables\n"
138" and use it to print better error messages in\n"
139" tools that make use of it (Memcheck, Helgrind)\n"
njn25e49d8e72002-09-23 09:36:25 +0000140"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000141" user options for Valgrind tools that report errors:\n"
njnca54af32006-04-16 10:25:43 +0000142" --xml=yes all output is in XML (some tools only)\n"
njnc8ec9f82005-07-20 03:03:28 +0000143" --xml-user-comment=STR copy STR verbatim to XML output\n"
nethercote2b0793f2003-12-02 10:41:18 +0000144" --demangle=no|yes automatically demangle C++ names? [yes]\n"
njn20b4a152005-10-19 22:39:40 +0000145" --num-callers=<number> show <number> callers in stack traces [12]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000146" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
sewardjb9779082006-05-12 23:50:15 +0000147" --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000148" --show-below-main=no|yes continue stack traces below main() [no]\n"
149" --suppressions=<filename> suppress errors described in <filename>\n"
sewardjd153fae2005-01-10 17:24:47 +0000150" --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000151" --db-attach=no|yes start debugger when errors detected? [no]\n"
sewardj7839d112007-11-20 19:45:03 +0000152" --db-command=<command> command to start debugger [%s -nw %%f %%p]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000153" --input-fd=<number> file descriptor for input [0=stdin]\n"
sewardj97724e52005-04-02 23:40:59 +0000154" --max-stackframe=<number> assume stack switch for SP changes larger\n"
155" than <number> bytes [2000000]\n"
sewardj95d86c02007-12-18 01:49:23 +0000156" --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
157" [use current 'ulimit' value]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000158"\n";
njn7cf0bd32002-06-08 13:36:03 +0000159
njn25e49d8e72002-09-23 09:36:25 +0000160 Char* usage2 =
161"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000162" debugging options for all Valgrind tools:\n"
njn25e49d8e72002-09-23 09:36:25 +0000163" --sanity-level=<number> level of sanity checking to do [1]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000164" --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
165" --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
sewardj33afdb52006-01-17 02:36:40 +0000166" --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
njn25e49d8e72002-09-23 09:36:25 +0000167" --trace-syscalls=no|yes show all system calls? [no]\n"
168" --trace-signals=no|yes show signal handling details? [no]\n"
169" --trace-symtab=no|yes show symbol table details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000170" --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
sewardjce058b02005-05-01 08:55:38 +0000171" --trace-cfi=no|yes show call-frame-info details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000172" --debug-dump=syms mimic /usr/bin/readelf --syms\n"
173" --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
174" --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
sewardj0ec07f32006-01-12 12:32:32 +0000175" --trace-redir=no|yes show redirection details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000176" --trace-sched=no|yes show thread scheduler details? [no]\n"
sewardj9c606bd2008-09-18 18:12:50 +0000177" --profile-heap=no|yes profile Valgrind's own space use\n"
jsgf855d93d2003-10-13 22:26:55 +0000178" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
sewardj17c11042006-10-15 01:26:40 +0000179" --sym-offsets=yes|no show syms in form 'name+offset' ? [no]\n"
sewardjb5f6f512005-03-10 23:59:00 +0000180" --command-line-only=no|yes only use command line options [no]\n"
njn613812e2005-03-11 04:57:30 +0000181"\n"
182" --vex-iropt-verbosity 0 .. 9 [0]\n"
183" --vex-iropt-level 0 .. 2 [2]\n"
184" --vex-iropt-precise-memory-exns [no]\n"
sewardj8b635a42004-11-22 19:01:47 +0000185" --vex-iropt-unroll-thresh 0 .. 400 [120]\n"
186" --vex-guest-max-insns 1 .. 100 [50]\n"
187" --vex-guest-chase-thresh 0 .. 99 [10]\n"
188"\n"
sewardjfa8ec112005-01-19 11:55:34 +0000189" --trace-flags and --profile-flags values (omit the middle space):\n"
sewardj2a99cf62004-11-24 10:44:19 +0000190" 1000 0000 show conversion into IR\n"
191" 0100 0000 show after initial opt\n"
192" 0010 0000 show after instrumentation\n"
193" 0001 0000 show after second opt\n"
194" 0000 1000 show after tree building\n"
195" 0000 0100 show selecting insns\n"
196" 0000 0010 show after reg-alloc\n"
197" 0000 0001 show final assembly\n"
njn33dbfce2006-06-02 22:58:34 +0000198" (Nb: you need --trace-notbelow with --trace-flags for full details)\n"
sewardj2a99cf62004-11-24 10:44:19 +0000199"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000200" debugging options for Valgrind tools that report errors\n"
201" --dump-error=<number> show translation for basic block associated\n"
202" with <number>'th error context [0=show none]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000203"\n";
njn3e884182003-04-15 13:03:23 +0000204
205 Char* usage3 =
206"\n"
nethercote71980f02004-01-24 18:18:54 +0000207" Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
njn25e49d8e72002-09-23 09:36:25 +0000208"\n"
njn9f207462009-03-10 22:02:09 +0000209" Valgrind is Copyright (C) 2000-2009 Julian Seward et al.\n"
njn25e49d8e72002-09-23 09:36:25 +0000210" and licensed under the GNU General Public License, version 2.\n"
211" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
njnd04b7c62002-10-03 14:05:52 +0000212"\n"
nethercote137bc552003-11-14 17:47:54 +0000213" Tools are copyright and licensed by their authors. See each\n"
214" tool's start-up message for more information.\n"
njn25e49d8e72002-09-23 09:36:25 +0000215"\n";
njn7cf0bd32002-06-08 13:36:03 +0000216
sewardj12373b12007-11-20 21:38:14 +0000217 Char* gdb_path = GDB_PATH;
sewardj12373b12007-11-20 21:38:14 +0000218
njnbe9b47b2005-05-15 16:22:58 +0000219 // Ensure the message goes to stdout
220 VG_(clo_log_fd) = 1;
221 vg_assert( !VG_(logging_to_socket) );
222
sewardj7839d112007-11-20 19:45:03 +0000223 /* 'usage1' expects one char* argument */
sewardj12373b12007-11-20 21:38:14 +0000224 VG_(printf)(usage1, gdb_path);
fitzhardinge98abfc72003-12-16 02:05:15 +0000225 if (VG_(details).name) {
226 VG_(printf)(" user options for %s:\n", VG_(details).name);
fitzhardinge98abfc72003-12-16 02:05:15 +0000227 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000228 VG_TDICT_CALL(tool_print_usage);
fitzhardinge98abfc72003-12-16 02:05:15 +0000229 else
230 VG_(printf)(" (none)\n");
231 }
nethercote6c999f22004-01-31 22:55:15 +0000232 if (debug_help) {
sewardjbbaef872008-11-01 23:55:32 +0000233 VG_(printf)("%s", usage2);
fitzhardinge98abfc72003-12-16 02:05:15 +0000234
nethercote6c999f22004-01-31 22:55:15 +0000235 if (VG_(details).name) {
236 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
237
238 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000239 VG_TDICT_CALL(tool_print_debug_usage);
nethercote6c999f22004-01-31 22:55:15 +0000240 else
241 VG_(printf)(" (none)\n");
242 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000243 }
nethercote421281e2003-11-20 16:20:55 +0000244 VG_(printf)(usage3, VG_BUGS_TO);
nethercotef4928da2004-06-15 10:54:40 +0000245 VG_(exit)(0);
njn7cf0bd32002-06-08 13:36:03 +0000246}
sewardjde4a1d02002-03-22 01:27:54 +0000247
sewardjde4a1d02002-03-22 01:27:54 +0000248
sewardj95d86c02007-12-18 01:49:23 +0000249/* Peer at previously set up VG_(args_for_valgrind) and do some
250 minimal command line processing that must happen early on:
sewardj45f4e7c2005-09-27 19:20:21 +0000251
sewardj95d86c02007-12-18 01:49:23 +0000252 - show the version string, if requested (-v)
253 - extract any request for help (--help, -h, --help-debug)
254 - get the toolname (--tool=)
255 - set VG_(clo_max_stackframe) (--max-stackframe=)
256 - set VG_(clo_main_stacksize) (--main-stacksize=)
257
258 That's all it does. The main command line processing is done below
259 by main_process_cmd_line_options. Note that
260 main_process_cmd_line_options has to handle but ignore the ones we
261 have handled here.
262*/
263static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
264 /*OUT*/HChar** tool )
sewardj45f4e7c2005-09-27 19:20:21 +0000265{
266 UInt i;
267 HChar* str;
sewardj8b635a42004-11-22 19:01:47 +0000268
sewardj14c7cc52007-02-25 15:08:24 +0000269 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000270
sewardj14c7cc52007-02-25 15:08:24 +0000271 /* parse the options we have (only the options we care about now) */
272 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
273
274 str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000275 vg_assert(str);
nethercote71980f02004-01-24 18:18:54 +0000276
njn83df0b62009-02-25 01:01:05 +0000277 // Nb: the version string goes to stdout.
278 if VG_XACT_CLO(str, "--version", VG_(clo_log_fd), 1) {
sewardj45f4e7c2005-09-27 19:20:21 +0000279 VG_(printf)("valgrind-" VERSION "\n");
280 VG_(exit)(0);
njn83df0b62009-02-25 01:01:05 +0000281 }
282 else if VG_XACT_CLO(str, "--help", *need_help, 1) {}
283 else if VG_XACT_CLO(str, "-h", *need_help, 1) {}
sewardj45f4e7c2005-09-27 19:20:21 +0000284
njn83df0b62009-02-25 01:01:05 +0000285 else if VG_XACT_CLO(str, "--help-debug", *need_help, 2) {}
nethercote71980f02004-01-24 18:18:54 +0000286
sewardj45f4e7c2005-09-27 19:20:21 +0000287 // The tool has already been determined, but we need to know the name
288 // here.
njn83df0b62009-02-25 01:01:05 +0000289 else if VG_STR_CLO(str, "--tool", *tool) {}
sewardj5bdfbd22007-12-15 22:13:05 +0000290
sewardj95d86c02007-12-18 01:49:23 +0000291 // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
292 // These are needed by VG_(ii_create_image), which happens
293 // before main_process_cmd_line_options().
njn83df0b62009-02-25 01:01:05 +0000294 else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
295 else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
nethercote71980f02004-01-24 18:18:54 +0000296 }
nethercote71980f02004-01-24 18:18:54 +0000297}
298
sewardj95d86c02007-12-18 01:49:23 +0000299/* The main processing for command line options. See comments above
300 on early_process_cmd_line_options.
301*/
njn1dcee092009-02-24 03:07:37 +0000302static Bool main_process_cmd_line_options( const HChar* toolname )
nethercote71980f02004-01-24 18:18:54 +0000303{
njnda033f52005-12-19 21:27:58 +0000304 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
305 // and we cannot change it until we know what we are changing it to is
306 // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
sewardj92645592005-07-23 09:18:34 +0000307 SysRes sres;
njnda033f52005-12-19 21:27:58 +0000308 Int i, tmp_log_fd;
sewardj92645592005-07-23 09:18:34 +0000309 Int toolname_len = VG_(strlen)(toolname);
njn83df0b62009-02-25 01:01:05 +0000310 Char* tmp_str; // Used in a couple of places.
njnbe9b47b2005-05-15 16:22:58 +0000311 enum {
312 VgLogTo_Fd,
313 VgLogTo_File,
njnbe9b47b2005-05-15 16:22:58 +0000314 VgLogTo_Socket
315 } log_to = VgLogTo_Fd; // Where is logging output to be sent?
sewardjde4a1d02002-03-22 01:27:54 +0000316
nethercotee1730692003-11-20 10:38:07 +0000317 /* log to stderr by default, but usage message goes to stdout */
njnda033f52005-12-19 21:27:58 +0000318 tmp_log_fd = 2;
sewardjde4a1d02002-03-22 01:27:54 +0000319
sewardj19d81412002-06-03 01:10:40 +0000320 /* Check for sane path in ./configure --prefix=... */
fitzhardinge98abfc72003-12-16 02:05:15 +0000321 if (VG_LIBDIR[0] != '/')
sewardj17c11042006-10-15 01:26:40 +0000322 VG_(err_config_error)("Please use absolute paths in "
323 "./configure --prefix=... or --libdir=...");
sewardj38170912002-05-10 21:07:22 +0000324
sewardj14c7cc52007-02-25 15:08:24 +0000325 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000326
sewardj14c7cc52007-02-25 15:08:24 +0000327 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
328
329 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000330 HChar* colon = arg;
nethercote71980f02004-01-24 18:18:54 +0000331
njn1274d242007-03-26 23:38:42 +0000332 // Look for a colon in the option name.
thughes3bfd5a02004-07-18 08:05:44 +0000333 while (*colon && *colon != ':' && *colon != '=')
334 colon++;
nethercote71980f02004-01-24 18:18:54 +0000335
njn1274d242007-03-26 23:38:42 +0000336 // Does it have the form "--toolname:foo"? We have to do it at the start
337 // in case someone has combined a prefix with a core-specific option,
338 // eg. "--memcheck:verbose".
thughes3bfd5a02004-07-18 08:05:44 +0000339 if (*colon == ':') {
njn83df0b62009-02-25 01:01:05 +0000340 if (VG_STREQN(2, arg, "--") &&
341 VG_STREQN(toolname_len, arg+2, toolname) &&
342 VG_STREQN(1, arg+2+toolname_len, ":"))
nethercote71980f02004-01-24 18:18:54 +0000343 {
njn1274d242007-03-26 23:38:42 +0000344 // Prefix matches, convert "--toolname:foo" to "--foo".
345 // Two things to note:
346 // - We cannot modify the option in-place. If we did, and then
347 // a child was spawned with --trace-children=yes, the
348 // now-non-prefixed option would be passed and could screw up
349 // the child.
350 // - We create copies, and never free them. Why? Non-prefixed
351 // options hang around forever, so tools need not make copies
352 // of strings within them. We need to have the same behaviour
353 // for prefixed options. The pointer to the copy will be lost
354 // once we leave this function (although a tool may keep a
355 // pointer into it), but the space wasted is insignificant.
356 // (In bug #142197, the copies were being freed, which caused
357 // problems for tools that reasonably assumed that arguments
358 // wouldn't disappear on them.)
nethercote71980f02004-01-24 18:18:54 +0000359 if (0)
360 VG_(printf)("tool-specific arg: %s\n", arg);
sewardj9c606bd2008-09-18 18:12:50 +0000361 arg = VG_(strdup)("main.mpclo.1", arg + toolname_len + 1);
nethercote71980f02004-01-24 18:18:54 +0000362 arg[0] = '-';
363 arg[1] = '-';
364
365 } else {
366 // prefix doesn't match, skip to next arg
367 continue;
368 }
369 }
370
fitzhardinge98abfc72003-12-16 02:05:15 +0000371 /* Ignore these options - they've already been handled */
njn83df0b62009-02-25 01:01:05 +0000372 if VG_STREQN( 7, arg, "--tool=") {}
373 else if VG_STREQN(20, arg, "--command-line-only=") {}
374 else if VG_STREQ( arg, "--") {}
375 else if VG_STREQ( arg, "-d") {}
376 else if VG_STREQN(16, arg, "--max-stackframe") {}
377 else if VG_STREQN(16, arg, "--main-stacksize") {}
378 else if VG_STREQN(14, arg, "--profile-heap") {}
nethercote27fec902004-06-16 21:26:32 +0000379
njn83df0b62009-02-25 01:01:05 +0000380 // These options are new.
381 else if (VG_STREQ(arg, "-v") ||
382 VG_STREQ(arg, "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000383 VG_(clo_verbosity)++;
nethercote27fec902004-06-16 21:26:32 +0000384
njn83df0b62009-02-25 01:01:05 +0000385 else if (VG_STREQ(arg, "-q") ||
386 VG_STREQ(arg, "--quiet"))
sewardjde4a1d02002-03-22 01:27:54 +0000387 VG_(clo_verbosity)--;
388
njn83df0b62009-02-25 01:01:05 +0000389 else if VG_BOOL_CLO(arg, "--xml", VG_(clo_xml)) {}
390 else if VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach)) {}
391 else if VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle)) {}
392 else if VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit)) {}
393 else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
394 else if VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns)) {}
sewardj95d86c02007-12-18 01:49:23 +0000395
njn83df0b62009-02-25 01:01:05 +0000396 else if VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres)) {}
397 else if VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main)) {}
398 else if VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp)) {}
399 else if VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds)) {}
400 else if VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children)) {}
401 else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
402 VG_(clo_child_silent_after_fork)) {}
403 else if VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched)) {}
404 else if VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals)) {}
405 else if VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab)) {}
406 else if VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt)) {}
407 else if VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi)) {}
408 else if VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms),
409 True) {}
410 else if VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line),
411 True) {}
412 else if VG_XACT_CLO(arg, "--debug-dump=frames",
413 VG_(clo_debug_dump_frames), True) {}
414 else if VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir)) {}
sewardj95d86c02007-12-18 01:49:23 +0000415
njn83df0b62009-02-25 01:01:05 +0000416 else if VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls)) {}
417 else if VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb)) {}
418 else if VG_STR_CLO (arg, "--db-command", VG_(clo_db_command)) {}
419 else if VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints)) {}
420 else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
421 else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
sewardjf767d962007-02-12 17:47:14 +0000422
njn83df0b62009-02-25 01:01:05 +0000423 else if VG_INT_CLO (arg, "--dump-error", VG_(clo_dump_error)) {}
424 else if VG_INT_CLO (arg, "--input-fd", VG_(clo_input_fd)) {}
425 else if VG_INT_CLO (arg, "--sanity-level", VG_(clo_sanity_level)) {}
426 else if VG_BINT_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
427 VG_DEEPEST_BACKTRACE) {}
sewardjde4a1d02002-03-22 01:27:54 +0000428
njn83df0b62009-02-25 01:01:05 +0000429 else if VG_XACT_CLO(arg, "--smc-check=none", VG_(clo_smc_check),
430 Vg_SmcNone);
431 else if VG_XACT_CLO(arg, "--smc-check=stack", VG_(clo_smc_check),
432 Vg_SmcStack);
433 else if VG_XACT_CLO(arg, "--smc-check=all", VG_(clo_smc_check),
434 Vg_SmcAll);
sewardjde4a1d02002-03-22 01:27:54 +0000435
njn83df0b62009-02-25 01:01:05 +0000436 else if VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant)) {}
sewardj26412bd2005-07-07 10:05:05 +0000437
njn83df0b62009-02-25 01:01:05 +0000438 else if VG_BINT_CLO(arg, "--vex-iropt-verbosity",
439 VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
440 else if VG_BINT_CLO(arg, "--vex-iropt-level",
441 VG_(clo_vex_control).iropt_level, 0, 2) {}
442 else if VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
443 VG_(clo_vex_control).iropt_precise_memory_exns) {}
444 else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
445 VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
446 else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
447 VG_(clo_vex_control).guest_max_insns, 1, 100) {}
448 else if VG_BINT_CLO(arg, "--vex-guest-chase-thresh",
449 VG_(clo_vex_control).guest_chase_thresh, 0, 99) {}
sewardj94c8eb42008-09-19 20:13:39 +0000450
njn83df0b62009-02-25 01:01:05 +0000451 else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
452 log_to = VgLogTo_Fd;
nethercotef8548672004-06-21 12:42:35 +0000453 VG_(clo_log_name) = NULL;
sewardj4cf05692002-10-27 20:28:29 +0000454 }
455
njn83df0b62009-02-25 01:01:05 +0000456 else if VG_STR_CLO(arg, "--log-file", VG_(clo_log_name)) {
457 log_to = VgLogTo_File;
sewardj4cf05692002-10-27 20:28:29 +0000458 }
njnd6bc3c32005-03-27 00:44:31 +0000459
njn83df0b62009-02-25 01:01:05 +0000460 else if VG_STR_CLO(arg, "--log-socket", VG_(clo_log_name)) {
461 log_to = VgLogTo_Socket;
sewardj73cf3bc2002-11-03 03:20:15 +0000462 }
463
njn83df0b62009-02-25 01:01:05 +0000464 else if VG_STR_CLO(arg, "--xml-user-comment",
465 VG_(clo_xml_user_comment)) {}
sewardj768db0e2005-07-19 14:18:56 +0000466
njn83df0b62009-02-25 01:01:05 +0000467 else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
sewardjde4a1d02002-03-22 01:27:54 +0000468 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njn25e49d8e72002-09-23 09:36:25 +0000469 VG_(message)(Vg_UserMsg, "Too many suppression files specified.");
sewardjde4a1d02002-03-22 01:27:54 +0000470 VG_(message)(Vg_UserMsg,
471 "Increase VG_CLO_MAX_SFILES and recompile.");
sewardj17c11042006-10-15 01:26:40 +0000472 VG_(err_bad_option)(arg);
sewardjde4a1d02002-03-22 01:27:54 +0000473 }
njn83df0b62009-02-25 01:01:05 +0000474 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = tmp_str;
sewardjde4a1d02002-03-22 01:27:54 +0000475 VG_(clo_n_suppressions)++;
476 }
sewardjde4a1d02002-03-22 01:27:54 +0000477
sewardjfa8ec112005-01-19 11:55:34 +0000478 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000479 else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
sewardjfa8ec112005-01-19 11:55:34 +0000480 Int j;
sewardjfa8ec112005-01-19 11:55:34 +0000481
njn83df0b62009-02-25 01:01:05 +0000482 if (8 != VG_(strlen)(tmp_str)) {
sewardjfa8ec112005-01-19 11:55:34 +0000483 VG_(message)(Vg_UserMsg,
484 "--trace-flags argument must have 8 digits");
sewardj17c11042006-10-15 01:26:40 +0000485 VG_(err_bad_option)(arg);
sewardjfa8ec112005-01-19 11:55:34 +0000486 }
487 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000488 if ('0' == tmp_str[j]) { /* do nothing */ }
489 else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
sewardjfa8ec112005-01-19 11:55:34 +0000490 else {
491 VG_(message)(Vg_UserMsg, "--trace-flags argument can only "
492 "contain 0s and 1s");
sewardj17c11042006-10-15 01:26:40 +0000493 VG_(err_bad_option)(arg);
sewardjfa8ec112005-01-19 11:55:34 +0000494 }
495 }
496 }
497
498 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000499 else if VG_STR_CLO(arg, "--profile-flags", tmp_str) {
njn25e49d8e72002-09-23 09:36:25 +0000500 Int j;
njn25e49d8e72002-09-23 09:36:25 +0000501
njn83df0b62009-02-25 01:01:05 +0000502 if (8 != VG_(strlen)(tmp_str)) {
njn25e49d8e72002-09-23 09:36:25 +0000503 VG_(message)(Vg_UserMsg,
sewardjfa8ec112005-01-19 11:55:34 +0000504 "--profile-flags argument must have 8 digits");
sewardj17c11042006-10-15 01:26:40 +0000505 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000506 }
sewardj8b635a42004-11-22 19:01:47 +0000507 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000508 if ('0' == tmp_str[j]) { /* do nothing */ }
509 else if ('1' == tmp_str[j]) VG_(clo_profile_flags) |= (1 << (7-j));
njn25e49d8e72002-09-23 09:36:25 +0000510 else {
sewardjfa8ec112005-01-19 11:55:34 +0000511 VG_(message)(Vg_UserMsg, "--profile-flags argument can only "
njn25e49d8e72002-09-23 09:36:25 +0000512 "contain 0s and 1s");
sewardj17c11042006-10-15 01:26:40 +0000513 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000514 }
515 }
516 }
sewardjde4a1d02002-03-22 01:27:54 +0000517
njn83df0b62009-02-25 01:01:05 +0000518 else if VG_INT_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow)) {}
sewardjc771b292004-11-30 18:55:21 +0000519
njn83df0b62009-02-25 01:01:05 +0000520 else if VG_XACT_CLO(arg, "--gen-suppressions=no",
521 VG_(clo_gen_suppressions), 0) {}
522 else if VG_XACT_CLO(arg, "--gen-suppressions=yes",
523 VG_(clo_gen_suppressions), 1) {}
524 else if VG_XACT_CLO(arg, "--gen-suppressions=all",
525 VG_(clo_gen_suppressions), 2) {}
sewardjd153fae2005-01-10 17:24:47 +0000526
nethercote71980f02004-01-24 18:18:54 +0000527 else if ( ! VG_(needs).command_line_options
njn51d827b2005-05-09 01:02:08 +0000528 || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
sewardj17c11042006-10-15 01:26:40 +0000529 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000530 }
sewardjde4a1d02002-03-22 01:27:54 +0000531 }
532
sewardj998d40d2004-12-06 14:24:52 +0000533 /* Make VEX control parameters sane */
534
535 if (VG_(clo_vex_control).guest_chase_thresh
536 >= VG_(clo_vex_control).guest_max_insns)
537 VG_(clo_vex_control).guest_chase_thresh
538 = VG_(clo_vex_control).guest_max_insns - 1;
539
540 if (VG_(clo_vex_control).guest_chase_thresh < 0)
541 VG_(clo_vex_control).guest_chase_thresh = 0;
542
543 /* Check various option values */
nethercote27fec902004-06-16 21:26:32 +0000544
njnf9ebf672003-05-12 21:41:30 +0000545 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +0000546 VG_(clo_verbosity) = 0;
547
njnbe9b47b2005-05-15 16:22:58 +0000548 if (VG_(clo_gen_suppressions) > 0 &&
549 !VG_(needs).core_errors && !VG_(needs).tool_errors) {
550 VG_(message)(Vg_UserMsg,
551 "Can't use --gen-suppressions= with this tool,");
552 VG_(message)(Vg_UserMsg,
553 "as it doesn't generate errors.");
sewardj17c11042006-10-15 01:26:40 +0000554 VG_(err_bad_option)("--gen-suppressions=");
njnbe9b47b2005-05-15 16:22:58 +0000555 }
556
sewardj71bc3cb2005-05-19 00:25:45 +0000557 /* If we've been asked to emit XML, mash around various other
558 options so as to constrain the output somewhat, and to remove
559 any need for user input during the run. */
560 if (VG_(clo_xml)) {
561 /* Disable suppression generation (requires user input) */
562 VG_(clo_gen_suppressions) = 0;
563 /* Disable attaching to GDB (requires user input) */
564 VG_(clo_db_attach) = False;
565 /* Set a known verbosity level */
566 VG_(clo_verbosity) = 1;
567 /* Disable error limits (this might be a bad idea!) */
568 VG_(clo_error_limit) = False;
569 /* Disable emulation warnings */
570 VG_(clo_show_emwarns) = False;
571 /* Disable waiting for GDB to debug Valgrind */
572 VG_(clo_wait_for_gdb) = False;
573 /* No file-descriptor leak checking yet */
574 VG_(clo_track_fds) = False;
sewardj21f7f0c2005-07-06 19:46:48 +0000575 /* Disable timestamped output */
576 VG_(clo_time_stamp) = False;
sewardj9c606bd2008-09-18 18:12:50 +0000577 /* Disable heap profiling, since that prints lots of stuff. */
578 VG_(clo_profile_heap) = False;
sewardj71bc3cb2005-05-19 00:25:45 +0000579 /* Also, we want to set options for the leak checker, but that
580 will have to be done in Memcheck's flag-handling code, not
581 here. */
582 }
583
njnbe9b47b2005-05-15 16:22:58 +0000584 /* All non-logging-related options have been checked. If the logging
585 option specified is ok, we can switch to it, as we know we won't
586 have to generate any other command-line-related error messages.
587 (So far we should be still attached to stderr, so we can show on
588 the terminal any problems to do with processing command line
589 opts.)
590
591 So set up logging now. After this is done, VG_(clo_log_fd)
sewardj4cf05692002-10-27 20:28:29 +0000592 should be connected to whatever sink has been selected, and we
593 indiscriminately chuck stuff into it without worrying what the
594 nature of it is. Oh the wonder of Unix streams. */
595
njnbe9b47b2005-05-15 16:22:58 +0000596 vg_assert(VG_(clo_log_fd) == 2 /* stderr */);
597 vg_assert(VG_(logging_to_socket) == False);
sewardj4cf05692002-10-27 20:28:29 +0000598
njnbe9b47b2005-05-15 16:22:58 +0000599 switch (log_to) {
sewardj73cf3bc2002-11-03 03:20:15 +0000600
sewardj4cf05692002-10-27 20:28:29 +0000601 case VgLogTo_Fd:
nethercotef8548672004-06-21 12:42:35 +0000602 vg_assert(VG_(clo_log_name) == NULL);
sewardj4cf05692002-10-27 20:28:29 +0000603 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000604
sewardj4cf05692002-10-27 20:28:29 +0000605 case VgLogTo_File: {
njn374a36d2007-11-23 01:41:32 +0000606 Char* logfilename;
jsgff3c3f1a2003-10-14 22:13:28 +0000607
nethercotef8548672004-06-21 12:42:35 +0000608 vg_assert(VG_(clo_log_name) != NULL);
609 vg_assert(VG_(strlen)(VG_(clo_log_name)) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +0000610
njn374a36d2007-11-23 01:41:32 +0000611 // Nb: we overwrite an existing file of this name without asking
612 // any questions.
613 logfilename = VG_(expand_file_name)("--log-file", VG_(clo_log_name));
614 sres = VG_(open)(logfilename,
njnda033f52005-12-19 21:27:58 +0000615 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
616 VKI_S_IRUSR|VKI_S_IWUSR);
njncda2f0f2009-05-18 02:12:08 +0000617 if (!sr_isError(sres)) {
618 tmp_log_fd = sr_Res(sres);
njnbe9b47b2005-05-15 16:22:58 +0000619 } else {
sewardj603d4102005-01-11 14:01:02 +0000620 VG_(message)(Vg_UserMsg,
njn374a36d2007-11-23 01:41:32 +0000621 "Can't create log file '%s' (%s); giving up!",
njncda2f0f2009-05-18 02:12:08 +0000622 logfilename, VG_(strerror)(sr_Err(sres)));
sewardj17c11042006-10-15 01:26:40 +0000623 VG_(err_bad_option)(
njn374a36d2007-11-23 01:41:32 +0000624 "--log-file=<file> (didn't work out for some reason.)");
sewardj603d4102005-01-11 14:01:02 +0000625 /*NOTREACHED*/
njn374a36d2007-11-23 01:41:32 +0000626 }
sewardj603d4102005-01-11 14:01:02 +0000627 break; /* switch (VG_(clo_log_to)) */
sewardj73cf3bc2002-11-03 03:20:15 +0000628 }
629
630 case VgLogTo_Socket: {
nethercotef8548672004-06-21 12:42:35 +0000631 vg_assert(VG_(clo_log_name) != NULL);
632 vg_assert(VG_(strlen)(VG_(clo_log_name)) <= 900); /* paranoia */
njnda033f52005-12-19 21:27:58 +0000633 tmp_log_fd = VG_(connect_via_socket)( VG_(clo_log_name) );
634 if (tmp_log_fd == -1) {
sewardj73cf3bc2002-11-03 03:20:15 +0000635 VG_(message)(Vg_UserMsg,
nethercotef8548672004-06-21 12:42:35 +0000636 "Invalid --log-socket=ipaddr or --log-socket=ipaddr:port spec");
sewardj73cf3bc2002-11-03 03:20:15 +0000637 VG_(message)(Vg_UserMsg,
njn02bc4b82005-05-15 17:28:26 +0000638 "of '%s'; giving up!", VG_(clo_log_name) );
sewardj17c11042006-10-15 01:26:40 +0000639 VG_(err_bad_option)(
nethercotef8548672004-06-21 12:42:35 +0000640 "--log-socket=");
njnbe9b47b2005-05-15 16:22:58 +0000641 /*NOTREACHED*/
sewardj4cf05692002-10-27 20:28:29 +0000642 }
njnda033f52005-12-19 21:27:58 +0000643 if (tmp_log_fd == -2) {
sewardj73cf3bc2002-11-03 03:20:15 +0000644 VG_(message)(Vg_UserMsg,
njn02bc4b82005-05-15 17:28:26 +0000645 "valgrind: failed to connect to logging server '%s'.",
nethercotef8548672004-06-21 12:42:35 +0000646 VG_(clo_log_name) );
sewardj570f8902002-11-03 11:44:36 +0000647 VG_(message)(Vg_UserMsg,
648 "Log messages will sent to stderr instead." );
649 VG_(message)(Vg_UserMsg,
650 "" );
651 /* We don't change anything here. */
njnbe9b47b2005-05-15 16:22:58 +0000652 vg_assert(VG_(clo_log_fd) == 2);
njnda033f52005-12-19 21:27:58 +0000653 tmp_log_fd = 2;
sewardj570f8902002-11-03 11:44:36 +0000654 } else {
njnda033f52005-12-19 21:27:58 +0000655 vg_assert(tmp_log_fd > 0);
njnbe9b47b2005-05-15 16:22:58 +0000656 VG_(logging_to_socket) = True;
sewardj570f8902002-11-03 11:44:36 +0000657 }
sewardj73cf3bc2002-11-03 03:20:15 +0000658 break;
659 }
sewardj4cf05692002-10-27 20:28:29 +0000660 }
661
sewardj71bc3cb2005-05-19 00:25:45 +0000662
663 /* Check that the requested tool actually supports XML output. */
njnca54af32006-04-16 10:25:43 +0000664 if (VG_(clo_xml) && !VG_(needs).xml_output) {
sewardj71bc3cb2005-05-19 00:25:45 +0000665 VG_(clo_xml) = False;
666 VG_(message)(Vg_UserMsg,
njnca54af32006-04-16 10:25:43 +0000667 "%s does not support XML output.", VG_(details).name);
sewardj17c11042006-10-15 01:26:40 +0000668 VG_(err_bad_option)("--xml=yes");
sewardj71bc3cb2005-05-19 00:25:45 +0000669 /*NOTREACHED*/
670 }
671
njnda033f52005-12-19 21:27:58 +0000672 if (tmp_log_fd >= 0) {
673 // Move log_fd into the safe range, so it doesn't conflict with any app fds.
674 tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
675 if (tmp_log_fd < 0) {
676 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd into safe range, using stderr");
677 VG_(clo_log_fd) = 2; // stderr
678 } else {
679 VG_(clo_log_fd) = tmp_log_fd;
680 VG_(fcntl)(VG_(clo_log_fd), VKI_F_SETFD, VKI_FD_CLOEXEC);
681 }
682 } else {
683 // If they said --log-fd=-1, don't print anything. Plausible for use in
684 // regression testing suites that use client requests to count errors.
685 VG_(clo_log_fd) = tmp_log_fd;
jsgf855d93d2003-10-13 22:26:55 +0000686 }
687
sewardj45f4e7c2005-09-27 19:20:21 +0000688 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
689 (VG_(needs).core_errors || VG_(needs).tool_errors)) {
690 /* If we haven't reached the max number of suppressions, load
691 the default one. */
692 static const Char default_supp[] = "default.supp";
693 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
sewardj9c606bd2008-09-18 18:12:50 +0000694 Char *buf = VG_(arena_malloc)(VG_AR_CORE, "main.mpclo.2", len);
sewardj45f4e7c2005-09-27 19:20:21 +0000695 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
696 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
697 VG_(clo_n_suppressions)++;
698 }
sewardjde4a1d02002-03-22 01:27:54 +0000699
sewardj45f4e7c2005-09-27 19:20:21 +0000700 return (log_to == VgLogTo_Fd);
701}
702
sewardj4efbaa72008-06-04 06:51:58 +0000703// Write the name and value of log file qualifiers to the xml file.
704static void print_file_vars(Char* format)
705{
706 Int i = 0;
707
708 while (format[i]) {
709 if (format[i] == '%') {
710 // We saw a '%'. What's next...
711 i++;
712 if ('q' == format[i]) {
713 i++;
714 if ('{' == format[i]) {
715 // Get the env var name, print its contents.
716 Char* qualname;
717 Char* qual;
718 i++;
719 qualname = &format[i];
720 while (True) {
721 if ('}' == format[i]) {
722 // Temporarily replace the '}' with NUL to extract var
723 // name.
724 format[i] = 0;
725 qual = VG_(getenv)(qualname);
726 break;
727 }
728 i++;
729 }
730
barta0b6b2c2008-07-07 06:49:24 +0000731 VG_(message_no_f_c)(Vg_UserMsg,
732 "<logfilequalifier> <var>%t</var> "
733 "<value>%t</value> </logfilequalifier>",
734 qualname,qual);
sewardj4efbaa72008-06-04 06:51:58 +0000735 format[i] = '}';
736 i++;
737 }
738 }
739 } else {
740 i++;
741 }
742 }
743}
744
sewardj45f4e7c2005-09-27 19:20:21 +0000745
746/*====================================================================*/
747/*=== Printing the preamble ===*/
748/*====================================================================*/
749
750/* Ok, the logging sink is running now. Print a suitable preamble.
751 If logging to file or a socket, write details of parent PID and
752 command line args, to help people trying to interpret the
753 results of a run which encompasses multiple processes. */
754static void print_preamble(Bool logging_to_fd, const char* toolname)
755{
tom60a4b0b2005-10-12 10:45:27 +0000756 HChar* xpre = VG_(clo_xml) ? " <line>" : "";
757 HChar* xpost = VG_(clo_xml) ? "</line>" : "";
758 Int i;
759
sewardj14c7cc52007-02-25 15:08:24 +0000760 vg_assert( VG_(args_for_client) );
761 vg_assert( VG_(args_for_valgrind) );
sewardj99a2ceb2007-11-09 12:30:36 +0000762 vg_assert( toolname );
sewardj14c7cc52007-02-25 15:08:24 +0000763
sewardj71bc3cb2005-05-19 00:25:45 +0000764 if (VG_(clo_xml)) {
sewardj8665d8e2005-06-01 17:35:23 +0000765 VG_(message)(Vg_UserMsg, "<?xml version=\"1.0\"?>");
766 VG_(message)(Vg_UserMsg, "");
sewardj71bc3cb2005-05-19 00:25:45 +0000767 VG_(message)(Vg_UserMsg, "<valgrindoutput>");
768 VG_(message)(Vg_UserMsg, "");
sewardj7cf4e6b2008-05-01 20:24:26 +0000769 VG_(message)(Vg_UserMsg, "<protocolversion>3</protocolversion>");
sewardj71bc3cb2005-05-19 00:25:45 +0000770 VG_(message)(Vg_UserMsg, "");
771 }
772
sewardj83adf412002-05-01 01:25:45 +0000773 if (VG_(clo_verbosity > 0)) {
sewardjd7bddad2005-06-13 16:48:32 +0000774
775 if (VG_(clo_xml))
776 VG_(message)(Vg_UserMsg, "<preamble>");
777
nethercote996901a2004-08-03 13:29:09 +0000778 /* Tool details */
sewardj71bc3cb2005-05-19 00:25:45 +0000779 VG_(message)(Vg_UserMsg, "%s%s%s%s, %s.%s",
780 xpre,
njnd04b7c62002-10-03 14:05:52 +0000781 VG_(details).name,
njnb9c427c2004-12-01 14:14:42 +0000782 NULL == VG_(details).version ? "" : "-",
njnd04b7c62002-10-03 14:05:52 +0000783 NULL == VG_(details).version
784 ? (Char*)"" : VG_(details).version,
sewardj71bc3cb2005-05-19 00:25:45 +0000785 VG_(details).description,
786 xpost);
sewardj99a2ceb2007-11-09 12:30:36 +0000787
788 if (VG_(strlen)(toolname) >= 4
789 && 0 == VG_(strncmp)(toolname, "exp-", 4)) {
790 VG_(message)(
791 Vg_UserMsg,
792 "%sNOTE: This is an Experimental-Class Valgrind Tool.%s",
793 xpre, xpost
794 );
795 }
796
sewardj71bc3cb2005-05-19 00:25:45 +0000797 VG_(message)(Vg_UserMsg, "%s%s%s",
798 xpre, VG_(details).copyright_author, xpost);
sewardj3b2736a2002-03-24 12:18:35 +0000799
njnd04b7c62002-10-03 14:05:52 +0000800 /* Core details */
801 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000802 "%sUsing LibVEX rev %s, a library for dynamic binary translation.%s",
803 xpre, LibVEX_Version(), xpost );
sewardjc7025332004-12-13 18:30:39 +0000804 VG_(message)(Vg_UserMsg,
njn9f207462009-03-10 22:02:09 +0000805 "%sCopyright (C) 2004-2009, and GNU GPL'd, by OpenWorks LLP.%s",
sewardj71bc3cb2005-05-19 00:25:45 +0000806 xpre, xpost );
sewardjc7025332004-12-13 18:30:39 +0000807 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000808 "%sUsing valgrind-%s, a dynamic binary instrumentation framework.%s",
809 xpre, VERSION, xpost);
sewardjde4a1d02002-03-22 01:27:54 +0000810 VG_(message)(Vg_UserMsg,
njn9f207462009-03-10 22:02:09 +0000811 "%sCopyright (C) 2000-2009, and GNU GPL'd, by Julian Seward et al.%s",
sewardj71bc3cb2005-05-19 00:25:45 +0000812 xpre, xpost );
sewardjd7bddad2005-06-13 16:48:32 +0000813
sewardj45f4e7c2005-09-27 19:20:21 +0000814 if (VG_(clo_verbosity) == 1 && !VG_(clo_xml))
815 VG_(message)(Vg_UserMsg, "For more details, rerun with: -v");
816
sewardjd7bddad2005-06-13 16:48:32 +0000817 if (VG_(clo_xml))
818 VG_(message)(Vg_UserMsg, "</preamble>");
njnd04b7c62002-10-03 14:05:52 +0000819 }
820
sewardj45f4e7c2005-09-27 19:20:21 +0000821 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
sewardj4cf05692002-10-27 20:28:29 +0000822 VG_(message)(Vg_UserMsg, "");
823 VG_(message)(Vg_UserMsg,
824 "My PID = %d, parent PID = %d. Prog and args are:",
825 VG_(getpid)(), VG_(getppid)() );
sewardj5e940782005-09-28 19:59:19 +0000826 if (VG_(args_the_exename))
827 VG_(message)(Vg_UserMsg, " %s", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000828 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
829 VG_(message)(Vg_UserMsg,
830 " %s",
831 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
sewardj4cf05692002-10-27 20:28:29 +0000832 }
sewardj71bc3cb2005-05-19 00:25:45 +0000833 else
834 if (VG_(clo_xml)) {
835 VG_(message)(Vg_UserMsg, "");
836 VG_(message)(Vg_UserMsg, "<pid>%d</pid>", VG_(getpid)());
837 VG_(message)(Vg_UserMsg, "<ppid>%d</ppid>", VG_(getppid)());
barta0b6b2c2008-07-07 06:49:24 +0000838 VG_(message_no_f_c)(Vg_UserMsg, "<tool>%t</tool>", toolname);
sewardjc191a042008-06-04 09:07:36 +0000839 if (VG_(clo_log_name))
840 print_file_vars(VG_(clo_log_name));
sewardj768db0e2005-07-19 14:18:56 +0000841 if (VG_(clo_xml_user_comment)) {
842 /* Note: the user comment itself is XML and is therefore to
843 be passed through verbatim (%s) rather than escaped
844 (%t). */
845 VG_(message)(Vg_UserMsg, "<usercomment>%s</usercomment>",
846 VG_(clo_xml_user_comment));
847 }
sewardj71bc3cb2005-05-19 00:25:45 +0000848 VG_(message)(Vg_UserMsg, "");
sewardjb8a3dac2005-07-19 12:39:11 +0000849 VG_(message)(Vg_UserMsg, "<args>");
sewardj45f4e7c2005-09-27 19:20:21 +0000850
sewardjb8a3dac2005-07-19 12:39:11 +0000851 VG_(message)(Vg_UserMsg, " <vargv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000852 if (VG_(name_of_launcher))
barta0b6b2c2008-07-07 06:49:24 +0000853 VG_(message_no_f_c)(Vg_UserMsg, " <exe>%t</exe>",
854 VG_(name_of_launcher));
sewardj125fd4f2007-03-08 19:56:14 +0000855 else
barta0b6b2c2008-07-07 06:49:24 +0000856 VG_(message_no_f_c)(Vg_UserMsg, " <exe>%t</exe>",
857 "(launcher name unknown)");
sewardj14c7cc52007-02-25 15:08:24 +0000858 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
barta0b6b2c2008-07-07 06:49:24 +0000859 VG_(message_no_f_c)(Vg_UserMsg,
860 " <arg>%t</arg>",
861 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjb8a3dac2005-07-19 12:39:11 +0000862 }
863 VG_(message)(Vg_UserMsg, " </vargv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000864
sewardjb8a3dac2005-07-19 12:39:11 +0000865 VG_(message)(Vg_UserMsg, " <argv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000866 if (VG_(args_the_exename))
barta0b6b2c2008-07-07 06:49:24 +0000867 VG_(message_no_f_c)(Vg_UserMsg, " <exe>%t</exe>",
868 VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000869 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
barta0b6b2c2008-07-07 06:49:24 +0000870 VG_(message_no_f_c)(Vg_UserMsg,
871 " <arg>%t</arg>",
872 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
sewardj8665d8e2005-06-01 17:35:23 +0000873 }
sewardjb8a3dac2005-07-19 12:39:11 +0000874 VG_(message)(Vg_UserMsg, " </argv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000875
sewardjb8a3dac2005-07-19 12:39:11 +0000876 VG_(message)(Vg_UserMsg, "</args>");
sewardj71bc3cb2005-05-19 00:25:45 +0000877 }
sewardj4cf05692002-10-27 20:28:29 +0000878
sewardj45f4e7c2005-09-27 19:20:21 +0000879 // Empty line after the preamble
880 if (VG_(clo_verbosity) > 0)
881 VG_(message)(Vg_UserMsg, "");
882
sewardjde4a1d02002-03-22 01:27:54 +0000883 if (VG_(clo_verbosity) > 1) {
sewardj92645592005-07-23 09:18:34 +0000884 SysRes fd;
sewardj1f0bbc72005-11-16 03:51:02 +0000885 VexArch vex_arch;
886 VexArchInfo vex_archinfo;
sewardj45f4e7c2005-09-27 19:20:21 +0000887 if (!logging_to_fd)
njn1fd5eb22005-03-13 05:43:23 +0000888 VG_(message)(Vg_DebugMsg, "");
njn1fd5eb22005-03-13 05:43:23 +0000889 VG_(message)(Vg_DebugMsg, "Command line");
sewardj45f4e7c2005-09-27 19:20:21 +0000890 if (VG_(args_the_exename))
891 VG_(message)(Vg_DebugMsg, " %s", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000892 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
893 VG_(message)(Vg_DebugMsg,
894 " %s",
895 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
njn86dc2bc2003-09-09 07:26:21 +0000896
njn1fd5eb22005-03-13 05:43:23 +0000897 VG_(message)(Vg_DebugMsg, "Startup, with flags:");
sewardj14c7cc52007-02-25 15:08:24 +0000898 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
899 VG_(message)(Vg_DebugMsg,
900 " %s",
901 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjde4a1d02002-03-22 01:27:54 +0000902 }
nethercotea70f7352004-04-18 12:08:46 +0000903
njn1fd5eb22005-03-13 05:43:23 +0000904 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:");
nethercotea70f7352004-04-18 12:08:46 +0000905 fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
njncda2f0f2009-05-18 02:12:08 +0000906 if (sr_isError(fd)) {
njn1fd5eb22005-03-13 05:43:23 +0000907 VG_(message)(Vg_DebugMsg, " can't open /proc/version");
nethercotea70f7352004-04-18 12:08:46 +0000908 } else {
sewardj71bc3cb2005-05-19 00:25:45 +0000909# define BUF_LEN 256
nethercotea70f7352004-04-18 12:08:46 +0000910 Char version_buf[BUF_LEN];
njncda2f0f2009-05-18 02:12:08 +0000911 Int n = VG_(read) ( sr_Res(fd), version_buf, BUF_LEN );
njnbe9b47b2005-05-15 16:22:58 +0000912 vg_assert(n <= BUF_LEN);
nethercotea70f7352004-04-18 12:08:46 +0000913 if (n > 0) {
914 version_buf[n-1] = '\0';
njn1fd5eb22005-03-13 05:43:23 +0000915 VG_(message)(Vg_DebugMsg, " %s", version_buf);
nethercotea70f7352004-04-18 12:08:46 +0000916 } else {
njn1fd5eb22005-03-13 05:43:23 +0000917 VG_(message)(Vg_DebugMsg, " (empty?)");
nethercotea70f7352004-04-18 12:08:46 +0000918 }
njncda2f0f2009-05-18 02:12:08 +0000919 VG_(close)(sr_Res(fd));
sewardj71bc3cb2005-05-19 00:25:45 +0000920# undef BUF_LEN
nethercotea70f7352004-04-18 12:08:46 +0000921 }
sewardj1f0bbc72005-11-16 03:51:02 +0000922
923 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +0000924 VG_(message)(
925 Vg_DebugMsg,
926 "Arch and hwcaps: %s, %s",
927 LibVEX_ppVexArch ( vex_arch ),
928 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
929 );
sewardje66f2e02006-12-30 17:45:08 +0000930 VG_(message)(
931 Vg_DebugMsg,
sewardj07854682006-12-30 17:56:32 +0000932 "Page sizes: currently %d, max supported %d",
sewardje66f2e02006-12-30 17:45:08 +0000933 (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
934 );
sewardj1f0bbc72005-11-16 03:51:02 +0000935 VG_(message)(Vg_DebugMsg, "Valgrind library directory: %s", VG_(libdir));
sewardjde4a1d02002-03-22 01:27:54 +0000936 }
nethercotef6a1d502004-08-09 12:21:57 +0000937}
938
sewardjde4a1d02002-03-22 01:27:54 +0000939
nethercote71980f02004-01-24 18:18:54 +0000940/*====================================================================*/
941/*=== File descriptor setup ===*/
942/*====================================================================*/
943
sewardj5f229e22005-09-28 01:36:01 +0000944/* Number of file descriptors that Valgrind tries to reserve for
945 it's own use - just a small constant. */
946#define N_RESERVED_FDS (10)
947
nethercote71980f02004-01-24 18:18:54 +0000948static void setup_file_descriptors(void)
949{
950 struct vki_rlimit rl;
sewardj17c11042006-10-15 01:26:40 +0000951 Bool show = False;
nethercote71980f02004-01-24 18:18:54 +0000952
953 /* Get the current file descriptor limits. */
954 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
955 rl.rlim_cur = 1024;
956 rl.rlim_max = 1024;
957 }
958
sewardj17c11042006-10-15 01:26:40 +0000959 if (show)
njn8a7b41b2007-09-23 00:51:24 +0000960 VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +0000961 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +0000962
963# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
964 /* I don't know why this kludge is needed; however if rl.rlim_cur
965 is RLIM_INFINITY, then VG_(safe_fd)'s attempts using VG_(fcntl)
966 to lift V's file descriptors above the threshold RLIM_INFINITY -
967 N_RESERVED_FDS fail. So just use a relatively conservative
968 value in this case. */
969 if (rl.rlim_cur > 1024)
970 rl.rlim_cur = 1024;
971# endif
972
nethercote71980f02004-01-24 18:18:54 +0000973 /* Work out where to move the soft limit to. */
njn14319cc2005-03-13 06:26:22 +0000974 if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
975 rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +0000976 } else {
977 rl.rlim_cur = rl.rlim_max;
978 }
979
980 /* Reserve some file descriptors for our use. */
njn14319cc2005-03-13 06:26:22 +0000981 VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
982 VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +0000983
984 /* Update the soft limit. */
985 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
986
sewardj17c11042006-10-15 01:26:40 +0000987 if (show) {
njn8a7b41b2007-09-23 00:51:24 +0000988 VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +0000989 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +0000990 VG_(printf)("fd limits: guest : cur %u max %u\n",
991 VG_(fd_soft_limit), VG_(fd_hard_limit));
992 }
993
sewardj45f4e7c2005-09-27 19:20:21 +0000994 if (VG_(cl_exec_fd) != -1)
995 VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
nethercote71980f02004-01-24 18:18:54 +0000996}
997
sewardjde4a1d02002-03-22 01:27:54 +0000998
njn2da73352005-06-18 01:35:16 +0000999/*====================================================================*/
njn2025cf92005-06-26 20:44:48 +00001000/*=== BB profiling ===*/
1001/*====================================================================*/
1002
1003static
1004void show_BB_profile ( BBProfEntry tops[], UInt n_tops, ULong score_total )
1005{
1006 ULong score_cumul, score_here;
1007 Char buf_cumul[10], buf_here[10];
1008 Char name[64];
1009 Int r;
1010
1011 VG_(printf)("\n");
1012 VG_(printf)("-----------------------------------------------------------\n");
1013 VG_(printf)("--- BEGIN BB Profile (summary of scores) ---\n");
1014 VG_(printf)("-----------------------------------------------------------\n");
1015 VG_(printf)("\n");
1016
1017 VG_(printf)("Total score = %lld\n\n", score_total);
1018
1019 score_cumul = 0;
1020 for (r = 0; r < n_tops; r++) {
1021 if (tops[r].addr == 0)
1022 continue;
1023 name[0] = 0;
1024 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1025 name[63] = 0;
1026 score_here = tops[r].score;
1027 score_cumul += score_here;
1028 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1029 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1030 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1031 r,
1032 score_cumul, buf_cumul,
1033 score_here, buf_here, tops[r].addr, name );
1034 }
1035
1036 VG_(printf)("\n");
1037 VG_(printf)("-----------------------------------------------------------\n");
1038 VG_(printf)("--- BB Profile (BB details) ---\n");
1039 VG_(printf)("-----------------------------------------------------------\n");
1040 VG_(printf)("\n");
1041
1042 score_cumul = 0;
1043 for (r = 0; r < n_tops; r++) {
1044 if (tops[r].addr == 0)
1045 continue;
1046 name[0] = 0;
1047 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1048 name[63] = 0;
1049 score_here = tops[r].score;
1050 score_cumul += score_here;
1051 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1052 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1053 VG_(printf)("\n");
1054 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin BB rank %d "
1055 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1056 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1057 r,
1058 score_cumul, buf_cumul,
1059 score_here, buf_here, tops[r].addr, name );
1060 VG_(printf)("\n");
sewardjbcccbc02007-04-09 22:24:57 +00001061 VG_(discard_translations)(tops[r].addr, 1, "bb profile");
sewardj0ec07f32006-01-12 12:32:32 +00001062 VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0, True);
njn2025cf92005-06-26 20:44:48 +00001063 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= end BB rank %d "
1064 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1065 }
1066
1067 VG_(printf)("\n");
1068 VG_(printf)("-----------------------------------------------------------\n");
1069 VG_(printf)("--- END BB Profile ---\n");
1070 VG_(printf)("-----------------------------------------------------------\n");
1071 VG_(printf)("\n");
1072}
1073
1074
1075/*====================================================================*/
nethercote71980f02004-01-24 18:18:54 +00001076/*=== main() ===*/
1077/*====================================================================*/
1078
sewardjfdf91b42005-09-28 00:53:09 +00001079/* When main() is entered, we should be on the following stack, not
1080 the one the kernel gave us. We will run on this stack until
1081 simulation of the root thread is started, at which point a transfer
1082 is made to a dynamically allocated stack. This is for the sake of
1083 uniform overflow detection for all Valgrind threads. This is
1084 marked global even though it isn't, because assembly code below
1085 needs to reference the name. */
1086
1087/*static*/ VgStack VG_(interim_stack);
1088
sewardjf9d2f9b2006-11-17 20:00:57 +00001089/* These are the structures used to hold info for creating the initial
1090 client image.
1091
1092 'iicii' mostly holds important register state present at system
1093 startup (_start_valgrind). valgrind_main() then fills in the rest
1094 of it and passes it to VG_(ii_create_image)(). That produces
1095 'iifii', which is later handed to VG_(ii_finalise_image). */
1096
1097/* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1098 This should get some address inside the stack on which we gained
sewardjfdf91b42005-09-28 00:53:09 +00001099 control (eg, it could be the SP at startup). It doesn't matter
1100 exactly where in the stack it is. This value is passed to the
sewardjf9d2f9b2006-11-17 20:00:57 +00001101 address space manager at startup. On Linux, aspacem then uses it
1102 to identify the initial stack segment and hence the upper end of
1103 the usable address space. */
sewardjfdf91b42005-09-28 00:53:09 +00001104
sewardjf9d2f9b2006-11-17 20:00:57 +00001105static IICreateImageInfo the_iicii;
1106static IIFinaliseImageInfo the_iifii;
1107
sewardjfdf91b42005-09-28 00:53:09 +00001108
sewardj9c606bd2008-09-18 18:12:50 +00001109/* A simple pair structure, used for conveying debuginfo handles to
1110 calls to VG_TRACK(new_mem_startup, ...). */
1111typedef struct { Addr a; ULong ull; } Addr_n_ULong;
1112
1113
sewardj1ae3f3a2005-09-28 10:47:38 +00001114/* --- Forwards decls to do with shutdown --- */
1115
1116static void final_tidyup(ThreadId tid);
1117
1118/* Do everything which needs doing when the last thread exits */
1119static
1120void shutdown_actions_NORETURN( ThreadId tid,
1121 VgSchedReturnCode tids_schedretcode );
1122
1123/* --- end of Forwards decls to do with shutdown --- */
sewardjfdf91b42005-09-28 00:53:09 +00001124
1125
sewardjf9d2f9b2006-11-17 20:00:57 +00001126/* By the time we get to valgrind_main, the_iicii should already have
1127 been filled in with any important details as required by whatever
1128 OS we have been built for.
1129*/
sewardj17c11042006-10-15 01:26:40 +00001130static
sewardjf9d2f9b2006-11-17 20:00:57 +00001131Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
nethercote71980f02004-01-24 18:18:54 +00001132{
sewardj13247ca2005-12-30 22:52:20 +00001133 HChar* toolname = "memcheck"; // default to Memcheck
sewardj13247ca2005-12-30 22:52:20 +00001134 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
sewardjde764e82007-11-09 23:13:22 +00001135 ThreadId tid_main = VG_INVALID_THREADID;
sewardj45f4e7c2005-09-27 19:20:21 +00001136 Int loglevel, i;
1137 Bool logging_to_fd;
nethercote73b526f2004-10-31 18:48:21 +00001138 struct vki_rlimit zero = { 0, 0 };
sewardj9c606bd2008-09-18 18:12:50 +00001139 XArray* addr2dihandle = NULL;
sewardj17c11042006-10-15 01:26:40 +00001140
nethercote71980f02004-01-24 18:18:54 +00001141 //============================================================
nethercote71980f02004-01-24 18:18:54 +00001142 //
sewardj45f4e7c2005-09-27 19:20:21 +00001143 // Nb: startup is complex. Prerequisites are shown at every step.
nethercote71980f02004-01-24 18:18:54 +00001144 // *** Be very careful when messing with the order ***
sewardj45f4e7c2005-09-27 19:20:21 +00001145 //
1146 // The first order of business is to get debug logging, the address
1147 // space manager and the dynamic memory manager up and running.
1148 // Once that's done, we can relax a bit.
1149 //
nethercote71980f02004-01-24 18:18:54 +00001150 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001151
1152 /* This is needed to make VG_(getenv) usable early. */
1153 VG_(client_envp) = (Char**)envp;
nethercote71980f02004-01-24 18:18:54 +00001154
sewardj1cf558c2005-04-25 01:36:56 +00001155 //--------------------------------------------------------------
1156 // Start up the logging mechanism
1157 // p: none
1158 //--------------------------------------------------------------
1159 /* Start the debugging-log system ASAP. First find out how many
njn83df0b62009-02-25 01:01:05 +00001160 "-d"s were specified. This is a pre-scan of the command line. Also
1161 get --profile-heap=yes which is needed by the time we start up dynamic
1162 memory management. */
sewardj1cf558c2005-04-25 01:36:56 +00001163 loglevel = 0;
1164 for (i = 1; i < argc; i++) {
njn83df0b62009-02-25 01:01:05 +00001165 if (argv[i][0] != '-') break;
1166 if VG_STREQ(argv[i], "--") break;
1167 if VG_STREQ(argv[i], "-d") loglevel++;
1168 if VG_BOOL_CLO(argv[i], "--profile-heap", VG_(clo_profile_heap)) {}
sewardj1cf558c2005-04-25 01:36:56 +00001169 }
1170
1171 /* ... and start the debug logger. Now we can safely emit logging
1172 messages all through startup. */
sewardj10759312005-05-30 23:52:47 +00001173 VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
sewardj45f4e7c2005-09-27 19:20:21 +00001174 VG_(debugLog)(1, "main", "Welcome to Valgrind version "
1175 VERSION " debug logging\n");
1176
1177 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001178 // AIX5 only: register the system call numbers
1179 // p: logging
1180 // p: that the initial few syscall numbers stated in the
1181 // bootblock have been installed (else we can't
1182 // open/read/close).
1183 //--------------------------------------------------------------
1184# if defined(VGO_aix5)
1185 VG_(debugLog)(1, "main", "aix5: registering syscalls ..\n");
1186 { UChar sysent_name[50];
1187 SysRes fd;
1188 Bool ok;
1189 Int n_unregd, sysent_used = 0;
1190 prsysent_t* sysent_hdr;
1191
1192 VG_(sprintf)(sysent_name, "/proc/%d/sysent", VG_(getpid)());
1193 fd = VG_(open)(sysent_name, VKI_O_RDONLY, 0);
1194 if (fd.isError)
1195 VG_(err_config_error)("aix5: can't open /proc/<pid>/sysent");
1196
1197 sysent_used = VG_(read)(fd.res, aix5_sysent_buf, VG_AIX5_SYSENT_SIZE);
1198 if (sysent_used < 0)
1199 VG_(err_config_error)("aix5: error reading /proc/<pid>/sysent");
1200 if (sysent_used >= VG_AIX5_SYSENT_SIZE)
1201 VG_(err_config_error)("aix5: VG_AIX5_SYSENT_SIZE is too low; "
1202 "increase and recompile");
1203 VG_(close)(fd.res);
1204
1205 vg_assert(sysent_used > 0 && sysent_used < VG_AIX5_SYSENT_SIZE);
1206
1207 sysent_hdr = (prsysent_t*)&aix5_sysent_buf[0];
1208
1209 n_unregd = 0;
1210 for (i = 0; i < sysent_hdr->pr_nsyscalls; i++) {
1211 UChar* name = &aix5_sysent_buf[ sysent_hdr
1212 ->pr_syscall[i].pr_nameoff ];
1213 UInt nmbr = sysent_hdr->pr_syscall[i].pr_number;
1214 VG_(debugLog)(3, "main", "aix5: bind syscall %d to \"%s\"\n",
1215 nmbr, name);
1216 ok = VG_(aix5_register_syscall)(nmbr, name);
1217 if (!ok)
1218 n_unregd++;
1219 if (!ok)
1220 VG_(debugLog)(3, "main",
1221 "aix5: bind FAILED: %d to \"%s\"\n",
1222 nmbr, name);
1223 }
1224 VG_(debugLog)(1, "main", "aix5: .. %d syscalls known, %d unknown\n",
1225 sysent_hdr->pr_nsyscalls - n_unregd, n_unregd );
1226 VG_(debugLog)(1, "main", "aix5: __NR_AIX5_FAKE_SIGRETURN = %d\n",
1227 __NR_AIX5_FAKE_SIGRETURN );
1228 }
1229# endif
1230
1231 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001232 // Ensure we're on a plausible stack.
1233 // p: logging
1234 //--------------------------------------------------------------
1235 VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
sewardjfdf91b42005-09-28 00:53:09 +00001236 { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
1237 HChar* limHi = limLo + sizeof(VG_(interim_stack));
sewardj45f4e7c2005-09-27 19:20:21 +00001238 HChar* aLocal = (HChar*)&zero; /* any auto local will do */
1239 if (aLocal < limLo || aLocal >= limHi) {
1240 /* something's wrong. Stop. */
1241 VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
1242 limLo, limHi, aLocal );
1243 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1244 "Initial stack switched failed.\n");
1245 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1246 VG_(exit)(1);
1247 }
1248 }
1249
1250 //--------------------------------------------------------------
1251 // Ensure we have a plausible pointer to the stack on which
1252 // we gained control (not the current stack!)
1253 // p: logging
1254 //--------------------------------------------------------------
1255 VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
sewardjf9d2f9b2006-11-17 20:00:57 +00001256 if (the_iicii.sp_at_startup == 0) {
sewardj45f4e7c2005-09-27 19:20:21 +00001257 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1258 "Initial stack was not noted.\n");
1259 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1260 VG_(exit)(1);
1261 }
1262
1263 //--------------------------------------------------------------
1264 // Start up the address space manager, and determine the
1265 // approximate location of the client's stack
1266 // p: logging, plausible-stack
1267 //--------------------------------------------------------------
1268 VG_(debugLog)(1, "main", "Starting the address space manager\n");
sewardje66f2e02006-12-30 17:45:08 +00001269 vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536);
1270 vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536);
1271 vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
1272 vg_assert(VKI_PAGE_SIZE == (1 << VKI_PAGE_SHIFT));
1273 vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
sewardjf9d2f9b2006-11-17 20:00:57 +00001274 the_iicii.clstack_top = VG_(am_startup)( the_iicii.sp_at_startup );
sewardj45f4e7c2005-09-27 19:20:21 +00001275 VG_(debugLog)(1, "main", "Address space manager is running\n");
1276
1277 //--------------------------------------------------------------
1278 // Start up the dynamic memory manager
1279 // p: address space management
njn83df0b62009-02-25 01:01:05 +00001280 // p: getting --profile-heap
sewardj45f4e7c2005-09-27 19:20:21 +00001281 // In fact m_mallocfree is self-initialising, so there's no
1282 // initialisation call to do. Instead, try a simple malloc/
1283 // free pair right now to check that nothing is broken.
1284 //--------------------------------------------------------------
1285 VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
sewardj9c606bd2008-09-18 18:12:50 +00001286 { void* p = VG_(malloc)( "main.vm.1", 12345 );
sewardj45f4e7c2005-09-27 19:20:21 +00001287 if (p) VG_(free)( p );
1288 }
1289 VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
sewardj1cf558c2005-04-25 01:36:56 +00001290
nethercotef4928da2004-06-15 10:54:40 +00001291 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001292 //
1293 // Dynamic memory management is now available.
1294 //
nethercotef4928da2004-06-15 10:54:40 +00001295 //============================================================
1296
sewardj45f4e7c2005-09-27 19:20:21 +00001297 //--------------------------------------------------------------
sewardjf98e1c02008-10-25 16:22:41 +00001298 // Initialise m_debuginfo
1299 // p: dynamic memory allocation
1300 VG_(debugLog)(1, "main", "Initialise m_debuginfo\n");
1301 VG_(di_initialise)();
1302
1303 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001304 // Look for alternative libdir
1305 { HChar *cp = VG_(getenv)(VALGRIND_LIB);
1306 if (cp != NULL)
1307 VG_(libdir) = cp;
1308 }
1309
1310 //--------------------------------------------------------------
1311 // Extract the launcher name from the environment.
njna842d792009-05-21 01:15:18 +00001312 VG_(debugLog)(1, "main", "Getting launcher's name ...\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001313 VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
1314 if (VG_(name_of_launcher) == NULL) {
1315 VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
1316 VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
1317 VG_(exit)(1);
1318 }
njna842d792009-05-21 01:15:18 +00001319 VG_(debugLog)(1, "main", "... %s\n", VG_(name_of_launcher));
sewardj45f4e7c2005-09-27 19:20:21 +00001320
1321 //--------------------------------------------------------------
fitzhardingeb50068f2004-02-24 23:42:55 +00001322 // Get the current process datasize rlimit, and set it to zero.
1323 // This prevents any internal uses of brk() from having any effect.
1324 // We remember the old value so we can restore it on exec, so that
1325 // child processes will have a reasonable brk value.
1326 VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1327 zero.rlim_max = VG_(client_rlimit_data).rlim_max;
1328 VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
thughesc37184f2004-09-11 14:16:57 +00001329
1330 // Get the current process stack rlimit.
1331 VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
1332
sewardje2d1e672005-11-12 23:10:48 +00001333 //--------------------------------------------------------------
1334 // Figure out what sort of CPU we're on, and whether it is
1335 // able to run V.
1336 VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
1337 { VexArch vex_arch;
1338 VexArchInfo vex_archinfo;
1339 Bool ok = VG_(machine_get_hwcaps)();
1340 if (!ok) {
1341 VG_(printf)("\n");
1342 VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
1343 VG_(printf)(" Supported CPUs are:\n");
1344 VG_(printf)(" * x86 (practically any; Pentium-I or above), "
1345 "AMD Athlon or above)\n");
1346 VG_(printf)(" * AMD Athlon64/Opteron\n");
1347 VG_(printf)(" * PowerPC (most; ppc405 and above)\n");
1348 VG_(printf)("\n");
1349 VG_(exit)(1);
1350 }
1351 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001352 VG_(debugLog)(
1353 1, "main", "... arch = %s, hwcaps = %s\n",
1354 LibVEX_ppVexArch ( vex_arch ),
1355 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1356 );
sewardje2d1e672005-11-12 23:10:48 +00001357 }
1358
sewardj198f34f2007-07-09 23:13:07 +00001359 //--------------------------------------------------------------
1360 // Record the working directory at startup
1361 // p: none (Linux), getenv and sys_getpid work (AIX)
1362 VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
1363 { Bool ok = VG_(record_startup_wd)();
1364 if (!ok)
1365 VG_(err_config_error)( "Can't establish current working "
1366 "directory at startup");
1367 }
1368 { Char buf[VKI_PATH_MAX+1];
1369 Bool ok = VG_(get_startup_wd)( buf, sizeof(buf) );
1370 vg_assert(ok);
1371 buf[VKI_PATH_MAX] = 0;
1372 VG_(debugLog)(1, "main", "... %s\n", buf );
1373 }
1374
sewardj45f4e7c2005-09-27 19:20:21 +00001375 //============================================================
1376 // Command line argument handling order:
1377 // * If --help/--help-debug are present, show usage message
1378 // (including the tool-specific usage)
1379 // * (If no --tool option given, default to Memcheck)
1380 // * Then, if client is missing, abort with error msg
1381 // * Then, if any cmdline args are bad, abort with error msg
1382 //============================================================
1383
1384 //--------------------------------------------------------------
1385 // Split up argv into: C args, V args, V extra args, and exename.
1386 // p: dynamic memory allocation
1387 //--------------------------------------------------------------
1388 VG_(debugLog)(1, "main", "Split up command line\n");
1389 VG_(split_up_argv)( argc, argv );
sewardj14c7cc52007-02-25 15:08:24 +00001390 vg_assert( VG_(args_for_valgrind) );
1391 vg_assert( VG_(args_for_client) );
sewardj45f4e7c2005-09-27 19:20:21 +00001392 if (0) {
sewardj14c7cc52007-02-25 15:08:24 +00001393 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
1394 VG_(printf)(
1395 "varg %s\n",
1396 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1397 );
sewardj45f4e7c2005-09-27 19:20:21 +00001398 VG_(printf)(" exe %s\n", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001399 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
1400 VG_(printf)(
1401 "carg %s\n",
1402 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1403 );
nethercote71980f02004-01-24 18:18:54 +00001404 }
1405
sewardj948a6fc2007-03-19 18:38:55 +00001406# if defined(VGO_aix5)
1407 /* Tolerate ptraced-based launchers. They can't run 'no program'
1408 if the user types "valgrind --help", so they run a do-nothing
1409 program $prefix/bin/no_op_client_for_valgrind, and we catch that
1410 here and turn it the exe name back into NULL. Then --help,
1411 --version etc work as they should. */
1412 if (VG_(args_the_exename)
1413 && VG_(strstr)( VG_(args_the_exename), "/no_op_client_for_valgrind" )) {
1414 VG_(args_the_exename) = NULL;
1415 }
1416# endif
1417
nethercote71980f02004-01-24 18:18:54 +00001418 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001419 // Extract tool name and whether help has been requested.
1420 // Note we can't print the help message yet, even if requested,
1421 // because the tool has not been initialised.
1422 // p: split_up_argv [for VG_(args_for_valgrind)]
nethercote71980f02004-01-24 18:18:54 +00001423 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001424 VG_(debugLog)(1, "main",
1425 "(early_) Process Valgrind's command line options\n");
1426 early_process_cmd_line_options(&need_help, &toolname);
nethercote71980f02004-01-24 18:18:54 +00001427
sewardj45f4e7c2005-09-27 19:20:21 +00001428 // Set default vex control params
1429 LibVEX_default_VexControl(& VG_(clo_vex_control));
nethercote71980f02004-01-24 18:18:54 +00001430
1431 //--------------------------------------------------------------
1432 // Load client executable, finding in $PATH if necessary
njn83df0b62009-02-25 01:01:05 +00001433 // p: early_process_cmd_line_options() [for 'exec', 'need_help',
1434 // clo_max_stackframe,
1435 // clo_main_stacksize]
sewardj95d86c02007-12-18 01:49:23 +00001436 // p: layout_remaining_space [so there's space]
sewardj17c11042006-10-15 01:26:40 +00001437 //
nethercote71980f02004-01-24 18:18:54 +00001438 // Set up client's environment
sewardj95d86c02007-12-18 01:49:23 +00001439 // p: set-libdir [for VG_(libdir)]
1440 // p: early_process_cmd_line_options [for toolname]
sewardj17c11042006-10-15 01:26:40 +00001441 //
nethercote5ee67ca2004-06-22 14:00:09 +00001442 // Setup client stack, eip, and VG_(client_arg[cv])
nethercote71980f02004-01-24 18:18:54 +00001443 // p: load_client() [for 'info']
1444 // p: fix_environment() [for 'env']
sewardj17c11042006-10-15 01:26:40 +00001445 //
sewardj45f4e7c2005-09-27 19:20:21 +00001446 // Setup client data (brk) segment. Initially a 1-page segment
1447 // which abuts a shrinkable reservation.
1448 // p: load_client() [for 'info' and hence VG_(brk_base)]
sewardjf9d2f9b2006-11-17 20:00:57 +00001449 //
1450 // p: _start_in_C (for zeroing out the_iicii and putting some
1451 // initial values into it)
sewardj45f4e7c2005-09-27 19:20:21 +00001452 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001453 if (!need_help) {
sewardjf9d2f9b2006-11-17 20:00:57 +00001454 VG_(debugLog)(1, "main", "Create initial image\n");
1455
1456# if defined(VGO_linux)
1457 the_iicii.argv = argv;
1458 the_iicii.envp = envp;
1459 the_iicii.toolname = toolname;
1460# elif defined(VGO_aix5)
1461 /* the_iicii.intregs37 already set up */
1462 /* the_iicii.bootblock already set up */
1463 /* the_iicii.adler32_exp already set up */
1464 /* the_iicii.sp_at_startup is irrelevant */
1465 /* the_iicii.clstack_top is irrelevant */
1466 the_iicii.toolname = toolname;
1467# else
njna842d792009-05-21 01:15:18 +00001468# error "Unknown platform"
sewardjf9d2f9b2006-11-17 20:00:57 +00001469# endif
1470
sewardjdc2f79e2007-12-22 14:14:04 +00001471 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001472 the_iifii = VG_(ii_create_image)( the_iicii );
1473
sewardj17c11042006-10-15 01:26:40 +00001474# if defined(VGO_aix5)
sewardj17c11042006-10-15 01:26:40 +00001475 /* Tell aspacem where the initial client stack is, so that it
1476 can later produce a faked-up NSegment in response to
1477 VG_(am_find_nsegment) for that address range, if asked. */
sewardjdc2f79e2007-12-22 14:14:04 +00001478 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001479 VG_(am_aix5_set_initial_client_sp)( the_iifii.initial_client_SP );
1480 /* Now have a look at said fake segment, so we can find out
1481 the size of it. */
1482 { SizeT sz;
1483 NSegment const* seg
1484 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
1485 vg_assert(seg);
1486 sz = seg->end - seg->start + 1;
sewardjc9d33832007-12-22 14:12:42 +00001487 vg_assert(sz >= 0 && sz <= (256+1)*1024*1024); /* stay sane */
sewardjf9d2f9b2006-11-17 20:00:57 +00001488 the_iifii.clstack_max_size = sz;
1489 }
sewardj17c11042006-10-15 01:26:40 +00001490# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001491 }
nethercote71980f02004-01-24 18:18:54 +00001492
1493 //==============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001494 //
1495 // Finished loading/setting up the client address space.
1496 //
nethercote71980f02004-01-24 18:18:54 +00001497 //==============================================================
1498
1499 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001500 // setup file descriptors
1501 // p: n/a
1502 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001503 VG_(debugLog)(1, "main", "Setup file descriptors\n");
nethercote71980f02004-01-24 18:18:54 +00001504 setup_file_descriptors();
1505
1506 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001507 // create the fake /proc/<pid>/cmdline file and then unlink it,
1508 // but hold onto the fd, so we can hand it out to the client
1509 // when it tries to open /proc/<pid>/cmdline for itself.
1510 // p: setup file descriptors
nethercotec314eba2004-07-15 12:59:41 +00001511 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001512 if (!need_help) {
1513 HChar buf[50], buf2[50+64];
1514 HChar nul[1];
1515 Int fd, r;
1516 HChar* exename;
nethercotec314eba2004-07-15 12:59:41 +00001517
sewardj45f4e7c2005-09-27 19:20:21 +00001518 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
1519
1520 VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
1521 fd = VG_(mkstemp)( buf, buf2 );
1522 if (fd == -1)
sewardj17c11042006-10-15 01:26:40 +00001523 VG_(err_config_error)("Can't create client cmdline file in /tmp.");
sewardj45f4e7c2005-09-27 19:20:21 +00001524
1525 nul[0] = 0;
1526 exename = VG_(args_the_exename) ? VG_(args_the_exename)
1527 : "unknown_exename";
sewardj45f4e7c2005-09-27 19:20:21 +00001528 VG_(write)(fd, VG_(args_the_exename),
1529 VG_(strlen)( VG_(args_the_exename) ));
1530 VG_(write)(fd, nul, 1);
1531
sewardj14c7cc52007-02-25 15:08:24 +00001532 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1533 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
1534 VG_(write)(fd, arg, VG_(strlen)( arg ));
sewardj45f4e7c2005-09-27 19:20:21 +00001535 VG_(write)(fd, nul, 1);
1536 }
1537
1538 /* Don't bother to seek the file back to the start; instead do
1539 it every time a copy of it is given out (by PRE(sys_open)).
1540 That is probably more robust across fork() etc. */
1541
1542 /* Now delete it, but hang on to the fd. */
1543 r = VG_(unlink)( buf2 );
1544 if (r)
sewardj17c11042006-10-15 01:26:40 +00001545 VG_(err_config_error)("Can't delete client cmdline file in /tmp.");
sewardj45f4e7c2005-09-27 19:20:21 +00001546
1547 VG_(cl_cmdline_fd) = fd;
1548 }
nethercotec314eba2004-07-15 12:59:41 +00001549
1550 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001551 // Init tool part 1: pre_clo_init
nethercotec314eba2004-07-15 12:59:41 +00001552 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
nethercotec314eba2004-07-15 12:59:41 +00001553 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
nethercote71980f02004-01-24 18:18:54 +00001554 //--------------------------------------------------------------
sewardj7cf4e6b2008-05-01 20:24:26 +00001555 VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
njn08ce7b32009-02-27 03:38:28 +00001556 VG_(tl_pre_clo_init)();
nethercote71980f02004-01-24 18:18:54 +00001557
sewardj45f4e7c2005-09-27 19:20:21 +00001558 //--------------------------------------------------------------
nethercotef4928da2004-06-15 10:54:40 +00001559 // If --tool and --help/--help-debug was given, now give the core+tool
1560 // help message
sewardj95d86c02007-12-18 01:49:23 +00001561 // p: early_process_cmd_line_options() [for 'need_help']
1562 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
sewardj45f4e7c2005-09-27 19:20:21 +00001563 //--------------------------------------------------------------
1564 VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
nethercotef4928da2004-06-15 10:54:40 +00001565 if (need_help) {
sewardj45f4e7c2005-09-27 19:20:21 +00001566 usage_NORETURN(/*--help-debug?*/2 == need_help);
nethercotef4928da2004-06-15 10:54:40 +00001567 }
nethercotec314eba2004-07-15 12:59:41 +00001568
sewardj45f4e7c2005-09-27 19:20:21 +00001569 //--------------------------------------------------------------
1570 // Process command line options to Valgrind + tool
1571 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1572 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1573 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001574 VG_(debugLog)(1, "main",
1575 "(main_) Process Valgrind's command line options, "
1576 "setup logging\n");
njn1dcee092009-02-24 03:07:37 +00001577 logging_to_fd = main_process_cmd_line_options(toolname);
sewardj45f4e7c2005-09-27 19:20:21 +00001578
1579 //--------------------------------------------------------------
sewardj592ae092005-11-08 19:01:44 +00001580 // Zeroise the millisecond counter by doing a first read of it.
1581 // p: none
1582 //--------------------------------------------------------------
1583 (void) VG_(read_millisecond_timer)();
1584
1585 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001586 // Print the preamble
1587 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
sewardj95d86c02007-12-18 01:49:23 +00001588 // p: main_process_cmd_line_options() [for VG_(clo_verbosity),
1589 // VG_(clo_xml),
1590 // logging_to_fd]
sewardj45f4e7c2005-09-27 19:20:21 +00001591 //--------------------------------------------------------------
1592 VG_(debugLog)(1, "main", "Print the preamble...\n");
1593 print_preamble(logging_to_fd, toolname);
1594 VG_(debugLog)(1, "main", "...finished the preamble\n");
1595
1596 //--------------------------------------------------------------
1597 // Init tool part 2: post_clo_init
1598 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1599 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1600 // p: print_preamble() [so any warnings printed in post_clo_init
1601 // are shown after the preamble]
1602 //--------------------------------------------------------------
1603 VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
njn51d827b2005-05-09 01:02:08 +00001604 VG_TDICT_CALL(tool_post_clo_init);
sewardj7cf4e6b2008-05-01 20:24:26 +00001605 {
1606 /* The tool's "needs" will by now be finalised, since it has no
1607 further opportunity to specify them. So now sanity check
1608 them. */
1609 Char* s;
1610 Bool ok;
1611 ok = VG_(sanity_check_needs)( &s );
1612 if (!ok) {
1613 VG_(tool_panic)(s);
1614 }
1615 }
nethercotef4928da2004-06-15 10:54:40 +00001616
1617 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001618 // Initialise translation table and translation cache
1619 // p: aspacem [??]
1620 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
nethercote71980f02004-01-24 18:18:54 +00001621 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001622 VG_(debugLog)(1, "main", "Initialise TT/TC\n");
1623 VG_(init_tt_tc)();
sewardjb5f6f512005-03-10 23:59:00 +00001624
sewardj45f4e7c2005-09-27 19:20:21 +00001625 //--------------------------------------------------------------
1626 // Initialise the redirect table.
1627 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
1628 // p: aspacem [so can change ownership of sysinfo pages]
1629 //--------------------------------------------------------------
1630 VG_(debugLog)(1, "main", "Initialise redirects\n");
sewardj0ec07f32006-01-12 12:32:32 +00001631 VG_(redir_initialise)();
nethercote71980f02004-01-24 18:18:54 +00001632
1633 //--------------------------------------------------------------
1634 // Allow GDB attach
sewardj95d86c02007-12-18 01:49:23 +00001635 // p: main_process_cmd_line_options() [for VG_(clo_wait_for_gdb)]
nethercote71980f02004-01-24 18:18:54 +00001636 //--------------------------------------------------------------
1637 /* Hook to delay things long enough so we can get the pid and
1638 attach GDB in another shell. */
1639 if (VG_(clo_wait_for_gdb)) {
sewardj95611ff2007-02-16 13:57:07 +00001640 Long iters;
1641 volatile Long q;
sewardj1fbc1a52005-04-25 02:05:54 +00001642 VG_(debugLog)(1, "main", "Wait for GDB\n");
sewardj93ab8572005-02-06 14:10:40 +00001643 VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
sewardj8211a572005-06-23 21:37:47 +00001644
1645# if defined(VGP_x86_linux)
1646 iters = 5;
sewardj2c48c7b2005-11-29 13:05:56 +00001647# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
sewardj8211a572005-06-23 21:37:47 +00001648 iters = 10;
1649# elif defined(VGP_ppc32_linux)
sewardjd714d2e2005-07-08 18:24:04 +00001650 iters = 5;
sewardj17c11042006-10-15 01:26:40 +00001651# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1652 iters = 4;
sewardj8211a572005-06-23 21:37:47 +00001653# else
sewardj17c11042006-10-15 01:26:40 +00001654# error "Unknown plat"
sewardj8211a572005-06-23 21:37:47 +00001655# endif
1656
1657 iters *= 1000*1000*1000;
1658 for (q = 0; q < iters; q++)
1659 ;
nethercote71980f02004-01-24 18:18:54 +00001660 }
1661
sewardjb5d320c2005-03-13 18:57:15 +00001662 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001663 // Search for file descriptors that are inherited from our parent
sewardj95d86c02007-12-18 01:49:23 +00001664 // p: main_process_cmd_line_options [for VG_(clo_track_fds)]
nethercote71980f02004-01-24 18:18:54 +00001665 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001666 if (VG_(clo_track_fds)) {
1667 VG_(debugLog)(1, "main", "Init preopened fds\n");
nethercote71980f02004-01-24 18:18:54 +00001668 VG_(init_preopened_fds)();
sewardj1fbc1a52005-04-25 02:05:54 +00001669 }
nethercote71980f02004-01-24 18:18:54 +00001670
1671 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001672 // Load debug info for the existing segments.
1673 // p: setup_code_redirect_table [so that redirs can be recorded]
1674 // p: mallocfree
1675 // p: probably: setup fds and process CLOs, so that logging works
sewardjf98e1c02008-10-25 16:22:41 +00001676 // p: initialise m_debuginfo
sewardj9c606bd2008-09-18 18:12:50 +00001677 //
1678 // While doing this, make a note of the debuginfo-handles that
1679 // come back from VG_(di_notify_mmap)/VG_(di_aix5_notify_segchange).
1680 // Later, in "Tell the tool about the initial client memory permissions"
1681 // (just below) we can then hand these handles off to the tool in
1682 // calls to VG_TRACK(new_mem_startup, ...). This gives the tool the
1683 // opportunity to make further queries to m_debuginfo before the
1684 // client is started, if it wants. We put this information into an
1685 // XArray, each handle along with the associated segment start address,
1686 // and search the XArray for the handles later, when calling
1687 // VG_TRACK(new_mem_startup, ...).
sewardj45f4e7c2005-09-27 19:20:21 +00001688 //--------------------------------------------------------------
1689 VG_(debugLog)(1, "main", "Load initial debug info\n");
sewardj9c606bd2008-09-18 18:12:50 +00001690
1691 tl_assert(!addr2dihandle);
1692 addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2",
1693 VG_(free), sizeof(Addr_n_ULong) );
1694 tl_assert(addr2dihandle);
1695
sewardj17c11042006-10-15 01:26:40 +00001696# if defined(VGO_linux)
sewardj45f4e7c2005-09-27 19:20:21 +00001697 { Addr* seg_starts;
1698 Int n_seg_starts;
sewardj9c606bd2008-09-18 18:12:50 +00001699 Addr_n_ULong anu;
sewardj45f4e7c2005-09-27 19:20:21 +00001700
njnac1e0332009-05-08 00:39:31 +00001701 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001702 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00001703
sewardjf72cced2005-11-08 00:45:47 +00001704 /* show them all to the debug info reader. allow_SkFileV has to
1705 be True here so that we read info from the valgrind executable
1706 itself. */
sewardj9c606bd2008-09-18 18:12:50 +00001707 for (i = 0; i < n_seg_starts; i++) {
1708 anu.ull = VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/ );
1709 /* anu.ull holds the debuginfo handle returned by di_notify_mmap,
1710 if any. */
1711 if (anu.ull > 0) {
1712 anu.a = seg_starts[i];
1713 VG_(addToXA)( addr2dihandle, &anu );
1714 }
1715 }
sewardj45f4e7c2005-09-27 19:20:21 +00001716
1717 VG_(free)( seg_starts );
1718 }
sewardj17c11042006-10-15 01:26:40 +00001719# elif defined(VGO_aix5)
1720 { AixCodeSegChange* changes;
1721 Int changes_size, changes_used;
sewardj9c606bd2008-09-18 18:12:50 +00001722 Addr_n_ULong anu;
sewardj17c11042006-10-15 01:26:40 +00001723
1724 /* Find out how many AixCodeSegChange records we will need,
1725 and acquire them. */
1726 changes_size = VG_(am_aix5_reread_procmap_howmany_directives)();
sewardj9c606bd2008-09-18 18:12:50 +00001727 changes = VG_(malloc)("main.vm.3", changes_size * sizeof(AixCodeSegChange));
sewardj17c11042006-10-15 01:26:40 +00001728 vg_assert(changes);
1729
1730 /* Now re-read /proc/<pid>/map and acquire a change set */
1731 VG_(am_aix5_reread_procmap)( changes, &changes_used );
1732 vg_assert(changes_used >= 0 && changes_used <= changes_size);
1733
1734 /* And notify m_debuginfo of the changes. */
sewardj9c606bd2008-09-18 18:12:50 +00001735 for (i = 0; i < changes_used; i++) {
1736 anu.ull = VG_(di_aix5_notify_segchange)(
1737 changes[i].code_start,
1738 changes[i].code_len,
1739 changes[i].data_start,
1740 changes[i].data_len,
1741 changes[i].file_name,
1742 changes[i].mem_name,
1743 changes[i].is_mainexe,
1744 changes[i].acquire
1745 );
1746 if (anu.ull > 0) {
1747 tl_assert(changes[i].acquire);
1748 anu.a = changes[i].code_start; /* is this correct? */
1749 VG_(addToXA)( addr2dihandle, &anu );
1750 }
1751 }
sewardj17c11042006-10-15 01:26:40 +00001752
1753 VG_(free)(changes);
1754 }
1755# else
1756# error Unknown OS
1757# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001758
1759 //--------------------------------------------------------------
1760 // Tell aspacem of ownership change of the asm helpers, so that
1761 // m_translate allows them to be translated. However, only do this
1762 // after the initial debug info read, since making a hole in the
1763 // address range for the stage2 binary confuses the debug info reader.
1764 // p: aspacem
1765 //--------------------------------------------------------------
1766 { Bool change_ownership_v_c_OK;
sewardj1a85f4f2006-01-12 21:15:35 +00001767 Addr co_start = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
1768 Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
sewardj45f4e7c2005-09-27 19:20:21 +00001769 VG_(debugLog)(1,"redir",
1770 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
1771 (ULong)co_start, (ULong)co_endPlus-1 );
1772
1773 change_ownership_v_c_OK
1774 = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
1775 vg_assert(change_ownership_v_c_OK);
1776 }
1777
1778 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001779 // Initialise the scheduler (phase 1) [generates tid_main]
1780 // p: none, afaics
1781 //--------------------------------------------------------------
1782 VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
1783 tid_main = VG_(scheduler_init_phase1)();
1784 vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
1785 && tid_main != VG_INVALID_THREADID);
1786 /* Tell the tool about tid_main */
1787 VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
1788
1789 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001790 // Tell the tool about the initial client memory permissions
1791 // p: aspacem
1792 // p: mallocfree
1793 // p: setup_client_stack
1794 // p: setup_client_dataseg
sewardj9c606bd2008-09-18 18:12:50 +00001795 //
1796 // For each segment we tell the client about, look up in
1797 // addr2dihandle as created above, to see if there's a debuginfo
1798 // handle associated with the segment, that we can hand along
1799 // to the tool, to be helpful.
sewardj45f4e7c2005-09-27 19:20:21 +00001800 //--------------------------------------------------------------
1801 VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
1802 { Addr* seg_starts;
1803 Int n_seg_starts;
sewardj45f4e7c2005-09-27 19:20:21 +00001804
sewardj9c606bd2008-09-18 18:12:50 +00001805 tl_assert(addr2dihandle);
1806
tom7c1a19a2008-01-02 10:13:04 +00001807 /* Mark the main thread as running while we tell the tool about
1808 the client memory so that the tool can associate that memory
1809 with the main thread. */
1810 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
1811 VG_(running_tid) = tid_main;
1812
njnac1e0332009-05-08 00:39:31 +00001813 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001814 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00001815
1816 /* show interesting ones to the tool */
1817 for (i = 0; i < n_seg_starts; i++) {
sewardj9c606bd2008-09-18 18:12:50 +00001818 Word j, n;
sewardj12ab7652006-10-17 02:10:42 +00001819 NSegment const* seg
sewardj17c11042006-10-15 01:26:40 +00001820 = VG_(am_find_nsegment)( seg_starts[i] );
sewardj45f4e7c2005-09-27 19:20:21 +00001821 vg_assert(seg);
1822 if (seg->kind == SkFileC || seg->kind == SkAnonC) {
sewardjc6d86a32009-01-31 15:08:08 +00001823 /* This next assertion is tricky. If it is placed
1824 immediately before this 'if', it very occasionally fails.
1825 Why? Because previous iterations of the loop may have
1826 caused tools (via the new_mem_startup calls) to do
1827 dynamic memory allocation, and that may affect the mapped
1828 segments; in particular it may cause segment merging to
1829 happen. Hence we cannot assume that seg_starts[i], which
1830 reflects the state of the world before we started this
1831 loop, is the same as seg->start, as the latter reflects
1832 the state of the world (viz, mappings) at this particular
1833 iteration of the loop.
1834
1835 Why does moving it inside the 'if' make it safe? Because
1836 any dynamic memory allocation done by the tools will
1837 affect only the state of Valgrind-owned segments, not of
1838 Client-owned segments. And the 'if' guards against that
1839 -- we only get in here for Client-owned segments.
1840
1841 In other words: the loop may change the state of
1842 Valgrind-owned segments as it proceeds. But it should
1843 not cause the Client-owned segments to change. */
1844 vg_assert(seg->start == seg_starts[i]);
sewardj45f4e7c2005-09-27 19:20:21 +00001845 VG_(debugLog)(2, "main",
1846 "tell tool about %010lx-%010lx %c%c%c\n",
1847 seg->start, seg->end,
1848 seg->hasR ? 'r' : '-',
1849 seg->hasW ? 'w' : '-',
1850 seg->hasX ? 'x' : '-' );
sewardj9c606bd2008-09-18 18:12:50 +00001851 /* search addr2dihandle to see if we have an entry
1852 matching seg->start. */
1853 n = VG_(sizeXA)( addr2dihandle );
1854 for (j = 0; j < n; j++) {
1855 Addr_n_ULong* anl = VG_(indexXA)( addr2dihandle, j );
1856 if (anl->a == seg->start) {
1857 tl_assert(anl->ull > 0); /* check it's a valid handle */
1858 break;
1859 }
1860 }
1861 vg_assert(j >= 0 && j <= n);
sewardj45f4e7c2005-09-27 19:20:21 +00001862 VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
sewardj9c606bd2008-09-18 18:12:50 +00001863 seg->hasR, seg->hasW, seg->hasX,
1864 /* and the retrieved debuginfo handle, if any */
1865 j < n
1866 ? ((Addr_n_ULong*)VG_(indexXA)( addr2dihandle, j ))->ull
1867 : 0 );
sewardj45f4e7c2005-09-27 19:20:21 +00001868 }
1869 }
1870
1871 VG_(free)( seg_starts );
sewardj9c606bd2008-09-18 18:12:50 +00001872 VG_(deleteXA)( addr2dihandle );
sewardj45f4e7c2005-09-27 19:20:21 +00001873
1874 /* Also do the initial stack permissions. */
sewardj12ab7652006-10-17 02:10:42 +00001875 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00001876 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj17c11042006-10-15 01:26:40 +00001877 vg_assert(seg);
1878 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00001879 vg_assert(the_iifii.initial_client_SP >= seg->start);
1880 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardj17c11042006-10-15 01:26:40 +00001881# if defined(VGO_aix5)
1882 VG_(clstk_base) = seg->start;
1883 VG_(clstk_end) = seg->end;
1884# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001885
sewardj17c11042006-10-15 01:26:40 +00001886 /* Stuff below the initial SP is unaddressable. Take into
1887 account any ABI-mandated space below the stack pointer that
1888 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
1889 will have allocated an extra page if a red zone is required,
1890 to be on the safe side. */
sewardjf9d2f9b2006-11-17 20:00:57 +00001891 vg_assert(the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
1892 >= seg->start);
sewardj17c11042006-10-15 01:26:40 +00001893 VG_TRACK( die_mem_stack,
1894 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00001895 the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
1896 - seg->start );
sewardj17c11042006-10-15 01:26:40 +00001897 VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
1898 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00001899 the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
sewardj17c11042006-10-15 01:26:40 +00001900 }
sewardj45f4e7c2005-09-27 19:20:21 +00001901
1902 /* Also the assembly helpers. */
1903 VG_TRACK( new_mem_startup,
1904 (Addr)&VG_(trampoline_stuff_start),
sewardjc6527d62006-02-13 17:54:31 +00001905 (Addr)&VG_(trampoline_stuff_end)
1906 - (Addr)&VG_(trampoline_stuff_start),
sewardj45f4e7c2005-09-27 19:20:21 +00001907 False, /* readable? */
1908 False, /* writable? */
sewardj9c606bd2008-09-18 18:12:50 +00001909 True /* executable? */,
1910 0 /* di_handle: no associated debug info */ );
tom7c1a19a2008-01-02 10:13:04 +00001911
1912 /* Clear the running thread indicator */
1913 VG_(running_tid) = VG_INVALID_THREADID;
1914 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
sewardj45f4e7c2005-09-27 19:20:21 +00001915 }
1916
1917 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001918 // Initialise the scheduler (phase 2)
1919 // p: Initialise the scheduler (phase 1) [for tid_main]
nethercote71980f02004-01-24 18:18:54 +00001920 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
sewardj45f4e7c2005-09-27 19:20:21 +00001921 // p: setup_client_stack
nethercote71980f02004-01-24 18:18:54 +00001922 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001923 VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
sewardj12ab7652006-10-17 02:10:42 +00001924 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00001925 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj45f4e7c2005-09-27 19:20:21 +00001926 vg_assert(seg);
1927 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00001928 vg_assert(the_iifii.initial_client_SP >= seg->start);
1929 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardjde764e82007-11-09 23:13:22 +00001930 VG_(scheduler_init_phase2)( tid_main,
1931 seg->end, the_iifii.clstack_max_size );
sewardj45f4e7c2005-09-27 19:20:21 +00001932 }
nethercote71980f02004-01-24 18:18:54 +00001933
1934 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001935 // Set up state for the root thread
sewardjb5f6f512005-03-10 23:59:00 +00001936 // p: ?
sewardj17c11042006-10-15 01:26:40 +00001937 // setup_scheduler() [for sched-specific thread 1 stuff]
sewardjf9d2f9b2006-11-17 20:00:57 +00001938 // VG_(ii_create_image) [for 'the_iicii' initial info]
sewardj2a99cf62004-11-24 10:44:19 +00001939 //--------------------------------------------------------------
sewardjf9d2f9b2006-11-17 20:00:57 +00001940 VG_(debugLog)(1, "main", "Finalise initial image\n");
1941 VG_(ii_finalise_image)( the_iifii );
njnea4b28c2004-11-30 16:04:58 +00001942
sewardj2a99cf62004-11-24 10:44:19 +00001943 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001944 // Initialise the signal handling subsystem
sewardjb5f6f512005-03-10 23:59:00 +00001945 // p: n/a
nethercote71980f02004-01-24 18:18:54 +00001946 //--------------------------------------------------------------
1947 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
sewardj1fbc1a52005-04-25 02:05:54 +00001948 VG_(debugLog)(1, "main", "Initialise signal management\n");
njncda2f0f2009-05-18 02:12:08 +00001949 /* Check that the kernel-interface signal definitions look sane */
1950 VG_(vki_do_initial_consistency_checks)();
1951 /* .. and go on to use them. */
nethercote71980f02004-01-24 18:18:54 +00001952 VG_(sigstartup_actions)();
1953
1954 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001955 // Read suppression file
sewardj95d86c02007-12-18 01:49:23 +00001956 // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
nethercote71980f02004-01-24 18:18:54 +00001957 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001958 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
1959 VG_(debugLog)(1, "main", "Load suppressions\n");
nethercote71980f02004-01-24 18:18:54 +00001960 VG_(load_suppressions)();
sewardj1fbc1a52005-04-25 02:05:54 +00001961 }
nethercote71980f02004-01-24 18:18:54 +00001962
1963 //--------------------------------------------------------------
rjwalsh0140af52005-06-04 20:42:33 +00001964 // register client stack
1965 //--------------------------------------------------------------
njn945ed2e2005-06-24 03:28:30 +00001966 VG_(clstk_id) = VG_(register_stack)(VG_(clstk_base), VG_(clstk_end));
rjwalsh0140af52005-06-04 20:42:33 +00001967
1968 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001969 // Show the address space state so far
1970 //--------------------------------------------------------------
1971 VG_(debugLog)(1, "main", "\n");
1972 VG_(debugLog)(1, "main", "\n");
1973 VG_(am_show_nsegments)(1,"Memory layout at client startup");
1974 VG_(debugLog)(1, "main", "\n");
1975 VG_(debugLog)(1, "main", "\n");
1976
1977 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001978 // Run!
1979 //--------------------------------------------------------------
sewardj71bc3cb2005-05-19 00:25:45 +00001980 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00001981 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00001982 VG_(elapsed_wallclock_time)(buf);
barta0b6b2c2008-07-07 06:49:24 +00001983 VG_(message_no_f_c)(Vg_UserMsg,
1984 "<status>\n"
1985 " <state>RUNNING</state>\n"
1986 " <time>%t</time>\n"
1987 "</status>",
1988 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00001989 VG_(message)(Vg_UserMsg, "");
1990 }
1991
sewardj1fbc1a52005-04-25 02:05:54 +00001992 VG_(debugLog)(1, "main", "Running thread 1\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00001993
sewardj1d887112005-05-30 21:44:08 +00001994 /* As a result of the following call, the last thread standing
sewardj1ae3f3a2005-09-28 10:47:38 +00001995 eventually winds up running shutdown_actions_NORETURN
1996 just below. Unfortunately, simply exporting said function
1997 causes m_main to be part of a module cycle, which is pretty
1998 nonsensical. So instead of doing that, the address of said
1999 function is stored in a global variable 'owned' by m_syswrap,
2000 and it uses that function pointer to get back here when it needs
2001 to. */
2002
2003 /* Set continuation address. */
2004 VG_(address_of_m_main_shutdown_actions_NORETURN)
2005 = & shutdown_actions_NORETURN;
2006
2007 /* Run the first thread, eventually ending up at the continuation
2008 address. */
njnaf839f52005-06-23 03:27:57 +00002009 VG_(main_thread_wrapper_NORETURN)(1);
nethercote71980f02004-01-24 18:18:54 +00002010
sewardj1d887112005-05-30 21:44:08 +00002011 /*NOTREACHED*/
2012 vg_assert(0);
sewardjb5f6f512005-03-10 23:59:00 +00002013}
2014
sewardj17c11042006-10-15 01:26:40 +00002015/* Do everything which needs doing when the last thread exits or when
2016 a thread exits requesting a complete process exit (exit on AIX).
2017
2018 We enter here holding The Lock. For the case VgSrc_ExitProcess we
2019 must never release it, because to do so would allow other threads
2020 to continue after the system is ostensibly shut down. So we must
2021 go to our grave, so to speak, holding the lock.
2022
2023 In fact, there is never any point in releasing the lock at this
2024 point - we have it, we're shutting down the entire system, and
2025 for the case VgSrc_ExitProcess doing so positively causes trouble.
2026 So don't.
2027
2028 The final_tidyup call makes a bit of a nonsense of the ExitProcess
2029 case, since it will run the libc_freeres function, thus allowing
2030 other lurking threads to run again. Hmm. */
sewardjb5f6f512005-03-10 23:59:00 +00002031
sewardj1ae3f3a2005-09-28 10:47:38 +00002032static
2033void shutdown_actions_NORETURN( ThreadId tid,
2034 VgSchedReturnCode tids_schedretcode )
sewardjb5f6f512005-03-10 23:59:00 +00002035{
sewardj1d887112005-05-30 21:44:08 +00002036 VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
sewardj17c11042006-10-15 01:26:40 +00002037 VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
sewardj1d887112005-05-30 21:44:08 +00002038
sewardjb5f6f512005-03-10 23:59:00 +00002039 vg_assert(VG_(is_running_thread)(tid));
2040
sewardj12ab7652006-10-17 02:10:42 +00002041 vg_assert(tids_schedretcode == VgSrc_ExitThread
2042 || tids_schedretcode == VgSrc_ExitProcess
2043 || tids_schedretcode == VgSrc_FatalSig );
sewardjb5f6f512005-03-10 23:59:00 +00002044
sewardj12ab7652006-10-17 02:10:42 +00002045 if (tids_schedretcode == VgSrc_ExitThread) {
sewardjb5f6f512005-03-10 23:59:00 +00002046
sewardj17c11042006-10-15 01:26:40 +00002047 // We are the last surviving thread. Right?
2048 vg_assert( VG_(count_living_threads)() == 1 );
sewardjb5f6f512005-03-10 23:59:00 +00002049
sewardj17c11042006-10-15 01:26:40 +00002050 // Wait for all other threads to exit.
2051 // jrs: Huh? but they surely are already gone
2052 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002053
sewardj17c11042006-10-15 01:26:40 +00002054 // Clean the client up before the final report
2055 // this causes the libc_freeres function to run
2056 final_tidyup(tid);
2057
2058 /* be paranoid */
2059 vg_assert(VG_(is_running_thread)(tid));
2060 vg_assert(VG_(count_living_threads)() == 1);
2061
2062 } else {
2063
2064 // We may not be the last surviving thread. However, we
2065 // want to shut down the entire process. We hold the lock
2066 // and we need to keep hold of it all the way out, in order
2067 // that none of the other threads ever run again.
2068 vg_assert( VG_(count_living_threads)() >= 1 );
2069
sewardj17c11042006-10-15 01:26:40 +00002070 // Clean the client up before the final report
2071 // this causes the libc_freeres function to run
2072 // perhaps this is unsafe, as per comment above
2073 final_tidyup(tid);
2074
2075 /* be paranoid */
2076 vg_assert(VG_(is_running_thread)(tid));
2077 vg_assert(VG_(count_living_threads)() >= 1);
2078 }
sewardjb5f6f512005-03-10 23:59:00 +00002079
2080 VG_(threads)[tid].status = VgTs_Empty;
nethercote71980f02004-01-24 18:18:54 +00002081 //--------------------------------------------------------------
2082 // Finalisation: cleanup, messages, etc. Order no so important, only
2083 // affects what order the messages come.
2084 //--------------------------------------------------------------
2085 if (VG_(clo_verbosity) > 0)
2086 VG_(message)(Vg_UserMsg, "");
2087
sewardj71bc3cb2005-05-19 00:25:45 +00002088 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002089 HChar buf[50];
sewardj9f297ca2005-05-20 02:29:52 +00002090 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
2091 VG_(show_error_counts_as_XML)();
2092 VG_(message)(Vg_UserMsg, "");
2093 }
sewardj592ae092005-11-08 19:01:44 +00002094 VG_(elapsed_wallclock_time)(buf);
barta0b6b2c2008-07-07 06:49:24 +00002095 VG_(message_no_f_c)(Vg_UserMsg,
2096 "<status>\n"
2097 " <state>FINISHED</state>\n"
2098 " <time>%t</time>\n"
2099 "</status>",
2100 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00002101 VG_(message)(Vg_UserMsg, "");
2102 }
2103
nethercote71980f02004-01-24 18:18:54 +00002104 /* Print out file descriptor summary and stats. */
2105 if (VG_(clo_track_fds))
nethercote3a42fb82004-08-03 18:08:50 +00002106 VG_(show_open_fds)();
nethercote71980f02004-01-24 18:18:54 +00002107
njn95ec8702004-11-22 16:46:13 +00002108 if (VG_(needs).core_errors || VG_(needs).tool_errors)
nethercote71980f02004-01-24 18:18:54 +00002109 VG_(show_all_errors)();
2110
njn51d827b2005-05-09 01:02:08 +00002111 VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
nethercote71980f02004-01-24 18:18:54 +00002112
sewardj71bc3cb2005-05-19 00:25:45 +00002113 if (VG_(clo_xml)) {
2114 VG_(message)(Vg_UserMsg, "");
2115 VG_(message)(Vg_UserMsg, "</valgrindoutput>");
2116 VG_(message)(Vg_UserMsg, "");
2117 }
2118
nethercote885dd912004-08-03 23:14:00 +00002119 VG_(sanity_check_general)( True /*include expensive checks*/ );
nethercote71980f02004-01-24 18:18:54 +00002120
2121 if (VG_(clo_verbosity) > 1)
nethercote3a42fb82004-08-03 18:08:50 +00002122 print_all_stats();
nethercote71980f02004-01-24 18:18:54 +00002123
sewardj9c606bd2008-09-18 18:12:50 +00002124 /* Show a profile of the heap(s) at shutdown. Optionally, first
2125 throw away all the debug info, as that makes it easy to spot
2126 leaks in the debuginfo reader. */
2127 if (VG_(clo_profile_heap)) {
2128 if (0) VG_(di_discard_ALL_debuginfo)();
2129 VG_(print_arena_cc_analysis)();
2130 }
2131
njn2025cf92005-06-26 20:44:48 +00002132 if (VG_(clo_profile_flags) > 0) {
sewardj5471ec62006-10-17 13:58:17 +00002133 #define N_MAX 200
njn2025cf92005-06-26 20:44:48 +00002134 BBProfEntry tops[N_MAX];
2135 ULong score_total = VG_(get_BB_profile) (tops, N_MAX);
2136 show_BB_profile(tops, N_MAX, score_total);
2137 }
sewardjfa8ec112005-01-19 11:55:34 +00002138
sewardj8b635a42004-11-22 19:01:47 +00002139 /* Print Vex storage stats */
sewardjbf426512005-01-17 18:35:30 +00002140 if (0)
2141 LibVEX_ShowAllocStats();
sewardj1d887112005-05-30 21:44:08 +00002142
njn8aa35852005-06-10 22:59:56 +00002143 /* Ok, finally exit in the os-specific way, according to the scheduler's
2144 return code. In short, if the (last) thread exited by calling
2145 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2146 signal, terminate the entire system with that same fatal signal. */
2147 VG_(debugLog)(1, "core_os",
njn7b85dd52005-06-12 17:26:29 +00002148 "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
njn8aa35852005-06-10 22:59:56 +00002149
njn8aa35852005-06-10 22:59:56 +00002150 switch (tids_schedretcode) {
sewardj12ab7652006-10-17 02:10:42 +00002151 case VgSrc_ExitThread: /* the normal way out (Linux) */
2152 case VgSrc_ExitProcess: /* the normal way out (AIX) */
sewardjb9779082006-05-12 23:50:15 +00002153 /* Change the application return code to user's return code,
2154 if an error was found */
2155 if (VG_(clo_error_exitcode) > 0
2156 && VG_(get_n_errs_found)() > 0) {
2157 VG_(exit)( VG_(clo_error_exitcode) );
2158 } else {
2159 /* otherwise, return the client's exit code, in the normal
2160 way. */
2161 VG_(exit)( VG_(threads)[tid].os_state.exitcode );
2162 }
njn8aa35852005-06-10 22:59:56 +00002163 /* NOT ALIVE HERE! */
sewardj17c11042006-10-15 01:26:40 +00002164 VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
njn8aa35852005-06-10 22:59:56 +00002165 break; /* what the hell :) */
2166
2167 case VgSrc_FatalSig:
2168 /* We were killed by a fatal signal, so replicate the effect */
2169 vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
2170 VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
2171 VG_(core_panic)("main(): signal was supposed to be fatal");
2172 break;
2173
2174 default:
2175 VG_(core_panic)("main(): unexpected scheduler return code");
2176 }
njne96be672005-05-08 19:08:54 +00002177}
sewardj8b635a42004-11-22 19:01:47 +00002178
sewardj1ae3f3a2005-09-28 10:47:38 +00002179/* -------------------- */
2180
2181/* Final clean-up before terminating the process.
2182 Clean up the client by calling __libc_freeres() (if requested)
2183 This is Linux-specific?
2184*/
2185static void final_tidyup(ThreadId tid)
2186{
sewardjcf951812006-01-17 02:22:21 +00002187# if defined(VGP_ppc64_linux)
2188 Addr r2;
2189# endif
sewardj0ec07f32006-01-12 12:32:32 +00002190 Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
sewardj1ae3f3a2005-09-28 10:47:38 +00002191
2192 vg_assert(VG_(is_running_thread)(tid));
2193
2194 if ( !VG_(needs).libc_freeres ||
2195 !VG_(clo_run_libc_freeres) ||
sewardj0ec07f32006-01-12 12:32:32 +00002196 0 == __libc_freeres_wrapper )
sewardj1ae3f3a2005-09-28 10:47:38 +00002197 return; /* can't/won't do it */
sewardj17c11042006-10-15 01:26:40 +00002198# if defined(VGO_aix5)
2199 return; /* inapplicable on non-Linux platforms */
2200# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002201
sewardjcf951812006-01-17 02:22:21 +00002202# if defined(VGP_ppc64_linux)
2203 r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
2204 if (r2 == 0) {
2205 VG_(message)(Vg_UserMsg,
2206 "Caught __NR_exit, but can't run __libc_freeres()");
2207 VG_(message)(Vg_UserMsg,
2208 " since cannot establish TOC pointer for it.");
2209 return;
2210 }
2211# endif
2212
sewardj1ae3f3a2005-09-28 10:47:38 +00002213 if (VG_(clo_verbosity) > 2 ||
2214 VG_(clo_trace_syscalls) ||
2215 VG_(clo_trace_sched))
2216 VG_(message)(Vg_DebugMsg,
2217 "Caught __NR_exit; running __libc_freeres()");
2218
sewardj0ec07f32006-01-12 12:32:32 +00002219 /* set thread context to point to libc_freeres_wrapper */
sewardj1a85f4f2006-01-12 21:15:35 +00002220 /* ppc64-linux note: __libc_freeres_wrapper gives us the real
2221 function entry point, not a fn descriptor, so can use it
2222 directly. However, we need to set R2 (the toc pointer)
2223 appropriately. */
sewardj1ae3f3a2005-09-28 10:47:38 +00002224 VG_(set_IP)(tid, __libc_freeres_wrapper);
sewardjcf951812006-01-17 02:22:21 +00002225# if defined(VGP_ppc64_linux)
2226 VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
2227# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002228
2229 /* Block all blockable signals by copying the real block state into
2230 the thread's block state*/
2231 VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
2232 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
2233
2234 /* and restore handlers to default */
2235 VG_(set_default_handler)(VKI_SIGSEGV);
2236 VG_(set_default_handler)(VKI_SIGBUS);
2237 VG_(set_default_handler)(VKI_SIGILL);
2238 VG_(set_default_handler)(VKI_SIGFPE);
2239
2240 // We were exiting, so assert that...
2241 vg_assert(VG_(is_exiting)(tid));
2242 // ...but now we're not again
2243 VG_(threads)[tid].exitreason = VgSrc_None;
2244
2245 // run until client thread exits - ideally with LIBC_FREERES_DONE,
2246 // but exit/exitgroup/signal will do
2247 VG_(scheduler)(tid);
2248
2249 vg_assert(VG_(is_exiting)(tid));
2250}
2251
sewardj45f4e7c2005-09-27 19:20:21 +00002252
2253/*====================================================================*/
njn49f80e82009-05-21 01:25:43 +00002254/*=== Getting to main() alive: LINUX ===*/
sewardj45f4e7c2005-09-27 19:20:21 +00002255/*====================================================================*/
2256
sewardj17c11042006-10-15 01:26:40 +00002257#if defined(VGO_linux)
2258
sewardj45f4e7c2005-09-27 19:20:21 +00002259/* If linking of the final executables is done with glibc present,
2260 then Valgrind starts at main() above as usual, and all of the
2261 following code is irrelevant.
2262
2263 However, this is not the intended mode of use. The plan is to
2264 avoid linking against glibc, by giving gcc the flags
2265 -nodefaultlibs -lgcc -nostartfiles at startup.
2266
2267 From this derive two requirements:
2268
2269 1. gcc may emit calls to memcpy and memset to deal with structure
2270 assignments etc. Since we have chosen to ignore all the
2271 "normal" supporting libraries, we have to provide our own
2272 implementations of them. No problem.
2273
2274 2. We have to provide a symbol "_start", to which the kernel
2275 hands control at startup. Hence the code below.
2276*/
2277
2278/* ---------------- Requirement 1 ---------------- */
2279
sewardj17c11042006-10-15 01:26:40 +00002280void* memcpy(void *dest, const void *src, SizeT n);
2281void* memcpy(void *dest, const void *src, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002282 return VG_(memcpy)(dest,src,n);
2283}
sewardj17c11042006-10-15 01:26:40 +00002284void* memset(void *s, int c, SizeT n);
2285void* memset(void *s, int c, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002286 return VG_(memset)(s,c,n);
2287}
2288
2289/* ---------------- Requirement 2 ---------------- */
2290
2291/* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2292 comment, which explains how the stack looks right at process start
2293 (when _start is jumped to). Hence _start passes %esp to
sewardj17c11042006-10-15 01:26:40 +00002294 _start_in_C_linux, which extracts argc/argv/envp and starts up
sewardj45f4e7c2005-09-27 19:20:21 +00002295 correctly. */
2296
2297/* This is the canonical entry point, usually the first thing in the text
2298 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2299 point runs, most registers' values are unspecified, except for:
2300
2301 %edx Contains a function pointer to be registered with `atexit'.
2302 This is how the dynamic linker arranges to have DT_FINI
2303 functions called for shared libraries that have been loaded
2304 before this code runs.
2305
2306 %esp The stack contains the arguments and environment:
2307 0(%esp) argc
2308 4(%esp) argv[0]
2309 ...
2310 (4*argc)(%esp) NULL
2311 (4*(argc+1))(%esp) envp[0]
2312 ...
2313 NULL
2314*/
2315
2316/* The kernel hands control to _start, which extracts the initial
sewardj17c11042006-10-15 01:26:40 +00002317 stack pointer and calls onwards to _start_in_C_linux. This also switches
sewardja48a4932005-09-29 11:09:56 +00002318 the new stack. */
sewardj45f4e7c2005-09-27 19:20:21 +00002319#if defined(VGP_x86_linux)
2320asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002321 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002322 "\t.globl _start\n"
2323 "\t.type _start,@function\n"
2324 "_start:\n"
2325 /* set up the new stack in %eax */
sewardjfdf91b42005-09-28 00:53:09 +00002326 "\tmovl $vgPlain_interim_stack, %eax\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002327 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2328 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2329 "\tsubl $16, %eax\n"
2330 "\tandl $~15, %eax\n"
2331 /* install it, and collect the original one */
2332 "\txchgl %eax, %esp\n"
sewardj17c11042006-10-15 01:26:40 +00002333 /* call _start_in_C_linux, passing it the startup %esp */
sewardj45f4e7c2005-09-27 19:20:21 +00002334 "\tpushl %eax\n"
sewardj17c11042006-10-15 01:26:40 +00002335 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002336 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002337 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002338);
2339#elif defined(VGP_amd64_linux)
2340asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002341 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002342 "\t.globl _start\n"
2343 "\t.type _start,@function\n"
2344 "_start:\n"
2345 /* set up the new stack in %rdi */
sewardjfdf91b42005-09-28 00:53:09 +00002346 "\tmovq $vgPlain_interim_stack, %rdi\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002347 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2348 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2349 "\tandq $~15, %rdi\n"
2350 /* install it, and collect the original one */
2351 "\txchgq %rdi, %rsp\n"
sewardj17c11042006-10-15 01:26:40 +00002352 /* call _start_in_C_linux, passing it the startup %rsp */
2353 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002354 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002355 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002356);
sewardja48a4932005-09-29 11:09:56 +00002357#elif defined(VGP_ppc32_linux)
2358asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002359 ".text\n"
sewardja48a4932005-09-29 11:09:56 +00002360 "\t.globl _start\n"
2361 "\t.type _start,@function\n"
2362 "_start:\n"
2363 /* set up the new stack in r16 */
2364 "\tlis 16,vgPlain_interim_stack@ha\n"
2365 "\tla 16,vgPlain_interim_stack@l(16)\n"
2366 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2367 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2368 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2369 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2370 "\tadd 16,17,16\n"
2371 "\tadd 16,18,16\n"
2372 "\trlwinm 16,16,0,0,27\n"
2373 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2374 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2375 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002376 call _start_in_C_linux, passing it the initial SP. */
sewardja48a4932005-09-29 11:09:56 +00002377 "\tmr 3,1\n"
2378 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002379 "\tbl _start_in_C_linux\n"
sewardja48a4932005-09-29 11:09:56 +00002380 "\ttrap\n"
sewardj2fedc642005-11-19 02:02:57 +00002381 ".previous\n"
sewardja48a4932005-09-29 11:09:56 +00002382);
sewardj2c48c7b2005-11-29 13:05:56 +00002383#elif defined(VGP_ppc64_linux)
2384asm("\n"
cerion21082042005-12-06 19:07:08 +00002385 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2386 So we must have one, and that is what goes into the .opd section. */
cerion297c88f2005-12-22 15:53:12 +00002387 "\t.align 2\n"
cerion21082042005-12-06 19:07:08 +00002388 "\t.global _start\n"
2389 "\t.section \".opd\",\"aw\"\n"
2390 "\t.align 3\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002391 "_start:\n"
cerion21082042005-12-06 19:07:08 +00002392 "\t.quad ._start,.TOC.@tocbase,0\n"
2393 "\t.previous\n"
2394 "\t.type ._start,@function\n"
2395 "\t.global ._start\n"
2396 "._start:\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002397 /* set up the new stack in r16 */
2398 "\tlis 16, vgPlain_interim_stack@highest\n"
2399 "\tori 16,16,vgPlain_interim_stack@higher\n"
2400 "\tsldi 16,16,32\n"
2401 "\toris 16,16,vgPlain_interim_stack@h\n"
2402 "\tori 16,16,vgPlain_interim_stack@l\n"
2403 "\txor 17,17,17\n"
2404 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2405 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2406 "\txor 18,18,18\n"
2407 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2408 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2409 "\tadd 16,17,16\n"
2410 "\tadd 16,18,16\n"
2411 "\trldicr 16,16,0,59\n"
2412 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2413 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2414 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002415 call _start_in_C_linux, passing it the initial SP. */
sewardj2c48c7b2005-11-29 13:05:56 +00002416 "\tmr 3,1\n"
2417 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002418 "\tbl ._start_in_C_linux\n"
cerion21082042005-12-06 19:07:08 +00002419 "\tnop\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002420 "\ttrap\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002421);
sewardj45f4e7c2005-09-27 19:20:21 +00002422#else
njn49f80e82009-05-21 01:25:43 +00002423# error "Unknown linux platform"
sewardj45f4e7c2005-09-27 19:20:21 +00002424#endif
2425
sewardje66f2e02006-12-30 17:45:08 +00002426/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
2427#define _GNU_SOURCE
2428#define _FILE_OFFSET_BITS 64
2429/* This is in order to get AT_NULL and AT_PAGESIZE. */
2430#include <elf.h>
2431/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
2432
sewardj45f4e7c2005-09-27 19:20:21 +00002433/* Avoid compiler warnings: this fn _is_ used, but labelling it
2434 'static' causes gcc to complain it isn't. */
sewardj17c11042006-10-15 01:26:40 +00002435void _start_in_C_linux ( UWord* pArgc );
2436void _start_in_C_linux ( UWord* pArgc )
sewardj45f4e7c2005-09-27 19:20:21 +00002437{
2438 Int r;
2439 Word argc = pArgc[0];
2440 HChar** argv = (HChar**)&pArgc[1];
2441 HChar** envp = (HChar**)&pArgc[1+argc+1];
sewardjf9d2f9b2006-11-17 20:00:57 +00002442
2443 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2444 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2445
2446 the_iicii.sp_at_startup = (Addr)pArgc;
2447
sewardje66f2e02006-12-30 17:45:08 +00002448# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
2449 {
2450 /* ppc/ppc64 can be configured with different page sizes.
2451 Determine this early. This is an ugly hack and really should
2452 be moved into valgrind_main. */
2453 UWord *sp = &pArgc[1+argc+1];
2454 while (*sp++ != 0)
2455 ;
2456 for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
2457 if (*sp == AT_PAGESZ) {
2458 VKI_PAGE_SIZE = sp[1];
2459 for (VKI_PAGE_SHIFT = 12;
2460 VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
2461 if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
2462 break;
2463 }
2464 }
2465# endif
2466
sewardjf9d2f9b2006-11-17 20:00:57 +00002467 r = valgrind_main( (Int)argc, argv, envp );
sewardj17c11042006-10-15 01:26:40 +00002468 /* NOTREACHED */
sewardj45f4e7c2005-09-27 19:20:21 +00002469 VG_(exit)(r);
2470}
2471
sewardj17c11042006-10-15 01:26:40 +00002472
2473/*====================================================================*/
2474/*=== Getting to main() alive: AIX5 ===*/
2475/*====================================================================*/
2476
njn49f80e82009-05-21 01:25:43 +00002477#elif defined(VGO_aix5)
sewardj17c11042006-10-15 01:26:40 +00002478
2479/* This is somewhat simpler than the Linux case. _start_valgrind
2480 receives control from the magic piece of code created in this
2481 process' address space by the launcher, via use of ptrace(). At
2482 the point of entry:
2483
2484 - the initial client process image is in memory and ready to roll,
2485 except that we've partially trashed its integer register state
2486 in order to get this far. So ..
2487
2488 - intregs37 holds the client's initial integer register state, so
2489 we can restore it before starting the client on the VCPU.
2490
2491 - we're on the client's stack. This is not good; therefore the
2492 first order of business is to switch to our temporary stack.
2493
2494 - the client's initial argc/v/envp is in r3/r4/r5 (32 bit mode) or
2495 r14/r15/r16 (64 bit mode). They are pulled out of the stashed
2496 integer register state and passed to our main().
2497
2498 The launcher will have played some games with argv. If the launcher
2499 ($prefix/bin/valgrind) was started like this
2500
2501 valgrind [args-for-V] app [args-for-app]
2502
2503 then the launcher will have started the client as
2504
2505 app [args-for-V] app [args-for-app]
2506
2507 m_initimg will have to mess with the client's initial r4/r5
2508 (32-bit) or r15/r16 (64-bit) so that it believes it was execd as
2509 "app [args-for-app]". Well, that's no big deal.
2510*/
2511
2512#include "launcher-aix5-bootblock.h"
2513
2514void _start_in_C_aix5 ( AIX5Bootblock* bootblock );
2515void _start_in_C_aix5 ( AIX5Bootblock* bootblock )
2516{
2517 Int r;
2518 ULong* intregs37;
2519 UWord argc, argv, envp;
2520 __NR_getpid = bootblock->__NR_getpid;
2521 __NR_write = bootblock->__NR_write;
2522 __NR_exit = bootblock->__NR_exit;
2523 __NR_open = bootblock->__NR_open;
2524 __NR_read = bootblock->__NR_read;
2525 __NR_close = bootblock->__NR_close;
sewardjf9d2f9b2006-11-17 20:00:57 +00002526
2527 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2528 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2529
sewardj17c11042006-10-15 01:26:40 +00002530 intregs37 = &bootblock->iregs_pc_cr_lr_ctr_xer[0];
sewardjf9d2f9b2006-11-17 20:00:57 +00002531 the_iicii.intregs37 = intregs37;
2532 the_iicii.bootblock = (void*)bootblock;
2533 the_iicii.adler32_exp = bootblock->adler32;
2534
2535 /* Not important on AIX. */
2536 the_iicii.sp_at_startup = (Addr)0x31415927ULL;
2537
sewardj17c11042006-10-15 01:26:40 +00002538# if defined(VGP_ppc32_aix5)
2539 argc = (UWord)intregs37[3]; /* client's r3 == argc */
2540 argv = (UWord)intregs37[4];
2541 envp = (UWord)intregs37[5];
2542# else /* defined(VGP_ppc64_aix5) */
2543 argc = (UWord)intregs37[14]; /* client's r14 == argc */
2544 argv = (UWord)intregs37[15];
2545 envp = (UWord)intregs37[16];
2546# endif
sewardjf9d2f9b2006-11-17 20:00:57 +00002547
2548 r = valgrind_main( (Int)argc, (HChar**)argv, (HChar**)envp );
2549
sewardj17c11042006-10-15 01:26:40 +00002550 /* NOTREACHED */
2551 VG_(exit)(r);
2552}
2553
2554/* THE ENTRY POINT */
2555void _start_valgrind ( AIX5Bootblock* bootblock );
2556void _start_valgrind ( AIX5Bootblock* bootblock )
2557{
2558 /* Switch immediately to our temporary stack, and continue. This
2559 is pretty dodgy in that it assumes that gcc does not place on
2560 the stack, anything needed to form the _start_in_C_aix5 call,
2561 since it will be on the old stack. */
2562 register UWord new_r1;
2563 new_r1 = (UWord)&VG_(interim_stack);
2564 new_r1 += VG_STACK_GUARD_SZB; /* step over lower guard page */
2565 new_r1 += VG_STACK_ACTIVE_SZB; /* step to top of active area */
2566 new_r1 -= 512; /* paranoia */
2567 __asm__ __volatile__("mr 1,%0" :/*wr*/
2568 :/*rd*/ "b"(new_r1)
2569 :/*trash*/"r1","memory");
2570 _start_in_C_aix5(bootblock);
2571 /*NOTREACHED*/
2572 VG_(exit)(0);
2573}
2574
sewardj61a1b052008-10-22 00:56:53 +00002575/* At some point in Oct 2008, static linking appeared to stop working
2576 on AIX 5.3. This breaks the build since we link statically. The
2577 linking fails citing absence of the following five symbols as the
2578 reason. In the absence of a better solution, here are stand-ins
2579 for them. Kludge appears to work; presumably said functions,
2580 assuming they are indeed functions, are never called. */
2581void encrypted_pw_passlen ( void ) { vg_assert(0); }
2582void crypt_r ( void ) { vg_assert(0); }
2583void max_history_size ( void ) { vg_assert(0); }
2584void getpass_auto ( void ) { vg_assert(0); }
2585void max_pw_passlen ( void ) { vg_assert(0); }
2586
njn49f80e82009-05-21 01:25:43 +00002587
2588#else
2589
2590# error "Unknown OS"
2591#endif
sewardj17c11042006-10-15 01:26:40 +00002592
2593
sewardjde4a1d02002-03-22 01:27:54 +00002594/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00002595/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00002596/*--------------------------------------------------------------------*/