blob: 50992f48a267401ef6ce5f31cf89867b95abdd95 [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
sewardj9ebd6e02007-01-08 06:01:59 +000010 Copyright (C) 2000-2007 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"
njn25e49d8e72002-09-23 09:36:25 +0000136"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000137" user options for Valgrind tools that report errors:\n"
njnca54af32006-04-16 10:25:43 +0000138" --xml=yes all output is in XML (some tools only)\n"
njnc8ec9f82005-07-20 03:03:28 +0000139" --xml-user-comment=STR copy STR verbatim to XML output\n"
nethercote2b0793f2003-12-02 10:41:18 +0000140" --demangle=no|yes automatically demangle C++ names? [yes]\n"
njn20b4a152005-10-19 22:39:40 +0000141" --num-callers=<number> show <number> callers in stack traces [12]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000142" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
sewardjb9779082006-05-12 23:50:15 +0000143" --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000144" --show-below-main=no|yes continue stack traces below main() [no]\n"
145" --suppressions=<filename> suppress errors described in <filename>\n"
sewardjd153fae2005-01-10 17:24:47 +0000146" --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000147" --db-attach=no|yes start debugger when errors detected? [no]\n"
sewardj7839d112007-11-20 19:45:03 +0000148" --db-command=<command> command to start debugger [%s -nw %%f %%p]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000149" --input-fd=<number> file descriptor for input [0=stdin]\n"
sewardj97724e52005-04-02 23:40:59 +0000150" --max-stackframe=<number> assume stack switch for SP changes larger\n"
151" than <number> bytes [2000000]\n"
sewardj95d86c02007-12-18 01:49:23 +0000152" --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
153" [use current 'ulimit' value]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000154"\n";
njn7cf0bd32002-06-08 13:36:03 +0000155
njn25e49d8e72002-09-23 09:36:25 +0000156 Char* usage2 =
157"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000158" debugging options for all Valgrind tools:\n"
njn25e49d8e72002-09-23 09:36:25 +0000159" --sanity-level=<number> level of sanity checking to do [1]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000160" --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
161" --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
sewardj33afdb52006-01-17 02:36:40 +0000162" --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
njn25e49d8e72002-09-23 09:36:25 +0000163" --trace-syscalls=no|yes show all system calls? [no]\n"
164" --trace-signals=no|yes show signal handling details? [no]\n"
165" --trace-symtab=no|yes show symbol table details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000166" --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
sewardjce058b02005-05-01 08:55:38 +0000167" --trace-cfi=no|yes show call-frame-info details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000168" --debug-dump=syms mimic /usr/bin/readelf --syms\n"
169" --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
170" --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
sewardj0ec07f32006-01-12 12:32:32 +0000171" --trace-redir=no|yes show redirection details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000172" --trace-sched=no|yes show thread scheduler details? [no]\n"
jsgf855d93d2003-10-13 22:26:55 +0000173" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
sewardj17c11042006-10-15 01:26:40 +0000174" --sym-offsets=yes|no show syms in form 'name+offset' ? [no]\n"
sewardjb5f6f512005-03-10 23:59:00 +0000175" --command-line-only=no|yes only use command line options [no]\n"
njn613812e2005-03-11 04:57:30 +0000176"\n"
177" --vex-iropt-verbosity 0 .. 9 [0]\n"
178" --vex-iropt-level 0 .. 2 [2]\n"
179" --vex-iropt-precise-memory-exns [no]\n"
sewardj8b635a42004-11-22 19:01:47 +0000180" --vex-iropt-unroll-thresh 0 .. 400 [120]\n"
181" --vex-guest-max-insns 1 .. 100 [50]\n"
182" --vex-guest-chase-thresh 0 .. 99 [10]\n"
183"\n"
sewardjfa8ec112005-01-19 11:55:34 +0000184" --trace-flags and --profile-flags values (omit the middle space):\n"
sewardj2a99cf62004-11-24 10:44:19 +0000185" 1000 0000 show conversion into IR\n"
186" 0100 0000 show after initial opt\n"
187" 0010 0000 show after instrumentation\n"
188" 0001 0000 show after second opt\n"
189" 0000 1000 show after tree building\n"
190" 0000 0100 show selecting insns\n"
191" 0000 0010 show after reg-alloc\n"
192" 0000 0001 show final assembly\n"
njn33dbfce2006-06-02 22:58:34 +0000193" (Nb: you need --trace-notbelow with --trace-flags for full details)\n"
sewardj2a99cf62004-11-24 10:44:19 +0000194"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000195" debugging options for Valgrind tools that report errors\n"
196" --dump-error=<number> show translation for basic block associated\n"
197" with <number>'th error context [0=show none]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000198"\n";
njn3e884182003-04-15 13:03:23 +0000199
200 Char* usage3 =
201"\n"
nethercote71980f02004-01-24 18:18:54 +0000202" Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
njn25e49d8e72002-09-23 09:36:25 +0000203"\n"
sewardj9ebd6e02007-01-08 06:01:59 +0000204" Valgrind is Copyright (C) 2000-2007 Julian Seward et al.\n"
njn25e49d8e72002-09-23 09:36:25 +0000205" and licensed under the GNU General Public License, version 2.\n"
206" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
njnd04b7c62002-10-03 14:05:52 +0000207"\n"
nethercote137bc552003-11-14 17:47:54 +0000208" Tools are copyright and licensed by their authors. See each\n"
209" tool's start-up message for more information.\n"
njn25e49d8e72002-09-23 09:36:25 +0000210"\n";
njn7cf0bd32002-06-08 13:36:03 +0000211
sewardj12373b12007-11-20 21:38:14 +0000212# if defined(GDB_PATH)
213 Char* gdb_path = GDB_PATH;
214# else
215 Char* gdb_path = "/no/gdb/was/found/at/configure/time";
216# endif
217
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) {
232 VG_(printf)(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);
sewardj45f4e7c2005-09-27 19:20:21 +0000366 arg = VG_(strdup)(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))
421 else VG_BOOL_CLO(arg, "--trace-pthreads", VG_(clo_trace_pthreads))
422 else VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb))
njn45270a22005-03-27 01:00:11 +0000423 else VG_STR_CLO (arg, "--db-command", VG_(clo_db_command))
njn628add62005-11-12 18:21:40 +0000424 else VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints))
sewardj12ab7652006-10-17 02:10:42 +0000425 else VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets))
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
sewardjce5a5662005-10-06 03:19:49 +0000440 else VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant))
441
njn45270a22005-03-27 01:00:11 +0000442 else VG_BNUM_CLO(arg, "--vex-iropt-verbosity",
sewardj8b635a42004-11-22 19:01:47 +0000443 VG_(clo_vex_control).iropt_verbosity, 0, 10)
njn45270a22005-03-27 01:00:11 +0000444 else VG_BNUM_CLO(arg, "--vex-iropt-level",
sewardj8b635a42004-11-22 19:01:47 +0000445 VG_(clo_vex_control).iropt_level, 0, 2)
njn45270a22005-03-27 01:00:11 +0000446 else VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
sewardj8b635a42004-11-22 19:01:47 +0000447 VG_(clo_vex_control).iropt_precise_memory_exns)
njn45270a22005-03-27 01:00:11 +0000448 else VG_BNUM_CLO(arg, "--vex-iropt-unroll-thresh",
sewardj8b635a42004-11-22 19:01:47 +0000449 VG_(clo_vex_control).iropt_unroll_thresh, 0, 400)
njn45270a22005-03-27 01:00:11 +0000450 else VG_BNUM_CLO(arg, "--vex-guest-max-insns",
sewardj8b635a42004-11-22 19:01:47 +0000451 VG_(clo_vex_control).guest_max_insns, 1, 100)
njn45270a22005-03-27 01:00:11 +0000452 else VG_BNUM_CLO(arg, "--vex-guest-chase-thresh",
sewardj8b635a42004-11-22 19:01:47 +0000453 VG_(clo_vex_control).guest_chase_thresh, 0, 99)
454
nethercotef8548672004-06-21 12:42:35 +0000455 else if (VG_CLO_STREQN(9, arg, "--log-fd=")) {
njnbe9b47b2005-05-15 16:22:58 +0000456 log_to = VgLogTo_Fd;
nethercotef8548672004-06-21 12:42:35 +0000457 VG_(clo_log_name) = NULL;
njnda033f52005-12-19 21:27:58 +0000458 tmp_log_fd = (Int)VG_(atoll)(&arg[9]);
sewardj4cf05692002-10-27 20:28:29 +0000459 }
460
nethercotef8548672004-06-21 12:42:35 +0000461 else if (VG_CLO_STREQN(11, arg, "--log-file=")) {
njnbe9b47b2005-05-15 16:22:58 +0000462 log_to = VgLogTo_File;
nethercotef8548672004-06-21 12:42:35 +0000463 VG_(clo_log_name) = &arg[11];
sewardj4cf05692002-10-27 20:28:29 +0000464 }
njnd6bc3c32005-03-27 00:44:31 +0000465
nethercotef8548672004-06-21 12:42:35 +0000466 else if (VG_CLO_STREQN(13, arg, "--log-socket=")) {
njnbe9b47b2005-05-15 16:22:58 +0000467 log_to = VgLogTo_Socket;
nethercotef8548672004-06-21 12:42:35 +0000468 VG_(clo_log_name) = &arg[13];
sewardj73cf3bc2002-11-03 03:20:15 +0000469 }
470
sewardj768db0e2005-07-19 14:18:56 +0000471 else if (VG_CLO_STREQN(19, arg, "--xml-user-comment=")) {
472 VG_(clo_xml_user_comment) = &arg[19];
473 }
474
nethercote71980f02004-01-24 18:18:54 +0000475 else if (VG_CLO_STREQN(15, arg, "--suppressions=")) {
sewardjde4a1d02002-03-22 01:27:54 +0000476 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njn25e49d8e72002-09-23 09:36:25 +0000477 VG_(message)(Vg_UserMsg, "Too many suppression files specified.");
sewardjde4a1d02002-03-22 01:27:54 +0000478 VG_(message)(Vg_UserMsg,
479 "Increase VG_CLO_MAX_SFILES and recompile.");
sewardj17c11042006-10-15 01:26:40 +0000480 VG_(err_bad_option)(arg);
sewardjde4a1d02002-03-22 01:27:54 +0000481 }
nethercote71980f02004-01-24 18:18:54 +0000482 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &arg[15];
sewardjde4a1d02002-03-22 01:27:54 +0000483 VG_(clo_n_suppressions)++;
484 }
sewardjde4a1d02002-03-22 01:27:54 +0000485
sewardjfa8ec112005-01-19 11:55:34 +0000486 /* "stuvwxyz" --> stuvwxyz (binary) */
487 else if (VG_CLO_STREQN(14, arg, "--trace-flags=")) {
488 Int j;
489 char* opt = & arg[14];
490
491 if (8 != VG_(strlen)(opt)) {
492 VG_(message)(Vg_UserMsg,
493 "--trace-flags argument must have 8 digits");
sewardj17c11042006-10-15 01:26:40 +0000494 VG_(err_bad_option)(arg);
sewardjfa8ec112005-01-19 11:55:34 +0000495 }
496 for (j = 0; j < 8; j++) {
497 if ('0' == opt[j]) { /* do nothing */ }
498 else if ('1' == opt[j]) VG_(clo_trace_flags) |= (1 << (7-j));
499 else {
500 VG_(message)(Vg_UserMsg, "--trace-flags argument can only "
501 "contain 0s and 1s");
sewardj17c11042006-10-15 01:26:40 +0000502 VG_(err_bad_option)(arg);
sewardjfa8ec112005-01-19 11:55:34 +0000503 }
504 }
505 }
506
507 /* "stuvwxyz" --> stuvwxyz (binary) */
508 else if (VG_CLO_STREQN(16, arg, "--profile-flags=")) {
njn25e49d8e72002-09-23 09:36:25 +0000509 Int j;
nethercote71980f02004-01-24 18:18:54 +0000510 char* opt = & arg[16];
njn25e49d8e72002-09-23 09:36:25 +0000511
sewardj2a99cf62004-11-24 10:44:19 +0000512 if (8 != VG_(strlen)(opt)) {
njn25e49d8e72002-09-23 09:36:25 +0000513 VG_(message)(Vg_UserMsg,
sewardjfa8ec112005-01-19 11:55:34 +0000514 "--profile-flags argument must have 8 digits");
sewardj17c11042006-10-15 01:26:40 +0000515 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000516 }
sewardj8b635a42004-11-22 19:01:47 +0000517 for (j = 0; j < 8; j++) {
njn25e49d8e72002-09-23 09:36:25 +0000518 if ('0' == opt[j]) { /* do nothing */ }
sewardjfa8ec112005-01-19 11:55:34 +0000519 else if ('1' == opt[j]) VG_(clo_profile_flags) |= (1 << (7-j));
njn25e49d8e72002-09-23 09:36:25 +0000520 else {
sewardjfa8ec112005-01-19 11:55:34 +0000521 VG_(message)(Vg_UserMsg, "--profile-flags argument can only "
njn25e49d8e72002-09-23 09:36:25 +0000522 "contain 0s and 1s");
sewardj17c11042006-10-15 01:26:40 +0000523 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000524 }
525 }
526 }
sewardjde4a1d02002-03-22 01:27:54 +0000527
njn45270a22005-03-27 01:00:11 +0000528 else VG_NUM_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow))
sewardjc771b292004-11-30 18:55:21 +0000529
sewardjd153fae2005-01-10 17:24:47 +0000530 else if (VG_CLO_STREQ(arg, "--gen-suppressions=no"))
531 VG_(clo_gen_suppressions) = 0;
532 else if (VG_CLO_STREQ(arg, "--gen-suppressions=yes"))
533 VG_(clo_gen_suppressions) = 1;
534 else if (VG_CLO_STREQ(arg, "--gen-suppressions=all"))
535 VG_(clo_gen_suppressions) = 2;
536
nethercote71980f02004-01-24 18:18:54 +0000537 else if ( ! VG_(needs).command_line_options
njn51d827b2005-05-09 01:02:08 +0000538 || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
sewardj17c11042006-10-15 01:26:40 +0000539 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000540 }
sewardjde4a1d02002-03-22 01:27:54 +0000541 }
542
sewardj998d40d2004-12-06 14:24:52 +0000543 /* Make VEX control parameters sane */
544
545 if (VG_(clo_vex_control).guest_chase_thresh
546 >= VG_(clo_vex_control).guest_max_insns)
547 VG_(clo_vex_control).guest_chase_thresh
548 = VG_(clo_vex_control).guest_max_insns - 1;
549
550 if (VG_(clo_vex_control).guest_chase_thresh < 0)
551 VG_(clo_vex_control).guest_chase_thresh = 0;
552
553 /* Check various option values */
nethercote27fec902004-06-16 21:26:32 +0000554
njnf9ebf672003-05-12 21:41:30 +0000555 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +0000556 VG_(clo_verbosity) = 0;
557
nethercote04d0fbc2004-01-26 16:48:06 +0000558 if (VG_(clo_db_attach) && VG_(clo_trace_children)) {
sewardjde4a1d02002-03-22 01:27:54 +0000559 VG_(message)(Vg_UserMsg, "");
560 VG_(message)(Vg_UserMsg,
nethercote04d0fbc2004-01-26 16:48:06 +0000561 "--db-attach=yes conflicts with --trace-children=yes");
sewardjde4a1d02002-03-22 01:27:54 +0000562 VG_(message)(Vg_UserMsg,
563 "Please choose one or the other, but not both.");
sewardj17c11042006-10-15 01:26:40 +0000564 VG_(err_bad_option)("--db-attach=yes and --trace-children=yes");
sewardjde4a1d02002-03-22 01:27:54 +0000565 }
566
njnbe9b47b2005-05-15 16:22:58 +0000567 if (VG_(clo_gen_suppressions) > 0 &&
568 !VG_(needs).core_errors && !VG_(needs).tool_errors) {
569 VG_(message)(Vg_UserMsg,
570 "Can't use --gen-suppressions= with this tool,");
571 VG_(message)(Vg_UserMsg,
572 "as it doesn't generate errors.");
sewardj17c11042006-10-15 01:26:40 +0000573 VG_(err_bad_option)("--gen-suppressions=");
njnbe9b47b2005-05-15 16:22:58 +0000574 }
575
sewardj71bc3cb2005-05-19 00:25:45 +0000576 /* If we've been asked to emit XML, mash around various other
577 options so as to constrain the output somewhat, and to remove
578 any need for user input during the run. */
579 if (VG_(clo_xml)) {
580 /* Disable suppression generation (requires user input) */
581 VG_(clo_gen_suppressions) = 0;
582 /* Disable attaching to GDB (requires user input) */
583 VG_(clo_db_attach) = False;
584 /* Set a known verbosity level */
585 VG_(clo_verbosity) = 1;
586 /* Disable error limits (this might be a bad idea!) */
587 VG_(clo_error_limit) = False;
588 /* Disable emulation warnings */
589 VG_(clo_show_emwarns) = False;
590 /* Disable waiting for GDB to debug Valgrind */
591 VG_(clo_wait_for_gdb) = False;
592 /* No file-descriptor leak checking yet */
593 VG_(clo_track_fds) = False;
sewardj21f7f0c2005-07-06 19:46:48 +0000594 /* Disable timestamped output */
595 VG_(clo_time_stamp) = False;
sewardj71bc3cb2005-05-19 00:25:45 +0000596 /* Also, we want to set options for the leak checker, but that
597 will have to be done in Memcheck's flag-handling code, not
598 here. */
599 }
600
njnbe9b47b2005-05-15 16:22:58 +0000601 /* All non-logging-related options have been checked. If the logging
602 option specified is ok, we can switch to it, as we know we won't
603 have to generate any other command-line-related error messages.
604 (So far we should be still attached to stderr, so we can show on
605 the terminal any problems to do with processing command line
606 opts.)
607
608 So set up logging now. After this is done, VG_(clo_log_fd)
sewardj4cf05692002-10-27 20:28:29 +0000609 should be connected to whatever sink has been selected, and we
610 indiscriminately chuck stuff into it without worrying what the
611 nature of it is. Oh the wonder of Unix streams. */
612
njnbe9b47b2005-05-15 16:22:58 +0000613 vg_assert(VG_(clo_log_fd) == 2 /* stderr */);
614 vg_assert(VG_(logging_to_socket) == False);
sewardj4cf05692002-10-27 20:28:29 +0000615
njnbe9b47b2005-05-15 16:22:58 +0000616 switch (log_to) {
sewardj73cf3bc2002-11-03 03:20:15 +0000617
sewardj4cf05692002-10-27 20:28:29 +0000618 case VgLogTo_Fd:
nethercotef8548672004-06-21 12:42:35 +0000619 vg_assert(VG_(clo_log_name) == NULL);
sewardj4cf05692002-10-27 20:28:29 +0000620 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000621
sewardj4cf05692002-10-27 20:28:29 +0000622 case VgLogTo_File: {
njn374a36d2007-11-23 01:41:32 +0000623 Char* logfilename;
jsgff3c3f1a2003-10-14 22:13:28 +0000624
nethercotef8548672004-06-21 12:42:35 +0000625 vg_assert(VG_(clo_log_name) != NULL);
626 vg_assert(VG_(strlen)(VG_(clo_log_name)) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +0000627
njn374a36d2007-11-23 01:41:32 +0000628 // Nb: we overwrite an existing file of this name without asking
629 // any questions.
630 logfilename = VG_(expand_file_name)("--log-file", VG_(clo_log_name));
631 sres = VG_(open)(logfilename,
njnda033f52005-12-19 21:27:58 +0000632 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
633 VKI_S_IRUSR|VKI_S_IWUSR);
sewardj92645592005-07-23 09:18:34 +0000634 if (!sres.isError) {
sewardj12ab7652006-10-17 02:10:42 +0000635 tmp_log_fd = sres.res;
njnbe9b47b2005-05-15 16:22:58 +0000636 } else {
sewardj603d4102005-01-11 14:01:02 +0000637 VG_(message)(Vg_UserMsg,
njn374a36d2007-11-23 01:41:32 +0000638 "Can't create log file '%s' (%s); giving up!",
639 logfilename, VG_(strerror)(sres.err));
sewardj17c11042006-10-15 01:26:40 +0000640 VG_(err_bad_option)(
njn374a36d2007-11-23 01:41:32 +0000641 "--log-file=<file> (didn't work out for some reason.)");
sewardj603d4102005-01-11 14:01:02 +0000642 /*NOTREACHED*/
njn374a36d2007-11-23 01:41:32 +0000643 }
sewardj603d4102005-01-11 14:01:02 +0000644 break; /* switch (VG_(clo_log_to)) */
sewardj73cf3bc2002-11-03 03:20:15 +0000645 }
646
647 case VgLogTo_Socket: {
nethercotef8548672004-06-21 12:42:35 +0000648 vg_assert(VG_(clo_log_name) != NULL);
649 vg_assert(VG_(strlen)(VG_(clo_log_name)) <= 900); /* paranoia */
njnda033f52005-12-19 21:27:58 +0000650 tmp_log_fd = VG_(connect_via_socket)( VG_(clo_log_name) );
651 if (tmp_log_fd == -1) {
sewardj73cf3bc2002-11-03 03:20:15 +0000652 VG_(message)(Vg_UserMsg,
nethercotef8548672004-06-21 12:42:35 +0000653 "Invalid --log-socket=ipaddr or --log-socket=ipaddr:port spec");
sewardj73cf3bc2002-11-03 03:20:15 +0000654 VG_(message)(Vg_UserMsg,
njn02bc4b82005-05-15 17:28:26 +0000655 "of '%s'; giving up!", VG_(clo_log_name) );
sewardj17c11042006-10-15 01:26:40 +0000656 VG_(err_bad_option)(
nethercotef8548672004-06-21 12:42:35 +0000657 "--log-socket=");
njnbe9b47b2005-05-15 16:22:58 +0000658 /*NOTREACHED*/
sewardj4cf05692002-10-27 20:28:29 +0000659 }
njnda033f52005-12-19 21:27:58 +0000660 if (tmp_log_fd == -2) {
sewardj73cf3bc2002-11-03 03:20:15 +0000661 VG_(message)(Vg_UserMsg,
njn02bc4b82005-05-15 17:28:26 +0000662 "valgrind: failed to connect to logging server '%s'.",
nethercotef8548672004-06-21 12:42:35 +0000663 VG_(clo_log_name) );
sewardj570f8902002-11-03 11:44:36 +0000664 VG_(message)(Vg_UserMsg,
665 "Log messages will sent to stderr instead." );
666 VG_(message)(Vg_UserMsg,
667 "" );
668 /* We don't change anything here. */
njnbe9b47b2005-05-15 16:22:58 +0000669 vg_assert(VG_(clo_log_fd) == 2);
njnda033f52005-12-19 21:27:58 +0000670 tmp_log_fd = 2;
sewardj570f8902002-11-03 11:44:36 +0000671 } else {
njnda033f52005-12-19 21:27:58 +0000672 vg_assert(tmp_log_fd > 0);
njnbe9b47b2005-05-15 16:22:58 +0000673 VG_(logging_to_socket) = True;
sewardj570f8902002-11-03 11:44:36 +0000674 }
sewardj73cf3bc2002-11-03 03:20:15 +0000675 break;
676 }
sewardj4cf05692002-10-27 20:28:29 +0000677 }
678
sewardj71bc3cb2005-05-19 00:25:45 +0000679
680 /* Check that the requested tool actually supports XML output. */
njnca54af32006-04-16 10:25:43 +0000681 if (VG_(clo_xml) && !VG_(needs).xml_output) {
sewardj71bc3cb2005-05-19 00:25:45 +0000682 VG_(clo_xml) = False;
683 VG_(message)(Vg_UserMsg,
njnca54af32006-04-16 10:25:43 +0000684 "%s does not support XML output.", VG_(details).name);
sewardj17c11042006-10-15 01:26:40 +0000685 VG_(err_bad_option)("--xml=yes");
sewardj71bc3cb2005-05-19 00:25:45 +0000686 /*NOTREACHED*/
687 }
688
njnda033f52005-12-19 21:27:58 +0000689 if (tmp_log_fd >= 0) {
690 // Move log_fd into the safe range, so it doesn't conflict with any app fds.
691 tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
692 if (tmp_log_fd < 0) {
693 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd into safe range, using stderr");
694 VG_(clo_log_fd) = 2; // stderr
695 } else {
696 VG_(clo_log_fd) = tmp_log_fd;
697 VG_(fcntl)(VG_(clo_log_fd), VKI_F_SETFD, VKI_FD_CLOEXEC);
698 }
699 } else {
700 // If they said --log-fd=-1, don't print anything. Plausible for use in
701 // regression testing suites that use client requests to count errors.
702 VG_(clo_log_fd) = tmp_log_fd;
jsgf855d93d2003-10-13 22:26:55 +0000703 }
704
sewardj45f4e7c2005-09-27 19:20:21 +0000705 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
706 (VG_(needs).core_errors || VG_(needs).tool_errors)) {
707 /* If we haven't reached the max number of suppressions, load
708 the default one. */
709 static const Char default_supp[] = "default.supp";
710 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
711 Char *buf = VG_(arena_malloc)(VG_AR_CORE, len);
712 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
713 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
714 VG_(clo_n_suppressions)++;
715 }
sewardjde4a1d02002-03-22 01:27:54 +0000716
sewardj45f4e7c2005-09-27 19:20:21 +0000717 return (log_to == VgLogTo_Fd);
718}
719
720
721/*====================================================================*/
722/*=== Printing the preamble ===*/
723/*====================================================================*/
724
725/* Ok, the logging sink is running now. Print a suitable preamble.
726 If logging to file or a socket, write details of parent PID and
727 command line args, to help people trying to interpret the
728 results of a run which encompasses multiple processes. */
729static void print_preamble(Bool logging_to_fd, const char* toolname)
730{
tom60a4b0b2005-10-12 10:45:27 +0000731 HChar* xpre = VG_(clo_xml) ? " <line>" : "";
732 HChar* xpost = VG_(clo_xml) ? "</line>" : "";
733 Int i;
734
sewardj14c7cc52007-02-25 15:08:24 +0000735 vg_assert( VG_(args_for_client) );
736 vg_assert( VG_(args_for_valgrind) );
sewardj99a2ceb2007-11-09 12:30:36 +0000737 vg_assert( toolname );
sewardj14c7cc52007-02-25 15:08:24 +0000738
sewardj71bc3cb2005-05-19 00:25:45 +0000739 if (VG_(clo_xml)) {
sewardj8665d8e2005-06-01 17:35:23 +0000740 VG_(message)(Vg_UserMsg, "<?xml version=\"1.0\"?>");
741 VG_(message)(Vg_UserMsg, "");
sewardj71bc3cb2005-05-19 00:25:45 +0000742 VG_(message)(Vg_UserMsg, "<valgrindoutput>");
743 VG_(message)(Vg_UserMsg, "");
cerion20241ba2005-11-15 19:07:53 +0000744 VG_(message)(Vg_UserMsg, "<protocolversion>2</protocolversion>");
sewardj71bc3cb2005-05-19 00:25:45 +0000745 VG_(message)(Vg_UserMsg, "");
746 }
747
sewardj83adf412002-05-01 01:25:45 +0000748 if (VG_(clo_verbosity > 0)) {
sewardjd7bddad2005-06-13 16:48:32 +0000749
750 if (VG_(clo_xml))
751 VG_(message)(Vg_UserMsg, "<preamble>");
752
nethercote996901a2004-08-03 13:29:09 +0000753 /* Tool details */
sewardj71bc3cb2005-05-19 00:25:45 +0000754 VG_(message)(Vg_UserMsg, "%s%s%s%s, %s.%s",
755 xpre,
njnd04b7c62002-10-03 14:05:52 +0000756 VG_(details).name,
njnb9c427c2004-12-01 14:14:42 +0000757 NULL == VG_(details).version ? "" : "-",
njnd04b7c62002-10-03 14:05:52 +0000758 NULL == VG_(details).version
759 ? (Char*)"" : VG_(details).version,
sewardj71bc3cb2005-05-19 00:25:45 +0000760 VG_(details).description,
761 xpost);
sewardj99a2ceb2007-11-09 12:30:36 +0000762
763 if (VG_(strlen)(toolname) >= 4
764 && 0 == VG_(strncmp)(toolname, "exp-", 4)) {
765 VG_(message)(
766 Vg_UserMsg,
767 "%sNOTE: This is an Experimental-Class Valgrind Tool.%s",
768 xpre, xpost
769 );
770 }
771
sewardj71bc3cb2005-05-19 00:25:45 +0000772 VG_(message)(Vg_UserMsg, "%s%s%s",
773 xpre, VG_(details).copyright_author, xpost);
sewardj3b2736a2002-03-24 12:18:35 +0000774
njnd04b7c62002-10-03 14:05:52 +0000775 /* Core details */
776 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000777 "%sUsing LibVEX rev %s, a library for dynamic binary translation.%s",
778 xpre, LibVEX_Version(), xpost );
sewardjc7025332004-12-13 18:30:39 +0000779 VG_(message)(Vg_UserMsg,
sewardj9ebd6e02007-01-08 06:01:59 +0000780 "%sCopyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.%s",
sewardj71bc3cb2005-05-19 00:25:45 +0000781 xpre, xpost );
sewardjc7025332004-12-13 18:30:39 +0000782 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000783 "%sUsing valgrind-%s, a dynamic binary instrumentation framework.%s",
784 xpre, VERSION, xpost);
sewardjde4a1d02002-03-22 01:27:54 +0000785 VG_(message)(Vg_UserMsg,
sewardj9ebd6e02007-01-08 06:01:59 +0000786 "%sCopyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.%s",
sewardj71bc3cb2005-05-19 00:25:45 +0000787 xpre, xpost );
sewardjd7bddad2005-06-13 16:48:32 +0000788
sewardj45f4e7c2005-09-27 19:20:21 +0000789 if (VG_(clo_verbosity) == 1 && !VG_(clo_xml))
790 VG_(message)(Vg_UserMsg, "For more details, rerun with: -v");
791
sewardjd7bddad2005-06-13 16:48:32 +0000792 if (VG_(clo_xml))
793 VG_(message)(Vg_UserMsg, "</preamble>");
njnd04b7c62002-10-03 14:05:52 +0000794 }
795
sewardj45f4e7c2005-09-27 19:20:21 +0000796 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
sewardj4cf05692002-10-27 20:28:29 +0000797 VG_(message)(Vg_UserMsg, "");
798 VG_(message)(Vg_UserMsg,
799 "My PID = %d, parent PID = %d. Prog and args are:",
800 VG_(getpid)(), VG_(getppid)() );
sewardj5e940782005-09-28 19:59:19 +0000801 if (VG_(args_the_exename))
802 VG_(message)(Vg_UserMsg, " %s", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000803 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
804 VG_(message)(Vg_UserMsg,
805 " %s",
806 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
sewardj4cf05692002-10-27 20:28:29 +0000807 }
sewardj71bc3cb2005-05-19 00:25:45 +0000808 else
809 if (VG_(clo_xml)) {
810 VG_(message)(Vg_UserMsg, "");
811 VG_(message)(Vg_UserMsg, "<pid>%d</pid>", VG_(getpid)());
812 VG_(message)(Vg_UserMsg, "<ppid>%d</ppid>", VG_(getppid)());
sewardj97f7e0c2005-07-19 15:00:25 +0000813 VG_(message)(Vg_UserMsg, "<tool>%t</tool>", toolname);
njn374a36d2007-11-23 01:41:32 +0000814// [This was made obsolete by the --log-file change in 3.3.0. But
815// I'm leaving it here (commented out) in case it needs to be reinstated in
816// some way --njn]
817// if (VG_(clo_log_file_qualifier)) {
818// HChar* val = VG_(getenv)(VG_(clo_log_file_qualifier));
819// VG_(message)(Vg_UserMsg, "<logfilequalifier> <var>%t</var> "
820// "<value>%t</value> </logfilequalifier>",
821// VG_(clo_log_file_qualifier),
822// val ? val : "");
823// }
sewardj768db0e2005-07-19 14:18:56 +0000824 if (VG_(clo_xml_user_comment)) {
825 /* Note: the user comment itself is XML and is therefore to
826 be passed through verbatim (%s) rather than escaped
827 (%t). */
828 VG_(message)(Vg_UserMsg, "<usercomment>%s</usercomment>",
829 VG_(clo_xml_user_comment));
830 }
sewardj71bc3cb2005-05-19 00:25:45 +0000831 VG_(message)(Vg_UserMsg, "");
sewardjb8a3dac2005-07-19 12:39:11 +0000832 VG_(message)(Vg_UserMsg, "<args>");
sewardj45f4e7c2005-09-27 19:20:21 +0000833
sewardjb8a3dac2005-07-19 12:39:11 +0000834 VG_(message)(Vg_UserMsg, " <vargv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000835 if (VG_(name_of_launcher))
836 VG_(message)(Vg_UserMsg, " <exe>%t</exe>",
837 VG_(name_of_launcher));
sewardj125fd4f2007-03-08 19:56:14 +0000838 else
839 VG_(message)(Vg_UserMsg, " <exe>%t</exe>",
840 "(launcher name unknown)");
sewardj14c7cc52007-02-25 15:08:24 +0000841 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
sewardj45f4e7c2005-09-27 19:20:21 +0000842 VG_(message)(Vg_UserMsg,
843 " <arg>%t</arg>",
sewardj14c7cc52007-02-25 15:08:24 +0000844 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjb8a3dac2005-07-19 12:39:11 +0000845 }
846 VG_(message)(Vg_UserMsg, " </vargv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000847
sewardjb8a3dac2005-07-19 12:39:11 +0000848 VG_(message)(Vg_UserMsg, " <argv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000849 if (VG_(args_the_exename))
850 VG_(message)(Vg_UserMsg, " <exe>%t</exe>",
851 VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000852 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
853 VG_(message)(Vg_UserMsg,
854 " <arg>%t</arg>",
855 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
sewardj8665d8e2005-06-01 17:35:23 +0000856 }
sewardjb8a3dac2005-07-19 12:39:11 +0000857 VG_(message)(Vg_UserMsg, " </argv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000858
sewardjb8a3dac2005-07-19 12:39:11 +0000859 VG_(message)(Vg_UserMsg, "</args>");
sewardj71bc3cb2005-05-19 00:25:45 +0000860 }
sewardj4cf05692002-10-27 20:28:29 +0000861
sewardj45f4e7c2005-09-27 19:20:21 +0000862 // Empty line after the preamble
863 if (VG_(clo_verbosity) > 0)
864 VG_(message)(Vg_UserMsg, "");
865
sewardjde4a1d02002-03-22 01:27:54 +0000866 if (VG_(clo_verbosity) > 1) {
sewardj92645592005-07-23 09:18:34 +0000867 SysRes fd;
sewardj1f0bbc72005-11-16 03:51:02 +0000868 VexArch vex_arch;
869 VexArchInfo vex_archinfo;
sewardj45f4e7c2005-09-27 19:20:21 +0000870 if (!logging_to_fd)
njn1fd5eb22005-03-13 05:43:23 +0000871 VG_(message)(Vg_DebugMsg, "");
njn1fd5eb22005-03-13 05:43:23 +0000872 VG_(message)(Vg_DebugMsg, "Command line");
sewardj45f4e7c2005-09-27 19:20:21 +0000873 if (VG_(args_the_exename))
874 VG_(message)(Vg_DebugMsg, " %s", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000875 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
876 VG_(message)(Vg_DebugMsg,
877 " %s",
878 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
njn86dc2bc2003-09-09 07:26:21 +0000879
njn1fd5eb22005-03-13 05:43:23 +0000880 VG_(message)(Vg_DebugMsg, "Startup, with flags:");
sewardj14c7cc52007-02-25 15:08:24 +0000881 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
882 VG_(message)(Vg_DebugMsg,
883 " %s",
884 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjde4a1d02002-03-22 01:27:54 +0000885 }
nethercotea70f7352004-04-18 12:08:46 +0000886
njn1fd5eb22005-03-13 05:43:23 +0000887 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:");
nethercotea70f7352004-04-18 12:08:46 +0000888 fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
sewardj92645592005-07-23 09:18:34 +0000889 if (fd.isError) {
njn1fd5eb22005-03-13 05:43:23 +0000890 VG_(message)(Vg_DebugMsg, " can't open /proc/version");
nethercotea70f7352004-04-18 12:08:46 +0000891 } else {
sewardj71bc3cb2005-05-19 00:25:45 +0000892# define BUF_LEN 256
nethercotea70f7352004-04-18 12:08:46 +0000893 Char version_buf[BUF_LEN];
sewardj12ab7652006-10-17 02:10:42 +0000894 Int n = VG_(read) ( fd.res, version_buf, BUF_LEN );
njnbe9b47b2005-05-15 16:22:58 +0000895 vg_assert(n <= BUF_LEN);
nethercotea70f7352004-04-18 12:08:46 +0000896 if (n > 0) {
897 version_buf[n-1] = '\0';
njn1fd5eb22005-03-13 05:43:23 +0000898 VG_(message)(Vg_DebugMsg, " %s", version_buf);
nethercotea70f7352004-04-18 12:08:46 +0000899 } else {
njn1fd5eb22005-03-13 05:43:23 +0000900 VG_(message)(Vg_DebugMsg, " (empty?)");
nethercotea70f7352004-04-18 12:08:46 +0000901 }
sewardj12ab7652006-10-17 02:10:42 +0000902 VG_(close)(fd.res);
sewardj71bc3cb2005-05-19 00:25:45 +0000903# undef BUF_LEN
nethercotea70f7352004-04-18 12:08:46 +0000904 }
sewardj1f0bbc72005-11-16 03:51:02 +0000905
906 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +0000907 VG_(message)(
908 Vg_DebugMsg,
909 "Arch and hwcaps: %s, %s",
910 LibVEX_ppVexArch ( vex_arch ),
911 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
912 );
sewardje66f2e02006-12-30 17:45:08 +0000913 VG_(message)(
914 Vg_DebugMsg,
sewardj07854682006-12-30 17:56:32 +0000915 "Page sizes: currently %d, max supported %d",
sewardje66f2e02006-12-30 17:45:08 +0000916 (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
917 );
sewardj1f0bbc72005-11-16 03:51:02 +0000918 VG_(message)(Vg_DebugMsg, "Valgrind library directory: %s", VG_(libdir));
sewardjde4a1d02002-03-22 01:27:54 +0000919 }
nethercotef6a1d502004-08-09 12:21:57 +0000920}
921
sewardjde4a1d02002-03-22 01:27:54 +0000922
nethercote71980f02004-01-24 18:18:54 +0000923/*====================================================================*/
924/*=== File descriptor setup ===*/
925/*====================================================================*/
926
sewardj5f229e22005-09-28 01:36:01 +0000927/* Number of file descriptors that Valgrind tries to reserve for
928 it's own use - just a small constant. */
929#define N_RESERVED_FDS (10)
930
nethercote71980f02004-01-24 18:18:54 +0000931static void setup_file_descriptors(void)
932{
933 struct vki_rlimit rl;
sewardj17c11042006-10-15 01:26:40 +0000934 Bool show = False;
nethercote71980f02004-01-24 18:18:54 +0000935
936 /* Get the current file descriptor limits. */
937 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
938 rl.rlim_cur = 1024;
939 rl.rlim_max = 1024;
940 }
941
sewardj17c11042006-10-15 01:26:40 +0000942 if (show)
njn8a7b41b2007-09-23 00:51:24 +0000943 VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
sewardj17c11042006-10-15 01:26:40 +0000944 rl.rlim_cur, rl.rlim_max);
945
946# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
947 /* I don't know why this kludge is needed; however if rl.rlim_cur
948 is RLIM_INFINITY, then VG_(safe_fd)'s attempts using VG_(fcntl)
949 to lift V's file descriptors above the threshold RLIM_INFINITY -
950 N_RESERVED_FDS fail. So just use a relatively conservative
951 value in this case. */
952 if (rl.rlim_cur > 1024)
953 rl.rlim_cur = 1024;
954# endif
955
nethercote71980f02004-01-24 18:18:54 +0000956 /* Work out where to move the soft limit to. */
njn14319cc2005-03-13 06:26:22 +0000957 if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
958 rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +0000959 } else {
960 rl.rlim_cur = rl.rlim_max;
961 }
962
963 /* Reserve some file descriptors for our use. */
njn14319cc2005-03-13 06:26:22 +0000964 VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
965 VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +0000966
967 /* Update the soft limit. */
968 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
969
sewardj17c11042006-10-15 01:26:40 +0000970 if (show) {
njn8a7b41b2007-09-23 00:51:24 +0000971 VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
sewardj17c11042006-10-15 01:26:40 +0000972 rl.rlim_cur, rl.rlim_max);
973 VG_(printf)("fd limits: guest : cur %u max %u\n",
974 VG_(fd_soft_limit), VG_(fd_hard_limit));
975 }
976
sewardj45f4e7c2005-09-27 19:20:21 +0000977 if (VG_(cl_exec_fd) != -1)
978 VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
nethercote71980f02004-01-24 18:18:54 +0000979}
980
sewardjde4a1d02002-03-22 01:27:54 +0000981
njn2da73352005-06-18 01:35:16 +0000982/*====================================================================*/
njn2025cf92005-06-26 20:44:48 +0000983/*=== BB profiling ===*/
984/*====================================================================*/
985
986static
987void show_BB_profile ( BBProfEntry tops[], UInt n_tops, ULong score_total )
988{
989 ULong score_cumul, score_here;
990 Char buf_cumul[10], buf_here[10];
991 Char name[64];
992 Int r;
993
994 VG_(printf)("\n");
995 VG_(printf)("-----------------------------------------------------------\n");
996 VG_(printf)("--- BEGIN BB Profile (summary of scores) ---\n");
997 VG_(printf)("-----------------------------------------------------------\n");
998 VG_(printf)("\n");
999
1000 VG_(printf)("Total score = %lld\n\n", score_total);
1001
1002 score_cumul = 0;
1003 for (r = 0; r < n_tops; r++) {
1004 if (tops[r].addr == 0)
1005 continue;
1006 name[0] = 0;
1007 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1008 name[63] = 0;
1009 score_here = tops[r].score;
1010 score_cumul += score_here;
1011 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1012 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1013 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1014 r,
1015 score_cumul, buf_cumul,
1016 score_here, buf_here, tops[r].addr, name );
1017 }
1018
1019 VG_(printf)("\n");
1020 VG_(printf)("-----------------------------------------------------------\n");
1021 VG_(printf)("--- BB Profile (BB details) ---\n");
1022 VG_(printf)("-----------------------------------------------------------\n");
1023 VG_(printf)("\n");
1024
1025 score_cumul = 0;
1026 for (r = 0; r < n_tops; r++) {
1027 if (tops[r].addr == 0)
1028 continue;
1029 name[0] = 0;
1030 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1031 name[63] = 0;
1032 score_here = tops[r].score;
1033 score_cumul += score_here;
1034 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1035 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1036 VG_(printf)("\n");
1037 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin BB rank %d "
1038 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1039 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1040 r,
1041 score_cumul, buf_cumul,
1042 score_here, buf_here, tops[r].addr, name );
1043 VG_(printf)("\n");
sewardjbcccbc02007-04-09 22:24:57 +00001044 VG_(discard_translations)(tops[r].addr, 1, "bb profile");
sewardj0ec07f32006-01-12 12:32:32 +00001045 VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0, True);
njn2025cf92005-06-26 20:44:48 +00001046 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= end BB rank %d "
1047 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1048 }
1049
1050 VG_(printf)("\n");
1051 VG_(printf)("-----------------------------------------------------------\n");
1052 VG_(printf)("--- END BB Profile ---\n");
1053 VG_(printf)("-----------------------------------------------------------\n");
1054 VG_(printf)("\n");
1055}
1056
1057
1058/*====================================================================*/
nethercote71980f02004-01-24 18:18:54 +00001059/*=== main() ===*/
1060/*====================================================================*/
1061
sewardjfdf91b42005-09-28 00:53:09 +00001062/* When main() is entered, we should be on the following stack, not
1063 the one the kernel gave us. We will run on this stack until
1064 simulation of the root thread is started, at which point a transfer
1065 is made to a dynamically allocated stack. This is for the sake of
1066 uniform overflow detection for all Valgrind threads. This is
1067 marked global even though it isn't, because assembly code below
1068 needs to reference the name. */
1069
1070/*static*/ VgStack VG_(interim_stack);
1071
sewardjf9d2f9b2006-11-17 20:00:57 +00001072/* These are the structures used to hold info for creating the initial
1073 client image.
1074
1075 'iicii' mostly holds important register state present at system
1076 startup (_start_valgrind). valgrind_main() then fills in the rest
1077 of it and passes it to VG_(ii_create_image)(). That produces
1078 'iifii', which is later handed to VG_(ii_finalise_image). */
1079
1080/* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1081 This should get some address inside the stack on which we gained
sewardjfdf91b42005-09-28 00:53:09 +00001082 control (eg, it could be the SP at startup). It doesn't matter
1083 exactly where in the stack it is. This value is passed to the
sewardjf9d2f9b2006-11-17 20:00:57 +00001084 address space manager at startup. On Linux, aspacem then uses it
1085 to identify the initial stack segment and hence the upper end of
1086 the usable address space. */
sewardjfdf91b42005-09-28 00:53:09 +00001087
sewardjf9d2f9b2006-11-17 20:00:57 +00001088static IICreateImageInfo the_iicii;
1089static IIFinaliseImageInfo the_iifii;
1090
sewardjfdf91b42005-09-28 00:53:09 +00001091
sewardj1ae3f3a2005-09-28 10:47:38 +00001092/* --- Forwards decls to do with shutdown --- */
1093
1094static void final_tidyup(ThreadId tid);
1095
1096/* Do everything which needs doing when the last thread exits */
1097static
1098void shutdown_actions_NORETURN( ThreadId tid,
1099 VgSchedReturnCode tids_schedretcode );
1100
1101/* --- end of Forwards decls to do with shutdown --- */
sewardjfdf91b42005-09-28 00:53:09 +00001102
1103
sewardj45f4e7c2005-09-27 19:20:21 +00001104/* TODO: GIVE THIS A PROPER HOME
njn1d0825f2006-03-27 11:37:07 +00001105 TODO: MERGE THIS WITH DUPLICATE IN mc_leakcheck.c and coredump-elf.c.
sewardj45f4e7c2005-09-27 19:20:21 +00001106 Extract from aspacem a vector of the current segment start
1107 addresses. The vector is dynamically allocated and should be freed
1108 by the caller when done. REQUIRES m_mallocfree to be running.
1109 Writes the number of addresses required into *n_acquired. */
nethercotec314eba2004-07-15 12:59:41 +00001110
sewardj45f4e7c2005-09-27 19:20:21 +00001111static Addr* get_seg_starts ( /*OUT*/Int* n_acquired )
sewardj1cf558c2005-04-25 01:36:56 +00001112{
sewardj45f4e7c2005-09-27 19:20:21 +00001113 Addr* starts;
sewardja48a4932005-09-29 11:09:56 +00001114 Int n_starts, r = 0;
sewardj45f4e7c2005-09-27 19:20:21 +00001115
1116 n_starts = 1;
sewardj1cf558c2005-04-25 01:36:56 +00001117 while (True) {
sewardj45f4e7c2005-09-27 19:20:21 +00001118 starts = VG_(malloc)( n_starts * sizeof(Addr) );
1119 if (starts == NULL)
1120 break;
1121 r = VG_(am_get_segment_starts)( starts, n_starts );
1122 if (r >= 0)
1123 break;
1124 VG_(free)(starts);
1125 n_starts *= 2;
sewardj1cf558c2005-04-25 01:36:56 +00001126 }
sewardj45f4e7c2005-09-27 19:20:21 +00001127
1128 if (starts == NULL) {
1129 *n_acquired = 0;
1130 return NULL;
1131 }
1132
1133 *n_acquired = r;
1134 return starts;
sewardj1cf558c2005-04-25 01:36:56 +00001135}
1136
1137
sewardjf9d2f9b2006-11-17 20:00:57 +00001138/* By the time we get to valgrind_main, the_iicii should already have
1139 been filled in with any important details as required by whatever
1140 OS we have been built for.
1141*/
sewardj17c11042006-10-15 01:26:40 +00001142static
sewardjf9d2f9b2006-11-17 20:00:57 +00001143Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
nethercote71980f02004-01-24 18:18:54 +00001144{
sewardj13247ca2005-12-30 22:52:20 +00001145 HChar* toolname = "memcheck"; // default to Memcheck
sewardj13247ca2005-12-30 22:52:20 +00001146 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
sewardj4c3faae2006-03-15 11:50:32 +00001147 UInt* client_auxv = NULL;
sewardjde764e82007-11-09 23:13:22 +00001148 ThreadId tid_main = VG_INVALID_THREADID;
sewardj45f4e7c2005-09-27 19:20:21 +00001149 Int loglevel, i;
1150 Bool logging_to_fd;
nethercote73b526f2004-10-31 18:48:21 +00001151 struct vki_rlimit zero = { 0, 0 };
sewardj17c11042006-10-15 01:26:40 +00001152
nethercote71980f02004-01-24 18:18:54 +00001153 //============================================================
nethercote71980f02004-01-24 18:18:54 +00001154 //
sewardj45f4e7c2005-09-27 19:20:21 +00001155 // Nb: startup is complex. Prerequisites are shown at every step.
nethercote71980f02004-01-24 18:18:54 +00001156 // *** Be very careful when messing with the order ***
sewardj45f4e7c2005-09-27 19:20:21 +00001157 //
1158 // The first order of business is to get debug logging, the address
1159 // space manager and the dynamic memory manager up and running.
1160 // Once that's done, we can relax a bit.
1161 //
nethercote71980f02004-01-24 18:18:54 +00001162 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001163
1164 /* This is needed to make VG_(getenv) usable early. */
1165 VG_(client_envp) = (Char**)envp;
nethercote71980f02004-01-24 18:18:54 +00001166
sewardj1cf558c2005-04-25 01:36:56 +00001167 //--------------------------------------------------------------
1168 // Start up the logging mechanism
1169 // p: none
1170 //--------------------------------------------------------------
1171 /* Start the debugging-log system ASAP. First find out how many
1172 "-d"s were specified. This is a pre-scan of the command line. */
1173 loglevel = 0;
1174 for (i = 1; i < argc; i++) {
sewardj10759312005-05-30 23:52:47 +00001175 if (argv[i][0] != '-')
1176 break;
sewardj45f4e7c2005-09-27 19:20:21 +00001177 if (VG_STREQ(argv[i], "--"))
sewardj10759312005-05-30 23:52:47 +00001178 break;
sewardj45f4e7c2005-09-27 19:20:21 +00001179 if (VG_STREQ(argv[i], "-d"))
sewardj10759312005-05-30 23:52:47 +00001180 loglevel++;
sewardj1cf558c2005-04-25 01:36:56 +00001181 }
1182
1183 /* ... and start the debug logger. Now we can safely emit logging
1184 messages all through startup. */
sewardj10759312005-05-30 23:52:47 +00001185 VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
sewardj45f4e7c2005-09-27 19:20:21 +00001186 VG_(debugLog)(1, "main", "Welcome to Valgrind version "
1187 VERSION " debug logging\n");
1188
1189 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001190 // AIX5 only: register the system call numbers
1191 // p: logging
1192 // p: that the initial few syscall numbers stated in the
1193 // bootblock have been installed (else we can't
1194 // open/read/close).
1195 //--------------------------------------------------------------
1196# if defined(VGO_aix5)
1197 VG_(debugLog)(1, "main", "aix5: registering syscalls ..\n");
1198 { UChar sysent_name[50];
1199 SysRes fd;
1200 Bool ok;
1201 Int n_unregd, sysent_used = 0;
1202 prsysent_t* sysent_hdr;
1203
1204 VG_(sprintf)(sysent_name, "/proc/%d/sysent", VG_(getpid)());
1205 fd = VG_(open)(sysent_name, VKI_O_RDONLY, 0);
1206 if (fd.isError)
1207 VG_(err_config_error)("aix5: can't open /proc/<pid>/sysent");
1208
1209 sysent_used = VG_(read)(fd.res, aix5_sysent_buf, VG_AIX5_SYSENT_SIZE);
1210 if (sysent_used < 0)
1211 VG_(err_config_error)("aix5: error reading /proc/<pid>/sysent");
1212 if (sysent_used >= VG_AIX5_SYSENT_SIZE)
1213 VG_(err_config_error)("aix5: VG_AIX5_SYSENT_SIZE is too low; "
1214 "increase and recompile");
1215 VG_(close)(fd.res);
1216
1217 vg_assert(sysent_used > 0 && sysent_used < VG_AIX5_SYSENT_SIZE);
1218
1219 sysent_hdr = (prsysent_t*)&aix5_sysent_buf[0];
1220
1221 n_unregd = 0;
1222 for (i = 0; i < sysent_hdr->pr_nsyscalls; i++) {
1223 UChar* name = &aix5_sysent_buf[ sysent_hdr
1224 ->pr_syscall[i].pr_nameoff ];
1225 UInt nmbr = sysent_hdr->pr_syscall[i].pr_number;
1226 VG_(debugLog)(3, "main", "aix5: bind syscall %d to \"%s\"\n",
1227 nmbr, name);
1228 ok = VG_(aix5_register_syscall)(nmbr, name);
1229 if (!ok)
1230 n_unregd++;
1231 if (!ok)
1232 VG_(debugLog)(3, "main",
1233 "aix5: bind FAILED: %d to \"%s\"\n",
1234 nmbr, name);
1235 }
1236 VG_(debugLog)(1, "main", "aix5: .. %d syscalls known, %d unknown\n",
1237 sysent_hdr->pr_nsyscalls - n_unregd, n_unregd );
1238 VG_(debugLog)(1, "main", "aix5: __NR_AIX5_FAKE_SIGRETURN = %d\n",
1239 __NR_AIX5_FAKE_SIGRETURN );
1240 }
1241# endif
1242
1243 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001244 // Ensure we're on a plausible stack.
1245 // p: logging
1246 //--------------------------------------------------------------
1247 VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
sewardjfdf91b42005-09-28 00:53:09 +00001248 { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
1249 HChar* limHi = limLo + sizeof(VG_(interim_stack));
sewardj45f4e7c2005-09-27 19:20:21 +00001250 HChar* aLocal = (HChar*)&zero; /* any auto local will do */
1251 if (aLocal < limLo || aLocal >= limHi) {
1252 /* something's wrong. Stop. */
1253 VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
1254 limLo, limHi, aLocal );
1255 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1256 "Initial stack switched failed.\n");
1257 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1258 VG_(exit)(1);
1259 }
1260 }
1261
1262 //--------------------------------------------------------------
1263 // Ensure we have a plausible pointer to the stack on which
1264 // we gained control (not the current stack!)
1265 // p: logging
1266 //--------------------------------------------------------------
1267 VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
sewardjf9d2f9b2006-11-17 20:00:57 +00001268 if (the_iicii.sp_at_startup == 0) {
sewardj45f4e7c2005-09-27 19:20:21 +00001269 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1270 "Initial stack was not noted.\n");
1271 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1272 VG_(exit)(1);
1273 }
1274
1275 //--------------------------------------------------------------
1276 // Start up the address space manager, and determine the
1277 // approximate location of the client's stack
1278 // p: logging, plausible-stack
1279 //--------------------------------------------------------------
1280 VG_(debugLog)(1, "main", "Starting the address space manager\n");
sewardje66f2e02006-12-30 17:45:08 +00001281 vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536);
1282 vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536);
1283 vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
1284 vg_assert(VKI_PAGE_SIZE == (1 << VKI_PAGE_SHIFT));
1285 vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
sewardjf9d2f9b2006-11-17 20:00:57 +00001286 the_iicii.clstack_top = VG_(am_startup)( the_iicii.sp_at_startup );
sewardj45f4e7c2005-09-27 19:20:21 +00001287 VG_(debugLog)(1, "main", "Address space manager is running\n");
1288
1289 //--------------------------------------------------------------
1290 // Start up the dynamic memory manager
1291 // p: address space management
1292 // In fact m_mallocfree is self-initialising, so there's no
1293 // initialisation call to do. Instead, try a simple malloc/
1294 // free pair right now to check that nothing is broken.
1295 //--------------------------------------------------------------
1296 VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
1297 { void* p = VG_(malloc)( 12345 );
1298 if (p) VG_(free)( p );
1299 }
1300 VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
sewardj1cf558c2005-04-25 01:36:56 +00001301
nethercotef4928da2004-06-15 10:54:40 +00001302 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001303 //
1304 // Dynamic memory management is now available.
1305 //
nethercotef4928da2004-06-15 10:54:40 +00001306 //============================================================
1307
sewardj45f4e7c2005-09-27 19:20:21 +00001308 //--------------------------------------------------------------
1309 // Look for alternative libdir
1310 { HChar *cp = VG_(getenv)(VALGRIND_LIB);
1311 if (cp != NULL)
1312 VG_(libdir) = cp;
1313 }
1314
1315 //--------------------------------------------------------------
1316 // Extract the launcher name from the environment.
1317 VG_(debugLog)(1, "main", "Getting stage1's name\n");
1318 VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
1319 if (VG_(name_of_launcher) == NULL) {
1320 VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
1321 VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
1322 VG_(exit)(1);
1323 }
1324
1325 //--------------------------------------------------------------
fitzhardingeb50068f2004-02-24 23:42:55 +00001326 // Get the current process datasize rlimit, and set it to zero.
1327 // This prevents any internal uses of brk() from having any effect.
1328 // We remember the old value so we can restore it on exec, so that
1329 // child processes will have a reasonable brk value.
1330 VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1331 zero.rlim_max = VG_(client_rlimit_data).rlim_max;
1332 VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
thughesc37184f2004-09-11 14:16:57 +00001333
1334 // Get the current process stack rlimit.
1335 VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
1336
sewardje2d1e672005-11-12 23:10:48 +00001337 //--------------------------------------------------------------
1338 // Figure out what sort of CPU we're on, and whether it is
1339 // able to run V.
1340 VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
1341 { VexArch vex_arch;
1342 VexArchInfo vex_archinfo;
1343 Bool ok = VG_(machine_get_hwcaps)();
1344 if (!ok) {
1345 VG_(printf)("\n");
1346 VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
1347 VG_(printf)(" Supported CPUs are:\n");
1348 VG_(printf)(" * x86 (practically any; Pentium-I or above), "
1349 "AMD Athlon or above)\n");
1350 VG_(printf)(" * AMD Athlon64/Opteron\n");
1351 VG_(printf)(" * PowerPC (most; ppc405 and above)\n");
1352 VG_(printf)("\n");
1353 VG_(exit)(1);
1354 }
1355 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001356 VG_(debugLog)(
1357 1, "main", "... arch = %s, hwcaps = %s\n",
1358 LibVEX_ppVexArch ( vex_arch ),
1359 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1360 );
sewardje2d1e672005-11-12 23:10:48 +00001361 }
1362
sewardj198f34f2007-07-09 23:13:07 +00001363 //--------------------------------------------------------------
1364 // Record the working directory at startup
1365 // p: none (Linux), getenv and sys_getpid work (AIX)
1366 VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
1367 { Bool ok = VG_(record_startup_wd)();
1368 if (!ok)
1369 VG_(err_config_error)( "Can't establish current working "
1370 "directory at startup");
1371 }
1372 { Char buf[VKI_PATH_MAX+1];
1373 Bool ok = VG_(get_startup_wd)( buf, sizeof(buf) );
1374 vg_assert(ok);
1375 buf[VKI_PATH_MAX] = 0;
1376 VG_(debugLog)(1, "main", "... %s\n", buf );
1377 }
1378
sewardj45f4e7c2005-09-27 19:20:21 +00001379 //============================================================
1380 // Command line argument handling order:
1381 // * If --help/--help-debug are present, show usage message
1382 // (including the tool-specific usage)
1383 // * (If no --tool option given, default to Memcheck)
1384 // * Then, if client is missing, abort with error msg
1385 // * Then, if any cmdline args are bad, abort with error msg
1386 //============================================================
1387
1388 //--------------------------------------------------------------
1389 // Split up argv into: C args, V args, V extra args, and exename.
1390 // p: dynamic memory allocation
1391 //--------------------------------------------------------------
1392 VG_(debugLog)(1, "main", "Split up command line\n");
1393 VG_(split_up_argv)( argc, argv );
sewardj14c7cc52007-02-25 15:08:24 +00001394 vg_assert( VG_(args_for_valgrind) );
1395 vg_assert( VG_(args_for_client) );
sewardj45f4e7c2005-09-27 19:20:21 +00001396 if (0) {
sewardj14c7cc52007-02-25 15:08:24 +00001397 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
1398 VG_(printf)(
1399 "varg %s\n",
1400 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1401 );
sewardj45f4e7c2005-09-27 19:20:21 +00001402 VG_(printf)(" exe %s\n", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001403 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
1404 VG_(printf)(
1405 "carg %s\n",
1406 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1407 );
nethercote71980f02004-01-24 18:18:54 +00001408 }
1409
sewardj948a6fc2007-03-19 18:38:55 +00001410# if defined(VGO_aix5)
1411 /* Tolerate ptraced-based launchers. They can't run 'no program'
1412 if the user types "valgrind --help", so they run a do-nothing
1413 program $prefix/bin/no_op_client_for_valgrind, and we catch that
1414 here and turn it the exe name back into NULL. Then --help,
1415 --version etc work as they should. */
1416 if (VG_(args_the_exename)
1417 && VG_(strstr)( VG_(args_the_exename), "/no_op_client_for_valgrind" )) {
1418 VG_(args_the_exename) = NULL;
1419 }
1420# endif
1421
nethercote71980f02004-01-24 18:18:54 +00001422 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001423 // Extract tool name and whether help has been requested.
1424 // Note we can't print the help message yet, even if requested,
1425 // because the tool has not been initialised.
1426 // p: split_up_argv [for VG_(args_for_valgrind)]
nethercote71980f02004-01-24 18:18:54 +00001427 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001428 VG_(debugLog)(1, "main",
1429 "(early_) Process Valgrind's command line options\n");
1430 early_process_cmd_line_options(&need_help, &toolname);
nethercote71980f02004-01-24 18:18:54 +00001431
sewardj45f4e7c2005-09-27 19:20:21 +00001432 // Set default vex control params
1433 LibVEX_default_VexControl(& VG_(clo_vex_control));
nethercote71980f02004-01-24 18:18:54 +00001434
1435 //--------------------------------------------------------------
1436 // Load client executable, finding in $PATH if necessary
sewardj95d86c02007-12-18 01:49:23 +00001437 // p: early_process_cmd_line_options() [for 'exec', 'need_help']
1438 // p: layout_remaining_space [so there's space]
sewardj17c11042006-10-15 01:26:40 +00001439 //
nethercote71980f02004-01-24 18:18:54 +00001440 // Set up client's environment
sewardj95d86c02007-12-18 01:49:23 +00001441 // p: set-libdir [for VG_(libdir)]
1442 // p: early_process_cmd_line_options [for toolname]
sewardj17c11042006-10-15 01:26:40 +00001443 //
nethercote5ee67ca2004-06-22 14:00:09 +00001444 // Setup client stack, eip, and VG_(client_arg[cv])
nethercote71980f02004-01-24 18:18:54 +00001445 // p: load_client() [for 'info']
1446 // p: fix_environment() [for 'env']
sewardj17c11042006-10-15 01:26:40 +00001447 //
sewardj45f4e7c2005-09-27 19:20:21 +00001448 // Setup client data (brk) segment. Initially a 1-page segment
1449 // which abuts a shrinkable reservation.
1450 // p: load_client() [for 'info' and hence VG_(brk_base)]
sewardjf9d2f9b2006-11-17 20:00:57 +00001451 //
1452 // p: _start_in_C (for zeroing out the_iicii and putting some
1453 // initial values into it)
sewardj45f4e7c2005-09-27 19:20:21 +00001454 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001455 if (!need_help) {
sewardjf9d2f9b2006-11-17 20:00:57 +00001456 VG_(debugLog)(1, "main", "Create initial image\n");
1457
1458# if defined(VGO_linux)
1459 the_iicii.argv = argv;
1460 the_iicii.envp = envp;
1461 the_iicii.toolname = toolname;
1462# elif defined(VGO_aix5)
1463 /* the_iicii.intregs37 already set up */
1464 /* the_iicii.bootblock already set up */
1465 /* the_iicii.adler32_exp already set up */
1466 /* the_iicii.sp_at_startup is irrelevant */
1467 /* the_iicii.clstack_top is irrelevant */
1468 the_iicii.toolname = toolname;
1469# else
1470# error "Uknown platform"
1471# endif
1472
1473 the_iifii = VG_(ii_create_image)( the_iicii );
1474
sewardj17c11042006-10-15 01:26:40 +00001475# if defined(VGO_aix5)
sewardj17c11042006-10-15 01:26:40 +00001476 /* Tell aspacem where the initial client stack is, so that it
1477 can later produce a faked-up NSegment in response to
1478 VG_(am_find_nsegment) for that address range, if asked. */
sewardjf9d2f9b2006-11-17 20:00:57 +00001479 VG_(am_aix5_set_initial_client_sp)( the_iifii.initial_client_SP );
1480 /* Now have a look at said fake segment, so we can find out
1481 the size of it. */
1482 { SizeT sz;
1483 NSegment const* seg
1484 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
1485 vg_assert(seg);
1486 sz = seg->end - seg->start + 1;
1487 vg_assert(sz >= 0 && sz <= 64*1024*1024); /* stay sane */
1488 the_iifii.clstack_max_size = sz;
1489 }
sewardj17c11042006-10-15 01:26:40 +00001490# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001491 }
nethercote71980f02004-01-24 18:18:54 +00001492
1493 //==============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001494 //
1495 // Finished loading/setting up the client address space.
1496 //
nethercote71980f02004-01-24 18:18:54 +00001497 //==============================================================
1498
1499 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001500 // setup file descriptors
1501 // p: n/a
1502 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001503 VG_(debugLog)(1, "main", "Setup file descriptors\n");
nethercote71980f02004-01-24 18:18:54 +00001504 setup_file_descriptors();
1505
1506 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001507 // create the fake /proc/<pid>/cmdline file and then unlink it,
1508 // but hold onto the fd, so we can hand it out to the client
1509 // when it tries to open /proc/<pid>/cmdline for itself.
1510 // p: setup file descriptors
nethercotec314eba2004-07-15 12:59:41 +00001511 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001512 if (!need_help) {
1513 HChar buf[50], buf2[50+64];
1514 HChar nul[1];
1515 Int fd, r;
1516 HChar* exename;
nethercotec314eba2004-07-15 12:59:41 +00001517
sewardj45f4e7c2005-09-27 19:20:21 +00001518 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
1519
1520 VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
1521 fd = VG_(mkstemp)( buf, buf2 );
1522 if (fd == -1)
sewardj17c11042006-10-15 01:26:40 +00001523 VG_(err_config_error)("Can't create client cmdline file in /tmp.");
sewardj45f4e7c2005-09-27 19:20:21 +00001524
1525 nul[0] = 0;
1526 exename = VG_(args_the_exename) ? VG_(args_the_exename)
1527 : "unknown_exename";
sewardj45f4e7c2005-09-27 19:20:21 +00001528 VG_(write)(fd, VG_(args_the_exename),
1529 VG_(strlen)( VG_(args_the_exename) ));
1530 VG_(write)(fd, nul, 1);
1531
sewardj14c7cc52007-02-25 15:08:24 +00001532 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1533 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
1534 VG_(write)(fd, arg, VG_(strlen)( arg ));
sewardj45f4e7c2005-09-27 19:20:21 +00001535 VG_(write)(fd, nul, 1);
1536 }
1537
1538 /* Don't bother to seek the file back to the start; instead do
1539 it every time a copy of it is given out (by PRE(sys_open)).
1540 That is probably more robust across fork() etc. */
1541
1542 /* Now delete it, but hang on to the fd. */
1543 r = VG_(unlink)( buf2 );
1544 if (r)
sewardj17c11042006-10-15 01:26:40 +00001545 VG_(err_config_error)("Can't delete client cmdline file in /tmp.");
sewardj45f4e7c2005-09-27 19:20:21 +00001546
1547 VG_(cl_cmdline_fd) = fd;
1548 }
nethercotec314eba2004-07-15 12:59:41 +00001549
1550 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001551 // Init tool part 1: pre_clo_init
nethercotec314eba2004-07-15 12:59:41 +00001552 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
nethercotec314eba2004-07-15 12:59:41 +00001553 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
nethercote71980f02004-01-24 18:18:54 +00001554 //--------------------------------------------------------------
njn64c83242005-06-21 01:54:38 +00001555 {
1556 Char* s;
1557 Bool ok;
sewardj45f4e7c2005-09-27 19:20:21 +00001558 VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
1559 (VG_(tool_info).tl_pre_clo_init)();
1560 ok = VG_(sanity_check_needs)( &s );
njn64c83242005-06-21 01:54:38 +00001561 if (!ok) {
1562 VG_(tool_panic)(s);
1563 }
1564 }
nethercote71980f02004-01-24 18:18:54 +00001565
sewardj45f4e7c2005-09-27 19:20:21 +00001566 //--------------------------------------------------------------
nethercotef4928da2004-06-15 10:54:40 +00001567 // If --tool and --help/--help-debug was given, now give the core+tool
1568 // help message
sewardj95d86c02007-12-18 01:49:23 +00001569 // p: early_process_cmd_line_options() [for 'need_help']
1570 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
sewardj45f4e7c2005-09-27 19:20:21 +00001571 //--------------------------------------------------------------
1572 VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
nethercotef4928da2004-06-15 10:54:40 +00001573 if (need_help) {
sewardj45f4e7c2005-09-27 19:20:21 +00001574 usage_NORETURN(/*--help-debug?*/2 == need_help);
nethercotef4928da2004-06-15 10:54:40 +00001575 }
nethercotec314eba2004-07-15 12:59:41 +00001576
sewardj45f4e7c2005-09-27 19:20:21 +00001577 //--------------------------------------------------------------
1578 // Process command line options to Valgrind + tool
1579 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1580 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1581 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001582 VG_(debugLog)(1, "main",
1583 "(main_) Process Valgrind's command line options, "
1584 "setup logging\n");
1585 logging_to_fd = main_process_cmd_line_options(client_auxv, toolname);
sewardj45f4e7c2005-09-27 19:20:21 +00001586
1587 //--------------------------------------------------------------
sewardj592ae092005-11-08 19:01:44 +00001588 // Zeroise the millisecond counter by doing a first read of it.
1589 // p: none
1590 //--------------------------------------------------------------
1591 (void) VG_(read_millisecond_timer)();
1592
1593 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001594 // Print the preamble
1595 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
sewardj95d86c02007-12-18 01:49:23 +00001596 // p: main_process_cmd_line_options() [for VG_(clo_verbosity),
1597 // VG_(clo_xml),
1598 // logging_to_fd]
sewardj45f4e7c2005-09-27 19:20:21 +00001599 //--------------------------------------------------------------
1600 VG_(debugLog)(1, "main", "Print the preamble...\n");
1601 print_preamble(logging_to_fd, toolname);
1602 VG_(debugLog)(1, "main", "...finished the preamble\n");
1603
1604 //--------------------------------------------------------------
1605 // Init tool part 2: post_clo_init
1606 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1607 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1608 // p: print_preamble() [so any warnings printed in post_clo_init
1609 // are shown after the preamble]
1610 //--------------------------------------------------------------
1611 VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
njn51d827b2005-05-09 01:02:08 +00001612 VG_TDICT_CALL(tool_post_clo_init);
nethercotef4928da2004-06-15 10:54:40 +00001613
1614 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001615 // Initialise translation table and translation cache
1616 // p: aspacem [??]
1617 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
nethercote71980f02004-01-24 18:18:54 +00001618 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001619 VG_(debugLog)(1, "main", "Initialise TT/TC\n");
1620 VG_(init_tt_tc)();
sewardjb5f6f512005-03-10 23:59:00 +00001621
sewardj45f4e7c2005-09-27 19:20:21 +00001622 //--------------------------------------------------------------
1623 // Initialise the redirect table.
1624 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
1625 // p: aspacem [so can change ownership of sysinfo pages]
1626 //--------------------------------------------------------------
1627 VG_(debugLog)(1, "main", "Initialise redirects\n");
sewardj0ec07f32006-01-12 12:32:32 +00001628 VG_(redir_initialise)();
nethercote71980f02004-01-24 18:18:54 +00001629
1630 //--------------------------------------------------------------
1631 // Allow GDB attach
sewardj95d86c02007-12-18 01:49:23 +00001632 // p: main_process_cmd_line_options() [for VG_(clo_wait_for_gdb)]
nethercote71980f02004-01-24 18:18:54 +00001633 //--------------------------------------------------------------
1634 /* Hook to delay things long enough so we can get the pid and
1635 attach GDB in another shell. */
1636 if (VG_(clo_wait_for_gdb)) {
sewardj95611ff2007-02-16 13:57:07 +00001637 Long iters;
1638 volatile Long q;
sewardj1fbc1a52005-04-25 02:05:54 +00001639 VG_(debugLog)(1, "main", "Wait for GDB\n");
sewardj93ab8572005-02-06 14:10:40 +00001640 VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
sewardj8211a572005-06-23 21:37:47 +00001641
1642# if defined(VGP_x86_linux)
1643 iters = 5;
sewardj2c48c7b2005-11-29 13:05:56 +00001644# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
sewardj8211a572005-06-23 21:37:47 +00001645 iters = 10;
1646# elif defined(VGP_ppc32_linux)
sewardjd714d2e2005-07-08 18:24:04 +00001647 iters = 5;
sewardj17c11042006-10-15 01:26:40 +00001648# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1649 iters = 4;
sewardj8211a572005-06-23 21:37:47 +00001650# else
sewardj17c11042006-10-15 01:26:40 +00001651# error "Unknown plat"
sewardj8211a572005-06-23 21:37:47 +00001652# endif
1653
1654 iters *= 1000*1000*1000;
1655 for (q = 0; q < iters; q++)
1656 ;
nethercote71980f02004-01-24 18:18:54 +00001657 }
1658
sewardjb5d320c2005-03-13 18:57:15 +00001659 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001660 // Search for file descriptors that are inherited from our parent
sewardj95d86c02007-12-18 01:49:23 +00001661 // p: main_process_cmd_line_options [for VG_(clo_track_fds)]
nethercote71980f02004-01-24 18:18:54 +00001662 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001663 if (VG_(clo_track_fds)) {
1664 VG_(debugLog)(1, "main", "Init preopened fds\n");
nethercote71980f02004-01-24 18:18:54 +00001665 VG_(init_preopened_fds)();
sewardj1fbc1a52005-04-25 02:05:54 +00001666 }
nethercote71980f02004-01-24 18:18:54 +00001667
1668 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001669 // Load debug info for the existing segments.
1670 // p: setup_code_redirect_table [so that redirs can be recorded]
1671 // p: mallocfree
1672 // p: probably: setup fds and process CLOs, so that logging works
1673 //--------------------------------------------------------------
1674 VG_(debugLog)(1, "main", "Load initial debug info\n");
sewardj17c11042006-10-15 01:26:40 +00001675# if defined(VGO_linux)
sewardj45f4e7c2005-09-27 19:20:21 +00001676 { Addr* seg_starts;
1677 Int n_seg_starts;
1678
1679 seg_starts = get_seg_starts( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001680 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00001681
sewardjf72cced2005-11-08 00:45:47 +00001682 /* show them all to the debug info reader. allow_SkFileV has to
1683 be True here so that we read info from the valgrind executable
1684 itself. */
sewardj45f4e7c2005-09-27 19:20:21 +00001685 for (i = 0; i < n_seg_starts; i++)
sewardjf72cced2005-11-08 00:45:47 +00001686 VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/ );
sewardj45f4e7c2005-09-27 19:20:21 +00001687
1688 VG_(free)( seg_starts );
1689 }
sewardj17c11042006-10-15 01:26:40 +00001690# elif defined(VGO_aix5)
1691 { AixCodeSegChange* changes;
1692 Int changes_size, changes_used;
1693
1694 /* Find out how many AixCodeSegChange records we will need,
1695 and acquire them. */
1696 changes_size = VG_(am_aix5_reread_procmap_howmany_directives)();
1697 changes = VG_(malloc)(changes_size * sizeof(AixCodeSegChange));
1698 vg_assert(changes);
1699
1700 /* Now re-read /proc/<pid>/map and acquire a change set */
1701 VG_(am_aix5_reread_procmap)( changes, &changes_used );
1702 vg_assert(changes_used >= 0 && changes_used <= changes_size);
1703
1704 /* And notify m_debuginfo of the changes. */
1705 for (i = 0; i < changes_used; i++)
1706 VG_(di_aix5_notify_segchange)(
1707 changes[i].code_start,
1708 changes[i].code_len,
1709 changes[i].data_start,
1710 changes[i].data_len,
1711 changes[i].file_name,
1712 changes[i].mem_name,
1713 changes[i].is_mainexe,
1714 changes[i].acquire
1715 );
1716
1717 VG_(free)(changes);
1718 }
1719# else
1720# error Unknown OS
1721# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001722
1723 //--------------------------------------------------------------
1724 // Tell aspacem of ownership change of the asm helpers, so that
1725 // m_translate allows them to be translated. However, only do this
1726 // after the initial debug info read, since making a hole in the
1727 // address range for the stage2 binary confuses the debug info reader.
1728 // p: aspacem
1729 //--------------------------------------------------------------
1730 { Bool change_ownership_v_c_OK;
sewardj1a85f4f2006-01-12 21:15:35 +00001731 Addr co_start = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
1732 Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
sewardj45f4e7c2005-09-27 19:20:21 +00001733 VG_(debugLog)(1,"redir",
1734 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
1735 (ULong)co_start, (ULong)co_endPlus-1 );
1736
1737 change_ownership_v_c_OK
1738 = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
1739 vg_assert(change_ownership_v_c_OK);
1740 }
1741
1742 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001743 // Initialise the scheduler (phase 1) [generates tid_main]
1744 // p: none, afaics
1745 //--------------------------------------------------------------
1746 VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
1747 tid_main = VG_(scheduler_init_phase1)();
1748 vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
1749 && tid_main != VG_INVALID_THREADID);
1750 /* Tell the tool about tid_main */
1751 VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
1752
1753 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001754 // Tell the tool about the initial client memory permissions
1755 // p: aspacem
1756 // p: mallocfree
1757 // p: setup_client_stack
1758 // p: setup_client_dataseg
1759 //--------------------------------------------------------------
1760 VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
1761 { Addr* seg_starts;
1762 Int n_seg_starts;
sewardj45f4e7c2005-09-27 19:20:21 +00001763
1764 seg_starts = get_seg_starts( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001765 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00001766
1767 /* show interesting ones to the tool */
1768 for (i = 0; i < n_seg_starts; i++) {
sewardj12ab7652006-10-17 02:10:42 +00001769 NSegment const* seg
sewardj17c11042006-10-15 01:26:40 +00001770 = VG_(am_find_nsegment)( seg_starts[i] );
sewardj45f4e7c2005-09-27 19:20:21 +00001771 vg_assert(seg);
1772 if (seg->kind == SkFileC || seg->kind == SkAnonC) {
1773 VG_(debugLog)(2, "main",
1774 "tell tool about %010lx-%010lx %c%c%c\n",
1775 seg->start, seg->end,
1776 seg->hasR ? 'r' : '-',
1777 seg->hasW ? 'w' : '-',
1778 seg->hasX ? 'x' : '-' );
1779 VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
1780 seg->hasR, seg->hasW, seg->hasX );
1781 }
1782 }
1783
1784 VG_(free)( seg_starts );
1785
1786 /* Also do the initial stack permissions. */
sewardj12ab7652006-10-17 02:10:42 +00001787 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00001788 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj17c11042006-10-15 01:26:40 +00001789 vg_assert(seg);
1790 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00001791 vg_assert(the_iifii.initial_client_SP >= seg->start);
1792 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardj17c11042006-10-15 01:26:40 +00001793# if defined(VGO_aix5)
1794 VG_(clstk_base) = seg->start;
1795 VG_(clstk_end) = seg->end;
1796# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001797
sewardj17c11042006-10-15 01:26:40 +00001798 /* Stuff below the initial SP is unaddressable. Take into
1799 account any ABI-mandated space below the stack pointer that
1800 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
1801 will have allocated an extra page if a red zone is required,
1802 to be on the safe side. */
sewardjf9d2f9b2006-11-17 20:00:57 +00001803 vg_assert(the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
1804 >= seg->start);
sewardj17c11042006-10-15 01:26:40 +00001805 VG_TRACK( die_mem_stack,
1806 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00001807 the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
1808 - seg->start );
sewardj17c11042006-10-15 01:26:40 +00001809 VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
1810 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00001811 the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
sewardj17c11042006-10-15 01:26:40 +00001812 }
sewardj45f4e7c2005-09-27 19:20:21 +00001813
1814 /* Also the assembly helpers. */
1815 VG_TRACK( new_mem_startup,
1816 (Addr)&VG_(trampoline_stuff_start),
sewardjc6527d62006-02-13 17:54:31 +00001817 (Addr)&VG_(trampoline_stuff_end)
1818 - (Addr)&VG_(trampoline_stuff_start),
sewardj45f4e7c2005-09-27 19:20:21 +00001819 False, /* readable? */
1820 False, /* writable? */
1821 True /* executable? */ );
1822 }
1823
1824 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001825 // Initialise the scheduler (phase 2)
1826 // p: Initialise the scheduler (phase 1) [for tid_main]
nethercote71980f02004-01-24 18:18:54 +00001827 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
sewardj45f4e7c2005-09-27 19:20:21 +00001828 // p: setup_client_stack
nethercote71980f02004-01-24 18:18:54 +00001829 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001830 VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
sewardj12ab7652006-10-17 02:10:42 +00001831 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00001832 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj45f4e7c2005-09-27 19:20:21 +00001833 vg_assert(seg);
1834 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00001835 vg_assert(the_iifii.initial_client_SP >= seg->start);
1836 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardjde764e82007-11-09 23:13:22 +00001837 VG_(scheduler_init_phase2)( tid_main,
1838 seg->end, the_iifii.clstack_max_size );
sewardj45f4e7c2005-09-27 19:20:21 +00001839 }
nethercote71980f02004-01-24 18:18:54 +00001840
1841 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001842 // Set up state for the root thread
sewardjb5f6f512005-03-10 23:59:00 +00001843 // p: ?
sewardj17c11042006-10-15 01:26:40 +00001844 // setup_scheduler() [for sched-specific thread 1 stuff]
sewardjf9d2f9b2006-11-17 20:00:57 +00001845 // VG_(ii_create_image) [for 'the_iicii' initial info]
sewardj2a99cf62004-11-24 10:44:19 +00001846 //--------------------------------------------------------------
sewardjf9d2f9b2006-11-17 20:00:57 +00001847 VG_(debugLog)(1, "main", "Finalise initial image\n");
1848 VG_(ii_finalise_image)( the_iifii );
njnea4b28c2004-11-30 16:04:58 +00001849
sewardj2a99cf62004-11-24 10:44:19 +00001850 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001851 // Initialise the signal handling subsystem
sewardjb5f6f512005-03-10 23:59:00 +00001852 // p: n/a
nethercote71980f02004-01-24 18:18:54 +00001853 //--------------------------------------------------------------
1854 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
sewardj1fbc1a52005-04-25 02:05:54 +00001855 VG_(debugLog)(1, "main", "Initialise signal management\n");
nethercote71980f02004-01-24 18:18:54 +00001856 VG_(sigstartup_actions)();
1857
1858 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001859 // Read suppression file
sewardj95d86c02007-12-18 01:49:23 +00001860 // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
nethercote71980f02004-01-24 18:18:54 +00001861 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001862 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
1863 VG_(debugLog)(1, "main", "Load suppressions\n");
nethercote71980f02004-01-24 18:18:54 +00001864 VG_(load_suppressions)();
sewardj1fbc1a52005-04-25 02:05:54 +00001865 }
nethercote71980f02004-01-24 18:18:54 +00001866
1867 //--------------------------------------------------------------
rjwalsh0140af52005-06-04 20:42:33 +00001868 // register client stack
1869 //--------------------------------------------------------------
njn945ed2e2005-06-24 03:28:30 +00001870 VG_(clstk_id) = VG_(register_stack)(VG_(clstk_base), VG_(clstk_end));
rjwalsh0140af52005-06-04 20:42:33 +00001871
1872 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001873 // Show the address space state so far
1874 //--------------------------------------------------------------
1875 VG_(debugLog)(1, "main", "\n");
1876 VG_(debugLog)(1, "main", "\n");
1877 VG_(am_show_nsegments)(1,"Memory layout at client startup");
1878 VG_(debugLog)(1, "main", "\n");
1879 VG_(debugLog)(1, "main", "\n");
1880
1881 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001882 // Run!
1883 //--------------------------------------------------------------
sewardj71bc3cb2005-05-19 00:25:45 +00001884 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00001885 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00001886 VG_(elapsed_wallclock_time)(buf);
sewardj753673f2005-08-09 22:03:08 +00001887 VG_(message)(Vg_UserMsg, "<status>\n"
1888 " <state>RUNNING</state>\n"
1889 " <time>%t</time>\n"
1890 "</status>",
1891 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00001892 VG_(message)(Vg_UserMsg, "");
1893 }
1894
sewardj1fbc1a52005-04-25 02:05:54 +00001895 VG_(debugLog)(1, "main", "Running thread 1\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00001896
sewardj1d887112005-05-30 21:44:08 +00001897 /* As a result of the following call, the last thread standing
sewardj1ae3f3a2005-09-28 10:47:38 +00001898 eventually winds up running shutdown_actions_NORETURN
1899 just below. Unfortunately, simply exporting said function
1900 causes m_main to be part of a module cycle, which is pretty
1901 nonsensical. So instead of doing that, the address of said
1902 function is stored in a global variable 'owned' by m_syswrap,
1903 and it uses that function pointer to get back here when it needs
1904 to. */
1905
1906 /* Set continuation address. */
1907 VG_(address_of_m_main_shutdown_actions_NORETURN)
1908 = & shutdown_actions_NORETURN;
1909
1910 /* Run the first thread, eventually ending up at the continuation
1911 address. */
njnaf839f52005-06-23 03:27:57 +00001912 VG_(main_thread_wrapper_NORETURN)(1);
nethercote71980f02004-01-24 18:18:54 +00001913
sewardj1d887112005-05-30 21:44:08 +00001914 /*NOTREACHED*/
1915 vg_assert(0);
sewardjb5f6f512005-03-10 23:59:00 +00001916}
1917
sewardj17c11042006-10-15 01:26:40 +00001918/* Do everything which needs doing when the last thread exits or when
1919 a thread exits requesting a complete process exit (exit on AIX).
1920
1921 We enter here holding The Lock. For the case VgSrc_ExitProcess we
1922 must never release it, because to do so would allow other threads
1923 to continue after the system is ostensibly shut down. So we must
1924 go to our grave, so to speak, holding the lock.
1925
1926 In fact, there is never any point in releasing the lock at this
1927 point - we have it, we're shutting down the entire system, and
1928 for the case VgSrc_ExitProcess doing so positively causes trouble.
1929 So don't.
1930
1931 The final_tidyup call makes a bit of a nonsense of the ExitProcess
1932 case, since it will run the libc_freeres function, thus allowing
1933 other lurking threads to run again. Hmm. */
sewardjb5f6f512005-03-10 23:59:00 +00001934
sewardj1ae3f3a2005-09-28 10:47:38 +00001935static
1936void shutdown_actions_NORETURN( ThreadId tid,
1937 VgSchedReturnCode tids_schedretcode )
sewardjb5f6f512005-03-10 23:59:00 +00001938{
sewardj1d887112005-05-30 21:44:08 +00001939 VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
sewardj17c11042006-10-15 01:26:40 +00001940 VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
sewardj1d887112005-05-30 21:44:08 +00001941
sewardjb5f6f512005-03-10 23:59:00 +00001942 vg_assert(VG_(is_running_thread)(tid));
1943
sewardj12ab7652006-10-17 02:10:42 +00001944 vg_assert(tids_schedretcode == VgSrc_ExitThread
1945 || tids_schedretcode == VgSrc_ExitProcess
1946 || tids_schedretcode == VgSrc_FatalSig );
sewardjb5f6f512005-03-10 23:59:00 +00001947
sewardj12ab7652006-10-17 02:10:42 +00001948 if (tids_schedretcode == VgSrc_ExitThread) {
sewardjb5f6f512005-03-10 23:59:00 +00001949
sewardj17c11042006-10-15 01:26:40 +00001950 // We are the last surviving thread. Right?
1951 vg_assert( VG_(count_living_threads)() == 1 );
sewardjb5f6f512005-03-10 23:59:00 +00001952
sewardj17c11042006-10-15 01:26:40 +00001953 // Wait for all other threads to exit.
1954 // jrs: Huh? but they surely are already gone
1955 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00001956
sewardj17c11042006-10-15 01:26:40 +00001957 // Clean the client up before the final report
1958 // this causes the libc_freeres function to run
1959 final_tidyup(tid);
1960
1961 /* be paranoid */
1962 vg_assert(VG_(is_running_thread)(tid));
1963 vg_assert(VG_(count_living_threads)() == 1);
1964
1965 } else {
1966
1967 // We may not be the last surviving thread. However, we
1968 // want to shut down the entire process. We hold the lock
1969 // and we need to keep hold of it all the way out, in order
1970 // that none of the other threads ever run again.
1971 vg_assert( VG_(count_living_threads)() >= 1 );
1972
sewardj17c11042006-10-15 01:26:40 +00001973 // Clean the client up before the final report
1974 // this causes the libc_freeres function to run
1975 // perhaps this is unsafe, as per comment above
1976 final_tidyup(tid);
1977
1978 /* be paranoid */
1979 vg_assert(VG_(is_running_thread)(tid));
1980 vg_assert(VG_(count_living_threads)() >= 1);
1981 }
sewardjb5f6f512005-03-10 23:59:00 +00001982
1983 VG_(threads)[tid].status = VgTs_Empty;
nethercote71980f02004-01-24 18:18:54 +00001984 //--------------------------------------------------------------
1985 // Finalisation: cleanup, messages, etc. Order no so important, only
1986 // affects what order the messages come.
1987 //--------------------------------------------------------------
1988 if (VG_(clo_verbosity) > 0)
1989 VG_(message)(Vg_UserMsg, "");
1990
sewardj71bc3cb2005-05-19 00:25:45 +00001991 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00001992 HChar buf[50];
sewardj9f297ca2005-05-20 02:29:52 +00001993 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
1994 VG_(show_error_counts_as_XML)();
1995 VG_(message)(Vg_UserMsg, "");
1996 }
sewardj592ae092005-11-08 19:01:44 +00001997 VG_(elapsed_wallclock_time)(buf);
sewardj753673f2005-08-09 22:03:08 +00001998 VG_(message)(Vg_UserMsg, "<status>\n"
1999 " <state>FINISHED</state>\n"
2000 " <time>%t</time>\n"
2001 "</status>",
2002 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00002003 VG_(message)(Vg_UserMsg, "");
2004 }
2005
nethercote71980f02004-01-24 18:18:54 +00002006 /* Print out file descriptor summary and stats. */
2007 if (VG_(clo_track_fds))
nethercote3a42fb82004-08-03 18:08:50 +00002008 VG_(show_open_fds)();
nethercote71980f02004-01-24 18:18:54 +00002009
njn95ec8702004-11-22 16:46:13 +00002010 if (VG_(needs).core_errors || VG_(needs).tool_errors)
nethercote71980f02004-01-24 18:18:54 +00002011 VG_(show_all_errors)();
2012
njn51d827b2005-05-09 01:02:08 +00002013 VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
nethercote71980f02004-01-24 18:18:54 +00002014
sewardj71bc3cb2005-05-19 00:25:45 +00002015 if (VG_(clo_xml)) {
2016 VG_(message)(Vg_UserMsg, "");
2017 VG_(message)(Vg_UserMsg, "</valgrindoutput>");
2018 VG_(message)(Vg_UserMsg, "");
2019 }
2020
nethercote885dd912004-08-03 23:14:00 +00002021 VG_(sanity_check_general)( True /*include expensive checks*/ );
nethercote71980f02004-01-24 18:18:54 +00002022
2023 if (VG_(clo_verbosity) > 1)
nethercote3a42fb82004-08-03 18:08:50 +00002024 print_all_stats();
nethercote71980f02004-01-24 18:18:54 +00002025
njn2025cf92005-06-26 20:44:48 +00002026 if (VG_(clo_profile_flags) > 0) {
sewardj5471ec62006-10-17 13:58:17 +00002027 #define N_MAX 200
njn2025cf92005-06-26 20:44:48 +00002028 BBProfEntry tops[N_MAX];
2029 ULong score_total = VG_(get_BB_profile) (tops, N_MAX);
2030 show_BB_profile(tops, N_MAX, score_total);
2031 }
sewardjfa8ec112005-01-19 11:55:34 +00002032
sewardj8b635a42004-11-22 19:01:47 +00002033 /* Print Vex storage stats */
sewardjbf426512005-01-17 18:35:30 +00002034 if (0)
2035 LibVEX_ShowAllocStats();
sewardj1d887112005-05-30 21:44:08 +00002036
njn8aa35852005-06-10 22:59:56 +00002037 /* Ok, finally exit in the os-specific way, according to the scheduler's
2038 return code. In short, if the (last) thread exited by calling
2039 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2040 signal, terminate the entire system with that same fatal signal. */
2041 VG_(debugLog)(1, "core_os",
njn7b85dd52005-06-12 17:26:29 +00002042 "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
njn8aa35852005-06-10 22:59:56 +00002043
njn8aa35852005-06-10 22:59:56 +00002044 switch (tids_schedretcode) {
sewardj12ab7652006-10-17 02:10:42 +00002045 case VgSrc_ExitThread: /* the normal way out (Linux) */
2046 case VgSrc_ExitProcess: /* the normal way out (AIX) */
sewardjb9779082006-05-12 23:50:15 +00002047 /* Change the application return code to user's return code,
2048 if an error was found */
2049 if (VG_(clo_error_exitcode) > 0
2050 && VG_(get_n_errs_found)() > 0) {
2051 VG_(exit)( VG_(clo_error_exitcode) );
2052 } else {
2053 /* otherwise, return the client's exit code, in the normal
2054 way. */
2055 VG_(exit)( VG_(threads)[tid].os_state.exitcode );
2056 }
njn8aa35852005-06-10 22:59:56 +00002057 /* NOT ALIVE HERE! */
sewardj17c11042006-10-15 01:26:40 +00002058 VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
njn8aa35852005-06-10 22:59:56 +00002059 break; /* what the hell :) */
2060
2061 case VgSrc_FatalSig:
2062 /* We were killed by a fatal signal, so replicate the effect */
2063 vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
2064 VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
2065 VG_(core_panic)("main(): signal was supposed to be fatal");
2066 break;
2067
2068 default:
2069 VG_(core_panic)("main(): unexpected scheduler return code");
2070 }
njne96be672005-05-08 19:08:54 +00002071}
sewardj8b635a42004-11-22 19:01:47 +00002072
sewardj1ae3f3a2005-09-28 10:47:38 +00002073/* -------------------- */
2074
2075/* Final clean-up before terminating the process.
2076 Clean up the client by calling __libc_freeres() (if requested)
2077 This is Linux-specific?
2078*/
2079static void final_tidyup(ThreadId tid)
2080{
sewardjcf951812006-01-17 02:22:21 +00002081# if defined(VGP_ppc64_linux)
2082 Addr r2;
2083# endif
sewardj0ec07f32006-01-12 12:32:32 +00002084 Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
sewardj1ae3f3a2005-09-28 10:47:38 +00002085
2086 vg_assert(VG_(is_running_thread)(tid));
2087
2088 if ( !VG_(needs).libc_freeres ||
2089 !VG_(clo_run_libc_freeres) ||
sewardj0ec07f32006-01-12 12:32:32 +00002090 0 == __libc_freeres_wrapper )
sewardj1ae3f3a2005-09-28 10:47:38 +00002091 return; /* can't/won't do it */
sewardj17c11042006-10-15 01:26:40 +00002092# if defined(VGO_aix5)
2093 return; /* inapplicable on non-Linux platforms */
2094# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002095
sewardjcf951812006-01-17 02:22:21 +00002096# if defined(VGP_ppc64_linux)
2097 r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
2098 if (r2 == 0) {
2099 VG_(message)(Vg_UserMsg,
2100 "Caught __NR_exit, but can't run __libc_freeres()");
2101 VG_(message)(Vg_UserMsg,
2102 " since cannot establish TOC pointer for it.");
2103 return;
2104 }
2105# endif
2106
sewardj1ae3f3a2005-09-28 10:47:38 +00002107 if (VG_(clo_verbosity) > 2 ||
2108 VG_(clo_trace_syscalls) ||
2109 VG_(clo_trace_sched))
2110 VG_(message)(Vg_DebugMsg,
2111 "Caught __NR_exit; running __libc_freeres()");
2112
sewardj0ec07f32006-01-12 12:32:32 +00002113 /* set thread context to point to libc_freeres_wrapper */
sewardj1a85f4f2006-01-12 21:15:35 +00002114 /* ppc64-linux note: __libc_freeres_wrapper gives us the real
2115 function entry point, not a fn descriptor, so can use it
2116 directly. However, we need to set R2 (the toc pointer)
2117 appropriately. */
sewardj1ae3f3a2005-09-28 10:47:38 +00002118 VG_(set_IP)(tid, __libc_freeres_wrapper);
sewardjcf951812006-01-17 02:22:21 +00002119# if defined(VGP_ppc64_linux)
2120 VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
2121# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002122
2123 /* Block all blockable signals by copying the real block state into
2124 the thread's block state*/
2125 VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
2126 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
2127
2128 /* and restore handlers to default */
2129 VG_(set_default_handler)(VKI_SIGSEGV);
2130 VG_(set_default_handler)(VKI_SIGBUS);
2131 VG_(set_default_handler)(VKI_SIGILL);
2132 VG_(set_default_handler)(VKI_SIGFPE);
2133
2134 // We were exiting, so assert that...
2135 vg_assert(VG_(is_exiting)(tid));
2136 // ...but now we're not again
2137 VG_(threads)[tid].exitreason = VgSrc_None;
2138
2139 // run until client thread exits - ideally with LIBC_FREERES_DONE,
2140 // but exit/exitgroup/signal will do
2141 VG_(scheduler)(tid);
2142
2143 vg_assert(VG_(is_exiting)(tid));
2144}
2145
sewardj45f4e7c2005-09-27 19:20:21 +00002146
2147/*====================================================================*/
sewardj17c11042006-10-15 01:26:40 +00002148/*=== Getting to main() alive: LINUX (for AIX5 see below) ===*/
sewardj45f4e7c2005-09-27 19:20:21 +00002149/*====================================================================*/
2150
sewardj17c11042006-10-15 01:26:40 +00002151#if defined(VGO_linux)
2152
sewardj45f4e7c2005-09-27 19:20:21 +00002153/* If linking of the final executables is done with glibc present,
2154 then Valgrind starts at main() above as usual, and all of the
2155 following code is irrelevant.
2156
2157 However, this is not the intended mode of use. The plan is to
2158 avoid linking against glibc, by giving gcc the flags
2159 -nodefaultlibs -lgcc -nostartfiles at startup.
2160
2161 From this derive two requirements:
2162
2163 1. gcc may emit calls to memcpy and memset to deal with structure
2164 assignments etc. Since we have chosen to ignore all the
2165 "normal" supporting libraries, we have to provide our own
2166 implementations of them. No problem.
2167
2168 2. We have to provide a symbol "_start", to which the kernel
2169 hands control at startup. Hence the code below.
2170*/
2171
2172/* ---------------- Requirement 1 ---------------- */
2173
sewardj17c11042006-10-15 01:26:40 +00002174void* memcpy(void *dest, const void *src, SizeT n);
2175void* memcpy(void *dest, const void *src, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002176 return VG_(memcpy)(dest,src,n);
2177}
sewardj17c11042006-10-15 01:26:40 +00002178void* memset(void *s, int c, SizeT n);
2179void* memset(void *s, int c, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002180 return VG_(memset)(s,c,n);
2181}
2182
2183/* ---------------- Requirement 2 ---------------- */
2184
2185/* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2186 comment, which explains how the stack looks right at process start
2187 (when _start is jumped to). Hence _start passes %esp to
sewardj17c11042006-10-15 01:26:40 +00002188 _start_in_C_linux, which extracts argc/argv/envp and starts up
sewardj45f4e7c2005-09-27 19:20:21 +00002189 correctly. */
2190
2191/* This is the canonical entry point, usually the first thing in the text
2192 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2193 point runs, most registers' values are unspecified, except for:
2194
2195 %edx Contains a function pointer to be registered with `atexit'.
2196 This is how the dynamic linker arranges to have DT_FINI
2197 functions called for shared libraries that have been loaded
2198 before this code runs.
2199
2200 %esp The stack contains the arguments and environment:
2201 0(%esp) argc
2202 4(%esp) argv[0]
2203 ...
2204 (4*argc)(%esp) NULL
2205 (4*(argc+1))(%esp) envp[0]
2206 ...
2207 NULL
2208*/
2209
2210/* The kernel hands control to _start, which extracts the initial
sewardj17c11042006-10-15 01:26:40 +00002211 stack pointer and calls onwards to _start_in_C_linux. This also switches
sewardja48a4932005-09-29 11:09:56 +00002212 the new stack. */
sewardj45f4e7c2005-09-27 19:20:21 +00002213#if defined(VGP_x86_linux)
2214asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002215 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002216 "\t.globl _start\n"
2217 "\t.type _start,@function\n"
2218 "_start:\n"
2219 /* set up the new stack in %eax */
sewardjfdf91b42005-09-28 00:53:09 +00002220 "\tmovl $vgPlain_interim_stack, %eax\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002221 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2222 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2223 "\tsubl $16, %eax\n"
2224 "\tandl $~15, %eax\n"
2225 /* install it, and collect the original one */
2226 "\txchgl %eax, %esp\n"
sewardj17c11042006-10-15 01:26:40 +00002227 /* call _start_in_C_linux, passing it the startup %esp */
sewardj45f4e7c2005-09-27 19:20:21 +00002228 "\tpushl %eax\n"
sewardj17c11042006-10-15 01:26:40 +00002229 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002230 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002231 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002232);
2233#elif defined(VGP_amd64_linux)
2234asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002235 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002236 "\t.globl _start\n"
2237 "\t.type _start,@function\n"
2238 "_start:\n"
2239 /* set up the new stack in %rdi */
sewardjfdf91b42005-09-28 00:53:09 +00002240 "\tmovq $vgPlain_interim_stack, %rdi\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002241 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2242 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2243 "\tandq $~15, %rdi\n"
2244 /* install it, and collect the original one */
2245 "\txchgq %rdi, %rsp\n"
sewardj17c11042006-10-15 01:26:40 +00002246 /* call _start_in_C_linux, passing it the startup %rsp */
2247 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002248 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002249 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002250);
sewardja48a4932005-09-29 11:09:56 +00002251#elif defined(VGP_ppc32_linux)
2252asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002253 ".text\n"
sewardja48a4932005-09-29 11:09:56 +00002254 "\t.globl _start\n"
2255 "\t.type _start,@function\n"
2256 "_start:\n"
2257 /* set up the new stack in r16 */
2258 "\tlis 16,vgPlain_interim_stack@ha\n"
2259 "\tla 16,vgPlain_interim_stack@l(16)\n"
2260 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2261 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2262 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2263 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2264 "\tadd 16,17,16\n"
2265 "\tadd 16,18,16\n"
2266 "\trlwinm 16,16,0,0,27\n"
2267 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2268 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2269 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002270 call _start_in_C_linux, passing it the initial SP. */
sewardja48a4932005-09-29 11:09:56 +00002271 "\tmr 3,1\n"
2272 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002273 "\tbl _start_in_C_linux\n"
sewardja48a4932005-09-29 11:09:56 +00002274 "\ttrap\n"
sewardj2fedc642005-11-19 02:02:57 +00002275 ".previous\n"
sewardja48a4932005-09-29 11:09:56 +00002276);
sewardj2c48c7b2005-11-29 13:05:56 +00002277#elif defined(VGP_ppc64_linux)
2278asm("\n"
cerion21082042005-12-06 19:07:08 +00002279 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2280 So we must have one, and that is what goes into the .opd section. */
cerion297c88f2005-12-22 15:53:12 +00002281 "\t.align 2\n"
cerion21082042005-12-06 19:07:08 +00002282 "\t.global _start\n"
2283 "\t.section \".opd\",\"aw\"\n"
2284 "\t.align 3\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002285 "_start:\n"
cerion21082042005-12-06 19:07:08 +00002286 "\t.quad ._start,.TOC.@tocbase,0\n"
2287 "\t.previous\n"
2288 "\t.type ._start,@function\n"
2289 "\t.global ._start\n"
2290 "._start:\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002291 /* set up the new stack in r16 */
2292 "\tlis 16, vgPlain_interim_stack@highest\n"
2293 "\tori 16,16,vgPlain_interim_stack@higher\n"
2294 "\tsldi 16,16,32\n"
2295 "\toris 16,16,vgPlain_interim_stack@h\n"
2296 "\tori 16,16,vgPlain_interim_stack@l\n"
2297 "\txor 17,17,17\n"
2298 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2299 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2300 "\txor 18,18,18\n"
2301 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2302 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2303 "\tadd 16,17,16\n"
2304 "\tadd 16,18,16\n"
2305 "\trldicr 16,16,0,59\n"
2306 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2307 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2308 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002309 call _start_in_C_linux, passing it the initial SP. */
sewardj2c48c7b2005-11-29 13:05:56 +00002310 "\tmr 3,1\n"
2311 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002312 "\tbl ._start_in_C_linux\n"
cerion21082042005-12-06 19:07:08 +00002313 "\tnop\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002314 "\ttrap\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002315);
sewardj45f4e7c2005-09-27 19:20:21 +00002316#else
2317#error "_start: needs implementation on this platform"
2318#endif
2319
sewardje66f2e02006-12-30 17:45:08 +00002320/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
2321#define _GNU_SOURCE
2322#define _FILE_OFFSET_BITS 64
2323/* This is in order to get AT_NULL and AT_PAGESIZE. */
2324#include <elf.h>
2325/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
2326
sewardj45f4e7c2005-09-27 19:20:21 +00002327/* Avoid compiler warnings: this fn _is_ used, but labelling it
2328 'static' causes gcc to complain it isn't. */
sewardj17c11042006-10-15 01:26:40 +00002329void _start_in_C_linux ( UWord* pArgc );
2330void _start_in_C_linux ( UWord* pArgc )
sewardj45f4e7c2005-09-27 19:20:21 +00002331{
2332 Int r;
2333 Word argc = pArgc[0];
2334 HChar** argv = (HChar**)&pArgc[1];
2335 HChar** envp = (HChar**)&pArgc[1+argc+1];
sewardjf9d2f9b2006-11-17 20:00:57 +00002336
2337 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2338 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2339
2340 the_iicii.sp_at_startup = (Addr)pArgc;
2341
sewardje66f2e02006-12-30 17:45:08 +00002342# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
2343 {
2344 /* ppc/ppc64 can be configured with different page sizes.
2345 Determine this early. This is an ugly hack and really should
2346 be moved into valgrind_main. */
2347 UWord *sp = &pArgc[1+argc+1];
2348 while (*sp++ != 0)
2349 ;
2350 for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
2351 if (*sp == AT_PAGESZ) {
2352 VKI_PAGE_SIZE = sp[1];
2353 for (VKI_PAGE_SHIFT = 12;
2354 VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
2355 if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
2356 break;
2357 }
2358 }
2359# endif
2360
sewardjf9d2f9b2006-11-17 20:00:57 +00002361 r = valgrind_main( (Int)argc, argv, envp );
sewardj17c11042006-10-15 01:26:40 +00002362 /* NOTREACHED */
sewardj45f4e7c2005-09-27 19:20:21 +00002363 VG_(exit)(r);
2364}
2365
sewardj17c11042006-10-15 01:26:40 +00002366#endif /* defined(VGO_linux) */
2367
2368
2369/*====================================================================*/
2370/*=== Getting to main() alive: AIX5 ===*/
2371/*====================================================================*/
2372
2373#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
2374
2375/* This is somewhat simpler than the Linux case. _start_valgrind
2376 receives control from the magic piece of code created in this
2377 process' address space by the launcher, via use of ptrace(). At
2378 the point of entry:
2379
2380 - the initial client process image is in memory and ready to roll,
2381 except that we've partially trashed its integer register state
2382 in order to get this far. So ..
2383
2384 - intregs37 holds the client's initial integer register state, so
2385 we can restore it before starting the client on the VCPU.
2386
2387 - we're on the client's stack. This is not good; therefore the
2388 first order of business is to switch to our temporary stack.
2389
2390 - the client's initial argc/v/envp is in r3/r4/r5 (32 bit mode) or
2391 r14/r15/r16 (64 bit mode). They are pulled out of the stashed
2392 integer register state and passed to our main().
2393
2394 The launcher will have played some games with argv. If the launcher
2395 ($prefix/bin/valgrind) was started like this
2396
2397 valgrind [args-for-V] app [args-for-app]
2398
2399 then the launcher will have started the client as
2400
2401 app [args-for-V] app [args-for-app]
2402
2403 m_initimg will have to mess with the client's initial r4/r5
2404 (32-bit) or r15/r16 (64-bit) so that it believes it was execd as
2405 "app [args-for-app]". Well, that's no big deal.
2406*/
2407
2408#include "launcher-aix5-bootblock.h"
2409
2410void _start_in_C_aix5 ( AIX5Bootblock* bootblock );
2411void _start_in_C_aix5 ( AIX5Bootblock* bootblock )
2412{
2413 Int r;
2414 ULong* intregs37;
2415 UWord argc, argv, envp;
2416 __NR_getpid = bootblock->__NR_getpid;
2417 __NR_write = bootblock->__NR_write;
2418 __NR_exit = bootblock->__NR_exit;
2419 __NR_open = bootblock->__NR_open;
2420 __NR_read = bootblock->__NR_read;
2421 __NR_close = bootblock->__NR_close;
sewardjf9d2f9b2006-11-17 20:00:57 +00002422
2423 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2424 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2425
sewardj17c11042006-10-15 01:26:40 +00002426 intregs37 = &bootblock->iregs_pc_cr_lr_ctr_xer[0];
sewardjf9d2f9b2006-11-17 20:00:57 +00002427 the_iicii.intregs37 = intregs37;
2428 the_iicii.bootblock = (void*)bootblock;
2429 the_iicii.adler32_exp = bootblock->adler32;
2430
2431 /* Not important on AIX. */
2432 the_iicii.sp_at_startup = (Addr)0x31415927ULL;
2433
sewardj17c11042006-10-15 01:26:40 +00002434# if defined(VGP_ppc32_aix5)
2435 argc = (UWord)intregs37[3]; /* client's r3 == argc */
2436 argv = (UWord)intregs37[4];
2437 envp = (UWord)intregs37[5];
2438# else /* defined(VGP_ppc64_aix5) */
2439 argc = (UWord)intregs37[14]; /* client's r14 == argc */
2440 argv = (UWord)intregs37[15];
2441 envp = (UWord)intregs37[16];
2442# endif
sewardjf9d2f9b2006-11-17 20:00:57 +00002443
2444 r = valgrind_main( (Int)argc, (HChar**)argv, (HChar**)envp );
2445
sewardj17c11042006-10-15 01:26:40 +00002446 /* NOTREACHED */
2447 VG_(exit)(r);
2448}
2449
2450/* THE ENTRY POINT */
2451void _start_valgrind ( AIX5Bootblock* bootblock );
2452void _start_valgrind ( AIX5Bootblock* bootblock )
2453{
2454 /* Switch immediately to our temporary stack, and continue. This
2455 is pretty dodgy in that it assumes that gcc does not place on
2456 the stack, anything needed to form the _start_in_C_aix5 call,
2457 since it will be on the old stack. */
2458 register UWord new_r1;
2459 new_r1 = (UWord)&VG_(interim_stack);
2460 new_r1 += VG_STACK_GUARD_SZB; /* step over lower guard page */
2461 new_r1 += VG_STACK_ACTIVE_SZB; /* step to top of active area */
2462 new_r1 -= 512; /* paranoia */
2463 __asm__ __volatile__("mr 1,%0" :/*wr*/
2464 :/*rd*/ "b"(new_r1)
2465 :/*trash*/"r1","memory");
2466 _start_in_C_aix5(bootblock);
2467 /*NOTREACHED*/
2468 VG_(exit)(0);
2469}
2470
2471#endif /* defined(VGP_ppc{32,64}_aix5) */
2472
2473
sewardjde4a1d02002-03-22 01:27:54 +00002474/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00002475/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00002476/*--------------------------------------------------------------------*/