blob: e076386d3099c7f468020007a2966674a25c471b [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00003/*--- Startup: the real stuff m_main.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00004/*--------------------------------------------------------------------*/
5
6/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjde4a1d02002-03-22 01:27:54 +00009
sewardj9eecbbb2010-05-03 21:37:12 +000010 Copyright (C) 2000-2010 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
njn25e49d8e72002-09-23 09:36:25 +000028 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000029*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000032#include "pub_core_vki.h"
sewardj17c11042006-10-15 01:26:40 +000033#include "pub_core_vkiscnums.h"
njnc7561b92005-06-19 01:24:32 +000034#include "pub_core_threadstate.h"
sewardj14c7cc52007-02-25 15:08:24 +000035#include "pub_core_xarray.h"
sewardj45f4e7c2005-09-27 19:20:21 +000036#include "pub_core_clientstate.h"
sewardj55f9d1a2005-04-25 11:11:44 +000037#include "pub_core_aspacemgr.h"
njnac1e0332009-05-08 00:39:31 +000038#include "pub_core_aspacehl.h"
sewardj45f4e7c2005-09-27 19:20:21 +000039#include "pub_core_commandline.h"
njn2521d322005-05-08 14:45:13 +000040#include "pub_core_debuglog.h"
41#include "pub_core_errormgr.h"
42#include "pub_core_execontext.h"
sewardj17c11042006-10-15 01:26:40 +000043#include "pub_core_initimg.h"
njn97405b22005-06-02 03:39:33 +000044#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000045#include "pub_core_libcassert.h"
njneb8896b2005-06-04 20:03:55 +000046#include "pub_core_libcfile.h"
njn36a20fa2005-06-03 03:08:39 +000047#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000048#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +000049#include "pub_core_libcsignal.h"
sewardj45f4e7c2005-09-27 19:20:21 +000050#include "pub_core_syscall.h" // VG_(strerror)
njnf76d27a2009-05-28 01:53:07 +000051#include "pub_core_mach.h"
njnf536bbb2005-06-13 04:21:38 +000052#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +000053#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000054#include "pub_core_options.h"
sewardjfdf91b42005-09-28 00:53:09 +000055#include "pub_core_debuginfo.h"
njnd1af0032005-05-29 17:01:48 +000056#include "pub_core_redir.h"
njnc7561b92005-06-19 01:24:32 +000057#include "pub_core_scheduler.h"
sewardjf9ebc392010-05-09 22:30:43 +000058#include "pub_core_seqmatch.h" // For VG_(string_match)
njn0c246472005-05-31 01:00:08 +000059#include "pub_core_signals.h"
njn2025cf92005-06-26 20:44:48 +000060#include "pub_core_stacks.h" // For VG_(register_stack)
njnc1b01812005-06-17 22:19:06 +000061#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +000062#include "pub_core_tooliface.h"
sewardj17c11042006-10-15 01:26:40 +000063#include "pub_core_translate.h" // For VG_(translate)
njna7598f62005-06-18 03:27:58 +000064#include "pub_core_trampoline.h"
njn8bddf582005-05-13 23:40:55 +000065#include "pub_core_transtab.h"
sewardj17c11042006-10-15 01:26:40 +000066
67/* Stuff for reading AIX5 /proc/<pid>/sysent files */
68#if defined(VGO_aix5)
69 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
70# include <sys/procfs.h> /* prsysent_t */
71 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
72# define VG_AIX5_SYSENT_SIZE 100000
73 static UChar aix5_sysent_buf[VG_AIX5_SYSENT_SIZE];
74#endif
nethercote71980f02004-01-24 18:18:54 +000075
sewardjb5f6f512005-03-10 23:59:00 +000076
nethercote71980f02004-01-24 18:18:54 +000077/*====================================================================*/
78/*=== Counters, for profiling purposes only ===*/
79/*====================================================================*/
sewardjde4a1d02002-03-22 01:27:54 +000080
nethercote3a42fb82004-08-03 18:08:50 +000081static void print_all_stats ( void )
nethercote71980f02004-01-24 18:18:54 +000082{
njn42c83552005-12-05 20:45:59 +000083 VG_(print_translation_stats)();
nethercote92e7b7f2004-08-07 17:52:25 +000084 VG_(print_tt_tc_stats)();
nethercote844e7122004-08-02 15:27:22 +000085 VG_(print_scheduler_stats)();
njn9271cbc2005-03-13 05:38:25 +000086 VG_(print_ExeContext_stats)();
sewardj12ab7652006-10-17 02:10:42 +000087 VG_(print_errormgr_stats)();
njn9271cbc2005-03-13 05:38:25 +000088
nethercote3a42fb82004-08-03 18:08:50 +000089 // Memory stats
nethercote885dd912004-08-03 23:14:00 +000090 if (VG_(clo_verbosity) > 2) {
sewardj738856f2009-07-15 14:48:32 +000091 VG_(message)(Vg_DebugMsg, "\n");
nethercote3a42fb82004-08-03 18:08:50 +000092 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +000093 "------ Valgrind's internal memory use stats follow ------\n" );
nethercote885dd912004-08-03 23:14:00 +000094 VG_(sanity_check_malloc_all)();
sewardj738856f2009-07-15 14:48:32 +000095 VG_(message)(Vg_DebugMsg, "------\n" );
nethercote3a42fb82004-08-03 18:08:50 +000096 VG_(print_all_arena_stats)();
sewardj738856f2009-07-15 14:48:32 +000097 VG_(message)(Vg_DebugMsg, "\n");
nethercote3a42fb82004-08-03 18:08:50 +000098 }
nethercote71980f02004-01-24 18:18:54 +000099}
100
101
102/*====================================================================*/
sewardj71bc3cb2005-05-19 00:25:45 +0000103/*=== Command-line: variables, processing, etc ===*/
104/*====================================================================*/
105
106// See pub_{core,tool}_options.h for explanations of all these.
107
sewardj45f4e7c2005-09-27 19:20:21 +0000108static void usage_NORETURN ( Bool debug_help )
njn7cf0bd32002-06-08 13:36:03 +0000109{
sewardj7839d112007-11-20 19:45:03 +0000110 /* 'usage1' contains a %s for the name of the GDB executable, which
111 must be supplied when it is VG_(printf)'d. */
njn25e49d8e72002-09-23 09:36:25 +0000112 Char* usage1 =
njn00cfcfc2005-11-12 18:53:50 +0000113"usage: valgrind [options] prog-and-args\n"
njn25e49d8e72002-09-23 09:36:25 +0000114"\n"
njn97db7612009-08-04 02:32:55 +0000115" tool-selection option, with default in [ ]:\n"
sewardjb5f6f512005-03-10 23:59:00 +0000116" --tool=<name> use the Valgrind tool named <name> [memcheck]\n"
njn97db7612009-08-04 02:32:55 +0000117"\n"
118" basic user options for all Valgrind tools, with defaults in [ ]:\n"
nethercotea76368b2004-06-16 11:56:29 +0000119" -h --help show this message\n"
nethercote6c999f22004-01-31 22:55:15 +0000120" --help-debug show this message, plus debugging options\n"
njn25e49d8e72002-09-23 09:36:25 +0000121" --version show version\n"
njn25e49d8e72002-09-23 09:36:25 +0000122" -q --quiet run silently; only print error msgs\n"
sewardj2d9e8742009-08-07 15:46:56 +0000123" -v --verbose be more verbose -- show misc extra info\n"
sewardj6e31f802007-11-17 22:29:25 +0000124" --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]\n"
sewardj06421272009-11-05 08:55:13 +0000125" --trace-children-skip=patt1,patt2,... specifies a list of executables\n"
126" that --trace-children=yes should not trace into\n"
njn97db7612009-08-04 02:32:55 +0000127" --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n"
nethercote0d588502004-06-21 13:27:11 +0000128" --track-fds=no|yes track open file descriptors? [no]\n"
thughes6233a382004-08-21 11:10:44 +0000129" --time-stamp=no|yes add timestamps to log messages? [no]\n"
njnce545552005-07-25 22:36:52 +0000130" --log-fd=<number> log messages to file descriptor [2=stderr]\n"
njn374a36d2007-11-23 01:41:32 +0000131" --log-file=<file> log messages to <file>\n"
njnce545552005-07-25 22:36:52 +0000132" --log-socket=ipaddr:port log messages to socket ipaddr:port\n"
nethercote2b0793f2003-12-02 10:41:18 +0000133"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000134" user options for Valgrind tools that report errors:\n"
sewardj738856f2009-07-15 14:48:32 +0000135" --xml=yes emit error output in XML (some tools only)\n"
136" --xml-fd=<number> XML output to file descriptor\n"
137" --xml-file=<file> XML output to <file>\n"
138" --xml-socket=ipaddr:port XML output to socket ipaddr:port\n"
139" --xml-user-comment=STR copy STR verbatim into XML output\n"
nethercote2b0793f2003-12-02 10:41:18 +0000140" --demangle=no|yes automatically demangle C++ names? [yes]\n"
njn20b4a152005-10-19 22:39:40 +0000141" --num-callers=<number> show <number> callers in stack traces [12]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000142" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
sewardjb9779082006-05-12 23:50:15 +0000143" --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000144" --show-below-main=no|yes continue stack traces below main() [no]\n"
145" --suppressions=<filename> suppress errors described in <filename>\n"
sewardjd153fae2005-01-10 17:24:47 +0000146" --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000147" --db-attach=no|yes start debugger when errors detected? [no]\n"
sewardj7839d112007-11-20 19:45:03 +0000148" --db-command=<command> command to start debugger [%s -nw %%f %%p]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000149" --input-fd=<number> file descriptor for input [0=stdin]\n"
njn97db7612009-08-04 02:32:55 +0000150" --dsymutil=no|yes run dsymutil on Mac OS X when helpful? [no]\n"
sewardj97724e52005-04-02 23:40:59 +0000151" --max-stackframe=<number> assume stack switch for SP changes larger\n"
152" than <number> bytes [2000000]\n"
sewardj95d86c02007-12-18 01:49:23 +0000153" --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
154" [use current 'ulimit' value]\n"
njn97db7612009-08-04 02:32:55 +0000155"\n"
156" user options for Valgrind tools that replace malloc:\n"
157" --alignment=<number> set minimum alignment of heap allocations [%ld]\n"
158"\n"
159" uncommon user options for all Valgrind tools:\n"
160" --smc-check=none|stack|all checks for self-modifying code: none,\n"
161" only for code found in stacks, or all [stack]\n"
162" --read-var-info=yes|no read debug info on stack and global variables\n"
163" and use it to print better error messages in\n"
164" tools that make use of it (Memcheck, Helgrind,\n"
bartf6122a02010-03-27 07:38:39 +0000165" DRD) [no]\n"
njn97db7612009-08-04 02:32:55 +0000166" --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
167" --sim-hints=hint1,hint2,... known hints:\n"
168" lax-ioctls, enable-outer [none]\n"
169" --kernel-variant=variant1,variant2,... known variants: bproc [none]\n"
170" handle non-standard kernel variants\n"
171" --show-emwarns=no|yes show warnings about emulation limits? [no]\n"
sewardjf9ebc392010-05-09 22:30:43 +0000172" --require-text-symbol=:sonamepattern:symbolpattern abort run if the\n"
173" stated shared object doesn't have the stated\n"
174" text symbol. Patterns can contain ? and *.\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000175"\n";
njn7cf0bd32002-06-08 13:36:03 +0000176
njn25e49d8e72002-09-23 09:36:25 +0000177 Char* usage2 =
178"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000179" debugging options for all Valgrind tools:\n"
sewardj2d9e8742009-08-07 15:46:56 +0000180" --stats=no|yes show tool and core statistics [no]\n"
njn97db7612009-08-04 02:32:55 +0000181" -d show verbose debugging output\n"
njn25e49d8e72002-09-23 09:36:25 +0000182" --sanity-level=<number> level of sanity checking to do [1]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000183" --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
184" --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
sewardj33afdb52006-01-17 02:36:40 +0000185" --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
njn25e49d8e72002-09-23 09:36:25 +0000186" --trace-syscalls=no|yes show all system calls? [no]\n"
187" --trace-signals=no|yes show signal handling details? [no]\n"
188" --trace-symtab=no|yes show symbol table details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000189" --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
sewardjce058b02005-05-01 08:55:38 +0000190" --trace-cfi=no|yes show call-frame-info details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000191" --debug-dump=syms mimic /usr/bin/readelf --syms\n"
192" --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
193" --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
sewardj0ec07f32006-01-12 12:32:32 +0000194" --trace-redir=no|yes show redirection details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000195" --trace-sched=no|yes show thread scheduler details? [no]\n"
sewardj9c606bd2008-09-18 18:12:50 +0000196" --profile-heap=no|yes profile Valgrind's own space use\n"
jsgf855d93d2003-10-13 22:26:55 +0000197" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
sewardj17c11042006-10-15 01:26:40 +0000198" --sym-offsets=yes|no show syms in form 'name+offset' ? [no]\n"
sewardjb5f6f512005-03-10 23:59:00 +0000199" --command-line-only=no|yes only use command line options [no]\n"
njn613812e2005-03-11 04:57:30 +0000200"\n"
njn97db7612009-08-04 02:32:55 +0000201" Vex options for all Valgrind tools:\n"
202" --vex-iropt-verbosity=<0..9> [0]\n"
203" --vex-iropt-level=<0..2> [2]\n"
204" --vex-iropt-precise-memory-exns=no|yes [no]\n"
205" --vex-iropt-unroll-thresh=<0..400> [120]\n"
206" --vex-guest-max-insns=<1..100> [50]\n"
207" --vex-guest-chase-thresh=<0..99> [10]\n"
sewardj540cc4a2010-01-15 10:57:57 +0000208" --vex-guest-chase-cond=no|yes [no]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000209" --trace-flags and --profile-flags values (omit the middle space):\n"
sewardj2a99cf62004-11-24 10:44:19 +0000210" 1000 0000 show conversion into IR\n"
211" 0100 0000 show after initial opt\n"
212" 0010 0000 show after instrumentation\n"
213" 0001 0000 show after second opt\n"
214" 0000 1000 show after tree building\n"
215" 0000 0100 show selecting insns\n"
216" 0000 0010 show after reg-alloc\n"
217" 0000 0001 show final assembly\n"
njn33dbfce2006-06-02 22:58:34 +0000218" (Nb: you need --trace-notbelow with --trace-flags for full details)\n"
sewardj2a99cf62004-11-24 10:44:19 +0000219"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000220" debugging options for Valgrind tools that report errors\n"
221" --dump-error=<number> show translation for basic block associated\n"
222" with <number>'th error context [0=show none]\n"
njn97db7612009-08-04 02:32:55 +0000223"\n"
224" debugging options for Valgrind tools that replace malloc:\n"
225" --trace-malloc=no|yes show client malloc details? [no]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000226"\n";
njn3e884182003-04-15 13:03:23 +0000227
228 Char* usage3 =
229"\n"
nethercote71980f02004-01-24 18:18:54 +0000230" Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
njn25e49d8e72002-09-23 09:36:25 +0000231"\n"
njn10b9aea2009-07-14 06:55:05 +0000232" %s is %s\n"
sewardj9eecbbb2010-05-03 21:37:12 +0000233" Valgrind is Copyright (C) 2000-2010, and GNU GPL'd, by Julian Seward et al.\n"
234" LibVEX is Copyright (C) 2004-2010, and GNU GPL'd, by OpenWorks LLP.\n"
njnd04b7c62002-10-03 14:05:52 +0000235"\n"
njn10b9aea2009-07-14 06:55:05 +0000236" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
njn25e49d8e72002-09-23 09:36:25 +0000237"\n";
njn7cf0bd32002-06-08 13:36:03 +0000238
sewardj12373b12007-11-20 21:38:14 +0000239 Char* gdb_path = GDB_PATH;
sewardj12373b12007-11-20 21:38:14 +0000240
njnbe9b47b2005-05-15 16:22:58 +0000241 // Ensure the message goes to stdout
sewardj738856f2009-07-15 14:48:32 +0000242 VG_(log_output_sink).fd = 1;
243 VG_(log_output_sink).is_socket = False;
njnbe9b47b2005-05-15 16:22:58 +0000244
njn97db7612009-08-04 02:32:55 +0000245 /* 'usage1' expects one char* argument and one SizeT argument. */
246 VG_(printf)(usage1, gdb_path, VG_MIN_MALLOC_SZB);
fitzhardinge98abfc72003-12-16 02:05:15 +0000247 if (VG_(details).name) {
248 VG_(printf)(" user options for %s:\n", VG_(details).name);
fitzhardinge98abfc72003-12-16 02:05:15 +0000249 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000250 VG_TDICT_CALL(tool_print_usage);
fitzhardinge98abfc72003-12-16 02:05:15 +0000251 else
252 VG_(printf)(" (none)\n");
253 }
nethercote6c999f22004-01-31 22:55:15 +0000254 if (debug_help) {
sewardjbbaef872008-11-01 23:55:32 +0000255 VG_(printf)("%s", usage2);
fitzhardinge98abfc72003-12-16 02:05:15 +0000256
nethercote6c999f22004-01-31 22:55:15 +0000257 if (VG_(details).name) {
258 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
259
260 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000261 VG_TDICT_CALL(tool_print_debug_usage);
nethercote6c999f22004-01-31 22:55:15 +0000262 else
263 VG_(printf)(" (none)\n");
264 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000265 }
njn10b9aea2009-07-14 06:55:05 +0000266 VG_(printf)(usage3, VG_(details).name, VG_(details).copyright_author,
267 VG_BUGS_TO);
nethercotef4928da2004-06-15 10:54:40 +0000268 VG_(exit)(0);
njn7cf0bd32002-06-08 13:36:03 +0000269}
sewardjde4a1d02002-03-22 01:27:54 +0000270
sewardjde4a1d02002-03-22 01:27:54 +0000271
sewardj95d86c02007-12-18 01:49:23 +0000272/* Peer at previously set up VG_(args_for_valgrind) and do some
273 minimal command line processing that must happen early on:
sewardj45f4e7c2005-09-27 19:20:21 +0000274
sewardj95d86c02007-12-18 01:49:23 +0000275 - show the version string, if requested (-v)
276 - extract any request for help (--help, -h, --help-debug)
277 - get the toolname (--tool=)
278 - set VG_(clo_max_stackframe) (--max-stackframe=)
279 - set VG_(clo_main_stacksize) (--main-stacksize=)
280
281 That's all it does. The main command line processing is done below
282 by main_process_cmd_line_options. Note that
283 main_process_cmd_line_options has to handle but ignore the ones we
284 have handled here.
285*/
286static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
287 /*OUT*/HChar** tool )
sewardj45f4e7c2005-09-27 19:20:21 +0000288{
289 UInt i;
290 HChar* str;
sewardj8b635a42004-11-22 19:01:47 +0000291
sewardj14c7cc52007-02-25 15:08:24 +0000292 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000293
sewardj14c7cc52007-02-25 15:08:24 +0000294 /* parse the options we have (only the options we care about now) */
295 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
296
297 str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000298 vg_assert(str);
nethercote71980f02004-01-24 18:18:54 +0000299
njn83df0b62009-02-25 01:01:05 +0000300 // Nb: the version string goes to stdout.
sewardj738856f2009-07-15 14:48:32 +0000301 if VG_XACT_CLO(str, "--version", VG_(log_output_sink).fd, 1) {
302 VG_(log_output_sink).is_socket = False;
sewardj45f4e7c2005-09-27 19:20:21 +0000303 VG_(printf)("valgrind-" VERSION "\n");
304 VG_(exit)(0);
njn83df0b62009-02-25 01:01:05 +0000305 }
306 else if VG_XACT_CLO(str, "--help", *need_help, 1) {}
307 else if VG_XACT_CLO(str, "-h", *need_help, 1) {}
sewardj45f4e7c2005-09-27 19:20:21 +0000308
njn83df0b62009-02-25 01:01:05 +0000309 else if VG_XACT_CLO(str, "--help-debug", *need_help, 2) {}
nethercote71980f02004-01-24 18:18:54 +0000310
sewardj45f4e7c2005-09-27 19:20:21 +0000311 // The tool has already been determined, but we need to know the name
312 // here.
njn83df0b62009-02-25 01:01:05 +0000313 else if VG_STR_CLO(str, "--tool", *tool) {}
sewardj5bdfbd22007-12-15 22:13:05 +0000314
sewardj95d86c02007-12-18 01:49:23 +0000315 // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
316 // These are needed by VG_(ii_create_image), which happens
317 // before main_process_cmd_line_options().
njn83df0b62009-02-25 01:01:05 +0000318 else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
319 else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
nethercote71980f02004-01-24 18:18:54 +0000320 }
nethercote71980f02004-01-24 18:18:54 +0000321}
322
sewardj95d86c02007-12-18 01:49:23 +0000323/* The main processing for command line options. See comments above
sewardj738856f2009-07-15 14:48:32 +0000324 on early_process_cmd_line_options.
325
326 Comments on how the logging options are handled:
327
328 User can specify:
329 --log-fd= for a fd to write to (default setting, fd = 2)
330 --log-file= for a file name to write to
331 --log-socket= for a socket to write to
332
333 As a result of examining these and doing relevant socket/file
334 opening, a final fd is established. This is stored in
335 VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
336 specified, then STR, after expansion of %p and %q templates within
337 it, is stored in VG_(clo_log_fname_expanded), in m_options, just in
338 case anybody wants to know what it is.
339
340 When printing, VG_(log_output_sink) is consulted to find the
341 fd to send output to.
342
343 Exactly analogous actions are undertaken for the XML output
344 channel, with the one difference that the default fd is -1, meaning
345 the channel is disabled by default.
sewardj95d86c02007-12-18 01:49:23 +0000346*/
sewardj738856f2009-07-15 14:48:32 +0000347static
348void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
349 /*OUT*/Char** xml_fname_unexpanded,
350 const HChar* toolname )
nethercote71980f02004-01-24 18:18:54 +0000351{
njnda033f52005-12-19 21:27:58 +0000352 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
353 // and we cannot change it until we know what we are changing it to is
354 // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
sewardj92645592005-07-23 09:18:34 +0000355 SysRes sres;
sewardj738856f2009-07-15 14:48:32 +0000356 Int i, tmp_log_fd, tmp_xml_fd;
sewardj92645592005-07-23 09:18:34 +0000357 Int toolname_len = VG_(strlen)(toolname);
njn83df0b62009-02-25 01:01:05 +0000358 Char* tmp_str; // Used in a couple of places.
njnbe9b47b2005-05-15 16:22:58 +0000359 enum {
360 VgLogTo_Fd,
361 VgLogTo_File,
njnbe9b47b2005-05-15 16:22:58 +0000362 VgLogTo_Socket
sewardj738856f2009-07-15 14:48:32 +0000363 } log_to = VgLogTo_Fd, // Where is logging output to be sent?
364 xml_to = VgLogTo_Fd; // Where is XML output to be sent?
sewardjde4a1d02002-03-22 01:27:54 +0000365
sewardj738856f2009-07-15 14:48:32 +0000366 /* Temporarily holds the string STR specified with
367 --{log,xml}-{name,socket}=STR. 'fs' stands for
368 file-or-socket. */
369 Char* log_fsname_unexpanded = NULL;
370 Char* xml_fsname_unexpanded = NULL;
371
372 /* Log to stderr by default, but usage message goes to stdout. XML
373 output is initially disabled. */
njnda033f52005-12-19 21:27:58 +0000374 tmp_log_fd = 2;
sewardj738856f2009-07-15 14:48:32 +0000375 tmp_xml_fd = -1;
376
sewardj19d81412002-06-03 01:10:40 +0000377 /* Check for sane path in ./configure --prefix=... */
fitzhardinge98abfc72003-12-16 02:05:15 +0000378 if (VG_LIBDIR[0] != '/')
sewardj17c11042006-10-15 01:26:40 +0000379 VG_(err_config_error)("Please use absolute paths in "
380 "./configure --prefix=... or --libdir=...");
sewardj38170912002-05-10 21:07:22 +0000381
sewardj14c7cc52007-02-25 15:08:24 +0000382 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000383
sewardj738856f2009-07-15 14:48:32 +0000384 /* BEGIN command-line processing loop */
385
sewardj14c7cc52007-02-25 15:08:24 +0000386 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
387
388 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000389 HChar* colon = arg;
nethercote71980f02004-01-24 18:18:54 +0000390
njn1274d242007-03-26 23:38:42 +0000391 // Look for a colon in the option name.
thughes3bfd5a02004-07-18 08:05:44 +0000392 while (*colon && *colon != ':' && *colon != '=')
393 colon++;
nethercote71980f02004-01-24 18:18:54 +0000394
njn1274d242007-03-26 23:38:42 +0000395 // Does it have the form "--toolname:foo"? We have to do it at the start
396 // in case someone has combined a prefix with a core-specific option,
397 // eg. "--memcheck:verbose".
thughes3bfd5a02004-07-18 08:05:44 +0000398 if (*colon == ':') {
njn83df0b62009-02-25 01:01:05 +0000399 if (VG_STREQN(2, arg, "--") &&
400 VG_STREQN(toolname_len, arg+2, toolname) &&
401 VG_STREQN(1, arg+2+toolname_len, ":"))
nethercote71980f02004-01-24 18:18:54 +0000402 {
njn1274d242007-03-26 23:38:42 +0000403 // Prefix matches, convert "--toolname:foo" to "--foo".
404 // Two things to note:
405 // - We cannot modify the option in-place. If we did, and then
406 // a child was spawned with --trace-children=yes, the
407 // now-non-prefixed option would be passed and could screw up
408 // the child.
409 // - We create copies, and never free them. Why? Non-prefixed
410 // options hang around forever, so tools need not make copies
411 // of strings within them. We need to have the same behaviour
412 // for prefixed options. The pointer to the copy will be lost
413 // once we leave this function (although a tool may keep a
414 // pointer into it), but the space wasted is insignificant.
415 // (In bug #142197, the copies were being freed, which caused
416 // problems for tools that reasonably assumed that arguments
417 // wouldn't disappear on them.)
nethercote71980f02004-01-24 18:18:54 +0000418 if (0)
419 VG_(printf)("tool-specific arg: %s\n", arg);
sewardj9c606bd2008-09-18 18:12:50 +0000420 arg = VG_(strdup)("main.mpclo.1", arg + toolname_len + 1);
nethercote71980f02004-01-24 18:18:54 +0000421 arg[0] = '-';
422 arg[1] = '-';
423
424 } else {
425 // prefix doesn't match, skip to next arg
426 continue;
427 }
428 }
429
fitzhardinge98abfc72003-12-16 02:05:15 +0000430 /* Ignore these options - they've already been handled */
njn83df0b62009-02-25 01:01:05 +0000431 if VG_STREQN( 7, arg, "--tool=") {}
432 else if VG_STREQN(20, arg, "--command-line-only=") {}
433 else if VG_STREQ( arg, "--") {}
434 else if VG_STREQ( arg, "-d") {}
435 else if VG_STREQN(16, arg, "--max-stackframe") {}
436 else if VG_STREQN(16, arg, "--main-stacksize") {}
437 else if VG_STREQN(14, arg, "--profile-heap") {}
nethercote27fec902004-06-16 21:26:32 +0000438
njn83df0b62009-02-25 01:01:05 +0000439 // These options are new.
440 else if (VG_STREQ(arg, "-v") ||
441 VG_STREQ(arg, "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000442 VG_(clo_verbosity)++;
nethercote27fec902004-06-16 21:26:32 +0000443
njn83df0b62009-02-25 01:01:05 +0000444 else if (VG_STREQ(arg, "-q") ||
445 VG_STREQ(arg, "--quiet"))
sewardjde4a1d02002-03-22 01:27:54 +0000446 VG_(clo_verbosity)--;
447
sewardj2d9e8742009-08-07 15:46:56 +0000448 else if VG_BOOL_CLO(arg, "--stats", VG_(clo_stats)) {}
njn83df0b62009-02-25 01:01:05 +0000449 else if VG_BOOL_CLO(arg, "--xml", VG_(clo_xml)) {}
450 else if VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach)) {}
451 else if VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle)) {}
452 else if VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit)) {}
453 else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
454 else if VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns)) {}
sewardj95d86c02007-12-18 01:49:23 +0000455
njn83df0b62009-02-25 01:01:05 +0000456 else if VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres)) {}
457 else if VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main)) {}
458 else if VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp)) {}
459 else if VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds)) {}
460 else if VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children)) {}
461 else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
462 VG_(clo_child_silent_after_fork)) {}
463 else if VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched)) {}
464 else if VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals)) {}
465 else if VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab)) {}
466 else if VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt)) {}
467 else if VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi)) {}
468 else if VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms),
469 True) {}
470 else if VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line),
471 True) {}
472 else if VG_XACT_CLO(arg, "--debug-dump=frames",
473 VG_(clo_debug_dump_frames), True) {}
474 else if VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir)) {}
sewardj95d86c02007-12-18 01:49:23 +0000475
njn83df0b62009-02-25 01:01:05 +0000476 else if VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls)) {}
477 else if VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb)) {}
478 else if VG_STR_CLO (arg, "--db-command", VG_(clo_db_command)) {}
479 else if VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints)) {}
480 else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
481 else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
sewardjf767d962007-02-12 17:47:14 +0000482
njn83df0b62009-02-25 01:01:05 +0000483 else if VG_INT_CLO (arg, "--dump-error", VG_(clo_dump_error)) {}
484 else if VG_INT_CLO (arg, "--input-fd", VG_(clo_input_fd)) {}
485 else if VG_INT_CLO (arg, "--sanity-level", VG_(clo_sanity_level)) {}
486 else if VG_BINT_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
487 VG_DEEPEST_BACKTRACE) {}
sewardjde4a1d02002-03-22 01:27:54 +0000488
njn83df0b62009-02-25 01:01:05 +0000489 else if VG_XACT_CLO(arg, "--smc-check=none", VG_(clo_smc_check),
490 Vg_SmcNone);
491 else if VG_XACT_CLO(arg, "--smc-check=stack", VG_(clo_smc_check),
492 Vg_SmcStack);
493 else if VG_XACT_CLO(arg, "--smc-check=all", VG_(clo_smc_check),
494 Vg_SmcAll);
sewardjde4a1d02002-03-22 01:27:54 +0000495
njn97db7612009-08-04 02:32:55 +0000496 else if VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant)) {}
sewardj26412bd2005-07-07 10:05:05 +0000497
njn97db7612009-08-04 02:32:55 +0000498 else if VG_BOOL_CLO(arg, "--dsymutil", VG_(clo_dsymutil)) {}
njnf76d27a2009-05-28 01:53:07 +0000499
sewardj06421272009-11-05 08:55:13 +0000500 else if VG_STR_CLO (arg, "--trace-children-skip", VG_(clo_trace_children_skip)) {}
501
njn83df0b62009-02-25 01:01:05 +0000502 else if VG_BINT_CLO(arg, "--vex-iropt-verbosity",
503 VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
504 else if VG_BINT_CLO(arg, "--vex-iropt-level",
505 VG_(clo_vex_control).iropt_level, 0, 2) {}
506 else if VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
507 VG_(clo_vex_control).iropt_precise_memory_exns) {}
508 else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
509 VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
510 else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
511 VG_(clo_vex_control).guest_max_insns, 1, 100) {}
512 else if VG_BINT_CLO(arg, "--vex-guest-chase-thresh",
513 VG_(clo_vex_control).guest_chase_thresh, 0, 99) {}
sewardj540cc4a2010-01-15 10:57:57 +0000514 else if VG_BOOL_CLO(arg, "--vex-guest-chase-cond",
515 VG_(clo_vex_control).guest_chase_cond) {}
sewardj94c8eb42008-09-19 20:13:39 +0000516
njn83df0b62009-02-25 01:01:05 +0000517 else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
518 log_to = VgLogTo_Fd;
sewardj738856f2009-07-15 14:48:32 +0000519 log_fsname_unexpanded = NULL;
520 }
521 else if VG_INT_CLO(arg, "--xml-fd", tmp_xml_fd) {
522 xml_to = VgLogTo_Fd;
523 xml_fsname_unexpanded = NULL;
sewardj4cf05692002-10-27 20:28:29 +0000524 }
525
sewardj738856f2009-07-15 14:48:32 +0000526 else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000527 log_to = VgLogTo_File;
sewardj4cf05692002-10-27 20:28:29 +0000528 }
sewardj738856f2009-07-15 14:48:32 +0000529 else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) {
530 xml_to = VgLogTo_File;
531 }
532
533 else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000534 log_to = VgLogTo_Socket;
sewardj73cf3bc2002-11-03 03:20:15 +0000535 }
sewardj738856f2009-07-15 14:48:32 +0000536 else if VG_STR_CLO(arg, "--xml-socket", xml_fsname_unexpanded) {
537 xml_to = VgLogTo_Socket;
538 }
sewardj73cf3bc2002-11-03 03:20:15 +0000539
njn83df0b62009-02-25 01:01:05 +0000540 else if VG_STR_CLO(arg, "--xml-user-comment",
541 VG_(clo_xml_user_comment)) {}
sewardj768db0e2005-07-19 14:18:56 +0000542
njn83df0b62009-02-25 01:01:05 +0000543 else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
sewardjde4a1d02002-03-22 01:27:54 +0000544 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
sewardjf9ebc392010-05-09 22:30:43 +0000545 VG_(message)(Vg_UserMsg,
546 "Too many suppression files specified.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000547 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +0000548 "Increase VG_CLO_MAX_SFILES and recompile.\n");
sewardj17c11042006-10-15 01:26:40 +0000549 VG_(err_bad_option)(arg);
sewardjde4a1d02002-03-22 01:27:54 +0000550 }
njn83df0b62009-02-25 01:01:05 +0000551 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = tmp_str;
sewardjde4a1d02002-03-22 01:27:54 +0000552 VG_(clo_n_suppressions)++;
553 }
sewardjde4a1d02002-03-22 01:27:54 +0000554
sewardjf9ebc392010-05-09 22:30:43 +0000555 else if VG_STR_CLO(arg, "--require-text-symbol", tmp_str) {
556 if (VG_(clo_n_req_tsyms) >= VG_CLO_MAX_REQ_TSYMS) {
557 VG_(message)(Vg_UserMsg,
558 "Too many --require-text-symbol= specifications.\n");
559 VG_(message)(Vg_UserMsg,
560 "Increase VG_CLO_MAX_REQ_TSYMS and recompile.\n");
561 VG_(err_bad_option)(arg);
562 }
563 /* String needs to be of the form C?*C?*, where C is any
564 character, but is the same both times. Having it in this
565 form facilitates finding the boundary between the sopatt
566 and the fnpatt just by looking for the second occurrence
567 of C, without hardwiring any assumption about what C
568 is. */
569 Char patt[7];
570 Bool ok = True;
571 ok = tmp_str && VG_(strlen)(tmp_str) > 0;
572 if (ok) {
573 patt[0] = patt[3] = tmp_str[0];
574 patt[1] = patt[4] = '?';
575 patt[2] = patt[5] = '*';
576 patt[6] = 0;
577 ok = VG_(string_match)(patt, tmp_str);
578 }
579 if (!ok) {
580 VG_(message)(Vg_UserMsg,
581 "Invalid --require-text-symbol= specification.\n");
582 VG_(err_bad_option)(arg);
583 }
584 VG_(clo_req_tsyms)[VG_(clo_n_req_tsyms)] = tmp_str;
585 VG_(clo_n_req_tsyms)++;
586 }
587
sewardjfa8ec112005-01-19 11:55:34 +0000588 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000589 else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
sewardjfa8ec112005-01-19 11:55:34 +0000590 Int j;
sewardjfa8ec112005-01-19 11:55:34 +0000591
njn83df0b62009-02-25 01:01:05 +0000592 if (8 != VG_(strlen)(tmp_str)) {
sewardjfa8ec112005-01-19 11:55:34 +0000593 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +0000594 "--trace-flags argument must have 8 digits\n");
sewardj17c11042006-10-15 01:26:40 +0000595 VG_(err_bad_option)(arg);
sewardjfa8ec112005-01-19 11:55:34 +0000596 }
597 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000598 if ('0' == tmp_str[j]) { /* do nothing */ }
599 else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
sewardjfa8ec112005-01-19 11:55:34 +0000600 else {
601 VG_(message)(Vg_UserMsg, "--trace-flags argument can only "
sewardj738856f2009-07-15 14:48:32 +0000602 "contain 0s and 1s\n");
sewardj17c11042006-10-15 01:26:40 +0000603 VG_(err_bad_option)(arg);
sewardjfa8ec112005-01-19 11:55:34 +0000604 }
605 }
606 }
607
608 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000609 else if VG_STR_CLO(arg, "--profile-flags", tmp_str) {
njn25e49d8e72002-09-23 09:36:25 +0000610 Int j;
njn25e49d8e72002-09-23 09:36:25 +0000611
njn83df0b62009-02-25 01:01:05 +0000612 if (8 != VG_(strlen)(tmp_str)) {
njn25e49d8e72002-09-23 09:36:25 +0000613 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +0000614 "--profile-flags argument must have 8 digits\n");
sewardj17c11042006-10-15 01:26:40 +0000615 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000616 }
sewardj8b635a42004-11-22 19:01:47 +0000617 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000618 if ('0' == tmp_str[j]) { /* do nothing */ }
619 else if ('1' == tmp_str[j]) VG_(clo_profile_flags) |= (1 << (7-j));
njn25e49d8e72002-09-23 09:36:25 +0000620 else {
sewardjfa8ec112005-01-19 11:55:34 +0000621 VG_(message)(Vg_UserMsg, "--profile-flags argument can only "
sewardj738856f2009-07-15 14:48:32 +0000622 "contain 0s and 1s\n");
sewardj17c11042006-10-15 01:26:40 +0000623 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000624 }
625 }
626 }
sewardjde4a1d02002-03-22 01:27:54 +0000627
njn83df0b62009-02-25 01:01:05 +0000628 else if VG_INT_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow)) {}
sewardjc771b292004-11-30 18:55:21 +0000629
njn83df0b62009-02-25 01:01:05 +0000630 else if VG_XACT_CLO(arg, "--gen-suppressions=no",
631 VG_(clo_gen_suppressions), 0) {}
632 else if VG_XACT_CLO(arg, "--gen-suppressions=yes",
633 VG_(clo_gen_suppressions), 1) {}
634 else if VG_XACT_CLO(arg, "--gen-suppressions=all",
635 VG_(clo_gen_suppressions), 2) {}
sewardjd153fae2005-01-10 17:24:47 +0000636
nethercote71980f02004-01-24 18:18:54 +0000637 else if ( ! VG_(needs).command_line_options
njn51d827b2005-05-09 01:02:08 +0000638 || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
sewardj17c11042006-10-15 01:26:40 +0000639 VG_(err_bad_option)(arg);
njn25e49d8e72002-09-23 09:36:25 +0000640 }
sewardjde4a1d02002-03-22 01:27:54 +0000641 }
642
sewardj738856f2009-07-15 14:48:32 +0000643 /* END command-line processing loop */
644
sewardj998d40d2004-12-06 14:24:52 +0000645 /* Make VEX control parameters sane */
646
647 if (VG_(clo_vex_control).guest_chase_thresh
648 >= VG_(clo_vex_control).guest_max_insns)
649 VG_(clo_vex_control).guest_chase_thresh
650 = VG_(clo_vex_control).guest_max_insns - 1;
651
652 if (VG_(clo_vex_control).guest_chase_thresh < 0)
653 VG_(clo_vex_control).guest_chase_thresh = 0;
654
655 /* Check various option values */
nethercote27fec902004-06-16 21:26:32 +0000656
njnf9ebf672003-05-12 21:41:30 +0000657 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +0000658 VG_(clo_verbosity) = 0;
659
njnbe9b47b2005-05-15 16:22:58 +0000660 if (VG_(clo_gen_suppressions) > 0 &&
661 !VG_(needs).core_errors && !VG_(needs).tool_errors) {
662 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +0000663 "Can't use --gen-suppressions= with this tool,\n");
njnbe9b47b2005-05-15 16:22:58 +0000664 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +0000665 "as it doesn't generate errors.\n");
sewardj17c11042006-10-15 01:26:40 +0000666 VG_(err_bad_option)("--gen-suppressions=");
njnbe9b47b2005-05-15 16:22:58 +0000667 }
668
sewardj738856f2009-07-15 14:48:32 +0000669 /* If XML output is requested, check that the tool actually
670 supports it. */
671 if (VG_(clo_xml) && !VG_(needs).xml_output) {
672 VG_(clo_xml) = False;
673 VG_(message)(Vg_UserMsg,
674 "%s does not support XML output.\n", VG_(details).name);
675 VG_(err_bad_option)("--xml=yes");
676 /*NOTREACHED*/
677 }
678
679 vg_assert( VG_(clo_gen_suppressions) >= 0 );
680 vg_assert( VG_(clo_gen_suppressions) <= 2 );
681
sewardj71bc3cb2005-05-19 00:25:45 +0000682 /* If we've been asked to emit XML, mash around various other
683 options so as to constrain the output somewhat, and to remove
sewardj738856f2009-07-15 14:48:32 +0000684 any need for user input during the run.
685 */
sewardj71bc3cb2005-05-19 00:25:45 +0000686 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +0000687
688 /* We can't allow --gen-suppressions=yes, since that requires us
689 to print the error and then ask the user if she wants a
690 suppression for it, but in XML mode we won't print it until
691 we know whether we also need to print a suppression. Hence a
692 circular dependency. So disallow this.
693 (--gen-suppressions=all is still OK since we don't need any
694 user interaction in this case.) */
695 if (VG_(clo_gen_suppressions) == 1) {
696 VG_(umsg)(
697 "When --xml=yes is specified, only --gen-suppressions=no\n"
698 "or --gen-suppressions=all are allowed, but not "
699 "--gen-suppressions=yes.\n");
700 /* FIXME: this is really a misuse of VG_(err_bad_option). */
701 VG_(err_bad_option)(
702 "--xml=yes together with --gen-suppressions=yes");
703 }
704
705 /* We can't allow DB attaching (or we maybe could, but results
706 could be chaotic ..) since it requires user input. Hence
707 disallow. */
708 if (VG_(clo_db_attach)) {
709 VG_(umsg)("--db-attach=yes is not allowed in XML mode,\n"
710 "as it would require user input.\n");
711 /* FIXME: this is really a misuse of VG_(err_bad_option). */
712 VG_(err_bad_option)(
713 "--xml=yes together with --db-attach=yes");
714 }
715
716 /* Disallow dump_error in XML mode; sounds like a recipe for
717 chaos. No big deal; dump_error is a flag for debugging V
718 itself. */
719 if (VG_(clo_dump_error) > 0) {
720 /* FIXME: this is really a misuse of VG_(err_bad_option). */
721 VG_(err_bad_option)(
722 "--xml=yes together with --dump-error=");
723 }
724
sewardj71bc3cb2005-05-19 00:25:45 +0000725 /* Disable error limits (this might be a bad idea!) */
726 VG_(clo_error_limit) = False;
727 /* Disable emulation warnings */
sewardj738856f2009-07-15 14:48:32 +0000728
sewardj71bc3cb2005-05-19 00:25:45 +0000729 /* Also, we want to set options for the leak checker, but that
730 will have to be done in Memcheck's flag-handling code, not
731 here. */
732 }
733
njnbe9b47b2005-05-15 16:22:58 +0000734 /* All non-logging-related options have been checked. If the logging
735 option specified is ok, we can switch to it, as we know we won't
736 have to generate any other command-line-related error messages.
737 (So far we should be still attached to stderr, so we can show on
738 the terminal any problems to do with processing command line
739 opts.)
740
sewardj738856f2009-07-15 14:48:32 +0000741 So set up logging now. After this is done, VG_(log_output_sink)
742 and (if relevant) VG_(xml_output_sink) should be connected to
743 whatever sink has been selected, and we indiscriminately chuck
744 stuff into it without worrying what the nature of it is. Oh the
745 wonder of Unix streams. */
sewardj4cf05692002-10-27 20:28:29 +0000746
sewardj738856f2009-07-15 14:48:32 +0000747 vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
748 vg_assert(VG_(log_output_sink).is_socket == False);
749 vg_assert(VG_(clo_log_fname_expanded) == NULL);
750
751 vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
752 vg_assert(VG_(xml_output_sink).is_socket == False);
753 vg_assert(VG_(clo_xml_fname_expanded) == NULL);
754
755 /* --- set up the normal text output channel --- */
sewardj4cf05692002-10-27 20:28:29 +0000756
njnbe9b47b2005-05-15 16:22:58 +0000757 switch (log_to) {
sewardj73cf3bc2002-11-03 03:20:15 +0000758
sewardj4cf05692002-10-27 20:28:29 +0000759 case VgLogTo_Fd:
sewardj738856f2009-07-15 14:48:32 +0000760 vg_assert(log_fsname_unexpanded == NULL);
sewardj4cf05692002-10-27 20:28:29 +0000761 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000762
sewardj4cf05692002-10-27 20:28:29 +0000763 case VgLogTo_File: {
njn374a36d2007-11-23 01:41:32 +0000764 Char* logfilename;
jsgff3c3f1a2003-10-14 22:13:28 +0000765
sewardj738856f2009-07-15 14:48:32 +0000766 vg_assert(log_fsname_unexpanded != NULL);
767 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +0000768
njn374a36d2007-11-23 01:41:32 +0000769 // Nb: we overwrite an existing file of this name without asking
770 // any questions.
sewardj738856f2009-07-15 14:48:32 +0000771 logfilename = VG_(expand_file_name)("--log-file",
772 log_fsname_unexpanded);
njn374a36d2007-11-23 01:41:32 +0000773 sres = VG_(open)(logfilename,
njnda033f52005-12-19 21:27:58 +0000774 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
775 VKI_S_IRUSR|VKI_S_IWUSR);
njncda2f0f2009-05-18 02:12:08 +0000776 if (!sr_isError(sres)) {
777 tmp_log_fd = sr_Res(sres);
sewardj738856f2009-07-15 14:48:32 +0000778 VG_(clo_log_fname_expanded) = logfilename;
njnbe9b47b2005-05-15 16:22:58 +0000779 } else {
sewardj603d4102005-01-11 14:01:02 +0000780 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +0000781 "Can't create log file '%s' (%s); giving up!\n",
njncda2f0f2009-05-18 02:12:08 +0000782 logfilename, VG_(strerror)(sr_Err(sres)));
sewardj17c11042006-10-15 01:26:40 +0000783 VG_(err_bad_option)(
njn374a36d2007-11-23 01:41:32 +0000784 "--log-file=<file> (didn't work out for some reason.)");
sewardj603d4102005-01-11 14:01:02 +0000785 /*NOTREACHED*/
njn374a36d2007-11-23 01:41:32 +0000786 }
sewardj738856f2009-07-15 14:48:32 +0000787 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000788 }
789
790 case VgLogTo_Socket: {
sewardj738856f2009-07-15 14:48:32 +0000791 vg_assert(log_fsname_unexpanded != NULL);
792 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
793 tmp_log_fd = VG_(connect_via_socket)( log_fsname_unexpanded );
njnda033f52005-12-19 21:27:58 +0000794 if (tmp_log_fd == -1) {
sewardj73cf3bc2002-11-03 03:20:15 +0000795 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +0000796 "Invalid --log-socket=ipaddr or "
797 "--log-socket=ipaddr:port spec\n");
sewardj73cf3bc2002-11-03 03:20:15 +0000798 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +0000799 "of '%s'; giving up!\n", log_fsname_unexpanded );
sewardj17c11042006-10-15 01:26:40 +0000800 VG_(err_bad_option)(
nethercotef8548672004-06-21 12:42:35 +0000801 "--log-socket=");
njnbe9b47b2005-05-15 16:22:58 +0000802 /*NOTREACHED*/
sewardj4cf05692002-10-27 20:28:29 +0000803 }
njnda033f52005-12-19 21:27:58 +0000804 if (tmp_log_fd == -2) {
sewardj73cf3bc2002-11-03 03:20:15 +0000805 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +0000806 "valgrind: failed to connect to logging server '%s'.\n",
807 log_fsname_unexpanded );
sewardj570f8902002-11-03 11:44:36 +0000808 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +0000809 "Log messages will sent to stderr instead.\n" );
sewardj570f8902002-11-03 11:44:36 +0000810 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +0000811 "\n" );
sewardj570f8902002-11-03 11:44:36 +0000812 /* We don't change anything here. */
sewardj738856f2009-07-15 14:48:32 +0000813 vg_assert(VG_(log_output_sink).fd == 2);
njnda033f52005-12-19 21:27:58 +0000814 tmp_log_fd = 2;
sewardj570f8902002-11-03 11:44:36 +0000815 } else {
njnda033f52005-12-19 21:27:58 +0000816 vg_assert(tmp_log_fd > 0);
sewardj738856f2009-07-15 14:48:32 +0000817 VG_(log_output_sink).is_socket = True;
sewardj570f8902002-11-03 11:44:36 +0000818 }
sewardj73cf3bc2002-11-03 03:20:15 +0000819 break;
820 }
sewardj4cf05692002-10-27 20:28:29 +0000821 }
822
sewardj738856f2009-07-15 14:48:32 +0000823 /* --- set up the XML output channel --- */
sewardj71bc3cb2005-05-19 00:25:45 +0000824
sewardj738856f2009-07-15 14:48:32 +0000825 switch (xml_to) {
826
827 case VgLogTo_Fd:
828 vg_assert(xml_fsname_unexpanded == NULL);
829 break;
830
831 case VgLogTo_File: {
832 Char* xmlfilename;
833
834 vg_assert(xml_fsname_unexpanded != NULL);
835 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
836
837 // Nb: we overwrite an existing file of this name without asking
838 // any questions.
839 xmlfilename = VG_(expand_file_name)("--xml-file",
840 xml_fsname_unexpanded);
841 sres = VG_(open)(xmlfilename,
842 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
843 VKI_S_IRUSR|VKI_S_IWUSR);
844 if (!sr_isError(sres)) {
845 tmp_xml_fd = sr_Res(sres);
846 VG_(clo_xml_fname_expanded) = xmlfilename;
847 /* strdup here is probably paranoid overkill, but ... */
848 *xml_fname_unexpanded = VG_(strdup)( "main.mpclo.2",
849 xml_fsname_unexpanded );
850 } else {
851 VG_(message)(Vg_UserMsg,
852 "Can't create XML file '%s' (%s); giving up!\n",
853 xmlfilename, VG_(strerror)(sr_Err(sres)));
854 VG_(err_bad_option)(
855 "--xml-file=<file> (didn't work out for some reason.)");
856 /*NOTREACHED*/
857 }
858 break;
859 }
860
861 case VgLogTo_Socket: {
862 vg_assert(xml_fsname_unexpanded != NULL);
863 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
864 tmp_xml_fd = VG_(connect_via_socket)( xml_fsname_unexpanded );
865 if (tmp_xml_fd == -1) {
866 VG_(message)(Vg_UserMsg,
867 "Invalid --xml-socket=ipaddr or "
868 "--xml-socket=ipaddr:port spec\n");
869 VG_(message)(Vg_UserMsg,
870 "of '%s'; giving up!\n", xml_fsname_unexpanded );
871 VG_(err_bad_option)(
872 "--xml-socket=");
873 /*NOTREACHED*/
874 }
875 if (tmp_xml_fd == -2) {
876 VG_(message)(Vg_UserMsg,
877 "valgrind: failed to connect to XML logging server '%s'.\n",
878 xml_fsname_unexpanded );
879 VG_(message)(Vg_UserMsg,
880 "XML output will sent to stderr instead.\n" );
881 VG_(message)(Vg_UserMsg,
882 "\n" );
883 /* We don't change anything here. */
884 vg_assert(VG_(xml_output_sink).fd == 2);
885 tmp_xml_fd = 2;
886 } else {
887 vg_assert(tmp_xml_fd > 0);
888 VG_(xml_output_sink).is_socket = True;
889 }
890 break;
891 }
sewardj71bc3cb2005-05-19 00:25:45 +0000892 }
893
sewardj738856f2009-07-15 14:48:32 +0000894 /* If we've got this far, and XML mode was requested, but no XML
895 output channel appears to have been specified, just stop. We
896 could continue, and XML output will simply vanish into nowhere,
897 but that is likely to confuse the hell out of users, which is
898 distinctly Ungood. */
899 if (VG_(clo_xml) && tmp_xml_fd == -1) {
900 VG_(umsg)(
901 "--xml=yes has been specified, but there is no XML output\n"
902 "destination. You must specify an XML output destination\n"
903 "using --xml-fd=, --xml-file= or --xml=socket=.\n" );
904 /* FIXME: this is really a misuse of VG_(err_bad_option). */
905 VG_(err_bad_option)(
906 "--xml=yes, but no XML destination specified");
907 }
908
909 // Finalise the output fds: the log fd ..
910
njnda033f52005-12-19 21:27:58 +0000911 if (tmp_log_fd >= 0) {
sewardj738856f2009-07-15 14:48:32 +0000912 // Move log_fd into the safe range, so it doesn't conflict with
913 // any app fds.
njnda033f52005-12-19 21:27:58 +0000914 tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
915 if (tmp_log_fd < 0) {
sewardj738856f2009-07-15 14:48:32 +0000916 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd "
917 "into safe range, using stderr\n");
918 VG_(log_output_sink).fd = 2; // stderr
919 VG_(log_output_sink).is_socket = False;
njnda033f52005-12-19 21:27:58 +0000920 } else {
sewardj738856f2009-07-15 14:48:32 +0000921 VG_(log_output_sink).fd = tmp_log_fd;
922 VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
njnda033f52005-12-19 21:27:58 +0000923 }
924 } else {
925 // If they said --log-fd=-1, don't print anything. Plausible for use in
926 // regression testing suites that use client requests to count errors.
sewardj738856f2009-07-15 14:48:32 +0000927 VG_(log_output_sink).fd = -1;
928 VG_(log_output_sink).is_socket = False;
jsgf855d93d2003-10-13 22:26:55 +0000929 }
930
sewardj738856f2009-07-15 14:48:32 +0000931 // Finalise the output fds: and the XML fd ..
932
933 if (tmp_xml_fd >= 0) {
934 // Move xml_fd into the safe range, so it doesn't conflict with
935 // any app fds.
936 tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
937 if (tmp_xml_fd < 0) {
938 VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd "
939 "into safe range, using stderr\n");
940 VG_(xml_output_sink).fd = 2; // stderr
941 VG_(xml_output_sink).is_socket = False;
942 } else {
943 VG_(xml_output_sink).fd = tmp_xml_fd;
944 VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
945 }
946 } else {
947 // If they said --xml-fd=-1, don't print anything. Plausible for use in
948 // regression testing suites that use client requests to count errors.
949 VG_(xml_output_sink).fd = -1;
950 VG_(xml_output_sink).is_socket = False;
951 }
952
953 // Suppressions related stuff
954
sewardj45f4e7c2005-09-27 19:20:21 +0000955 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
956 (VG_(needs).core_errors || VG_(needs).tool_errors)) {
957 /* If we haven't reached the max number of suppressions, load
958 the default one. */
959 static const Char default_supp[] = "default.supp";
960 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
sewardj738856f2009-07-15 14:48:32 +0000961 Char *buf = VG_(arena_malloc)(VG_AR_CORE, "main.mpclo.3", len);
sewardj45f4e7c2005-09-27 19:20:21 +0000962 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
963 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
964 VG_(clo_n_suppressions)++;
965 }
sewardjde4a1d02002-03-22 01:27:54 +0000966
sewardj738856f2009-07-15 14:48:32 +0000967 *logging_to_fd = log_to == VgLogTo_Fd || log_to == VgLogTo_Socket;
sewardj45f4e7c2005-09-27 19:20:21 +0000968}
969
sewardj4efbaa72008-06-04 06:51:58 +0000970// Write the name and value of log file qualifiers to the xml file.
971static void print_file_vars(Char* format)
972{
973 Int i = 0;
974
975 while (format[i]) {
976 if (format[i] == '%') {
977 // We saw a '%'. What's next...
978 i++;
979 if ('q' == format[i]) {
980 i++;
981 if ('{' == format[i]) {
982 // Get the env var name, print its contents.
983 Char* qualname;
984 Char* qual;
985 i++;
986 qualname = &format[i];
987 while (True) {
988 if ('}' == format[i]) {
989 // Temporarily replace the '}' with NUL to extract var
990 // name.
991 format[i] = 0;
992 qual = VG_(getenv)(qualname);
993 break;
994 }
995 i++;
996 }
997
sewardj7ca100d2009-08-15 23:05:34 +0000998 VG_(printf_xml_no_f_c)(
999 "<logfilequalifier> <var>%t</var> "
1000 "<value>%t</value> </logfilequalifier>\n",
1001 qualname,qual
1002 );
sewardj4efbaa72008-06-04 06:51:58 +00001003 format[i] = '}';
1004 i++;
1005 }
1006 }
1007 } else {
1008 i++;
1009 }
1010 }
1011}
1012
sewardj45f4e7c2005-09-27 19:20:21 +00001013
1014/*====================================================================*/
1015/*=== Printing the preamble ===*/
1016/*====================================================================*/
1017
njnf8a11cf2009-08-02 23:03:06 +00001018// Print the command, escaping any chars that require it.
barta3054f52010-06-14 18:12:56 +00001019static void umsg_or_xml_arg(const Char* arg,
njnf8a11cf2009-08-02 23:03:06 +00001020 UInt (*umsg_or_xml)( const HChar*, ... ) )
1021{
1022 SizeT len = VG_(strlen)(arg);
1023 Char* special = " \\<>";
1024 Int i;
1025 for (i = 0; i < len; i++) {
1026 if (VG_(strchr)(special, arg[i])) {
1027 umsg_or_xml("\\"); // escape with a backslash if necessary
1028 }
1029 umsg_or_xml("%c", arg[i]);
1030 }
1031}
1032
sewardj45f4e7c2005-09-27 19:20:21 +00001033/* Ok, the logging sink is running now. Print a suitable preamble.
1034 If logging to file or a socket, write details of parent PID and
1035 command line args, to help people trying to interpret the
1036 results of a run which encompasses multiple processes. */
sewardj738856f2009-07-15 14:48:32 +00001037static void print_preamble ( Bool logging_to_fd,
1038 Char* xml_fname_unexpanded,
1039 const HChar* toolname )
sewardj45f4e7c2005-09-27 19:20:21 +00001040{
sewardj738856f2009-07-15 14:48:32 +00001041 Int i;
tom60a4b0b2005-10-12 10:45:27 +00001042 HChar* xpre = VG_(clo_xml) ? " <line>" : "";
1043 HChar* xpost = VG_(clo_xml) ? "</line>" : "";
sewardj738856f2009-07-15 14:48:32 +00001044 UInt (*umsg_or_xml)( const HChar*, ... )
1045 = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
tom60a4b0b2005-10-12 10:45:27 +00001046
sewardj14c7cc52007-02-25 15:08:24 +00001047 vg_assert( VG_(args_for_client) );
1048 vg_assert( VG_(args_for_valgrind) );
sewardj99a2ceb2007-11-09 12:30:36 +00001049 vg_assert( toolname );
sewardj14c7cc52007-02-25 15:08:24 +00001050
sewardj71bc3cb2005-05-19 00:25:45 +00001051 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001052 VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
1053 VG_(printf_xml)("\n");
1054 VG_(printf_xml)("<valgrindoutput>\n");
1055 VG_(printf_xml)("\n");
1056 VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
1057 VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", toolname);
1058 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001059 }
1060
sewardj738856f2009-07-15 14:48:32 +00001061 if (VG_(clo_xml) || VG_(clo_verbosity > 0)) {
sewardjd7bddad2005-06-13 16:48:32 +00001062
1063 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001064 VG_(printf_xml)("<preamble>\n");
sewardjd7bddad2005-06-13 16:48:32 +00001065
nethercote996901a2004-08-03 13:29:09 +00001066 /* Tool details */
njnb6267bd2009-08-12 00:14:16 +00001067 umsg_or_xml( "%s%s%s%s, %s%s\n",
sewardj71bc3cb2005-05-19 00:25:45 +00001068 xpre,
njnd04b7c62002-10-03 14:05:52 +00001069 VG_(details).name,
njnb9c427c2004-12-01 14:14:42 +00001070 NULL == VG_(details).version ? "" : "-",
njnd04b7c62002-10-03 14:05:52 +00001071 NULL == VG_(details).version
1072 ? (Char*)"" : VG_(details).version,
sewardj71bc3cb2005-05-19 00:25:45 +00001073 VG_(details).description,
sewardj738856f2009-07-15 14:48:32 +00001074 xpost );
sewardj99a2ceb2007-11-09 12:30:36 +00001075
njn10b9aea2009-07-14 06:55:05 +00001076 if (VG_(strlen)(toolname) >= 4 && VG_STREQN(4, toolname, "exp-")) {
sewardj738856f2009-07-15 14:48:32 +00001077 umsg_or_xml(
njnb6267bd2009-08-12 00:14:16 +00001078 "%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
sewardj99a2ceb2007-11-09 12:30:36 +00001079 xpre, xpost
1080 );
1081 }
1082
njnf3977a32009-08-04 00:27:56 +00001083 umsg_or_xml("%s%s%s\n", xpre, VG_(details).copyright_author, xpost);
sewardj3b2736a2002-03-24 12:18:35 +00001084
njnd04b7c62002-10-03 14:05:52 +00001085 /* Core details */
sewardj738856f2009-07-15 14:48:32 +00001086 umsg_or_xml(
njnf73d87f2009-07-24 04:47:04 +00001087 "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
1088 xpre, VERSION, xpost
sewardj738856f2009-07-15 14:48:32 +00001089 );
sewardj45f4e7c2005-09-27 19:20:21 +00001090
njnf3977a32009-08-04 00:27:56 +00001091 // Print the command line. At one point we wrapped at 80 chars and
1092 // printed a '\' as a line joiner, but that makes it hard to cut and
1093 // paste the command line (because of the "==pid==" prefixes), so we now
1094 // favour utility and simplicity over aesthetics.
1095 umsg_or_xml("%sCommand: ", xpre);
njn53162bf2009-07-29 23:34:49 +00001096 if (VG_(args_the_exename))
njnf8a11cf2009-08-02 23:03:06 +00001097 umsg_or_xml_arg(VG_(args_the_exename), umsg_or_xml);
njn53162bf2009-07-29 23:34:49 +00001098 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1099 HChar* s = *(HChar**)VG_(indexXA)( VG_(args_for_client), i );
njnf8a11cf2009-08-02 23:03:06 +00001100 umsg_or_xml(" ");
1101 umsg_or_xml_arg(s, umsg_or_xml);
njn53162bf2009-07-29 23:34:49 +00001102 }
njnf3977a32009-08-04 00:27:56 +00001103 umsg_or_xml("%s\n", xpost);
njn53162bf2009-07-29 23:34:49 +00001104
sewardjd7bddad2005-06-13 16:48:32 +00001105 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001106 VG_(printf_xml)("</preamble>\n");
njnd04b7c62002-10-03 14:05:52 +00001107 }
1108
njnb6267bd2009-08-12 00:14:16 +00001109 // Print the parent PID, and other stuff, if necessary.
sewardj45f4e7c2005-09-27 19:20:21 +00001110 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
njn305dc002009-07-30 23:36:43 +00001111 VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
sewardj4cf05692002-10-27 20:28:29 +00001112 }
sewardj71bc3cb2005-05-19 00:25:45 +00001113 else
1114 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001115 VG_(printf_xml)("\n");
1116 VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
1117 VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
1118 VG_(printf_xml_no_f_c)("<tool>%t</tool>\n", toolname);
1119 if (xml_fname_unexpanded)
1120 print_file_vars(xml_fname_unexpanded);
sewardj768db0e2005-07-19 14:18:56 +00001121 if (VG_(clo_xml_user_comment)) {
1122 /* Note: the user comment itself is XML and is therefore to
1123 be passed through verbatim (%s) rather than escaped
1124 (%t). */
sewardj738856f2009-07-15 14:48:32 +00001125 VG_(printf_xml)("<usercomment>%s</usercomment>\n",
1126 VG_(clo_xml_user_comment));
sewardj768db0e2005-07-19 14:18:56 +00001127 }
sewardj738856f2009-07-15 14:48:32 +00001128 VG_(printf_xml)("\n");
1129 VG_(printf_xml)("<args>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001130
sewardj738856f2009-07-15 14:48:32 +00001131 VG_(printf_xml)(" <vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001132 if (VG_(name_of_launcher))
sewardj738856f2009-07-15 14:48:32 +00001133 VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
1134 VG_(name_of_launcher));
sewardj125fd4f2007-03-08 19:56:14 +00001135 else
sewardj738856f2009-07-15 14:48:32 +00001136 VG_(printf_xml_no_f_c)(Vg_UserMsg, " <exe>%t</exe>\n",
1137 "(launcher name unknown)");
sewardj14c7cc52007-02-25 15:08:24 +00001138 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
sewardj738856f2009-07-15 14:48:32 +00001139 VG_(printf_xml_no_f_c)(
1140 " <arg>%t</arg>\n",
1141 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1142 );
sewardjb8a3dac2005-07-19 12:39:11 +00001143 }
sewardj738856f2009-07-15 14:48:32 +00001144 VG_(printf_xml)(" </vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001145
sewardj738856f2009-07-15 14:48:32 +00001146 VG_(printf_xml)(" <argv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001147 if (VG_(args_the_exename))
sewardj738856f2009-07-15 14:48:32 +00001148 VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
1149 VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001150 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
sewardj738856f2009-07-15 14:48:32 +00001151 VG_(printf_xml_no_f_c)(
1152 " <arg>%t</arg>\n",
1153 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1154 );
sewardj8665d8e2005-06-01 17:35:23 +00001155 }
sewardj738856f2009-07-15 14:48:32 +00001156 VG_(printf_xml)(" </argv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001157
sewardj738856f2009-07-15 14:48:32 +00001158 VG_(printf_xml)("</args>\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001159 }
sewardj4cf05692002-10-27 20:28:29 +00001160
njnb6267bd2009-08-12 00:14:16 +00001161 // Last thing in the preamble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00001162 if (VG_(clo_xml))
1163 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00001164 else if (VG_(clo_verbosity) > 0)
1165 VG_(umsg)("\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001166
sewardjde4a1d02002-03-22 01:27:54 +00001167 if (VG_(clo_verbosity) > 1) {
sewardj92645592005-07-23 09:18:34 +00001168 SysRes fd;
sewardj1f0bbc72005-11-16 03:51:02 +00001169 VexArch vex_arch;
1170 VexArchInfo vex_archinfo;
sewardj45f4e7c2005-09-27 19:20:21 +00001171 if (!logging_to_fd)
sewardj738856f2009-07-15 14:48:32 +00001172 VG_(message)(Vg_DebugMsg, "\n");
njna3311642009-08-10 01:29:14 +00001173 VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
sewardj14c7cc52007-02-25 15:08:24 +00001174 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
1175 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001176 " %s\n",
sewardj14c7cc52007-02-25 15:08:24 +00001177 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjde4a1d02002-03-22 01:27:54 +00001178 }
nethercotea70f7352004-04-18 12:08:46 +00001179
sewardj738856f2009-07-15 14:48:32 +00001180 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
nethercotea70f7352004-04-18 12:08:46 +00001181 fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
njncda2f0f2009-05-18 02:12:08 +00001182 if (sr_isError(fd)) {
sewardj738856f2009-07-15 14:48:32 +00001183 VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
nethercotea70f7352004-04-18 12:08:46 +00001184 } else {
sewardj71bc3cb2005-05-19 00:25:45 +00001185# define BUF_LEN 256
nethercotea70f7352004-04-18 12:08:46 +00001186 Char version_buf[BUF_LEN];
njnf3977a32009-08-04 00:27:56 +00001187 Int n = VG_(read) ( sr_Res(fd), version_buf, BUF_LEN );
1188 vg_assert(n <= BUF_LEN);
1189 if (n > 0) {
1190 version_buf[n-1] = '\0';
sewardj738856f2009-07-15 14:48:32 +00001191 VG_(message)(Vg_DebugMsg, " %s\n", version_buf);
nethercotea70f7352004-04-18 12:08:46 +00001192 } else {
sewardj738856f2009-07-15 14:48:32 +00001193 VG_(message)(Vg_DebugMsg, " (empty?)\n");
nethercotea70f7352004-04-18 12:08:46 +00001194 }
njncda2f0f2009-05-18 02:12:08 +00001195 VG_(close)(sr_Res(fd));
sewardj71bc3cb2005-05-19 00:25:45 +00001196# undef BUF_LEN
nethercotea70f7352004-04-18 12:08:46 +00001197 }
sewardj1f0bbc72005-11-16 03:51:02 +00001198
1199 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001200 VG_(message)(
1201 Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001202 "Arch and hwcaps: %s, %s\n",
sewardje3121f32006-01-27 21:23:23 +00001203 LibVEX_ppVexArch ( vex_arch ),
1204 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1205 );
sewardje66f2e02006-12-30 17:45:08 +00001206 VG_(message)(
1207 Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001208 "Page sizes: currently %d, max supported %d\n",
sewardje66f2e02006-12-30 17:45:08 +00001209 (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
1210 );
sewardj738856f2009-07-15 14:48:32 +00001211 VG_(message)(Vg_DebugMsg,
1212 "Valgrind library directory: %s\n", VG_(libdir));
sewardjde4a1d02002-03-22 01:27:54 +00001213 }
nethercotef6a1d502004-08-09 12:21:57 +00001214}
1215
sewardjde4a1d02002-03-22 01:27:54 +00001216
nethercote71980f02004-01-24 18:18:54 +00001217/*====================================================================*/
1218/*=== File descriptor setup ===*/
1219/*====================================================================*/
1220
sewardj5f229e22005-09-28 01:36:01 +00001221/* Number of file descriptors that Valgrind tries to reserve for
1222 it's own use - just a small constant. */
1223#define N_RESERVED_FDS (10)
1224
nethercote71980f02004-01-24 18:18:54 +00001225static void setup_file_descriptors(void)
1226{
1227 struct vki_rlimit rl;
sewardj17c11042006-10-15 01:26:40 +00001228 Bool show = False;
nethercote71980f02004-01-24 18:18:54 +00001229
1230 /* Get the current file descriptor limits. */
1231 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
1232 rl.rlim_cur = 1024;
1233 rl.rlim_max = 1024;
1234 }
1235
njnf76d27a2009-05-28 01:53:07 +00001236# if defined(VGO_darwin)
1237 /* Darwin lies. It reports file max as RLIM_INFINITY but
1238 silently disallows anything bigger than 10240. */
1239 if (rl.rlim_cur >= 10240 && rl.rlim_max == 0x7fffffffffffffffULL) {
1240 rl.rlim_max = 10240;
1241 }
1242# endif
1243
sewardj17c11042006-10-15 01:26:40 +00001244 if (show)
njn8a7b41b2007-09-23 00:51:24 +00001245 VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001246 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001247
1248# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1249 /* I don't know why this kludge is needed; however if rl.rlim_cur
1250 is RLIM_INFINITY, then VG_(safe_fd)'s attempts using VG_(fcntl)
1251 to lift V's file descriptors above the threshold RLIM_INFINITY -
1252 N_RESERVED_FDS fail. So just use a relatively conservative
1253 value in this case. */
1254 if (rl.rlim_cur > 1024)
1255 rl.rlim_cur = 1024;
1256# endif
1257
nethercote71980f02004-01-24 18:18:54 +00001258 /* Work out where to move the soft limit to. */
njn14319cc2005-03-13 06:26:22 +00001259 if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
1260 rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001261 } else {
1262 rl.rlim_cur = rl.rlim_max;
1263 }
1264
1265 /* Reserve some file descriptors for our use. */
njn14319cc2005-03-13 06:26:22 +00001266 VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
1267 VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001268
1269 /* Update the soft limit. */
1270 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
1271
sewardj17c11042006-10-15 01:26:40 +00001272 if (show) {
njn8a7b41b2007-09-23 00:51:24 +00001273 VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001274 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001275 VG_(printf)("fd limits: guest : cur %u max %u\n",
1276 VG_(fd_soft_limit), VG_(fd_hard_limit));
1277 }
1278
sewardj45f4e7c2005-09-27 19:20:21 +00001279 if (VG_(cl_exec_fd) != -1)
1280 VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
nethercote71980f02004-01-24 18:18:54 +00001281}
1282
sewardjde4a1d02002-03-22 01:27:54 +00001283
njn2da73352005-06-18 01:35:16 +00001284/*====================================================================*/
njn2025cf92005-06-26 20:44:48 +00001285/*=== BB profiling ===*/
1286/*====================================================================*/
1287
1288static
1289void show_BB_profile ( BBProfEntry tops[], UInt n_tops, ULong score_total )
1290{
1291 ULong score_cumul, score_here;
1292 Char buf_cumul[10], buf_here[10];
1293 Char name[64];
1294 Int r;
1295
1296 VG_(printf)("\n");
1297 VG_(printf)("-----------------------------------------------------------\n");
1298 VG_(printf)("--- BEGIN BB Profile (summary of scores) ---\n");
1299 VG_(printf)("-----------------------------------------------------------\n");
1300 VG_(printf)("\n");
1301
1302 VG_(printf)("Total score = %lld\n\n", score_total);
1303
1304 score_cumul = 0;
1305 for (r = 0; r < n_tops; r++) {
1306 if (tops[r].addr == 0)
1307 continue;
1308 name[0] = 0;
1309 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1310 name[63] = 0;
1311 score_here = tops[r].score;
1312 score_cumul += score_here;
1313 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1314 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1315 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1316 r,
1317 score_cumul, buf_cumul,
1318 score_here, buf_here, tops[r].addr, name );
1319 }
1320
1321 VG_(printf)("\n");
1322 VG_(printf)("-----------------------------------------------------------\n");
1323 VG_(printf)("--- BB Profile (BB details) ---\n");
1324 VG_(printf)("-----------------------------------------------------------\n");
1325 VG_(printf)("\n");
1326
1327 score_cumul = 0;
1328 for (r = 0; r < n_tops; r++) {
1329 if (tops[r].addr == 0)
1330 continue;
1331 name[0] = 0;
1332 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1333 name[63] = 0;
1334 score_here = tops[r].score;
1335 score_cumul += score_here;
1336 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1337 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1338 VG_(printf)("\n");
1339 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin BB rank %d "
1340 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1341 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1342 r,
1343 score_cumul, buf_cumul,
1344 score_here, buf_here, tops[r].addr, name );
1345 VG_(printf)("\n");
sewardjbcccbc02007-04-09 22:24:57 +00001346 VG_(discard_translations)(tops[r].addr, 1, "bb profile");
sewardj0ec07f32006-01-12 12:32:32 +00001347 VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0, True);
njn2025cf92005-06-26 20:44:48 +00001348 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= end BB rank %d "
1349 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1350 }
1351
1352 VG_(printf)("\n");
1353 VG_(printf)("-----------------------------------------------------------\n");
1354 VG_(printf)("--- END BB Profile ---\n");
1355 VG_(printf)("-----------------------------------------------------------\n");
1356 VG_(printf)("\n");
1357}
1358
1359
1360/*====================================================================*/
nethercote71980f02004-01-24 18:18:54 +00001361/*=== main() ===*/
1362/*====================================================================*/
1363
sewardjfdf91b42005-09-28 00:53:09 +00001364/* When main() is entered, we should be on the following stack, not
1365 the one the kernel gave us. We will run on this stack until
1366 simulation of the root thread is started, at which point a transfer
1367 is made to a dynamically allocated stack. This is for the sake of
1368 uniform overflow detection for all Valgrind threads. This is
1369 marked global even though it isn't, because assembly code below
1370 needs to reference the name. */
1371
1372/*static*/ VgStack VG_(interim_stack);
1373
sewardjf9d2f9b2006-11-17 20:00:57 +00001374/* These are the structures used to hold info for creating the initial
1375 client image.
1376
1377 'iicii' mostly holds important register state present at system
1378 startup (_start_valgrind). valgrind_main() then fills in the rest
1379 of it and passes it to VG_(ii_create_image)(). That produces
1380 'iifii', which is later handed to VG_(ii_finalise_image). */
1381
1382/* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1383 This should get some address inside the stack on which we gained
sewardjfdf91b42005-09-28 00:53:09 +00001384 control (eg, it could be the SP at startup). It doesn't matter
1385 exactly where in the stack it is. This value is passed to the
sewardjf9d2f9b2006-11-17 20:00:57 +00001386 address space manager at startup. On Linux, aspacem then uses it
1387 to identify the initial stack segment and hence the upper end of
1388 the usable address space. */
sewardjfdf91b42005-09-28 00:53:09 +00001389
sewardjf9d2f9b2006-11-17 20:00:57 +00001390static IICreateImageInfo the_iicii;
1391static IIFinaliseImageInfo the_iifii;
1392
sewardjfdf91b42005-09-28 00:53:09 +00001393
sewardj9c606bd2008-09-18 18:12:50 +00001394/* A simple pair structure, used for conveying debuginfo handles to
1395 calls to VG_TRACK(new_mem_startup, ...). */
1396typedef struct { Addr a; ULong ull; } Addr_n_ULong;
1397
1398
sewardj1ae3f3a2005-09-28 10:47:38 +00001399/* --- Forwards decls to do with shutdown --- */
1400
1401static void final_tidyup(ThreadId tid);
1402
1403/* Do everything which needs doing when the last thread exits */
1404static
1405void shutdown_actions_NORETURN( ThreadId tid,
1406 VgSchedReturnCode tids_schedretcode );
1407
1408/* --- end of Forwards decls to do with shutdown --- */
sewardjfdf91b42005-09-28 00:53:09 +00001409
1410
sewardjf9d2f9b2006-11-17 20:00:57 +00001411/* By the time we get to valgrind_main, the_iicii should already have
1412 been filled in with any important details as required by whatever
1413 OS we have been built for.
1414*/
sewardj17c11042006-10-15 01:26:40 +00001415static
sewardjf9d2f9b2006-11-17 20:00:57 +00001416Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
nethercote71980f02004-01-24 18:18:54 +00001417{
sewardj13247ca2005-12-30 22:52:20 +00001418 HChar* toolname = "memcheck"; // default to Memcheck
sewardj13247ca2005-12-30 22:52:20 +00001419 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
sewardjde764e82007-11-09 23:13:22 +00001420 ThreadId tid_main = VG_INVALID_THREADID;
sewardj738856f2009-07-15 14:48:32 +00001421 Bool logging_to_fd = False;
1422 Char* xml_fname_unexpanded = NULL;
sewardj45f4e7c2005-09-27 19:20:21 +00001423 Int loglevel, i;
nethercote73b526f2004-10-31 18:48:21 +00001424 struct vki_rlimit zero = { 0, 0 };
sewardj9c606bd2008-09-18 18:12:50 +00001425 XArray* addr2dihandle = NULL;
sewardj17c11042006-10-15 01:26:40 +00001426
nethercote71980f02004-01-24 18:18:54 +00001427 //============================================================
nethercote71980f02004-01-24 18:18:54 +00001428 //
sewardj45f4e7c2005-09-27 19:20:21 +00001429 // Nb: startup is complex. Prerequisites are shown at every step.
nethercote71980f02004-01-24 18:18:54 +00001430 // *** Be very careful when messing with the order ***
sewardj45f4e7c2005-09-27 19:20:21 +00001431 //
1432 // The first order of business is to get debug logging, the address
1433 // space manager and the dynamic memory manager up and running.
1434 // Once that's done, we can relax a bit.
1435 //
nethercote71980f02004-01-24 18:18:54 +00001436 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001437
1438 /* This is needed to make VG_(getenv) usable early. */
1439 VG_(client_envp) = (Char**)envp;
nethercote71980f02004-01-24 18:18:54 +00001440
sewardj1cf558c2005-04-25 01:36:56 +00001441 //--------------------------------------------------------------
njnf76d27a2009-05-28 01:53:07 +00001442 // Start up Mach kernel interface, if any
1443 // p: none
1444 //--------------------------------------------------------------
1445# if defined(VGO_darwin)
1446 VG_(mach_init)();
1447# endif
1448
1449 //--------------------------------------------------------------
sewardj1cf558c2005-04-25 01:36:56 +00001450 // Start up the logging mechanism
1451 // p: none
1452 //--------------------------------------------------------------
1453 /* Start the debugging-log system ASAP. First find out how many
njn83df0b62009-02-25 01:01:05 +00001454 "-d"s were specified. This is a pre-scan of the command line. Also
1455 get --profile-heap=yes which is needed by the time we start up dynamic
1456 memory management. */
sewardj1cf558c2005-04-25 01:36:56 +00001457 loglevel = 0;
1458 for (i = 1; i < argc; i++) {
njn83df0b62009-02-25 01:01:05 +00001459 if (argv[i][0] != '-') break;
1460 if VG_STREQ(argv[i], "--") break;
1461 if VG_STREQ(argv[i], "-d") loglevel++;
1462 if VG_BOOL_CLO(argv[i], "--profile-heap", VG_(clo_profile_heap)) {}
sewardj1cf558c2005-04-25 01:36:56 +00001463 }
1464
1465 /* ... and start the debug logger. Now we can safely emit logging
1466 messages all through startup. */
sewardj10759312005-05-30 23:52:47 +00001467 VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
sewardj45f4e7c2005-09-27 19:20:21 +00001468 VG_(debugLog)(1, "main", "Welcome to Valgrind version "
1469 VERSION " debug logging\n");
1470
1471 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001472 // AIX5 only: register the system call numbers
1473 // p: logging
1474 // p: that the initial few syscall numbers stated in the
1475 // bootblock have been installed (else we can't
1476 // open/read/close).
1477 //--------------------------------------------------------------
1478# if defined(VGO_aix5)
1479 VG_(debugLog)(1, "main", "aix5: registering syscalls ..\n");
1480 { UChar sysent_name[50];
1481 SysRes fd;
1482 Bool ok;
1483 Int n_unregd, sysent_used = 0;
1484 prsysent_t* sysent_hdr;
1485
1486 VG_(sprintf)(sysent_name, "/proc/%d/sysent", VG_(getpid)());
1487 fd = VG_(open)(sysent_name, VKI_O_RDONLY, 0);
1488 if (fd.isError)
1489 VG_(err_config_error)("aix5: can't open /proc/<pid>/sysent");
1490
1491 sysent_used = VG_(read)(fd.res, aix5_sysent_buf, VG_AIX5_SYSENT_SIZE);
1492 if (sysent_used < 0)
1493 VG_(err_config_error)("aix5: error reading /proc/<pid>/sysent");
1494 if (sysent_used >= VG_AIX5_SYSENT_SIZE)
1495 VG_(err_config_error)("aix5: VG_AIX5_SYSENT_SIZE is too low; "
1496 "increase and recompile");
1497 VG_(close)(fd.res);
1498
1499 vg_assert(sysent_used > 0 && sysent_used < VG_AIX5_SYSENT_SIZE);
1500
1501 sysent_hdr = (prsysent_t*)&aix5_sysent_buf[0];
1502
1503 n_unregd = 0;
1504 for (i = 0; i < sysent_hdr->pr_nsyscalls; i++) {
1505 UChar* name = &aix5_sysent_buf[ sysent_hdr
1506 ->pr_syscall[i].pr_nameoff ];
1507 UInt nmbr = sysent_hdr->pr_syscall[i].pr_number;
1508 VG_(debugLog)(3, "main", "aix5: bind syscall %d to \"%s\"\n",
1509 nmbr, name);
1510 ok = VG_(aix5_register_syscall)(nmbr, name);
1511 if (!ok)
1512 n_unregd++;
1513 if (!ok)
1514 VG_(debugLog)(3, "main",
1515 "aix5: bind FAILED: %d to \"%s\"\n",
1516 nmbr, name);
1517 }
1518 VG_(debugLog)(1, "main", "aix5: .. %d syscalls known, %d unknown\n",
1519 sysent_hdr->pr_nsyscalls - n_unregd, n_unregd );
1520 VG_(debugLog)(1, "main", "aix5: __NR_AIX5_FAKE_SIGRETURN = %d\n",
1521 __NR_AIX5_FAKE_SIGRETURN );
1522 }
1523# endif
1524
1525 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001526 // Ensure we're on a plausible stack.
1527 // p: logging
1528 //--------------------------------------------------------------
1529 VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
sewardjfdf91b42005-09-28 00:53:09 +00001530 { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
1531 HChar* limHi = limLo + sizeof(VG_(interim_stack));
sewardj45f4e7c2005-09-27 19:20:21 +00001532 HChar* aLocal = (HChar*)&zero; /* any auto local will do */
1533 if (aLocal < limLo || aLocal >= limHi) {
1534 /* something's wrong. Stop. */
1535 VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
1536 limLo, limHi, aLocal );
1537 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1538 "Initial stack switched failed.\n");
1539 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1540 VG_(exit)(1);
1541 }
1542 }
1543
1544 //--------------------------------------------------------------
1545 // Ensure we have a plausible pointer to the stack on which
1546 // we gained control (not the current stack!)
1547 // p: logging
1548 //--------------------------------------------------------------
1549 VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
sewardjf9d2f9b2006-11-17 20:00:57 +00001550 if (the_iicii.sp_at_startup == 0) {
sewardj45f4e7c2005-09-27 19:20:21 +00001551 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1552 "Initial stack was not noted.\n");
1553 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1554 VG_(exit)(1);
1555 }
1556
1557 //--------------------------------------------------------------
1558 // Start up the address space manager, and determine the
1559 // approximate location of the client's stack
njnea2d6fd2010-07-01 00:20:20 +00001560 // p: logging, plausible-stack
sewardj45f4e7c2005-09-27 19:20:21 +00001561 //--------------------------------------------------------------
1562 VG_(debugLog)(1, "main", "Starting the address space manager\n");
sewardje66f2e02006-12-30 17:45:08 +00001563 vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536);
1564 vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536);
1565 vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
1566 vg_assert(VKI_PAGE_SIZE == (1 << VKI_PAGE_SHIFT));
1567 vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
sewardjf9d2f9b2006-11-17 20:00:57 +00001568 the_iicii.clstack_top = VG_(am_startup)( the_iicii.sp_at_startup );
sewardj45f4e7c2005-09-27 19:20:21 +00001569 VG_(debugLog)(1, "main", "Address space manager is running\n");
1570
1571 //--------------------------------------------------------------
1572 // Start up the dynamic memory manager
1573 // p: address space management
njn83df0b62009-02-25 01:01:05 +00001574 // p: getting --profile-heap
sewardj45f4e7c2005-09-27 19:20:21 +00001575 // In fact m_mallocfree is self-initialising, so there's no
1576 // initialisation call to do. Instead, try a simple malloc/
1577 // free pair right now to check that nothing is broken.
1578 //--------------------------------------------------------------
1579 VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
sewardj9c606bd2008-09-18 18:12:50 +00001580 { void* p = VG_(malloc)( "main.vm.1", 12345 );
sewardj45f4e7c2005-09-27 19:20:21 +00001581 if (p) VG_(free)( p );
1582 }
1583 VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
sewardj1cf558c2005-04-25 01:36:56 +00001584
nethercotef4928da2004-06-15 10:54:40 +00001585 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001586 //
1587 // Dynamic memory management is now available.
1588 //
nethercotef4928da2004-06-15 10:54:40 +00001589 //============================================================
1590
sewardj45f4e7c2005-09-27 19:20:21 +00001591 //--------------------------------------------------------------
sewardjf98e1c02008-10-25 16:22:41 +00001592 // Initialise m_debuginfo
1593 // p: dynamic memory allocation
1594 VG_(debugLog)(1, "main", "Initialise m_debuginfo\n");
1595 VG_(di_initialise)();
1596
1597 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001598 // Look for alternative libdir
1599 { HChar *cp = VG_(getenv)(VALGRIND_LIB);
1600 if (cp != NULL)
1601 VG_(libdir) = cp;
njncde90d32009-07-22 22:41:38 +00001602 VG_(debugLog)(1, "main", "VG_(libdir) = %s\n", VG_(libdir));
sewardj45f4e7c2005-09-27 19:20:21 +00001603 }
1604
1605 //--------------------------------------------------------------
1606 // Extract the launcher name from the environment.
njna842d792009-05-21 01:15:18 +00001607 VG_(debugLog)(1, "main", "Getting launcher's name ...\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001608 VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
1609 if (VG_(name_of_launcher) == NULL) {
1610 VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
1611 VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
1612 VG_(exit)(1);
1613 }
njna842d792009-05-21 01:15:18 +00001614 VG_(debugLog)(1, "main", "... %s\n", VG_(name_of_launcher));
sewardj45f4e7c2005-09-27 19:20:21 +00001615
1616 //--------------------------------------------------------------
fitzhardingeb50068f2004-02-24 23:42:55 +00001617 // Get the current process datasize rlimit, and set it to zero.
1618 // This prevents any internal uses of brk() from having any effect.
1619 // We remember the old value so we can restore it on exec, so that
1620 // child processes will have a reasonable brk value.
1621 VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1622 zero.rlim_max = VG_(client_rlimit_data).rlim_max;
1623 VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
thughesc37184f2004-09-11 14:16:57 +00001624
1625 // Get the current process stack rlimit.
1626 VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
1627
sewardje2d1e672005-11-12 23:10:48 +00001628 //--------------------------------------------------------------
1629 // Figure out what sort of CPU we're on, and whether it is
1630 // able to run V.
1631 VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
1632 { VexArch vex_arch;
1633 VexArchInfo vex_archinfo;
1634 Bool ok = VG_(machine_get_hwcaps)();
1635 if (!ok) {
1636 VG_(printf)("\n");
1637 VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
1638 VG_(printf)(" Supported CPUs are:\n");
1639 VG_(printf)(" * x86 (practically any; Pentium-I or above), "
1640 "AMD Athlon or above)\n");
1641 VG_(printf)(" * AMD Athlon64/Opteron\n");
1642 VG_(printf)(" * PowerPC (most; ppc405 and above)\n");
1643 VG_(printf)("\n");
1644 VG_(exit)(1);
1645 }
1646 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001647 VG_(debugLog)(
1648 1, "main", "... arch = %s, hwcaps = %s\n",
1649 LibVEX_ppVexArch ( vex_arch ),
1650 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1651 );
sewardje2d1e672005-11-12 23:10:48 +00001652 }
1653
sewardj198f34f2007-07-09 23:13:07 +00001654 //--------------------------------------------------------------
1655 // Record the working directory at startup
1656 // p: none (Linux), getenv and sys_getpid work (AIX)
1657 VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
1658 { Bool ok = VG_(record_startup_wd)();
1659 if (!ok)
1660 VG_(err_config_error)( "Can't establish current working "
1661 "directory at startup");
1662 }
1663 { Char buf[VKI_PATH_MAX+1];
1664 Bool ok = VG_(get_startup_wd)( buf, sizeof(buf) );
1665 vg_assert(ok);
1666 buf[VKI_PATH_MAX] = 0;
1667 VG_(debugLog)(1, "main", "... %s\n", buf );
1668 }
1669
sewardj45f4e7c2005-09-27 19:20:21 +00001670 //============================================================
1671 // Command line argument handling order:
1672 // * If --help/--help-debug are present, show usage message
1673 // (including the tool-specific usage)
1674 // * (If no --tool option given, default to Memcheck)
1675 // * Then, if client is missing, abort with error msg
1676 // * Then, if any cmdline args are bad, abort with error msg
1677 //============================================================
1678
1679 //--------------------------------------------------------------
1680 // Split up argv into: C args, V args, V extra args, and exename.
1681 // p: dynamic memory allocation
1682 //--------------------------------------------------------------
1683 VG_(debugLog)(1, "main", "Split up command line\n");
1684 VG_(split_up_argv)( argc, argv );
sewardj14c7cc52007-02-25 15:08:24 +00001685 vg_assert( VG_(args_for_valgrind) );
1686 vg_assert( VG_(args_for_client) );
sewardj45f4e7c2005-09-27 19:20:21 +00001687 if (0) {
sewardj14c7cc52007-02-25 15:08:24 +00001688 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
1689 VG_(printf)(
1690 "varg %s\n",
1691 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1692 );
sewardj45f4e7c2005-09-27 19:20:21 +00001693 VG_(printf)(" exe %s\n", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001694 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
1695 VG_(printf)(
1696 "carg %s\n",
1697 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1698 );
nethercote71980f02004-01-24 18:18:54 +00001699 }
1700
sewardj948a6fc2007-03-19 18:38:55 +00001701# if defined(VGO_aix5)
1702 /* Tolerate ptraced-based launchers. They can't run 'no program'
1703 if the user types "valgrind --help", so they run a do-nothing
1704 program $prefix/bin/no_op_client_for_valgrind, and we catch that
1705 here and turn it the exe name back into NULL. Then --help,
1706 --version etc work as they should. */
1707 if (VG_(args_the_exename)
1708 && VG_(strstr)( VG_(args_the_exename), "/no_op_client_for_valgrind" )) {
1709 VG_(args_the_exename) = NULL;
1710 }
1711# endif
1712
nethercote71980f02004-01-24 18:18:54 +00001713 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001714 // Extract tool name and whether help has been requested.
1715 // Note we can't print the help message yet, even if requested,
1716 // because the tool has not been initialised.
1717 // p: split_up_argv [for VG_(args_for_valgrind)]
nethercote71980f02004-01-24 18:18:54 +00001718 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001719 VG_(debugLog)(1, "main",
1720 "(early_) Process Valgrind's command line options\n");
1721 early_process_cmd_line_options(&need_help, &toolname);
nethercote71980f02004-01-24 18:18:54 +00001722
sewardj45f4e7c2005-09-27 19:20:21 +00001723 // Set default vex control params
1724 LibVEX_default_VexControl(& VG_(clo_vex_control));
nethercote71980f02004-01-24 18:18:54 +00001725
1726 //--------------------------------------------------------------
1727 // Load client executable, finding in $PATH if necessary
njn83df0b62009-02-25 01:01:05 +00001728 // p: early_process_cmd_line_options() [for 'exec', 'need_help',
1729 // clo_max_stackframe,
1730 // clo_main_stacksize]
sewardj95d86c02007-12-18 01:49:23 +00001731 // p: layout_remaining_space [so there's space]
sewardj17c11042006-10-15 01:26:40 +00001732 //
nethercote71980f02004-01-24 18:18:54 +00001733 // Set up client's environment
sewardj95d86c02007-12-18 01:49:23 +00001734 // p: set-libdir [for VG_(libdir)]
1735 // p: early_process_cmd_line_options [for toolname]
sewardj17c11042006-10-15 01:26:40 +00001736 //
nethercote5ee67ca2004-06-22 14:00:09 +00001737 // Setup client stack, eip, and VG_(client_arg[cv])
nethercote71980f02004-01-24 18:18:54 +00001738 // p: load_client() [for 'info']
1739 // p: fix_environment() [for 'env']
sewardj17c11042006-10-15 01:26:40 +00001740 //
sewardj45f4e7c2005-09-27 19:20:21 +00001741 // Setup client data (brk) segment. Initially a 1-page segment
1742 // which abuts a shrinkable reservation.
1743 // p: load_client() [for 'info' and hence VG_(brk_base)]
sewardjf9d2f9b2006-11-17 20:00:57 +00001744 //
1745 // p: _start_in_C (for zeroing out the_iicii and putting some
1746 // initial values into it)
sewardj45f4e7c2005-09-27 19:20:21 +00001747 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001748 if (!need_help) {
sewardjf9d2f9b2006-11-17 20:00:57 +00001749 VG_(debugLog)(1, "main", "Create initial image\n");
1750
njnf76d27a2009-05-28 01:53:07 +00001751# if defined(VGO_linux) || defined(VGO_darwin)
sewardjf9d2f9b2006-11-17 20:00:57 +00001752 the_iicii.argv = argv;
1753 the_iicii.envp = envp;
1754 the_iicii.toolname = toolname;
1755# elif defined(VGO_aix5)
1756 /* the_iicii.intregs37 already set up */
1757 /* the_iicii.bootblock already set up */
1758 /* the_iicii.adler32_exp already set up */
1759 /* the_iicii.sp_at_startup is irrelevant */
1760 /* the_iicii.clstack_top is irrelevant */
1761 the_iicii.toolname = toolname;
1762# else
njna842d792009-05-21 01:15:18 +00001763# error "Unknown platform"
sewardjf9d2f9b2006-11-17 20:00:57 +00001764# endif
1765
sewardjdc2f79e2007-12-22 14:14:04 +00001766 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001767 the_iifii = VG_(ii_create_image)( the_iicii );
1768
sewardj17c11042006-10-15 01:26:40 +00001769# if defined(VGO_aix5)
sewardj17c11042006-10-15 01:26:40 +00001770 /* Tell aspacem where the initial client stack is, so that it
1771 can later produce a faked-up NSegment in response to
1772 VG_(am_find_nsegment) for that address range, if asked. */
sewardjdc2f79e2007-12-22 14:14:04 +00001773 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001774 VG_(am_aix5_set_initial_client_sp)( the_iifii.initial_client_SP );
1775 /* Now have a look at said fake segment, so we can find out
1776 the size of it. */
1777 { SizeT sz;
1778 NSegment const* seg
1779 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
1780 vg_assert(seg);
1781 sz = seg->end - seg->start + 1;
sewardjc9d33832007-12-22 14:12:42 +00001782 vg_assert(sz >= 0 && sz <= (256+1)*1024*1024); /* stay sane */
sewardjf9d2f9b2006-11-17 20:00:57 +00001783 the_iifii.clstack_max_size = sz;
1784 }
sewardj17c11042006-10-15 01:26:40 +00001785# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001786 }
nethercote71980f02004-01-24 18:18:54 +00001787
1788 //==============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001789 //
1790 // Finished loading/setting up the client address space.
1791 //
nethercote71980f02004-01-24 18:18:54 +00001792 //==============================================================
1793
1794 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001795 // setup file descriptors
1796 // p: n/a
1797 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001798 VG_(debugLog)(1, "main", "Setup file descriptors\n");
nethercote71980f02004-01-24 18:18:54 +00001799 setup_file_descriptors();
1800
1801 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001802 // create the fake /proc/<pid>/cmdline file and then unlink it,
1803 // but hold onto the fd, so we can hand it out to the client
1804 // when it tries to open /proc/<pid>/cmdline for itself.
1805 // p: setup file descriptors
nethercotec314eba2004-07-15 12:59:41 +00001806 //--------------------------------------------------------------
bart9b533f82009-08-25 20:15:41 +00001807#if !defined(VGO_linux)
1808 // client shouldn't be using /proc!
1809 VG_(cl_cmdline_fd) = -1;
1810#else
1811 if (!need_help) {
1812 HChar buf[50], buf2[50+64];
1813 HChar nul[1];
1814 Int fd, r;
barta3054f52010-06-14 18:12:56 +00001815 const HChar* exename;
nethercotec314eba2004-07-15 12:59:41 +00001816
bart9b533f82009-08-25 20:15:41 +00001817 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001818
bart9b533f82009-08-25 20:15:41 +00001819 VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
1820 fd = VG_(mkstemp)( buf, buf2 );
1821 if (fd == -1)
1822 VG_(err_config_error)("Can't create client cmdline file in /tmp.");
sewardj45f4e7c2005-09-27 19:20:21 +00001823
bart9b533f82009-08-25 20:15:41 +00001824 nul[0] = 0;
1825 exename = VG_(args_the_exename) ? VG_(args_the_exename)
1826 : "unknown_exename";
1827 VG_(write)(fd, VG_(args_the_exename),
1828 VG_(strlen)( VG_(args_the_exename) ));
1829 VG_(write)(fd, nul, 1);
1830
1831 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1832 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
1833 VG_(write)(fd, arg, VG_(strlen)( arg ));
sewardj45f4e7c2005-09-27 19:20:21 +00001834 VG_(write)(fd, nul, 1);
1835 }
bart9b533f82009-08-25 20:15:41 +00001836
1837 /* Don't bother to seek the file back to the start; instead do
1838 it every time a copy of it is given out (by PRE(sys_open)).
1839 That is probably more robust across fork() etc. */
1840
1841 /* Now delete it, but hang on to the fd. */
1842 r = VG_(unlink)( buf2 );
1843 if (r)
1844 VG_(err_config_error)("Can't delete client cmdline file in /tmp.");
1845
1846 VG_(cl_cmdline_fd) = fd;
sewardj45f4e7c2005-09-27 19:20:21 +00001847 }
bart9b533f82009-08-25 20:15:41 +00001848#endif
nethercotec314eba2004-07-15 12:59:41 +00001849
1850 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001851 // Init tool part 1: pre_clo_init
nethercotec314eba2004-07-15 12:59:41 +00001852 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
nethercotec314eba2004-07-15 12:59:41 +00001853 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
nethercote71980f02004-01-24 18:18:54 +00001854 //--------------------------------------------------------------
sewardj7cf4e6b2008-05-01 20:24:26 +00001855 VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
njn08ce7b32009-02-27 03:38:28 +00001856 VG_(tl_pre_clo_init)();
nethercote71980f02004-01-24 18:18:54 +00001857
sewardj45f4e7c2005-09-27 19:20:21 +00001858 //--------------------------------------------------------------
nethercotef4928da2004-06-15 10:54:40 +00001859 // If --tool and --help/--help-debug was given, now give the core+tool
1860 // help message
sewardj95d86c02007-12-18 01:49:23 +00001861 // p: early_process_cmd_line_options() [for 'need_help']
1862 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
sewardj45f4e7c2005-09-27 19:20:21 +00001863 //--------------------------------------------------------------
1864 VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
nethercotef4928da2004-06-15 10:54:40 +00001865 if (need_help) {
sewardj45f4e7c2005-09-27 19:20:21 +00001866 usage_NORETURN(/*--help-debug?*/2 == need_help);
nethercotef4928da2004-06-15 10:54:40 +00001867 }
nethercotec314eba2004-07-15 12:59:41 +00001868
sewardj45f4e7c2005-09-27 19:20:21 +00001869 //--------------------------------------------------------------
1870 // Process command line options to Valgrind + tool
1871 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1872 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1873 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001874 VG_(debugLog)(1, "main",
1875 "(main_) Process Valgrind's command line options, "
1876 "setup logging\n");
sewardj738856f2009-07-15 14:48:32 +00001877 main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded,
1878 toolname );
sewardj45f4e7c2005-09-27 19:20:21 +00001879
1880 //--------------------------------------------------------------
sewardj592ae092005-11-08 19:01:44 +00001881 // Zeroise the millisecond counter by doing a first read of it.
1882 // p: none
1883 //--------------------------------------------------------------
1884 (void) VG_(read_millisecond_timer)();
1885
1886 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001887 // Print the preamble
1888 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
sewardj738856f2009-07-15 14:48:32 +00001889 // p: main_process_cmd_line_options()
1890 // [for VG_(clo_verbosity), VG_(clo_xml),
1891 // logging_to_fd, xml_fname_unexpanded]
sewardj45f4e7c2005-09-27 19:20:21 +00001892 //--------------------------------------------------------------
1893 VG_(debugLog)(1, "main", "Print the preamble...\n");
sewardj738856f2009-07-15 14:48:32 +00001894 print_preamble(logging_to_fd, xml_fname_unexpanded, toolname);
sewardj45f4e7c2005-09-27 19:20:21 +00001895 VG_(debugLog)(1, "main", "...finished the preamble\n");
1896
1897 //--------------------------------------------------------------
1898 // Init tool part 2: post_clo_init
1899 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1900 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1901 // p: print_preamble() [so any warnings printed in post_clo_init
1902 // are shown after the preamble]
1903 //--------------------------------------------------------------
1904 VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
njn51d827b2005-05-09 01:02:08 +00001905 VG_TDICT_CALL(tool_post_clo_init);
sewardj7cf4e6b2008-05-01 20:24:26 +00001906 {
1907 /* The tool's "needs" will by now be finalised, since it has no
1908 further opportunity to specify them. So now sanity check
1909 them. */
1910 Char* s;
1911 Bool ok;
1912 ok = VG_(sanity_check_needs)( &s );
1913 if (!ok) {
1914 VG_(tool_panic)(s);
1915 }
1916 }
nethercotef4928da2004-06-15 10:54:40 +00001917
1918 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001919 // Initialise translation table and translation cache
1920 // p: aspacem [??]
1921 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
nethercote71980f02004-01-24 18:18:54 +00001922 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001923 VG_(debugLog)(1, "main", "Initialise TT/TC\n");
1924 VG_(init_tt_tc)();
sewardjb5f6f512005-03-10 23:59:00 +00001925
sewardj45f4e7c2005-09-27 19:20:21 +00001926 //--------------------------------------------------------------
1927 // Initialise the redirect table.
1928 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
1929 // p: aspacem [so can change ownership of sysinfo pages]
1930 //--------------------------------------------------------------
1931 VG_(debugLog)(1, "main", "Initialise redirects\n");
sewardj0ec07f32006-01-12 12:32:32 +00001932 VG_(redir_initialise)();
nethercote71980f02004-01-24 18:18:54 +00001933
1934 //--------------------------------------------------------------
1935 // Allow GDB attach
sewardj95d86c02007-12-18 01:49:23 +00001936 // p: main_process_cmd_line_options() [for VG_(clo_wait_for_gdb)]
nethercote71980f02004-01-24 18:18:54 +00001937 //--------------------------------------------------------------
1938 /* Hook to delay things long enough so we can get the pid and
1939 attach GDB in another shell. */
1940 if (VG_(clo_wait_for_gdb)) {
sewardj95611ff2007-02-16 13:57:07 +00001941 Long iters;
1942 volatile Long q;
sewardj1fbc1a52005-04-25 02:05:54 +00001943 VG_(debugLog)(1, "main", "Wait for GDB\n");
sewardj93ab8572005-02-06 14:10:40 +00001944 VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
sewardj8211a572005-06-23 21:37:47 +00001945
1946# if defined(VGP_x86_linux)
1947 iters = 5;
sewardj2c48c7b2005-11-29 13:05:56 +00001948# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
sewardj8211a572005-06-23 21:37:47 +00001949 iters = 10;
1950# elif defined(VGP_ppc32_linux)
sewardjd714d2e2005-07-08 18:24:04 +00001951 iters = 5;
sewardj59570ff2010-01-01 11:59:33 +00001952# elif defined(VGP_arm_linux)
1953 iters = 1;
sewardj17c11042006-10-15 01:26:40 +00001954# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1955 iters = 4;
njnf76d27a2009-05-28 01:53:07 +00001956# elif defined(VGO_darwin)
1957 iters = 3;
sewardj8211a572005-06-23 21:37:47 +00001958# else
sewardj17c11042006-10-15 01:26:40 +00001959# error "Unknown plat"
sewardj8211a572005-06-23 21:37:47 +00001960# endif
1961
1962 iters *= 1000*1000*1000;
1963 for (q = 0; q < iters; q++)
1964 ;
nethercote71980f02004-01-24 18:18:54 +00001965 }
1966
sewardjb5d320c2005-03-13 18:57:15 +00001967 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001968 // Search for file descriptors that are inherited from our parent
sewardj95d86c02007-12-18 01:49:23 +00001969 // p: main_process_cmd_line_options [for VG_(clo_track_fds)]
nethercote71980f02004-01-24 18:18:54 +00001970 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001971 if (VG_(clo_track_fds)) {
1972 VG_(debugLog)(1, "main", "Init preopened fds\n");
nethercote71980f02004-01-24 18:18:54 +00001973 VG_(init_preopened_fds)();
sewardj1fbc1a52005-04-25 02:05:54 +00001974 }
nethercote71980f02004-01-24 18:18:54 +00001975
1976 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001977 // Load debug info for the existing segments.
1978 // p: setup_code_redirect_table [so that redirs can be recorded]
1979 // p: mallocfree
1980 // p: probably: setup fds and process CLOs, so that logging works
sewardjf98e1c02008-10-25 16:22:41 +00001981 // p: initialise m_debuginfo
sewardj9c606bd2008-09-18 18:12:50 +00001982 //
1983 // While doing this, make a note of the debuginfo-handles that
1984 // come back from VG_(di_notify_mmap)/VG_(di_aix5_notify_segchange).
1985 // Later, in "Tell the tool about the initial client memory permissions"
1986 // (just below) we can then hand these handles off to the tool in
1987 // calls to VG_TRACK(new_mem_startup, ...). This gives the tool the
1988 // opportunity to make further queries to m_debuginfo before the
1989 // client is started, if it wants. We put this information into an
1990 // XArray, each handle along with the associated segment start address,
1991 // and search the XArray for the handles later, when calling
1992 // VG_TRACK(new_mem_startup, ...).
sewardj45f4e7c2005-09-27 19:20:21 +00001993 //--------------------------------------------------------------
1994 VG_(debugLog)(1, "main", "Load initial debug info\n");
sewardj9c606bd2008-09-18 18:12:50 +00001995
1996 tl_assert(!addr2dihandle);
1997 addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2",
1998 VG_(free), sizeof(Addr_n_ULong) );
1999 tl_assert(addr2dihandle);
2000
sewardj17c11042006-10-15 01:26:40 +00002001# if defined(VGO_linux)
sewardj45f4e7c2005-09-27 19:20:21 +00002002 { Addr* seg_starts;
2003 Int n_seg_starts;
sewardj9c606bd2008-09-18 18:12:50 +00002004 Addr_n_ULong anu;
sewardj45f4e7c2005-09-27 19:20:21 +00002005
njnac1e0332009-05-08 00:39:31 +00002006 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00002007 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00002008
sewardjf72cced2005-11-08 00:45:47 +00002009 /* show them all to the debug info reader. allow_SkFileV has to
2010 be True here so that we read info from the valgrind executable
2011 itself. */
sewardj9c606bd2008-09-18 18:12:50 +00002012 for (i = 0; i < n_seg_starts; i++) {
2013 anu.ull = VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/ );
2014 /* anu.ull holds the debuginfo handle returned by di_notify_mmap,
2015 if any. */
2016 if (anu.ull > 0) {
2017 anu.a = seg_starts[i];
2018 VG_(addToXA)( addr2dihandle, &anu );
2019 }
2020 }
sewardj45f4e7c2005-09-27 19:20:21 +00002021
2022 VG_(free)( seg_starts );
2023 }
sewardj17c11042006-10-15 01:26:40 +00002024# elif defined(VGO_aix5)
2025 { AixCodeSegChange* changes;
2026 Int changes_size, changes_used;
sewardj9c606bd2008-09-18 18:12:50 +00002027 Addr_n_ULong anu;
sewardj17c11042006-10-15 01:26:40 +00002028
2029 /* Find out how many AixCodeSegChange records we will need,
2030 and acquire them. */
2031 changes_size = VG_(am_aix5_reread_procmap_howmany_directives)();
sewardj9c606bd2008-09-18 18:12:50 +00002032 changes = VG_(malloc)("main.vm.3", changes_size * sizeof(AixCodeSegChange));
sewardj17c11042006-10-15 01:26:40 +00002033 vg_assert(changes);
2034
2035 /* Now re-read /proc/<pid>/map and acquire a change set */
2036 VG_(am_aix5_reread_procmap)( changes, &changes_used );
2037 vg_assert(changes_used >= 0 && changes_used <= changes_size);
2038
2039 /* And notify m_debuginfo of the changes. */
sewardj9c606bd2008-09-18 18:12:50 +00002040 for (i = 0; i < changes_used; i++) {
2041 anu.ull = VG_(di_aix5_notify_segchange)(
2042 changes[i].code_start,
2043 changes[i].code_len,
2044 changes[i].data_start,
2045 changes[i].data_len,
2046 changes[i].file_name,
2047 changes[i].mem_name,
2048 changes[i].is_mainexe,
2049 changes[i].acquire
2050 );
2051 if (anu.ull > 0) {
2052 tl_assert(changes[i].acquire);
2053 anu.a = changes[i].code_start; /* is this correct? */
2054 VG_(addToXA)( addr2dihandle, &anu );
2055 }
2056 }
sewardj17c11042006-10-15 01:26:40 +00002057
2058 VG_(free)(changes);
2059 }
njnf76d27a2009-05-28 01:53:07 +00002060# elif defined(VGO_darwin)
2061 { Addr* seg_starts;
2062 Int n_seg_starts;
2063 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
2064 vg_assert(seg_starts && n_seg_starts >= 0);
2065
2066 /* show them all to the debug info reader.
2067 Don't read from V segments (unlike Linux) */
2068 // GrP fixme really?
2069 for (i = 0; i < n_seg_starts; i++)
2070 VG_(di_notify_mmap)( seg_starts[i], False/*don't allow_SkFileV*/ );
2071
2072 VG_(free)( seg_starts );
2073 }
sewardj17c11042006-10-15 01:26:40 +00002074# else
2075# error Unknown OS
2076# endif
sewardj45f4e7c2005-09-27 19:20:21 +00002077
2078 //--------------------------------------------------------------
2079 // Tell aspacem of ownership change of the asm helpers, so that
2080 // m_translate allows them to be translated. However, only do this
2081 // after the initial debug info read, since making a hole in the
2082 // address range for the stage2 binary confuses the debug info reader.
2083 // p: aspacem
2084 //--------------------------------------------------------------
2085 { Bool change_ownership_v_c_OK;
sewardj1a85f4f2006-01-12 21:15:35 +00002086 Addr co_start = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
2087 Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
sewardj45f4e7c2005-09-27 19:20:21 +00002088 VG_(debugLog)(1,"redir",
2089 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
2090 (ULong)co_start, (ULong)co_endPlus-1 );
2091
2092 change_ownership_v_c_OK
2093 = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
2094 vg_assert(change_ownership_v_c_OK);
2095 }
2096
2097 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002098 // Initialise the scheduler (phase 1) [generates tid_main]
2099 // p: none, afaics
2100 //--------------------------------------------------------------
2101 VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
2102 tid_main = VG_(scheduler_init_phase1)();
2103 vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
2104 && tid_main != VG_INVALID_THREADID);
2105 /* Tell the tool about tid_main */
2106 VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
2107
2108 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002109 // Tell the tool about the initial client memory permissions
2110 // p: aspacem
2111 // p: mallocfree
2112 // p: setup_client_stack
2113 // p: setup_client_dataseg
sewardj9c606bd2008-09-18 18:12:50 +00002114 //
2115 // For each segment we tell the client about, look up in
2116 // addr2dihandle as created above, to see if there's a debuginfo
2117 // handle associated with the segment, that we can hand along
2118 // to the tool, to be helpful.
sewardj45f4e7c2005-09-27 19:20:21 +00002119 //--------------------------------------------------------------
2120 VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
2121 { Addr* seg_starts;
2122 Int n_seg_starts;
sewardj45f4e7c2005-09-27 19:20:21 +00002123
sewardj9c606bd2008-09-18 18:12:50 +00002124 tl_assert(addr2dihandle);
2125
tom7c1a19a2008-01-02 10:13:04 +00002126 /* Mark the main thread as running while we tell the tool about
2127 the client memory so that the tool can associate that memory
2128 with the main thread. */
2129 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
2130 VG_(running_tid) = tid_main;
2131
njnac1e0332009-05-08 00:39:31 +00002132 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00002133 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00002134
2135 /* show interesting ones to the tool */
2136 for (i = 0; i < n_seg_starts; i++) {
sewardj9c606bd2008-09-18 18:12:50 +00002137 Word j, n;
sewardj12ab7652006-10-17 02:10:42 +00002138 NSegment const* seg
sewardj17c11042006-10-15 01:26:40 +00002139 = VG_(am_find_nsegment)( seg_starts[i] );
sewardj45f4e7c2005-09-27 19:20:21 +00002140 vg_assert(seg);
2141 if (seg->kind == SkFileC || seg->kind == SkAnonC) {
sewardjc6d86a32009-01-31 15:08:08 +00002142 /* This next assertion is tricky. If it is placed
2143 immediately before this 'if', it very occasionally fails.
2144 Why? Because previous iterations of the loop may have
2145 caused tools (via the new_mem_startup calls) to do
2146 dynamic memory allocation, and that may affect the mapped
2147 segments; in particular it may cause segment merging to
2148 happen. Hence we cannot assume that seg_starts[i], which
2149 reflects the state of the world before we started this
2150 loop, is the same as seg->start, as the latter reflects
2151 the state of the world (viz, mappings) at this particular
2152 iteration of the loop.
2153
2154 Why does moving it inside the 'if' make it safe? Because
2155 any dynamic memory allocation done by the tools will
2156 affect only the state of Valgrind-owned segments, not of
2157 Client-owned segments. And the 'if' guards against that
2158 -- we only get in here for Client-owned segments.
2159
2160 In other words: the loop may change the state of
2161 Valgrind-owned segments as it proceeds. But it should
2162 not cause the Client-owned segments to change. */
2163 vg_assert(seg->start == seg_starts[i]);
sewardj45f4e7c2005-09-27 19:20:21 +00002164 VG_(debugLog)(2, "main",
2165 "tell tool about %010lx-%010lx %c%c%c\n",
2166 seg->start, seg->end,
2167 seg->hasR ? 'r' : '-',
2168 seg->hasW ? 'w' : '-',
2169 seg->hasX ? 'x' : '-' );
sewardj9c606bd2008-09-18 18:12:50 +00002170 /* search addr2dihandle to see if we have an entry
2171 matching seg->start. */
2172 n = VG_(sizeXA)( addr2dihandle );
2173 for (j = 0; j < n; j++) {
2174 Addr_n_ULong* anl = VG_(indexXA)( addr2dihandle, j );
2175 if (anl->a == seg->start) {
2176 tl_assert(anl->ull > 0); /* check it's a valid handle */
2177 break;
2178 }
2179 }
2180 vg_assert(j >= 0 && j <= n);
sewardj45f4e7c2005-09-27 19:20:21 +00002181 VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
sewardj9c606bd2008-09-18 18:12:50 +00002182 seg->hasR, seg->hasW, seg->hasX,
2183 /* and the retrieved debuginfo handle, if any */
2184 j < n
2185 ? ((Addr_n_ULong*)VG_(indexXA)( addr2dihandle, j ))->ull
2186 : 0 );
sewardj45f4e7c2005-09-27 19:20:21 +00002187 }
2188 }
2189
2190 VG_(free)( seg_starts );
sewardj9c606bd2008-09-18 18:12:50 +00002191 VG_(deleteXA)( addr2dihandle );
sewardj45f4e7c2005-09-27 19:20:21 +00002192
2193 /* Also do the initial stack permissions. */
sewardj12ab7652006-10-17 02:10:42 +00002194 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002195 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj17c11042006-10-15 01:26:40 +00002196 vg_assert(seg);
2197 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002198 vg_assert(the_iifii.initial_client_SP >= seg->start);
2199 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardj17c11042006-10-15 01:26:40 +00002200# if defined(VGO_aix5)
2201 VG_(clstk_base) = seg->start;
2202 VG_(clstk_end) = seg->end;
2203# endif
sewardj45f4e7c2005-09-27 19:20:21 +00002204
sewardj17c11042006-10-15 01:26:40 +00002205 /* Stuff below the initial SP is unaddressable. Take into
2206 account any ABI-mandated space below the stack pointer that
2207 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
2208 will have allocated an extra page if a red zone is required,
2209 to be on the safe side. */
sewardjf9d2f9b2006-11-17 20:00:57 +00002210 vg_assert(the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
2211 >= seg->start);
sewardj17c11042006-10-15 01:26:40 +00002212 VG_TRACK( die_mem_stack,
2213 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00002214 the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
2215 - seg->start );
sewardj17c11042006-10-15 01:26:40 +00002216 VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
2217 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00002218 the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
sewardj17c11042006-10-15 01:26:40 +00002219 }
sewardj45f4e7c2005-09-27 19:20:21 +00002220
2221 /* Also the assembly helpers. */
2222 VG_TRACK( new_mem_startup,
2223 (Addr)&VG_(trampoline_stuff_start),
sewardjc6527d62006-02-13 17:54:31 +00002224 (Addr)&VG_(trampoline_stuff_end)
2225 - (Addr)&VG_(trampoline_stuff_start),
sewardj45f4e7c2005-09-27 19:20:21 +00002226 False, /* readable? */
2227 False, /* writable? */
sewardj9c606bd2008-09-18 18:12:50 +00002228 True /* executable? */,
2229 0 /* di_handle: no associated debug info */ );
tom7c1a19a2008-01-02 10:13:04 +00002230
2231 /* Clear the running thread indicator */
2232 VG_(running_tid) = VG_INVALID_THREADID;
2233 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
sewardj45f4e7c2005-09-27 19:20:21 +00002234 }
2235
2236 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002237 // Initialise the scheduler (phase 2)
2238 // p: Initialise the scheduler (phase 1) [for tid_main]
nethercote71980f02004-01-24 18:18:54 +00002239 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
sewardj45f4e7c2005-09-27 19:20:21 +00002240 // p: setup_client_stack
nethercote71980f02004-01-24 18:18:54 +00002241 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002242 VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
sewardj12ab7652006-10-17 02:10:42 +00002243 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002244 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj45f4e7c2005-09-27 19:20:21 +00002245 vg_assert(seg);
2246 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002247 vg_assert(the_iifii.initial_client_SP >= seg->start);
2248 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardjde764e82007-11-09 23:13:22 +00002249 VG_(scheduler_init_phase2)( tid_main,
2250 seg->end, the_iifii.clstack_max_size );
sewardj45f4e7c2005-09-27 19:20:21 +00002251 }
nethercote71980f02004-01-24 18:18:54 +00002252
2253 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00002254 // Set up state for the root thread
sewardjb5f6f512005-03-10 23:59:00 +00002255 // p: ?
sewardj17c11042006-10-15 01:26:40 +00002256 // setup_scheduler() [for sched-specific thread 1 stuff]
sewardjf9d2f9b2006-11-17 20:00:57 +00002257 // VG_(ii_create_image) [for 'the_iicii' initial info]
sewardj2a99cf62004-11-24 10:44:19 +00002258 //--------------------------------------------------------------
sewardjf9d2f9b2006-11-17 20:00:57 +00002259 VG_(debugLog)(1, "main", "Finalise initial image\n");
2260 VG_(ii_finalise_image)( the_iifii );
njnea4b28c2004-11-30 16:04:58 +00002261
sewardj2a99cf62004-11-24 10:44:19 +00002262 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002263 // Initialise the signal handling subsystem
sewardjb5f6f512005-03-10 23:59:00 +00002264 // p: n/a
nethercote71980f02004-01-24 18:18:54 +00002265 //--------------------------------------------------------------
2266 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
sewardj1fbc1a52005-04-25 02:05:54 +00002267 VG_(debugLog)(1, "main", "Initialise signal management\n");
njncda2f0f2009-05-18 02:12:08 +00002268 /* Check that the kernel-interface signal definitions look sane */
2269 VG_(vki_do_initial_consistency_checks)();
2270 /* .. and go on to use them. */
nethercote71980f02004-01-24 18:18:54 +00002271 VG_(sigstartup_actions)();
2272
2273 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002274 // Read suppression file
sewardj95d86c02007-12-18 01:49:23 +00002275 // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
nethercote71980f02004-01-24 18:18:54 +00002276 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00002277 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
2278 VG_(debugLog)(1, "main", "Load suppressions\n");
nethercote71980f02004-01-24 18:18:54 +00002279 VG_(load_suppressions)();
sewardj1fbc1a52005-04-25 02:05:54 +00002280 }
nethercote71980f02004-01-24 18:18:54 +00002281
2282 //--------------------------------------------------------------
rjwalsh0140af52005-06-04 20:42:33 +00002283 // register client stack
2284 //--------------------------------------------------------------
njn945ed2e2005-06-24 03:28:30 +00002285 VG_(clstk_id) = VG_(register_stack)(VG_(clstk_base), VG_(clstk_end));
rjwalsh0140af52005-06-04 20:42:33 +00002286
2287 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002288 // Show the address space state so far
2289 //--------------------------------------------------------------
2290 VG_(debugLog)(1, "main", "\n");
2291 VG_(debugLog)(1, "main", "\n");
2292 VG_(am_show_nsegments)(1,"Memory layout at client startup");
2293 VG_(debugLog)(1, "main", "\n");
2294 VG_(debugLog)(1, "main", "\n");
2295
2296 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002297 // Run!
2298 //--------------------------------------------------------------
sewardj71bc3cb2005-05-19 00:25:45 +00002299 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002300 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00002301 VG_(elapsed_wallclock_time)(buf);
sewardj738856f2009-07-15 14:48:32 +00002302 VG_(printf_xml_no_f_c)( "<status>\n"
2303 " <state>RUNNING</state>\n"
2304 " <time>%t</time>\n"
2305 "</status>\n",
2306 buf );
2307 VG_(printf_xml_no_f_c)( "\n" );
sewardj71bc3cb2005-05-19 00:25:45 +00002308 }
2309
sewardj1fbc1a52005-04-25 02:05:54 +00002310 VG_(debugLog)(1, "main", "Running thread 1\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002311
sewardj1d887112005-05-30 21:44:08 +00002312 /* As a result of the following call, the last thread standing
sewardj1ae3f3a2005-09-28 10:47:38 +00002313 eventually winds up running shutdown_actions_NORETURN
2314 just below. Unfortunately, simply exporting said function
2315 causes m_main to be part of a module cycle, which is pretty
2316 nonsensical. So instead of doing that, the address of said
2317 function is stored in a global variable 'owned' by m_syswrap,
2318 and it uses that function pointer to get back here when it needs
2319 to. */
2320
2321 /* Set continuation address. */
2322 VG_(address_of_m_main_shutdown_actions_NORETURN)
2323 = & shutdown_actions_NORETURN;
2324
2325 /* Run the first thread, eventually ending up at the continuation
2326 address. */
njnaf839f52005-06-23 03:27:57 +00002327 VG_(main_thread_wrapper_NORETURN)(1);
nethercote71980f02004-01-24 18:18:54 +00002328
sewardj1d887112005-05-30 21:44:08 +00002329 /*NOTREACHED*/
2330 vg_assert(0);
sewardjb5f6f512005-03-10 23:59:00 +00002331}
2332
sewardj17c11042006-10-15 01:26:40 +00002333/* Do everything which needs doing when the last thread exits or when
2334 a thread exits requesting a complete process exit (exit on AIX).
2335
2336 We enter here holding The Lock. For the case VgSrc_ExitProcess we
2337 must never release it, because to do so would allow other threads
2338 to continue after the system is ostensibly shut down. So we must
2339 go to our grave, so to speak, holding the lock.
2340
2341 In fact, there is never any point in releasing the lock at this
2342 point - we have it, we're shutting down the entire system, and
2343 for the case VgSrc_ExitProcess doing so positively causes trouble.
2344 So don't.
2345
2346 The final_tidyup call makes a bit of a nonsense of the ExitProcess
2347 case, since it will run the libc_freeres function, thus allowing
2348 other lurking threads to run again. Hmm. */
sewardjb5f6f512005-03-10 23:59:00 +00002349
sewardj1ae3f3a2005-09-28 10:47:38 +00002350static
2351void shutdown_actions_NORETURN( ThreadId tid,
2352 VgSchedReturnCode tids_schedretcode )
sewardjb5f6f512005-03-10 23:59:00 +00002353{
sewardj1d887112005-05-30 21:44:08 +00002354 VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
sewardj17c11042006-10-15 01:26:40 +00002355 VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
sewardj1d887112005-05-30 21:44:08 +00002356
sewardjb5f6f512005-03-10 23:59:00 +00002357 vg_assert(VG_(is_running_thread)(tid));
2358
sewardj12ab7652006-10-17 02:10:42 +00002359 vg_assert(tids_schedretcode == VgSrc_ExitThread
2360 || tids_schedretcode == VgSrc_ExitProcess
2361 || tids_schedretcode == VgSrc_FatalSig );
sewardjb5f6f512005-03-10 23:59:00 +00002362
sewardj12ab7652006-10-17 02:10:42 +00002363 if (tids_schedretcode == VgSrc_ExitThread) {
sewardjb5f6f512005-03-10 23:59:00 +00002364
sewardj17c11042006-10-15 01:26:40 +00002365 // We are the last surviving thread. Right?
2366 vg_assert( VG_(count_living_threads)() == 1 );
sewardjb5f6f512005-03-10 23:59:00 +00002367
sewardj17c11042006-10-15 01:26:40 +00002368 // Wait for all other threads to exit.
2369 // jrs: Huh? but they surely are already gone
2370 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002371
sewardj17c11042006-10-15 01:26:40 +00002372 // Clean the client up before the final report
2373 // this causes the libc_freeres function to run
2374 final_tidyup(tid);
2375
2376 /* be paranoid */
2377 vg_assert(VG_(is_running_thread)(tid));
2378 vg_assert(VG_(count_living_threads)() == 1);
2379
2380 } else {
2381
2382 // We may not be the last surviving thread. However, we
2383 // want to shut down the entire process. We hold the lock
2384 // and we need to keep hold of it all the way out, in order
2385 // that none of the other threads ever run again.
2386 vg_assert( VG_(count_living_threads)() >= 1 );
2387
sewardj17c11042006-10-15 01:26:40 +00002388 // Clean the client up before the final report
2389 // this causes the libc_freeres function to run
2390 // perhaps this is unsafe, as per comment above
2391 final_tidyup(tid);
2392
2393 /* be paranoid */
2394 vg_assert(VG_(is_running_thread)(tid));
2395 vg_assert(VG_(count_living_threads)() >= 1);
2396 }
sewardjb5f6f512005-03-10 23:59:00 +00002397
2398 VG_(threads)[tid].status = VgTs_Empty;
nethercote71980f02004-01-24 18:18:54 +00002399 //--------------------------------------------------------------
sewardj738856f2009-07-15 14:48:32 +00002400 // Finalisation: cleanup, messages, etc. Order not so important, only
nethercote71980f02004-01-24 18:18:54 +00002401 // affects what order the messages come.
2402 //--------------------------------------------------------------
njnb6267bd2009-08-12 00:14:16 +00002403 // First thing in the post-amble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00002404 if (VG_(clo_xml))
2405 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00002406 else if (VG_(clo_verbosity) > 0)
2407 VG_(message)(Vg_UserMsg, "\n");
nethercote71980f02004-01-24 18:18:54 +00002408
sewardj71bc3cb2005-05-19 00:25:45 +00002409 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002410 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00002411 VG_(elapsed_wallclock_time)(buf);
sewardj738856f2009-07-15 14:48:32 +00002412 VG_(printf_xml_no_f_c)( "<status>\n"
2413 " <state>FINISHED</state>\n"
2414 " <time>%t</time>\n"
njnb6267bd2009-08-12 00:14:16 +00002415 "</status>\n"
2416 "\n",
sewardj738856f2009-07-15 14:48:32 +00002417 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00002418 }
2419
nethercote71980f02004-01-24 18:18:54 +00002420 /* Print out file descriptor summary and stats. */
2421 if (VG_(clo_track_fds))
nethercote3a42fb82004-08-03 18:08:50 +00002422 VG_(show_open_fds)();
nethercote71980f02004-01-24 18:18:54 +00002423
sewardj2d9e8742009-08-07 15:46:56 +00002424 /* Call the tool's finalisation function. This makes Memcheck's
2425 leak checker run, and possibly chuck a bunch of leak errors into
2426 the error management machinery. */
2427 VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
nethercote71980f02004-01-24 18:18:54 +00002428
sewardj2d9e8742009-08-07 15:46:56 +00002429 /* Show the error counts. */
sewardj7ca100d2009-08-15 23:05:34 +00002430 if (VG_(clo_xml)
2431 && (VG_(needs).core_errors || VG_(needs).tool_errors)) {
sewardj2d9e8742009-08-07 15:46:56 +00002432 VG_(show_error_counts_as_XML)();
sewardj738856f2009-07-15 14:48:32 +00002433 }
sewardj2d9e8742009-08-07 15:46:56 +00002434
2435 /* In XML mode, this merely prints the used suppressions. */
2436 if (VG_(needs).core_errors || VG_(needs).tool_errors)
2437 VG_(show_all_errors)();
nethercote71980f02004-01-24 18:18:54 +00002438
sewardj71bc3cb2005-05-19 00:25:45 +00002439 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00002440 VG_(printf_xml)("\n");
2441 VG_(printf_xml)("</valgrindoutput>\n");
2442 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00002443 }
2444
nethercote885dd912004-08-03 23:14:00 +00002445 VG_(sanity_check_general)( True /*include expensive checks*/ );
nethercote71980f02004-01-24 18:18:54 +00002446
sewardj2d9e8742009-08-07 15:46:56 +00002447 if (VG_(clo_stats))
nethercote3a42fb82004-08-03 18:08:50 +00002448 print_all_stats();
nethercote71980f02004-01-24 18:18:54 +00002449
sewardj9c606bd2008-09-18 18:12:50 +00002450 /* Show a profile of the heap(s) at shutdown. Optionally, first
2451 throw away all the debug info, as that makes it easy to spot
2452 leaks in the debuginfo reader. */
2453 if (VG_(clo_profile_heap)) {
2454 if (0) VG_(di_discard_ALL_debuginfo)();
2455 VG_(print_arena_cc_analysis)();
2456 }
2457
njn2025cf92005-06-26 20:44:48 +00002458 if (VG_(clo_profile_flags) > 0) {
sewardj5471ec62006-10-17 13:58:17 +00002459 #define N_MAX 200
njn2025cf92005-06-26 20:44:48 +00002460 BBProfEntry tops[N_MAX];
2461 ULong score_total = VG_(get_BB_profile) (tops, N_MAX);
2462 show_BB_profile(tops, N_MAX, score_total);
2463 }
sewardjfa8ec112005-01-19 11:55:34 +00002464
sewardj8b635a42004-11-22 19:01:47 +00002465 /* Print Vex storage stats */
sewardjbf426512005-01-17 18:35:30 +00002466 if (0)
2467 LibVEX_ShowAllocStats();
sewardj1d887112005-05-30 21:44:08 +00002468
sewardj738856f2009-07-15 14:48:32 +00002469 /* Flush any output cached by previous calls to VG_(message). */
2470 VG_(message_flush)();
2471
njn8aa35852005-06-10 22:59:56 +00002472 /* Ok, finally exit in the os-specific way, according to the scheduler's
2473 return code. In short, if the (last) thread exited by calling
2474 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2475 signal, terminate the entire system with that same fatal signal. */
2476 VG_(debugLog)(1, "core_os",
njn7b85dd52005-06-12 17:26:29 +00002477 "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
njn8aa35852005-06-10 22:59:56 +00002478
njn8aa35852005-06-10 22:59:56 +00002479 switch (tids_schedretcode) {
sewardj12ab7652006-10-17 02:10:42 +00002480 case VgSrc_ExitThread: /* the normal way out (Linux) */
2481 case VgSrc_ExitProcess: /* the normal way out (AIX) */
sewardjb9779082006-05-12 23:50:15 +00002482 /* Change the application return code to user's return code,
2483 if an error was found */
2484 if (VG_(clo_error_exitcode) > 0
2485 && VG_(get_n_errs_found)() > 0) {
2486 VG_(exit)( VG_(clo_error_exitcode) );
2487 } else {
2488 /* otherwise, return the client's exit code, in the normal
2489 way. */
2490 VG_(exit)( VG_(threads)[tid].os_state.exitcode );
2491 }
njn8aa35852005-06-10 22:59:56 +00002492 /* NOT ALIVE HERE! */
sewardj17c11042006-10-15 01:26:40 +00002493 VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
njn8aa35852005-06-10 22:59:56 +00002494 break; /* what the hell :) */
2495
2496 case VgSrc_FatalSig:
2497 /* We were killed by a fatal signal, so replicate the effect */
2498 vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
2499 VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
njnf76d27a2009-05-28 01:53:07 +00002500 /* we shouldn't be alive at this point. But VG_(kill_self)
2501 sometimes fails with EPERM on Darwin, for unclear reasons. */
2502# if defined(VGO_darwin)
2503 VG_(debugLog)(0, "main", "VG_(kill_self) failed. Exiting normally.\n");
2504 VG_(exit)(0); /* bogus, but we really need to exit now */
2505 /* fall through .. */
2506# endif
njn8aa35852005-06-10 22:59:56 +00002507 VG_(core_panic)("main(): signal was supposed to be fatal");
2508 break;
2509
2510 default:
2511 VG_(core_panic)("main(): unexpected scheduler return code");
2512 }
njne96be672005-05-08 19:08:54 +00002513}
sewardj8b635a42004-11-22 19:01:47 +00002514
sewardj1ae3f3a2005-09-28 10:47:38 +00002515/* -------------------- */
2516
2517/* Final clean-up before terminating the process.
2518 Clean up the client by calling __libc_freeres() (if requested)
2519 This is Linux-specific?
njnf76d27a2009-05-28 01:53:07 +00002520 GrP fixme glibc-specific, anyway
sewardj1ae3f3a2005-09-28 10:47:38 +00002521*/
2522static void final_tidyup(ThreadId tid)
2523{
njnf76d27a2009-05-28 01:53:07 +00002524#if !defined(VGO_darwin)
sewardjcf951812006-01-17 02:22:21 +00002525# if defined(VGP_ppc64_linux)
2526 Addr r2;
2527# endif
sewardj0ec07f32006-01-12 12:32:32 +00002528 Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
sewardj1ae3f3a2005-09-28 10:47:38 +00002529
2530 vg_assert(VG_(is_running_thread)(tid));
2531
2532 if ( !VG_(needs).libc_freeres ||
2533 !VG_(clo_run_libc_freeres) ||
sewardj0ec07f32006-01-12 12:32:32 +00002534 0 == __libc_freeres_wrapper )
sewardj1ae3f3a2005-09-28 10:47:38 +00002535 return; /* can't/won't do it */
sewardj17c11042006-10-15 01:26:40 +00002536# if defined(VGO_aix5)
2537 return; /* inapplicable on non-Linux platforms */
2538# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002539
sewardjcf951812006-01-17 02:22:21 +00002540# if defined(VGP_ppc64_linux)
2541 r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
2542 if (r2 == 0) {
2543 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002544 "Caught __NR_exit, but can't run __libc_freeres()\n");
sewardjcf951812006-01-17 02:22:21 +00002545 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002546 " since cannot establish TOC pointer for it.\n");
sewardjcf951812006-01-17 02:22:21 +00002547 return;
2548 }
2549# endif
2550
sewardj1ae3f3a2005-09-28 10:47:38 +00002551 if (VG_(clo_verbosity) > 2 ||
2552 VG_(clo_trace_syscalls) ||
2553 VG_(clo_trace_sched))
2554 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00002555 "Caught __NR_exit; running __libc_freeres()\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002556
sewardj0ec07f32006-01-12 12:32:32 +00002557 /* set thread context to point to libc_freeres_wrapper */
sewardj1a85f4f2006-01-12 21:15:35 +00002558 /* ppc64-linux note: __libc_freeres_wrapper gives us the real
2559 function entry point, not a fn descriptor, so can use it
2560 directly. However, we need to set R2 (the toc pointer)
2561 appropriately. */
sewardj1ae3f3a2005-09-28 10:47:38 +00002562 VG_(set_IP)(tid, __libc_freeres_wrapper);
sewardjcf951812006-01-17 02:22:21 +00002563# if defined(VGP_ppc64_linux)
2564 VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
2565# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002566
2567 /* Block all blockable signals by copying the real block state into
2568 the thread's block state*/
2569 VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
2570 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
2571
2572 /* and restore handlers to default */
2573 VG_(set_default_handler)(VKI_SIGSEGV);
2574 VG_(set_default_handler)(VKI_SIGBUS);
2575 VG_(set_default_handler)(VKI_SIGILL);
2576 VG_(set_default_handler)(VKI_SIGFPE);
2577
2578 // We were exiting, so assert that...
2579 vg_assert(VG_(is_exiting)(tid));
2580 // ...but now we're not again
2581 VG_(threads)[tid].exitreason = VgSrc_None;
2582
2583 // run until client thread exits - ideally with LIBC_FREERES_DONE,
2584 // but exit/exitgroup/signal will do
2585 VG_(scheduler)(tid);
2586
2587 vg_assert(VG_(is_exiting)(tid));
njnf76d27a2009-05-28 01:53:07 +00002588#endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002589}
2590
sewardj45f4e7c2005-09-27 19:20:21 +00002591
2592/*====================================================================*/
njn49f80e82009-05-21 01:25:43 +00002593/*=== Getting to main() alive: LINUX ===*/
sewardj45f4e7c2005-09-27 19:20:21 +00002594/*====================================================================*/
2595
sewardj17c11042006-10-15 01:26:40 +00002596#if defined(VGO_linux)
2597
sewardj45f4e7c2005-09-27 19:20:21 +00002598/* If linking of the final executables is done with glibc present,
2599 then Valgrind starts at main() above as usual, and all of the
2600 following code is irrelevant.
2601
2602 However, this is not the intended mode of use. The plan is to
2603 avoid linking against glibc, by giving gcc the flags
2604 -nodefaultlibs -lgcc -nostartfiles at startup.
2605
2606 From this derive two requirements:
2607
2608 1. gcc may emit calls to memcpy and memset to deal with structure
2609 assignments etc. Since we have chosen to ignore all the
2610 "normal" supporting libraries, we have to provide our own
2611 implementations of them. No problem.
2612
2613 2. We have to provide a symbol "_start", to which the kernel
2614 hands control at startup. Hence the code below.
2615*/
2616
2617/* ---------------- Requirement 1 ---------------- */
2618
sewardj17c11042006-10-15 01:26:40 +00002619void* memcpy(void *dest, const void *src, SizeT n);
2620void* memcpy(void *dest, const void *src, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002621 return VG_(memcpy)(dest,src,n);
2622}
sewardj17c11042006-10-15 01:26:40 +00002623void* memset(void *s, int c, SizeT n);
2624void* memset(void *s, int c, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002625 return VG_(memset)(s,c,n);
2626}
2627
bart82616e12010-06-13 13:46:24 +00002628/* BVA: abort() for those platforms that need it (PPC and ARM). */
2629void abort(void);
2630void abort(void){
2631 VG_(printf)("Something called raise().\n");
2632 vg_assert(0);
2633}
2634
sewardj59570ff2010-01-01 11:59:33 +00002635/* EAZG: ARM's EABI will call floating point exception handlers in
2636 libgcc which boil down to an abort or raise, that's usually defined
2637 in libc. Instead, define them here. */
2638#if defined(VGP_arm_linux)
2639void raise(void);
2640void raise(void){
2641 VG_(printf)("Something called raise().\n");
2642 vg_assert(0);
2643}
2644
sewardj59570ff2010-01-01 11:59:33 +00002645void __aeabi_unwind_cpp_pr0(void);
2646void __aeabi_unwind_cpp_pr0(void){
2647 VG_(printf)("Something called __aeabi_unwind_cpp_pr0()\n");
2648 vg_assert(0);
2649}
2650#endif
2651
sewardj45f4e7c2005-09-27 19:20:21 +00002652/* ---------------- Requirement 2 ---------------- */
2653
2654/* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2655 comment, which explains how the stack looks right at process start
2656 (when _start is jumped to). Hence _start passes %esp to
sewardj17c11042006-10-15 01:26:40 +00002657 _start_in_C_linux, which extracts argc/argv/envp and starts up
sewardj45f4e7c2005-09-27 19:20:21 +00002658 correctly. */
2659
2660/* This is the canonical entry point, usually the first thing in the text
2661 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2662 point runs, most registers' values are unspecified, except for:
2663
2664 %edx Contains a function pointer to be registered with `atexit'.
2665 This is how the dynamic linker arranges to have DT_FINI
2666 functions called for shared libraries that have been loaded
2667 before this code runs.
2668
2669 %esp The stack contains the arguments and environment:
2670 0(%esp) argc
2671 4(%esp) argv[0]
2672 ...
2673 (4*argc)(%esp) NULL
2674 (4*(argc+1))(%esp) envp[0]
2675 ...
2676 NULL
2677*/
2678
2679/* The kernel hands control to _start, which extracts the initial
sewardj17c11042006-10-15 01:26:40 +00002680 stack pointer and calls onwards to _start_in_C_linux. This also switches
sewardja48a4932005-09-29 11:09:56 +00002681 the new stack. */
sewardj45f4e7c2005-09-27 19:20:21 +00002682#if defined(VGP_x86_linux)
2683asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002684 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002685 "\t.globl _start\n"
2686 "\t.type _start,@function\n"
2687 "_start:\n"
2688 /* set up the new stack in %eax */
sewardjfdf91b42005-09-28 00:53:09 +00002689 "\tmovl $vgPlain_interim_stack, %eax\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002690 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2691 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2692 "\tsubl $16, %eax\n"
2693 "\tandl $~15, %eax\n"
2694 /* install it, and collect the original one */
2695 "\txchgl %eax, %esp\n"
sewardj17c11042006-10-15 01:26:40 +00002696 /* call _start_in_C_linux, passing it the startup %esp */
sewardj45f4e7c2005-09-27 19:20:21 +00002697 "\tpushl %eax\n"
sewardj17c11042006-10-15 01:26:40 +00002698 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002699 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002700 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002701);
2702#elif defined(VGP_amd64_linux)
2703asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002704 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002705 "\t.globl _start\n"
2706 "\t.type _start,@function\n"
2707 "_start:\n"
2708 /* set up the new stack in %rdi */
sewardjfdf91b42005-09-28 00:53:09 +00002709 "\tmovq $vgPlain_interim_stack, %rdi\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002710 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2711 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2712 "\tandq $~15, %rdi\n"
2713 /* install it, and collect the original one */
2714 "\txchgq %rdi, %rsp\n"
sewardj17c11042006-10-15 01:26:40 +00002715 /* call _start_in_C_linux, passing it the startup %rsp */
2716 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002717 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002718 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002719);
sewardja48a4932005-09-29 11:09:56 +00002720#elif defined(VGP_ppc32_linux)
2721asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002722 ".text\n"
sewardja48a4932005-09-29 11:09:56 +00002723 "\t.globl _start\n"
2724 "\t.type _start,@function\n"
2725 "_start:\n"
2726 /* set up the new stack in r16 */
2727 "\tlis 16,vgPlain_interim_stack@ha\n"
2728 "\tla 16,vgPlain_interim_stack@l(16)\n"
2729 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2730 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2731 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2732 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2733 "\tadd 16,17,16\n"
2734 "\tadd 16,18,16\n"
2735 "\trlwinm 16,16,0,0,27\n"
2736 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2737 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2738 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002739 call _start_in_C_linux, passing it the initial SP. */
sewardja48a4932005-09-29 11:09:56 +00002740 "\tmr 3,1\n"
2741 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002742 "\tbl _start_in_C_linux\n"
sewardja48a4932005-09-29 11:09:56 +00002743 "\ttrap\n"
sewardj2fedc642005-11-19 02:02:57 +00002744 ".previous\n"
sewardja48a4932005-09-29 11:09:56 +00002745);
sewardj2c48c7b2005-11-29 13:05:56 +00002746#elif defined(VGP_ppc64_linux)
2747asm("\n"
cerion21082042005-12-06 19:07:08 +00002748 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2749 So we must have one, and that is what goes into the .opd section. */
cerion297c88f2005-12-22 15:53:12 +00002750 "\t.align 2\n"
cerion21082042005-12-06 19:07:08 +00002751 "\t.global _start\n"
2752 "\t.section \".opd\",\"aw\"\n"
2753 "\t.align 3\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002754 "_start:\n"
cerion21082042005-12-06 19:07:08 +00002755 "\t.quad ._start,.TOC.@tocbase,0\n"
2756 "\t.previous\n"
2757 "\t.type ._start,@function\n"
2758 "\t.global ._start\n"
2759 "._start:\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002760 /* set up the new stack in r16 */
2761 "\tlis 16, vgPlain_interim_stack@highest\n"
2762 "\tori 16,16,vgPlain_interim_stack@higher\n"
2763 "\tsldi 16,16,32\n"
2764 "\toris 16,16,vgPlain_interim_stack@h\n"
2765 "\tori 16,16,vgPlain_interim_stack@l\n"
2766 "\txor 17,17,17\n"
2767 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2768 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2769 "\txor 18,18,18\n"
2770 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2771 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2772 "\tadd 16,17,16\n"
2773 "\tadd 16,18,16\n"
2774 "\trldicr 16,16,0,59\n"
2775 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2776 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2777 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002778 call _start_in_C_linux, passing it the initial SP. */
sewardj2c48c7b2005-11-29 13:05:56 +00002779 "\tmr 3,1\n"
2780 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002781 "\tbl ._start_in_C_linux\n"
cerion21082042005-12-06 19:07:08 +00002782 "\tnop\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002783 "\ttrap\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002784);
sewardj59570ff2010-01-01 11:59:33 +00002785#elif defined(VGP_arm_linux)
2786asm("\n"
2787 "\t.align 2\n"
2788 "\t.global _start\n"
2789 "_start:\n"
2790 "\tldr r0, [pc, #36]\n"
2791 "\tldr r1, [pc, #36]\n"
2792 "\tadd r0, r1, r0\n"
2793 "\tldr r1, [pc, #32]\n"
2794 "\tadd r0, r1, r0\n"
2795 "\tmvn r1, #15\n"
2796 "\tand r0, r0, r1\n"
2797 "\tmov r1, sp\n"
2798 "\tmov sp, r0\n"
2799 "\tmov r0, r1\n"
2800 "\tb _start_in_C_linux\n"
2801 "\t.word vgPlain_interim_stack\n"
2802 "\t.word "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
2803 "\t.word "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
2804);
sewardj45f4e7c2005-09-27 19:20:21 +00002805#else
njn49f80e82009-05-21 01:25:43 +00002806# error "Unknown linux platform"
sewardj45f4e7c2005-09-27 19:20:21 +00002807#endif
2808
sewardje66f2e02006-12-30 17:45:08 +00002809/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
2810#define _GNU_SOURCE
2811#define _FILE_OFFSET_BITS 64
2812/* This is in order to get AT_NULL and AT_PAGESIZE. */
2813#include <elf.h>
2814/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
2815
sewardj45f4e7c2005-09-27 19:20:21 +00002816/* Avoid compiler warnings: this fn _is_ used, but labelling it
2817 'static' causes gcc to complain it isn't. */
sewardj17c11042006-10-15 01:26:40 +00002818void _start_in_C_linux ( UWord* pArgc );
2819void _start_in_C_linux ( UWord* pArgc )
sewardj45f4e7c2005-09-27 19:20:21 +00002820{
2821 Int r;
2822 Word argc = pArgc[0];
2823 HChar** argv = (HChar**)&pArgc[1];
2824 HChar** envp = (HChar**)&pArgc[1+argc+1];
sewardjf9d2f9b2006-11-17 20:00:57 +00002825
2826 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2827 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2828
2829 the_iicii.sp_at_startup = (Addr)pArgc;
2830
sewardje66f2e02006-12-30 17:45:08 +00002831# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
2832 {
2833 /* ppc/ppc64 can be configured with different page sizes.
2834 Determine this early. This is an ugly hack and really should
2835 be moved into valgrind_main. */
2836 UWord *sp = &pArgc[1+argc+1];
2837 while (*sp++ != 0)
2838 ;
2839 for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
2840 if (*sp == AT_PAGESZ) {
2841 VKI_PAGE_SIZE = sp[1];
2842 for (VKI_PAGE_SHIFT = 12;
2843 VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
2844 if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
2845 break;
2846 }
2847 }
2848# endif
2849
sewardjf9d2f9b2006-11-17 20:00:57 +00002850 r = valgrind_main( (Int)argc, argv, envp );
sewardj17c11042006-10-15 01:26:40 +00002851 /* NOTREACHED */
sewardj45f4e7c2005-09-27 19:20:21 +00002852 VG_(exit)(r);
2853}
2854
sewardj17c11042006-10-15 01:26:40 +00002855
2856/*====================================================================*/
2857/*=== Getting to main() alive: AIX5 ===*/
2858/*====================================================================*/
2859
njn49f80e82009-05-21 01:25:43 +00002860#elif defined(VGO_aix5)
sewardj17c11042006-10-15 01:26:40 +00002861
2862/* This is somewhat simpler than the Linux case. _start_valgrind
2863 receives control from the magic piece of code created in this
2864 process' address space by the launcher, via use of ptrace(). At
2865 the point of entry:
2866
2867 - the initial client process image is in memory and ready to roll,
2868 except that we've partially trashed its integer register state
2869 in order to get this far. So ..
2870
2871 - intregs37 holds the client's initial integer register state, so
2872 we can restore it before starting the client on the VCPU.
2873
2874 - we're on the client's stack. This is not good; therefore the
2875 first order of business is to switch to our temporary stack.
2876
2877 - the client's initial argc/v/envp is in r3/r4/r5 (32 bit mode) or
2878 r14/r15/r16 (64 bit mode). They are pulled out of the stashed
2879 integer register state and passed to our main().
2880
2881 The launcher will have played some games with argv. If the launcher
2882 ($prefix/bin/valgrind) was started like this
2883
2884 valgrind [args-for-V] app [args-for-app]
2885
2886 then the launcher will have started the client as
2887
2888 app [args-for-V] app [args-for-app]
2889
2890 m_initimg will have to mess with the client's initial r4/r5
2891 (32-bit) or r15/r16 (64-bit) so that it believes it was execd as
2892 "app [args-for-app]". Well, that's no big deal.
2893*/
2894
2895#include "launcher-aix5-bootblock.h"
2896
2897void _start_in_C_aix5 ( AIX5Bootblock* bootblock );
2898void _start_in_C_aix5 ( AIX5Bootblock* bootblock )
2899{
2900 Int r;
2901 ULong* intregs37;
2902 UWord argc, argv, envp;
2903 __NR_getpid = bootblock->__NR_getpid;
2904 __NR_write = bootblock->__NR_write;
2905 __NR_exit = bootblock->__NR_exit;
2906 __NR_open = bootblock->__NR_open;
2907 __NR_read = bootblock->__NR_read;
2908 __NR_close = bootblock->__NR_close;
sewardjf9d2f9b2006-11-17 20:00:57 +00002909
2910 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2911 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2912
sewardj17c11042006-10-15 01:26:40 +00002913 intregs37 = &bootblock->iregs_pc_cr_lr_ctr_xer[0];
sewardjf9d2f9b2006-11-17 20:00:57 +00002914 the_iicii.intregs37 = intregs37;
2915 the_iicii.bootblock = (void*)bootblock;
2916 the_iicii.adler32_exp = bootblock->adler32;
2917
2918 /* Not important on AIX. */
2919 the_iicii.sp_at_startup = (Addr)0x31415927ULL;
2920
sewardj17c11042006-10-15 01:26:40 +00002921# if defined(VGP_ppc32_aix5)
2922 argc = (UWord)intregs37[3]; /* client's r3 == argc */
2923 argv = (UWord)intregs37[4];
2924 envp = (UWord)intregs37[5];
2925# else /* defined(VGP_ppc64_aix5) */
2926 argc = (UWord)intregs37[14]; /* client's r14 == argc */
2927 argv = (UWord)intregs37[15];
2928 envp = (UWord)intregs37[16];
2929# endif
sewardjf9d2f9b2006-11-17 20:00:57 +00002930
2931 r = valgrind_main( (Int)argc, (HChar**)argv, (HChar**)envp );
2932
sewardj17c11042006-10-15 01:26:40 +00002933 /* NOTREACHED */
2934 VG_(exit)(r);
2935}
2936
2937/* THE ENTRY POINT */
2938void _start_valgrind ( AIX5Bootblock* bootblock );
2939void _start_valgrind ( AIX5Bootblock* bootblock )
2940{
2941 /* Switch immediately to our temporary stack, and continue. This
2942 is pretty dodgy in that it assumes that gcc does not place on
2943 the stack, anything needed to form the _start_in_C_aix5 call,
2944 since it will be on the old stack. */
2945 register UWord new_r1;
2946 new_r1 = (UWord)&VG_(interim_stack);
2947 new_r1 += VG_STACK_GUARD_SZB; /* step over lower guard page */
2948 new_r1 += VG_STACK_ACTIVE_SZB; /* step to top of active area */
2949 new_r1 -= 512; /* paranoia */
2950 __asm__ __volatile__("mr 1,%0" :/*wr*/
2951 :/*rd*/ "b"(new_r1)
2952 :/*trash*/"r1","memory");
2953 _start_in_C_aix5(bootblock);
2954 /*NOTREACHED*/
2955 VG_(exit)(0);
2956}
2957
sewardj61a1b052008-10-22 00:56:53 +00002958/* At some point in Oct 2008, static linking appeared to stop working
2959 on AIX 5.3. This breaks the build since we link statically. The
2960 linking fails citing absence of the following five symbols as the
2961 reason. In the absence of a better solution, here are stand-ins
2962 for them. Kludge appears to work; presumably said functions,
2963 assuming they are indeed functions, are never called. */
2964void encrypted_pw_passlen ( void ) { vg_assert(0); }
2965void crypt_r ( void ) { vg_assert(0); }
2966void max_history_size ( void ) { vg_assert(0); }
2967void getpass_auto ( void ) { vg_assert(0); }
2968void max_pw_passlen ( void ) { vg_assert(0); }
2969
njn49f80e82009-05-21 01:25:43 +00002970
njnf76d27a2009-05-28 01:53:07 +00002971/*====================================================================*/
2972/*=== Getting to main() alive: darwin ===*/
2973/*====================================================================*/
2974
2975#elif defined(VGO_darwin)
2976
njnea2d6fd2010-07-01 00:20:20 +00002977/*
2978 Memory layout established by kernel:
2979
2980 0(%esp) argc
2981 4(%esp) argv[0]
2982 ...
2983 argv[argc-1]
2984 NULL
2985 envp[0]
2986 ...
2987 envp[n]
2988 NULL
2989 executable name (presumably, a pointer to it)
2990 NULL
2991
2992 Ditto in the 64-bit case, except all offsets from SP are obviously
2993 twice as large.
2994*/
2995
2996/* The kernel hands control to _start, which extracts the initial
2997 stack pointer and calls onwards to _start_in_C_darwin. This also
2998 switches to the new stack. */
2999#if defined(VGP_x86_darwin)
3000asm("\n"
3001 ".text\n"
3002 ".align 2,0x90\n"
3003 "\t.globl __start\n"
3004 "__start:\n"
3005 /* set up the new stack in %eax */
3006 "\tmovl $_vgPlain_interim_stack, %eax\n"
3007 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
3008 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
3009 "\tsubl $16, %eax\n"
3010 "\tandl $~15, %eax\n"
3011 /* install it, and collect the original one */
3012 "\txchgl %eax, %esp\n"
3013 /* call _start_in_C_darwin, passing it the startup %esp */
3014 "\tpushl %eax\n"
3015 "\tcall __start_in_C_darwin\n"
3016 "\tint $3\n"
3017 "\tint $3\n"
3018);
3019#elif defined(VGP_amd64_darwin)
3020asm("\n"
3021 ".text\n"
3022 "\t.globl __start\n"
3023 ".align 3,0x90\n"
3024 "__start:\n"
3025 /* set up the new stack in %rdi */
3026 "\tmovabsq $_vgPlain_interim_stack, %rdi\n"
3027 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
3028 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
3029 "\tandq $~15, %rdi\n"
3030 /* install it, and collect the original one */
3031 "\txchgq %rdi, %rsp\n"
3032 /* call _start_in_C_darwin, passing it the startup %rsp */
3033 "\tcall __start_in_C_darwin\n"
3034 "\tint $3\n"
3035 "\tint $3\n"
3036);
3037#endif
3038
njnf76d27a2009-05-28 01:53:07 +00003039void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2);
3040void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2) {
3041 // skip check
3042 return VG_(memcpy)(dest,src,n);
3043}
3044void* __memset_chk(void *s, int c, SizeT n, SizeT n2);
3045void* __memset_chk(void *s, int c, SizeT n, SizeT n2) {
3046 // skip check
3047 return VG_(memset)(s,c,n);
3048}
3049void bzero(void *s, SizeT n);
3050void bzero(void *s, SizeT n) {
3051 VG_(memset)(s,0,n);
3052}
3053
3054void* memcpy(void *dest, const void *src, SizeT n);
3055void* memcpy(void *dest, const void *src, SizeT n) {
3056 return VG_(memcpy)(dest,src,n);
3057}
3058void* memset(void *s, int c, SizeT n);
3059void* memset(void *s, int c, SizeT n) {
3060 return VG_(memset)(s,c,n);
3061}
3062
njnf76d27a2009-05-28 01:53:07 +00003063/* Avoid compiler warnings: this fn _is_ used, but labelling it
3064 'static' causes gcc to complain it isn't. */
3065void _start_in_C_darwin ( UWord* pArgc );
3066void _start_in_C_darwin ( UWord* pArgc )
3067{
3068 Int r;
njnea2d6fd2010-07-01 00:20:20 +00003069 Int argc = *(Int *)pArgc; // not pArgc[0] on LP64
njnf76d27a2009-05-28 01:53:07 +00003070 HChar** argv = (HChar**)&pArgc[1];
3071 HChar** envp = (HChar**)&pArgc[1+argc+1];
3072
3073 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
3074 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
3075
3076 the_iicii.sp_at_startup = (Addr)pArgc;
3077
3078 r = valgrind_main( (Int)argc, argv, envp );
3079 /* NOTREACHED */
3080 VG_(exit)(r);
3081}
3082
3083
njn49f80e82009-05-21 01:25:43 +00003084#else
3085
3086# error "Unknown OS"
3087#endif
sewardj17c11042006-10-15 01:26:40 +00003088
3089
njnea2d6fd2010-07-01 00:20:20 +00003090////////////////////////////////////////////////////////////////
3091
3092/* For static linking on x86-darwin, we need to supply our own 64-bit
3093 integer division code, else the link dies thusly:
3094
3095 ld_classic: Undefined symbols:
3096 ___udivdi3
3097 ___umoddi3
3098*/
3099#if defined(VGP_x86_darwin)
3100
3101/* Routines for doing signed/unsigned 64 x 64 ==> 64 div and mod
3102 (udivdi3, umoddi3, divdi3, moddi3) using only 32 x 32 ==> 32
3103 division. Cobbled together from
3104
3105 http://www.hackersdelight.org/HDcode/divlu.c
3106 http://www.hackersdelight.org/HDcode/divls.c
3107 http://www.hackersdelight.org/HDcode/newCode/divDouble.c
3108
3109 The code from those three files is covered by the following license,
3110 as it appears at:
3111
3112 http://www.hackersdelight.org/permissions.htm
3113
3114 You are free to use, copy, and distribute any of the code on
3115 this web site, whether modified by you or not. You need not give
3116 attribution. This includes the algorithms (some of which appear
3117 in Hacker's Delight), the Hacker's Assistant, and any code
3118 submitted by readers. Submitters implicitly agree to this.
3119*/
3120
3121/* Long division, unsigned (64/32 ==> 32).
3122 This procedure performs unsigned "long division" i.e., division of a
312364-bit unsigned dividend by a 32-bit unsigned divisor, producing a
312432-bit quotient. In the overflow cases (divide by 0, or quotient
3125exceeds 32 bits), it returns a remainder of 0xFFFFFFFF (an impossible
3126value).
3127 The dividend is u1 and u0, with u1 being the most significant word.
3128The divisor is parameter v. The value returned is the quotient.
3129 Max line length is 57, to fit in hacker.book. */
3130
3131static Int nlz32(UInt x)
3132{
3133 Int n;
3134 if (x == 0) return(32);
3135 n = 0;
3136 if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
3137 if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
3138 if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
3139 if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
3140 if (x <= 0x7FFFFFFF) {n = n + 1;}
3141 return n;
3142}
3143
3144/* 64 x 32 ==> 32 unsigned division, using only 32 x 32 ==> 32
3145 division as a primitive. */
3146static UInt divlu2(UInt u1, UInt u0, UInt v, UInt *r)
3147{
3148 const UInt b = 65536; // Number base (16 bits).
3149 UInt un1, un0, // Norm. dividend LSD's.
3150 vn1, vn0, // Norm. divisor digits.
3151 q1, q0, // Quotient digits.
3152 un32, un21, un10, // Dividend digit pairs.
3153 rhat; // A remainder.
3154 Int s; // Shift amount for norm.
3155
3156 if (u1 >= v) { // If overflow, set rem.
3157 if (r != NULL) // to an impossible value,
3158 *r = 0xFFFFFFFF; // and return the largest
3159 return 0xFFFFFFFF;} // possible quotient.
3160
3161 s = nlz32(v); // 0 <= s <= 31.
3162 v = v << s; // Normalize divisor.
3163 vn1 = v >> 16; // Break divisor up into
3164 vn0 = v & 0xFFFF; // two 16-bit digits.
3165
3166 un32 = (u1 << s) | ((u0 >> (32 - s)) & (-s >> 31));
3167 un10 = u0 << s; // Shift dividend left.
3168
3169 un1 = un10 >> 16; // Break right half of
3170 un0 = un10 & 0xFFFF; // dividend into two digits.
3171
3172 q1 = un32/vn1; // Compute the first
3173 rhat = un32 - q1*vn1; // quotient digit, q1.
3174 again1:
3175 if (q1 >= b || q1*vn0 > b*rhat + un1) {
3176 q1 = q1 - 1;
3177 rhat = rhat + vn1;
3178 if (rhat < b) goto again1;}
3179
3180 un21 = un32*b + un1 - q1*v; // Multiply and subtract.
3181
3182 q0 = un21/vn1; // Compute the second
3183 rhat = un21 - q0*vn1; // quotient digit, q0.
3184 again2:
3185 if (q0 >= b || q0*vn0 > b*rhat + un0) {
3186 q0 = q0 - 1;
3187 rhat = rhat + vn1;
3188 if (rhat < b) goto again2;}
3189
3190 if (r != NULL) // If remainder is wanted,
3191 *r = (un21*b + un0 - q0*v) >> s; // return it.
3192 return q1*b + q0;
3193}
3194
3195
3196/* 64 x 32 ==> 32 signed division, using only 32 x 32 ==> 32 division
3197 as a primitive. */
3198static Int divls(Int u1, UInt u0, Int v, Int *r)
3199{
3200 Int q, uneg, vneg, diff, borrow;
3201
3202 uneg = u1 >> 31; // -1 if u < 0.
3203 if (uneg) { // Compute the absolute
3204 u0 = -u0; // value of the dividend u.
3205 borrow = (u0 != 0);
3206 u1 = -u1 - borrow;}
3207
3208 vneg = v >> 31; // -1 if v < 0.
3209 v = (v ^ vneg) - vneg; // Absolute value of v.
3210
3211 if ((UInt)u1 >= (UInt)v) goto overflow;
3212
3213 q = divlu2(u1, u0, v, (UInt *)r);
3214
3215 diff = uneg ^ vneg; // Negate q if signs of
3216 q = (q ^ diff) - diff; // u and v differed.
3217 if (uneg && r != NULL)
3218 *r = -*r;
3219
3220 if ((diff ^ q) < 0 && q != 0) { // If overflow,
3221 overflow: // set remainder
3222 if (r != NULL) // to an impossible value,
3223 *r = 0x80000000; // and return the largest
3224 q = 0x80000000;} // possible neg. quotient.
3225 return q;
3226}
3227
3228
3229
3230/* This file contains a program for doing 64/64 ==> 64 division, on a
3231machine that does not have that instruction but that does have
3232instructions for "long division" (64/32 ==> 32). Code for unsigned
3233division is given first, followed by a simple program for doing the
3234signed version by using the unsigned version.
3235 These programs are useful in implementing "long long" (64-bit)
3236arithmetic on a machine that has the long division instruction. It will
3237work on 64- and 32-bit machines, provided the compiler implements long
3238long's (64-bit integers). It is desirable that the machine have the
3239Count Leading Zeros instruction.
3240 In the GNU world, these programs are known as __divdi3 and __udivdi3,
3241and similar names are used here.
3242 This material is not in HD, but may be in a future edition.
3243Max line length is 57, to fit in hacker.book. */
3244
3245
3246static Int nlz64(ULong x)
3247{
3248 Int n;
3249 if (x == 0) return(64);
3250 n = 0;
3251 if (x <= 0x00000000FFFFFFFFULL) {n = n + 32; x = x << 32;}
3252 if (x <= 0x0000FFFFFFFFFFFFULL) {n = n + 16; x = x << 16;}
3253 if (x <= 0x00FFFFFFFFFFFFFFULL) {n = n + 8; x = x << 8;}
3254 if (x <= 0x0FFFFFFFFFFFFFFFULL) {n = n + 4; x = x << 4;}
3255 if (x <= 0x3FFFFFFFFFFFFFFFULL) {n = n + 2; x = x << 2;}
3256 if (x <= 0x7FFFFFFFFFFFFFFFULL) {n = n + 1;}
3257 return n;
3258}
3259
3260// ---------------------------- udivdi3 --------------------------------
3261
3262 /* The variables u0, u1, etc. take on only 32-bit values, but they
3263 are declared long long to avoid some compiler warning messages and to
3264 avoid some unnecessary EXTRs that the compiler would put in, to
3265 convert long longs to ints.
3266
3267 First the procedure takes care of the case in which the divisor is a
3268 32-bit quantity. There are two subcases: (1) If the left half of the
3269 dividend is less than the divisor, one execution of DIVU is all that
3270 is required (overflow is not possible). (2) Otherwise it does two
3271 divisions, using the grade school method, with variables used as
3272 suggested below.
3273
3274 q1 q0
3275 ________
3276 v) u1 u0
3277 q1*v
3278 ____
3279 k u0 */
3280
3281/* These macros must be used with arguments of the appropriate type
3282(unsigned long long for DIVU and long long for DIVS. They are
3283simulations of the presumed machines ops. I.e., they look at only the
3284low-order 32 bits of the divisor, they return garbage if the division
3285overflows, and they return garbage in the high-order half of the
3286quotient doubleword.
3287 In practice, these would be replaced with uses of the machine's DIVU
3288and DIVS instructions (e.g., by using the GNU "asm" facility). */
3289
3290static UInt DIVU ( ULong u, UInt v )
3291{
3292 UInt uHi = (UInt)(u >> 32);
3293 UInt uLo = (UInt)u;
3294 return divlu2(uHi, uLo, v, NULL);
3295}
3296
3297static Int DIVS ( Long u, Int v )
3298{
3299 Int uHi = (Int)(u >> 32);
3300 UInt uLo = (UInt)u;
3301 return divls(uHi, uLo, v, NULL);
3302}
3303
3304/* 64 x 64 ==> 64 unsigned division, using only 32 x 32 ==> 32
3305 division as a primitive. */
3306static ULong udivdi3(ULong u, ULong v)
3307{
3308 ULong u0, u1, v1, q0, q1, k, n;
3309
3310 if (v >> 32 == 0) { // If v < 2**32:
3311 if (u >> 32 < v) // If u/v cannot overflow,
3312 return DIVU(u, v) // just do one division.
3313 & 0xFFFFFFFF;
3314 else { // If u/v would overflow:
3315 u1 = u >> 32; // Break u up into two
3316 u0 = u & 0xFFFFFFFF; // halves.
3317 q1 = DIVU(u1, v) // First quotient digit.
3318 & 0xFFFFFFFF;
3319 k = u1 - q1*v; // First remainder, < v.
3320 q0 = DIVU((k << 32) + u0, v) // 2nd quot. digit.
3321 & 0xFFFFFFFF;
3322 return (q1 << 32) + q0;
3323 }
3324 }
3325 // Here v >= 2**32.
3326 n = nlz64(v); // 0 <= n <= 31.
3327 v1 = (v << n) >> 32; // Normalize the divisor
3328 // so its MSB is 1.
3329 u1 = u >> 1; // To ensure no overflow.
3330 q1 = DIVU(u1, v1) // Get quotient from
3331 & 0xFFFFFFFF; // divide unsigned insn.
3332 q0 = (q1 << n) >> 31; // Undo normalization and
3333 // division of u by 2.
3334 if (q0 != 0) // Make q0 correct or
3335 q0 = q0 - 1; // too small by 1.
3336 if ((u - q0*v) >= v)
3337 q0 = q0 + 1; // Now q0 is correct.
3338 return q0;
3339}
3340
3341
3342// ----------------------------- divdi3 --------------------------------
3343
3344/* This routine presumes that smallish cases (those which can be done in
3345one execution of DIVS) are common. If this is not the case, the test for
3346this case should be deleted.
3347 Note that the test for when DIVS can be used is not entirely
3348accurate. For example, DIVS is not used if v = 0xFFFFFFFF8000000,
3349whereas if could be (if u is sufficiently small in magnitude). */
3350
3351// ------------------------------ cut ----------------------------------
3352
3353static ULong my_llabs ( Long x )
3354{
3355 ULong t = x >> 63;
3356 return (x ^ t) - t;
3357}
3358
3359/* 64 x 64 ==> 64 signed division, using only 32 x 32 ==> 32 division
3360 as a primitive. */
3361static Long divdi3(Long u, Long v)
3362{
3363 ULong au, av;
3364 Long q, t;
3365 au = my_llabs(u);
3366 av = my_llabs(v);
3367 if (av >> 31 == 0) { // If |v| < 2**31 and
3368 // if (v << 32 >> 32 == v) { // If v is in range and
3369 if (au < av << 31) { // |u|/|v| cannot
3370 q = DIVS(u, v); // overflow, use DIVS.
3371 return (q << 32) >> 32;
3372 }
3373 }
3374 q = udivdi3(au,av); // Invoke udivdi3.
3375 t = (u ^ v) >> 63; // If u, v have different
3376 return (q ^ t) - t; // signs, negate q.
3377}
3378
3379// ---------------------------- end cut --------------------------------
3380
3381ULong __udivdi3 (ULong u, ULong v)
3382{
3383 return udivdi3(u,v);
3384}
3385
3386Long __divdi3 (Long u, Long v)
3387{
3388 return divdi3(u,v);
3389}
3390
3391ULong __umoddi3 (ULong u, ULong v)
3392{
3393 ULong q = __udivdi3(u, v);
3394 ULong r = u - q * v;
3395 return r;
3396}
3397
3398Long __moddi3 (Long u, Long v)
3399{
3400 Long q = __divdi3(u, v);
3401 Long r = u - q * v;
3402 return r;
3403}
3404
3405#endif
3406
3407
sewardjde4a1d02002-03-22 01:27:54 +00003408/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00003409/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00003410/*--------------------------------------------------------------------*/