blob: 7cf141d0f57949ef99c02ff59f29a2318066925c [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
sewardj4d474d02008-02-11 11:34:59 +000010 Copyright (C) 2000-2008 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"
sewardj45f4e7c2005-09-27 19:20:21 +000038#include "pub_core_commandline.h"
njn2521d322005-05-08 14:45:13 +000039#include "pub_core_debuglog.h"
40#include "pub_core_errormgr.h"
41#include "pub_core_execontext.h"
sewardj17c11042006-10-15 01:26:40 +000042#include "pub_core_initimg.h"
njn97405b22005-06-02 03:39:33 +000043#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000044#include "pub_core_libcassert.h"
njneb8896b2005-06-04 20:03:55 +000045#include "pub_core_libcfile.h"
njn36a20fa2005-06-03 03:08:39 +000046#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000047#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +000048#include "pub_core_libcsignal.h"
sewardj45f4e7c2005-09-27 19:20:21 +000049#include "pub_core_syscall.h" // VG_(strerror)
njnf536bbb2005-06-13 04:21:38 +000050#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +000051#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000052#include "pub_core_options.h"
sewardjfdf91b42005-09-28 00:53:09 +000053#include "pub_core_debuginfo.h"
njnd1af0032005-05-29 17:01:48 +000054#include "pub_core_redir.h"
njnc7561b92005-06-19 01:24:32 +000055#include "pub_core_scheduler.h"
njn0c246472005-05-31 01:00:08 +000056#include "pub_core_signals.h"
njn2025cf92005-06-26 20:44:48 +000057#include "pub_core_stacks.h" // For VG_(register_stack)
njnc1b01812005-06-17 22:19:06 +000058#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +000059#include "pub_core_tooliface.h"
sewardj17c11042006-10-15 01:26:40 +000060#include "pub_core_translate.h" // For VG_(translate)
njna7598f62005-06-18 03:27:58 +000061#include "pub_core_trampoline.h"
njn8bddf582005-05-13 23:40:55 +000062#include "pub_core_transtab.h"
sewardj17c11042006-10-15 01:26:40 +000063
64/* Stuff for reading AIX5 /proc/<pid>/sysent files */
65#if defined(VGO_aix5)
66 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
67# include <sys/procfs.h> /* prsysent_t */
68 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
69# define VG_AIX5_SYSENT_SIZE 100000
70 static UChar aix5_sysent_buf[VG_AIX5_SYSENT_SIZE];
71#endif
nethercote71980f02004-01-24 18:18:54 +000072
sewardjb5f6f512005-03-10 23:59:00 +000073
nethercote71980f02004-01-24 18:18:54 +000074/*====================================================================*/
75/*=== Counters, for profiling purposes only ===*/
76/*====================================================================*/
sewardjde4a1d02002-03-22 01:27:54 +000077
nethercote3a42fb82004-08-03 18:08:50 +000078static void print_all_stats ( void )
nethercote71980f02004-01-24 18:18:54 +000079{
njn42c83552005-12-05 20:45:59 +000080 VG_(print_translation_stats)();
nethercote92e7b7f2004-08-07 17:52:25 +000081 VG_(print_tt_tc_stats)();
nethercote844e7122004-08-02 15:27:22 +000082 VG_(print_scheduler_stats)();
njn9271cbc2005-03-13 05:38:25 +000083 VG_(print_ExeContext_stats)();
sewardj12ab7652006-10-17 02:10:42 +000084 VG_(print_errormgr_stats)();
njn9271cbc2005-03-13 05:38:25 +000085
nethercote3a42fb82004-08-03 18:08:50 +000086 // Memory stats
nethercote885dd912004-08-03 23:14:00 +000087 if (VG_(clo_verbosity) > 2) {
nethercote3a42fb82004-08-03 18:08:50 +000088 VG_(message)(Vg_DebugMsg, "");
89 VG_(message)(Vg_DebugMsg,
90 "------ Valgrind's internal memory use stats follow ------" );
nethercote885dd912004-08-03 23:14:00 +000091 VG_(sanity_check_malloc_all)();
njn11adeb22005-07-03 20:22:39 +000092 VG_(message)(Vg_DebugMsg, "------" );
nethercote3a42fb82004-08-03 18:08:50 +000093 VG_(print_all_arena_stats)();
nethercote885dd912004-08-03 23:14:00 +000094 VG_(message)(Vg_DebugMsg, "");
nethercote3a42fb82004-08-03 18:08:50 +000095 }
nethercote71980f02004-01-24 18:18:54 +000096}
97
98
99/*====================================================================*/
sewardj71bc3cb2005-05-19 00:25:45 +0000100/*=== Command-line: variables, processing, etc ===*/
101/*====================================================================*/
102
103// See pub_{core,tool}_options.h for explanations of all these.
104
sewardj45f4e7c2005-09-27 19:20:21 +0000105static void usage_NORETURN ( Bool debug_help )
njn7cf0bd32002-06-08 13:36:03 +0000106{
sewardj7839d112007-11-20 19:45:03 +0000107 /* 'usage1' contains a %s for the name of the GDB executable, which
108 must be supplied when it is VG_(printf)'d. */
njn25e49d8e72002-09-23 09:36:25 +0000109 Char* usage1 =
njn00cfcfc2005-11-12 18:53:50 +0000110"usage: valgrind [options] prog-and-args\n"
njn25e49d8e72002-09-23 09:36:25 +0000111"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000112" common user options for all Valgrind tools, with defaults in [ ]:\n"
sewardjb5f6f512005-03-10 23:59:00 +0000113" --tool=<name> use the Valgrind tool named <name> [memcheck]\n"
nethercotea76368b2004-06-16 11:56:29 +0000114" -h --help show this message\n"
nethercote6c999f22004-01-31 22:55:15 +0000115" --help-debug show this message, plus debugging options\n"
njn25e49d8e72002-09-23 09:36:25 +0000116" --version show version\n"
njn25e49d8e72002-09-23 09:36:25 +0000117" -q --quiet run silently; only print error msgs\n"
118" -v --verbose be more verbose, incl counts of errors\n"
sewardj6e31f802007-11-17 22:29:25 +0000119" --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]\n"
120" --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n"
nethercote0d588502004-06-21 13:27:11 +0000121" --track-fds=no|yes track open file descriptors? [no]\n"
thughes6233a382004-08-21 11:10:44 +0000122" --time-stamp=no|yes add timestamps to log messages? [no]\n"
njnce545552005-07-25 22:36:52 +0000123" --log-fd=<number> log messages to file descriptor [2=stderr]\n"
njn374a36d2007-11-23 01:41:32 +0000124" --log-file=<file> log messages to <file>\n"
njnce545552005-07-25 22:36:52 +0000125" --log-socket=ipaddr:port log messages to socket ipaddr:port\n"
nethercote2b0793f2003-12-02 10:41:18 +0000126"\n"
127" uncommon user options for all Valgrind tools:\n"
nethercote0d588502004-06-21 13:27:11 +0000128" --run-libc-freeres=no|yes free up glibc memory at exit? [yes]\n"
njn628add62005-11-12 18:21:40 +0000129" --sim-hints=hint1,hint2,... known hints:\n"
sewardj19617ae2005-10-20 01:09:57 +0000130" lax-ioctls, enable-outer [none]\n"
sewardjb1131a82005-03-19 15:12:21 +0000131" --show-emwarns=no|yes show warnings about emulation limits? [no]\n"
sewardj6c3a2192005-07-24 07:00:45 +0000132" --smc-check=none|stack|all checks for self-modifying code: none,\n"
133" only for code found in stacks, or all [stack]\n"
sewardj3c3f0c12005-11-08 15:52:36 +0000134" --kernel-variant=variant1,variant2,... known variants: bproc [none]\n"
135" handle non-standard kernel variants\n"
sewardj04eb1092008-12-21 10:45:55 +0000136" --read-var-info=yes|no read debug info on stack and global variables\n"
137" and use it to print better error messages in\n"
138" tools that make use of it (Memcheck, Helgrind)\n"
njn25e49d8e72002-09-23 09:36:25 +0000139"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000140" user options for Valgrind tools that report errors:\n"
njnca54af32006-04-16 10:25:43 +0000141" --xml=yes all output is in XML (some tools only)\n"
njnc8ec9f82005-07-20 03:03:28 +0000142" --xml-user-comment=STR copy STR verbatim to XML output\n"
nethercote2b0793f2003-12-02 10:41:18 +0000143" --demangle=no|yes automatically demangle C++ names? [yes]\n"
njn20b4a152005-10-19 22:39:40 +0000144" --num-callers=<number> show <number> callers in stack traces [12]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000145" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
sewardjb9779082006-05-12 23:50:15 +0000146" --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000147" --show-below-main=no|yes continue stack traces below main() [no]\n"
148" --suppressions=<filename> suppress errors described in <filename>\n"
sewardjd153fae2005-01-10 17:24:47 +0000149" --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000150" --db-attach=no|yes start debugger when errors detected? [no]\n"
sewardj7839d112007-11-20 19:45:03 +0000151" --db-command=<command> command to start debugger [%s -nw %%f %%p]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000152" --input-fd=<number> file descriptor for input [0=stdin]\n"
sewardj97724e52005-04-02 23:40:59 +0000153" --max-stackframe=<number> assume stack switch for SP changes larger\n"
154" than <number> bytes [2000000]\n"
sewardj95d86c02007-12-18 01:49:23 +0000155" --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
156" [use current 'ulimit' value]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000157"\n";
njn7cf0bd32002-06-08 13:36:03 +0000158
njn25e49d8e72002-09-23 09:36:25 +0000159 Char* usage2 =
160"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000161" debugging options for all Valgrind tools:\n"
njn25e49d8e72002-09-23 09:36:25 +0000162" --sanity-level=<number> level of sanity checking to do [1]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000163" --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
164" --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
sewardj33afdb52006-01-17 02:36:40 +0000165" --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
njn25e49d8e72002-09-23 09:36:25 +0000166" --trace-syscalls=no|yes show all system calls? [no]\n"
167" --trace-signals=no|yes show signal handling details? [no]\n"
168" --trace-symtab=no|yes show symbol table details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000169" --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
sewardjce058b02005-05-01 08:55:38 +0000170" --trace-cfi=no|yes show call-frame-info details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000171" --debug-dump=syms mimic /usr/bin/readelf --syms\n"
172" --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
173" --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
sewardj0ec07f32006-01-12 12:32:32 +0000174" --trace-redir=no|yes show redirection details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000175" --trace-sched=no|yes show thread scheduler details? [no]\n"
sewardj9c606bd2008-09-18 18:12:50 +0000176" --profile-heap=no|yes profile Valgrind's own space use\n"
jsgf855d93d2003-10-13 22:26:55 +0000177" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
sewardj17c11042006-10-15 01:26:40 +0000178" --sym-offsets=yes|no show syms in form 'name+offset' ? [no]\n"
sewardjb5f6f512005-03-10 23:59:00 +0000179" --command-line-only=no|yes only use command line options [no]\n"
njn613812e2005-03-11 04:57:30 +0000180"\n"
181" --vex-iropt-verbosity 0 .. 9 [0]\n"
182" --vex-iropt-level 0 .. 2 [2]\n"
183" --vex-iropt-precise-memory-exns [no]\n"
sewardj8b635a42004-11-22 19:01:47 +0000184" --vex-iropt-unroll-thresh 0 .. 400 [120]\n"
185" --vex-guest-max-insns 1 .. 100 [50]\n"
186" --vex-guest-chase-thresh 0 .. 99 [10]\n"
187"\n"
sewardjfa8ec112005-01-19 11:55:34 +0000188" --trace-flags and --profile-flags values (omit the middle space):\n"
sewardj2a99cf62004-11-24 10:44:19 +0000189" 1000 0000 show conversion into IR\n"
190" 0100 0000 show after initial opt\n"
191" 0010 0000 show after instrumentation\n"
192" 0001 0000 show after second opt\n"
193" 0000 1000 show after tree building\n"
194" 0000 0100 show selecting insns\n"
195" 0000 0010 show after reg-alloc\n"
196" 0000 0001 show final assembly\n"
njn33dbfce2006-06-02 22:58:34 +0000197" (Nb: you need --trace-notbelow with --trace-flags for full details)\n"
sewardj2a99cf62004-11-24 10:44:19 +0000198"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000199" debugging options for Valgrind tools that report errors\n"
200" --dump-error=<number> show translation for basic block associated\n"
201" with <number>'th error context [0=show none]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000202"\n";
njn3e884182003-04-15 13:03:23 +0000203
204 Char* usage3 =
205"\n"
nethercote71980f02004-01-24 18:18:54 +0000206" Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
njn25e49d8e72002-09-23 09:36:25 +0000207"\n"
sewardj4d474d02008-02-11 11:34:59 +0000208" Valgrind is Copyright (C) 2000-2008 Julian Seward et al.\n"
njn25e49d8e72002-09-23 09:36:25 +0000209" and licensed under the GNU General Public License, version 2.\n"
210" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
njnd04b7c62002-10-03 14:05:52 +0000211"\n"
nethercote137bc552003-11-14 17:47:54 +0000212" Tools are copyright and licensed by their authors. See each\n"
213" tool's start-up message for more information.\n"
njn25e49d8e72002-09-23 09:36:25 +0000214"\n";
njn7cf0bd32002-06-08 13:36:03 +0000215
sewardj12373b12007-11-20 21:38:14 +0000216 Char* gdb_path = GDB_PATH;
sewardj12373b12007-11-20 21:38:14 +0000217
njnbe9b47b2005-05-15 16:22:58 +0000218 // Ensure the message goes to stdout
219 VG_(clo_log_fd) = 1;
220 vg_assert( !VG_(logging_to_socket) );
221
sewardj7839d112007-11-20 19:45:03 +0000222 /* 'usage1' expects one char* argument */
sewardj12373b12007-11-20 21:38:14 +0000223 VG_(printf)(usage1, gdb_path);
fitzhardinge98abfc72003-12-16 02:05:15 +0000224 if (VG_(details).name) {
225 VG_(printf)(" user options for %s:\n", VG_(details).name);
fitzhardinge98abfc72003-12-16 02:05:15 +0000226 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000227 VG_TDICT_CALL(tool_print_usage);
fitzhardinge98abfc72003-12-16 02:05:15 +0000228 else
229 VG_(printf)(" (none)\n");
230 }
nethercote6c999f22004-01-31 22:55:15 +0000231 if (debug_help) {
sewardjbbaef872008-11-01 23:55:32 +0000232 VG_(printf)("%s", usage2);
fitzhardinge98abfc72003-12-16 02:05:15 +0000233
nethercote6c999f22004-01-31 22:55:15 +0000234 if (VG_(details).name) {
235 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
236
237 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000238 VG_TDICT_CALL(tool_print_debug_usage);
nethercote6c999f22004-01-31 22:55:15 +0000239 else
240 VG_(printf)(" (none)\n");
241 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000242 }
nethercote421281e2003-11-20 16:20:55 +0000243 VG_(printf)(usage3, VG_BUGS_TO);
nethercotef4928da2004-06-15 10:54:40 +0000244 VG_(exit)(0);
njn7cf0bd32002-06-08 13:36:03 +0000245}
sewardjde4a1d02002-03-22 01:27:54 +0000246
sewardjde4a1d02002-03-22 01:27:54 +0000247
sewardj95d86c02007-12-18 01:49:23 +0000248/* Peer at previously set up VG_(args_for_valgrind) and do some
249 minimal command line processing that must happen early on:
sewardj45f4e7c2005-09-27 19:20:21 +0000250
sewardj95d86c02007-12-18 01:49:23 +0000251 - show the version string, if requested (-v)
252 - extract any request for help (--help, -h, --help-debug)
253 - get the toolname (--tool=)
254 - set VG_(clo_max_stackframe) (--max-stackframe=)
255 - set VG_(clo_main_stacksize) (--main-stacksize=)
256
257 That's all it does. The main command line processing is done below
258 by main_process_cmd_line_options. Note that
259 main_process_cmd_line_options has to handle but ignore the ones we
260 have handled here.
261*/
262static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
263 /*OUT*/HChar** tool )
sewardj45f4e7c2005-09-27 19:20:21 +0000264{
265 UInt i;
266 HChar* str;
sewardj8b635a42004-11-22 19:01:47 +0000267
sewardj14c7cc52007-02-25 15:08:24 +0000268 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000269
sewardj14c7cc52007-02-25 15:08:24 +0000270 /* parse the options we have (only the options we care about now) */
271 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
272
273 str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000274 vg_assert(str);
nethercote71980f02004-01-24 18:18:54 +0000275
sewardj45f4e7c2005-09-27 19:20:21 +0000276 if (VG_STREQ(str, "--version")) {
njn2e9f3f32005-10-26 16:17:46 +0000277 // Ensure the version string goes to stdout
278 VG_(clo_log_fd) = 1;
sewardj45f4e7c2005-09-27 19:20:21 +0000279 VG_(printf)("valgrind-" VERSION "\n");
280 VG_(exit)(0);
281
282 } else if (VG_CLO_STREQ(str, "--help") ||
283 VG_CLO_STREQ(str, "-h")) {
nethercote6c999f22004-01-31 22:55:15 +0000284 *need_help = 1;
285
sewardj45f4e7c2005-09-27 19:20:21 +0000286 } else if (VG_CLO_STREQ(str, "--help-debug")) {
nethercote6c999f22004-01-31 22:55:15 +0000287 *need_help = 2;
nethercote71980f02004-01-24 18:18:54 +0000288
sewardj45f4e7c2005-09-27 19:20:21 +0000289 // The tool has already been determined, but we need to know the name
290 // here.
291 } else if (VG_CLO_STREQN(7, str, "--tool=")) {
292 *tool = &str[7];
sewardj5bdfbd22007-12-15 22:13:05 +0000293
sewardj95d86c02007-12-18 01:49:23 +0000294 // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
295 // These are needed by VG_(ii_create_image), which happens
296 // before main_process_cmd_line_options().
297 }
298 else VG_NUM_CLO(str, "--max-stackframe", VG_(clo_max_stackframe))
299 else VG_NUM_CLO(str, "--main-stacksize", VG_(clo_main_stacksize));
sewardj5bdfbd22007-12-15 22:13:05 +0000300
nethercote71980f02004-01-24 18:18:54 +0000301 }
nethercote71980f02004-01-24 18:18:54 +0000302}
303
sewardj95d86c02007-12-18 01:49:23 +0000304/* The main processing for command line options. See comments above
305 on early_process_cmd_line_options.
306*/
307static Bool main_process_cmd_line_options( UInt* client_auxv,
308 const HChar* toolname )
nethercote71980f02004-01-24 18:18:54 +0000309{
njnda033f52005-12-19 21:27:58 +0000310 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
311 // and we cannot change it until we know what we are changing it to is
312 // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
sewardj92645592005-07-23 09:18:34 +0000313 SysRes sres;
njnda033f52005-12-19 21:27:58 +0000314 Int i, tmp_log_fd;
sewardj92645592005-07-23 09:18:34 +0000315 Int toolname_len = VG_(strlen)(toolname);
njnbe9b47b2005-05-15 16:22:58 +0000316 enum {
317 VgLogTo_Fd,
318 VgLogTo_File,
njnbe9b47b2005-05-15 16:22:58 +0000319 VgLogTo_Socket
320 } log_to = VgLogTo_Fd; // Where is logging output to be sent?
sewardjde4a1d02002-03-22 01:27:54 +0000321
nethercotee1730692003-11-20 10:38:07 +0000322 /* log to stderr by default, but usage message goes to stdout */
njnda033f52005-12-19 21:27:58 +0000323 tmp_log_fd = 2;
sewardjde4a1d02002-03-22 01:27:54 +0000324
sewardj19d81412002-06-03 01:10:40 +0000325 /* Check for sane path in ./configure --prefix=... */
fitzhardinge98abfc72003-12-16 02:05:15 +0000326 if (VG_LIBDIR[0] != '/')
sewardj17c11042006-10-15 01:26:40 +0000327 VG_(err_config_error)("Please use absolute paths in "
328 "./configure --prefix=... or --libdir=...");
sewardj38170912002-05-10 21:07:22 +0000329
sewardj14c7cc52007-02-25 15:08:24 +0000330 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000331
sewardj14c7cc52007-02-25 15:08:24 +0000332 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
333
334 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000335 HChar* colon = arg;
nethercote71980f02004-01-24 18:18:54 +0000336
njn1274d242007-03-26 23:38:42 +0000337 // Look for a colon in the option name.
thughes3bfd5a02004-07-18 08:05:44 +0000338 while (*colon && *colon != ':' && *colon != '=')
339 colon++;
nethercote71980f02004-01-24 18:18:54 +0000340
njn1274d242007-03-26 23:38:42 +0000341 // Does it have the form "--toolname:foo"? We have to do it at the start
342 // in case someone has combined a prefix with a core-specific option,
343 // eg. "--memcheck:verbose".
thughes3bfd5a02004-07-18 08:05:44 +0000344 if (*colon == ':') {
nethercote71980f02004-01-24 18:18:54 +0000345 if (VG_CLO_STREQN(2, arg, "--") &&
346 VG_CLO_STREQN(toolname_len, arg+2, toolname) &&
347 VG_CLO_STREQN(1, arg+2+toolname_len, ":"))
348 {
njn1274d242007-03-26 23:38:42 +0000349 // Prefix matches, convert "--toolname:foo" to "--foo".
350 // Two things to note:
351 // - We cannot modify the option in-place. If we did, and then
352 // a child was spawned with --trace-children=yes, the
353 // now-non-prefixed option would be passed and could screw up
354 // the child.
355 // - We create copies, and never free them. Why? Non-prefixed
356 // options hang around forever, so tools need not make copies
357 // of strings within them. We need to have the same behaviour
358 // for prefixed options. The pointer to the copy will be lost
359 // once we leave this function (although a tool may keep a
360 // pointer into it), but the space wasted is insignificant.
361 // (In bug #142197, the copies were being freed, which caused
362 // problems for tools that reasonably assumed that arguments
363 // wouldn't disappear on them.)
nethercote71980f02004-01-24 18:18:54 +0000364 if (0)
365 VG_(printf)("tool-specific arg: %s\n", arg);
sewardj9c606bd2008-09-18 18:12:50 +0000366 arg = VG_(strdup)("main.mpclo.1", arg + toolname_len + 1);
nethercote71980f02004-01-24 18:18:54 +0000367 arg[0] = '-';
368 arg[1] = '-';
369
370 } else {
371 // prefix doesn't match, skip to next arg
372 continue;
373 }
374 }
375
fitzhardinge98abfc72003-12-16 02:05:15 +0000376 /* Ignore these options - they've already been handled */
njn1274d242007-03-26 23:38:42 +0000377 if (VG_CLO_STREQN( 7, arg, "--tool=")) { }
378 else if (VG_CLO_STREQN(20, arg, "--command-line-only=")) { }
379 else if (VG_CLO_STREQ(arg, "--")) { }
380 else if (VG_CLO_STREQ(arg, "-d")) { }
nethercote27fec902004-06-16 21:26:32 +0000381
nethercote71980f02004-01-24 18:18:54 +0000382 else if (VG_CLO_STREQ(arg, "-v") ||
383 VG_CLO_STREQ(arg, "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000384 VG_(clo_verbosity)++;
nethercote27fec902004-06-16 21:26:32 +0000385
nethercote71980f02004-01-24 18:18:54 +0000386 else if (VG_CLO_STREQ(arg, "-q") ||
387 VG_CLO_STREQ(arg, "--quiet"))
sewardjde4a1d02002-03-22 01:27:54 +0000388 VG_(clo_verbosity)--;
389
sewardj71bc3cb2005-05-19 00:25:45 +0000390 else VG_BOOL_CLO(arg, "--xml", VG_(clo_xml))
njn45270a22005-03-27 01:00:11 +0000391 else VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach))
392 else VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle))
393 else VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit))
sewardjb9779082006-05-12 23:50:15 +0000394 else VG_NUM_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode))
njn45270a22005-03-27 01:00:11 +0000395 else VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns))
sewardj95d86c02007-12-18 01:49:23 +0000396
397 /* The next two are already done in
398 early_process_cmd_line_options, but we need to redundantly
399 handle them again, so they do not get rejected as invalid. */
sewardj5abcc0b2007-11-30 17:50:44 +0000400 else VG_NUM_CLO (arg, "--max-stackframe", VG_(clo_max_stackframe))
sewardj95d86c02007-12-18 01:49:23 +0000401 else VG_NUM_CLO (arg, "--main-stacksize", VG_(clo_main_stacksize))
402
njn45270a22005-03-27 01:00:11 +0000403 else VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres))
404 else VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main))
405 else VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp))
406 else VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds))
407 else VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children))
sewardj6e31f802007-11-17 22:29:25 +0000408 else VG_BOOL_CLO(arg, "--child-silent-after-fork",
409 VG_(clo_child_silent_after_fork))
njn45270a22005-03-27 01:00:11 +0000410 else VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched))
411 else VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals))
412 else VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab))
sewardjf767d962007-02-12 17:47:14 +0000413 else VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt))
sewardjce058b02005-05-01 08:55:38 +0000414 else VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi))
sewardjf767d962007-02-12 17:47:14 +0000415 else VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms))
416 else VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line))
417 else VG_XACT_CLO(arg, "--debug-dump=frames", VG_(clo_debug_dump_frames))
njn45270a22005-03-27 01:00:11 +0000418 else VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir))
sewardjf767d962007-02-12 17:47:14 +0000419
njn45270a22005-03-27 01:00:11 +0000420 else VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls))
njn45270a22005-03-27 01:00:11 +0000421 else VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb))
njn45270a22005-03-27 01:00:11 +0000422 else VG_STR_CLO (arg, "--db-command", VG_(clo_db_command))
njn628add62005-11-12 18:21:40 +0000423 else VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints))
sewardj12ab7652006-10-17 02:10:42 +0000424 else VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets))
sewardjb8b79ad2008-03-03 01:35:41 +0000425 else VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info))
sewardjde4a1d02002-03-22 01:27:54 +0000426
njn45270a22005-03-27 01:00:11 +0000427 else VG_NUM_CLO (arg, "--dump-error", VG_(clo_dump_error))
428 else VG_NUM_CLO (arg, "--input-fd", VG_(clo_input_fd))
429 else VG_NUM_CLO (arg, "--sanity-level", VG_(clo_sanity_level))
430 else VG_BNUM_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
431 VG_DEEPEST_BACKTRACE)
sewardjde4a1d02002-03-22 01:27:54 +0000432
sewardj6c3a2192005-07-24 07:00:45 +0000433 else if (VG_CLO_STREQ(arg, "--smc-check=none"))
434 VG_(clo_smc_check) = Vg_SmcNone;
435 else if (VG_CLO_STREQ(arg, "--smc-check=stack"))
436 VG_(clo_smc_check) = Vg_SmcStack;
437 else if (VG_CLO_STREQ(arg, "--smc-check=all"))
438 VG_(clo_smc_check) = Vg_SmcAll;
sewardj26412bd2005-07-07 10:05:05 +0000439
sewardj94c8eb42008-09-19 20:13:39 +0000440 else if (VG_CLO_STREQ(arg, "--profile-heap=no"))
441 ; /* We already handled it right at the top of valgrind_main.
442 Just ignore. */
443 else if (VG_CLO_STREQ(arg, "--profile-heap=yes"))
444 ; /* ditto */
445
sewardjce5a5662005-10-06 03:19:49 +0000446 else VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant))
447
njn45270a22005-03-27 01:00:11 +0000448 else VG_BNUM_CLO(arg, "--vex-iropt-verbosity",
sewardj8b635a42004-11-22 19:01:47 +0000449 VG_(clo_vex_control).iropt_verbosity, 0, 10)
njn45270a22005-03-27 01:00:11 +0000450 else VG_BNUM_CLO(arg, "--vex-iropt-level",
sewardj8b635a42004-11-22 19:01:47 +0000451 VG_(clo_vex_control).iropt_level, 0, 2)
njn45270a22005-03-27 01:00:11 +0000452 else VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
sewardj8b635a42004-11-22 19:01:47 +0000453 VG_(clo_vex_control).iropt_precise_memory_exns)
njn45270a22005-03-27 01:00:11 +0000454 else VG_BNUM_CLO(arg, "--vex-iropt-unroll-thresh",
sewardj8b635a42004-11-22 19:01:47 +0000455 VG_(clo_vex_control).iropt_unroll_thresh, 0, 400)
njn45270a22005-03-27 01:00:11 +0000456 else VG_BNUM_CLO(arg, "--vex-guest-max-insns",
sewardj8b635a42004-11-22 19:01:47 +0000457 VG_(clo_vex_control).guest_max_insns, 1, 100)
njn45270a22005-03-27 01:00:11 +0000458 else VG_BNUM_CLO(arg, "--vex-guest-chase-thresh",
sewardj8b635a42004-11-22 19:01:47 +0000459 VG_(clo_vex_control).guest_chase_thresh, 0, 99)
460
nethercotef8548672004-06-21 12:42:35 +0000461 else if (VG_CLO_STREQN(9, arg, "--log-fd=")) {
njnbe9b47b2005-05-15 16:22:58 +0000462 log_to = VgLogTo_Fd;
nethercotef8548672004-06-21 12:42:35 +0000463 VG_(clo_log_name) = NULL;
njnda033f52005-12-19 21:27:58 +0000464 tmp_log_fd = (Int)VG_(atoll)(&arg[9]);
sewardj4cf05692002-10-27 20:28:29 +0000465 }
466
nethercotef8548672004-06-21 12:42:35 +0000467 else if (VG_CLO_STREQN(11, arg, "--log-file=")) {
njnbe9b47b2005-05-15 16:22:58 +0000468 log_to = VgLogTo_File;
nethercotef8548672004-06-21 12:42:35 +0000469 VG_(clo_log_name) = &arg[11];
sewardj4cf05692002-10-27 20:28:29 +0000470 }
njnd6bc3c32005-03-27 00:44:31 +0000471
nethercotef8548672004-06-21 12:42:35 +0000472 else if (VG_CLO_STREQN(13, arg, "--log-socket=")) {
njnbe9b47b2005-05-15 16:22:58 +0000473 log_to = VgLogTo_Socket;
nethercotef8548672004-06-21 12:42:35 +0000474 VG_(clo_log_name) = &arg[13];
sewardj73cf3bc2002-11-03 03:20:15 +0000475 }
476
sewardj768db0e2005-07-19 14:18:56 +0000477 else if (VG_CLO_STREQN(19, arg, "--xml-user-comment=")) {
478 VG_(clo_xml_user_comment) = &arg[19];
479 }
480
nethercote71980f02004-01-24 18:18:54 +0000481 else if (VG_CLO_STREQN(15, arg, "--suppressions=")) {
sewardjde4a1d02002-03-22 01:27:54 +0000482 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njn25e49d8e72002-09-23 09:36:25 +0000483 VG_(message)(Vg_UserMsg, "Too many suppression files specified.");
sewardjde4a1d02002-03-22 01:27:54 +0000484 VG_(message)(Vg_UserMsg,
485 "Increase VG_CLO_MAX_SFILES and recompile.");
sewardj17c11042006-10-15 01:26:40 +0000486 VG_(err_bad_option)(arg);
sewardjde4a1d02002-03-22 01:27:54 +0000487 }
nethercote71980f02004-01-24 18:18:54 +0000488 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &arg[15];
sewardjde4a1d02002-03-22 01:27:54 +0000489 VG_(clo_n_suppressions)++;
490 }
sewardjde4a1d02002-03-22 01:27:54 +0000491
sewardjfa8ec112005-01-19 11:55:34 +0000492 /* "stuvwxyz" --> stuvwxyz (binary) */
493 else if (VG_CLO_STREQN(14, arg, "--trace-flags=")) {
494 Int j;
495 char* opt = & arg[14];
496
497 if (8 != VG_(strlen)(opt)) {
498 VG_(message)(Vg_UserMsg,
499 "--trace-flags argument must have 8 digits");
sewardj17c11042006-10-15 01:26:40 +0000500 VG_(err_bad_option)(arg);
sewardjfa8ec112005-01-19 11:55:34 +0000501 }
502 for (j = 0; j < 8; j++) {
503 if ('0' == opt[j]) { /* do nothing */ }
504 else if ('1' == opt[j]) VG_(clo_trace_flags) |= (1 << (7-j));
505 else {
506 VG_(message)(Vg_UserMsg, "--trace-flags argument can only "
507 "contain 0s and 1s");
sewardj17c11042006-10-15 01:26:40 +0000508 VG_(err_bad_option)(arg);
sewardjfa8ec112005-01-19 11:55:34 +0000509 }
510 }
511 }
512
513 /* "stuvwxyz" --> stuvwxyz (binary) */
514 else if (VG_CLO_STREQN(16, arg, "--profile-flags=")) {
njn25e49d8e72002-09-23 09:36:25 +0000515 Int j;
nethercote71980f02004-01-24 18:18:54 +0000516 char* opt = & arg[16];
njn25e49d8e72002-09-23 09:36:25 +0000517
sewardj2a99cf62004-11-24 10:44:19 +0000518 if (8 != VG_(strlen)(opt)) {
njn25e49d8e72002-09-23 09:36:25 +0000519 VG_(message)(Vg_UserMsg,
sewardjfa8ec112005-01-19 11:55:34 +0000520 "--profile-flags argument must have 8 digits");
sewardj17c11042006-10-15 01:26:40 +0000521 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000522 }
sewardj8b635a42004-11-22 19:01:47 +0000523 for (j = 0; j < 8; j++) {
njn25e49d8e72002-09-23 09:36:25 +0000524 if ('0' == opt[j]) { /* do nothing */ }
sewardjfa8ec112005-01-19 11:55:34 +0000525 else if ('1' == opt[j]) VG_(clo_profile_flags) |= (1 << (7-j));
njn25e49d8e72002-09-23 09:36:25 +0000526 else {
sewardjfa8ec112005-01-19 11:55:34 +0000527 VG_(message)(Vg_UserMsg, "--profile-flags argument can only "
njn25e49d8e72002-09-23 09:36:25 +0000528 "contain 0s and 1s");
sewardj17c11042006-10-15 01:26:40 +0000529 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000530 }
531 }
532 }
sewardjde4a1d02002-03-22 01:27:54 +0000533
njn45270a22005-03-27 01:00:11 +0000534 else VG_NUM_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow))
sewardjc771b292004-11-30 18:55:21 +0000535
sewardjd153fae2005-01-10 17:24:47 +0000536 else if (VG_CLO_STREQ(arg, "--gen-suppressions=no"))
537 VG_(clo_gen_suppressions) = 0;
538 else if (VG_CLO_STREQ(arg, "--gen-suppressions=yes"))
539 VG_(clo_gen_suppressions) = 1;
540 else if (VG_CLO_STREQ(arg, "--gen-suppressions=all"))
541 VG_(clo_gen_suppressions) = 2;
542
nethercote71980f02004-01-24 18:18:54 +0000543 else if ( ! VG_(needs).command_line_options
njn51d827b2005-05-09 01:02:08 +0000544 || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
sewardj17c11042006-10-15 01:26:40 +0000545 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000546 }
sewardjde4a1d02002-03-22 01:27:54 +0000547 }
548
sewardj998d40d2004-12-06 14:24:52 +0000549 /* Make VEX control parameters sane */
550
551 if (VG_(clo_vex_control).guest_chase_thresh
552 >= VG_(clo_vex_control).guest_max_insns)
553 VG_(clo_vex_control).guest_chase_thresh
554 = VG_(clo_vex_control).guest_max_insns - 1;
555
556 if (VG_(clo_vex_control).guest_chase_thresh < 0)
557 VG_(clo_vex_control).guest_chase_thresh = 0;
558
559 /* Check various option values */
nethercote27fec902004-06-16 21:26:32 +0000560
njnf9ebf672003-05-12 21:41:30 +0000561 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +0000562 VG_(clo_verbosity) = 0;
563
njnbe9b47b2005-05-15 16:22:58 +0000564 if (VG_(clo_gen_suppressions) > 0 &&
565 !VG_(needs).core_errors && !VG_(needs).tool_errors) {
566 VG_(message)(Vg_UserMsg,
567 "Can't use --gen-suppressions= with this tool,");
568 VG_(message)(Vg_UserMsg,
569 "as it doesn't generate errors.");
sewardj17c11042006-10-15 01:26:40 +0000570 VG_(err_bad_option)("--gen-suppressions=");
njnbe9b47b2005-05-15 16:22:58 +0000571 }
572
sewardj71bc3cb2005-05-19 00:25:45 +0000573 /* If we've been asked to emit XML, mash around various other
574 options so as to constrain the output somewhat, and to remove
575 any need for user input during the run. */
576 if (VG_(clo_xml)) {
577 /* Disable suppression generation (requires user input) */
578 VG_(clo_gen_suppressions) = 0;
579 /* Disable attaching to GDB (requires user input) */
580 VG_(clo_db_attach) = False;
581 /* Set a known verbosity level */
582 VG_(clo_verbosity) = 1;
583 /* Disable error limits (this might be a bad idea!) */
584 VG_(clo_error_limit) = False;
585 /* Disable emulation warnings */
586 VG_(clo_show_emwarns) = False;
587 /* Disable waiting for GDB to debug Valgrind */
588 VG_(clo_wait_for_gdb) = False;
589 /* No file-descriptor leak checking yet */
590 VG_(clo_track_fds) = False;
sewardj21f7f0c2005-07-06 19:46:48 +0000591 /* Disable timestamped output */
592 VG_(clo_time_stamp) = False;
sewardj9c606bd2008-09-18 18:12:50 +0000593 /* Disable heap profiling, since that prints lots of stuff. */
594 VG_(clo_profile_heap) = False;
sewardj71bc3cb2005-05-19 00:25:45 +0000595 /* Also, we want to set options for the leak checker, but that
596 will have to be done in Memcheck's flag-handling code, not
597 here. */
598 }
599
njnbe9b47b2005-05-15 16:22:58 +0000600 /* All non-logging-related options have been checked. If the logging
601 option specified is ok, we can switch to it, as we know we won't
602 have to generate any other command-line-related error messages.
603 (So far we should be still attached to stderr, so we can show on
604 the terminal any problems to do with processing command line
605 opts.)
606
607 So set up logging now. After this is done, VG_(clo_log_fd)
sewardj4cf05692002-10-27 20:28:29 +0000608 should be connected to whatever sink has been selected, and we
609 indiscriminately chuck stuff into it without worrying what the
610 nature of it is. Oh the wonder of Unix streams. */
611
njnbe9b47b2005-05-15 16:22:58 +0000612 vg_assert(VG_(clo_log_fd) == 2 /* stderr */);
613 vg_assert(VG_(logging_to_socket) == False);
sewardj4cf05692002-10-27 20:28:29 +0000614
njnbe9b47b2005-05-15 16:22:58 +0000615 switch (log_to) {
sewardj73cf3bc2002-11-03 03:20:15 +0000616
sewardj4cf05692002-10-27 20:28:29 +0000617 case VgLogTo_Fd:
nethercotef8548672004-06-21 12:42:35 +0000618 vg_assert(VG_(clo_log_name) == NULL);
sewardj4cf05692002-10-27 20:28:29 +0000619 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000620
sewardj4cf05692002-10-27 20:28:29 +0000621 case VgLogTo_File: {
njn374a36d2007-11-23 01:41:32 +0000622 Char* logfilename;
jsgff3c3f1a2003-10-14 22:13:28 +0000623
nethercotef8548672004-06-21 12:42:35 +0000624 vg_assert(VG_(clo_log_name) != NULL);
625 vg_assert(VG_(strlen)(VG_(clo_log_name)) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +0000626
njn374a36d2007-11-23 01:41:32 +0000627 // Nb: we overwrite an existing file of this name without asking
628 // any questions.
629 logfilename = VG_(expand_file_name)("--log-file", VG_(clo_log_name));
630 sres = VG_(open)(logfilename,
njnda033f52005-12-19 21:27:58 +0000631 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
632 VKI_S_IRUSR|VKI_S_IWUSR);
sewardj92645592005-07-23 09:18:34 +0000633 if (!sres.isError) {
sewardj12ab7652006-10-17 02:10:42 +0000634 tmp_log_fd = sres.res;
njnbe9b47b2005-05-15 16:22:58 +0000635 } else {
sewardj603d4102005-01-11 14:01:02 +0000636 VG_(message)(Vg_UserMsg,
njn374a36d2007-11-23 01:41:32 +0000637 "Can't create log file '%s' (%s); giving up!",
638 logfilename, VG_(strerror)(sres.err));
sewardj17c11042006-10-15 01:26:40 +0000639 VG_(err_bad_option)(
njn374a36d2007-11-23 01:41:32 +0000640 "--log-file=<file> (didn't work out for some reason.)");
sewardj603d4102005-01-11 14:01:02 +0000641 /*NOTREACHED*/
njn374a36d2007-11-23 01:41:32 +0000642 }
sewardj603d4102005-01-11 14:01:02 +0000643 break; /* switch (VG_(clo_log_to)) */
sewardj73cf3bc2002-11-03 03:20:15 +0000644 }
645
646 case VgLogTo_Socket: {
nethercotef8548672004-06-21 12:42:35 +0000647 vg_assert(VG_(clo_log_name) != NULL);
648 vg_assert(VG_(strlen)(VG_(clo_log_name)) <= 900); /* paranoia */
njnda033f52005-12-19 21:27:58 +0000649 tmp_log_fd = VG_(connect_via_socket)( VG_(clo_log_name) );
650 if (tmp_log_fd == -1) {
sewardj73cf3bc2002-11-03 03:20:15 +0000651 VG_(message)(Vg_UserMsg,
nethercotef8548672004-06-21 12:42:35 +0000652 "Invalid --log-socket=ipaddr or --log-socket=ipaddr:port spec");
sewardj73cf3bc2002-11-03 03:20:15 +0000653 VG_(message)(Vg_UserMsg,
njn02bc4b82005-05-15 17:28:26 +0000654 "of '%s'; giving up!", VG_(clo_log_name) );
sewardj17c11042006-10-15 01:26:40 +0000655 VG_(err_bad_option)(
nethercotef8548672004-06-21 12:42:35 +0000656 "--log-socket=");
njnbe9b47b2005-05-15 16:22:58 +0000657 /*NOTREACHED*/
sewardj4cf05692002-10-27 20:28:29 +0000658 }
njnda033f52005-12-19 21:27:58 +0000659 if (tmp_log_fd == -2) {
sewardj73cf3bc2002-11-03 03:20:15 +0000660 VG_(message)(Vg_UserMsg,
njn02bc4b82005-05-15 17:28:26 +0000661 "valgrind: failed to connect to logging server '%s'.",
nethercotef8548672004-06-21 12:42:35 +0000662 VG_(clo_log_name) );
sewardj570f8902002-11-03 11:44:36 +0000663 VG_(message)(Vg_UserMsg,
664 "Log messages will sent to stderr instead." );
665 VG_(message)(Vg_UserMsg,
666 "" );
667 /* We don't change anything here. */
njnbe9b47b2005-05-15 16:22:58 +0000668 vg_assert(VG_(clo_log_fd) == 2);
njnda033f52005-12-19 21:27:58 +0000669 tmp_log_fd = 2;
sewardj570f8902002-11-03 11:44:36 +0000670 } else {
njnda033f52005-12-19 21:27:58 +0000671 vg_assert(tmp_log_fd > 0);
njnbe9b47b2005-05-15 16:22:58 +0000672 VG_(logging_to_socket) = True;
sewardj570f8902002-11-03 11:44:36 +0000673 }
sewardj73cf3bc2002-11-03 03:20:15 +0000674 break;
675 }
sewardj4cf05692002-10-27 20:28:29 +0000676 }
677
sewardj71bc3cb2005-05-19 00:25:45 +0000678
679 /* Check that the requested tool actually supports XML output. */
njnca54af32006-04-16 10:25:43 +0000680 if (VG_(clo_xml) && !VG_(needs).xml_output) {
sewardj71bc3cb2005-05-19 00:25:45 +0000681 VG_(clo_xml) = False;
682 VG_(message)(Vg_UserMsg,
njnca54af32006-04-16 10:25:43 +0000683 "%s does not support XML output.", VG_(details).name);
sewardj17c11042006-10-15 01:26:40 +0000684 VG_(err_bad_option)("--xml=yes");
sewardj71bc3cb2005-05-19 00:25:45 +0000685 /*NOTREACHED*/
686 }
687
njnda033f52005-12-19 21:27:58 +0000688 if (tmp_log_fd >= 0) {
689 // Move log_fd into the safe range, so it doesn't conflict with any app fds.
690 tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
691 if (tmp_log_fd < 0) {
692 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd into safe range, using stderr");
693 VG_(clo_log_fd) = 2; // stderr
694 } else {
695 VG_(clo_log_fd) = tmp_log_fd;
696 VG_(fcntl)(VG_(clo_log_fd), VKI_F_SETFD, VKI_FD_CLOEXEC);
697 }
698 } else {
699 // If they said --log-fd=-1, don't print anything. Plausible for use in
700 // regression testing suites that use client requests to count errors.
701 VG_(clo_log_fd) = tmp_log_fd;
jsgf855d93d2003-10-13 22:26:55 +0000702 }
703
sewardj45f4e7c2005-09-27 19:20:21 +0000704 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
705 (VG_(needs).core_errors || VG_(needs).tool_errors)) {
706 /* If we haven't reached the max number of suppressions, load
707 the default one. */
708 static const Char default_supp[] = "default.supp";
709 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
sewardj9c606bd2008-09-18 18:12:50 +0000710 Char *buf = VG_(arena_malloc)(VG_AR_CORE, "main.mpclo.2", len);
sewardj45f4e7c2005-09-27 19:20:21 +0000711 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
712 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
713 VG_(clo_n_suppressions)++;
714 }
sewardjde4a1d02002-03-22 01:27:54 +0000715
sewardj45f4e7c2005-09-27 19:20:21 +0000716 return (log_to == VgLogTo_Fd);
717}
718
sewardj4efbaa72008-06-04 06:51:58 +0000719// Write the name and value of log file qualifiers to the xml file.
720static void print_file_vars(Char* format)
721{
722 Int i = 0;
723
724 while (format[i]) {
725 if (format[i] == '%') {
726 // We saw a '%'. What's next...
727 i++;
728 if ('q' == format[i]) {
729 i++;
730 if ('{' == format[i]) {
731 // Get the env var name, print its contents.
732 Char* qualname;
733 Char* qual;
734 i++;
735 qualname = &format[i];
736 while (True) {
737 if ('}' == format[i]) {
738 // Temporarily replace the '}' with NUL to extract var
739 // name.
740 format[i] = 0;
741 qual = VG_(getenv)(qualname);
742 break;
743 }
744 i++;
745 }
746
barta0b6b2c2008-07-07 06:49:24 +0000747 VG_(message_no_f_c)(Vg_UserMsg,
748 "<logfilequalifier> <var>%t</var> "
749 "<value>%t</value> </logfilequalifier>",
750 qualname,qual);
sewardj4efbaa72008-06-04 06:51:58 +0000751 format[i] = '}';
752 i++;
753 }
754 }
755 } else {
756 i++;
757 }
758 }
759}
760
sewardj45f4e7c2005-09-27 19:20:21 +0000761
762/*====================================================================*/
763/*=== Printing the preamble ===*/
764/*====================================================================*/
765
766/* Ok, the logging sink is running now. Print a suitable preamble.
767 If logging to file or a socket, write details of parent PID and
768 command line args, to help people trying to interpret the
769 results of a run which encompasses multiple processes. */
770static void print_preamble(Bool logging_to_fd, const char* toolname)
771{
tom60a4b0b2005-10-12 10:45:27 +0000772 HChar* xpre = VG_(clo_xml) ? " <line>" : "";
773 HChar* xpost = VG_(clo_xml) ? "</line>" : "";
774 Int i;
775
sewardj14c7cc52007-02-25 15:08:24 +0000776 vg_assert( VG_(args_for_client) );
777 vg_assert( VG_(args_for_valgrind) );
sewardj99a2ceb2007-11-09 12:30:36 +0000778 vg_assert( toolname );
sewardj14c7cc52007-02-25 15:08:24 +0000779
sewardj71bc3cb2005-05-19 00:25:45 +0000780 if (VG_(clo_xml)) {
sewardj8665d8e2005-06-01 17:35:23 +0000781 VG_(message)(Vg_UserMsg, "<?xml version=\"1.0\"?>");
782 VG_(message)(Vg_UserMsg, "");
sewardj71bc3cb2005-05-19 00:25:45 +0000783 VG_(message)(Vg_UserMsg, "<valgrindoutput>");
784 VG_(message)(Vg_UserMsg, "");
sewardj7cf4e6b2008-05-01 20:24:26 +0000785 VG_(message)(Vg_UserMsg, "<protocolversion>3</protocolversion>");
sewardj71bc3cb2005-05-19 00:25:45 +0000786 VG_(message)(Vg_UserMsg, "");
787 }
788
sewardj83adf412002-05-01 01:25:45 +0000789 if (VG_(clo_verbosity > 0)) {
sewardjd7bddad2005-06-13 16:48:32 +0000790
791 if (VG_(clo_xml))
792 VG_(message)(Vg_UserMsg, "<preamble>");
793
nethercote996901a2004-08-03 13:29:09 +0000794 /* Tool details */
sewardj71bc3cb2005-05-19 00:25:45 +0000795 VG_(message)(Vg_UserMsg, "%s%s%s%s, %s.%s",
796 xpre,
njnd04b7c62002-10-03 14:05:52 +0000797 VG_(details).name,
njnb9c427c2004-12-01 14:14:42 +0000798 NULL == VG_(details).version ? "" : "-",
njnd04b7c62002-10-03 14:05:52 +0000799 NULL == VG_(details).version
800 ? (Char*)"" : VG_(details).version,
sewardj71bc3cb2005-05-19 00:25:45 +0000801 VG_(details).description,
802 xpost);
sewardj99a2ceb2007-11-09 12:30:36 +0000803
804 if (VG_(strlen)(toolname) >= 4
805 && 0 == VG_(strncmp)(toolname, "exp-", 4)) {
806 VG_(message)(
807 Vg_UserMsg,
808 "%sNOTE: This is an Experimental-Class Valgrind Tool.%s",
809 xpre, xpost
810 );
811 }
812
sewardj71bc3cb2005-05-19 00:25:45 +0000813 VG_(message)(Vg_UserMsg, "%s%s%s",
814 xpre, VG_(details).copyright_author, xpost);
sewardj3b2736a2002-03-24 12:18:35 +0000815
njnd04b7c62002-10-03 14:05:52 +0000816 /* Core details */
817 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000818 "%sUsing LibVEX rev %s, a library for dynamic binary translation.%s",
819 xpre, LibVEX_Version(), xpost );
sewardjc7025332004-12-13 18:30:39 +0000820 VG_(message)(Vg_UserMsg,
sewardj4d474d02008-02-11 11:34:59 +0000821 "%sCopyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.%s",
sewardj71bc3cb2005-05-19 00:25:45 +0000822 xpre, xpost );
sewardjc7025332004-12-13 18:30:39 +0000823 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000824 "%sUsing valgrind-%s, a dynamic binary instrumentation framework.%s",
825 xpre, VERSION, xpost);
sewardjde4a1d02002-03-22 01:27:54 +0000826 VG_(message)(Vg_UserMsg,
sewardj4d474d02008-02-11 11:34:59 +0000827 "%sCopyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.%s",
sewardj71bc3cb2005-05-19 00:25:45 +0000828 xpre, xpost );
sewardjd7bddad2005-06-13 16:48:32 +0000829
sewardj45f4e7c2005-09-27 19:20:21 +0000830 if (VG_(clo_verbosity) == 1 && !VG_(clo_xml))
831 VG_(message)(Vg_UserMsg, "For more details, rerun with: -v");
832
sewardjd7bddad2005-06-13 16:48:32 +0000833 if (VG_(clo_xml))
834 VG_(message)(Vg_UserMsg, "</preamble>");
njnd04b7c62002-10-03 14:05:52 +0000835 }
836
sewardj45f4e7c2005-09-27 19:20:21 +0000837 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
sewardj4cf05692002-10-27 20:28:29 +0000838 VG_(message)(Vg_UserMsg, "");
839 VG_(message)(Vg_UserMsg,
840 "My PID = %d, parent PID = %d. Prog and args are:",
841 VG_(getpid)(), VG_(getppid)() );
sewardj5e940782005-09-28 19:59:19 +0000842 if (VG_(args_the_exename))
843 VG_(message)(Vg_UserMsg, " %s", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000844 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
845 VG_(message)(Vg_UserMsg,
846 " %s",
847 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
sewardj4cf05692002-10-27 20:28:29 +0000848 }
sewardj71bc3cb2005-05-19 00:25:45 +0000849 else
850 if (VG_(clo_xml)) {
851 VG_(message)(Vg_UserMsg, "");
852 VG_(message)(Vg_UserMsg, "<pid>%d</pid>", VG_(getpid)());
853 VG_(message)(Vg_UserMsg, "<ppid>%d</ppid>", VG_(getppid)());
barta0b6b2c2008-07-07 06:49:24 +0000854 VG_(message_no_f_c)(Vg_UserMsg, "<tool>%t</tool>", toolname);
sewardjc191a042008-06-04 09:07:36 +0000855 if (VG_(clo_log_name))
856 print_file_vars(VG_(clo_log_name));
sewardj768db0e2005-07-19 14:18:56 +0000857 if (VG_(clo_xml_user_comment)) {
858 /* Note: the user comment itself is XML and is therefore to
859 be passed through verbatim (%s) rather than escaped
860 (%t). */
861 VG_(message)(Vg_UserMsg, "<usercomment>%s</usercomment>",
862 VG_(clo_xml_user_comment));
863 }
sewardj71bc3cb2005-05-19 00:25:45 +0000864 VG_(message)(Vg_UserMsg, "");
sewardjb8a3dac2005-07-19 12:39:11 +0000865 VG_(message)(Vg_UserMsg, "<args>");
sewardj45f4e7c2005-09-27 19:20:21 +0000866
sewardjb8a3dac2005-07-19 12:39:11 +0000867 VG_(message)(Vg_UserMsg, " <vargv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000868 if (VG_(name_of_launcher))
barta0b6b2c2008-07-07 06:49:24 +0000869 VG_(message_no_f_c)(Vg_UserMsg, " <exe>%t</exe>",
870 VG_(name_of_launcher));
sewardj125fd4f2007-03-08 19:56:14 +0000871 else
barta0b6b2c2008-07-07 06:49:24 +0000872 VG_(message_no_f_c)(Vg_UserMsg, " <exe>%t</exe>",
873 "(launcher name unknown)");
sewardj14c7cc52007-02-25 15:08:24 +0000874 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
barta0b6b2c2008-07-07 06:49:24 +0000875 VG_(message_no_f_c)(Vg_UserMsg,
876 " <arg>%t</arg>",
877 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjb8a3dac2005-07-19 12:39:11 +0000878 }
879 VG_(message)(Vg_UserMsg, " </vargv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000880
sewardjb8a3dac2005-07-19 12:39:11 +0000881 VG_(message)(Vg_UserMsg, " <argv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000882 if (VG_(args_the_exename))
barta0b6b2c2008-07-07 06:49:24 +0000883 VG_(message_no_f_c)(Vg_UserMsg, " <exe>%t</exe>",
884 VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000885 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
barta0b6b2c2008-07-07 06:49:24 +0000886 VG_(message_no_f_c)(Vg_UserMsg,
887 " <arg>%t</arg>",
888 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
sewardj8665d8e2005-06-01 17:35:23 +0000889 }
sewardjb8a3dac2005-07-19 12:39:11 +0000890 VG_(message)(Vg_UserMsg, " </argv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000891
sewardjb8a3dac2005-07-19 12:39:11 +0000892 VG_(message)(Vg_UserMsg, "</args>");
sewardj71bc3cb2005-05-19 00:25:45 +0000893 }
sewardj4cf05692002-10-27 20:28:29 +0000894
sewardj45f4e7c2005-09-27 19:20:21 +0000895 // Empty line after the preamble
896 if (VG_(clo_verbosity) > 0)
897 VG_(message)(Vg_UserMsg, "");
898
sewardjde4a1d02002-03-22 01:27:54 +0000899 if (VG_(clo_verbosity) > 1) {
sewardj92645592005-07-23 09:18:34 +0000900 SysRes fd;
sewardj1f0bbc72005-11-16 03:51:02 +0000901 VexArch vex_arch;
902 VexArchInfo vex_archinfo;
sewardj45f4e7c2005-09-27 19:20:21 +0000903 if (!logging_to_fd)
njn1fd5eb22005-03-13 05:43:23 +0000904 VG_(message)(Vg_DebugMsg, "");
njn1fd5eb22005-03-13 05:43:23 +0000905 VG_(message)(Vg_DebugMsg, "Command line");
sewardj45f4e7c2005-09-27 19:20:21 +0000906 if (VG_(args_the_exename))
907 VG_(message)(Vg_DebugMsg, " %s", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000908 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
909 VG_(message)(Vg_DebugMsg,
910 " %s",
911 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
njn86dc2bc2003-09-09 07:26:21 +0000912
njn1fd5eb22005-03-13 05:43:23 +0000913 VG_(message)(Vg_DebugMsg, "Startup, with flags:");
sewardj14c7cc52007-02-25 15:08:24 +0000914 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
915 VG_(message)(Vg_DebugMsg,
916 " %s",
917 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjde4a1d02002-03-22 01:27:54 +0000918 }
nethercotea70f7352004-04-18 12:08:46 +0000919
njn1fd5eb22005-03-13 05:43:23 +0000920 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:");
nethercotea70f7352004-04-18 12:08:46 +0000921 fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
sewardj92645592005-07-23 09:18:34 +0000922 if (fd.isError) {
njn1fd5eb22005-03-13 05:43:23 +0000923 VG_(message)(Vg_DebugMsg, " can't open /proc/version");
nethercotea70f7352004-04-18 12:08:46 +0000924 } else {
sewardj71bc3cb2005-05-19 00:25:45 +0000925# define BUF_LEN 256
nethercotea70f7352004-04-18 12:08:46 +0000926 Char version_buf[BUF_LEN];
sewardj12ab7652006-10-17 02:10:42 +0000927 Int n = VG_(read) ( fd.res, version_buf, BUF_LEN );
njnbe9b47b2005-05-15 16:22:58 +0000928 vg_assert(n <= BUF_LEN);
nethercotea70f7352004-04-18 12:08:46 +0000929 if (n > 0) {
930 version_buf[n-1] = '\0';
njn1fd5eb22005-03-13 05:43:23 +0000931 VG_(message)(Vg_DebugMsg, " %s", version_buf);
nethercotea70f7352004-04-18 12:08:46 +0000932 } else {
njn1fd5eb22005-03-13 05:43:23 +0000933 VG_(message)(Vg_DebugMsg, " (empty?)");
nethercotea70f7352004-04-18 12:08:46 +0000934 }
sewardj12ab7652006-10-17 02:10:42 +0000935 VG_(close)(fd.res);
sewardj71bc3cb2005-05-19 00:25:45 +0000936# undef BUF_LEN
nethercotea70f7352004-04-18 12:08:46 +0000937 }
sewardj1f0bbc72005-11-16 03:51:02 +0000938
939 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +0000940 VG_(message)(
941 Vg_DebugMsg,
942 "Arch and hwcaps: %s, %s",
943 LibVEX_ppVexArch ( vex_arch ),
944 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
945 );
sewardje66f2e02006-12-30 17:45:08 +0000946 VG_(message)(
947 Vg_DebugMsg,
sewardj07854682006-12-30 17:56:32 +0000948 "Page sizes: currently %d, max supported %d",
sewardje66f2e02006-12-30 17:45:08 +0000949 (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
950 );
sewardj1f0bbc72005-11-16 03:51:02 +0000951 VG_(message)(Vg_DebugMsg, "Valgrind library directory: %s", VG_(libdir));
sewardjde4a1d02002-03-22 01:27:54 +0000952 }
nethercotef6a1d502004-08-09 12:21:57 +0000953}
954
sewardjde4a1d02002-03-22 01:27:54 +0000955
nethercote71980f02004-01-24 18:18:54 +0000956/*====================================================================*/
957/*=== File descriptor setup ===*/
958/*====================================================================*/
959
sewardj5f229e22005-09-28 01:36:01 +0000960/* Number of file descriptors that Valgrind tries to reserve for
961 it's own use - just a small constant. */
962#define N_RESERVED_FDS (10)
963
nethercote71980f02004-01-24 18:18:54 +0000964static void setup_file_descriptors(void)
965{
966 struct vki_rlimit rl;
sewardj17c11042006-10-15 01:26:40 +0000967 Bool show = False;
nethercote71980f02004-01-24 18:18:54 +0000968
969 /* Get the current file descriptor limits. */
970 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
971 rl.rlim_cur = 1024;
972 rl.rlim_max = 1024;
973 }
974
sewardj17c11042006-10-15 01:26:40 +0000975 if (show)
njn8a7b41b2007-09-23 00:51:24 +0000976 VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +0000977 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +0000978
979# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
980 /* I don't know why this kludge is needed; however if rl.rlim_cur
981 is RLIM_INFINITY, then VG_(safe_fd)'s attempts using VG_(fcntl)
982 to lift V's file descriptors above the threshold RLIM_INFINITY -
983 N_RESERVED_FDS fail. So just use a relatively conservative
984 value in this case. */
985 if (rl.rlim_cur > 1024)
986 rl.rlim_cur = 1024;
987# endif
988
nethercote71980f02004-01-24 18:18:54 +0000989 /* Work out where to move the soft limit to. */
njn14319cc2005-03-13 06:26:22 +0000990 if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
991 rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +0000992 } else {
993 rl.rlim_cur = rl.rlim_max;
994 }
995
996 /* Reserve some file descriptors for our use. */
njn14319cc2005-03-13 06:26:22 +0000997 VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
998 VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +0000999
1000 /* Update the soft limit. */
1001 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
1002
sewardj17c11042006-10-15 01:26:40 +00001003 if (show) {
njn8a7b41b2007-09-23 00:51:24 +00001004 VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001005 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001006 VG_(printf)("fd limits: guest : cur %u max %u\n",
1007 VG_(fd_soft_limit), VG_(fd_hard_limit));
1008 }
1009
sewardj45f4e7c2005-09-27 19:20:21 +00001010 if (VG_(cl_exec_fd) != -1)
1011 VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
nethercote71980f02004-01-24 18:18:54 +00001012}
1013
sewardjde4a1d02002-03-22 01:27:54 +00001014
njn2da73352005-06-18 01:35:16 +00001015/*====================================================================*/
njn2025cf92005-06-26 20:44:48 +00001016/*=== BB profiling ===*/
1017/*====================================================================*/
1018
1019static
1020void show_BB_profile ( BBProfEntry tops[], UInt n_tops, ULong score_total )
1021{
1022 ULong score_cumul, score_here;
1023 Char buf_cumul[10], buf_here[10];
1024 Char name[64];
1025 Int r;
1026
1027 VG_(printf)("\n");
1028 VG_(printf)("-----------------------------------------------------------\n");
1029 VG_(printf)("--- BEGIN BB Profile (summary of scores) ---\n");
1030 VG_(printf)("-----------------------------------------------------------\n");
1031 VG_(printf)("\n");
1032
1033 VG_(printf)("Total score = %lld\n\n", score_total);
1034
1035 score_cumul = 0;
1036 for (r = 0; r < n_tops; r++) {
1037 if (tops[r].addr == 0)
1038 continue;
1039 name[0] = 0;
1040 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1041 name[63] = 0;
1042 score_here = tops[r].score;
1043 score_cumul += score_here;
1044 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1045 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1046 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1047 r,
1048 score_cumul, buf_cumul,
1049 score_here, buf_here, tops[r].addr, name );
1050 }
1051
1052 VG_(printf)("\n");
1053 VG_(printf)("-----------------------------------------------------------\n");
1054 VG_(printf)("--- BB Profile (BB details) ---\n");
1055 VG_(printf)("-----------------------------------------------------------\n");
1056 VG_(printf)("\n");
1057
1058 score_cumul = 0;
1059 for (r = 0; r < n_tops; r++) {
1060 if (tops[r].addr == 0)
1061 continue;
1062 name[0] = 0;
1063 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1064 name[63] = 0;
1065 score_here = tops[r].score;
1066 score_cumul += score_here;
1067 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1068 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1069 VG_(printf)("\n");
1070 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin BB rank %d "
1071 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1072 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1073 r,
1074 score_cumul, buf_cumul,
1075 score_here, buf_here, tops[r].addr, name );
1076 VG_(printf)("\n");
sewardjbcccbc02007-04-09 22:24:57 +00001077 VG_(discard_translations)(tops[r].addr, 1, "bb profile");
sewardj0ec07f32006-01-12 12:32:32 +00001078 VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0, True);
njn2025cf92005-06-26 20:44:48 +00001079 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= end BB rank %d "
1080 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1081 }
1082
1083 VG_(printf)("\n");
1084 VG_(printf)("-----------------------------------------------------------\n");
1085 VG_(printf)("--- END BB Profile ---\n");
1086 VG_(printf)("-----------------------------------------------------------\n");
1087 VG_(printf)("\n");
1088}
1089
1090
1091/*====================================================================*/
nethercote71980f02004-01-24 18:18:54 +00001092/*=== main() ===*/
1093/*====================================================================*/
1094
sewardjfdf91b42005-09-28 00:53:09 +00001095/* When main() is entered, we should be on the following stack, not
1096 the one the kernel gave us. We will run on this stack until
1097 simulation of the root thread is started, at which point a transfer
1098 is made to a dynamically allocated stack. This is for the sake of
1099 uniform overflow detection for all Valgrind threads. This is
1100 marked global even though it isn't, because assembly code below
1101 needs to reference the name. */
1102
1103/*static*/ VgStack VG_(interim_stack);
1104
sewardjf9d2f9b2006-11-17 20:00:57 +00001105/* These are the structures used to hold info for creating the initial
1106 client image.
1107
1108 'iicii' mostly holds important register state present at system
1109 startup (_start_valgrind). valgrind_main() then fills in the rest
1110 of it and passes it to VG_(ii_create_image)(). That produces
1111 'iifii', which is later handed to VG_(ii_finalise_image). */
1112
1113/* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1114 This should get some address inside the stack on which we gained
sewardjfdf91b42005-09-28 00:53:09 +00001115 control (eg, it could be the SP at startup). It doesn't matter
1116 exactly where in the stack it is. This value is passed to the
sewardjf9d2f9b2006-11-17 20:00:57 +00001117 address space manager at startup. On Linux, aspacem then uses it
1118 to identify the initial stack segment and hence the upper end of
1119 the usable address space. */
sewardjfdf91b42005-09-28 00:53:09 +00001120
sewardjf9d2f9b2006-11-17 20:00:57 +00001121static IICreateImageInfo the_iicii;
1122static IIFinaliseImageInfo the_iifii;
1123
sewardjfdf91b42005-09-28 00:53:09 +00001124
sewardj9c606bd2008-09-18 18:12:50 +00001125/* A simple pair structure, used for conveying debuginfo handles to
1126 calls to VG_TRACK(new_mem_startup, ...). */
1127typedef struct { Addr a; ULong ull; } Addr_n_ULong;
1128
1129
sewardj1ae3f3a2005-09-28 10:47:38 +00001130/* --- Forwards decls to do with shutdown --- */
1131
1132static void final_tidyup(ThreadId tid);
1133
1134/* Do everything which needs doing when the last thread exits */
1135static
1136void shutdown_actions_NORETURN( ThreadId tid,
1137 VgSchedReturnCode tids_schedretcode );
1138
1139/* --- end of Forwards decls to do with shutdown --- */
sewardjfdf91b42005-09-28 00:53:09 +00001140
1141
sewardj45f4e7c2005-09-27 19:20:21 +00001142/* TODO: GIVE THIS A PROPER HOME
njn1d0825f2006-03-27 11:37:07 +00001143 TODO: MERGE THIS WITH DUPLICATE IN mc_leakcheck.c and coredump-elf.c.
sewardj45f4e7c2005-09-27 19:20:21 +00001144 Extract from aspacem a vector of the current segment start
1145 addresses. The vector is dynamically allocated and should be freed
1146 by the caller when done. REQUIRES m_mallocfree to be running.
1147 Writes the number of addresses required into *n_acquired. */
nethercotec314eba2004-07-15 12:59:41 +00001148
sewardj45f4e7c2005-09-27 19:20:21 +00001149static Addr* get_seg_starts ( /*OUT*/Int* n_acquired )
sewardj1cf558c2005-04-25 01:36:56 +00001150{
sewardj45f4e7c2005-09-27 19:20:21 +00001151 Addr* starts;
sewardja48a4932005-09-29 11:09:56 +00001152 Int n_starts, r = 0;
sewardj45f4e7c2005-09-27 19:20:21 +00001153
1154 n_starts = 1;
sewardj1cf558c2005-04-25 01:36:56 +00001155 while (True) {
sewardj9c606bd2008-09-18 18:12:50 +00001156 starts = VG_(malloc)( "main.gss.1", n_starts * sizeof(Addr) );
sewardj45f4e7c2005-09-27 19:20:21 +00001157 if (starts == NULL)
1158 break;
1159 r = VG_(am_get_segment_starts)( starts, n_starts );
1160 if (r >= 0)
1161 break;
1162 VG_(free)(starts);
1163 n_starts *= 2;
sewardj1cf558c2005-04-25 01:36:56 +00001164 }
sewardj45f4e7c2005-09-27 19:20:21 +00001165
1166 if (starts == NULL) {
1167 *n_acquired = 0;
1168 return NULL;
1169 }
1170
1171 *n_acquired = r;
1172 return starts;
sewardj1cf558c2005-04-25 01:36:56 +00001173}
1174
1175
sewardjf9d2f9b2006-11-17 20:00:57 +00001176/* By the time we get to valgrind_main, the_iicii should already have
1177 been filled in with any important details as required by whatever
1178 OS we have been built for.
1179*/
sewardj17c11042006-10-15 01:26:40 +00001180static
sewardjf9d2f9b2006-11-17 20:00:57 +00001181Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
nethercote71980f02004-01-24 18:18:54 +00001182{
sewardj13247ca2005-12-30 22:52:20 +00001183 HChar* toolname = "memcheck"; // default to Memcheck
sewardj13247ca2005-12-30 22:52:20 +00001184 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
sewardj4c3faae2006-03-15 11:50:32 +00001185 UInt* client_auxv = NULL;
sewardjde764e82007-11-09 23:13:22 +00001186 ThreadId tid_main = VG_INVALID_THREADID;
sewardj45f4e7c2005-09-27 19:20:21 +00001187 Int loglevel, i;
1188 Bool logging_to_fd;
nethercote73b526f2004-10-31 18:48:21 +00001189 struct vki_rlimit zero = { 0, 0 };
sewardj9c606bd2008-09-18 18:12:50 +00001190 XArray* addr2dihandle = NULL;
sewardj17c11042006-10-15 01:26:40 +00001191
nethercote71980f02004-01-24 18:18:54 +00001192 //============================================================
nethercote71980f02004-01-24 18:18:54 +00001193 //
sewardj45f4e7c2005-09-27 19:20:21 +00001194 // Nb: startup is complex. Prerequisites are shown at every step.
nethercote71980f02004-01-24 18:18:54 +00001195 // *** Be very careful when messing with the order ***
sewardj45f4e7c2005-09-27 19:20:21 +00001196 //
1197 // The first order of business is to get debug logging, the address
1198 // space manager and the dynamic memory manager up and running.
1199 // Once that's done, we can relax a bit.
1200 //
nethercote71980f02004-01-24 18:18:54 +00001201 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001202
1203 /* This is needed to make VG_(getenv) usable early. */
1204 VG_(client_envp) = (Char**)envp;
nethercote71980f02004-01-24 18:18:54 +00001205
sewardj1cf558c2005-04-25 01:36:56 +00001206 //--------------------------------------------------------------
1207 // Start up the logging mechanism
1208 // p: none
1209 //--------------------------------------------------------------
1210 /* Start the debugging-log system ASAP. First find out how many
1211 "-d"s were specified. This is a pre-scan of the command line. */
1212 loglevel = 0;
1213 for (i = 1; i < argc; i++) {
sewardj10759312005-05-30 23:52:47 +00001214 if (argv[i][0] != '-')
1215 break;
sewardj45f4e7c2005-09-27 19:20:21 +00001216 if (VG_STREQ(argv[i], "--"))
sewardj10759312005-05-30 23:52:47 +00001217 break;
sewardj45f4e7c2005-09-27 19:20:21 +00001218 if (VG_STREQ(argv[i], "-d"))
sewardj10759312005-05-30 23:52:47 +00001219 loglevel++;
sewardj94c8eb42008-09-19 20:13:39 +00001220 if (VG_STREQ(argv[i], "--profile-heap=yes"))
1221 VG_(clo_profile_heap) = True;
1222 if (VG_STREQ(argv[i], "--profile-heap=no"))
1223 VG_(clo_profile_heap) = False;
sewardj1cf558c2005-04-25 01:36:56 +00001224 }
1225
1226 /* ... and start the debug logger. Now we can safely emit logging
1227 messages all through startup. */
sewardj10759312005-05-30 23:52:47 +00001228 VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
sewardj45f4e7c2005-09-27 19:20:21 +00001229 VG_(debugLog)(1, "main", "Welcome to Valgrind version "
1230 VERSION " debug logging\n");
1231
1232 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001233 // AIX5 only: register the system call numbers
1234 // p: logging
1235 // p: that the initial few syscall numbers stated in the
1236 // bootblock have been installed (else we can't
1237 // open/read/close).
1238 //--------------------------------------------------------------
1239# if defined(VGO_aix5)
1240 VG_(debugLog)(1, "main", "aix5: registering syscalls ..\n");
1241 { UChar sysent_name[50];
1242 SysRes fd;
1243 Bool ok;
1244 Int n_unregd, sysent_used = 0;
1245 prsysent_t* sysent_hdr;
1246
1247 VG_(sprintf)(sysent_name, "/proc/%d/sysent", VG_(getpid)());
1248 fd = VG_(open)(sysent_name, VKI_O_RDONLY, 0);
1249 if (fd.isError)
1250 VG_(err_config_error)("aix5: can't open /proc/<pid>/sysent");
1251
1252 sysent_used = VG_(read)(fd.res, aix5_sysent_buf, VG_AIX5_SYSENT_SIZE);
1253 if (sysent_used < 0)
1254 VG_(err_config_error)("aix5: error reading /proc/<pid>/sysent");
1255 if (sysent_used >= VG_AIX5_SYSENT_SIZE)
1256 VG_(err_config_error)("aix5: VG_AIX5_SYSENT_SIZE is too low; "
1257 "increase and recompile");
1258 VG_(close)(fd.res);
1259
1260 vg_assert(sysent_used > 0 && sysent_used < VG_AIX5_SYSENT_SIZE);
1261
1262 sysent_hdr = (prsysent_t*)&aix5_sysent_buf[0];
1263
1264 n_unregd = 0;
1265 for (i = 0; i < sysent_hdr->pr_nsyscalls; i++) {
1266 UChar* name = &aix5_sysent_buf[ sysent_hdr
1267 ->pr_syscall[i].pr_nameoff ];
1268 UInt nmbr = sysent_hdr->pr_syscall[i].pr_number;
1269 VG_(debugLog)(3, "main", "aix5: bind syscall %d to \"%s\"\n",
1270 nmbr, name);
1271 ok = VG_(aix5_register_syscall)(nmbr, name);
1272 if (!ok)
1273 n_unregd++;
1274 if (!ok)
1275 VG_(debugLog)(3, "main",
1276 "aix5: bind FAILED: %d to \"%s\"\n",
1277 nmbr, name);
1278 }
1279 VG_(debugLog)(1, "main", "aix5: .. %d syscalls known, %d unknown\n",
1280 sysent_hdr->pr_nsyscalls - n_unregd, n_unregd );
1281 VG_(debugLog)(1, "main", "aix5: __NR_AIX5_FAKE_SIGRETURN = %d\n",
1282 __NR_AIX5_FAKE_SIGRETURN );
1283 }
1284# endif
1285
1286 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001287 // Ensure we're on a plausible stack.
1288 // p: logging
1289 //--------------------------------------------------------------
1290 VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
sewardjfdf91b42005-09-28 00:53:09 +00001291 { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
1292 HChar* limHi = limLo + sizeof(VG_(interim_stack));
sewardj45f4e7c2005-09-27 19:20:21 +00001293 HChar* aLocal = (HChar*)&zero; /* any auto local will do */
1294 if (aLocal < limLo || aLocal >= limHi) {
1295 /* something's wrong. Stop. */
1296 VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
1297 limLo, limHi, aLocal );
1298 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1299 "Initial stack switched failed.\n");
1300 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1301 VG_(exit)(1);
1302 }
1303 }
1304
1305 //--------------------------------------------------------------
1306 // Ensure we have a plausible pointer to the stack on which
1307 // we gained control (not the current stack!)
1308 // p: logging
1309 //--------------------------------------------------------------
1310 VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
sewardjf9d2f9b2006-11-17 20:00:57 +00001311 if (the_iicii.sp_at_startup == 0) {
sewardj45f4e7c2005-09-27 19:20:21 +00001312 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1313 "Initial stack was not noted.\n");
1314 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1315 VG_(exit)(1);
1316 }
1317
1318 //--------------------------------------------------------------
1319 // Start up the address space manager, and determine the
1320 // approximate location of the client's stack
1321 // p: logging, plausible-stack
1322 //--------------------------------------------------------------
1323 VG_(debugLog)(1, "main", "Starting the address space manager\n");
sewardje66f2e02006-12-30 17:45:08 +00001324 vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536);
1325 vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536);
1326 vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
1327 vg_assert(VKI_PAGE_SIZE == (1 << VKI_PAGE_SHIFT));
1328 vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
sewardjf9d2f9b2006-11-17 20:00:57 +00001329 the_iicii.clstack_top = VG_(am_startup)( the_iicii.sp_at_startup );
sewardj45f4e7c2005-09-27 19:20:21 +00001330 VG_(debugLog)(1, "main", "Address space manager is running\n");
1331
1332 //--------------------------------------------------------------
1333 // Start up the dynamic memory manager
1334 // p: address space management
1335 // In fact m_mallocfree is self-initialising, so there's no
1336 // initialisation call to do. Instead, try a simple malloc/
1337 // free pair right now to check that nothing is broken.
1338 //--------------------------------------------------------------
1339 VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
sewardj9c606bd2008-09-18 18:12:50 +00001340 { void* p = VG_(malloc)( "main.vm.1", 12345 );
sewardj45f4e7c2005-09-27 19:20:21 +00001341 if (p) VG_(free)( p );
1342 }
1343 VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
sewardj1cf558c2005-04-25 01:36:56 +00001344
nethercotef4928da2004-06-15 10:54:40 +00001345 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001346 //
1347 // Dynamic memory management is now available.
1348 //
nethercotef4928da2004-06-15 10:54:40 +00001349 //============================================================
1350
sewardj45f4e7c2005-09-27 19:20:21 +00001351 //--------------------------------------------------------------
sewardjf98e1c02008-10-25 16:22:41 +00001352 // Initialise m_debuginfo
1353 // p: dynamic memory allocation
1354 VG_(debugLog)(1, "main", "Initialise m_debuginfo\n");
1355 VG_(di_initialise)();
1356
1357 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001358 // Look for alternative libdir
1359 { HChar *cp = VG_(getenv)(VALGRIND_LIB);
1360 if (cp != NULL)
1361 VG_(libdir) = cp;
1362 }
1363
1364 //--------------------------------------------------------------
1365 // Extract the launcher name from the environment.
1366 VG_(debugLog)(1, "main", "Getting stage1's name\n");
1367 VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
1368 if (VG_(name_of_launcher) == NULL) {
1369 VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
1370 VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
1371 VG_(exit)(1);
1372 }
1373
1374 //--------------------------------------------------------------
fitzhardingeb50068f2004-02-24 23:42:55 +00001375 // Get the current process datasize rlimit, and set it to zero.
1376 // This prevents any internal uses of brk() from having any effect.
1377 // We remember the old value so we can restore it on exec, so that
1378 // child processes will have a reasonable brk value.
1379 VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1380 zero.rlim_max = VG_(client_rlimit_data).rlim_max;
1381 VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
thughesc37184f2004-09-11 14:16:57 +00001382
1383 // Get the current process stack rlimit.
1384 VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
1385
sewardje2d1e672005-11-12 23:10:48 +00001386 //--------------------------------------------------------------
1387 // Figure out what sort of CPU we're on, and whether it is
1388 // able to run V.
1389 VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
1390 { VexArch vex_arch;
1391 VexArchInfo vex_archinfo;
1392 Bool ok = VG_(machine_get_hwcaps)();
1393 if (!ok) {
1394 VG_(printf)("\n");
1395 VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
1396 VG_(printf)(" Supported CPUs are:\n");
1397 VG_(printf)(" * x86 (practically any; Pentium-I or above), "
1398 "AMD Athlon or above)\n");
1399 VG_(printf)(" * AMD Athlon64/Opteron\n");
1400 VG_(printf)(" * PowerPC (most; ppc405 and above)\n");
1401 VG_(printf)("\n");
1402 VG_(exit)(1);
1403 }
1404 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001405 VG_(debugLog)(
1406 1, "main", "... arch = %s, hwcaps = %s\n",
1407 LibVEX_ppVexArch ( vex_arch ),
1408 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1409 );
sewardje2d1e672005-11-12 23:10:48 +00001410 }
1411
sewardj198f34f2007-07-09 23:13:07 +00001412 //--------------------------------------------------------------
1413 // Record the working directory at startup
1414 // p: none (Linux), getenv and sys_getpid work (AIX)
1415 VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
1416 { Bool ok = VG_(record_startup_wd)();
1417 if (!ok)
1418 VG_(err_config_error)( "Can't establish current working "
1419 "directory at startup");
1420 }
1421 { Char buf[VKI_PATH_MAX+1];
1422 Bool ok = VG_(get_startup_wd)( buf, sizeof(buf) );
1423 vg_assert(ok);
1424 buf[VKI_PATH_MAX] = 0;
1425 VG_(debugLog)(1, "main", "... %s\n", buf );
1426 }
1427
sewardj45f4e7c2005-09-27 19:20:21 +00001428 //============================================================
1429 // Command line argument handling order:
1430 // * If --help/--help-debug are present, show usage message
1431 // (including the tool-specific usage)
1432 // * (If no --tool option given, default to Memcheck)
1433 // * Then, if client is missing, abort with error msg
1434 // * Then, if any cmdline args are bad, abort with error msg
1435 //============================================================
1436
1437 //--------------------------------------------------------------
1438 // Split up argv into: C args, V args, V extra args, and exename.
1439 // p: dynamic memory allocation
1440 //--------------------------------------------------------------
1441 VG_(debugLog)(1, "main", "Split up command line\n");
1442 VG_(split_up_argv)( argc, argv );
sewardj14c7cc52007-02-25 15:08:24 +00001443 vg_assert( VG_(args_for_valgrind) );
1444 vg_assert( VG_(args_for_client) );
sewardj45f4e7c2005-09-27 19:20:21 +00001445 if (0) {
sewardj14c7cc52007-02-25 15:08:24 +00001446 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
1447 VG_(printf)(
1448 "varg %s\n",
1449 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1450 );
sewardj45f4e7c2005-09-27 19:20:21 +00001451 VG_(printf)(" exe %s\n", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001452 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
1453 VG_(printf)(
1454 "carg %s\n",
1455 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1456 );
nethercote71980f02004-01-24 18:18:54 +00001457 }
1458
sewardj948a6fc2007-03-19 18:38:55 +00001459# if defined(VGO_aix5)
1460 /* Tolerate ptraced-based launchers. They can't run 'no program'
1461 if the user types "valgrind --help", so they run a do-nothing
1462 program $prefix/bin/no_op_client_for_valgrind, and we catch that
1463 here and turn it the exe name back into NULL. Then --help,
1464 --version etc work as they should. */
1465 if (VG_(args_the_exename)
1466 && VG_(strstr)( VG_(args_the_exename), "/no_op_client_for_valgrind" )) {
1467 VG_(args_the_exename) = NULL;
1468 }
1469# endif
1470
nethercote71980f02004-01-24 18:18:54 +00001471 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001472 // Extract tool name and whether help has been requested.
1473 // Note we can't print the help message yet, even if requested,
1474 // because the tool has not been initialised.
1475 // p: split_up_argv [for VG_(args_for_valgrind)]
nethercote71980f02004-01-24 18:18:54 +00001476 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001477 VG_(debugLog)(1, "main",
1478 "(early_) Process Valgrind's command line options\n");
1479 early_process_cmd_line_options(&need_help, &toolname);
nethercote71980f02004-01-24 18:18:54 +00001480
sewardj45f4e7c2005-09-27 19:20:21 +00001481 // Set default vex control params
1482 LibVEX_default_VexControl(& VG_(clo_vex_control));
nethercote71980f02004-01-24 18:18:54 +00001483
1484 //--------------------------------------------------------------
1485 // Load client executable, finding in $PATH if necessary
sewardj95d86c02007-12-18 01:49:23 +00001486 // p: early_process_cmd_line_options() [for 'exec', 'need_help']
1487 // p: layout_remaining_space [so there's space]
sewardj17c11042006-10-15 01:26:40 +00001488 //
nethercote71980f02004-01-24 18:18:54 +00001489 // Set up client's environment
sewardj95d86c02007-12-18 01:49:23 +00001490 // p: set-libdir [for VG_(libdir)]
1491 // p: early_process_cmd_line_options [for toolname]
sewardj17c11042006-10-15 01:26:40 +00001492 //
nethercote5ee67ca2004-06-22 14:00:09 +00001493 // Setup client stack, eip, and VG_(client_arg[cv])
nethercote71980f02004-01-24 18:18:54 +00001494 // p: load_client() [for 'info']
1495 // p: fix_environment() [for 'env']
sewardj17c11042006-10-15 01:26:40 +00001496 //
sewardj45f4e7c2005-09-27 19:20:21 +00001497 // Setup client data (brk) segment. Initially a 1-page segment
1498 // which abuts a shrinkable reservation.
1499 // p: load_client() [for 'info' and hence VG_(brk_base)]
sewardjf9d2f9b2006-11-17 20:00:57 +00001500 //
1501 // p: _start_in_C (for zeroing out the_iicii and putting some
1502 // initial values into it)
sewardj45f4e7c2005-09-27 19:20:21 +00001503 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001504 if (!need_help) {
sewardjf9d2f9b2006-11-17 20:00:57 +00001505 VG_(debugLog)(1, "main", "Create initial image\n");
1506
1507# if defined(VGO_linux)
1508 the_iicii.argv = argv;
1509 the_iicii.envp = envp;
1510 the_iicii.toolname = toolname;
1511# elif defined(VGO_aix5)
1512 /* the_iicii.intregs37 already set up */
1513 /* the_iicii.bootblock already set up */
1514 /* the_iicii.adler32_exp already set up */
1515 /* the_iicii.sp_at_startup is irrelevant */
1516 /* the_iicii.clstack_top is irrelevant */
1517 the_iicii.toolname = toolname;
1518# else
1519# error "Uknown platform"
1520# endif
1521
sewardjdc2f79e2007-12-22 14:14:04 +00001522 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001523 the_iifii = VG_(ii_create_image)( the_iicii );
1524
sewardj17c11042006-10-15 01:26:40 +00001525# if defined(VGO_aix5)
sewardj17c11042006-10-15 01:26:40 +00001526 /* Tell aspacem where the initial client stack is, so that it
1527 can later produce a faked-up NSegment in response to
1528 VG_(am_find_nsegment) for that address range, if asked. */
sewardjdc2f79e2007-12-22 14:14:04 +00001529 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001530 VG_(am_aix5_set_initial_client_sp)( the_iifii.initial_client_SP );
1531 /* Now have a look at said fake segment, so we can find out
1532 the size of it. */
1533 { SizeT sz;
1534 NSegment const* seg
1535 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
1536 vg_assert(seg);
1537 sz = seg->end - seg->start + 1;
sewardjc9d33832007-12-22 14:12:42 +00001538 vg_assert(sz >= 0 && sz <= (256+1)*1024*1024); /* stay sane */
sewardjf9d2f9b2006-11-17 20:00:57 +00001539 the_iifii.clstack_max_size = sz;
1540 }
sewardj17c11042006-10-15 01:26:40 +00001541# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001542 }
nethercote71980f02004-01-24 18:18:54 +00001543
1544 //==============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001545 //
1546 // Finished loading/setting up the client address space.
1547 //
nethercote71980f02004-01-24 18:18:54 +00001548 //==============================================================
1549
1550 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001551 // setup file descriptors
1552 // p: n/a
1553 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001554 VG_(debugLog)(1, "main", "Setup file descriptors\n");
nethercote71980f02004-01-24 18:18:54 +00001555 setup_file_descriptors();
1556
1557 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001558 // create the fake /proc/<pid>/cmdline file and then unlink it,
1559 // but hold onto the fd, so we can hand it out to the client
1560 // when it tries to open /proc/<pid>/cmdline for itself.
1561 // p: setup file descriptors
nethercotec314eba2004-07-15 12:59:41 +00001562 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001563 if (!need_help) {
1564 HChar buf[50], buf2[50+64];
1565 HChar nul[1];
1566 Int fd, r;
1567 HChar* exename;
nethercotec314eba2004-07-15 12:59:41 +00001568
sewardj45f4e7c2005-09-27 19:20:21 +00001569 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
1570
1571 VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
1572 fd = VG_(mkstemp)( buf, buf2 );
1573 if (fd == -1)
sewardj17c11042006-10-15 01:26:40 +00001574 VG_(err_config_error)("Can't create client cmdline file in /tmp.");
sewardj45f4e7c2005-09-27 19:20:21 +00001575
1576 nul[0] = 0;
1577 exename = VG_(args_the_exename) ? VG_(args_the_exename)
1578 : "unknown_exename";
sewardj45f4e7c2005-09-27 19:20:21 +00001579 VG_(write)(fd, VG_(args_the_exename),
1580 VG_(strlen)( VG_(args_the_exename) ));
1581 VG_(write)(fd, nul, 1);
1582
sewardj14c7cc52007-02-25 15:08:24 +00001583 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1584 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
1585 VG_(write)(fd, arg, VG_(strlen)( arg ));
sewardj45f4e7c2005-09-27 19:20:21 +00001586 VG_(write)(fd, nul, 1);
1587 }
1588
1589 /* Don't bother to seek the file back to the start; instead do
1590 it every time a copy of it is given out (by PRE(sys_open)).
1591 That is probably more robust across fork() etc. */
1592
1593 /* Now delete it, but hang on to the fd. */
1594 r = VG_(unlink)( buf2 );
1595 if (r)
sewardj17c11042006-10-15 01:26:40 +00001596 VG_(err_config_error)("Can't delete client cmdline file in /tmp.");
sewardj45f4e7c2005-09-27 19:20:21 +00001597
1598 VG_(cl_cmdline_fd) = fd;
1599 }
nethercotec314eba2004-07-15 12:59:41 +00001600
1601 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001602 // Init tool part 1: pre_clo_init
nethercotec314eba2004-07-15 12:59:41 +00001603 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
nethercotec314eba2004-07-15 12:59:41 +00001604 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
nethercote71980f02004-01-24 18:18:54 +00001605 //--------------------------------------------------------------
sewardj7cf4e6b2008-05-01 20:24:26 +00001606 VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
1607 (VG_(tool_info).tl_pre_clo_init)();
nethercote71980f02004-01-24 18:18:54 +00001608
sewardj45f4e7c2005-09-27 19:20:21 +00001609 //--------------------------------------------------------------
nethercotef4928da2004-06-15 10:54:40 +00001610 // If --tool and --help/--help-debug was given, now give the core+tool
1611 // help message
sewardj95d86c02007-12-18 01:49:23 +00001612 // p: early_process_cmd_line_options() [for 'need_help']
1613 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
sewardj45f4e7c2005-09-27 19:20:21 +00001614 //--------------------------------------------------------------
1615 VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
nethercotef4928da2004-06-15 10:54:40 +00001616 if (need_help) {
sewardj45f4e7c2005-09-27 19:20:21 +00001617 usage_NORETURN(/*--help-debug?*/2 == need_help);
nethercotef4928da2004-06-15 10:54:40 +00001618 }
nethercotec314eba2004-07-15 12:59:41 +00001619
sewardj45f4e7c2005-09-27 19:20:21 +00001620 //--------------------------------------------------------------
1621 // Process command line options to Valgrind + tool
1622 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1623 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1624 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001625 VG_(debugLog)(1, "main",
1626 "(main_) Process Valgrind's command line options, "
1627 "setup logging\n");
1628 logging_to_fd = main_process_cmd_line_options(client_auxv, toolname);
sewardj45f4e7c2005-09-27 19:20:21 +00001629
1630 //--------------------------------------------------------------
sewardj592ae092005-11-08 19:01:44 +00001631 // Zeroise the millisecond counter by doing a first read of it.
1632 // p: none
1633 //--------------------------------------------------------------
1634 (void) VG_(read_millisecond_timer)();
1635
1636 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001637 // Print the preamble
1638 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
sewardj95d86c02007-12-18 01:49:23 +00001639 // p: main_process_cmd_line_options() [for VG_(clo_verbosity),
1640 // VG_(clo_xml),
1641 // logging_to_fd]
sewardj45f4e7c2005-09-27 19:20:21 +00001642 //--------------------------------------------------------------
1643 VG_(debugLog)(1, "main", "Print the preamble...\n");
1644 print_preamble(logging_to_fd, toolname);
1645 VG_(debugLog)(1, "main", "...finished the preamble\n");
1646
1647 //--------------------------------------------------------------
1648 // Init tool part 2: post_clo_init
1649 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1650 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1651 // p: print_preamble() [so any warnings printed in post_clo_init
1652 // are shown after the preamble]
1653 //--------------------------------------------------------------
1654 VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
njn51d827b2005-05-09 01:02:08 +00001655 VG_TDICT_CALL(tool_post_clo_init);
sewardj7cf4e6b2008-05-01 20:24:26 +00001656 {
1657 /* The tool's "needs" will by now be finalised, since it has no
1658 further opportunity to specify them. So now sanity check
1659 them. */
1660 Char* s;
1661 Bool ok;
1662 ok = VG_(sanity_check_needs)( &s );
1663 if (!ok) {
1664 VG_(tool_panic)(s);
1665 }
1666 }
nethercotef4928da2004-06-15 10:54:40 +00001667
1668 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001669 // Initialise translation table and translation cache
1670 // p: aspacem [??]
1671 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
nethercote71980f02004-01-24 18:18:54 +00001672 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001673 VG_(debugLog)(1, "main", "Initialise TT/TC\n");
1674 VG_(init_tt_tc)();
sewardjb5f6f512005-03-10 23:59:00 +00001675
sewardj45f4e7c2005-09-27 19:20:21 +00001676 //--------------------------------------------------------------
1677 // Initialise the redirect table.
1678 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
1679 // p: aspacem [so can change ownership of sysinfo pages]
1680 //--------------------------------------------------------------
1681 VG_(debugLog)(1, "main", "Initialise redirects\n");
sewardj0ec07f32006-01-12 12:32:32 +00001682 VG_(redir_initialise)();
nethercote71980f02004-01-24 18:18:54 +00001683
1684 //--------------------------------------------------------------
1685 // Allow GDB attach
sewardj95d86c02007-12-18 01:49:23 +00001686 // p: main_process_cmd_line_options() [for VG_(clo_wait_for_gdb)]
nethercote71980f02004-01-24 18:18:54 +00001687 //--------------------------------------------------------------
1688 /* Hook to delay things long enough so we can get the pid and
1689 attach GDB in another shell. */
1690 if (VG_(clo_wait_for_gdb)) {
sewardj95611ff2007-02-16 13:57:07 +00001691 Long iters;
1692 volatile Long q;
sewardj1fbc1a52005-04-25 02:05:54 +00001693 VG_(debugLog)(1, "main", "Wait for GDB\n");
sewardj93ab8572005-02-06 14:10:40 +00001694 VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
sewardj8211a572005-06-23 21:37:47 +00001695
1696# if defined(VGP_x86_linux)
1697 iters = 5;
sewardj2c48c7b2005-11-29 13:05:56 +00001698# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
sewardj8211a572005-06-23 21:37:47 +00001699 iters = 10;
1700# elif defined(VGP_ppc32_linux)
sewardjd714d2e2005-07-08 18:24:04 +00001701 iters = 5;
sewardj17c11042006-10-15 01:26:40 +00001702# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1703 iters = 4;
sewardj8211a572005-06-23 21:37:47 +00001704# else
sewardj17c11042006-10-15 01:26:40 +00001705# error "Unknown plat"
sewardj8211a572005-06-23 21:37:47 +00001706# endif
1707
1708 iters *= 1000*1000*1000;
1709 for (q = 0; q < iters; q++)
1710 ;
nethercote71980f02004-01-24 18:18:54 +00001711 }
1712
sewardjb5d320c2005-03-13 18:57:15 +00001713 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001714 // Search for file descriptors that are inherited from our parent
sewardj95d86c02007-12-18 01:49:23 +00001715 // p: main_process_cmd_line_options [for VG_(clo_track_fds)]
nethercote71980f02004-01-24 18:18:54 +00001716 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001717 if (VG_(clo_track_fds)) {
1718 VG_(debugLog)(1, "main", "Init preopened fds\n");
nethercote71980f02004-01-24 18:18:54 +00001719 VG_(init_preopened_fds)();
sewardj1fbc1a52005-04-25 02:05:54 +00001720 }
nethercote71980f02004-01-24 18:18:54 +00001721
1722 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001723 // Load debug info for the existing segments.
1724 // p: setup_code_redirect_table [so that redirs can be recorded]
1725 // p: mallocfree
1726 // p: probably: setup fds and process CLOs, so that logging works
sewardjf98e1c02008-10-25 16:22:41 +00001727 // p: initialise m_debuginfo
sewardj9c606bd2008-09-18 18:12:50 +00001728 //
1729 // While doing this, make a note of the debuginfo-handles that
1730 // come back from VG_(di_notify_mmap)/VG_(di_aix5_notify_segchange).
1731 // Later, in "Tell the tool about the initial client memory permissions"
1732 // (just below) we can then hand these handles off to the tool in
1733 // calls to VG_TRACK(new_mem_startup, ...). This gives the tool the
1734 // opportunity to make further queries to m_debuginfo before the
1735 // client is started, if it wants. We put this information into an
1736 // XArray, each handle along with the associated segment start address,
1737 // and search the XArray for the handles later, when calling
1738 // VG_TRACK(new_mem_startup, ...).
sewardj45f4e7c2005-09-27 19:20:21 +00001739 //--------------------------------------------------------------
1740 VG_(debugLog)(1, "main", "Load initial debug info\n");
sewardj9c606bd2008-09-18 18:12:50 +00001741
1742 tl_assert(!addr2dihandle);
1743 addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2",
1744 VG_(free), sizeof(Addr_n_ULong) );
1745 tl_assert(addr2dihandle);
1746
sewardj17c11042006-10-15 01:26:40 +00001747# if defined(VGO_linux)
sewardj45f4e7c2005-09-27 19:20:21 +00001748 { Addr* seg_starts;
1749 Int n_seg_starts;
sewardj9c606bd2008-09-18 18:12:50 +00001750 Addr_n_ULong anu;
sewardj45f4e7c2005-09-27 19:20:21 +00001751
1752 seg_starts = get_seg_starts( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001753 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00001754
sewardjf72cced2005-11-08 00:45:47 +00001755 /* show them all to the debug info reader. allow_SkFileV has to
1756 be True here so that we read info from the valgrind executable
1757 itself. */
sewardj9c606bd2008-09-18 18:12:50 +00001758 for (i = 0; i < n_seg_starts; i++) {
1759 anu.ull = VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/ );
1760 /* anu.ull holds the debuginfo handle returned by di_notify_mmap,
1761 if any. */
1762 if (anu.ull > 0) {
1763 anu.a = seg_starts[i];
1764 VG_(addToXA)( addr2dihandle, &anu );
1765 }
1766 }
sewardj45f4e7c2005-09-27 19:20:21 +00001767
1768 VG_(free)( seg_starts );
1769 }
sewardj17c11042006-10-15 01:26:40 +00001770# elif defined(VGO_aix5)
1771 { AixCodeSegChange* changes;
1772 Int changes_size, changes_used;
sewardj9c606bd2008-09-18 18:12:50 +00001773 Addr_n_ULong anu;
sewardj17c11042006-10-15 01:26:40 +00001774
1775 /* Find out how many AixCodeSegChange records we will need,
1776 and acquire them. */
1777 changes_size = VG_(am_aix5_reread_procmap_howmany_directives)();
sewardj9c606bd2008-09-18 18:12:50 +00001778 changes = VG_(malloc)("main.vm.3", changes_size * sizeof(AixCodeSegChange));
sewardj17c11042006-10-15 01:26:40 +00001779 vg_assert(changes);
1780
1781 /* Now re-read /proc/<pid>/map and acquire a change set */
1782 VG_(am_aix5_reread_procmap)( changes, &changes_used );
1783 vg_assert(changes_used >= 0 && changes_used <= changes_size);
1784
1785 /* And notify m_debuginfo of the changes. */
sewardj9c606bd2008-09-18 18:12:50 +00001786 for (i = 0; i < changes_used; i++) {
1787 anu.ull = VG_(di_aix5_notify_segchange)(
1788 changes[i].code_start,
1789 changes[i].code_len,
1790 changes[i].data_start,
1791 changes[i].data_len,
1792 changes[i].file_name,
1793 changes[i].mem_name,
1794 changes[i].is_mainexe,
1795 changes[i].acquire
1796 );
1797 if (anu.ull > 0) {
1798 tl_assert(changes[i].acquire);
1799 anu.a = changes[i].code_start; /* is this correct? */
1800 VG_(addToXA)( addr2dihandle, &anu );
1801 }
1802 }
sewardj17c11042006-10-15 01:26:40 +00001803
1804 VG_(free)(changes);
1805 }
1806# else
1807# error Unknown OS
1808# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001809
1810 //--------------------------------------------------------------
1811 // Tell aspacem of ownership change of the asm helpers, so that
1812 // m_translate allows them to be translated. However, only do this
1813 // after the initial debug info read, since making a hole in the
1814 // address range for the stage2 binary confuses the debug info reader.
1815 // p: aspacem
1816 //--------------------------------------------------------------
1817 { Bool change_ownership_v_c_OK;
sewardj1a85f4f2006-01-12 21:15:35 +00001818 Addr co_start = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
1819 Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
sewardj45f4e7c2005-09-27 19:20:21 +00001820 VG_(debugLog)(1,"redir",
1821 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
1822 (ULong)co_start, (ULong)co_endPlus-1 );
1823
1824 change_ownership_v_c_OK
1825 = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
1826 vg_assert(change_ownership_v_c_OK);
1827 }
1828
1829 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001830 // Initialise the scheduler (phase 1) [generates tid_main]
1831 // p: none, afaics
1832 //--------------------------------------------------------------
1833 VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
1834 tid_main = VG_(scheduler_init_phase1)();
1835 vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
1836 && tid_main != VG_INVALID_THREADID);
1837 /* Tell the tool about tid_main */
1838 VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
1839
1840 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001841 // Tell the tool about the initial client memory permissions
1842 // p: aspacem
1843 // p: mallocfree
1844 // p: setup_client_stack
1845 // p: setup_client_dataseg
sewardj9c606bd2008-09-18 18:12:50 +00001846 //
1847 // For each segment we tell the client about, look up in
1848 // addr2dihandle as created above, to see if there's a debuginfo
1849 // handle associated with the segment, that we can hand along
1850 // to the tool, to be helpful.
sewardj45f4e7c2005-09-27 19:20:21 +00001851 //--------------------------------------------------------------
1852 VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
1853 { Addr* seg_starts;
1854 Int n_seg_starts;
sewardj45f4e7c2005-09-27 19:20:21 +00001855
sewardj9c606bd2008-09-18 18:12:50 +00001856 tl_assert(addr2dihandle);
1857
tom7c1a19a2008-01-02 10:13:04 +00001858 /* Mark the main thread as running while we tell the tool about
1859 the client memory so that the tool can associate that memory
1860 with the main thread. */
1861 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
1862 VG_(running_tid) = tid_main;
1863
sewardj45f4e7c2005-09-27 19:20:21 +00001864 seg_starts = get_seg_starts( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001865 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00001866
1867 /* show interesting ones to the tool */
1868 for (i = 0; i < n_seg_starts; i++) {
sewardj9c606bd2008-09-18 18:12:50 +00001869 Word j, n;
sewardj12ab7652006-10-17 02:10:42 +00001870 NSegment const* seg
sewardj17c11042006-10-15 01:26:40 +00001871 = VG_(am_find_nsegment)( seg_starts[i] );
sewardj45f4e7c2005-09-27 19:20:21 +00001872 vg_assert(seg);
sewardj9c606bd2008-09-18 18:12:50 +00001873 vg_assert(seg->start == seg_starts[i] );
sewardj45f4e7c2005-09-27 19:20:21 +00001874 if (seg->kind == SkFileC || seg->kind == SkAnonC) {
1875 VG_(debugLog)(2, "main",
1876 "tell tool about %010lx-%010lx %c%c%c\n",
1877 seg->start, seg->end,
1878 seg->hasR ? 'r' : '-',
1879 seg->hasW ? 'w' : '-',
1880 seg->hasX ? 'x' : '-' );
sewardj9c606bd2008-09-18 18:12:50 +00001881 /* search addr2dihandle to see if we have an entry
1882 matching seg->start. */
1883 n = VG_(sizeXA)( addr2dihandle );
1884 for (j = 0; j < n; j++) {
1885 Addr_n_ULong* anl = VG_(indexXA)( addr2dihandle, j );
1886 if (anl->a == seg->start) {
1887 tl_assert(anl->ull > 0); /* check it's a valid handle */
1888 break;
1889 }
1890 }
1891 vg_assert(j >= 0 && j <= n);
sewardj45f4e7c2005-09-27 19:20:21 +00001892 VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
sewardj9c606bd2008-09-18 18:12:50 +00001893 seg->hasR, seg->hasW, seg->hasX,
1894 /* and the retrieved debuginfo handle, if any */
1895 j < n
1896 ? ((Addr_n_ULong*)VG_(indexXA)( addr2dihandle, j ))->ull
1897 : 0 );
sewardj45f4e7c2005-09-27 19:20:21 +00001898 }
1899 }
1900
1901 VG_(free)( seg_starts );
sewardj9c606bd2008-09-18 18:12:50 +00001902 VG_(deleteXA)( addr2dihandle );
sewardj45f4e7c2005-09-27 19:20:21 +00001903
1904 /* Also do the initial stack permissions. */
sewardj12ab7652006-10-17 02:10:42 +00001905 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00001906 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj17c11042006-10-15 01:26:40 +00001907 vg_assert(seg);
1908 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00001909 vg_assert(the_iifii.initial_client_SP >= seg->start);
1910 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardj17c11042006-10-15 01:26:40 +00001911# if defined(VGO_aix5)
1912 VG_(clstk_base) = seg->start;
1913 VG_(clstk_end) = seg->end;
1914# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001915
sewardj17c11042006-10-15 01:26:40 +00001916 /* Stuff below the initial SP is unaddressable. Take into
1917 account any ABI-mandated space below the stack pointer that
1918 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
1919 will have allocated an extra page if a red zone is required,
1920 to be on the safe side. */
sewardjf9d2f9b2006-11-17 20:00:57 +00001921 vg_assert(the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
1922 >= seg->start);
sewardj17c11042006-10-15 01:26:40 +00001923 VG_TRACK( die_mem_stack,
1924 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00001925 the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
1926 - seg->start );
sewardj17c11042006-10-15 01:26:40 +00001927 VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
1928 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00001929 the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
sewardj17c11042006-10-15 01:26:40 +00001930 }
sewardj45f4e7c2005-09-27 19:20:21 +00001931
1932 /* Also the assembly helpers. */
1933 VG_TRACK( new_mem_startup,
1934 (Addr)&VG_(trampoline_stuff_start),
sewardjc6527d62006-02-13 17:54:31 +00001935 (Addr)&VG_(trampoline_stuff_end)
1936 - (Addr)&VG_(trampoline_stuff_start),
sewardj45f4e7c2005-09-27 19:20:21 +00001937 False, /* readable? */
1938 False, /* writable? */
sewardj9c606bd2008-09-18 18:12:50 +00001939 True /* executable? */,
1940 0 /* di_handle: no associated debug info */ );
tom7c1a19a2008-01-02 10:13:04 +00001941
1942 /* Clear the running thread indicator */
1943 VG_(running_tid) = VG_INVALID_THREADID;
1944 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
sewardj45f4e7c2005-09-27 19:20:21 +00001945 }
1946
1947 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001948 // Initialise the scheduler (phase 2)
1949 // p: Initialise the scheduler (phase 1) [for tid_main]
nethercote71980f02004-01-24 18:18:54 +00001950 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
sewardj45f4e7c2005-09-27 19:20:21 +00001951 // p: setup_client_stack
nethercote71980f02004-01-24 18:18:54 +00001952 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001953 VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
sewardj12ab7652006-10-17 02:10:42 +00001954 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00001955 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj45f4e7c2005-09-27 19:20:21 +00001956 vg_assert(seg);
1957 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00001958 vg_assert(the_iifii.initial_client_SP >= seg->start);
1959 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardjde764e82007-11-09 23:13:22 +00001960 VG_(scheduler_init_phase2)( tid_main,
1961 seg->end, the_iifii.clstack_max_size );
sewardj45f4e7c2005-09-27 19:20:21 +00001962 }
nethercote71980f02004-01-24 18:18:54 +00001963
1964 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001965 // Set up state for the root thread
sewardjb5f6f512005-03-10 23:59:00 +00001966 // p: ?
sewardj17c11042006-10-15 01:26:40 +00001967 // setup_scheduler() [for sched-specific thread 1 stuff]
sewardjf9d2f9b2006-11-17 20:00:57 +00001968 // VG_(ii_create_image) [for 'the_iicii' initial info]
sewardj2a99cf62004-11-24 10:44:19 +00001969 //--------------------------------------------------------------
sewardjf9d2f9b2006-11-17 20:00:57 +00001970 VG_(debugLog)(1, "main", "Finalise initial image\n");
1971 VG_(ii_finalise_image)( the_iifii );
njnea4b28c2004-11-30 16:04:58 +00001972
sewardj2a99cf62004-11-24 10:44:19 +00001973 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001974 // Initialise the signal handling subsystem
sewardjb5f6f512005-03-10 23:59:00 +00001975 // p: n/a
nethercote71980f02004-01-24 18:18:54 +00001976 //--------------------------------------------------------------
1977 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
sewardj1fbc1a52005-04-25 02:05:54 +00001978 VG_(debugLog)(1, "main", "Initialise signal management\n");
nethercote71980f02004-01-24 18:18:54 +00001979 VG_(sigstartup_actions)();
1980
1981 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001982 // Read suppression file
sewardj95d86c02007-12-18 01:49:23 +00001983 // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
nethercote71980f02004-01-24 18:18:54 +00001984 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001985 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
1986 VG_(debugLog)(1, "main", "Load suppressions\n");
nethercote71980f02004-01-24 18:18:54 +00001987 VG_(load_suppressions)();
sewardj1fbc1a52005-04-25 02:05:54 +00001988 }
nethercote71980f02004-01-24 18:18:54 +00001989
1990 //--------------------------------------------------------------
rjwalsh0140af52005-06-04 20:42:33 +00001991 // register client stack
1992 //--------------------------------------------------------------
njn945ed2e2005-06-24 03:28:30 +00001993 VG_(clstk_id) = VG_(register_stack)(VG_(clstk_base), VG_(clstk_end));
rjwalsh0140af52005-06-04 20:42:33 +00001994
1995 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001996 // Show the address space state so far
1997 //--------------------------------------------------------------
1998 VG_(debugLog)(1, "main", "\n");
1999 VG_(debugLog)(1, "main", "\n");
2000 VG_(am_show_nsegments)(1,"Memory layout at client startup");
2001 VG_(debugLog)(1, "main", "\n");
2002 VG_(debugLog)(1, "main", "\n");
2003
2004 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002005 // Run!
2006 //--------------------------------------------------------------
sewardj71bc3cb2005-05-19 00:25:45 +00002007 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002008 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00002009 VG_(elapsed_wallclock_time)(buf);
barta0b6b2c2008-07-07 06:49:24 +00002010 VG_(message_no_f_c)(Vg_UserMsg,
2011 "<status>\n"
2012 " <state>RUNNING</state>\n"
2013 " <time>%t</time>\n"
2014 "</status>",
2015 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00002016 VG_(message)(Vg_UserMsg, "");
2017 }
2018
sewardj1fbc1a52005-04-25 02:05:54 +00002019 VG_(debugLog)(1, "main", "Running thread 1\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002020
sewardj1d887112005-05-30 21:44:08 +00002021 /* As a result of the following call, the last thread standing
sewardj1ae3f3a2005-09-28 10:47:38 +00002022 eventually winds up running shutdown_actions_NORETURN
2023 just below. Unfortunately, simply exporting said function
2024 causes m_main to be part of a module cycle, which is pretty
2025 nonsensical. So instead of doing that, the address of said
2026 function is stored in a global variable 'owned' by m_syswrap,
2027 and it uses that function pointer to get back here when it needs
2028 to. */
2029
2030 /* Set continuation address. */
2031 VG_(address_of_m_main_shutdown_actions_NORETURN)
2032 = & shutdown_actions_NORETURN;
2033
2034 /* Run the first thread, eventually ending up at the continuation
2035 address. */
njnaf839f52005-06-23 03:27:57 +00002036 VG_(main_thread_wrapper_NORETURN)(1);
nethercote71980f02004-01-24 18:18:54 +00002037
sewardj1d887112005-05-30 21:44:08 +00002038 /*NOTREACHED*/
2039 vg_assert(0);
sewardjb5f6f512005-03-10 23:59:00 +00002040}
2041
sewardj17c11042006-10-15 01:26:40 +00002042/* Do everything which needs doing when the last thread exits or when
2043 a thread exits requesting a complete process exit (exit on AIX).
2044
2045 We enter here holding The Lock. For the case VgSrc_ExitProcess we
2046 must never release it, because to do so would allow other threads
2047 to continue after the system is ostensibly shut down. So we must
2048 go to our grave, so to speak, holding the lock.
2049
2050 In fact, there is never any point in releasing the lock at this
2051 point - we have it, we're shutting down the entire system, and
2052 for the case VgSrc_ExitProcess doing so positively causes trouble.
2053 So don't.
2054
2055 The final_tidyup call makes a bit of a nonsense of the ExitProcess
2056 case, since it will run the libc_freeres function, thus allowing
2057 other lurking threads to run again. Hmm. */
sewardjb5f6f512005-03-10 23:59:00 +00002058
sewardj1ae3f3a2005-09-28 10:47:38 +00002059static
2060void shutdown_actions_NORETURN( ThreadId tid,
2061 VgSchedReturnCode tids_schedretcode )
sewardjb5f6f512005-03-10 23:59:00 +00002062{
sewardj1d887112005-05-30 21:44:08 +00002063 VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
sewardj17c11042006-10-15 01:26:40 +00002064 VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
sewardj1d887112005-05-30 21:44:08 +00002065
sewardjb5f6f512005-03-10 23:59:00 +00002066 vg_assert(VG_(is_running_thread)(tid));
2067
sewardj12ab7652006-10-17 02:10:42 +00002068 vg_assert(tids_schedretcode == VgSrc_ExitThread
2069 || tids_schedretcode == VgSrc_ExitProcess
2070 || tids_schedretcode == VgSrc_FatalSig );
sewardjb5f6f512005-03-10 23:59:00 +00002071
sewardj12ab7652006-10-17 02:10:42 +00002072 if (tids_schedretcode == VgSrc_ExitThread) {
sewardjb5f6f512005-03-10 23:59:00 +00002073
sewardj17c11042006-10-15 01:26:40 +00002074 // We are the last surviving thread. Right?
2075 vg_assert( VG_(count_living_threads)() == 1 );
sewardjb5f6f512005-03-10 23:59:00 +00002076
sewardj17c11042006-10-15 01:26:40 +00002077 // Wait for all other threads to exit.
2078 // jrs: Huh? but they surely are already gone
2079 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002080
sewardj17c11042006-10-15 01:26:40 +00002081 // Clean the client up before the final report
2082 // this causes the libc_freeres function to run
2083 final_tidyup(tid);
2084
2085 /* be paranoid */
2086 vg_assert(VG_(is_running_thread)(tid));
2087 vg_assert(VG_(count_living_threads)() == 1);
2088
2089 } else {
2090
2091 // We may not be the last surviving thread. However, we
2092 // want to shut down the entire process. We hold the lock
2093 // and we need to keep hold of it all the way out, in order
2094 // that none of the other threads ever run again.
2095 vg_assert( VG_(count_living_threads)() >= 1 );
2096
sewardj17c11042006-10-15 01:26:40 +00002097 // Clean the client up before the final report
2098 // this causes the libc_freeres function to run
2099 // perhaps this is unsafe, as per comment above
2100 final_tidyup(tid);
2101
2102 /* be paranoid */
2103 vg_assert(VG_(is_running_thread)(tid));
2104 vg_assert(VG_(count_living_threads)() >= 1);
2105 }
sewardjb5f6f512005-03-10 23:59:00 +00002106
2107 VG_(threads)[tid].status = VgTs_Empty;
nethercote71980f02004-01-24 18:18:54 +00002108 //--------------------------------------------------------------
2109 // Finalisation: cleanup, messages, etc. Order no so important, only
2110 // affects what order the messages come.
2111 //--------------------------------------------------------------
2112 if (VG_(clo_verbosity) > 0)
2113 VG_(message)(Vg_UserMsg, "");
2114
sewardj71bc3cb2005-05-19 00:25:45 +00002115 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002116 HChar buf[50];
sewardj9f297ca2005-05-20 02:29:52 +00002117 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
2118 VG_(show_error_counts_as_XML)();
2119 VG_(message)(Vg_UserMsg, "");
2120 }
sewardj592ae092005-11-08 19:01:44 +00002121 VG_(elapsed_wallclock_time)(buf);
barta0b6b2c2008-07-07 06:49:24 +00002122 VG_(message_no_f_c)(Vg_UserMsg,
2123 "<status>\n"
2124 " <state>FINISHED</state>\n"
2125 " <time>%t</time>\n"
2126 "</status>",
2127 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00002128 VG_(message)(Vg_UserMsg, "");
2129 }
2130
nethercote71980f02004-01-24 18:18:54 +00002131 /* Print out file descriptor summary and stats. */
2132 if (VG_(clo_track_fds))
nethercote3a42fb82004-08-03 18:08:50 +00002133 VG_(show_open_fds)();
nethercote71980f02004-01-24 18:18:54 +00002134
njn95ec8702004-11-22 16:46:13 +00002135 if (VG_(needs).core_errors || VG_(needs).tool_errors)
nethercote71980f02004-01-24 18:18:54 +00002136 VG_(show_all_errors)();
2137
njn51d827b2005-05-09 01:02:08 +00002138 VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
nethercote71980f02004-01-24 18:18:54 +00002139
sewardj71bc3cb2005-05-19 00:25:45 +00002140 if (VG_(clo_xml)) {
2141 VG_(message)(Vg_UserMsg, "");
2142 VG_(message)(Vg_UserMsg, "</valgrindoutput>");
2143 VG_(message)(Vg_UserMsg, "");
2144 }
2145
nethercote885dd912004-08-03 23:14:00 +00002146 VG_(sanity_check_general)( True /*include expensive checks*/ );
nethercote71980f02004-01-24 18:18:54 +00002147
2148 if (VG_(clo_verbosity) > 1)
nethercote3a42fb82004-08-03 18:08:50 +00002149 print_all_stats();
nethercote71980f02004-01-24 18:18:54 +00002150
sewardj9c606bd2008-09-18 18:12:50 +00002151 /* Show a profile of the heap(s) at shutdown. Optionally, first
2152 throw away all the debug info, as that makes it easy to spot
2153 leaks in the debuginfo reader. */
2154 if (VG_(clo_profile_heap)) {
2155 if (0) VG_(di_discard_ALL_debuginfo)();
2156 VG_(print_arena_cc_analysis)();
2157 }
2158
njn2025cf92005-06-26 20:44:48 +00002159 if (VG_(clo_profile_flags) > 0) {
sewardj5471ec62006-10-17 13:58:17 +00002160 #define N_MAX 200
njn2025cf92005-06-26 20:44:48 +00002161 BBProfEntry tops[N_MAX];
2162 ULong score_total = VG_(get_BB_profile) (tops, N_MAX);
2163 show_BB_profile(tops, N_MAX, score_total);
2164 }
sewardjfa8ec112005-01-19 11:55:34 +00002165
sewardj8b635a42004-11-22 19:01:47 +00002166 /* Print Vex storage stats */
sewardjbf426512005-01-17 18:35:30 +00002167 if (0)
2168 LibVEX_ShowAllocStats();
sewardj1d887112005-05-30 21:44:08 +00002169
njn8aa35852005-06-10 22:59:56 +00002170 /* Ok, finally exit in the os-specific way, according to the scheduler's
2171 return code. In short, if the (last) thread exited by calling
2172 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2173 signal, terminate the entire system with that same fatal signal. */
2174 VG_(debugLog)(1, "core_os",
njn7b85dd52005-06-12 17:26:29 +00002175 "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
njn8aa35852005-06-10 22:59:56 +00002176
njn8aa35852005-06-10 22:59:56 +00002177 switch (tids_schedretcode) {
sewardj12ab7652006-10-17 02:10:42 +00002178 case VgSrc_ExitThread: /* the normal way out (Linux) */
2179 case VgSrc_ExitProcess: /* the normal way out (AIX) */
sewardjb9779082006-05-12 23:50:15 +00002180 /* Change the application return code to user's return code,
2181 if an error was found */
2182 if (VG_(clo_error_exitcode) > 0
2183 && VG_(get_n_errs_found)() > 0) {
2184 VG_(exit)( VG_(clo_error_exitcode) );
2185 } else {
2186 /* otherwise, return the client's exit code, in the normal
2187 way. */
2188 VG_(exit)( VG_(threads)[tid].os_state.exitcode );
2189 }
njn8aa35852005-06-10 22:59:56 +00002190 /* NOT ALIVE HERE! */
sewardj17c11042006-10-15 01:26:40 +00002191 VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
njn8aa35852005-06-10 22:59:56 +00002192 break; /* what the hell :) */
2193
2194 case VgSrc_FatalSig:
2195 /* We were killed by a fatal signal, so replicate the effect */
2196 vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
2197 VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
2198 VG_(core_panic)("main(): signal was supposed to be fatal");
2199 break;
2200
2201 default:
2202 VG_(core_panic)("main(): unexpected scheduler return code");
2203 }
njne96be672005-05-08 19:08:54 +00002204}
sewardj8b635a42004-11-22 19:01:47 +00002205
sewardj1ae3f3a2005-09-28 10:47:38 +00002206/* -------------------- */
2207
2208/* Final clean-up before terminating the process.
2209 Clean up the client by calling __libc_freeres() (if requested)
2210 This is Linux-specific?
2211*/
2212static void final_tidyup(ThreadId tid)
2213{
sewardjcf951812006-01-17 02:22:21 +00002214# if defined(VGP_ppc64_linux)
2215 Addr r2;
2216# endif
sewardj0ec07f32006-01-12 12:32:32 +00002217 Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
sewardj1ae3f3a2005-09-28 10:47:38 +00002218
2219 vg_assert(VG_(is_running_thread)(tid));
2220
2221 if ( !VG_(needs).libc_freeres ||
2222 !VG_(clo_run_libc_freeres) ||
sewardj0ec07f32006-01-12 12:32:32 +00002223 0 == __libc_freeres_wrapper )
sewardj1ae3f3a2005-09-28 10:47:38 +00002224 return; /* can't/won't do it */
sewardj17c11042006-10-15 01:26:40 +00002225# if defined(VGO_aix5)
2226 return; /* inapplicable on non-Linux platforms */
2227# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002228
sewardjcf951812006-01-17 02:22:21 +00002229# if defined(VGP_ppc64_linux)
2230 r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
2231 if (r2 == 0) {
2232 VG_(message)(Vg_UserMsg,
2233 "Caught __NR_exit, but can't run __libc_freeres()");
2234 VG_(message)(Vg_UserMsg,
2235 " since cannot establish TOC pointer for it.");
2236 return;
2237 }
2238# endif
2239
sewardj1ae3f3a2005-09-28 10:47:38 +00002240 if (VG_(clo_verbosity) > 2 ||
2241 VG_(clo_trace_syscalls) ||
2242 VG_(clo_trace_sched))
2243 VG_(message)(Vg_DebugMsg,
2244 "Caught __NR_exit; running __libc_freeres()");
2245
sewardj0ec07f32006-01-12 12:32:32 +00002246 /* set thread context to point to libc_freeres_wrapper */
sewardj1a85f4f2006-01-12 21:15:35 +00002247 /* ppc64-linux note: __libc_freeres_wrapper gives us the real
2248 function entry point, not a fn descriptor, so can use it
2249 directly. However, we need to set R2 (the toc pointer)
2250 appropriately. */
sewardj1ae3f3a2005-09-28 10:47:38 +00002251 VG_(set_IP)(tid, __libc_freeres_wrapper);
sewardjcf951812006-01-17 02:22:21 +00002252# if defined(VGP_ppc64_linux)
2253 VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
2254# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002255
2256 /* Block all blockable signals by copying the real block state into
2257 the thread's block state*/
2258 VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
2259 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
2260
2261 /* and restore handlers to default */
2262 VG_(set_default_handler)(VKI_SIGSEGV);
2263 VG_(set_default_handler)(VKI_SIGBUS);
2264 VG_(set_default_handler)(VKI_SIGILL);
2265 VG_(set_default_handler)(VKI_SIGFPE);
2266
2267 // We were exiting, so assert that...
2268 vg_assert(VG_(is_exiting)(tid));
2269 // ...but now we're not again
2270 VG_(threads)[tid].exitreason = VgSrc_None;
2271
2272 // run until client thread exits - ideally with LIBC_FREERES_DONE,
2273 // but exit/exitgroup/signal will do
2274 VG_(scheduler)(tid);
2275
2276 vg_assert(VG_(is_exiting)(tid));
2277}
2278
sewardj45f4e7c2005-09-27 19:20:21 +00002279
2280/*====================================================================*/
sewardj17c11042006-10-15 01:26:40 +00002281/*=== Getting to main() alive: LINUX (for AIX5 see below) ===*/
sewardj45f4e7c2005-09-27 19:20:21 +00002282/*====================================================================*/
2283
sewardj17c11042006-10-15 01:26:40 +00002284#if defined(VGO_linux)
2285
sewardj45f4e7c2005-09-27 19:20:21 +00002286/* If linking of the final executables is done with glibc present,
2287 then Valgrind starts at main() above as usual, and all of the
2288 following code is irrelevant.
2289
2290 However, this is not the intended mode of use. The plan is to
2291 avoid linking against glibc, by giving gcc the flags
2292 -nodefaultlibs -lgcc -nostartfiles at startup.
2293
2294 From this derive two requirements:
2295
2296 1. gcc may emit calls to memcpy and memset to deal with structure
2297 assignments etc. Since we have chosen to ignore all the
2298 "normal" supporting libraries, we have to provide our own
2299 implementations of them. No problem.
2300
2301 2. We have to provide a symbol "_start", to which the kernel
2302 hands control at startup. Hence the code below.
2303*/
2304
2305/* ---------------- Requirement 1 ---------------- */
2306
sewardj17c11042006-10-15 01:26:40 +00002307void* memcpy(void *dest, const void *src, SizeT n);
2308void* memcpy(void *dest, const void *src, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002309 return VG_(memcpy)(dest,src,n);
2310}
sewardj17c11042006-10-15 01:26:40 +00002311void* memset(void *s, int c, SizeT n);
2312void* memset(void *s, int c, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002313 return VG_(memset)(s,c,n);
2314}
2315
2316/* ---------------- Requirement 2 ---------------- */
2317
2318/* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2319 comment, which explains how the stack looks right at process start
2320 (when _start is jumped to). Hence _start passes %esp to
sewardj17c11042006-10-15 01:26:40 +00002321 _start_in_C_linux, which extracts argc/argv/envp and starts up
sewardj45f4e7c2005-09-27 19:20:21 +00002322 correctly. */
2323
2324/* This is the canonical entry point, usually the first thing in the text
2325 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2326 point runs, most registers' values are unspecified, except for:
2327
2328 %edx Contains a function pointer to be registered with `atexit'.
2329 This is how the dynamic linker arranges to have DT_FINI
2330 functions called for shared libraries that have been loaded
2331 before this code runs.
2332
2333 %esp The stack contains the arguments and environment:
2334 0(%esp) argc
2335 4(%esp) argv[0]
2336 ...
2337 (4*argc)(%esp) NULL
2338 (4*(argc+1))(%esp) envp[0]
2339 ...
2340 NULL
2341*/
2342
2343/* The kernel hands control to _start, which extracts the initial
sewardj17c11042006-10-15 01:26:40 +00002344 stack pointer and calls onwards to _start_in_C_linux. This also switches
sewardja48a4932005-09-29 11:09:56 +00002345 the new stack. */
sewardj45f4e7c2005-09-27 19:20:21 +00002346#if defined(VGP_x86_linux)
2347asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002348 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002349 "\t.globl _start\n"
2350 "\t.type _start,@function\n"
2351 "_start:\n"
2352 /* set up the new stack in %eax */
sewardjfdf91b42005-09-28 00:53:09 +00002353 "\tmovl $vgPlain_interim_stack, %eax\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002354 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2355 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2356 "\tsubl $16, %eax\n"
2357 "\tandl $~15, %eax\n"
2358 /* install it, and collect the original one */
2359 "\txchgl %eax, %esp\n"
sewardj17c11042006-10-15 01:26:40 +00002360 /* call _start_in_C_linux, passing it the startup %esp */
sewardj45f4e7c2005-09-27 19:20:21 +00002361 "\tpushl %eax\n"
sewardj17c11042006-10-15 01:26:40 +00002362 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002363 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002364 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002365);
2366#elif defined(VGP_amd64_linux)
2367asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002368 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002369 "\t.globl _start\n"
2370 "\t.type _start,@function\n"
2371 "_start:\n"
2372 /* set up the new stack in %rdi */
sewardjfdf91b42005-09-28 00:53:09 +00002373 "\tmovq $vgPlain_interim_stack, %rdi\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002374 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2375 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2376 "\tandq $~15, %rdi\n"
2377 /* install it, and collect the original one */
2378 "\txchgq %rdi, %rsp\n"
sewardj17c11042006-10-15 01:26:40 +00002379 /* call _start_in_C_linux, passing it the startup %rsp */
2380 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002381 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002382 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002383);
sewardja48a4932005-09-29 11:09:56 +00002384#elif defined(VGP_ppc32_linux)
2385asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002386 ".text\n"
sewardja48a4932005-09-29 11:09:56 +00002387 "\t.globl _start\n"
2388 "\t.type _start,@function\n"
2389 "_start:\n"
2390 /* set up the new stack in r16 */
2391 "\tlis 16,vgPlain_interim_stack@ha\n"
2392 "\tla 16,vgPlain_interim_stack@l(16)\n"
2393 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2394 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2395 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2396 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2397 "\tadd 16,17,16\n"
2398 "\tadd 16,18,16\n"
2399 "\trlwinm 16,16,0,0,27\n"
2400 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2401 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2402 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002403 call _start_in_C_linux, passing it the initial SP. */
sewardja48a4932005-09-29 11:09:56 +00002404 "\tmr 3,1\n"
2405 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002406 "\tbl _start_in_C_linux\n"
sewardja48a4932005-09-29 11:09:56 +00002407 "\ttrap\n"
sewardj2fedc642005-11-19 02:02:57 +00002408 ".previous\n"
sewardja48a4932005-09-29 11:09:56 +00002409);
sewardj2c48c7b2005-11-29 13:05:56 +00002410#elif defined(VGP_ppc64_linux)
2411asm("\n"
cerion21082042005-12-06 19:07:08 +00002412 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2413 So we must have one, and that is what goes into the .opd section. */
cerion297c88f2005-12-22 15:53:12 +00002414 "\t.align 2\n"
cerion21082042005-12-06 19:07:08 +00002415 "\t.global _start\n"
2416 "\t.section \".opd\",\"aw\"\n"
2417 "\t.align 3\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002418 "_start:\n"
cerion21082042005-12-06 19:07:08 +00002419 "\t.quad ._start,.TOC.@tocbase,0\n"
2420 "\t.previous\n"
2421 "\t.type ._start,@function\n"
2422 "\t.global ._start\n"
2423 "._start:\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002424 /* set up the new stack in r16 */
2425 "\tlis 16, vgPlain_interim_stack@highest\n"
2426 "\tori 16,16,vgPlain_interim_stack@higher\n"
2427 "\tsldi 16,16,32\n"
2428 "\toris 16,16,vgPlain_interim_stack@h\n"
2429 "\tori 16,16,vgPlain_interim_stack@l\n"
2430 "\txor 17,17,17\n"
2431 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2432 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2433 "\txor 18,18,18\n"
2434 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2435 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2436 "\tadd 16,17,16\n"
2437 "\tadd 16,18,16\n"
2438 "\trldicr 16,16,0,59\n"
2439 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2440 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2441 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002442 call _start_in_C_linux, passing it the initial SP. */
sewardj2c48c7b2005-11-29 13:05:56 +00002443 "\tmr 3,1\n"
2444 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002445 "\tbl ._start_in_C_linux\n"
cerion21082042005-12-06 19:07:08 +00002446 "\tnop\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002447 "\ttrap\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002448);
sewardj45f4e7c2005-09-27 19:20:21 +00002449#else
2450#error "_start: needs implementation on this platform"
2451#endif
2452
sewardje66f2e02006-12-30 17:45:08 +00002453/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
2454#define _GNU_SOURCE
2455#define _FILE_OFFSET_BITS 64
2456/* This is in order to get AT_NULL and AT_PAGESIZE. */
2457#include <elf.h>
2458/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
2459
sewardj45f4e7c2005-09-27 19:20:21 +00002460/* Avoid compiler warnings: this fn _is_ used, but labelling it
2461 'static' causes gcc to complain it isn't. */
sewardj17c11042006-10-15 01:26:40 +00002462void _start_in_C_linux ( UWord* pArgc );
2463void _start_in_C_linux ( UWord* pArgc )
sewardj45f4e7c2005-09-27 19:20:21 +00002464{
2465 Int r;
2466 Word argc = pArgc[0];
2467 HChar** argv = (HChar**)&pArgc[1];
2468 HChar** envp = (HChar**)&pArgc[1+argc+1];
sewardjf9d2f9b2006-11-17 20:00:57 +00002469
2470 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2471 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2472
2473 the_iicii.sp_at_startup = (Addr)pArgc;
2474
sewardje66f2e02006-12-30 17:45:08 +00002475# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
2476 {
2477 /* ppc/ppc64 can be configured with different page sizes.
2478 Determine this early. This is an ugly hack and really should
2479 be moved into valgrind_main. */
2480 UWord *sp = &pArgc[1+argc+1];
2481 while (*sp++ != 0)
2482 ;
2483 for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
2484 if (*sp == AT_PAGESZ) {
2485 VKI_PAGE_SIZE = sp[1];
2486 for (VKI_PAGE_SHIFT = 12;
2487 VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
2488 if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
2489 break;
2490 }
2491 }
2492# endif
2493
sewardjf9d2f9b2006-11-17 20:00:57 +00002494 r = valgrind_main( (Int)argc, argv, envp );
sewardj17c11042006-10-15 01:26:40 +00002495 /* NOTREACHED */
sewardj45f4e7c2005-09-27 19:20:21 +00002496 VG_(exit)(r);
2497}
2498
sewardj17c11042006-10-15 01:26:40 +00002499#endif /* defined(VGO_linux) */
2500
2501
2502/*====================================================================*/
2503/*=== Getting to main() alive: AIX5 ===*/
2504/*====================================================================*/
2505
2506#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
2507
2508/* This is somewhat simpler than the Linux case. _start_valgrind
2509 receives control from the magic piece of code created in this
2510 process' address space by the launcher, via use of ptrace(). At
2511 the point of entry:
2512
2513 - the initial client process image is in memory and ready to roll,
2514 except that we've partially trashed its integer register state
2515 in order to get this far. So ..
2516
2517 - intregs37 holds the client's initial integer register state, so
2518 we can restore it before starting the client on the VCPU.
2519
2520 - we're on the client's stack. This is not good; therefore the
2521 first order of business is to switch to our temporary stack.
2522
2523 - the client's initial argc/v/envp is in r3/r4/r5 (32 bit mode) or
2524 r14/r15/r16 (64 bit mode). They are pulled out of the stashed
2525 integer register state and passed to our main().
2526
2527 The launcher will have played some games with argv. If the launcher
2528 ($prefix/bin/valgrind) was started like this
2529
2530 valgrind [args-for-V] app [args-for-app]
2531
2532 then the launcher will have started the client as
2533
2534 app [args-for-V] app [args-for-app]
2535
2536 m_initimg will have to mess with the client's initial r4/r5
2537 (32-bit) or r15/r16 (64-bit) so that it believes it was execd as
2538 "app [args-for-app]". Well, that's no big deal.
2539*/
2540
2541#include "launcher-aix5-bootblock.h"
2542
2543void _start_in_C_aix5 ( AIX5Bootblock* bootblock );
2544void _start_in_C_aix5 ( AIX5Bootblock* bootblock )
2545{
2546 Int r;
2547 ULong* intregs37;
2548 UWord argc, argv, envp;
2549 __NR_getpid = bootblock->__NR_getpid;
2550 __NR_write = bootblock->__NR_write;
2551 __NR_exit = bootblock->__NR_exit;
2552 __NR_open = bootblock->__NR_open;
2553 __NR_read = bootblock->__NR_read;
2554 __NR_close = bootblock->__NR_close;
sewardjf9d2f9b2006-11-17 20:00:57 +00002555
2556 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2557 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2558
sewardj17c11042006-10-15 01:26:40 +00002559 intregs37 = &bootblock->iregs_pc_cr_lr_ctr_xer[0];
sewardjf9d2f9b2006-11-17 20:00:57 +00002560 the_iicii.intregs37 = intregs37;
2561 the_iicii.bootblock = (void*)bootblock;
2562 the_iicii.adler32_exp = bootblock->adler32;
2563
2564 /* Not important on AIX. */
2565 the_iicii.sp_at_startup = (Addr)0x31415927ULL;
2566
sewardj17c11042006-10-15 01:26:40 +00002567# if defined(VGP_ppc32_aix5)
2568 argc = (UWord)intregs37[3]; /* client's r3 == argc */
2569 argv = (UWord)intregs37[4];
2570 envp = (UWord)intregs37[5];
2571# else /* defined(VGP_ppc64_aix5) */
2572 argc = (UWord)intregs37[14]; /* client's r14 == argc */
2573 argv = (UWord)intregs37[15];
2574 envp = (UWord)intregs37[16];
2575# endif
sewardjf9d2f9b2006-11-17 20:00:57 +00002576
2577 r = valgrind_main( (Int)argc, (HChar**)argv, (HChar**)envp );
2578
sewardj17c11042006-10-15 01:26:40 +00002579 /* NOTREACHED */
2580 VG_(exit)(r);
2581}
2582
2583/* THE ENTRY POINT */
2584void _start_valgrind ( AIX5Bootblock* bootblock );
2585void _start_valgrind ( AIX5Bootblock* bootblock )
2586{
2587 /* Switch immediately to our temporary stack, and continue. This
2588 is pretty dodgy in that it assumes that gcc does not place on
2589 the stack, anything needed to form the _start_in_C_aix5 call,
2590 since it will be on the old stack. */
2591 register UWord new_r1;
2592 new_r1 = (UWord)&VG_(interim_stack);
2593 new_r1 += VG_STACK_GUARD_SZB; /* step over lower guard page */
2594 new_r1 += VG_STACK_ACTIVE_SZB; /* step to top of active area */
2595 new_r1 -= 512; /* paranoia */
2596 __asm__ __volatile__("mr 1,%0" :/*wr*/
2597 :/*rd*/ "b"(new_r1)
2598 :/*trash*/"r1","memory");
2599 _start_in_C_aix5(bootblock);
2600 /*NOTREACHED*/
2601 VG_(exit)(0);
2602}
2603
sewardj61a1b052008-10-22 00:56:53 +00002604/* At some point in Oct 2008, static linking appeared to stop working
2605 on AIX 5.3. This breaks the build since we link statically. The
2606 linking fails citing absence of the following five symbols as the
2607 reason. In the absence of a better solution, here are stand-ins
2608 for them. Kludge appears to work; presumably said functions,
2609 assuming they are indeed functions, are never called. */
2610void encrypted_pw_passlen ( void ) { vg_assert(0); }
2611void crypt_r ( void ) { vg_assert(0); }
2612void max_history_size ( void ) { vg_assert(0); }
2613void getpass_auto ( void ) { vg_assert(0); }
2614void max_pw_passlen ( void ) { vg_assert(0); }
2615
sewardj17c11042006-10-15 01:26:40 +00002616#endif /* defined(VGP_ppc{32,64}_aix5) */
2617
2618
sewardjde4a1d02002-03-22 01:27:54 +00002619/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00002620/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00002621/*--------------------------------------------------------------------*/