blob: ca9dc4b98df1b46dae877f9fbd7f4cbc78eff4f1 [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{
njn25e49d8e72002-09-23 09:36:25 +0000107 Char* usage1 =
njn00cfcfc2005-11-12 18:53:50 +0000108"usage: valgrind [options] prog-and-args\n"
njn25e49d8e72002-09-23 09:36:25 +0000109"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000110" common user options for all Valgrind tools, with defaults in [ ]:\n"
sewardjb5f6f512005-03-10 23:59:00 +0000111" --tool=<name> use the Valgrind tool named <name> [memcheck]\n"
nethercotea76368b2004-06-16 11:56:29 +0000112" -h --help show this message\n"
nethercote6c999f22004-01-31 22:55:15 +0000113" --help-debug show this message, plus debugging options\n"
njn25e49d8e72002-09-23 09:36:25 +0000114" --version show version\n"
njn25e49d8e72002-09-23 09:36:25 +0000115" -q --quiet run silently; only print error msgs\n"
116" -v --verbose be more verbose, incl counts of errors\n"
nethercote77eba602003-11-13 17:35:04 +0000117" --trace-children=no|yes Valgrind-ise child processes? [no]\n"
nethercote0d588502004-06-21 13:27:11 +0000118" --track-fds=no|yes track open file descriptors? [no]\n"
thughes6233a382004-08-21 11:10:44 +0000119" --time-stamp=no|yes add timestamps to log messages? [no]\n"
njnce545552005-07-25 22:36:52 +0000120" --log-fd=<number> log messages to file descriptor [2=stderr]\n"
tombbe14b12005-11-04 16:49:39 +0000121" --log-file=<file> log messages to <file>.<pid>\n"
njnce545552005-07-25 22:36:52 +0000122" --log-file-exactly=<file> log messages to <file>\n"
123" --log-file-qualifier=<VAR> incorporate $VAR in logfile name [none]\n"
124" --log-socket=ipaddr:port log messages to socket ipaddr:port\n"
nethercote2b0793f2003-12-02 10:41:18 +0000125"\n"
126" uncommon user options for all Valgrind tools:\n"
nethercote0d588502004-06-21 13:27:11 +0000127" --run-libc-freeres=no|yes free up glibc memory at exit? [yes]\n"
njn628add62005-11-12 18:21:40 +0000128" --sim-hints=hint1,hint2,... known hints:\n"
sewardj19617ae2005-10-20 01:09:57 +0000129" lax-ioctls, enable-outer [none]\n"
sewardjb1131a82005-03-19 15:12:21 +0000130" --show-emwarns=no|yes show warnings about emulation limits? [no]\n"
sewardj6c3a2192005-07-24 07:00:45 +0000131" --smc-check=none|stack|all checks for self-modifying code: none,\n"
132" only for code found in stacks, or all [stack]\n"
sewardj3c3f0c12005-11-08 15:52:36 +0000133" --kernel-variant=variant1,variant2,... known variants: bproc [none]\n"
134" handle non-standard kernel variants\n"
njn25e49d8e72002-09-23 09:36:25 +0000135"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000136" user options for Valgrind tools that report errors:\n"
njnca54af32006-04-16 10:25:43 +0000137" --xml=yes all output is in XML (some tools only)\n"
njnc8ec9f82005-07-20 03:03:28 +0000138" --xml-user-comment=STR copy STR verbatim to XML output\n"
nethercote2b0793f2003-12-02 10:41:18 +0000139" --demangle=no|yes automatically demangle C++ names? [yes]\n"
njn20b4a152005-10-19 22:39:40 +0000140" --num-callers=<number> show <number> callers in stack traces [12]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000141" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
sewardjb9779082006-05-12 23:50:15 +0000142" --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000143" --show-below-main=no|yes continue stack traces below main() [no]\n"
144" --suppressions=<filename> suppress errors described in <filename>\n"
sewardjd153fae2005-01-10 17:24:47 +0000145" --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000146" --db-attach=no|yes start debugger when errors detected? [no]\n"
147" --db-command=<command> command to start debugger [gdb -nw %%f %%p]\n"
148" --input-fd=<number> file descriptor for input [0=stdin]\n"
sewardj97724e52005-04-02 23:40:59 +0000149" --max-stackframe=<number> assume stack switch for SP changes larger\n"
150" than <number> bytes [2000000]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000151"\n";
njn7cf0bd32002-06-08 13:36:03 +0000152
njn25e49d8e72002-09-23 09:36:25 +0000153 Char* usage2 =
154"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000155" debugging options for all Valgrind tools:\n"
njn25e49d8e72002-09-23 09:36:25 +0000156" --sanity-level=<number> level of sanity checking to do [1]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000157" --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
158" --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
sewardj33afdb52006-01-17 02:36:40 +0000159" --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
njn25e49d8e72002-09-23 09:36:25 +0000160" --trace-syscalls=no|yes show all system calls? [no]\n"
161" --trace-signals=no|yes show signal handling details? [no]\n"
162" --trace-symtab=no|yes show symbol table details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000163" --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
sewardjce058b02005-05-01 08:55:38 +0000164" --trace-cfi=no|yes show call-frame-info details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000165" --debug-dump=syms mimic /usr/bin/readelf --syms\n"
166" --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
167" --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
sewardj0ec07f32006-01-12 12:32:32 +0000168" --trace-redir=no|yes show redirection details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000169" --trace-sched=no|yes show thread scheduler details? [no]\n"
jsgf855d93d2003-10-13 22:26:55 +0000170" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
sewardj17c11042006-10-15 01:26:40 +0000171" --sym-offsets=yes|no show syms in form 'name+offset' ? [no]\n"
sewardjb5f6f512005-03-10 23:59:00 +0000172#if 0
173" --model-pthreads=yes|no model the pthreads library [no]\n"
174#endif
175" --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
njnbe9b47b2005-05-15 16:22:58 +0000212 // Ensure the message goes to stdout
213 VG_(clo_log_fd) = 1;
214 vg_assert( !VG_(logging_to_socket) );
215
fitzhardinge98abfc72003-12-16 02:05:15 +0000216 VG_(printf)(usage1);
217 if (VG_(details).name) {
218 VG_(printf)(" user options for %s:\n", VG_(details).name);
fitzhardinge98abfc72003-12-16 02:05:15 +0000219 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000220 VG_TDICT_CALL(tool_print_usage);
fitzhardinge98abfc72003-12-16 02:05:15 +0000221 else
222 VG_(printf)(" (none)\n");
223 }
nethercote6c999f22004-01-31 22:55:15 +0000224 if (debug_help) {
225 VG_(printf)(usage2);
fitzhardinge98abfc72003-12-16 02:05:15 +0000226
nethercote6c999f22004-01-31 22:55:15 +0000227 if (VG_(details).name) {
228 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
229
230 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000231 VG_TDICT_CALL(tool_print_debug_usage);
nethercote6c999f22004-01-31 22:55:15 +0000232 else
233 VG_(printf)(" (none)\n");
234 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000235 }
nethercote421281e2003-11-20 16:20:55 +0000236 VG_(printf)(usage3, VG_BUGS_TO);
nethercotef4928da2004-06-15 10:54:40 +0000237 VG_(exit)(0);
njn7cf0bd32002-06-08 13:36:03 +0000238}
sewardjde4a1d02002-03-22 01:27:54 +0000239
sewardjde4a1d02002-03-22 01:27:54 +0000240
sewardj45f4e7c2005-09-27 19:20:21 +0000241/* Peer at previously set up VG_(args_for_valgrind) and extract any
242 request for help and also the tool name. */
243
244static void get_helprequest_and_toolname ( Int* need_help, HChar** tool )
245{
246 UInt i;
247 HChar* str;
sewardj8b635a42004-11-22 19:01:47 +0000248
sewardj14c7cc52007-02-25 15:08:24 +0000249 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000250
sewardj14c7cc52007-02-25 15:08:24 +0000251 /* parse the options we have (only the options we care about now) */
252 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
253
254 str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000255 vg_assert(str);
nethercote71980f02004-01-24 18:18:54 +0000256
sewardj45f4e7c2005-09-27 19:20:21 +0000257 if (VG_STREQ(str, "--version")) {
njn2e9f3f32005-10-26 16:17:46 +0000258 // Ensure the version string goes to stdout
259 VG_(clo_log_fd) = 1;
sewardj45f4e7c2005-09-27 19:20:21 +0000260 VG_(printf)("valgrind-" VERSION "\n");
261 VG_(exit)(0);
262
263 } else if (VG_CLO_STREQ(str, "--help") ||
264 VG_CLO_STREQ(str, "-h")) {
nethercote6c999f22004-01-31 22:55:15 +0000265 *need_help = 1;
266
sewardj45f4e7c2005-09-27 19:20:21 +0000267 } else if (VG_CLO_STREQ(str, "--help-debug")) {
nethercote6c999f22004-01-31 22:55:15 +0000268 *need_help = 2;
nethercote71980f02004-01-24 18:18:54 +0000269
sewardj45f4e7c2005-09-27 19:20:21 +0000270 // The tool has already been determined, but we need to know the name
271 // here.
272 } else if (VG_CLO_STREQN(7, str, "--tool=")) {
273 *tool = &str[7];
nethercote71980f02004-01-24 18:18:54 +0000274 }
275 }
nethercote71980f02004-01-24 18:18:54 +0000276}
277
sewardj45f4e7c2005-09-27 19:20:21 +0000278static Bool process_cmd_line_options( UInt* client_auxv, const char* toolname )
nethercote71980f02004-01-24 18:18:54 +0000279{
njnda033f52005-12-19 21:27:58 +0000280 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
281 // and we cannot change it until we know what we are changing it to is
282 // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
sewardj92645592005-07-23 09:18:34 +0000283 SysRes sres;
njnda033f52005-12-19 21:27:58 +0000284 Int i, tmp_log_fd;
sewardj92645592005-07-23 09:18:34 +0000285 Int toolname_len = VG_(strlen)(toolname);
njnbe9b47b2005-05-15 16:22:58 +0000286 enum {
287 VgLogTo_Fd,
288 VgLogTo_File,
289 VgLogTo_FileExactly,
290 VgLogTo_Socket
291 } log_to = VgLogTo_Fd; // Where is logging output to be sent?
sewardjde4a1d02002-03-22 01:27:54 +0000292
nethercotee1730692003-11-20 10:38:07 +0000293 /* log to stderr by default, but usage message goes to stdout */
njnda033f52005-12-19 21:27:58 +0000294 tmp_log_fd = 2;
sewardjde4a1d02002-03-22 01:27:54 +0000295
sewardj19d81412002-06-03 01:10:40 +0000296 /* Check for sane path in ./configure --prefix=... */
fitzhardinge98abfc72003-12-16 02:05:15 +0000297 if (VG_LIBDIR[0] != '/')
sewardj17c11042006-10-15 01:26:40 +0000298 VG_(err_config_error)("Please use absolute paths in "
299 "./configure --prefix=... or --libdir=...");
sewardj38170912002-05-10 21:07:22 +0000300
sewardj14c7cc52007-02-25 15:08:24 +0000301 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000302
sewardj14c7cc52007-02-25 15:08:24 +0000303 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
304
305 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000306 HChar* colon = arg;
nethercote71980f02004-01-24 18:18:54 +0000307
njn1274d242007-03-26 23:38:42 +0000308 // Look for a colon in the option name.
thughes3bfd5a02004-07-18 08:05:44 +0000309 while (*colon && *colon != ':' && *colon != '=')
310 colon++;
nethercote71980f02004-01-24 18:18:54 +0000311
njn1274d242007-03-26 23:38:42 +0000312 // Does it have the form "--toolname:foo"? We have to do it at the start
313 // in case someone has combined a prefix with a core-specific option,
314 // eg. "--memcheck:verbose".
thughes3bfd5a02004-07-18 08:05:44 +0000315 if (*colon == ':') {
nethercote71980f02004-01-24 18:18:54 +0000316 if (VG_CLO_STREQN(2, arg, "--") &&
317 VG_CLO_STREQN(toolname_len, arg+2, toolname) &&
318 VG_CLO_STREQN(1, arg+2+toolname_len, ":"))
319 {
njn1274d242007-03-26 23:38:42 +0000320 // Prefix matches, convert "--toolname:foo" to "--foo".
321 // Two things to note:
322 // - We cannot modify the option in-place. If we did, and then
323 // a child was spawned with --trace-children=yes, the
324 // now-non-prefixed option would be passed and could screw up
325 // the child.
326 // - We create copies, and never free them. Why? Non-prefixed
327 // options hang around forever, so tools need not make copies
328 // of strings within them. We need to have the same behaviour
329 // for prefixed options. The pointer to the copy will be lost
330 // once we leave this function (although a tool may keep a
331 // pointer into it), but the space wasted is insignificant.
332 // (In bug #142197, the copies were being freed, which caused
333 // problems for tools that reasonably assumed that arguments
334 // wouldn't disappear on them.)
nethercote71980f02004-01-24 18:18:54 +0000335 if (0)
336 VG_(printf)("tool-specific arg: %s\n", arg);
sewardj45f4e7c2005-09-27 19:20:21 +0000337 arg = VG_(strdup)(arg + toolname_len + 1);
nethercote71980f02004-01-24 18:18:54 +0000338 arg[0] = '-';
339 arg[1] = '-';
340
341 } else {
342 // prefix doesn't match, skip to next arg
343 continue;
344 }
345 }
346
fitzhardinge98abfc72003-12-16 02:05:15 +0000347 /* Ignore these options - they've already been handled */
njn1274d242007-03-26 23:38:42 +0000348 if (VG_CLO_STREQN( 7, arg, "--tool=")) { }
349 else if (VG_CLO_STREQN(20, arg, "--command-line-only=")) { }
350 else if (VG_CLO_STREQ(arg, "--")) { }
351 else if (VG_CLO_STREQ(arg, "-d")) { }
nethercote27fec902004-06-16 21:26:32 +0000352
nethercote71980f02004-01-24 18:18:54 +0000353 else if (VG_CLO_STREQ(arg, "-v") ||
354 VG_CLO_STREQ(arg, "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000355 VG_(clo_verbosity)++;
nethercote27fec902004-06-16 21:26:32 +0000356
nethercote71980f02004-01-24 18:18:54 +0000357 else if (VG_CLO_STREQ(arg, "-q") ||
358 VG_CLO_STREQ(arg, "--quiet"))
sewardjde4a1d02002-03-22 01:27:54 +0000359 VG_(clo_verbosity)--;
360
sewardj71bc3cb2005-05-19 00:25:45 +0000361 else VG_BOOL_CLO(arg, "--xml", VG_(clo_xml))
njn45270a22005-03-27 01:00:11 +0000362 else VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach))
363 else VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle))
364 else VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit))
sewardjb9779082006-05-12 23:50:15 +0000365 else VG_NUM_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode))
njn45270a22005-03-27 01:00:11 +0000366 else VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns))
sewardj91b470c2007-08-28 17:03:01 +0000367 else VG_NUMW_CLO(arg, "--max-stackframe", VG_(clo_max_stackframe))
njn45270a22005-03-27 01:00:11 +0000368 else VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres))
369 else VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main))
370 else VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp))
371 else VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds))
372 else VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children))
373 else VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched))
374 else VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals))
375 else VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab))
sewardjf767d962007-02-12 17:47:14 +0000376 else VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt))
sewardjce058b02005-05-01 08:55:38 +0000377 else VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi))
sewardjf767d962007-02-12 17:47:14 +0000378 else VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms))
379 else VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line))
380 else VG_XACT_CLO(arg, "--debug-dump=frames", VG_(clo_debug_dump_frames))
njn45270a22005-03-27 01:00:11 +0000381 else VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir))
sewardjf767d962007-02-12 17:47:14 +0000382
njn45270a22005-03-27 01:00:11 +0000383 else VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls))
384 else VG_BOOL_CLO(arg, "--trace-pthreads", VG_(clo_trace_pthreads))
385 else VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb))
njn45270a22005-03-27 01:00:11 +0000386 else VG_STR_CLO (arg, "--db-command", VG_(clo_db_command))
njn628add62005-11-12 18:21:40 +0000387 else VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints))
sewardj12ab7652006-10-17 02:10:42 +0000388 else VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets))
sewardjde4a1d02002-03-22 01:27:54 +0000389
njn45270a22005-03-27 01:00:11 +0000390 else VG_NUM_CLO (arg, "--dump-error", VG_(clo_dump_error))
391 else VG_NUM_CLO (arg, "--input-fd", VG_(clo_input_fd))
392 else VG_NUM_CLO (arg, "--sanity-level", VG_(clo_sanity_level))
393 else VG_BNUM_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
394 VG_DEEPEST_BACKTRACE)
sewardjde4a1d02002-03-22 01:27:54 +0000395
sewardj6c3a2192005-07-24 07:00:45 +0000396 else if (VG_CLO_STREQ(arg, "--smc-check=none"))
397 VG_(clo_smc_check) = Vg_SmcNone;
398 else if (VG_CLO_STREQ(arg, "--smc-check=stack"))
399 VG_(clo_smc_check) = Vg_SmcStack;
400 else if (VG_CLO_STREQ(arg, "--smc-check=all"))
401 VG_(clo_smc_check) = Vg_SmcAll;
sewardj26412bd2005-07-07 10:05:05 +0000402
sewardjce5a5662005-10-06 03:19:49 +0000403 else VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant))
404
njn45270a22005-03-27 01:00:11 +0000405 else VG_BNUM_CLO(arg, "--vex-iropt-verbosity",
sewardj8b635a42004-11-22 19:01:47 +0000406 VG_(clo_vex_control).iropt_verbosity, 0, 10)
njn45270a22005-03-27 01:00:11 +0000407 else VG_BNUM_CLO(arg, "--vex-iropt-level",
sewardj8b635a42004-11-22 19:01:47 +0000408 VG_(clo_vex_control).iropt_level, 0, 2)
njn45270a22005-03-27 01:00:11 +0000409 else VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
sewardj8b635a42004-11-22 19:01:47 +0000410 VG_(clo_vex_control).iropt_precise_memory_exns)
njn45270a22005-03-27 01:00:11 +0000411 else VG_BNUM_CLO(arg, "--vex-iropt-unroll-thresh",
sewardj8b635a42004-11-22 19:01:47 +0000412 VG_(clo_vex_control).iropt_unroll_thresh, 0, 400)
njn45270a22005-03-27 01:00:11 +0000413 else VG_BNUM_CLO(arg, "--vex-guest-max-insns",
sewardj8b635a42004-11-22 19:01:47 +0000414 VG_(clo_vex_control).guest_max_insns, 1, 100)
njn45270a22005-03-27 01:00:11 +0000415 else VG_BNUM_CLO(arg, "--vex-guest-chase-thresh",
sewardj8b635a42004-11-22 19:01:47 +0000416 VG_(clo_vex_control).guest_chase_thresh, 0, 99)
417
nethercotef8548672004-06-21 12:42:35 +0000418 else if (VG_CLO_STREQN(9, arg, "--log-fd=")) {
njnbe9b47b2005-05-15 16:22:58 +0000419 log_to = VgLogTo_Fd;
nethercotef8548672004-06-21 12:42:35 +0000420 VG_(clo_log_name) = NULL;
njnda033f52005-12-19 21:27:58 +0000421 tmp_log_fd = (Int)VG_(atoll)(&arg[9]);
sewardj4cf05692002-10-27 20:28:29 +0000422 }
423
nethercotef8548672004-06-21 12:42:35 +0000424 else if (VG_CLO_STREQN(11, arg, "--log-file=")) {
njnbe9b47b2005-05-15 16:22:58 +0000425 log_to = VgLogTo_File;
nethercotef8548672004-06-21 12:42:35 +0000426 VG_(clo_log_name) = &arg[11];
sewardj4cf05692002-10-27 20:28:29 +0000427 }
njnd6bc3c32005-03-27 00:44:31 +0000428
sewardjad311162005-07-19 11:25:02 +0000429 else if (VG_CLO_STREQN(21, arg, "--log-file-qualifier=")) {
430 VG_(clo_log_file_qualifier) = &arg[21];
431 }
432
sewardj603d4102005-01-11 14:01:02 +0000433 else if (VG_CLO_STREQN(19, arg, "--log-file-exactly=")) {
njnbe9b47b2005-05-15 16:22:58 +0000434 log_to = VgLogTo_FileExactly;
sewardj603d4102005-01-11 14:01:02 +0000435 VG_(clo_log_name) = &arg[19];
436 }
sewardjde4a1d02002-03-22 01:27:54 +0000437
nethercotef8548672004-06-21 12:42:35 +0000438 else if (VG_CLO_STREQN(13, arg, "--log-socket=")) {
njnbe9b47b2005-05-15 16:22:58 +0000439 log_to = VgLogTo_Socket;
nethercotef8548672004-06-21 12:42:35 +0000440 VG_(clo_log_name) = &arg[13];
sewardj73cf3bc2002-11-03 03:20:15 +0000441 }
442
sewardj768db0e2005-07-19 14:18:56 +0000443 else if (VG_CLO_STREQN(19, arg, "--xml-user-comment=")) {
444 VG_(clo_xml_user_comment) = &arg[19];
445 }
446
nethercote71980f02004-01-24 18:18:54 +0000447 else if (VG_CLO_STREQN(15, arg, "--suppressions=")) {
sewardjde4a1d02002-03-22 01:27:54 +0000448 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njn25e49d8e72002-09-23 09:36:25 +0000449 VG_(message)(Vg_UserMsg, "Too many suppression files specified.");
sewardjde4a1d02002-03-22 01:27:54 +0000450 VG_(message)(Vg_UserMsg,
451 "Increase VG_CLO_MAX_SFILES and recompile.");
sewardj17c11042006-10-15 01:26:40 +0000452 VG_(err_bad_option)(arg);
sewardjde4a1d02002-03-22 01:27:54 +0000453 }
nethercote71980f02004-01-24 18:18:54 +0000454 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &arg[15];
sewardjde4a1d02002-03-22 01:27:54 +0000455 VG_(clo_n_suppressions)++;
456 }
sewardjde4a1d02002-03-22 01:27:54 +0000457
sewardjfa8ec112005-01-19 11:55:34 +0000458 /* "stuvwxyz" --> stuvwxyz (binary) */
459 else if (VG_CLO_STREQN(14, arg, "--trace-flags=")) {
460 Int j;
461 char* opt = & arg[14];
462
463 if (8 != VG_(strlen)(opt)) {
464 VG_(message)(Vg_UserMsg,
465 "--trace-flags argument must have 8 digits");
sewardj17c11042006-10-15 01:26:40 +0000466 VG_(err_bad_option)(arg);
sewardjfa8ec112005-01-19 11:55:34 +0000467 }
468 for (j = 0; j < 8; j++) {
469 if ('0' == opt[j]) { /* do nothing */ }
470 else if ('1' == opt[j]) VG_(clo_trace_flags) |= (1 << (7-j));
471 else {
472 VG_(message)(Vg_UserMsg, "--trace-flags argument can only "
473 "contain 0s and 1s");
sewardj17c11042006-10-15 01:26:40 +0000474 VG_(err_bad_option)(arg);
sewardjfa8ec112005-01-19 11:55:34 +0000475 }
476 }
477 }
478
479 /* "stuvwxyz" --> stuvwxyz (binary) */
480 else if (VG_CLO_STREQN(16, arg, "--profile-flags=")) {
njn25e49d8e72002-09-23 09:36:25 +0000481 Int j;
nethercote71980f02004-01-24 18:18:54 +0000482 char* opt = & arg[16];
njn25e49d8e72002-09-23 09:36:25 +0000483
sewardj2a99cf62004-11-24 10:44:19 +0000484 if (8 != VG_(strlen)(opt)) {
njn25e49d8e72002-09-23 09:36:25 +0000485 VG_(message)(Vg_UserMsg,
sewardjfa8ec112005-01-19 11:55:34 +0000486 "--profile-flags argument must have 8 digits");
sewardj17c11042006-10-15 01:26:40 +0000487 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000488 }
sewardj8b635a42004-11-22 19:01:47 +0000489 for (j = 0; j < 8; j++) {
njn25e49d8e72002-09-23 09:36:25 +0000490 if ('0' == opt[j]) { /* do nothing */ }
sewardjfa8ec112005-01-19 11:55:34 +0000491 else if ('1' == opt[j]) VG_(clo_profile_flags) |= (1 << (7-j));
njn25e49d8e72002-09-23 09:36:25 +0000492 else {
sewardjfa8ec112005-01-19 11:55:34 +0000493 VG_(message)(Vg_UserMsg, "--profile-flags argument can only "
njn25e49d8e72002-09-23 09:36:25 +0000494 "contain 0s and 1s");
sewardj17c11042006-10-15 01:26:40 +0000495 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000496 }
497 }
498 }
sewardjde4a1d02002-03-22 01:27:54 +0000499
njn45270a22005-03-27 01:00:11 +0000500 else VG_NUM_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow))
sewardjc771b292004-11-30 18:55:21 +0000501
sewardjd153fae2005-01-10 17:24:47 +0000502 else if (VG_CLO_STREQ(arg, "--gen-suppressions=no"))
503 VG_(clo_gen_suppressions) = 0;
504 else if (VG_CLO_STREQ(arg, "--gen-suppressions=yes"))
505 VG_(clo_gen_suppressions) = 1;
506 else if (VG_CLO_STREQ(arg, "--gen-suppressions=all"))
507 VG_(clo_gen_suppressions) = 2;
508
nethercote71980f02004-01-24 18:18:54 +0000509 else if ( ! VG_(needs).command_line_options
njn51d827b2005-05-09 01:02:08 +0000510 || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
sewardj17c11042006-10-15 01:26:40 +0000511 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000512 }
sewardjde4a1d02002-03-22 01:27:54 +0000513 }
514
sewardj998d40d2004-12-06 14:24:52 +0000515 /* Make VEX control parameters sane */
516
517 if (VG_(clo_vex_control).guest_chase_thresh
518 >= VG_(clo_vex_control).guest_max_insns)
519 VG_(clo_vex_control).guest_chase_thresh
520 = VG_(clo_vex_control).guest_max_insns - 1;
521
522 if (VG_(clo_vex_control).guest_chase_thresh < 0)
523 VG_(clo_vex_control).guest_chase_thresh = 0;
524
525 /* Check various option values */
nethercote27fec902004-06-16 21:26:32 +0000526
njnf9ebf672003-05-12 21:41:30 +0000527 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +0000528 VG_(clo_verbosity) = 0;
529
nethercote04d0fbc2004-01-26 16:48:06 +0000530 if (VG_(clo_db_attach) && VG_(clo_trace_children)) {
sewardjde4a1d02002-03-22 01:27:54 +0000531 VG_(message)(Vg_UserMsg, "");
532 VG_(message)(Vg_UserMsg,
nethercote04d0fbc2004-01-26 16:48:06 +0000533 "--db-attach=yes conflicts with --trace-children=yes");
sewardjde4a1d02002-03-22 01:27:54 +0000534 VG_(message)(Vg_UserMsg,
535 "Please choose one or the other, but not both.");
sewardj17c11042006-10-15 01:26:40 +0000536 VG_(err_bad_option)("--db-attach=yes and --trace-children=yes");
sewardjde4a1d02002-03-22 01:27:54 +0000537 }
538
njnbe9b47b2005-05-15 16:22:58 +0000539 if (VG_(clo_gen_suppressions) > 0 &&
540 !VG_(needs).core_errors && !VG_(needs).tool_errors) {
541 VG_(message)(Vg_UserMsg,
542 "Can't use --gen-suppressions= with this tool,");
543 VG_(message)(Vg_UserMsg,
544 "as it doesn't generate errors.");
sewardj17c11042006-10-15 01:26:40 +0000545 VG_(err_bad_option)("--gen-suppressions=");
njnbe9b47b2005-05-15 16:22:58 +0000546 }
547
sewardj71bc3cb2005-05-19 00:25:45 +0000548 /* If we've been asked to emit XML, mash around various other
549 options so as to constrain the output somewhat, and to remove
550 any need for user input during the run. */
551 if (VG_(clo_xml)) {
552 /* Disable suppression generation (requires user input) */
553 VG_(clo_gen_suppressions) = 0;
554 /* Disable attaching to GDB (requires user input) */
555 VG_(clo_db_attach) = False;
556 /* Set a known verbosity level */
557 VG_(clo_verbosity) = 1;
558 /* Disable error limits (this might be a bad idea!) */
559 VG_(clo_error_limit) = False;
560 /* Disable emulation warnings */
561 VG_(clo_show_emwarns) = False;
562 /* Disable waiting for GDB to debug Valgrind */
563 VG_(clo_wait_for_gdb) = False;
564 /* No file-descriptor leak checking yet */
565 VG_(clo_track_fds) = False;
sewardj21f7f0c2005-07-06 19:46:48 +0000566 /* Disable timestamped output */
567 VG_(clo_time_stamp) = False;
sewardj71bc3cb2005-05-19 00:25:45 +0000568 /* Also, we want to set options for the leak checker, but that
569 will have to be done in Memcheck's flag-handling code, not
570 here. */
571 }
572
njnbe9b47b2005-05-15 16:22:58 +0000573 /* All non-logging-related options have been checked. If the logging
574 option specified is ok, we can switch to it, as we know we won't
575 have to generate any other command-line-related error messages.
576 (So far we should be still attached to stderr, so we can show on
577 the terminal any problems to do with processing command line
578 opts.)
579
580 So set up logging now. After this is done, VG_(clo_log_fd)
sewardj4cf05692002-10-27 20:28:29 +0000581 should be connected to whatever sink has been selected, and we
582 indiscriminately chuck stuff into it without worrying what the
583 nature of it is. Oh the wonder of Unix streams. */
584
njnbe9b47b2005-05-15 16:22:58 +0000585 vg_assert(VG_(clo_log_fd) == 2 /* stderr */);
586 vg_assert(VG_(logging_to_socket) == False);
sewardj4cf05692002-10-27 20:28:29 +0000587
njnbe9b47b2005-05-15 16:22:58 +0000588 switch (log_to) {
sewardj73cf3bc2002-11-03 03:20:15 +0000589
sewardj4cf05692002-10-27 20:28:29 +0000590 case VgLogTo_Fd:
nethercotef8548672004-06-21 12:42:35 +0000591 vg_assert(VG_(clo_log_name) == NULL);
sewardj4cf05692002-10-27 20:28:29 +0000592 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000593
sewardj4cf05692002-10-27 20:28:29 +0000594 case VgLogTo_File: {
sewardjad311162005-07-19 11:25:02 +0000595 HChar logfilename[1000];
596 Int seq = 0;
597 Int pid = VG_(getpid)();
598 HChar* qual = NULL;
jsgff3c3f1a2003-10-14 22:13:28 +0000599
nethercotef8548672004-06-21 12:42:35 +0000600 vg_assert(VG_(clo_log_name) != NULL);
601 vg_assert(VG_(strlen)(VG_(clo_log_name)) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +0000602
sewardjad311162005-07-19 11:25:02 +0000603 if (VG_(clo_log_file_qualifier)) {
604 qual = VG_(getenv)(VG_(clo_log_file_qualifier));
605 }
606
nethercote71980f02004-01-24 18:18:54 +0000607 for (;;) {
sewardj92645592005-07-23 09:18:34 +0000608 HChar pidtxt[20], seqtxt[20];
609
610 VG_(sprintf)(pidtxt, "%d", pid);
611
612 if (seq == 0)
613 seqtxt[0] = 0;
614 else
615 VG_(sprintf)(seqtxt, ".%d", seq);
616
jsgff3c3f1a2003-10-14 22:13:28 +0000617 seq++;
618
sewardj92645592005-07-23 09:18:34 +0000619 /* Result:
620 if (qual) base_name ++ "." ++ qual ++ seqtxt
621 if (not qual) base_name ++ "." ++ pid ++ seqtxt
622 */
623 VG_(sprintf)( logfilename,
624 "%s.%s%s",
625 VG_(clo_log_name),
626 qual ? qual : pidtxt,
627 seqtxt );
628
njnbe9b47b2005-05-15 16:22:58 +0000629 // EXCL: it will fail with EEXIST if the file already exists.
njnda033f52005-12-19 21:27:58 +0000630 sres = VG_(open)(logfilename,
631 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_EXCL|VKI_O_TRUNC,
632 VKI_S_IRUSR|VKI_S_IWUSR);
sewardj92645592005-07-23 09:18:34 +0000633 if (!sres.isError) {
sewardj12ab7652006-10-17 02:10:42 +0000634 tmp_log_fd = sres.res;
sewardj603d4102005-01-11 14:01:02 +0000635 break; /* for (;;) */
jsgff3c3f1a2003-10-14 22:13:28 +0000636 } else {
njnbe9b47b2005-05-15 16:22:58 +0000637 // If the file already existed, we try the next name. If it
638 // was some other file error, we give up.
sewardj12ab7652006-10-17 02:10:42 +0000639 if (sres.err != VKI_EEXIST) {
jsgff3c3f1a2003-10-14 22:13:28 +0000640 VG_(message)(Vg_UserMsg,
sewardjc40fce52006-05-03 13:52:17 +0000641 "Can't create log file '%s' (%s); giving up!",
sewardj12ab7652006-10-17 02:10:42 +0000642 logfilename, VG_(strerror)(sres.err));
sewardj17c11042006-10-15 01:26:40 +0000643 VG_(err_bad_option)(
sewardj603d4102005-01-11 14:01:02 +0000644 "--log-file=<file> (didn't work out for some reason.)");
njnbe9b47b2005-05-15 16:22:58 +0000645 /*NOTREACHED*/
jsgff3c3f1a2003-10-14 22:13:28 +0000646 }
647 }
648 }
sewardj603d4102005-01-11 14:01:02 +0000649 break; /* switch (VG_(clo_log_to)) */
650 }
651
652 case VgLogTo_FileExactly: {
sewardj603d4102005-01-11 14:01:02 +0000653 vg_assert(VG_(clo_log_name) != NULL);
654 vg_assert(VG_(strlen)(VG_(clo_log_name)) <= 900); /* paranoia */
sewardj603d4102005-01-11 14:01:02 +0000655
njnda033f52005-12-19 21:27:58 +0000656 sres = VG_(open)(VG_(clo_log_name),
657 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
658 VKI_S_IRUSR|VKI_S_IWUSR);
sewardj92645592005-07-23 09:18:34 +0000659 if (!sres.isError) {
sewardj12ab7652006-10-17 02:10:42 +0000660 tmp_log_fd = sres.res;
njnbe9b47b2005-05-15 16:22:58 +0000661 } else {
sewardj603d4102005-01-11 14:01:02 +0000662 VG_(message)(Vg_UserMsg,
njn02bc4b82005-05-15 17:28:26 +0000663 "Can't create/open log file '%s'; giving up!",
sewardj603d4102005-01-11 14:01:02 +0000664 VG_(clo_log_name));
sewardj17c11042006-10-15 01:26:40 +0000665 VG_(err_bad_option)(
sewardj603d4102005-01-11 14:01:02 +0000666 "--log-file-exactly=<file> (didn't work out for some reason.)");
667 /*NOTREACHED*/
668 }
669 break; /* switch (VG_(clo_log_to)) */
sewardj73cf3bc2002-11-03 03:20:15 +0000670 }
671
672 case VgLogTo_Socket: {
nethercotef8548672004-06-21 12:42:35 +0000673 vg_assert(VG_(clo_log_name) != NULL);
674 vg_assert(VG_(strlen)(VG_(clo_log_name)) <= 900); /* paranoia */
njnda033f52005-12-19 21:27:58 +0000675 tmp_log_fd = VG_(connect_via_socket)( VG_(clo_log_name) );
676 if (tmp_log_fd == -1) {
sewardj73cf3bc2002-11-03 03:20:15 +0000677 VG_(message)(Vg_UserMsg,
nethercotef8548672004-06-21 12:42:35 +0000678 "Invalid --log-socket=ipaddr or --log-socket=ipaddr:port spec");
sewardj73cf3bc2002-11-03 03:20:15 +0000679 VG_(message)(Vg_UserMsg,
njn02bc4b82005-05-15 17:28:26 +0000680 "of '%s'; giving up!", VG_(clo_log_name) );
sewardj17c11042006-10-15 01:26:40 +0000681 VG_(err_bad_option)(
nethercotef8548672004-06-21 12:42:35 +0000682 "--log-socket=");
njnbe9b47b2005-05-15 16:22:58 +0000683 /*NOTREACHED*/
sewardj4cf05692002-10-27 20:28:29 +0000684 }
njnda033f52005-12-19 21:27:58 +0000685 if (tmp_log_fd == -2) {
sewardj73cf3bc2002-11-03 03:20:15 +0000686 VG_(message)(Vg_UserMsg,
njn02bc4b82005-05-15 17:28:26 +0000687 "valgrind: failed to connect to logging server '%s'.",
nethercotef8548672004-06-21 12:42:35 +0000688 VG_(clo_log_name) );
sewardj570f8902002-11-03 11:44:36 +0000689 VG_(message)(Vg_UserMsg,
690 "Log messages will sent to stderr instead." );
691 VG_(message)(Vg_UserMsg,
692 "" );
693 /* We don't change anything here. */
njnbe9b47b2005-05-15 16:22:58 +0000694 vg_assert(VG_(clo_log_fd) == 2);
njnda033f52005-12-19 21:27:58 +0000695 tmp_log_fd = 2;
sewardj570f8902002-11-03 11:44:36 +0000696 } else {
njnda033f52005-12-19 21:27:58 +0000697 vg_assert(tmp_log_fd > 0);
njnbe9b47b2005-05-15 16:22:58 +0000698 VG_(logging_to_socket) = True;
sewardj570f8902002-11-03 11:44:36 +0000699 }
sewardj73cf3bc2002-11-03 03:20:15 +0000700 break;
701 }
sewardj4cf05692002-10-27 20:28:29 +0000702 }
703
sewardj71bc3cb2005-05-19 00:25:45 +0000704
705 /* Check that the requested tool actually supports XML output. */
njnca54af32006-04-16 10:25:43 +0000706 if (VG_(clo_xml) && !VG_(needs).xml_output) {
sewardj71bc3cb2005-05-19 00:25:45 +0000707 VG_(clo_xml) = False;
708 VG_(message)(Vg_UserMsg,
njnca54af32006-04-16 10:25:43 +0000709 "%s does not support XML output.", VG_(details).name);
sewardj17c11042006-10-15 01:26:40 +0000710 VG_(err_bad_option)("--xml=yes");
sewardj71bc3cb2005-05-19 00:25:45 +0000711 /*NOTREACHED*/
712 }
713
njnda033f52005-12-19 21:27:58 +0000714 if (tmp_log_fd >= 0) {
715 // Move log_fd into the safe range, so it doesn't conflict with any app fds.
716 tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
717 if (tmp_log_fd < 0) {
718 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd into safe range, using stderr");
719 VG_(clo_log_fd) = 2; // stderr
720 } else {
721 VG_(clo_log_fd) = tmp_log_fd;
722 VG_(fcntl)(VG_(clo_log_fd), VKI_F_SETFD, VKI_FD_CLOEXEC);
723 }
724 } else {
725 // If they said --log-fd=-1, don't print anything. Plausible for use in
726 // regression testing suites that use client requests to count errors.
727 VG_(clo_log_fd) = tmp_log_fd;
jsgf855d93d2003-10-13 22:26:55 +0000728 }
729
sewardj45f4e7c2005-09-27 19:20:21 +0000730 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
731 (VG_(needs).core_errors || VG_(needs).tool_errors)) {
732 /* If we haven't reached the max number of suppressions, load
733 the default one. */
734 static const Char default_supp[] = "default.supp";
735 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
736 Char *buf = VG_(arena_malloc)(VG_AR_CORE, len);
737 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
738 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
739 VG_(clo_n_suppressions)++;
740 }
sewardjde4a1d02002-03-22 01:27:54 +0000741
sewardj45f4e7c2005-09-27 19:20:21 +0000742 return (log_to == VgLogTo_Fd);
743}
744
745
746/*====================================================================*/
747/*=== Printing the preamble ===*/
748/*====================================================================*/
749
750/* Ok, the logging sink is running now. Print a suitable preamble.
751 If logging to file or a socket, write details of parent PID and
752 command line args, to help people trying to interpret the
753 results of a run which encompasses multiple processes. */
754static void print_preamble(Bool logging_to_fd, const char* toolname)
755{
tom60a4b0b2005-10-12 10:45:27 +0000756 HChar* xpre = VG_(clo_xml) ? " <line>" : "";
757 HChar* xpost = VG_(clo_xml) ? "</line>" : "";
758 Int i;
759
sewardj14c7cc52007-02-25 15:08:24 +0000760 vg_assert( VG_(args_for_client) );
761 vg_assert( VG_(args_for_valgrind) );
sewardj99a2ceb2007-11-09 12:30:36 +0000762 vg_assert( toolname );
sewardj14c7cc52007-02-25 15:08:24 +0000763
sewardj71bc3cb2005-05-19 00:25:45 +0000764 if (VG_(clo_xml)) {
sewardj8665d8e2005-06-01 17:35:23 +0000765 VG_(message)(Vg_UserMsg, "<?xml version=\"1.0\"?>");
766 VG_(message)(Vg_UserMsg, "");
sewardj71bc3cb2005-05-19 00:25:45 +0000767 VG_(message)(Vg_UserMsg, "<valgrindoutput>");
768 VG_(message)(Vg_UserMsg, "");
cerion20241ba2005-11-15 19:07:53 +0000769 VG_(message)(Vg_UserMsg, "<protocolversion>2</protocolversion>");
sewardj71bc3cb2005-05-19 00:25:45 +0000770 VG_(message)(Vg_UserMsg, "");
771 }
772
sewardj83adf412002-05-01 01:25:45 +0000773 if (VG_(clo_verbosity > 0)) {
sewardjd7bddad2005-06-13 16:48:32 +0000774
775 if (VG_(clo_xml))
776 VG_(message)(Vg_UserMsg, "<preamble>");
777
nethercote996901a2004-08-03 13:29:09 +0000778 /* Tool details */
sewardj71bc3cb2005-05-19 00:25:45 +0000779 VG_(message)(Vg_UserMsg, "%s%s%s%s, %s.%s",
780 xpre,
njnd04b7c62002-10-03 14:05:52 +0000781 VG_(details).name,
njnb9c427c2004-12-01 14:14:42 +0000782 NULL == VG_(details).version ? "" : "-",
njnd04b7c62002-10-03 14:05:52 +0000783 NULL == VG_(details).version
784 ? (Char*)"" : VG_(details).version,
sewardj71bc3cb2005-05-19 00:25:45 +0000785 VG_(details).description,
786 xpost);
sewardj99a2ceb2007-11-09 12:30:36 +0000787
788 if (VG_(strlen)(toolname) >= 4
789 && 0 == VG_(strncmp)(toolname, "exp-", 4)) {
790 VG_(message)(
791 Vg_UserMsg,
792 "%sNOTE: This is an Experimental-Class Valgrind Tool.%s",
793 xpre, xpost
794 );
795 }
796
sewardj71bc3cb2005-05-19 00:25:45 +0000797 VG_(message)(Vg_UserMsg, "%s%s%s",
798 xpre, VG_(details).copyright_author, xpost);
sewardj3b2736a2002-03-24 12:18:35 +0000799
njnd04b7c62002-10-03 14:05:52 +0000800 /* Core details */
801 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000802 "%sUsing LibVEX rev %s, a library for dynamic binary translation.%s",
803 xpre, LibVEX_Version(), xpost );
sewardjc7025332004-12-13 18:30:39 +0000804 VG_(message)(Vg_UserMsg,
sewardj9ebd6e02007-01-08 06:01:59 +0000805 "%sCopyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.%s",
sewardj71bc3cb2005-05-19 00:25:45 +0000806 xpre, xpost );
sewardjc7025332004-12-13 18:30:39 +0000807 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000808 "%sUsing valgrind-%s, a dynamic binary instrumentation framework.%s",
809 xpre, VERSION, xpost);
sewardjde4a1d02002-03-22 01:27:54 +0000810 VG_(message)(Vg_UserMsg,
sewardj9ebd6e02007-01-08 06:01:59 +0000811 "%sCopyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.%s",
sewardj71bc3cb2005-05-19 00:25:45 +0000812 xpre, xpost );
sewardjd7bddad2005-06-13 16:48:32 +0000813
sewardj45f4e7c2005-09-27 19:20:21 +0000814 if (VG_(clo_verbosity) == 1 && !VG_(clo_xml))
815 VG_(message)(Vg_UserMsg, "For more details, rerun with: -v");
816
sewardjd7bddad2005-06-13 16:48:32 +0000817 if (VG_(clo_xml))
818 VG_(message)(Vg_UserMsg, "</preamble>");
njnd04b7c62002-10-03 14:05:52 +0000819 }
820
sewardj45f4e7c2005-09-27 19:20:21 +0000821 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
sewardj4cf05692002-10-27 20:28:29 +0000822 VG_(message)(Vg_UserMsg, "");
823 VG_(message)(Vg_UserMsg,
824 "My PID = %d, parent PID = %d. Prog and args are:",
825 VG_(getpid)(), VG_(getppid)() );
sewardj5e940782005-09-28 19:59:19 +0000826 if (VG_(args_the_exename))
827 VG_(message)(Vg_UserMsg, " %s", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000828 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
829 VG_(message)(Vg_UserMsg,
830 " %s",
831 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
sewardj5b742c32005-07-26 23:43:26 +0000832 if (VG_(clo_log_file_qualifier)) {
833 HChar* val = VG_(getenv)(VG_(clo_log_file_qualifier));
834 VG_(message)(Vg_UserMsg, "");
835 VG_(message)(Vg_UserMsg, "Log file qualifier: var %s, value %s.",
836 VG_(clo_log_file_qualifier),
837 val ? val : "");
838 }
sewardj4cf05692002-10-27 20:28:29 +0000839 }
sewardj71bc3cb2005-05-19 00:25:45 +0000840 else
841 if (VG_(clo_xml)) {
842 VG_(message)(Vg_UserMsg, "");
843 VG_(message)(Vg_UserMsg, "<pid>%d</pid>", VG_(getpid)());
844 VG_(message)(Vg_UserMsg, "<ppid>%d</ppid>", VG_(getppid)());
sewardj97f7e0c2005-07-19 15:00:25 +0000845 VG_(message)(Vg_UserMsg, "<tool>%t</tool>", toolname);
sewardjad311162005-07-19 11:25:02 +0000846 if (VG_(clo_log_file_qualifier)) {
847 HChar* val = VG_(getenv)(VG_(clo_log_file_qualifier));
sewardj97f7e0c2005-07-19 15:00:25 +0000848 VG_(message)(Vg_UserMsg, "<logfilequalifier> <var>%t</var> "
849 "<value>%t</value> </logfilequalifier>",
sewardjad311162005-07-19 11:25:02 +0000850 VG_(clo_log_file_qualifier),
851 val ? val : "");
852 }
sewardj768db0e2005-07-19 14:18:56 +0000853 if (VG_(clo_xml_user_comment)) {
854 /* Note: the user comment itself is XML and is therefore to
855 be passed through verbatim (%s) rather than escaped
856 (%t). */
857 VG_(message)(Vg_UserMsg, "<usercomment>%s</usercomment>",
858 VG_(clo_xml_user_comment));
859 }
sewardj71bc3cb2005-05-19 00:25:45 +0000860 VG_(message)(Vg_UserMsg, "");
sewardjb8a3dac2005-07-19 12:39:11 +0000861 VG_(message)(Vg_UserMsg, "<args>");
sewardj45f4e7c2005-09-27 19:20:21 +0000862
sewardjb8a3dac2005-07-19 12:39:11 +0000863 VG_(message)(Vg_UserMsg, " <vargv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000864 if (VG_(name_of_launcher))
865 VG_(message)(Vg_UserMsg, " <exe>%t</exe>",
866 VG_(name_of_launcher));
sewardj125fd4f2007-03-08 19:56:14 +0000867 else
868 VG_(message)(Vg_UserMsg, " <exe>%t</exe>",
869 "(launcher name unknown)");
sewardj14c7cc52007-02-25 15:08:24 +0000870 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
sewardj45f4e7c2005-09-27 19:20:21 +0000871 VG_(message)(Vg_UserMsg,
872 " <arg>%t</arg>",
sewardj14c7cc52007-02-25 15:08:24 +0000873 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjb8a3dac2005-07-19 12:39:11 +0000874 }
875 VG_(message)(Vg_UserMsg, " </vargv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000876
sewardjb8a3dac2005-07-19 12:39:11 +0000877 VG_(message)(Vg_UserMsg, " <argv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000878 if (VG_(args_the_exename))
879 VG_(message)(Vg_UserMsg, " <exe>%t</exe>",
880 VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000881 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
882 VG_(message)(Vg_UserMsg,
883 " <arg>%t</arg>",
884 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
sewardj8665d8e2005-06-01 17:35:23 +0000885 }
sewardjb8a3dac2005-07-19 12:39:11 +0000886 VG_(message)(Vg_UserMsg, " </argv>");
sewardj45f4e7c2005-09-27 19:20:21 +0000887
sewardjb8a3dac2005-07-19 12:39:11 +0000888 VG_(message)(Vg_UserMsg, "</args>");
sewardj71bc3cb2005-05-19 00:25:45 +0000889 }
sewardj4cf05692002-10-27 20:28:29 +0000890
sewardj45f4e7c2005-09-27 19:20:21 +0000891 // Empty line after the preamble
892 if (VG_(clo_verbosity) > 0)
893 VG_(message)(Vg_UserMsg, "");
894
sewardjde4a1d02002-03-22 01:27:54 +0000895 if (VG_(clo_verbosity) > 1) {
sewardj92645592005-07-23 09:18:34 +0000896 SysRes fd;
sewardj1f0bbc72005-11-16 03:51:02 +0000897 VexArch vex_arch;
898 VexArchInfo vex_archinfo;
sewardj45f4e7c2005-09-27 19:20:21 +0000899 if (!logging_to_fd)
njn1fd5eb22005-03-13 05:43:23 +0000900 VG_(message)(Vg_DebugMsg, "");
njn1fd5eb22005-03-13 05:43:23 +0000901 VG_(message)(Vg_DebugMsg, "Command line");
sewardj45f4e7c2005-09-27 19:20:21 +0000902 if (VG_(args_the_exename))
903 VG_(message)(Vg_DebugMsg, " %s", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +0000904 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
905 VG_(message)(Vg_DebugMsg,
906 " %s",
907 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ));
njn86dc2bc2003-09-09 07:26:21 +0000908
njn1fd5eb22005-03-13 05:43:23 +0000909 VG_(message)(Vg_DebugMsg, "Startup, with flags:");
sewardj14c7cc52007-02-25 15:08:24 +0000910 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
911 VG_(message)(Vg_DebugMsg,
912 " %s",
913 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjde4a1d02002-03-22 01:27:54 +0000914 }
nethercotea70f7352004-04-18 12:08:46 +0000915
njn1fd5eb22005-03-13 05:43:23 +0000916 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:");
nethercotea70f7352004-04-18 12:08:46 +0000917 fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
sewardj92645592005-07-23 09:18:34 +0000918 if (fd.isError) {
njn1fd5eb22005-03-13 05:43:23 +0000919 VG_(message)(Vg_DebugMsg, " can't open /proc/version");
nethercotea70f7352004-04-18 12:08:46 +0000920 } else {
sewardj71bc3cb2005-05-19 00:25:45 +0000921# define BUF_LEN 256
nethercotea70f7352004-04-18 12:08:46 +0000922 Char version_buf[BUF_LEN];
sewardj12ab7652006-10-17 02:10:42 +0000923 Int n = VG_(read) ( fd.res, version_buf, BUF_LEN );
njnbe9b47b2005-05-15 16:22:58 +0000924 vg_assert(n <= BUF_LEN);
nethercotea70f7352004-04-18 12:08:46 +0000925 if (n > 0) {
926 version_buf[n-1] = '\0';
njn1fd5eb22005-03-13 05:43:23 +0000927 VG_(message)(Vg_DebugMsg, " %s", version_buf);
nethercotea70f7352004-04-18 12:08:46 +0000928 } else {
njn1fd5eb22005-03-13 05:43:23 +0000929 VG_(message)(Vg_DebugMsg, " (empty?)");
nethercotea70f7352004-04-18 12:08:46 +0000930 }
sewardj12ab7652006-10-17 02:10:42 +0000931 VG_(close)(fd.res);
sewardj71bc3cb2005-05-19 00:25:45 +0000932# undef BUF_LEN
nethercotea70f7352004-04-18 12:08:46 +0000933 }
sewardj1f0bbc72005-11-16 03:51:02 +0000934
935 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +0000936 VG_(message)(
937 Vg_DebugMsg,
938 "Arch and hwcaps: %s, %s",
939 LibVEX_ppVexArch ( vex_arch ),
940 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
941 );
sewardje66f2e02006-12-30 17:45:08 +0000942 VG_(message)(
943 Vg_DebugMsg,
sewardj07854682006-12-30 17:56:32 +0000944 "Page sizes: currently %d, max supported %d",
sewardje66f2e02006-12-30 17:45:08 +0000945 (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
946 );
sewardj1f0bbc72005-11-16 03:51:02 +0000947 VG_(message)(Vg_DebugMsg, "Valgrind library directory: %s", VG_(libdir));
sewardjde4a1d02002-03-22 01:27:54 +0000948 }
nethercotef6a1d502004-08-09 12:21:57 +0000949}
950
sewardjde4a1d02002-03-22 01:27:54 +0000951
nethercote71980f02004-01-24 18:18:54 +0000952/*====================================================================*/
953/*=== File descriptor setup ===*/
954/*====================================================================*/
955
sewardj5f229e22005-09-28 01:36:01 +0000956/* Number of file descriptors that Valgrind tries to reserve for
957 it's own use - just a small constant. */
958#define N_RESERVED_FDS (10)
959
nethercote71980f02004-01-24 18:18:54 +0000960static void setup_file_descriptors(void)
961{
962 struct vki_rlimit rl;
sewardj17c11042006-10-15 01:26:40 +0000963 Bool show = False;
nethercote71980f02004-01-24 18:18:54 +0000964
965 /* Get the current file descriptor limits. */
966 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
967 rl.rlim_cur = 1024;
968 rl.rlim_max = 1024;
969 }
970
sewardj17c11042006-10-15 01:26:40 +0000971 if (show)
njn8a7b41b2007-09-23 00:51:24 +0000972 VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
sewardj17c11042006-10-15 01:26:40 +0000973 rl.rlim_cur, rl.rlim_max);
974
975# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
976 /* I don't know why this kludge is needed; however if rl.rlim_cur
977 is RLIM_INFINITY, then VG_(safe_fd)'s attempts using VG_(fcntl)
978 to lift V's file descriptors above the threshold RLIM_INFINITY -
979 N_RESERVED_FDS fail. So just use a relatively conservative
980 value in this case. */
981 if (rl.rlim_cur > 1024)
982 rl.rlim_cur = 1024;
983# endif
984
nethercote71980f02004-01-24 18:18:54 +0000985 /* Work out where to move the soft limit to. */
njn14319cc2005-03-13 06:26:22 +0000986 if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
987 rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +0000988 } else {
989 rl.rlim_cur = rl.rlim_max;
990 }
991
992 /* Reserve some file descriptors for our use. */
njn14319cc2005-03-13 06:26:22 +0000993 VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
994 VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +0000995
996 /* Update the soft limit. */
997 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
998
sewardj17c11042006-10-15 01:26:40 +0000999 if (show) {
njn8a7b41b2007-09-23 00:51:24 +00001000 VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
sewardj17c11042006-10-15 01:26:40 +00001001 rl.rlim_cur, rl.rlim_max);
1002 VG_(printf)("fd limits: guest : cur %u max %u\n",
1003 VG_(fd_soft_limit), VG_(fd_hard_limit));
1004 }
1005
sewardj45f4e7c2005-09-27 19:20:21 +00001006 if (VG_(cl_exec_fd) != -1)
1007 VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
nethercote71980f02004-01-24 18:18:54 +00001008}
1009
sewardjde4a1d02002-03-22 01:27:54 +00001010
njn2da73352005-06-18 01:35:16 +00001011/*====================================================================*/
njn2025cf92005-06-26 20:44:48 +00001012/*=== BB profiling ===*/
1013/*====================================================================*/
1014
1015static
1016void show_BB_profile ( BBProfEntry tops[], UInt n_tops, ULong score_total )
1017{
1018 ULong score_cumul, score_here;
1019 Char buf_cumul[10], buf_here[10];
1020 Char name[64];
1021 Int r;
1022
1023 VG_(printf)("\n");
1024 VG_(printf)("-----------------------------------------------------------\n");
1025 VG_(printf)("--- BEGIN BB Profile (summary of scores) ---\n");
1026 VG_(printf)("-----------------------------------------------------------\n");
1027 VG_(printf)("\n");
1028
1029 VG_(printf)("Total score = %lld\n\n", score_total);
1030
1031 score_cumul = 0;
1032 for (r = 0; r < n_tops; r++) {
1033 if (tops[r].addr == 0)
1034 continue;
1035 name[0] = 0;
1036 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1037 name[63] = 0;
1038 score_here = tops[r].score;
1039 score_cumul += score_here;
1040 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1041 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1042 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1043 r,
1044 score_cumul, buf_cumul,
1045 score_here, buf_here, tops[r].addr, name );
1046 }
1047
1048 VG_(printf)("\n");
1049 VG_(printf)("-----------------------------------------------------------\n");
1050 VG_(printf)("--- BB Profile (BB details) ---\n");
1051 VG_(printf)("-----------------------------------------------------------\n");
1052 VG_(printf)("\n");
1053
1054 score_cumul = 0;
1055 for (r = 0; r < n_tops; r++) {
1056 if (tops[r].addr == 0)
1057 continue;
1058 name[0] = 0;
1059 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1060 name[63] = 0;
1061 score_here = tops[r].score;
1062 score_cumul += score_here;
1063 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1064 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1065 VG_(printf)("\n");
1066 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin BB rank %d "
1067 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1068 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1069 r,
1070 score_cumul, buf_cumul,
1071 score_here, buf_here, tops[r].addr, name );
1072 VG_(printf)("\n");
sewardjbcccbc02007-04-09 22:24:57 +00001073 VG_(discard_translations)(tops[r].addr, 1, "bb profile");
sewardj0ec07f32006-01-12 12:32:32 +00001074 VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0, True);
njn2025cf92005-06-26 20:44:48 +00001075 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= end BB rank %d "
1076 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1077 }
1078
1079 VG_(printf)("\n");
1080 VG_(printf)("-----------------------------------------------------------\n");
1081 VG_(printf)("--- END BB Profile ---\n");
1082 VG_(printf)("-----------------------------------------------------------\n");
1083 VG_(printf)("\n");
1084}
1085
1086
1087/*====================================================================*/
nethercote71980f02004-01-24 18:18:54 +00001088/*=== main() ===*/
1089/*====================================================================*/
1090
sewardjfdf91b42005-09-28 00:53:09 +00001091/* When main() is entered, we should be on the following stack, not
1092 the one the kernel gave us. We will run on this stack until
1093 simulation of the root thread is started, at which point a transfer
1094 is made to a dynamically allocated stack. This is for the sake of
1095 uniform overflow detection for all Valgrind threads. This is
1096 marked global even though it isn't, because assembly code below
1097 needs to reference the name. */
1098
1099/*static*/ VgStack VG_(interim_stack);
1100
sewardjf9d2f9b2006-11-17 20:00:57 +00001101/* These are the structures used to hold info for creating the initial
1102 client image.
1103
1104 'iicii' mostly holds important register state present at system
1105 startup (_start_valgrind). valgrind_main() then fills in the rest
1106 of it and passes it to VG_(ii_create_image)(). That produces
1107 'iifii', which is later handed to VG_(ii_finalise_image). */
1108
1109/* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1110 This should get some address inside the stack on which we gained
sewardjfdf91b42005-09-28 00:53:09 +00001111 control (eg, it could be the SP at startup). It doesn't matter
1112 exactly where in the stack it is. This value is passed to the
sewardjf9d2f9b2006-11-17 20:00:57 +00001113 address space manager at startup. On Linux, aspacem then uses it
1114 to identify the initial stack segment and hence the upper end of
1115 the usable address space. */
sewardjfdf91b42005-09-28 00:53:09 +00001116
sewardjf9d2f9b2006-11-17 20:00:57 +00001117static IICreateImageInfo the_iicii;
1118static IIFinaliseImageInfo the_iifii;
1119
sewardjfdf91b42005-09-28 00:53:09 +00001120
sewardj1ae3f3a2005-09-28 10:47:38 +00001121/* --- Forwards decls to do with shutdown --- */
1122
1123static void final_tidyup(ThreadId tid);
1124
1125/* Do everything which needs doing when the last thread exits */
1126static
1127void shutdown_actions_NORETURN( ThreadId tid,
1128 VgSchedReturnCode tids_schedretcode );
1129
1130/* --- end of Forwards decls to do with shutdown --- */
sewardjfdf91b42005-09-28 00:53:09 +00001131
1132
sewardj45f4e7c2005-09-27 19:20:21 +00001133/* TODO: GIVE THIS A PROPER HOME
njn1d0825f2006-03-27 11:37:07 +00001134 TODO: MERGE THIS WITH DUPLICATE IN mc_leakcheck.c and coredump-elf.c.
sewardj45f4e7c2005-09-27 19:20:21 +00001135 Extract from aspacem a vector of the current segment start
1136 addresses. The vector is dynamically allocated and should be freed
1137 by the caller when done. REQUIRES m_mallocfree to be running.
1138 Writes the number of addresses required into *n_acquired. */
nethercotec314eba2004-07-15 12:59:41 +00001139
sewardj45f4e7c2005-09-27 19:20:21 +00001140static Addr* get_seg_starts ( /*OUT*/Int* n_acquired )
sewardj1cf558c2005-04-25 01:36:56 +00001141{
sewardj45f4e7c2005-09-27 19:20:21 +00001142 Addr* starts;
sewardja48a4932005-09-29 11:09:56 +00001143 Int n_starts, r = 0;
sewardj45f4e7c2005-09-27 19:20:21 +00001144
1145 n_starts = 1;
sewardj1cf558c2005-04-25 01:36:56 +00001146 while (True) {
sewardj45f4e7c2005-09-27 19:20:21 +00001147 starts = VG_(malloc)( n_starts * sizeof(Addr) );
1148 if (starts == NULL)
1149 break;
1150 r = VG_(am_get_segment_starts)( starts, n_starts );
1151 if (r >= 0)
1152 break;
1153 VG_(free)(starts);
1154 n_starts *= 2;
sewardj1cf558c2005-04-25 01:36:56 +00001155 }
sewardj45f4e7c2005-09-27 19:20:21 +00001156
1157 if (starts == NULL) {
1158 *n_acquired = 0;
1159 return NULL;
1160 }
1161
1162 *n_acquired = r;
1163 return starts;
sewardj1cf558c2005-04-25 01:36:56 +00001164}
1165
1166
sewardjf9d2f9b2006-11-17 20:00:57 +00001167/* By the time we get to valgrind_main, the_iicii should already have
1168 been filled in with any important details as required by whatever
1169 OS we have been built for.
1170*/
sewardj17c11042006-10-15 01:26:40 +00001171static
sewardjf9d2f9b2006-11-17 20:00:57 +00001172Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
nethercote71980f02004-01-24 18:18:54 +00001173{
sewardj13247ca2005-12-30 22:52:20 +00001174 HChar* toolname = "memcheck"; // default to Memcheck
sewardj13247ca2005-12-30 22:52:20 +00001175 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
sewardj4c3faae2006-03-15 11:50:32 +00001176 UInt* client_auxv = NULL;
sewardjde764e82007-11-09 23:13:22 +00001177 ThreadId tid_main = VG_INVALID_THREADID;
sewardj45f4e7c2005-09-27 19:20:21 +00001178 Int loglevel, i;
1179 Bool logging_to_fd;
nethercote73b526f2004-10-31 18:48:21 +00001180 struct vki_rlimit zero = { 0, 0 };
sewardj17c11042006-10-15 01:26:40 +00001181
nethercote71980f02004-01-24 18:18:54 +00001182 //============================================================
nethercote71980f02004-01-24 18:18:54 +00001183 //
sewardj45f4e7c2005-09-27 19:20:21 +00001184 // Nb: startup is complex. Prerequisites are shown at every step.
nethercote71980f02004-01-24 18:18:54 +00001185 // *** Be very careful when messing with the order ***
sewardj45f4e7c2005-09-27 19:20:21 +00001186 //
1187 // The first order of business is to get debug logging, the address
1188 // space manager and the dynamic memory manager up and running.
1189 // Once that's done, we can relax a bit.
1190 //
nethercote71980f02004-01-24 18:18:54 +00001191 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001192
1193 /* This is needed to make VG_(getenv) usable early. */
1194 VG_(client_envp) = (Char**)envp;
nethercote71980f02004-01-24 18:18:54 +00001195
sewardj1cf558c2005-04-25 01:36:56 +00001196 //--------------------------------------------------------------
1197 // Start up the logging mechanism
1198 // p: none
1199 //--------------------------------------------------------------
1200 /* Start the debugging-log system ASAP. First find out how many
1201 "-d"s were specified. This is a pre-scan of the command line. */
1202 loglevel = 0;
1203 for (i = 1; i < argc; i++) {
sewardj10759312005-05-30 23:52:47 +00001204 if (argv[i][0] != '-')
1205 break;
sewardj45f4e7c2005-09-27 19:20:21 +00001206 if (VG_STREQ(argv[i], "--"))
sewardj10759312005-05-30 23:52:47 +00001207 break;
sewardj45f4e7c2005-09-27 19:20:21 +00001208 if (VG_STREQ(argv[i], "-d"))
sewardj10759312005-05-30 23:52:47 +00001209 loglevel++;
sewardj1cf558c2005-04-25 01:36:56 +00001210 }
1211
1212 /* ... and start the debug logger. Now we can safely emit logging
1213 messages all through startup. */
sewardj10759312005-05-30 23:52:47 +00001214 VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
sewardj45f4e7c2005-09-27 19:20:21 +00001215 VG_(debugLog)(1, "main", "Welcome to Valgrind version "
1216 VERSION " debug logging\n");
1217
1218 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001219 // AIX5 only: register the system call numbers
1220 // p: logging
1221 // p: that the initial few syscall numbers stated in the
1222 // bootblock have been installed (else we can't
1223 // open/read/close).
1224 //--------------------------------------------------------------
1225# if defined(VGO_aix5)
1226 VG_(debugLog)(1, "main", "aix5: registering syscalls ..\n");
1227 { UChar sysent_name[50];
1228 SysRes fd;
1229 Bool ok;
1230 Int n_unregd, sysent_used = 0;
1231 prsysent_t* sysent_hdr;
1232
1233 VG_(sprintf)(sysent_name, "/proc/%d/sysent", VG_(getpid)());
1234 fd = VG_(open)(sysent_name, VKI_O_RDONLY, 0);
1235 if (fd.isError)
1236 VG_(err_config_error)("aix5: can't open /proc/<pid>/sysent");
1237
1238 sysent_used = VG_(read)(fd.res, aix5_sysent_buf, VG_AIX5_SYSENT_SIZE);
1239 if (sysent_used < 0)
1240 VG_(err_config_error)("aix5: error reading /proc/<pid>/sysent");
1241 if (sysent_used >= VG_AIX5_SYSENT_SIZE)
1242 VG_(err_config_error)("aix5: VG_AIX5_SYSENT_SIZE is too low; "
1243 "increase and recompile");
1244 VG_(close)(fd.res);
1245
1246 vg_assert(sysent_used > 0 && sysent_used < VG_AIX5_SYSENT_SIZE);
1247
1248 sysent_hdr = (prsysent_t*)&aix5_sysent_buf[0];
1249
1250 n_unregd = 0;
1251 for (i = 0; i < sysent_hdr->pr_nsyscalls; i++) {
1252 UChar* name = &aix5_sysent_buf[ sysent_hdr
1253 ->pr_syscall[i].pr_nameoff ];
1254 UInt nmbr = sysent_hdr->pr_syscall[i].pr_number;
1255 VG_(debugLog)(3, "main", "aix5: bind syscall %d to \"%s\"\n",
1256 nmbr, name);
1257 ok = VG_(aix5_register_syscall)(nmbr, name);
1258 if (!ok)
1259 n_unregd++;
1260 if (!ok)
1261 VG_(debugLog)(3, "main",
1262 "aix5: bind FAILED: %d to \"%s\"\n",
1263 nmbr, name);
1264 }
1265 VG_(debugLog)(1, "main", "aix5: .. %d syscalls known, %d unknown\n",
1266 sysent_hdr->pr_nsyscalls - n_unregd, n_unregd );
1267 VG_(debugLog)(1, "main", "aix5: __NR_AIX5_FAKE_SIGRETURN = %d\n",
1268 __NR_AIX5_FAKE_SIGRETURN );
1269 }
1270# endif
1271
1272 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001273 // Ensure we're on a plausible stack.
1274 // p: logging
1275 //--------------------------------------------------------------
1276 VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
sewardjfdf91b42005-09-28 00:53:09 +00001277 { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
1278 HChar* limHi = limLo + sizeof(VG_(interim_stack));
sewardj45f4e7c2005-09-27 19:20:21 +00001279 HChar* aLocal = (HChar*)&zero; /* any auto local will do */
1280 if (aLocal < limLo || aLocal >= limHi) {
1281 /* something's wrong. Stop. */
1282 VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
1283 limLo, limHi, aLocal );
1284 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1285 "Initial stack switched failed.\n");
1286 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1287 VG_(exit)(1);
1288 }
1289 }
1290
1291 //--------------------------------------------------------------
1292 // Ensure we have a plausible pointer to the stack on which
1293 // we gained control (not the current stack!)
1294 // p: logging
1295 //--------------------------------------------------------------
1296 VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
sewardjf9d2f9b2006-11-17 20:00:57 +00001297 if (the_iicii.sp_at_startup == 0) {
sewardj45f4e7c2005-09-27 19:20:21 +00001298 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1299 "Initial stack was not noted.\n");
1300 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1301 VG_(exit)(1);
1302 }
1303
1304 //--------------------------------------------------------------
1305 // Start up the address space manager, and determine the
1306 // approximate location of the client's stack
1307 // p: logging, plausible-stack
1308 //--------------------------------------------------------------
1309 VG_(debugLog)(1, "main", "Starting the address space manager\n");
sewardje66f2e02006-12-30 17:45:08 +00001310 vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536);
1311 vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536);
1312 vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
1313 vg_assert(VKI_PAGE_SIZE == (1 << VKI_PAGE_SHIFT));
1314 vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
sewardjf9d2f9b2006-11-17 20:00:57 +00001315 the_iicii.clstack_top = VG_(am_startup)( the_iicii.sp_at_startup );
sewardj45f4e7c2005-09-27 19:20:21 +00001316 VG_(debugLog)(1, "main", "Address space manager is running\n");
1317
1318 //--------------------------------------------------------------
1319 // Start up the dynamic memory manager
1320 // p: address space management
1321 // In fact m_mallocfree is self-initialising, so there's no
1322 // initialisation call to do. Instead, try a simple malloc/
1323 // free pair right now to check that nothing is broken.
1324 //--------------------------------------------------------------
1325 VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
1326 { void* p = VG_(malloc)( 12345 );
1327 if (p) VG_(free)( p );
1328 }
1329 VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
sewardj1cf558c2005-04-25 01:36:56 +00001330
nethercotef4928da2004-06-15 10:54:40 +00001331 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001332 //
1333 // Dynamic memory management is now available.
1334 //
nethercotef4928da2004-06-15 10:54:40 +00001335 //============================================================
1336
sewardj45f4e7c2005-09-27 19:20:21 +00001337 //--------------------------------------------------------------
1338 // Look for alternative libdir
1339 { HChar *cp = VG_(getenv)(VALGRIND_LIB);
1340 if (cp != NULL)
1341 VG_(libdir) = cp;
1342 }
1343
1344 //--------------------------------------------------------------
1345 // Extract the launcher name from the environment.
1346 VG_(debugLog)(1, "main", "Getting stage1's name\n");
1347 VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
1348 if (VG_(name_of_launcher) == NULL) {
1349 VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
1350 VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
1351 VG_(exit)(1);
1352 }
1353
1354 //--------------------------------------------------------------
fitzhardingeb50068f2004-02-24 23:42:55 +00001355 // Get the current process datasize rlimit, and set it to zero.
1356 // This prevents any internal uses of brk() from having any effect.
1357 // We remember the old value so we can restore it on exec, so that
1358 // child processes will have a reasonable brk value.
1359 VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1360 zero.rlim_max = VG_(client_rlimit_data).rlim_max;
1361 VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
thughesc37184f2004-09-11 14:16:57 +00001362
1363 // Get the current process stack rlimit.
1364 VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
1365
sewardje2d1e672005-11-12 23:10:48 +00001366 //--------------------------------------------------------------
1367 // Figure out what sort of CPU we're on, and whether it is
1368 // able to run V.
1369 VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
1370 { VexArch vex_arch;
1371 VexArchInfo vex_archinfo;
1372 Bool ok = VG_(machine_get_hwcaps)();
1373 if (!ok) {
1374 VG_(printf)("\n");
1375 VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
1376 VG_(printf)(" Supported CPUs are:\n");
1377 VG_(printf)(" * x86 (practically any; Pentium-I or above), "
1378 "AMD Athlon or above)\n");
1379 VG_(printf)(" * AMD Athlon64/Opteron\n");
1380 VG_(printf)(" * PowerPC (most; ppc405 and above)\n");
1381 VG_(printf)("\n");
1382 VG_(exit)(1);
1383 }
1384 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001385 VG_(debugLog)(
1386 1, "main", "... arch = %s, hwcaps = %s\n",
1387 LibVEX_ppVexArch ( vex_arch ),
1388 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1389 );
sewardje2d1e672005-11-12 23:10:48 +00001390 }
1391
sewardj198f34f2007-07-09 23:13:07 +00001392 //--------------------------------------------------------------
1393 // Record the working directory at startup
1394 // p: none (Linux), getenv and sys_getpid work (AIX)
1395 VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
1396 { Bool ok = VG_(record_startup_wd)();
1397 if (!ok)
1398 VG_(err_config_error)( "Can't establish current working "
1399 "directory at startup");
1400 }
1401 { Char buf[VKI_PATH_MAX+1];
1402 Bool ok = VG_(get_startup_wd)( buf, sizeof(buf) );
1403 vg_assert(ok);
1404 buf[VKI_PATH_MAX] = 0;
1405 VG_(debugLog)(1, "main", "... %s\n", buf );
1406 }
1407
sewardj45f4e7c2005-09-27 19:20:21 +00001408 //============================================================
1409 // Command line argument handling order:
1410 // * If --help/--help-debug are present, show usage message
1411 // (including the tool-specific usage)
1412 // * (If no --tool option given, default to Memcheck)
1413 // * Then, if client is missing, abort with error msg
1414 // * Then, if any cmdline args are bad, abort with error msg
1415 //============================================================
1416
1417 //--------------------------------------------------------------
1418 // Split up argv into: C args, V args, V extra args, and exename.
1419 // p: dynamic memory allocation
1420 //--------------------------------------------------------------
1421 VG_(debugLog)(1, "main", "Split up command line\n");
1422 VG_(split_up_argv)( argc, argv );
sewardj14c7cc52007-02-25 15:08:24 +00001423 vg_assert( VG_(args_for_valgrind) );
1424 vg_assert( VG_(args_for_client) );
sewardj45f4e7c2005-09-27 19:20:21 +00001425 if (0) {
sewardj14c7cc52007-02-25 15:08:24 +00001426 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
1427 VG_(printf)(
1428 "varg %s\n",
1429 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1430 );
sewardj45f4e7c2005-09-27 19:20:21 +00001431 VG_(printf)(" exe %s\n", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001432 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
1433 VG_(printf)(
1434 "carg %s\n",
1435 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1436 );
nethercote71980f02004-01-24 18:18:54 +00001437 }
1438
sewardj948a6fc2007-03-19 18:38:55 +00001439# if defined(VGO_aix5)
1440 /* Tolerate ptraced-based launchers. They can't run 'no program'
1441 if the user types "valgrind --help", so they run a do-nothing
1442 program $prefix/bin/no_op_client_for_valgrind, and we catch that
1443 here and turn it the exe name back into NULL. Then --help,
1444 --version etc work as they should. */
1445 if (VG_(args_the_exename)
1446 && VG_(strstr)( VG_(args_the_exename), "/no_op_client_for_valgrind" )) {
1447 VG_(args_the_exename) = NULL;
1448 }
1449# endif
1450
nethercote71980f02004-01-24 18:18:54 +00001451 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001452 // Extract tool name and whether help has been requested.
1453 // Note we can't print the help message yet, even if requested,
1454 // because the tool has not been initialised.
1455 // p: split_up_argv [for VG_(args_for_valgrind)]
nethercote71980f02004-01-24 18:18:54 +00001456 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001457 VG_(debugLog)(1, "main", "Preprocess command line opts\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001458 get_helprequest_and_toolname(&need_help, &toolname);
nethercote71980f02004-01-24 18:18:54 +00001459
sewardj45f4e7c2005-09-27 19:20:21 +00001460 // Set default vex control params
1461 LibVEX_default_VexControl(& VG_(clo_vex_control));
nethercote71980f02004-01-24 18:18:54 +00001462
1463 //--------------------------------------------------------------
1464 // Load client executable, finding in $PATH if necessary
sewardj45f4e7c2005-09-27 19:20:21 +00001465 // p: get_helprequest_and_toolname() [for 'exec', 'need_help']
nethercote71980f02004-01-24 18:18:54 +00001466 // p: layout_remaining_space [so there's space]
sewardj17c11042006-10-15 01:26:40 +00001467 //
nethercote71980f02004-01-24 18:18:54 +00001468 // Set up client's environment
sewardj45f4e7c2005-09-27 19:20:21 +00001469 // p: set-libdir [for VG_(libdir)]
1470 // p: get_helprequest_and_toolname [for toolname]
sewardj17c11042006-10-15 01:26:40 +00001471 //
nethercote5ee67ca2004-06-22 14:00:09 +00001472 // Setup client stack, eip, and VG_(client_arg[cv])
nethercote71980f02004-01-24 18:18:54 +00001473 // p: load_client() [for 'info']
1474 // p: fix_environment() [for 'env']
sewardj17c11042006-10-15 01:26:40 +00001475 //
sewardj45f4e7c2005-09-27 19:20:21 +00001476 // Setup client data (brk) segment. Initially a 1-page segment
1477 // which abuts a shrinkable reservation.
1478 // p: load_client() [for 'info' and hence VG_(brk_base)]
sewardjf9d2f9b2006-11-17 20:00:57 +00001479 //
1480 // p: _start_in_C (for zeroing out the_iicii and putting some
1481 // initial values into it)
sewardj45f4e7c2005-09-27 19:20:21 +00001482 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001483 if (!need_help) {
sewardjf9d2f9b2006-11-17 20:00:57 +00001484 VG_(debugLog)(1, "main", "Create initial image\n");
1485
1486# if defined(VGO_linux)
1487 the_iicii.argv = argv;
1488 the_iicii.envp = envp;
1489 the_iicii.toolname = toolname;
1490# elif defined(VGO_aix5)
1491 /* the_iicii.intregs37 already set up */
1492 /* the_iicii.bootblock already set up */
1493 /* the_iicii.adler32_exp already set up */
1494 /* the_iicii.sp_at_startup is irrelevant */
1495 /* the_iicii.clstack_top is irrelevant */
1496 the_iicii.toolname = toolname;
1497# else
1498# error "Uknown platform"
1499# endif
1500
1501 the_iifii = VG_(ii_create_image)( the_iicii );
1502
sewardj17c11042006-10-15 01:26:40 +00001503# if defined(VGO_aix5)
sewardj17c11042006-10-15 01:26:40 +00001504 /* Tell aspacem where the initial client stack is, so that it
1505 can later produce a faked-up NSegment in response to
1506 VG_(am_find_nsegment) for that address range, if asked. */
sewardjf9d2f9b2006-11-17 20:00:57 +00001507 VG_(am_aix5_set_initial_client_sp)( the_iifii.initial_client_SP );
1508 /* Now have a look at said fake segment, so we can find out
1509 the size of it. */
1510 { SizeT sz;
1511 NSegment const* seg
1512 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
1513 vg_assert(seg);
1514 sz = seg->end - seg->start + 1;
1515 vg_assert(sz >= 0 && sz <= 64*1024*1024); /* stay sane */
1516 the_iifii.clstack_max_size = sz;
1517 }
sewardj17c11042006-10-15 01:26:40 +00001518# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001519 }
nethercote71980f02004-01-24 18:18:54 +00001520
1521 //==============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001522 //
1523 // Finished loading/setting up the client address space.
1524 //
nethercote71980f02004-01-24 18:18:54 +00001525 //==============================================================
1526
1527 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001528 // setup file descriptors
1529 // p: n/a
1530 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001531 VG_(debugLog)(1, "main", "Setup file descriptors\n");
nethercote71980f02004-01-24 18:18:54 +00001532 setup_file_descriptors();
1533
1534 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001535 // create the fake /proc/<pid>/cmdline file and then unlink it,
1536 // but hold onto the fd, so we can hand it out to the client
1537 // when it tries to open /proc/<pid>/cmdline for itself.
1538 // p: setup file descriptors
nethercotec314eba2004-07-15 12:59:41 +00001539 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001540 if (!need_help) {
1541 HChar buf[50], buf2[50+64];
1542 HChar nul[1];
1543 Int fd, r;
1544 HChar* exename;
nethercotec314eba2004-07-15 12:59:41 +00001545
sewardj45f4e7c2005-09-27 19:20:21 +00001546 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
1547
1548 VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
1549 fd = VG_(mkstemp)( buf, buf2 );
1550 if (fd == -1)
sewardj17c11042006-10-15 01:26:40 +00001551 VG_(err_config_error)("Can't create client cmdline file in /tmp.");
sewardj45f4e7c2005-09-27 19:20:21 +00001552
1553 nul[0] = 0;
1554 exename = VG_(args_the_exename) ? VG_(args_the_exename)
1555 : "unknown_exename";
sewardj45f4e7c2005-09-27 19:20:21 +00001556 VG_(write)(fd, VG_(args_the_exename),
1557 VG_(strlen)( VG_(args_the_exename) ));
1558 VG_(write)(fd, nul, 1);
1559
sewardj14c7cc52007-02-25 15:08:24 +00001560 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1561 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
1562 VG_(write)(fd, arg, VG_(strlen)( arg ));
sewardj45f4e7c2005-09-27 19:20:21 +00001563 VG_(write)(fd, nul, 1);
1564 }
1565
1566 /* Don't bother to seek the file back to the start; instead do
1567 it every time a copy of it is given out (by PRE(sys_open)).
1568 That is probably more robust across fork() etc. */
1569
1570 /* Now delete it, but hang on to the fd. */
1571 r = VG_(unlink)( buf2 );
1572 if (r)
sewardj17c11042006-10-15 01:26:40 +00001573 VG_(err_config_error)("Can't delete client cmdline file in /tmp.");
sewardj45f4e7c2005-09-27 19:20:21 +00001574
1575 VG_(cl_cmdline_fd) = fd;
1576 }
nethercotec314eba2004-07-15 12:59:41 +00001577
1578 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001579 // Init tool part 1: pre_clo_init
nethercotec314eba2004-07-15 12:59:41 +00001580 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
nethercotec314eba2004-07-15 12:59:41 +00001581 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
nethercote71980f02004-01-24 18:18:54 +00001582 //--------------------------------------------------------------
njn64c83242005-06-21 01:54:38 +00001583 {
1584 Char* s;
1585 Bool ok;
sewardj45f4e7c2005-09-27 19:20:21 +00001586 VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
1587 (VG_(tool_info).tl_pre_clo_init)();
1588 ok = VG_(sanity_check_needs)( &s );
njn64c83242005-06-21 01:54:38 +00001589 if (!ok) {
1590 VG_(tool_panic)(s);
1591 }
1592 }
nethercote71980f02004-01-24 18:18:54 +00001593
sewardj45f4e7c2005-09-27 19:20:21 +00001594 //--------------------------------------------------------------
nethercotef4928da2004-06-15 10:54:40 +00001595 // If --tool and --help/--help-debug was given, now give the core+tool
1596 // help message
sewardj45f4e7c2005-09-27 19:20:21 +00001597 // p: get_helprequest_and_toolname() [for 'need_help']
1598 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
1599 //--------------------------------------------------------------
1600 VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
nethercotef4928da2004-06-15 10:54:40 +00001601 if (need_help) {
sewardj45f4e7c2005-09-27 19:20:21 +00001602 usage_NORETURN(/*--help-debug?*/2 == need_help);
nethercotef4928da2004-06-15 10:54:40 +00001603 }
nethercotec314eba2004-07-15 12:59:41 +00001604
sewardj45f4e7c2005-09-27 19:20:21 +00001605 //--------------------------------------------------------------
1606 // Process command line options to Valgrind + tool
1607 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1608 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1609 //--------------------------------------------------------------
1610 VG_(debugLog)(1, "main", "Process Valgrind's command line options, "
sewardja48a4932005-09-29 11:09:56 +00001611 "setup logging\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001612 logging_to_fd = process_cmd_line_options(client_auxv, toolname);
1613
1614 //--------------------------------------------------------------
sewardj592ae092005-11-08 19:01:44 +00001615 // Zeroise the millisecond counter by doing a first read of it.
1616 // p: none
1617 //--------------------------------------------------------------
1618 (void) VG_(read_millisecond_timer)();
1619
1620 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001621 // Print the preamble
1622 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
1623 // p: process_cmd_line_options() [for VG_(clo_verbosity), VG_(clo_xml),
1624 // VG_(clo_log_file_qualifier),
1625 // logging_to_fd]
1626 //--------------------------------------------------------------
1627 VG_(debugLog)(1, "main", "Print the preamble...\n");
1628 print_preamble(logging_to_fd, toolname);
1629 VG_(debugLog)(1, "main", "...finished the preamble\n");
1630
1631 //--------------------------------------------------------------
1632 // Init tool part 2: post_clo_init
1633 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1634 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1635 // p: print_preamble() [so any warnings printed in post_clo_init
1636 // are shown after the preamble]
1637 //--------------------------------------------------------------
1638 VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
njn51d827b2005-05-09 01:02:08 +00001639 VG_TDICT_CALL(tool_post_clo_init);
nethercotef4928da2004-06-15 10:54:40 +00001640
1641 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001642 // Initialise translation table and translation cache
1643 // p: aspacem [??]
1644 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
nethercote71980f02004-01-24 18:18:54 +00001645 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001646 VG_(debugLog)(1, "main", "Initialise TT/TC\n");
1647 VG_(init_tt_tc)();
sewardjb5f6f512005-03-10 23:59:00 +00001648
sewardj45f4e7c2005-09-27 19:20:21 +00001649 //--------------------------------------------------------------
1650 // Initialise the redirect table.
1651 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
1652 // p: aspacem [so can change ownership of sysinfo pages]
1653 //--------------------------------------------------------------
1654 VG_(debugLog)(1, "main", "Initialise redirects\n");
sewardj0ec07f32006-01-12 12:32:32 +00001655 VG_(redir_initialise)();
nethercote71980f02004-01-24 18:18:54 +00001656
1657 //--------------------------------------------------------------
1658 // Allow GDB attach
1659 // p: process_cmd_line_options() [for VG_(clo_wait_for_gdb)]
1660 //--------------------------------------------------------------
1661 /* Hook to delay things long enough so we can get the pid and
1662 attach GDB in another shell. */
1663 if (VG_(clo_wait_for_gdb)) {
sewardj95611ff2007-02-16 13:57:07 +00001664 Long iters;
1665 volatile Long q;
sewardj1fbc1a52005-04-25 02:05:54 +00001666 VG_(debugLog)(1, "main", "Wait for GDB\n");
sewardj93ab8572005-02-06 14:10:40 +00001667 VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
sewardj8211a572005-06-23 21:37:47 +00001668
1669# if defined(VGP_x86_linux)
1670 iters = 5;
sewardj2c48c7b2005-11-29 13:05:56 +00001671# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
sewardj8211a572005-06-23 21:37:47 +00001672 iters = 10;
1673# elif defined(VGP_ppc32_linux)
sewardjd714d2e2005-07-08 18:24:04 +00001674 iters = 5;
sewardj17c11042006-10-15 01:26:40 +00001675# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1676 iters = 4;
sewardj8211a572005-06-23 21:37:47 +00001677# else
sewardj17c11042006-10-15 01:26:40 +00001678# error "Unknown plat"
sewardj8211a572005-06-23 21:37:47 +00001679# endif
1680
1681 iters *= 1000*1000*1000;
1682 for (q = 0; q < iters; q++)
1683 ;
nethercote71980f02004-01-24 18:18:54 +00001684 }
1685
sewardjb5d320c2005-03-13 18:57:15 +00001686 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001687 // Search for file descriptors that are inherited from our parent
1688 // p: process_cmd_line_options [for VG_(clo_track_fds)]
1689 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001690 if (VG_(clo_track_fds)) {
1691 VG_(debugLog)(1, "main", "Init preopened fds\n");
nethercote71980f02004-01-24 18:18:54 +00001692 VG_(init_preopened_fds)();
sewardj1fbc1a52005-04-25 02:05:54 +00001693 }
nethercote71980f02004-01-24 18:18:54 +00001694
1695 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001696 // Load debug info for the existing segments.
1697 // p: setup_code_redirect_table [so that redirs can be recorded]
1698 // p: mallocfree
1699 // p: probably: setup fds and process CLOs, so that logging works
1700 //--------------------------------------------------------------
1701 VG_(debugLog)(1, "main", "Load initial debug info\n");
sewardj17c11042006-10-15 01:26:40 +00001702# if defined(VGO_linux)
sewardj45f4e7c2005-09-27 19:20:21 +00001703 { Addr* seg_starts;
1704 Int n_seg_starts;
1705
1706 seg_starts = get_seg_starts( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001707 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00001708
sewardjf72cced2005-11-08 00:45:47 +00001709 /* show them all to the debug info reader. allow_SkFileV has to
1710 be True here so that we read info from the valgrind executable
1711 itself. */
sewardj45f4e7c2005-09-27 19:20:21 +00001712 for (i = 0; i < n_seg_starts; i++)
sewardjf72cced2005-11-08 00:45:47 +00001713 VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/ );
sewardj45f4e7c2005-09-27 19:20:21 +00001714
1715 VG_(free)( seg_starts );
1716 }
sewardj17c11042006-10-15 01:26:40 +00001717# elif defined(VGO_aix5)
1718 { AixCodeSegChange* changes;
1719 Int changes_size, changes_used;
1720
1721 /* Find out how many AixCodeSegChange records we will need,
1722 and acquire them. */
1723 changes_size = VG_(am_aix5_reread_procmap_howmany_directives)();
1724 changes = VG_(malloc)(changes_size * sizeof(AixCodeSegChange));
1725 vg_assert(changes);
1726
1727 /* Now re-read /proc/<pid>/map and acquire a change set */
1728 VG_(am_aix5_reread_procmap)( changes, &changes_used );
1729 vg_assert(changes_used >= 0 && changes_used <= changes_size);
1730
1731 /* And notify m_debuginfo of the changes. */
1732 for (i = 0; i < changes_used; i++)
1733 VG_(di_aix5_notify_segchange)(
1734 changes[i].code_start,
1735 changes[i].code_len,
1736 changes[i].data_start,
1737 changes[i].data_len,
1738 changes[i].file_name,
1739 changes[i].mem_name,
1740 changes[i].is_mainexe,
1741 changes[i].acquire
1742 );
1743
1744 VG_(free)(changes);
1745 }
1746# else
1747# error Unknown OS
1748# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001749
1750 //--------------------------------------------------------------
1751 // Tell aspacem of ownership change of the asm helpers, so that
1752 // m_translate allows them to be translated. However, only do this
1753 // after the initial debug info read, since making a hole in the
1754 // address range for the stage2 binary confuses the debug info reader.
1755 // p: aspacem
1756 //--------------------------------------------------------------
1757 { Bool change_ownership_v_c_OK;
sewardj1a85f4f2006-01-12 21:15:35 +00001758 Addr co_start = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
1759 Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
sewardj45f4e7c2005-09-27 19:20:21 +00001760 VG_(debugLog)(1,"redir",
1761 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
1762 (ULong)co_start, (ULong)co_endPlus-1 );
1763
1764 change_ownership_v_c_OK
1765 = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
1766 vg_assert(change_ownership_v_c_OK);
1767 }
1768
1769 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001770 // Initialise the scheduler (phase 1) [generates tid_main]
1771 // p: none, afaics
1772 //--------------------------------------------------------------
1773 VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
1774 tid_main = VG_(scheduler_init_phase1)();
1775 vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
1776 && tid_main != VG_INVALID_THREADID);
1777 /* Tell the tool about tid_main */
1778 VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
1779
1780 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001781 // Tell the tool about the initial client memory permissions
1782 // p: aspacem
1783 // p: mallocfree
1784 // p: setup_client_stack
1785 // p: setup_client_dataseg
1786 //--------------------------------------------------------------
1787 VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
1788 { Addr* seg_starts;
1789 Int n_seg_starts;
sewardj45f4e7c2005-09-27 19:20:21 +00001790
1791 seg_starts = get_seg_starts( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001792 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00001793
1794 /* show interesting ones to the tool */
1795 for (i = 0; i < n_seg_starts; i++) {
sewardj12ab7652006-10-17 02:10:42 +00001796 NSegment const* seg
sewardj17c11042006-10-15 01:26:40 +00001797 = VG_(am_find_nsegment)( seg_starts[i] );
sewardj45f4e7c2005-09-27 19:20:21 +00001798 vg_assert(seg);
1799 if (seg->kind == SkFileC || seg->kind == SkAnonC) {
1800 VG_(debugLog)(2, "main",
1801 "tell tool about %010lx-%010lx %c%c%c\n",
1802 seg->start, seg->end,
1803 seg->hasR ? 'r' : '-',
1804 seg->hasW ? 'w' : '-',
1805 seg->hasX ? 'x' : '-' );
1806 VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
1807 seg->hasR, seg->hasW, seg->hasX );
1808 }
1809 }
1810
1811 VG_(free)( seg_starts );
1812
1813 /* Also do the initial stack permissions. */
sewardj12ab7652006-10-17 02:10:42 +00001814 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00001815 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj17c11042006-10-15 01:26:40 +00001816 vg_assert(seg);
1817 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00001818 vg_assert(the_iifii.initial_client_SP >= seg->start);
1819 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardj17c11042006-10-15 01:26:40 +00001820# if defined(VGO_aix5)
1821 VG_(clstk_base) = seg->start;
1822 VG_(clstk_end) = seg->end;
1823# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001824
sewardj17c11042006-10-15 01:26:40 +00001825 /* Stuff below the initial SP is unaddressable. Take into
1826 account any ABI-mandated space below the stack pointer that
1827 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
1828 will have allocated an extra page if a red zone is required,
1829 to be on the safe side. */
sewardjf9d2f9b2006-11-17 20:00:57 +00001830 vg_assert(the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
1831 >= seg->start);
sewardj17c11042006-10-15 01:26:40 +00001832 VG_TRACK( die_mem_stack,
1833 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00001834 the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
1835 - seg->start );
sewardj17c11042006-10-15 01:26:40 +00001836 VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
1837 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00001838 the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
sewardj17c11042006-10-15 01:26:40 +00001839 }
sewardj45f4e7c2005-09-27 19:20:21 +00001840
1841 /* Also the assembly helpers. */
1842 VG_TRACK( new_mem_startup,
1843 (Addr)&VG_(trampoline_stuff_start),
sewardjc6527d62006-02-13 17:54:31 +00001844 (Addr)&VG_(trampoline_stuff_end)
1845 - (Addr)&VG_(trampoline_stuff_start),
sewardj45f4e7c2005-09-27 19:20:21 +00001846 False, /* readable? */
1847 False, /* writable? */
1848 True /* executable? */ );
1849 }
1850
1851 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001852 // Initialise the scheduler (phase 2)
1853 // p: Initialise the scheduler (phase 1) [for tid_main]
nethercote71980f02004-01-24 18:18:54 +00001854 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
sewardj45f4e7c2005-09-27 19:20:21 +00001855 // p: setup_client_stack
nethercote71980f02004-01-24 18:18:54 +00001856 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00001857 VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
sewardj12ab7652006-10-17 02:10:42 +00001858 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00001859 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj45f4e7c2005-09-27 19:20:21 +00001860 vg_assert(seg);
1861 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00001862 vg_assert(the_iifii.initial_client_SP >= seg->start);
1863 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardjde764e82007-11-09 23:13:22 +00001864 VG_(scheduler_init_phase2)( tid_main,
1865 seg->end, the_iifii.clstack_max_size );
sewardj45f4e7c2005-09-27 19:20:21 +00001866 }
nethercote71980f02004-01-24 18:18:54 +00001867
1868 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001869 // Set up state for the root thread
sewardjb5f6f512005-03-10 23:59:00 +00001870 // p: ?
sewardj17c11042006-10-15 01:26:40 +00001871 // setup_scheduler() [for sched-specific thread 1 stuff]
sewardjf9d2f9b2006-11-17 20:00:57 +00001872 // VG_(ii_create_image) [for 'the_iicii' initial info]
sewardj2a99cf62004-11-24 10:44:19 +00001873 //--------------------------------------------------------------
sewardjf9d2f9b2006-11-17 20:00:57 +00001874 VG_(debugLog)(1, "main", "Finalise initial image\n");
1875 VG_(ii_finalise_image)( the_iifii );
njnea4b28c2004-11-30 16:04:58 +00001876
sewardj2a99cf62004-11-24 10:44:19 +00001877 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001878 // Initialise the signal handling subsystem
sewardjb5f6f512005-03-10 23:59:00 +00001879 // p: n/a
nethercote71980f02004-01-24 18:18:54 +00001880 //--------------------------------------------------------------
1881 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
sewardj1fbc1a52005-04-25 02:05:54 +00001882 VG_(debugLog)(1, "main", "Initialise signal management\n");
nethercote71980f02004-01-24 18:18:54 +00001883 VG_(sigstartup_actions)();
1884
1885 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001886 // Read suppression file
1887 // p: process_cmd_line_options() [for VG_(clo_suppressions)]
1888 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001889 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
1890 VG_(debugLog)(1, "main", "Load suppressions\n");
nethercote71980f02004-01-24 18:18:54 +00001891 VG_(load_suppressions)();
sewardj1fbc1a52005-04-25 02:05:54 +00001892 }
nethercote71980f02004-01-24 18:18:54 +00001893
1894 //--------------------------------------------------------------
rjwalsh0140af52005-06-04 20:42:33 +00001895 // register client stack
1896 //--------------------------------------------------------------
njn945ed2e2005-06-24 03:28:30 +00001897 VG_(clstk_id) = VG_(register_stack)(VG_(clstk_base), VG_(clstk_end));
rjwalsh0140af52005-06-04 20:42:33 +00001898
1899 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001900 // Show the address space state so far
1901 //--------------------------------------------------------------
1902 VG_(debugLog)(1, "main", "\n");
1903 VG_(debugLog)(1, "main", "\n");
1904 VG_(am_show_nsegments)(1,"Memory layout at client startup");
1905 VG_(debugLog)(1, "main", "\n");
1906 VG_(debugLog)(1, "main", "\n");
1907
1908 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001909 // Run!
1910 //--------------------------------------------------------------
sewardj71bc3cb2005-05-19 00:25:45 +00001911 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00001912 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00001913 VG_(elapsed_wallclock_time)(buf);
sewardj753673f2005-08-09 22:03:08 +00001914 VG_(message)(Vg_UserMsg, "<status>\n"
1915 " <state>RUNNING</state>\n"
1916 " <time>%t</time>\n"
1917 "</status>",
1918 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00001919 VG_(message)(Vg_UserMsg, "");
1920 }
1921
sewardj1fbc1a52005-04-25 02:05:54 +00001922 VG_(debugLog)(1, "main", "Running thread 1\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00001923
sewardj1d887112005-05-30 21:44:08 +00001924 /* As a result of the following call, the last thread standing
sewardj1ae3f3a2005-09-28 10:47:38 +00001925 eventually winds up running shutdown_actions_NORETURN
1926 just below. Unfortunately, simply exporting said function
1927 causes m_main to be part of a module cycle, which is pretty
1928 nonsensical. So instead of doing that, the address of said
1929 function is stored in a global variable 'owned' by m_syswrap,
1930 and it uses that function pointer to get back here when it needs
1931 to. */
1932
1933 /* Set continuation address. */
1934 VG_(address_of_m_main_shutdown_actions_NORETURN)
1935 = & shutdown_actions_NORETURN;
1936
1937 /* Run the first thread, eventually ending up at the continuation
1938 address. */
njnaf839f52005-06-23 03:27:57 +00001939 VG_(main_thread_wrapper_NORETURN)(1);
nethercote71980f02004-01-24 18:18:54 +00001940
sewardj1d887112005-05-30 21:44:08 +00001941 /*NOTREACHED*/
1942 vg_assert(0);
sewardjb5f6f512005-03-10 23:59:00 +00001943}
1944
sewardj17c11042006-10-15 01:26:40 +00001945/* Do everything which needs doing when the last thread exits or when
1946 a thread exits requesting a complete process exit (exit on AIX).
1947
1948 We enter here holding The Lock. For the case VgSrc_ExitProcess we
1949 must never release it, because to do so would allow other threads
1950 to continue after the system is ostensibly shut down. So we must
1951 go to our grave, so to speak, holding the lock.
1952
1953 In fact, there is never any point in releasing the lock at this
1954 point - we have it, we're shutting down the entire system, and
1955 for the case VgSrc_ExitProcess doing so positively causes trouble.
1956 So don't.
1957
1958 The final_tidyup call makes a bit of a nonsense of the ExitProcess
1959 case, since it will run the libc_freeres function, thus allowing
1960 other lurking threads to run again. Hmm. */
sewardjb5f6f512005-03-10 23:59:00 +00001961
sewardj1ae3f3a2005-09-28 10:47:38 +00001962static
1963void shutdown_actions_NORETURN( ThreadId tid,
1964 VgSchedReturnCode tids_schedretcode )
sewardjb5f6f512005-03-10 23:59:00 +00001965{
sewardj1d887112005-05-30 21:44:08 +00001966 VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
sewardj17c11042006-10-15 01:26:40 +00001967 VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
sewardj1d887112005-05-30 21:44:08 +00001968
sewardjb5f6f512005-03-10 23:59:00 +00001969 vg_assert(VG_(is_running_thread)(tid));
1970
sewardj12ab7652006-10-17 02:10:42 +00001971 vg_assert(tids_schedretcode == VgSrc_ExitThread
1972 || tids_schedretcode == VgSrc_ExitProcess
1973 || tids_schedretcode == VgSrc_FatalSig );
sewardjb5f6f512005-03-10 23:59:00 +00001974
sewardj12ab7652006-10-17 02:10:42 +00001975 if (tids_schedretcode == VgSrc_ExitThread) {
sewardjb5f6f512005-03-10 23:59:00 +00001976
sewardj17c11042006-10-15 01:26:40 +00001977 // We are the last surviving thread. Right?
1978 vg_assert( VG_(count_living_threads)() == 1 );
sewardjb5f6f512005-03-10 23:59:00 +00001979
sewardj17c11042006-10-15 01:26:40 +00001980 // Wait for all other threads to exit.
1981 // jrs: Huh? but they surely are already gone
1982 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00001983
sewardj17c11042006-10-15 01:26:40 +00001984 // Clean the client up before the final report
1985 // this causes the libc_freeres function to run
1986 final_tidyup(tid);
1987
1988 /* be paranoid */
1989 vg_assert(VG_(is_running_thread)(tid));
1990 vg_assert(VG_(count_living_threads)() == 1);
1991
1992 } else {
1993
1994 // We may not be the last surviving thread. However, we
1995 // want to shut down the entire process. We hold the lock
1996 // and we need to keep hold of it all the way out, in order
1997 // that none of the other threads ever run again.
1998 vg_assert( VG_(count_living_threads)() >= 1 );
1999
sewardj17c11042006-10-15 01:26:40 +00002000 // Clean the client up before the final report
2001 // this causes the libc_freeres function to run
2002 // perhaps this is unsafe, as per comment above
2003 final_tidyup(tid);
2004
2005 /* be paranoid */
2006 vg_assert(VG_(is_running_thread)(tid));
2007 vg_assert(VG_(count_living_threads)() >= 1);
2008 }
sewardjb5f6f512005-03-10 23:59:00 +00002009
2010 VG_(threads)[tid].status = VgTs_Empty;
nethercote71980f02004-01-24 18:18:54 +00002011 //--------------------------------------------------------------
2012 // Finalisation: cleanup, messages, etc. Order no so important, only
2013 // affects what order the messages come.
2014 //--------------------------------------------------------------
2015 if (VG_(clo_verbosity) > 0)
2016 VG_(message)(Vg_UserMsg, "");
2017
sewardj71bc3cb2005-05-19 00:25:45 +00002018 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002019 HChar buf[50];
sewardj9f297ca2005-05-20 02:29:52 +00002020 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
2021 VG_(show_error_counts_as_XML)();
2022 VG_(message)(Vg_UserMsg, "");
2023 }
sewardj592ae092005-11-08 19:01:44 +00002024 VG_(elapsed_wallclock_time)(buf);
sewardj753673f2005-08-09 22:03:08 +00002025 VG_(message)(Vg_UserMsg, "<status>\n"
2026 " <state>FINISHED</state>\n"
2027 " <time>%t</time>\n"
2028 "</status>",
2029 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00002030 VG_(message)(Vg_UserMsg, "");
2031 }
2032
nethercote71980f02004-01-24 18:18:54 +00002033 /* Print out file descriptor summary and stats. */
2034 if (VG_(clo_track_fds))
nethercote3a42fb82004-08-03 18:08:50 +00002035 VG_(show_open_fds)();
nethercote71980f02004-01-24 18:18:54 +00002036
njn95ec8702004-11-22 16:46:13 +00002037 if (VG_(needs).core_errors || VG_(needs).tool_errors)
nethercote71980f02004-01-24 18:18:54 +00002038 VG_(show_all_errors)();
2039
njn51d827b2005-05-09 01:02:08 +00002040 VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
nethercote71980f02004-01-24 18:18:54 +00002041
sewardj71bc3cb2005-05-19 00:25:45 +00002042 if (VG_(clo_xml)) {
2043 VG_(message)(Vg_UserMsg, "");
2044 VG_(message)(Vg_UserMsg, "</valgrindoutput>");
2045 VG_(message)(Vg_UserMsg, "");
2046 }
2047
nethercote885dd912004-08-03 23:14:00 +00002048 VG_(sanity_check_general)( True /*include expensive checks*/ );
nethercote71980f02004-01-24 18:18:54 +00002049
2050 if (VG_(clo_verbosity) > 1)
nethercote3a42fb82004-08-03 18:08:50 +00002051 print_all_stats();
nethercote71980f02004-01-24 18:18:54 +00002052
njn2025cf92005-06-26 20:44:48 +00002053 if (VG_(clo_profile_flags) > 0) {
sewardj5471ec62006-10-17 13:58:17 +00002054 #define N_MAX 200
njn2025cf92005-06-26 20:44:48 +00002055 BBProfEntry tops[N_MAX];
2056 ULong score_total = VG_(get_BB_profile) (tops, N_MAX);
2057 show_BB_profile(tops, N_MAX, score_total);
2058 }
sewardjfa8ec112005-01-19 11:55:34 +00002059
sewardj8b635a42004-11-22 19:01:47 +00002060 /* Print Vex storage stats */
sewardjbf426512005-01-17 18:35:30 +00002061 if (0)
2062 LibVEX_ShowAllocStats();
sewardj1d887112005-05-30 21:44:08 +00002063
njn8aa35852005-06-10 22:59:56 +00002064 /* Ok, finally exit in the os-specific way, according to the scheduler's
2065 return code. In short, if the (last) thread exited by calling
2066 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2067 signal, terminate the entire system with that same fatal signal. */
2068 VG_(debugLog)(1, "core_os",
njn7b85dd52005-06-12 17:26:29 +00002069 "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
njn8aa35852005-06-10 22:59:56 +00002070
njn8aa35852005-06-10 22:59:56 +00002071 switch (tids_schedretcode) {
sewardj12ab7652006-10-17 02:10:42 +00002072 case VgSrc_ExitThread: /* the normal way out (Linux) */
2073 case VgSrc_ExitProcess: /* the normal way out (AIX) */
sewardjb9779082006-05-12 23:50:15 +00002074 /* Change the application return code to user's return code,
2075 if an error was found */
2076 if (VG_(clo_error_exitcode) > 0
2077 && VG_(get_n_errs_found)() > 0) {
2078 VG_(exit)( VG_(clo_error_exitcode) );
2079 } else {
2080 /* otherwise, return the client's exit code, in the normal
2081 way. */
2082 VG_(exit)( VG_(threads)[tid].os_state.exitcode );
2083 }
njn8aa35852005-06-10 22:59:56 +00002084 /* NOT ALIVE HERE! */
sewardj17c11042006-10-15 01:26:40 +00002085 VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
njn8aa35852005-06-10 22:59:56 +00002086 break; /* what the hell :) */
2087
2088 case VgSrc_FatalSig:
2089 /* We were killed by a fatal signal, so replicate the effect */
2090 vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
2091 VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
2092 VG_(core_panic)("main(): signal was supposed to be fatal");
2093 break;
2094
2095 default:
2096 VG_(core_panic)("main(): unexpected scheduler return code");
2097 }
njne96be672005-05-08 19:08:54 +00002098}
sewardj8b635a42004-11-22 19:01:47 +00002099
sewardj1ae3f3a2005-09-28 10:47:38 +00002100/* -------------------- */
2101
2102/* Final clean-up before terminating the process.
2103 Clean up the client by calling __libc_freeres() (if requested)
2104 This is Linux-specific?
2105*/
2106static void final_tidyup(ThreadId tid)
2107{
sewardjcf951812006-01-17 02:22:21 +00002108# if defined(VGP_ppc64_linux)
2109 Addr r2;
2110# endif
sewardj0ec07f32006-01-12 12:32:32 +00002111 Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
sewardj1ae3f3a2005-09-28 10:47:38 +00002112
2113 vg_assert(VG_(is_running_thread)(tid));
2114
2115 if ( !VG_(needs).libc_freeres ||
2116 !VG_(clo_run_libc_freeres) ||
sewardj0ec07f32006-01-12 12:32:32 +00002117 0 == __libc_freeres_wrapper )
sewardj1ae3f3a2005-09-28 10:47:38 +00002118 return; /* can't/won't do it */
sewardj17c11042006-10-15 01:26:40 +00002119# if defined(VGO_aix5)
2120 return; /* inapplicable on non-Linux platforms */
2121# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002122
sewardjcf951812006-01-17 02:22:21 +00002123# if defined(VGP_ppc64_linux)
2124 r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
2125 if (r2 == 0) {
2126 VG_(message)(Vg_UserMsg,
2127 "Caught __NR_exit, but can't run __libc_freeres()");
2128 VG_(message)(Vg_UserMsg,
2129 " since cannot establish TOC pointer for it.");
2130 return;
2131 }
2132# endif
2133
sewardj1ae3f3a2005-09-28 10:47:38 +00002134 if (VG_(clo_verbosity) > 2 ||
2135 VG_(clo_trace_syscalls) ||
2136 VG_(clo_trace_sched))
2137 VG_(message)(Vg_DebugMsg,
2138 "Caught __NR_exit; running __libc_freeres()");
2139
sewardj0ec07f32006-01-12 12:32:32 +00002140 /* set thread context to point to libc_freeres_wrapper */
sewardj1a85f4f2006-01-12 21:15:35 +00002141 /* ppc64-linux note: __libc_freeres_wrapper gives us the real
2142 function entry point, not a fn descriptor, so can use it
2143 directly. However, we need to set R2 (the toc pointer)
2144 appropriately. */
sewardj1ae3f3a2005-09-28 10:47:38 +00002145 VG_(set_IP)(tid, __libc_freeres_wrapper);
sewardjcf951812006-01-17 02:22:21 +00002146# if defined(VGP_ppc64_linux)
2147 VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
2148# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002149
2150 /* Block all blockable signals by copying the real block state into
2151 the thread's block state*/
2152 VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
2153 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
2154
2155 /* and restore handlers to default */
2156 VG_(set_default_handler)(VKI_SIGSEGV);
2157 VG_(set_default_handler)(VKI_SIGBUS);
2158 VG_(set_default_handler)(VKI_SIGILL);
2159 VG_(set_default_handler)(VKI_SIGFPE);
2160
2161 // We were exiting, so assert that...
2162 vg_assert(VG_(is_exiting)(tid));
2163 // ...but now we're not again
2164 VG_(threads)[tid].exitreason = VgSrc_None;
2165
2166 // run until client thread exits - ideally with LIBC_FREERES_DONE,
2167 // but exit/exitgroup/signal will do
2168 VG_(scheduler)(tid);
2169
2170 vg_assert(VG_(is_exiting)(tid));
2171}
2172
sewardj45f4e7c2005-09-27 19:20:21 +00002173
2174/*====================================================================*/
sewardj17c11042006-10-15 01:26:40 +00002175/*=== Getting to main() alive: LINUX (for AIX5 see below) ===*/
sewardj45f4e7c2005-09-27 19:20:21 +00002176/*====================================================================*/
2177
sewardj17c11042006-10-15 01:26:40 +00002178#if defined(VGO_linux)
2179
sewardj45f4e7c2005-09-27 19:20:21 +00002180/* If linking of the final executables is done with glibc present,
2181 then Valgrind starts at main() above as usual, and all of the
2182 following code is irrelevant.
2183
2184 However, this is not the intended mode of use. The plan is to
2185 avoid linking against glibc, by giving gcc the flags
2186 -nodefaultlibs -lgcc -nostartfiles at startup.
2187
2188 From this derive two requirements:
2189
2190 1. gcc may emit calls to memcpy and memset to deal with structure
2191 assignments etc. Since we have chosen to ignore all the
2192 "normal" supporting libraries, we have to provide our own
2193 implementations of them. No problem.
2194
2195 2. We have to provide a symbol "_start", to which the kernel
2196 hands control at startup. Hence the code below.
2197*/
2198
2199/* ---------------- Requirement 1 ---------------- */
2200
sewardj17c11042006-10-15 01:26:40 +00002201void* memcpy(void *dest, const void *src, SizeT n);
2202void* memcpy(void *dest, const void *src, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002203 return VG_(memcpy)(dest,src,n);
2204}
sewardj17c11042006-10-15 01:26:40 +00002205void* memset(void *s, int c, SizeT n);
2206void* memset(void *s, int c, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002207 return VG_(memset)(s,c,n);
2208}
2209
2210/* ---------------- Requirement 2 ---------------- */
2211
2212/* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2213 comment, which explains how the stack looks right at process start
2214 (when _start is jumped to). Hence _start passes %esp to
sewardj17c11042006-10-15 01:26:40 +00002215 _start_in_C_linux, which extracts argc/argv/envp and starts up
sewardj45f4e7c2005-09-27 19:20:21 +00002216 correctly. */
2217
2218/* This is the canonical entry point, usually the first thing in the text
2219 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2220 point runs, most registers' values are unspecified, except for:
2221
2222 %edx Contains a function pointer to be registered with `atexit'.
2223 This is how the dynamic linker arranges to have DT_FINI
2224 functions called for shared libraries that have been loaded
2225 before this code runs.
2226
2227 %esp The stack contains the arguments and environment:
2228 0(%esp) argc
2229 4(%esp) argv[0]
2230 ...
2231 (4*argc)(%esp) NULL
2232 (4*(argc+1))(%esp) envp[0]
2233 ...
2234 NULL
2235*/
2236
2237/* The kernel hands control to _start, which extracts the initial
sewardj17c11042006-10-15 01:26:40 +00002238 stack pointer and calls onwards to _start_in_C_linux. This also switches
sewardja48a4932005-09-29 11:09:56 +00002239 the new stack. */
sewardj45f4e7c2005-09-27 19:20:21 +00002240#if defined(VGP_x86_linux)
2241asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002242 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002243 "\t.globl _start\n"
2244 "\t.type _start,@function\n"
2245 "_start:\n"
2246 /* set up the new stack in %eax */
sewardjfdf91b42005-09-28 00:53:09 +00002247 "\tmovl $vgPlain_interim_stack, %eax\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002248 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2249 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2250 "\tsubl $16, %eax\n"
2251 "\tandl $~15, %eax\n"
2252 /* install it, and collect the original one */
2253 "\txchgl %eax, %esp\n"
sewardj17c11042006-10-15 01:26:40 +00002254 /* call _start_in_C_linux, passing it the startup %esp */
sewardj45f4e7c2005-09-27 19:20:21 +00002255 "\tpushl %eax\n"
sewardj17c11042006-10-15 01:26:40 +00002256 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002257 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002258 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002259);
2260#elif defined(VGP_amd64_linux)
2261asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002262 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002263 "\t.globl _start\n"
2264 "\t.type _start,@function\n"
2265 "_start:\n"
2266 /* set up the new stack in %rdi */
sewardjfdf91b42005-09-28 00:53:09 +00002267 "\tmovq $vgPlain_interim_stack, %rdi\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002268 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2269 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2270 "\tandq $~15, %rdi\n"
2271 /* install it, and collect the original one */
2272 "\txchgq %rdi, %rsp\n"
sewardj17c11042006-10-15 01:26:40 +00002273 /* call _start_in_C_linux, passing it the startup %rsp */
2274 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002275 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002276 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002277);
sewardja48a4932005-09-29 11:09:56 +00002278#elif defined(VGP_ppc32_linux)
2279asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002280 ".text\n"
sewardja48a4932005-09-29 11:09:56 +00002281 "\t.globl _start\n"
2282 "\t.type _start,@function\n"
2283 "_start:\n"
2284 /* set up the new stack in r16 */
2285 "\tlis 16,vgPlain_interim_stack@ha\n"
2286 "\tla 16,vgPlain_interim_stack@l(16)\n"
2287 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2288 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2289 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2290 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2291 "\tadd 16,17,16\n"
2292 "\tadd 16,18,16\n"
2293 "\trlwinm 16,16,0,0,27\n"
2294 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2295 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2296 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002297 call _start_in_C_linux, passing it the initial SP. */
sewardja48a4932005-09-29 11:09:56 +00002298 "\tmr 3,1\n"
2299 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002300 "\tbl _start_in_C_linux\n"
sewardja48a4932005-09-29 11:09:56 +00002301 "\ttrap\n"
sewardj2fedc642005-11-19 02:02:57 +00002302 ".previous\n"
sewardja48a4932005-09-29 11:09:56 +00002303);
sewardj2c48c7b2005-11-29 13:05:56 +00002304#elif defined(VGP_ppc64_linux)
2305asm("\n"
cerion21082042005-12-06 19:07:08 +00002306 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2307 So we must have one, and that is what goes into the .opd section. */
cerion297c88f2005-12-22 15:53:12 +00002308 "\t.align 2\n"
cerion21082042005-12-06 19:07:08 +00002309 "\t.global _start\n"
2310 "\t.section \".opd\",\"aw\"\n"
2311 "\t.align 3\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002312 "_start:\n"
cerion21082042005-12-06 19:07:08 +00002313 "\t.quad ._start,.TOC.@tocbase,0\n"
2314 "\t.previous\n"
2315 "\t.type ._start,@function\n"
2316 "\t.global ._start\n"
2317 "._start:\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002318 /* set up the new stack in r16 */
2319 "\tlis 16, vgPlain_interim_stack@highest\n"
2320 "\tori 16,16,vgPlain_interim_stack@higher\n"
2321 "\tsldi 16,16,32\n"
2322 "\toris 16,16,vgPlain_interim_stack@h\n"
2323 "\tori 16,16,vgPlain_interim_stack@l\n"
2324 "\txor 17,17,17\n"
2325 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2326 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2327 "\txor 18,18,18\n"
2328 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2329 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2330 "\tadd 16,17,16\n"
2331 "\tadd 16,18,16\n"
2332 "\trldicr 16,16,0,59\n"
2333 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2334 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2335 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002336 call _start_in_C_linux, passing it the initial SP. */
sewardj2c48c7b2005-11-29 13:05:56 +00002337 "\tmr 3,1\n"
2338 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002339 "\tbl ._start_in_C_linux\n"
cerion21082042005-12-06 19:07:08 +00002340 "\tnop\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002341 "\ttrap\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002342);
sewardj45f4e7c2005-09-27 19:20:21 +00002343#else
2344#error "_start: needs implementation on this platform"
2345#endif
2346
sewardje66f2e02006-12-30 17:45:08 +00002347/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
2348#define _GNU_SOURCE
2349#define _FILE_OFFSET_BITS 64
2350/* This is in order to get AT_NULL and AT_PAGESIZE. */
2351#include <elf.h>
2352/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
2353
sewardj45f4e7c2005-09-27 19:20:21 +00002354/* Avoid compiler warnings: this fn _is_ used, but labelling it
2355 'static' causes gcc to complain it isn't. */
sewardj17c11042006-10-15 01:26:40 +00002356void _start_in_C_linux ( UWord* pArgc );
2357void _start_in_C_linux ( UWord* pArgc )
sewardj45f4e7c2005-09-27 19:20:21 +00002358{
2359 Int r;
2360 Word argc = pArgc[0];
2361 HChar** argv = (HChar**)&pArgc[1];
2362 HChar** envp = (HChar**)&pArgc[1+argc+1];
sewardjf9d2f9b2006-11-17 20:00:57 +00002363
2364 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2365 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2366
2367 the_iicii.sp_at_startup = (Addr)pArgc;
2368
sewardje66f2e02006-12-30 17:45:08 +00002369# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
2370 {
2371 /* ppc/ppc64 can be configured with different page sizes.
2372 Determine this early. This is an ugly hack and really should
2373 be moved into valgrind_main. */
2374 UWord *sp = &pArgc[1+argc+1];
2375 while (*sp++ != 0)
2376 ;
2377 for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
2378 if (*sp == AT_PAGESZ) {
2379 VKI_PAGE_SIZE = sp[1];
2380 for (VKI_PAGE_SHIFT = 12;
2381 VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
2382 if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
2383 break;
2384 }
2385 }
2386# endif
2387
sewardjf9d2f9b2006-11-17 20:00:57 +00002388 r = valgrind_main( (Int)argc, argv, envp );
sewardj17c11042006-10-15 01:26:40 +00002389 /* NOTREACHED */
sewardj45f4e7c2005-09-27 19:20:21 +00002390 VG_(exit)(r);
2391}
2392
sewardj17c11042006-10-15 01:26:40 +00002393#endif /* defined(VGO_linux) */
2394
2395
2396/*====================================================================*/
2397/*=== Getting to main() alive: AIX5 ===*/
2398/*====================================================================*/
2399
2400#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
2401
2402/* This is somewhat simpler than the Linux case. _start_valgrind
2403 receives control from the magic piece of code created in this
2404 process' address space by the launcher, via use of ptrace(). At
2405 the point of entry:
2406
2407 - the initial client process image is in memory and ready to roll,
2408 except that we've partially trashed its integer register state
2409 in order to get this far. So ..
2410
2411 - intregs37 holds the client's initial integer register state, so
2412 we can restore it before starting the client on the VCPU.
2413
2414 - we're on the client's stack. This is not good; therefore the
2415 first order of business is to switch to our temporary stack.
2416
2417 - the client's initial argc/v/envp is in r3/r4/r5 (32 bit mode) or
2418 r14/r15/r16 (64 bit mode). They are pulled out of the stashed
2419 integer register state and passed to our main().
2420
2421 The launcher will have played some games with argv. If the launcher
2422 ($prefix/bin/valgrind) was started like this
2423
2424 valgrind [args-for-V] app [args-for-app]
2425
2426 then the launcher will have started the client as
2427
2428 app [args-for-V] app [args-for-app]
2429
2430 m_initimg will have to mess with the client's initial r4/r5
2431 (32-bit) or r15/r16 (64-bit) so that it believes it was execd as
2432 "app [args-for-app]". Well, that's no big deal.
2433*/
2434
2435#include "launcher-aix5-bootblock.h"
2436
2437void _start_in_C_aix5 ( AIX5Bootblock* bootblock );
2438void _start_in_C_aix5 ( AIX5Bootblock* bootblock )
2439{
2440 Int r;
2441 ULong* intregs37;
2442 UWord argc, argv, envp;
2443 __NR_getpid = bootblock->__NR_getpid;
2444 __NR_write = bootblock->__NR_write;
2445 __NR_exit = bootblock->__NR_exit;
2446 __NR_open = bootblock->__NR_open;
2447 __NR_read = bootblock->__NR_read;
2448 __NR_close = bootblock->__NR_close;
sewardjf9d2f9b2006-11-17 20:00:57 +00002449
2450 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2451 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2452
sewardj17c11042006-10-15 01:26:40 +00002453 intregs37 = &bootblock->iregs_pc_cr_lr_ctr_xer[0];
sewardjf9d2f9b2006-11-17 20:00:57 +00002454 the_iicii.intregs37 = intregs37;
2455 the_iicii.bootblock = (void*)bootblock;
2456 the_iicii.adler32_exp = bootblock->adler32;
2457
2458 /* Not important on AIX. */
2459 the_iicii.sp_at_startup = (Addr)0x31415927ULL;
2460
sewardj17c11042006-10-15 01:26:40 +00002461# if defined(VGP_ppc32_aix5)
2462 argc = (UWord)intregs37[3]; /* client's r3 == argc */
2463 argv = (UWord)intregs37[4];
2464 envp = (UWord)intregs37[5];
2465# else /* defined(VGP_ppc64_aix5) */
2466 argc = (UWord)intregs37[14]; /* client's r14 == argc */
2467 argv = (UWord)intregs37[15];
2468 envp = (UWord)intregs37[16];
2469# endif
sewardjf9d2f9b2006-11-17 20:00:57 +00002470
2471 r = valgrind_main( (Int)argc, (HChar**)argv, (HChar**)envp );
2472
sewardj17c11042006-10-15 01:26:40 +00002473 /* NOTREACHED */
2474 VG_(exit)(r);
2475}
2476
2477/* THE ENTRY POINT */
2478void _start_valgrind ( AIX5Bootblock* bootblock );
2479void _start_valgrind ( AIX5Bootblock* bootblock )
2480{
2481 /* Switch immediately to our temporary stack, and continue. This
2482 is pretty dodgy in that it assumes that gcc does not place on
2483 the stack, anything needed to form the _start_in_C_aix5 call,
2484 since it will be on the old stack. */
2485 register UWord new_r1;
2486 new_r1 = (UWord)&VG_(interim_stack);
2487 new_r1 += VG_STACK_GUARD_SZB; /* step over lower guard page */
2488 new_r1 += VG_STACK_ACTIVE_SZB; /* step to top of active area */
2489 new_r1 -= 512; /* paranoia */
2490 __asm__ __volatile__("mr 1,%0" :/*wr*/
2491 :/*rd*/ "b"(new_r1)
2492 :/*trash*/"r1","memory");
2493 _start_in_C_aix5(bootblock);
2494 /*NOTREACHED*/
2495 VG_(exit)(0);
2496}
2497
2498#endif /* defined(VGP_ppc{32,64}_aix5) */
2499
2500
sewardjde4a1d02002-03-22 01:27:54 +00002501/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00002502/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00002503/*--------------------------------------------------------------------*/