blob: c98bf087cba33f76cacb1fa60410d6aa7e746ad7 [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"
bart5dd01902010-08-31 15:18:32 +0000166" --prefix-to-strip=<pfx> If not empty, specifies that full source file\n"
167" paths must be printed in call stacks and also\n" " that <pfx> must be stripped from these paths.\n"
168" [""].\n"
njn97db7612009-08-04 02:32:55 +0000169" --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
170" --sim-hints=hint1,hint2,... known hints:\n"
171" lax-ioctls, enable-outer [none]\n"
172" --kernel-variant=variant1,variant2,... known variants: bproc [none]\n"
173" handle non-standard kernel variants\n"
174" --show-emwarns=no|yes show warnings about emulation limits? [no]\n"
sewardjf9ebc392010-05-09 22:30:43 +0000175" --require-text-symbol=:sonamepattern:symbolpattern abort run if the\n"
176" stated shared object doesn't have the stated\n"
177" text symbol. Patterns can contain ? and *.\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000178"\n";
njn7cf0bd32002-06-08 13:36:03 +0000179
njn25e49d8e72002-09-23 09:36:25 +0000180 Char* usage2 =
181"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000182" debugging options for all Valgrind tools:\n"
njn97db7612009-08-04 02:32:55 +0000183" -d show verbose debugging output\n"
njnb1cc5d62010-07-06 04:05:23 +0000184" --stats=no|yes show tool and core statistics [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000185" --sanity-level=<number> level of sanity checking to do [1]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000186" --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
187" --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
sewardj33afdb52006-01-17 02:36:40 +0000188" --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
njn25e49d8e72002-09-23 09:36:25 +0000189" --trace-syscalls=no|yes show all system calls? [no]\n"
190" --trace-signals=no|yes show signal handling details? [no]\n"
191" --trace-symtab=no|yes show symbol table details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000192" --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
sewardjce058b02005-05-01 08:55:38 +0000193" --trace-cfi=no|yes show call-frame-info details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000194" --debug-dump=syms mimic /usr/bin/readelf --syms\n"
195" --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
196" --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
sewardj0ec07f32006-01-12 12:32:32 +0000197" --trace-redir=no|yes show redirection details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000198" --trace-sched=no|yes show thread scheduler details? [no]\n"
sewardj9c606bd2008-09-18 18:12:50 +0000199" --profile-heap=no|yes profile Valgrind's own space use\n"
jsgf855d93d2003-10-13 22:26:55 +0000200" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
sewardj17c11042006-10-15 01:26:40 +0000201" --sym-offsets=yes|no show syms in form 'name+offset' ? [no]\n"
sewardjb5f6f512005-03-10 23:59:00 +0000202" --command-line-only=no|yes only use command line options [no]\n"
njn613812e2005-03-11 04:57:30 +0000203"\n"
njn97db7612009-08-04 02:32:55 +0000204" Vex options for all Valgrind tools:\n"
205" --vex-iropt-verbosity=<0..9> [0]\n"
206" --vex-iropt-level=<0..2> [2]\n"
207" --vex-iropt-precise-memory-exns=no|yes [no]\n"
208" --vex-iropt-unroll-thresh=<0..400> [120]\n"
209" --vex-guest-max-insns=<1..100> [50]\n"
210" --vex-guest-chase-thresh=<0..99> [10]\n"
sewardj540cc4a2010-01-15 10:57:57 +0000211" --vex-guest-chase-cond=no|yes [no]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000212" --trace-flags and --profile-flags values (omit the middle space):\n"
sewardj2a99cf62004-11-24 10:44:19 +0000213" 1000 0000 show conversion into IR\n"
214" 0100 0000 show after initial opt\n"
215" 0010 0000 show after instrumentation\n"
216" 0001 0000 show after second opt\n"
217" 0000 1000 show after tree building\n"
218" 0000 0100 show selecting insns\n"
219" 0000 0010 show after reg-alloc\n"
220" 0000 0001 show final assembly\n"
njn33dbfce2006-06-02 22:58:34 +0000221" (Nb: you need --trace-notbelow with --trace-flags for full details)\n"
sewardj2a99cf62004-11-24 10:44:19 +0000222"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000223" debugging options for Valgrind tools that report errors\n"
224" --dump-error=<number> show translation for basic block associated\n"
225" with <number>'th error context [0=show none]\n"
njn97db7612009-08-04 02:32:55 +0000226"\n"
227" debugging options for Valgrind tools that replace malloc:\n"
228" --trace-malloc=no|yes show client malloc details? [no]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000229"\n";
njn3e884182003-04-15 13:03:23 +0000230
231 Char* usage3 =
232"\n"
nethercote71980f02004-01-24 18:18:54 +0000233" Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
njn25e49d8e72002-09-23 09:36:25 +0000234"\n"
njn10b9aea2009-07-14 06:55:05 +0000235" %s is %s\n"
sewardj9eecbbb2010-05-03 21:37:12 +0000236" Valgrind is Copyright (C) 2000-2010, and GNU GPL'd, by Julian Seward et al.\n"
237" LibVEX is Copyright (C) 2004-2010, and GNU GPL'd, by OpenWorks LLP.\n"
njnd04b7c62002-10-03 14:05:52 +0000238"\n"
njn10b9aea2009-07-14 06:55:05 +0000239" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
njn25e49d8e72002-09-23 09:36:25 +0000240"\n";
njn7cf0bd32002-06-08 13:36:03 +0000241
sewardj12373b12007-11-20 21:38:14 +0000242 Char* gdb_path = GDB_PATH;
sewardj12373b12007-11-20 21:38:14 +0000243
njnbe9b47b2005-05-15 16:22:58 +0000244 // Ensure the message goes to stdout
sewardj738856f2009-07-15 14:48:32 +0000245 VG_(log_output_sink).fd = 1;
246 VG_(log_output_sink).is_socket = False;
njnbe9b47b2005-05-15 16:22:58 +0000247
njn97db7612009-08-04 02:32:55 +0000248 /* 'usage1' expects one char* argument and one SizeT argument. */
249 VG_(printf)(usage1, gdb_path, VG_MIN_MALLOC_SZB);
fitzhardinge98abfc72003-12-16 02:05:15 +0000250 if (VG_(details).name) {
251 VG_(printf)(" user options for %s:\n", VG_(details).name);
fitzhardinge98abfc72003-12-16 02:05:15 +0000252 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000253 VG_TDICT_CALL(tool_print_usage);
fitzhardinge98abfc72003-12-16 02:05:15 +0000254 else
255 VG_(printf)(" (none)\n");
256 }
nethercote6c999f22004-01-31 22:55:15 +0000257 if (debug_help) {
sewardjbbaef872008-11-01 23:55:32 +0000258 VG_(printf)("%s", usage2);
fitzhardinge98abfc72003-12-16 02:05:15 +0000259
nethercote6c999f22004-01-31 22:55:15 +0000260 if (VG_(details).name) {
261 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
262
263 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000264 VG_TDICT_CALL(tool_print_debug_usage);
nethercote6c999f22004-01-31 22:55:15 +0000265 else
266 VG_(printf)(" (none)\n");
267 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000268 }
njn10b9aea2009-07-14 06:55:05 +0000269 VG_(printf)(usage3, VG_(details).name, VG_(details).copyright_author,
270 VG_BUGS_TO);
nethercotef4928da2004-06-15 10:54:40 +0000271 VG_(exit)(0);
njn7cf0bd32002-06-08 13:36:03 +0000272}
sewardjde4a1d02002-03-22 01:27:54 +0000273
sewardjde4a1d02002-03-22 01:27:54 +0000274
sewardj95d86c02007-12-18 01:49:23 +0000275/* Peer at previously set up VG_(args_for_valgrind) and do some
276 minimal command line processing that must happen early on:
sewardj45f4e7c2005-09-27 19:20:21 +0000277
sewardj95d86c02007-12-18 01:49:23 +0000278 - show the version string, if requested (-v)
279 - extract any request for help (--help, -h, --help-debug)
280 - get the toolname (--tool=)
281 - set VG_(clo_max_stackframe) (--max-stackframe=)
282 - set VG_(clo_main_stacksize) (--main-stacksize=)
283
284 That's all it does. The main command line processing is done below
285 by main_process_cmd_line_options. Note that
286 main_process_cmd_line_options has to handle but ignore the ones we
287 have handled here.
288*/
289static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
290 /*OUT*/HChar** tool )
sewardj45f4e7c2005-09-27 19:20:21 +0000291{
292 UInt i;
293 HChar* str;
sewardj8b635a42004-11-22 19:01:47 +0000294
sewardj14c7cc52007-02-25 15:08:24 +0000295 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000296
sewardj14c7cc52007-02-25 15:08:24 +0000297 /* parse the options we have (only the options we care about now) */
298 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
299
300 str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000301 vg_assert(str);
nethercote71980f02004-01-24 18:18:54 +0000302
njn83df0b62009-02-25 01:01:05 +0000303 // Nb: the version string goes to stdout.
sewardj738856f2009-07-15 14:48:32 +0000304 if VG_XACT_CLO(str, "--version", VG_(log_output_sink).fd, 1) {
305 VG_(log_output_sink).is_socket = False;
sewardj45f4e7c2005-09-27 19:20:21 +0000306 VG_(printf)("valgrind-" VERSION "\n");
307 VG_(exit)(0);
njn83df0b62009-02-25 01:01:05 +0000308 }
njncce38e62010-07-06 04:25:12 +0000309 else if VG_XACT_CLO(str, "--help", *need_help, *need_help+1) {}
310 else if VG_XACT_CLO(str, "-h", *need_help, *need_help+1) {}
sewardj45f4e7c2005-09-27 19:20:21 +0000311
njncce38e62010-07-06 04:25:12 +0000312 else if VG_XACT_CLO(str, "--help-debug", *need_help, *need_help+2) {}
nethercote71980f02004-01-24 18:18:54 +0000313
sewardj45f4e7c2005-09-27 19:20:21 +0000314 // The tool has already been determined, but we need to know the name
315 // here.
njn83df0b62009-02-25 01:01:05 +0000316 else if VG_STR_CLO(str, "--tool", *tool) {}
sewardj5bdfbd22007-12-15 22:13:05 +0000317
sewardj95d86c02007-12-18 01:49:23 +0000318 // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
319 // These are needed by VG_(ii_create_image), which happens
320 // before main_process_cmd_line_options().
njn83df0b62009-02-25 01:01:05 +0000321 else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
322 else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
nethercote71980f02004-01-24 18:18:54 +0000323 }
nethercote71980f02004-01-24 18:18:54 +0000324}
325
sewardj95d86c02007-12-18 01:49:23 +0000326/* The main processing for command line options. See comments above
sewardj738856f2009-07-15 14:48:32 +0000327 on early_process_cmd_line_options.
328
329 Comments on how the logging options are handled:
330
331 User can specify:
332 --log-fd= for a fd to write to (default setting, fd = 2)
333 --log-file= for a file name to write to
334 --log-socket= for a socket to write to
335
336 As a result of examining these and doing relevant socket/file
337 opening, a final fd is established. This is stored in
338 VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
339 specified, then STR, after expansion of %p and %q templates within
340 it, is stored in VG_(clo_log_fname_expanded), in m_options, just in
341 case anybody wants to know what it is.
342
343 When printing, VG_(log_output_sink) is consulted to find the
344 fd to send output to.
345
346 Exactly analogous actions are undertaken for the XML output
347 channel, with the one difference that the default fd is -1, meaning
348 the channel is disabled by default.
sewardj95d86c02007-12-18 01:49:23 +0000349*/
sewardj738856f2009-07-15 14:48:32 +0000350static
351void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
352 /*OUT*/Char** xml_fname_unexpanded,
353 const HChar* toolname )
nethercote71980f02004-01-24 18:18:54 +0000354{
njnda033f52005-12-19 21:27:58 +0000355 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
356 // and we cannot change it until we know what we are changing it to is
357 // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
sewardj92645592005-07-23 09:18:34 +0000358 SysRes sres;
sewardj738856f2009-07-15 14:48:32 +0000359 Int i, tmp_log_fd, tmp_xml_fd;
sewardj92645592005-07-23 09:18:34 +0000360 Int toolname_len = VG_(strlen)(toolname);
njn83df0b62009-02-25 01:01:05 +0000361 Char* tmp_str; // Used in a couple of places.
njnbe9b47b2005-05-15 16:22:58 +0000362 enum {
363 VgLogTo_Fd,
364 VgLogTo_File,
njnbe9b47b2005-05-15 16:22:58 +0000365 VgLogTo_Socket
sewardj738856f2009-07-15 14:48:32 +0000366 } log_to = VgLogTo_Fd, // Where is logging output to be sent?
367 xml_to = VgLogTo_Fd; // Where is XML output to be sent?
sewardjde4a1d02002-03-22 01:27:54 +0000368
sewardj738856f2009-07-15 14:48:32 +0000369 /* Temporarily holds the string STR specified with
370 --{log,xml}-{name,socket}=STR. 'fs' stands for
371 file-or-socket. */
372 Char* log_fsname_unexpanded = NULL;
373 Char* xml_fsname_unexpanded = NULL;
374
375 /* Log to stderr by default, but usage message goes to stdout. XML
376 output is initially disabled. */
njnda033f52005-12-19 21:27:58 +0000377 tmp_log_fd = 2;
sewardj738856f2009-07-15 14:48:32 +0000378 tmp_xml_fd = -1;
379
sewardj19d81412002-06-03 01:10:40 +0000380 /* Check for sane path in ./configure --prefix=... */
fitzhardinge98abfc72003-12-16 02:05:15 +0000381 if (VG_LIBDIR[0] != '/')
sewardj17c11042006-10-15 01:26:40 +0000382 VG_(err_config_error)("Please use absolute paths in "
383 "./configure --prefix=... or --libdir=...");
sewardj38170912002-05-10 21:07:22 +0000384
sewardj14c7cc52007-02-25 15:08:24 +0000385 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000386
sewardj738856f2009-07-15 14:48:32 +0000387 /* BEGIN command-line processing loop */
388
sewardj14c7cc52007-02-25 15:08:24 +0000389 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
390
391 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000392 HChar* colon = arg;
nethercote71980f02004-01-24 18:18:54 +0000393
njn1274d242007-03-26 23:38:42 +0000394 // Look for a colon in the option name.
thughes3bfd5a02004-07-18 08:05:44 +0000395 while (*colon && *colon != ':' && *colon != '=')
396 colon++;
nethercote71980f02004-01-24 18:18:54 +0000397
njn1274d242007-03-26 23:38:42 +0000398 // Does it have the form "--toolname:foo"? We have to do it at the start
399 // in case someone has combined a prefix with a core-specific option,
400 // eg. "--memcheck:verbose".
thughes3bfd5a02004-07-18 08:05:44 +0000401 if (*colon == ':') {
njn83df0b62009-02-25 01:01:05 +0000402 if (VG_STREQN(2, arg, "--") &&
403 VG_STREQN(toolname_len, arg+2, toolname) &&
404 VG_STREQN(1, arg+2+toolname_len, ":"))
nethercote71980f02004-01-24 18:18:54 +0000405 {
njn1274d242007-03-26 23:38:42 +0000406 // Prefix matches, convert "--toolname:foo" to "--foo".
407 // Two things to note:
408 // - We cannot modify the option in-place. If we did, and then
409 // a child was spawned with --trace-children=yes, the
410 // now-non-prefixed option would be passed and could screw up
411 // the child.
412 // - We create copies, and never free them. Why? Non-prefixed
413 // options hang around forever, so tools need not make copies
414 // of strings within them. We need to have the same behaviour
415 // for prefixed options. The pointer to the copy will be lost
416 // once we leave this function (although a tool may keep a
417 // pointer into it), but the space wasted is insignificant.
418 // (In bug #142197, the copies were being freed, which caused
419 // problems for tools that reasonably assumed that arguments
420 // wouldn't disappear on them.)
nethercote71980f02004-01-24 18:18:54 +0000421 if (0)
422 VG_(printf)("tool-specific arg: %s\n", arg);
sewardj9c606bd2008-09-18 18:12:50 +0000423 arg = VG_(strdup)("main.mpclo.1", arg + toolname_len + 1);
nethercote71980f02004-01-24 18:18:54 +0000424 arg[0] = '-';
425 arg[1] = '-';
426
427 } else {
428 // prefix doesn't match, skip to next arg
429 continue;
430 }
431 }
432
fitzhardinge98abfc72003-12-16 02:05:15 +0000433 /* Ignore these options - they've already been handled */
njn83df0b62009-02-25 01:01:05 +0000434 if VG_STREQN( 7, arg, "--tool=") {}
435 else if VG_STREQN(20, arg, "--command-line-only=") {}
436 else if VG_STREQ( arg, "--") {}
437 else if VG_STREQ( arg, "-d") {}
438 else if VG_STREQN(16, arg, "--max-stackframe") {}
439 else if VG_STREQN(16, arg, "--main-stacksize") {}
440 else if VG_STREQN(14, arg, "--profile-heap") {}
nethercote27fec902004-06-16 21:26:32 +0000441
njn83df0b62009-02-25 01:01:05 +0000442 // These options are new.
443 else if (VG_STREQ(arg, "-v") ||
444 VG_STREQ(arg, "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000445 VG_(clo_verbosity)++;
nethercote27fec902004-06-16 21:26:32 +0000446
njn83df0b62009-02-25 01:01:05 +0000447 else if (VG_STREQ(arg, "-q") ||
448 VG_STREQ(arg, "--quiet"))
sewardjde4a1d02002-03-22 01:27:54 +0000449 VG_(clo_verbosity)--;
450
sewardj2d9e8742009-08-07 15:46:56 +0000451 else if VG_BOOL_CLO(arg, "--stats", VG_(clo_stats)) {}
njn83df0b62009-02-25 01:01:05 +0000452 else if VG_BOOL_CLO(arg, "--xml", VG_(clo_xml)) {}
453 else if VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach)) {}
454 else if VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle)) {}
455 else if VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit)) {}
456 else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
457 else if VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns)) {}
sewardj95d86c02007-12-18 01:49:23 +0000458
njn83df0b62009-02-25 01:01:05 +0000459 else if VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres)) {}
460 else if VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main)) {}
461 else if VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp)) {}
462 else if VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds)) {}
463 else if VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children)) {}
464 else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
465 VG_(clo_child_silent_after_fork)) {}
466 else if VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched)) {}
467 else if VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals)) {}
468 else if VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab)) {}
469 else if VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt)) {}
470 else if VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi)) {}
471 else if VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms),
472 True) {}
473 else if VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line),
474 True) {}
475 else if VG_XACT_CLO(arg, "--debug-dump=frames",
476 VG_(clo_debug_dump_frames), True) {}
477 else if VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir)) {}
sewardj95d86c02007-12-18 01:49:23 +0000478
njn83df0b62009-02-25 01:01:05 +0000479 else if VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls)) {}
480 else if VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb)) {}
481 else if VG_STR_CLO (arg, "--db-command", VG_(clo_db_command)) {}
482 else if VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints)) {}
483 else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
484 else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
bart5dd01902010-08-31 15:18:32 +0000485 else if VG_STR_CLO (arg, "--prefix-to-strip", VG_(clo_prefix_to_strip)) {
486 Char *const pfx = VG_(clo_prefix_to_strip);
487 Char *const pfx_end = pfx + VG_(strlen)(pfx);
488 Char *const last_slash = VG_(strrchr)(pfx, '/');
489 if (last_slash == pfx_end - 1)
490 *last_slash = '\0';
491 }
sewardjf767d962007-02-12 17:47:14 +0000492
njn83df0b62009-02-25 01:01:05 +0000493 else if VG_INT_CLO (arg, "--dump-error", VG_(clo_dump_error)) {}
494 else if VG_INT_CLO (arg, "--input-fd", VG_(clo_input_fd)) {}
495 else if VG_INT_CLO (arg, "--sanity-level", VG_(clo_sanity_level)) {}
496 else if VG_BINT_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
497 VG_DEEPEST_BACKTRACE) {}
sewardjde4a1d02002-03-22 01:27:54 +0000498
njn83df0b62009-02-25 01:01:05 +0000499 else if VG_XACT_CLO(arg, "--smc-check=none", VG_(clo_smc_check),
500 Vg_SmcNone);
501 else if VG_XACT_CLO(arg, "--smc-check=stack", VG_(clo_smc_check),
502 Vg_SmcStack);
503 else if VG_XACT_CLO(arg, "--smc-check=all", VG_(clo_smc_check),
504 Vg_SmcAll);
sewardjde4a1d02002-03-22 01:27:54 +0000505
njn97db7612009-08-04 02:32:55 +0000506 else if VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant)) {}
sewardj26412bd2005-07-07 10:05:05 +0000507
njn97db7612009-08-04 02:32:55 +0000508 else if VG_BOOL_CLO(arg, "--dsymutil", VG_(clo_dsymutil)) {}
njnf76d27a2009-05-28 01:53:07 +0000509
sewardj06421272009-11-05 08:55:13 +0000510 else if VG_STR_CLO (arg, "--trace-children-skip", VG_(clo_trace_children_skip)) {}
511
njn83df0b62009-02-25 01:01:05 +0000512 else if VG_BINT_CLO(arg, "--vex-iropt-verbosity",
513 VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
514 else if VG_BINT_CLO(arg, "--vex-iropt-level",
515 VG_(clo_vex_control).iropt_level, 0, 2) {}
516 else if VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
517 VG_(clo_vex_control).iropt_precise_memory_exns) {}
518 else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
519 VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
520 else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
521 VG_(clo_vex_control).guest_max_insns, 1, 100) {}
522 else if VG_BINT_CLO(arg, "--vex-guest-chase-thresh",
523 VG_(clo_vex_control).guest_chase_thresh, 0, 99) {}
sewardj540cc4a2010-01-15 10:57:57 +0000524 else if VG_BOOL_CLO(arg, "--vex-guest-chase-cond",
525 VG_(clo_vex_control).guest_chase_cond) {}
sewardj94c8eb42008-09-19 20:13:39 +0000526
njn83df0b62009-02-25 01:01:05 +0000527 else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
528 log_to = VgLogTo_Fd;
sewardj738856f2009-07-15 14:48:32 +0000529 log_fsname_unexpanded = NULL;
530 }
531 else if VG_INT_CLO(arg, "--xml-fd", tmp_xml_fd) {
532 xml_to = VgLogTo_Fd;
533 xml_fsname_unexpanded = NULL;
sewardj4cf05692002-10-27 20:28:29 +0000534 }
535
sewardj738856f2009-07-15 14:48:32 +0000536 else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000537 log_to = VgLogTo_File;
sewardj4cf05692002-10-27 20:28:29 +0000538 }
sewardj738856f2009-07-15 14:48:32 +0000539 else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) {
540 xml_to = VgLogTo_File;
541 }
542
543 else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000544 log_to = VgLogTo_Socket;
sewardj73cf3bc2002-11-03 03:20:15 +0000545 }
sewardj738856f2009-07-15 14:48:32 +0000546 else if VG_STR_CLO(arg, "--xml-socket", xml_fsname_unexpanded) {
547 xml_to = VgLogTo_Socket;
548 }
sewardj73cf3bc2002-11-03 03:20:15 +0000549
njn83df0b62009-02-25 01:01:05 +0000550 else if VG_STR_CLO(arg, "--xml-user-comment",
551 VG_(clo_xml_user_comment)) {}
sewardj768db0e2005-07-19 14:18:56 +0000552
njn83df0b62009-02-25 01:01:05 +0000553 else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
sewardjde4a1d02002-03-22 01:27:54 +0000554 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njnb1cc5d62010-07-06 04:05:23 +0000555 VG_(fmsg_bad_option)(arg,
556 "Too many suppression files specified.\n"
557 "Increase VG_CLO_MAX_SFILES and recompile.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000558 }
njn83df0b62009-02-25 01:01:05 +0000559 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = tmp_str;
sewardjde4a1d02002-03-22 01:27:54 +0000560 VG_(clo_n_suppressions)++;
561 }
sewardjde4a1d02002-03-22 01:27:54 +0000562
sewardjf9ebc392010-05-09 22:30:43 +0000563 else if VG_STR_CLO(arg, "--require-text-symbol", tmp_str) {
564 if (VG_(clo_n_req_tsyms) >= VG_CLO_MAX_REQ_TSYMS) {
njnb1cc5d62010-07-06 04:05:23 +0000565 VG_(fmsg_bad_option)(arg,
566 "Too many --require-text-symbol= specifications.\n"
567 "Increase VG_CLO_MAX_REQ_TSYMS and recompile.\n");
sewardjf9ebc392010-05-09 22:30:43 +0000568 }
569 /* String needs to be of the form C?*C?*, where C is any
570 character, but is the same both times. Having it in this
571 form facilitates finding the boundary between the sopatt
572 and the fnpatt just by looking for the second occurrence
573 of C, without hardwiring any assumption about what C
574 is. */
575 Char patt[7];
576 Bool ok = True;
577 ok = tmp_str && VG_(strlen)(tmp_str) > 0;
578 if (ok) {
579 patt[0] = patt[3] = tmp_str[0];
580 patt[1] = patt[4] = '?';
581 patt[2] = patt[5] = '*';
582 patt[6] = 0;
583 ok = VG_(string_match)(patt, tmp_str);
584 }
585 if (!ok) {
njnb1cc5d62010-07-06 04:05:23 +0000586 VG_(fmsg_bad_option)(arg,
587 "Invalid --require-text-symbol= specification.\n");
sewardjf9ebc392010-05-09 22:30:43 +0000588 }
589 VG_(clo_req_tsyms)[VG_(clo_n_req_tsyms)] = tmp_str;
590 VG_(clo_n_req_tsyms)++;
591 }
592
sewardjfa8ec112005-01-19 11:55:34 +0000593 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000594 else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
sewardjfa8ec112005-01-19 11:55:34 +0000595 Int j;
sewardjfa8ec112005-01-19 11:55:34 +0000596
njn83df0b62009-02-25 01:01:05 +0000597 if (8 != VG_(strlen)(tmp_str)) {
njnb1cc5d62010-07-06 04:05:23 +0000598 VG_(fmsg_bad_option)(arg,
599 "--trace-flags argument must have 8 digits\n");
sewardjfa8ec112005-01-19 11:55:34 +0000600 }
601 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000602 if ('0' == tmp_str[j]) { /* do nothing */ }
603 else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
sewardjfa8ec112005-01-19 11:55:34 +0000604 else {
njnb1cc5d62010-07-06 04:05:23 +0000605 VG_(fmsg_bad_option)(arg,
606 "--trace-flags argument can only contain 0s and 1s\n");
sewardjfa8ec112005-01-19 11:55:34 +0000607 }
608 }
609 }
610
611 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000612 else if VG_STR_CLO(arg, "--profile-flags", tmp_str) {
njn25e49d8e72002-09-23 09:36:25 +0000613 Int j;
njn25e49d8e72002-09-23 09:36:25 +0000614
njn83df0b62009-02-25 01:01:05 +0000615 if (8 != VG_(strlen)(tmp_str)) {
njnb1cc5d62010-07-06 04:05:23 +0000616 VG_(fmsg_bad_option)(arg,
617 "--profile-flags argument must have 8 digits\n");
njn25e49d8e72002-09-23 09:36:25 +0000618 }
sewardj8b635a42004-11-22 19:01:47 +0000619 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000620 if ('0' == tmp_str[j]) { /* do nothing */ }
621 else if ('1' == tmp_str[j]) VG_(clo_profile_flags) |= (1 << (7-j));
njn25e49d8e72002-09-23 09:36:25 +0000622 else {
njnb1cc5d62010-07-06 04:05:23 +0000623 VG_(fmsg_bad_option)(arg,
624 "--profile-flags argument can only contain 0s and 1s\n");
njn25e49d8e72002-09-23 09:36:25 +0000625 }
626 }
627 }
sewardjde4a1d02002-03-22 01:27:54 +0000628
njn83df0b62009-02-25 01:01:05 +0000629 else if VG_INT_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow)) {}
sewardjc771b292004-11-30 18:55:21 +0000630
njn83df0b62009-02-25 01:01:05 +0000631 else if VG_XACT_CLO(arg, "--gen-suppressions=no",
632 VG_(clo_gen_suppressions), 0) {}
633 else if VG_XACT_CLO(arg, "--gen-suppressions=yes",
634 VG_(clo_gen_suppressions), 1) {}
635 else if VG_XACT_CLO(arg, "--gen-suppressions=all",
636 VG_(clo_gen_suppressions), 2) {}
sewardjd153fae2005-01-10 17:24:47 +0000637
nethercote71980f02004-01-24 18:18:54 +0000638 else if ( ! VG_(needs).command_line_options
njn51d827b2005-05-09 01:02:08 +0000639 || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
njnb1cc5d62010-07-06 04:05:23 +0000640 VG_(fmsg_bad_option)(arg, "");
njn25e49d8e72002-09-23 09:36:25 +0000641 }
sewardjde4a1d02002-03-22 01:27:54 +0000642 }
643
sewardj738856f2009-07-15 14:48:32 +0000644 /* END command-line processing loop */
645
sewardj998d40d2004-12-06 14:24:52 +0000646 /* Make VEX control parameters sane */
647
648 if (VG_(clo_vex_control).guest_chase_thresh
649 >= VG_(clo_vex_control).guest_max_insns)
650 VG_(clo_vex_control).guest_chase_thresh
651 = VG_(clo_vex_control).guest_max_insns - 1;
652
653 if (VG_(clo_vex_control).guest_chase_thresh < 0)
654 VG_(clo_vex_control).guest_chase_thresh = 0;
655
656 /* Check various option values */
nethercote27fec902004-06-16 21:26:32 +0000657
njnf9ebf672003-05-12 21:41:30 +0000658 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +0000659 VG_(clo_verbosity) = 0;
660
njnbe9b47b2005-05-15 16:22:58 +0000661 if (VG_(clo_gen_suppressions) > 0 &&
662 !VG_(needs).core_errors && !VG_(needs).tool_errors) {
njnb1cc5d62010-07-06 04:05:23 +0000663 VG_(fmsg_bad_option)("--gen-suppressions=yes",
664 "Can't use --gen-suppressions= with %s\n"
665 "because it doesn't generate errors.\n", VG_(details).name);
njnbe9b47b2005-05-15 16:22:58 +0000666 }
667
sewardj738856f2009-07-15 14:48:32 +0000668 /* If XML output is requested, check that the tool actually
669 supports it. */
670 if (VG_(clo_xml) && !VG_(needs).xml_output) {
671 VG_(clo_xml) = False;
njnb1cc5d62010-07-06 04:05:23 +0000672 VG_(fmsg_bad_option)("--xml=yes",
sewardj738856f2009-07-15 14:48:32 +0000673 "%s does not support XML output.\n", VG_(details).name);
sewardj738856f2009-07-15 14:48:32 +0000674 /*NOTREACHED*/
675 }
676
677 vg_assert( VG_(clo_gen_suppressions) >= 0 );
678 vg_assert( VG_(clo_gen_suppressions) <= 2 );
679
sewardj71bc3cb2005-05-19 00:25:45 +0000680 /* If we've been asked to emit XML, mash around various other
681 options so as to constrain the output somewhat, and to remove
sewardj738856f2009-07-15 14:48:32 +0000682 any need for user input during the run.
683 */
sewardj71bc3cb2005-05-19 00:25:45 +0000684 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +0000685
686 /* We can't allow --gen-suppressions=yes, since that requires us
687 to print the error and then ask the user if she wants a
688 suppression for it, but in XML mode we won't print it until
689 we know whether we also need to print a suppression. Hence a
690 circular dependency. So disallow this.
691 (--gen-suppressions=all is still OK since we don't need any
692 user interaction in this case.) */
693 if (VG_(clo_gen_suppressions) == 1) {
njnb1cc5d62010-07-06 04:05:23 +0000694 VG_(fmsg_bad_option)(
695 "--xml=yes together with --gen-suppressions=yes",
696 "When --xml=yes is specified, --gen-suppressions=no\n"
697 "or --gen-suppressions=all is allowed, but not "
sewardj738856f2009-07-15 14:48:32 +0000698 "--gen-suppressions=yes.\n");
sewardj738856f2009-07-15 14:48:32 +0000699 }
700
701 /* We can't allow DB attaching (or we maybe could, but results
702 could be chaotic ..) since it requires user input. Hence
703 disallow. */
704 if (VG_(clo_db_attach)) {
njnb1cc5d62010-07-06 04:05:23 +0000705 VG_(fmsg_bad_option)(
706 "--xml=yes together with --db-attach=yes",
707 "--db-attach=yes is not allowed with --xml=yes\n"
708 "because it would require user input.\n");
sewardj738856f2009-07-15 14:48:32 +0000709 }
710
711 /* Disallow dump_error in XML mode; sounds like a recipe for
712 chaos. No big deal; dump_error is a flag for debugging V
713 itself. */
714 if (VG_(clo_dump_error) > 0) {
njnb1cc5d62010-07-06 04:05:23 +0000715 VG_(fmsg_bad_option)("--xml=yes together with --dump-error", "");
sewardj738856f2009-07-15 14:48:32 +0000716 }
717
sewardj71bc3cb2005-05-19 00:25:45 +0000718 /* Disable error limits (this might be a bad idea!) */
719 VG_(clo_error_limit) = False;
720 /* Disable emulation warnings */
sewardj738856f2009-07-15 14:48:32 +0000721
sewardj71bc3cb2005-05-19 00:25:45 +0000722 /* Also, we want to set options for the leak checker, but that
723 will have to be done in Memcheck's flag-handling code, not
724 here. */
725 }
726
njnbe9b47b2005-05-15 16:22:58 +0000727 /* All non-logging-related options have been checked. If the logging
728 option specified is ok, we can switch to it, as we know we won't
729 have to generate any other command-line-related error messages.
730 (So far we should be still attached to stderr, so we can show on
731 the terminal any problems to do with processing command line
732 opts.)
733
sewardj738856f2009-07-15 14:48:32 +0000734 So set up logging now. After this is done, VG_(log_output_sink)
735 and (if relevant) VG_(xml_output_sink) should be connected to
736 whatever sink has been selected, and we indiscriminately chuck
737 stuff into it without worrying what the nature of it is. Oh the
738 wonder of Unix streams. */
sewardj4cf05692002-10-27 20:28:29 +0000739
sewardj738856f2009-07-15 14:48:32 +0000740 vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
741 vg_assert(VG_(log_output_sink).is_socket == False);
742 vg_assert(VG_(clo_log_fname_expanded) == NULL);
743
744 vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
745 vg_assert(VG_(xml_output_sink).is_socket == False);
746 vg_assert(VG_(clo_xml_fname_expanded) == NULL);
747
748 /* --- set up the normal text output channel --- */
sewardj4cf05692002-10-27 20:28:29 +0000749
njnbe9b47b2005-05-15 16:22:58 +0000750 switch (log_to) {
sewardj73cf3bc2002-11-03 03:20:15 +0000751
sewardj4cf05692002-10-27 20:28:29 +0000752 case VgLogTo_Fd:
sewardj738856f2009-07-15 14:48:32 +0000753 vg_assert(log_fsname_unexpanded == NULL);
sewardj4cf05692002-10-27 20:28:29 +0000754 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000755
sewardj4cf05692002-10-27 20:28:29 +0000756 case VgLogTo_File: {
njn374a36d2007-11-23 01:41:32 +0000757 Char* logfilename;
jsgff3c3f1a2003-10-14 22:13:28 +0000758
sewardj738856f2009-07-15 14:48:32 +0000759 vg_assert(log_fsname_unexpanded != NULL);
760 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +0000761
njn374a36d2007-11-23 01:41:32 +0000762 // Nb: we overwrite an existing file of this name without asking
763 // any questions.
sewardj738856f2009-07-15 14:48:32 +0000764 logfilename = VG_(expand_file_name)("--log-file",
765 log_fsname_unexpanded);
njn374a36d2007-11-23 01:41:32 +0000766 sres = VG_(open)(logfilename,
njnda033f52005-12-19 21:27:58 +0000767 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
768 VKI_S_IRUSR|VKI_S_IWUSR);
njncda2f0f2009-05-18 02:12:08 +0000769 if (!sr_isError(sres)) {
770 tmp_log_fd = sr_Res(sres);
sewardj738856f2009-07-15 14:48:32 +0000771 VG_(clo_log_fname_expanded) = logfilename;
njnbe9b47b2005-05-15 16:22:58 +0000772 } else {
njnb1cc5d62010-07-06 04:05:23 +0000773 VG_(fmsg)("can't create log file '%s': %s\n",
774 logfilename, VG_(strerror)(sr_Err(sres)));
775 VG_(exit)(1);
sewardj603d4102005-01-11 14:01:02 +0000776 /*NOTREACHED*/
njn374a36d2007-11-23 01:41:32 +0000777 }
sewardj738856f2009-07-15 14:48:32 +0000778 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000779 }
780
781 case VgLogTo_Socket: {
sewardj738856f2009-07-15 14:48:32 +0000782 vg_assert(log_fsname_unexpanded != NULL);
783 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
784 tmp_log_fd = VG_(connect_via_socket)( log_fsname_unexpanded );
njnda033f52005-12-19 21:27:58 +0000785 if (tmp_log_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +0000786 VG_(fmsg)("Invalid --log-socket spec of '%s'\n",
787 log_fsname_unexpanded);
788 VG_(exit)(1);
njnbe9b47b2005-05-15 16:22:58 +0000789 /*NOTREACHED*/
sewardj4cf05692002-10-27 20:28:29 +0000790 }
njnda033f52005-12-19 21:27:58 +0000791 if (tmp_log_fd == -2) {
njnb1cc5d62010-07-06 04:05:23 +0000792 VG_(umsg)("failed to connect to logging server '%s'.\n"
793 "Log messages will sent to stderr instead.\n",
794 log_fsname_unexpanded );
795
sewardj570f8902002-11-03 11:44:36 +0000796 /* We don't change anything here. */
sewardj738856f2009-07-15 14:48:32 +0000797 vg_assert(VG_(log_output_sink).fd == 2);
njnda033f52005-12-19 21:27:58 +0000798 tmp_log_fd = 2;
sewardj570f8902002-11-03 11:44:36 +0000799 } else {
njnda033f52005-12-19 21:27:58 +0000800 vg_assert(tmp_log_fd > 0);
sewardj738856f2009-07-15 14:48:32 +0000801 VG_(log_output_sink).is_socket = True;
sewardj570f8902002-11-03 11:44:36 +0000802 }
sewardj73cf3bc2002-11-03 03:20:15 +0000803 break;
804 }
sewardj4cf05692002-10-27 20:28:29 +0000805 }
806
sewardj738856f2009-07-15 14:48:32 +0000807 /* --- set up the XML output channel --- */
sewardj71bc3cb2005-05-19 00:25:45 +0000808
sewardj738856f2009-07-15 14:48:32 +0000809 switch (xml_to) {
810
811 case VgLogTo_Fd:
812 vg_assert(xml_fsname_unexpanded == NULL);
813 break;
814
815 case VgLogTo_File: {
816 Char* xmlfilename;
817
818 vg_assert(xml_fsname_unexpanded != NULL);
819 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
820
821 // Nb: we overwrite an existing file of this name without asking
822 // any questions.
823 xmlfilename = VG_(expand_file_name)("--xml-file",
824 xml_fsname_unexpanded);
825 sres = VG_(open)(xmlfilename,
826 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
827 VKI_S_IRUSR|VKI_S_IWUSR);
828 if (!sr_isError(sres)) {
829 tmp_xml_fd = sr_Res(sres);
830 VG_(clo_xml_fname_expanded) = xmlfilename;
831 /* strdup here is probably paranoid overkill, but ... */
832 *xml_fname_unexpanded = VG_(strdup)( "main.mpclo.2",
833 xml_fsname_unexpanded );
834 } else {
njnb1cc5d62010-07-06 04:05:23 +0000835 VG_(fmsg)("can't create XML file '%s': %s\n",
836 xmlfilename, VG_(strerror)(sr_Err(sres)));
837 VG_(exit)(1);
sewardj738856f2009-07-15 14:48:32 +0000838 /*NOTREACHED*/
839 }
840 break;
841 }
842
843 case VgLogTo_Socket: {
844 vg_assert(xml_fsname_unexpanded != NULL);
845 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
846 tmp_xml_fd = VG_(connect_via_socket)( xml_fsname_unexpanded );
847 if (tmp_xml_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +0000848 VG_(fmsg)("Invalid --xml-socket spec of '%s'\n",
849 xml_fsname_unexpanded );
850 VG_(exit)(1);
sewardj738856f2009-07-15 14:48:32 +0000851 /*NOTREACHED*/
852 }
853 if (tmp_xml_fd == -2) {
njnb1cc5d62010-07-06 04:05:23 +0000854 VG_(umsg)("failed to connect to XML logging server '%s'.\n"
855 "XML output will sent to stderr instead.\n",
856 xml_fsname_unexpanded);
sewardj738856f2009-07-15 14:48:32 +0000857 /* We don't change anything here. */
858 vg_assert(VG_(xml_output_sink).fd == 2);
859 tmp_xml_fd = 2;
860 } else {
861 vg_assert(tmp_xml_fd > 0);
862 VG_(xml_output_sink).is_socket = True;
863 }
864 break;
865 }
sewardj71bc3cb2005-05-19 00:25:45 +0000866 }
867
sewardj738856f2009-07-15 14:48:32 +0000868 /* If we've got this far, and XML mode was requested, but no XML
869 output channel appears to have been specified, just stop. We
870 could continue, and XML output will simply vanish into nowhere,
871 but that is likely to confuse the hell out of users, which is
872 distinctly Ungood. */
873 if (VG_(clo_xml) && tmp_xml_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +0000874 VG_(fmsg_bad_option)(
875 "--xml=yes, but no XML destination specified",
sewardj738856f2009-07-15 14:48:32 +0000876 "--xml=yes has been specified, but there is no XML output\n"
877 "destination. You must specify an XML output destination\n"
njnb1cc5d62010-07-06 04:05:23 +0000878 "using --xml-fd, --xml-file or --xml-socket.\n"
879 );
sewardj738856f2009-07-15 14:48:32 +0000880 }
881
882 // Finalise the output fds: the log fd ..
883
njnda033f52005-12-19 21:27:58 +0000884 if (tmp_log_fd >= 0) {
sewardj738856f2009-07-15 14:48:32 +0000885 // Move log_fd into the safe range, so it doesn't conflict with
886 // any app fds.
njnda033f52005-12-19 21:27:58 +0000887 tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
888 if (tmp_log_fd < 0) {
sewardj738856f2009-07-15 14:48:32 +0000889 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd "
890 "into safe range, using stderr\n");
891 VG_(log_output_sink).fd = 2; // stderr
892 VG_(log_output_sink).is_socket = False;
njnda033f52005-12-19 21:27:58 +0000893 } else {
sewardj738856f2009-07-15 14:48:32 +0000894 VG_(log_output_sink).fd = tmp_log_fd;
895 VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
njnda033f52005-12-19 21:27:58 +0000896 }
897 } else {
898 // If they said --log-fd=-1, don't print anything. Plausible for use in
899 // regression testing suites that use client requests to count errors.
sewardj738856f2009-07-15 14:48:32 +0000900 VG_(log_output_sink).fd = -1;
901 VG_(log_output_sink).is_socket = False;
jsgf855d93d2003-10-13 22:26:55 +0000902 }
903
sewardj738856f2009-07-15 14:48:32 +0000904 // Finalise the output fds: and the XML fd ..
905
906 if (tmp_xml_fd >= 0) {
907 // Move xml_fd into the safe range, so it doesn't conflict with
908 // any app fds.
909 tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
910 if (tmp_xml_fd < 0) {
911 VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd "
912 "into safe range, using stderr\n");
913 VG_(xml_output_sink).fd = 2; // stderr
914 VG_(xml_output_sink).is_socket = False;
915 } else {
916 VG_(xml_output_sink).fd = tmp_xml_fd;
917 VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
918 }
919 } else {
920 // If they said --xml-fd=-1, don't print anything. Plausible for use in
921 // regression testing suites that use client requests to count errors.
922 VG_(xml_output_sink).fd = -1;
923 VG_(xml_output_sink).is_socket = False;
924 }
925
926 // Suppressions related stuff
927
sewardj45f4e7c2005-09-27 19:20:21 +0000928 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
929 (VG_(needs).core_errors || VG_(needs).tool_errors)) {
930 /* If we haven't reached the max number of suppressions, load
931 the default one. */
932 static const Char default_supp[] = "default.supp";
933 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
sewardj738856f2009-07-15 14:48:32 +0000934 Char *buf = VG_(arena_malloc)(VG_AR_CORE, "main.mpclo.3", len);
sewardj45f4e7c2005-09-27 19:20:21 +0000935 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
936 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
937 VG_(clo_n_suppressions)++;
938 }
sewardjde4a1d02002-03-22 01:27:54 +0000939
sewardj738856f2009-07-15 14:48:32 +0000940 *logging_to_fd = log_to == VgLogTo_Fd || log_to == VgLogTo_Socket;
sewardj45f4e7c2005-09-27 19:20:21 +0000941}
942
sewardj4efbaa72008-06-04 06:51:58 +0000943// Write the name and value of log file qualifiers to the xml file.
944static void print_file_vars(Char* format)
945{
946 Int i = 0;
947
948 while (format[i]) {
949 if (format[i] == '%') {
950 // We saw a '%'. What's next...
951 i++;
952 if ('q' == format[i]) {
953 i++;
954 if ('{' == format[i]) {
955 // Get the env var name, print its contents.
956 Char* qualname;
957 Char* qual;
958 i++;
959 qualname = &format[i];
960 while (True) {
961 if ('}' == format[i]) {
962 // Temporarily replace the '}' with NUL to extract var
963 // name.
964 format[i] = 0;
965 qual = VG_(getenv)(qualname);
966 break;
967 }
968 i++;
969 }
970
sewardj7ca100d2009-08-15 23:05:34 +0000971 VG_(printf_xml_no_f_c)(
972 "<logfilequalifier> <var>%t</var> "
973 "<value>%t</value> </logfilequalifier>\n",
974 qualname,qual
975 );
sewardj4efbaa72008-06-04 06:51:58 +0000976 format[i] = '}';
977 i++;
978 }
979 }
980 } else {
981 i++;
982 }
983 }
984}
985
sewardj45f4e7c2005-09-27 19:20:21 +0000986
987/*====================================================================*/
988/*=== Printing the preamble ===*/
989/*====================================================================*/
990
njnf8a11cf2009-08-02 23:03:06 +0000991// Print the command, escaping any chars that require it.
barta3054f52010-06-14 18:12:56 +0000992static void umsg_or_xml_arg(const Char* arg,
njnf8a11cf2009-08-02 23:03:06 +0000993 UInt (*umsg_or_xml)( const HChar*, ... ) )
994{
995 SizeT len = VG_(strlen)(arg);
996 Char* special = " \\<>";
997 Int i;
998 for (i = 0; i < len; i++) {
999 if (VG_(strchr)(special, arg[i])) {
1000 umsg_or_xml("\\"); // escape with a backslash if necessary
1001 }
1002 umsg_or_xml("%c", arg[i]);
1003 }
1004}
1005
sewardj45f4e7c2005-09-27 19:20:21 +00001006/* Ok, the logging sink is running now. Print a suitable preamble.
1007 If logging to file or a socket, write details of parent PID and
1008 command line args, to help people trying to interpret the
1009 results of a run which encompasses multiple processes. */
sewardj738856f2009-07-15 14:48:32 +00001010static void print_preamble ( Bool logging_to_fd,
1011 Char* xml_fname_unexpanded,
1012 const HChar* toolname )
sewardj45f4e7c2005-09-27 19:20:21 +00001013{
sewardj738856f2009-07-15 14:48:32 +00001014 Int i;
tom60a4b0b2005-10-12 10:45:27 +00001015 HChar* xpre = VG_(clo_xml) ? " <line>" : "";
1016 HChar* xpost = VG_(clo_xml) ? "</line>" : "";
sewardj738856f2009-07-15 14:48:32 +00001017 UInt (*umsg_or_xml)( const HChar*, ... )
1018 = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
tom60a4b0b2005-10-12 10:45:27 +00001019
sewardj14c7cc52007-02-25 15:08:24 +00001020 vg_assert( VG_(args_for_client) );
1021 vg_assert( VG_(args_for_valgrind) );
sewardj99a2ceb2007-11-09 12:30:36 +00001022 vg_assert( toolname );
sewardj14c7cc52007-02-25 15:08:24 +00001023
sewardj71bc3cb2005-05-19 00:25:45 +00001024 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001025 VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
1026 VG_(printf_xml)("\n");
1027 VG_(printf_xml)("<valgrindoutput>\n");
1028 VG_(printf_xml)("\n");
1029 VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
1030 VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", toolname);
1031 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001032 }
1033
sewardj738856f2009-07-15 14:48:32 +00001034 if (VG_(clo_xml) || VG_(clo_verbosity > 0)) {
sewardjd7bddad2005-06-13 16:48:32 +00001035
1036 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001037 VG_(printf_xml)("<preamble>\n");
sewardjd7bddad2005-06-13 16:48:32 +00001038
nethercote996901a2004-08-03 13:29:09 +00001039 /* Tool details */
sewardj743a2082010-07-23 17:03:22 +00001040 umsg_or_xml( VG_(clo_xml) ? "%s%t%t%t, %t%s\n" : "%s%s%s%s, %s%s\n",
sewardj71bc3cb2005-05-19 00:25:45 +00001041 xpre,
njnd04b7c62002-10-03 14:05:52 +00001042 VG_(details).name,
njnb9c427c2004-12-01 14:14:42 +00001043 NULL == VG_(details).version ? "" : "-",
njnd04b7c62002-10-03 14:05:52 +00001044 NULL == VG_(details).version
1045 ? (Char*)"" : VG_(details).version,
sewardj71bc3cb2005-05-19 00:25:45 +00001046 VG_(details).description,
sewardj738856f2009-07-15 14:48:32 +00001047 xpost );
sewardj99a2ceb2007-11-09 12:30:36 +00001048
njn10b9aea2009-07-14 06:55:05 +00001049 if (VG_(strlen)(toolname) >= 4 && VG_STREQN(4, toolname, "exp-")) {
sewardj738856f2009-07-15 14:48:32 +00001050 umsg_or_xml(
njnb6267bd2009-08-12 00:14:16 +00001051 "%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
sewardj99a2ceb2007-11-09 12:30:36 +00001052 xpre, xpost
1053 );
1054 }
1055
sewardj743a2082010-07-23 17:03:22 +00001056 umsg_or_xml( VG_(clo_xml) ? "%s%t%s\n" : "%s%s%s\n",
1057 xpre, VG_(details).copyright_author, xpost );
sewardj3b2736a2002-03-24 12:18:35 +00001058
njnd04b7c62002-10-03 14:05:52 +00001059 /* Core details */
sewardj738856f2009-07-15 14:48:32 +00001060 umsg_or_xml(
njnf73d87f2009-07-24 04:47:04 +00001061 "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
1062 xpre, VERSION, xpost
sewardj738856f2009-07-15 14:48:32 +00001063 );
sewardj45f4e7c2005-09-27 19:20:21 +00001064
njnf3977a32009-08-04 00:27:56 +00001065 // Print the command line. At one point we wrapped at 80 chars and
1066 // printed a '\' as a line joiner, but that makes it hard to cut and
1067 // paste the command line (because of the "==pid==" prefixes), so we now
1068 // favour utility and simplicity over aesthetics.
1069 umsg_or_xml("%sCommand: ", xpre);
njn53162bf2009-07-29 23:34:49 +00001070 if (VG_(args_the_exename))
njnf8a11cf2009-08-02 23:03:06 +00001071 umsg_or_xml_arg(VG_(args_the_exename), umsg_or_xml);
njn53162bf2009-07-29 23:34:49 +00001072 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1073 HChar* s = *(HChar**)VG_(indexXA)( VG_(args_for_client), i );
njnf8a11cf2009-08-02 23:03:06 +00001074 umsg_or_xml(" ");
1075 umsg_or_xml_arg(s, umsg_or_xml);
njn53162bf2009-07-29 23:34:49 +00001076 }
njnf3977a32009-08-04 00:27:56 +00001077 umsg_or_xml("%s\n", xpost);
njn53162bf2009-07-29 23:34:49 +00001078
sewardjd7bddad2005-06-13 16:48:32 +00001079 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001080 VG_(printf_xml)("</preamble>\n");
njnd04b7c62002-10-03 14:05:52 +00001081 }
1082
njnb6267bd2009-08-12 00:14:16 +00001083 // Print the parent PID, and other stuff, if necessary.
sewardj45f4e7c2005-09-27 19:20:21 +00001084 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
njn305dc002009-07-30 23:36:43 +00001085 VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
sewardj4cf05692002-10-27 20:28:29 +00001086 }
sewardj71bc3cb2005-05-19 00:25:45 +00001087 else
1088 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001089 VG_(printf_xml)("\n");
1090 VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
1091 VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
1092 VG_(printf_xml_no_f_c)("<tool>%t</tool>\n", toolname);
1093 if (xml_fname_unexpanded)
1094 print_file_vars(xml_fname_unexpanded);
sewardj768db0e2005-07-19 14:18:56 +00001095 if (VG_(clo_xml_user_comment)) {
1096 /* Note: the user comment itself is XML and is therefore to
1097 be passed through verbatim (%s) rather than escaped
1098 (%t). */
sewardj738856f2009-07-15 14:48:32 +00001099 VG_(printf_xml)("<usercomment>%s</usercomment>\n",
1100 VG_(clo_xml_user_comment));
sewardj768db0e2005-07-19 14:18:56 +00001101 }
sewardj738856f2009-07-15 14:48:32 +00001102 VG_(printf_xml)("\n");
1103 VG_(printf_xml)("<args>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001104
sewardj738856f2009-07-15 14:48:32 +00001105 VG_(printf_xml)(" <vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001106 if (VG_(name_of_launcher))
sewardj738856f2009-07-15 14:48:32 +00001107 VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
1108 VG_(name_of_launcher));
sewardj125fd4f2007-03-08 19:56:14 +00001109 else
njnb1cc5d62010-07-06 04:05:23 +00001110 VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
1111 "(launcher name unknown)");
sewardj14c7cc52007-02-25 15:08:24 +00001112 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
sewardj738856f2009-07-15 14:48:32 +00001113 VG_(printf_xml_no_f_c)(
1114 " <arg>%t</arg>\n",
1115 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1116 );
sewardjb8a3dac2005-07-19 12:39:11 +00001117 }
sewardj738856f2009-07-15 14:48:32 +00001118 VG_(printf_xml)(" </vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001119
sewardj738856f2009-07-15 14:48:32 +00001120 VG_(printf_xml)(" <argv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001121 if (VG_(args_the_exename))
sewardj738856f2009-07-15 14:48:32 +00001122 VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
1123 VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001124 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
sewardj738856f2009-07-15 14:48:32 +00001125 VG_(printf_xml_no_f_c)(
1126 " <arg>%t</arg>\n",
1127 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1128 );
sewardj8665d8e2005-06-01 17:35:23 +00001129 }
sewardj738856f2009-07-15 14:48:32 +00001130 VG_(printf_xml)(" </argv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001131
sewardj738856f2009-07-15 14:48:32 +00001132 VG_(printf_xml)("</args>\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001133 }
sewardj4cf05692002-10-27 20:28:29 +00001134
njnb6267bd2009-08-12 00:14:16 +00001135 // Last thing in the preamble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00001136 if (VG_(clo_xml))
1137 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00001138 else if (VG_(clo_verbosity) > 0)
1139 VG_(umsg)("\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001140
sewardjde4a1d02002-03-22 01:27:54 +00001141 if (VG_(clo_verbosity) > 1) {
sewardj92645592005-07-23 09:18:34 +00001142 SysRes fd;
sewardj1f0bbc72005-11-16 03:51:02 +00001143 VexArch vex_arch;
1144 VexArchInfo vex_archinfo;
sewardj45f4e7c2005-09-27 19:20:21 +00001145 if (!logging_to_fd)
sewardj738856f2009-07-15 14:48:32 +00001146 VG_(message)(Vg_DebugMsg, "\n");
njna3311642009-08-10 01:29:14 +00001147 VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
sewardj14c7cc52007-02-25 15:08:24 +00001148 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
1149 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001150 " %s\n",
sewardj14c7cc52007-02-25 15:08:24 +00001151 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjde4a1d02002-03-22 01:27:54 +00001152 }
nethercotea70f7352004-04-18 12:08:46 +00001153
sewardj738856f2009-07-15 14:48:32 +00001154 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
nethercotea70f7352004-04-18 12:08:46 +00001155 fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
njncda2f0f2009-05-18 02:12:08 +00001156 if (sr_isError(fd)) {
sewardj738856f2009-07-15 14:48:32 +00001157 VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
nethercotea70f7352004-04-18 12:08:46 +00001158 } else {
sewardj71bc3cb2005-05-19 00:25:45 +00001159# define BUF_LEN 256
nethercotea70f7352004-04-18 12:08:46 +00001160 Char version_buf[BUF_LEN];
njnf3977a32009-08-04 00:27:56 +00001161 Int n = VG_(read) ( sr_Res(fd), version_buf, BUF_LEN );
1162 vg_assert(n <= BUF_LEN);
1163 if (n > 0) {
1164 version_buf[n-1] = '\0';
sewardj738856f2009-07-15 14:48:32 +00001165 VG_(message)(Vg_DebugMsg, " %s\n", version_buf);
nethercotea70f7352004-04-18 12:08:46 +00001166 } else {
sewardj738856f2009-07-15 14:48:32 +00001167 VG_(message)(Vg_DebugMsg, " (empty?)\n");
nethercotea70f7352004-04-18 12:08:46 +00001168 }
njncda2f0f2009-05-18 02:12:08 +00001169 VG_(close)(sr_Res(fd));
sewardj71bc3cb2005-05-19 00:25:45 +00001170# undef BUF_LEN
nethercotea70f7352004-04-18 12:08:46 +00001171 }
sewardj1f0bbc72005-11-16 03:51:02 +00001172
1173 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001174 VG_(message)(
1175 Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001176 "Arch and hwcaps: %s, %s\n",
sewardje3121f32006-01-27 21:23:23 +00001177 LibVEX_ppVexArch ( vex_arch ),
1178 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1179 );
sewardje66f2e02006-12-30 17:45:08 +00001180 VG_(message)(
1181 Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001182 "Page sizes: currently %d, max supported %d\n",
sewardje66f2e02006-12-30 17:45:08 +00001183 (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
1184 );
sewardj738856f2009-07-15 14:48:32 +00001185 VG_(message)(Vg_DebugMsg,
1186 "Valgrind library directory: %s\n", VG_(libdir));
sewardjde4a1d02002-03-22 01:27:54 +00001187 }
nethercotef6a1d502004-08-09 12:21:57 +00001188}
1189
sewardjde4a1d02002-03-22 01:27:54 +00001190
nethercote71980f02004-01-24 18:18:54 +00001191/*====================================================================*/
1192/*=== File descriptor setup ===*/
1193/*====================================================================*/
1194
sewardj5f229e22005-09-28 01:36:01 +00001195/* Number of file descriptors that Valgrind tries to reserve for
1196 it's own use - just a small constant. */
1197#define N_RESERVED_FDS (10)
1198
nethercote71980f02004-01-24 18:18:54 +00001199static void setup_file_descriptors(void)
1200{
1201 struct vki_rlimit rl;
sewardj17c11042006-10-15 01:26:40 +00001202 Bool show = False;
nethercote71980f02004-01-24 18:18:54 +00001203
1204 /* Get the current file descriptor limits. */
1205 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
1206 rl.rlim_cur = 1024;
1207 rl.rlim_max = 1024;
1208 }
1209
njnf76d27a2009-05-28 01:53:07 +00001210# if defined(VGO_darwin)
1211 /* Darwin lies. It reports file max as RLIM_INFINITY but
1212 silently disallows anything bigger than 10240. */
1213 if (rl.rlim_cur >= 10240 && rl.rlim_max == 0x7fffffffffffffffULL) {
1214 rl.rlim_max = 10240;
1215 }
1216# endif
1217
sewardj17c11042006-10-15 01:26:40 +00001218 if (show)
njn8a7b41b2007-09-23 00:51:24 +00001219 VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001220 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001221
1222# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1223 /* I don't know why this kludge is needed; however if rl.rlim_cur
1224 is RLIM_INFINITY, then VG_(safe_fd)'s attempts using VG_(fcntl)
1225 to lift V's file descriptors above the threshold RLIM_INFINITY -
1226 N_RESERVED_FDS fail. So just use a relatively conservative
1227 value in this case. */
1228 if (rl.rlim_cur > 1024)
1229 rl.rlim_cur = 1024;
1230# endif
1231
nethercote71980f02004-01-24 18:18:54 +00001232 /* Work out where to move the soft limit to. */
njn14319cc2005-03-13 06:26:22 +00001233 if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
1234 rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001235 } else {
1236 rl.rlim_cur = rl.rlim_max;
1237 }
1238
1239 /* Reserve some file descriptors for our use. */
njn14319cc2005-03-13 06:26:22 +00001240 VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
1241 VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001242
1243 /* Update the soft limit. */
1244 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
1245
sewardj17c11042006-10-15 01:26:40 +00001246 if (show) {
njn8a7b41b2007-09-23 00:51:24 +00001247 VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001248 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001249 VG_(printf)("fd limits: guest : cur %u max %u\n",
1250 VG_(fd_soft_limit), VG_(fd_hard_limit));
1251 }
1252
sewardj45f4e7c2005-09-27 19:20:21 +00001253 if (VG_(cl_exec_fd) != -1)
1254 VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
nethercote71980f02004-01-24 18:18:54 +00001255}
1256
sewardjde4a1d02002-03-22 01:27:54 +00001257
njn2da73352005-06-18 01:35:16 +00001258/*====================================================================*/
njn2025cf92005-06-26 20:44:48 +00001259/*=== BB profiling ===*/
1260/*====================================================================*/
1261
1262static
1263void show_BB_profile ( BBProfEntry tops[], UInt n_tops, ULong score_total )
1264{
1265 ULong score_cumul, score_here;
1266 Char buf_cumul[10], buf_here[10];
1267 Char name[64];
1268 Int r;
1269
1270 VG_(printf)("\n");
1271 VG_(printf)("-----------------------------------------------------------\n");
1272 VG_(printf)("--- BEGIN BB Profile (summary of scores) ---\n");
1273 VG_(printf)("-----------------------------------------------------------\n");
1274 VG_(printf)("\n");
1275
1276 VG_(printf)("Total score = %lld\n\n", score_total);
1277
1278 score_cumul = 0;
1279 for (r = 0; r < n_tops; r++) {
1280 if (tops[r].addr == 0)
1281 continue;
1282 name[0] = 0;
1283 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1284 name[63] = 0;
1285 score_here = tops[r].score;
1286 score_cumul += score_here;
1287 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1288 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1289 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1290 r,
1291 score_cumul, buf_cumul,
1292 score_here, buf_here, tops[r].addr, name );
1293 }
1294
1295 VG_(printf)("\n");
1296 VG_(printf)("-----------------------------------------------------------\n");
1297 VG_(printf)("--- BB Profile (BB details) ---\n");
1298 VG_(printf)("-----------------------------------------------------------\n");
1299 VG_(printf)("\n");
1300
1301 score_cumul = 0;
1302 for (r = 0; r < n_tops; r++) {
1303 if (tops[r].addr == 0)
1304 continue;
1305 name[0] = 0;
1306 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1307 name[63] = 0;
1308 score_here = tops[r].score;
1309 score_cumul += score_here;
1310 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1311 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1312 VG_(printf)("\n");
1313 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin BB rank %d "
1314 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
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 VG_(printf)("\n");
sewardjbcccbc02007-04-09 22:24:57 +00001320 VG_(discard_translations)(tops[r].addr, 1, "bb profile");
sewardj0ec07f32006-01-12 12:32:32 +00001321 VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0, True);
njn2025cf92005-06-26 20:44:48 +00001322 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= end BB rank %d "
1323 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1324 }
1325
1326 VG_(printf)("\n");
1327 VG_(printf)("-----------------------------------------------------------\n");
1328 VG_(printf)("--- END BB Profile ---\n");
1329 VG_(printf)("-----------------------------------------------------------\n");
1330 VG_(printf)("\n");
1331}
1332
1333
1334/*====================================================================*/
nethercote71980f02004-01-24 18:18:54 +00001335/*=== main() ===*/
1336/*====================================================================*/
1337
sewardjfdf91b42005-09-28 00:53:09 +00001338/* When main() is entered, we should be on the following stack, not
1339 the one the kernel gave us. We will run on this stack until
1340 simulation of the root thread is started, at which point a transfer
1341 is made to a dynamically allocated stack. This is for the sake of
1342 uniform overflow detection for all Valgrind threads. This is
1343 marked global even though it isn't, because assembly code below
1344 needs to reference the name. */
1345
1346/*static*/ VgStack VG_(interim_stack);
1347
sewardjf9d2f9b2006-11-17 20:00:57 +00001348/* These are the structures used to hold info for creating the initial
1349 client image.
1350
1351 'iicii' mostly holds important register state present at system
1352 startup (_start_valgrind). valgrind_main() then fills in the rest
1353 of it and passes it to VG_(ii_create_image)(). That produces
1354 'iifii', which is later handed to VG_(ii_finalise_image). */
1355
1356/* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1357 This should get some address inside the stack on which we gained
sewardjfdf91b42005-09-28 00:53:09 +00001358 control (eg, it could be the SP at startup). It doesn't matter
1359 exactly where in the stack it is. This value is passed to the
sewardjf9d2f9b2006-11-17 20:00:57 +00001360 address space manager at startup. On Linux, aspacem then uses it
1361 to identify the initial stack segment and hence the upper end of
1362 the usable address space. */
sewardjfdf91b42005-09-28 00:53:09 +00001363
sewardjf9d2f9b2006-11-17 20:00:57 +00001364static IICreateImageInfo the_iicii;
1365static IIFinaliseImageInfo the_iifii;
1366
sewardjfdf91b42005-09-28 00:53:09 +00001367
sewardj9c606bd2008-09-18 18:12:50 +00001368/* A simple pair structure, used for conveying debuginfo handles to
1369 calls to VG_TRACK(new_mem_startup, ...). */
1370typedef struct { Addr a; ULong ull; } Addr_n_ULong;
1371
1372
sewardj1ae3f3a2005-09-28 10:47:38 +00001373/* --- Forwards decls to do with shutdown --- */
1374
1375static void final_tidyup(ThreadId tid);
1376
1377/* Do everything which needs doing when the last thread exits */
1378static
1379void shutdown_actions_NORETURN( ThreadId tid,
1380 VgSchedReturnCode tids_schedretcode );
1381
1382/* --- end of Forwards decls to do with shutdown --- */
sewardjfdf91b42005-09-28 00:53:09 +00001383
1384
sewardjf9d2f9b2006-11-17 20:00:57 +00001385/* By the time we get to valgrind_main, the_iicii should already have
1386 been filled in with any important details as required by whatever
1387 OS we have been built for.
1388*/
sewardj17c11042006-10-15 01:26:40 +00001389static
sewardjf9d2f9b2006-11-17 20:00:57 +00001390Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
nethercote71980f02004-01-24 18:18:54 +00001391{
sewardj13247ca2005-12-30 22:52:20 +00001392 HChar* toolname = "memcheck"; // default to Memcheck
sewardj13247ca2005-12-30 22:52:20 +00001393 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
sewardjde764e82007-11-09 23:13:22 +00001394 ThreadId tid_main = VG_INVALID_THREADID;
sewardj738856f2009-07-15 14:48:32 +00001395 Bool logging_to_fd = False;
1396 Char* xml_fname_unexpanded = NULL;
sewardj45f4e7c2005-09-27 19:20:21 +00001397 Int loglevel, i;
nethercote73b526f2004-10-31 18:48:21 +00001398 struct vki_rlimit zero = { 0, 0 };
sewardj9c606bd2008-09-18 18:12:50 +00001399 XArray* addr2dihandle = NULL;
sewardj17c11042006-10-15 01:26:40 +00001400
nethercote71980f02004-01-24 18:18:54 +00001401 //============================================================
nethercote71980f02004-01-24 18:18:54 +00001402 //
sewardj45f4e7c2005-09-27 19:20:21 +00001403 // Nb: startup is complex. Prerequisites are shown at every step.
nethercote71980f02004-01-24 18:18:54 +00001404 // *** Be very careful when messing with the order ***
sewardj45f4e7c2005-09-27 19:20:21 +00001405 //
1406 // The first order of business is to get debug logging, the address
1407 // space manager and the dynamic memory manager up and running.
1408 // Once that's done, we can relax a bit.
1409 //
nethercote71980f02004-01-24 18:18:54 +00001410 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001411
1412 /* This is needed to make VG_(getenv) usable early. */
1413 VG_(client_envp) = (Char**)envp;
nethercote71980f02004-01-24 18:18:54 +00001414
sewardj1cf558c2005-04-25 01:36:56 +00001415 //--------------------------------------------------------------
njnf76d27a2009-05-28 01:53:07 +00001416 // Start up Mach kernel interface, if any
1417 // p: none
1418 //--------------------------------------------------------------
1419# if defined(VGO_darwin)
1420 VG_(mach_init)();
1421# endif
1422
1423 //--------------------------------------------------------------
sewardj1cf558c2005-04-25 01:36:56 +00001424 // Start up the logging mechanism
1425 // p: none
1426 //--------------------------------------------------------------
1427 /* Start the debugging-log system ASAP. First find out how many
njn83df0b62009-02-25 01:01:05 +00001428 "-d"s were specified. This is a pre-scan of the command line. Also
1429 get --profile-heap=yes which is needed by the time we start up dynamic
1430 memory management. */
sewardj1cf558c2005-04-25 01:36:56 +00001431 loglevel = 0;
1432 for (i = 1; i < argc; i++) {
njn83df0b62009-02-25 01:01:05 +00001433 if (argv[i][0] != '-') break;
1434 if VG_STREQ(argv[i], "--") break;
1435 if VG_STREQ(argv[i], "-d") loglevel++;
1436 if VG_BOOL_CLO(argv[i], "--profile-heap", VG_(clo_profile_heap)) {}
sewardj1cf558c2005-04-25 01:36:56 +00001437 }
1438
1439 /* ... and start the debug logger. Now we can safely emit logging
1440 messages all through startup. */
sewardj10759312005-05-30 23:52:47 +00001441 VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
sewardj45f4e7c2005-09-27 19:20:21 +00001442 VG_(debugLog)(1, "main", "Welcome to Valgrind version "
1443 VERSION " debug logging\n");
1444
1445 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001446 // AIX5 only: register the system call numbers
1447 // p: logging
1448 // p: that the initial few syscall numbers stated in the
1449 // bootblock have been installed (else we can't
1450 // open/read/close).
1451 //--------------------------------------------------------------
1452# if defined(VGO_aix5)
1453 VG_(debugLog)(1, "main", "aix5: registering syscalls ..\n");
1454 { UChar sysent_name[50];
1455 SysRes fd;
1456 Bool ok;
1457 Int n_unregd, sysent_used = 0;
1458 prsysent_t* sysent_hdr;
1459
1460 VG_(sprintf)(sysent_name, "/proc/%d/sysent", VG_(getpid)());
1461 fd = VG_(open)(sysent_name, VKI_O_RDONLY, 0);
1462 if (fd.isError)
1463 VG_(err_config_error)("aix5: can't open /proc/<pid>/sysent");
1464
1465 sysent_used = VG_(read)(fd.res, aix5_sysent_buf, VG_AIX5_SYSENT_SIZE);
1466 if (sysent_used < 0)
1467 VG_(err_config_error)("aix5: error reading /proc/<pid>/sysent");
1468 if (sysent_used >= VG_AIX5_SYSENT_SIZE)
1469 VG_(err_config_error)("aix5: VG_AIX5_SYSENT_SIZE is too low; "
1470 "increase and recompile");
1471 VG_(close)(fd.res);
1472
1473 vg_assert(sysent_used > 0 && sysent_used < VG_AIX5_SYSENT_SIZE);
1474
1475 sysent_hdr = (prsysent_t*)&aix5_sysent_buf[0];
1476
1477 n_unregd = 0;
1478 for (i = 0; i < sysent_hdr->pr_nsyscalls; i++) {
1479 UChar* name = &aix5_sysent_buf[ sysent_hdr
1480 ->pr_syscall[i].pr_nameoff ];
1481 UInt nmbr = sysent_hdr->pr_syscall[i].pr_number;
1482 VG_(debugLog)(3, "main", "aix5: bind syscall %d to \"%s\"\n",
1483 nmbr, name);
1484 ok = VG_(aix5_register_syscall)(nmbr, name);
1485 if (!ok)
1486 n_unregd++;
1487 if (!ok)
1488 VG_(debugLog)(3, "main",
1489 "aix5: bind FAILED: %d to \"%s\"\n",
1490 nmbr, name);
1491 }
1492 VG_(debugLog)(1, "main", "aix5: .. %d syscalls known, %d unknown\n",
1493 sysent_hdr->pr_nsyscalls - n_unregd, n_unregd );
1494 VG_(debugLog)(1, "main", "aix5: __NR_AIX5_FAKE_SIGRETURN = %d\n",
1495 __NR_AIX5_FAKE_SIGRETURN );
1496 }
1497# endif
1498
1499 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001500 // Ensure we're on a plausible stack.
1501 // p: logging
1502 //--------------------------------------------------------------
1503 VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
sewardjfdf91b42005-09-28 00:53:09 +00001504 { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
1505 HChar* limHi = limLo + sizeof(VG_(interim_stack));
sewardj45f4e7c2005-09-27 19:20:21 +00001506 HChar* aLocal = (HChar*)&zero; /* any auto local will do */
1507 if (aLocal < limLo || aLocal >= limHi) {
1508 /* something's wrong. Stop. */
1509 VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
1510 limLo, limHi, aLocal );
1511 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1512 "Initial stack switched failed.\n");
1513 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1514 VG_(exit)(1);
1515 }
1516 }
1517
1518 //--------------------------------------------------------------
1519 // Ensure we have a plausible pointer to the stack on which
1520 // we gained control (not the current stack!)
1521 // p: logging
1522 //--------------------------------------------------------------
1523 VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
sewardjf9d2f9b2006-11-17 20:00:57 +00001524 if (the_iicii.sp_at_startup == 0) {
sewardj45f4e7c2005-09-27 19:20:21 +00001525 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1526 "Initial stack was not noted.\n");
1527 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1528 VG_(exit)(1);
1529 }
1530
1531 //--------------------------------------------------------------
1532 // Start up the address space manager, and determine the
1533 // approximate location of the client's stack
njnea2d6fd2010-07-01 00:20:20 +00001534 // p: logging, plausible-stack
sewardj45f4e7c2005-09-27 19:20:21 +00001535 //--------------------------------------------------------------
1536 VG_(debugLog)(1, "main", "Starting the address space manager\n");
sewardje66f2e02006-12-30 17:45:08 +00001537 vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536);
1538 vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536);
1539 vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
1540 vg_assert(VKI_PAGE_SIZE == (1 << VKI_PAGE_SHIFT));
1541 vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
sewardjf9d2f9b2006-11-17 20:00:57 +00001542 the_iicii.clstack_top = VG_(am_startup)( the_iicii.sp_at_startup );
sewardj45f4e7c2005-09-27 19:20:21 +00001543 VG_(debugLog)(1, "main", "Address space manager is running\n");
1544
1545 //--------------------------------------------------------------
1546 // Start up the dynamic memory manager
1547 // p: address space management
njn83df0b62009-02-25 01:01:05 +00001548 // p: getting --profile-heap
sewardj45f4e7c2005-09-27 19:20:21 +00001549 // In fact m_mallocfree is self-initialising, so there's no
1550 // initialisation call to do. Instead, try a simple malloc/
1551 // free pair right now to check that nothing is broken.
1552 //--------------------------------------------------------------
1553 VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
sewardj9c606bd2008-09-18 18:12:50 +00001554 { void* p = VG_(malloc)( "main.vm.1", 12345 );
sewardj45f4e7c2005-09-27 19:20:21 +00001555 if (p) VG_(free)( p );
1556 }
1557 VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
sewardj1cf558c2005-04-25 01:36:56 +00001558
nethercotef4928da2004-06-15 10:54:40 +00001559 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001560 //
1561 // Dynamic memory management is now available.
1562 //
nethercotef4928da2004-06-15 10:54:40 +00001563 //============================================================
1564
sewardj45f4e7c2005-09-27 19:20:21 +00001565 //--------------------------------------------------------------
sewardjf98e1c02008-10-25 16:22:41 +00001566 // Initialise m_debuginfo
1567 // p: dynamic memory allocation
1568 VG_(debugLog)(1, "main", "Initialise m_debuginfo\n");
1569 VG_(di_initialise)();
1570
1571 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001572 // Look for alternative libdir
1573 { HChar *cp = VG_(getenv)(VALGRIND_LIB);
1574 if (cp != NULL)
1575 VG_(libdir) = cp;
njncde90d32009-07-22 22:41:38 +00001576 VG_(debugLog)(1, "main", "VG_(libdir) = %s\n", VG_(libdir));
sewardj45f4e7c2005-09-27 19:20:21 +00001577 }
1578
1579 //--------------------------------------------------------------
1580 // Extract the launcher name from the environment.
njna842d792009-05-21 01:15:18 +00001581 VG_(debugLog)(1, "main", "Getting launcher's name ...\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001582 VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
1583 if (VG_(name_of_launcher) == NULL) {
1584 VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
1585 VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
1586 VG_(exit)(1);
1587 }
njna842d792009-05-21 01:15:18 +00001588 VG_(debugLog)(1, "main", "... %s\n", VG_(name_of_launcher));
sewardj45f4e7c2005-09-27 19:20:21 +00001589
1590 //--------------------------------------------------------------
fitzhardingeb50068f2004-02-24 23:42:55 +00001591 // Get the current process datasize rlimit, and set it to zero.
1592 // This prevents any internal uses of brk() from having any effect.
1593 // We remember the old value so we can restore it on exec, so that
1594 // child processes will have a reasonable brk value.
1595 VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1596 zero.rlim_max = VG_(client_rlimit_data).rlim_max;
1597 VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
thughesc37184f2004-09-11 14:16:57 +00001598
1599 // Get the current process stack rlimit.
1600 VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
1601
sewardje2d1e672005-11-12 23:10:48 +00001602 //--------------------------------------------------------------
1603 // Figure out what sort of CPU we're on, and whether it is
1604 // able to run V.
1605 VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
1606 { VexArch vex_arch;
1607 VexArchInfo vex_archinfo;
1608 Bool ok = VG_(machine_get_hwcaps)();
1609 if (!ok) {
1610 VG_(printf)("\n");
1611 VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
1612 VG_(printf)(" Supported CPUs are:\n");
1613 VG_(printf)(" * x86 (practically any; Pentium-I or above), "
1614 "AMD Athlon or above)\n");
1615 VG_(printf)(" * AMD Athlon64/Opteron\n");
1616 VG_(printf)(" * PowerPC (most; ppc405 and above)\n");
1617 VG_(printf)("\n");
1618 VG_(exit)(1);
1619 }
1620 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001621 VG_(debugLog)(
1622 1, "main", "... arch = %s, hwcaps = %s\n",
1623 LibVEX_ppVexArch ( vex_arch ),
1624 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1625 );
sewardje2d1e672005-11-12 23:10:48 +00001626 }
1627
sewardj198f34f2007-07-09 23:13:07 +00001628 //--------------------------------------------------------------
1629 // Record the working directory at startup
1630 // p: none (Linux), getenv and sys_getpid work (AIX)
1631 VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
1632 { Bool ok = VG_(record_startup_wd)();
1633 if (!ok)
1634 VG_(err_config_error)( "Can't establish current working "
1635 "directory at startup");
1636 }
1637 { Char buf[VKI_PATH_MAX+1];
1638 Bool ok = VG_(get_startup_wd)( buf, sizeof(buf) );
1639 vg_assert(ok);
1640 buf[VKI_PATH_MAX] = 0;
1641 VG_(debugLog)(1, "main", "... %s\n", buf );
1642 }
1643
sewardj45f4e7c2005-09-27 19:20:21 +00001644 //============================================================
1645 // Command line argument handling order:
1646 // * If --help/--help-debug are present, show usage message
1647 // (including the tool-specific usage)
1648 // * (If no --tool option given, default to Memcheck)
1649 // * Then, if client is missing, abort with error msg
1650 // * Then, if any cmdline args are bad, abort with error msg
1651 //============================================================
1652
1653 //--------------------------------------------------------------
1654 // Split up argv into: C args, V args, V extra args, and exename.
1655 // p: dynamic memory allocation
1656 //--------------------------------------------------------------
1657 VG_(debugLog)(1, "main", "Split up command line\n");
1658 VG_(split_up_argv)( argc, argv );
sewardj14c7cc52007-02-25 15:08:24 +00001659 vg_assert( VG_(args_for_valgrind) );
1660 vg_assert( VG_(args_for_client) );
sewardj45f4e7c2005-09-27 19:20:21 +00001661 if (0) {
sewardj14c7cc52007-02-25 15:08:24 +00001662 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
1663 VG_(printf)(
1664 "varg %s\n",
1665 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1666 );
sewardj45f4e7c2005-09-27 19:20:21 +00001667 VG_(printf)(" exe %s\n", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001668 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
1669 VG_(printf)(
1670 "carg %s\n",
1671 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1672 );
nethercote71980f02004-01-24 18:18:54 +00001673 }
1674
sewardj948a6fc2007-03-19 18:38:55 +00001675# if defined(VGO_aix5)
1676 /* Tolerate ptraced-based launchers. They can't run 'no program'
1677 if the user types "valgrind --help", so they run a do-nothing
1678 program $prefix/bin/no_op_client_for_valgrind, and we catch that
1679 here and turn it the exe name back into NULL. Then --help,
1680 --version etc work as they should. */
1681 if (VG_(args_the_exename)
1682 && VG_(strstr)( VG_(args_the_exename), "/no_op_client_for_valgrind" )) {
1683 VG_(args_the_exename) = NULL;
1684 }
1685# endif
1686
nethercote71980f02004-01-24 18:18:54 +00001687 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001688 // Extract tool name and whether help has been requested.
1689 // Note we can't print the help message yet, even if requested,
1690 // because the tool has not been initialised.
1691 // p: split_up_argv [for VG_(args_for_valgrind)]
nethercote71980f02004-01-24 18:18:54 +00001692 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001693 VG_(debugLog)(1, "main",
1694 "(early_) Process Valgrind's command line options\n");
1695 early_process_cmd_line_options(&need_help, &toolname);
nethercote71980f02004-01-24 18:18:54 +00001696
sewardj45f4e7c2005-09-27 19:20:21 +00001697 // Set default vex control params
1698 LibVEX_default_VexControl(& VG_(clo_vex_control));
nethercote71980f02004-01-24 18:18:54 +00001699
1700 //--------------------------------------------------------------
1701 // Load client executable, finding in $PATH if necessary
njn83df0b62009-02-25 01:01:05 +00001702 // p: early_process_cmd_line_options() [for 'exec', 'need_help',
1703 // clo_max_stackframe,
1704 // clo_main_stacksize]
sewardj95d86c02007-12-18 01:49:23 +00001705 // p: layout_remaining_space [so there's space]
sewardj17c11042006-10-15 01:26:40 +00001706 //
nethercote71980f02004-01-24 18:18:54 +00001707 // Set up client's environment
sewardj95d86c02007-12-18 01:49:23 +00001708 // p: set-libdir [for VG_(libdir)]
1709 // p: early_process_cmd_line_options [for toolname]
sewardj17c11042006-10-15 01:26:40 +00001710 //
nethercote5ee67ca2004-06-22 14:00:09 +00001711 // Setup client stack, eip, and VG_(client_arg[cv])
nethercote71980f02004-01-24 18:18:54 +00001712 // p: load_client() [for 'info']
1713 // p: fix_environment() [for 'env']
sewardj17c11042006-10-15 01:26:40 +00001714 //
sewardj45f4e7c2005-09-27 19:20:21 +00001715 // Setup client data (brk) segment. Initially a 1-page segment
1716 // which abuts a shrinkable reservation.
1717 // p: load_client() [for 'info' and hence VG_(brk_base)]
sewardjf9d2f9b2006-11-17 20:00:57 +00001718 //
1719 // p: _start_in_C (for zeroing out the_iicii and putting some
1720 // initial values into it)
sewardj45f4e7c2005-09-27 19:20:21 +00001721 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001722 if (!need_help) {
sewardjf9d2f9b2006-11-17 20:00:57 +00001723 VG_(debugLog)(1, "main", "Create initial image\n");
1724
njnf76d27a2009-05-28 01:53:07 +00001725# if defined(VGO_linux) || defined(VGO_darwin)
sewardjf9d2f9b2006-11-17 20:00:57 +00001726 the_iicii.argv = argv;
1727 the_iicii.envp = envp;
1728 the_iicii.toolname = toolname;
1729# elif defined(VGO_aix5)
1730 /* the_iicii.intregs37 already set up */
1731 /* the_iicii.bootblock already set up */
1732 /* the_iicii.adler32_exp already set up */
1733 /* the_iicii.sp_at_startup is irrelevant */
1734 /* the_iicii.clstack_top is irrelevant */
1735 the_iicii.toolname = toolname;
1736# else
njna842d792009-05-21 01:15:18 +00001737# error "Unknown platform"
sewardjf9d2f9b2006-11-17 20:00:57 +00001738# endif
1739
sewardjdc2f79e2007-12-22 14:14:04 +00001740 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001741 the_iifii = VG_(ii_create_image)( the_iicii );
1742
sewardj17c11042006-10-15 01:26:40 +00001743# if defined(VGO_aix5)
sewardj17c11042006-10-15 01:26:40 +00001744 /* Tell aspacem where the initial client stack is, so that it
1745 can later produce a faked-up NSegment in response to
1746 VG_(am_find_nsegment) for that address range, if asked. */
sewardjdc2f79e2007-12-22 14:14:04 +00001747 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001748 VG_(am_aix5_set_initial_client_sp)( the_iifii.initial_client_SP );
1749 /* Now have a look at said fake segment, so we can find out
1750 the size of it. */
1751 { SizeT sz;
1752 NSegment const* seg
1753 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
1754 vg_assert(seg);
1755 sz = seg->end - seg->start + 1;
sewardjc9d33832007-12-22 14:12:42 +00001756 vg_assert(sz >= 0 && sz <= (256+1)*1024*1024); /* stay sane */
sewardjf9d2f9b2006-11-17 20:00:57 +00001757 the_iifii.clstack_max_size = sz;
1758 }
sewardj17c11042006-10-15 01:26:40 +00001759# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001760 }
nethercote71980f02004-01-24 18:18:54 +00001761
1762 //==============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001763 //
1764 // Finished loading/setting up the client address space.
1765 //
nethercote71980f02004-01-24 18:18:54 +00001766 //==============================================================
1767
1768 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001769 // setup file descriptors
1770 // p: n/a
1771 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001772 VG_(debugLog)(1, "main", "Setup file descriptors\n");
nethercote71980f02004-01-24 18:18:54 +00001773 setup_file_descriptors();
1774
1775 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001776 // create the fake /proc/<pid>/cmdline file and then unlink it,
1777 // but hold onto the fd, so we can hand it out to the client
1778 // when it tries to open /proc/<pid>/cmdline for itself.
1779 // p: setup file descriptors
nethercotec314eba2004-07-15 12:59:41 +00001780 //--------------------------------------------------------------
bart9b533f82009-08-25 20:15:41 +00001781#if !defined(VGO_linux)
1782 // client shouldn't be using /proc!
1783 VG_(cl_cmdline_fd) = -1;
1784#else
1785 if (!need_help) {
1786 HChar buf[50], buf2[50+64];
1787 HChar nul[1];
1788 Int fd, r;
barta3054f52010-06-14 18:12:56 +00001789 const HChar* exename;
nethercotec314eba2004-07-15 12:59:41 +00001790
bart9b533f82009-08-25 20:15:41 +00001791 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001792
bart9b533f82009-08-25 20:15:41 +00001793 VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
1794 fd = VG_(mkstemp)( buf, buf2 );
1795 if (fd == -1)
1796 VG_(err_config_error)("Can't create client cmdline file in /tmp.");
sewardj45f4e7c2005-09-27 19:20:21 +00001797
bart9b533f82009-08-25 20:15:41 +00001798 nul[0] = 0;
1799 exename = VG_(args_the_exename) ? VG_(args_the_exename)
1800 : "unknown_exename";
1801 VG_(write)(fd, VG_(args_the_exename),
1802 VG_(strlen)( VG_(args_the_exename) ));
1803 VG_(write)(fd, nul, 1);
1804
1805 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1806 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
1807 VG_(write)(fd, arg, VG_(strlen)( arg ));
sewardj45f4e7c2005-09-27 19:20:21 +00001808 VG_(write)(fd, nul, 1);
1809 }
bart9b533f82009-08-25 20:15:41 +00001810
1811 /* Don't bother to seek the file back to the start; instead do
1812 it every time a copy of it is given out (by PRE(sys_open)).
1813 That is probably more robust across fork() etc. */
1814
1815 /* Now delete it, but hang on to the fd. */
1816 r = VG_(unlink)( buf2 );
1817 if (r)
1818 VG_(err_config_error)("Can't delete client cmdline file in /tmp.");
1819
1820 VG_(cl_cmdline_fd) = fd;
sewardj45f4e7c2005-09-27 19:20:21 +00001821 }
bart9b533f82009-08-25 20:15:41 +00001822#endif
nethercotec314eba2004-07-15 12:59:41 +00001823
1824 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001825 // Init tool part 1: pre_clo_init
nethercotec314eba2004-07-15 12:59:41 +00001826 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
nethercotec314eba2004-07-15 12:59:41 +00001827 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
nethercote71980f02004-01-24 18:18:54 +00001828 //--------------------------------------------------------------
sewardj7cf4e6b2008-05-01 20:24:26 +00001829 VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
njn08ce7b32009-02-27 03:38:28 +00001830 VG_(tl_pre_clo_init)();
nethercote71980f02004-01-24 18:18:54 +00001831
sewardj45f4e7c2005-09-27 19:20:21 +00001832 //--------------------------------------------------------------
nethercotef4928da2004-06-15 10:54:40 +00001833 // If --tool and --help/--help-debug was given, now give the core+tool
1834 // help message
sewardj95d86c02007-12-18 01:49:23 +00001835 // p: early_process_cmd_line_options() [for 'need_help']
1836 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
sewardj45f4e7c2005-09-27 19:20:21 +00001837 //--------------------------------------------------------------
1838 VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
nethercotef4928da2004-06-15 10:54:40 +00001839 if (need_help) {
njncce38e62010-07-06 04:25:12 +00001840 usage_NORETURN(/*--help-debug?*/need_help >= 2);
nethercotef4928da2004-06-15 10:54:40 +00001841 }
nethercotec314eba2004-07-15 12:59:41 +00001842
sewardj45f4e7c2005-09-27 19:20:21 +00001843 //--------------------------------------------------------------
1844 // Process command line options to Valgrind + tool
1845 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1846 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1847 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001848 VG_(debugLog)(1, "main",
1849 "(main_) Process Valgrind's command line options, "
1850 "setup logging\n");
sewardj738856f2009-07-15 14:48:32 +00001851 main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded,
1852 toolname );
sewardj45f4e7c2005-09-27 19:20:21 +00001853
1854 //--------------------------------------------------------------
sewardj592ae092005-11-08 19:01:44 +00001855 // Zeroise the millisecond counter by doing a first read of it.
1856 // p: none
1857 //--------------------------------------------------------------
1858 (void) VG_(read_millisecond_timer)();
1859
1860 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001861 // Print the preamble
1862 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
sewardj738856f2009-07-15 14:48:32 +00001863 // p: main_process_cmd_line_options()
1864 // [for VG_(clo_verbosity), VG_(clo_xml),
1865 // logging_to_fd, xml_fname_unexpanded]
sewardj45f4e7c2005-09-27 19:20:21 +00001866 //--------------------------------------------------------------
1867 VG_(debugLog)(1, "main", "Print the preamble...\n");
sewardj738856f2009-07-15 14:48:32 +00001868 print_preamble(logging_to_fd, xml_fname_unexpanded, toolname);
sewardj45f4e7c2005-09-27 19:20:21 +00001869 VG_(debugLog)(1, "main", "...finished the preamble\n");
1870
1871 //--------------------------------------------------------------
1872 // Init tool part 2: post_clo_init
1873 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1874 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1875 // p: print_preamble() [so any warnings printed in post_clo_init
1876 // are shown after the preamble]
1877 //--------------------------------------------------------------
1878 VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
njn51d827b2005-05-09 01:02:08 +00001879 VG_TDICT_CALL(tool_post_clo_init);
sewardj7cf4e6b2008-05-01 20:24:26 +00001880 {
1881 /* The tool's "needs" will by now be finalised, since it has no
1882 further opportunity to specify them. So now sanity check
1883 them. */
1884 Char* s;
1885 Bool ok;
1886 ok = VG_(sanity_check_needs)( &s );
1887 if (!ok) {
1888 VG_(tool_panic)(s);
1889 }
1890 }
nethercotef4928da2004-06-15 10:54:40 +00001891
1892 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001893 // Initialise translation table and translation cache
1894 // p: aspacem [??]
1895 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
nethercote71980f02004-01-24 18:18:54 +00001896 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001897 VG_(debugLog)(1, "main", "Initialise TT/TC\n");
1898 VG_(init_tt_tc)();
sewardjb5f6f512005-03-10 23:59:00 +00001899
sewardj45f4e7c2005-09-27 19:20:21 +00001900 //--------------------------------------------------------------
1901 // Initialise the redirect table.
1902 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
1903 // p: aspacem [so can change ownership of sysinfo pages]
1904 //--------------------------------------------------------------
1905 VG_(debugLog)(1, "main", "Initialise redirects\n");
sewardj0ec07f32006-01-12 12:32:32 +00001906 VG_(redir_initialise)();
nethercote71980f02004-01-24 18:18:54 +00001907
1908 //--------------------------------------------------------------
1909 // Allow GDB attach
sewardj95d86c02007-12-18 01:49:23 +00001910 // p: main_process_cmd_line_options() [for VG_(clo_wait_for_gdb)]
nethercote71980f02004-01-24 18:18:54 +00001911 //--------------------------------------------------------------
1912 /* Hook to delay things long enough so we can get the pid and
1913 attach GDB in another shell. */
1914 if (VG_(clo_wait_for_gdb)) {
sewardj95611ff2007-02-16 13:57:07 +00001915 Long iters;
1916 volatile Long q;
sewardj1fbc1a52005-04-25 02:05:54 +00001917 VG_(debugLog)(1, "main", "Wait for GDB\n");
sewardj93ab8572005-02-06 14:10:40 +00001918 VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
sewardj8211a572005-06-23 21:37:47 +00001919
1920# if defined(VGP_x86_linux)
1921 iters = 5;
sewardj2c48c7b2005-11-29 13:05:56 +00001922# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
sewardj8211a572005-06-23 21:37:47 +00001923 iters = 10;
1924# elif defined(VGP_ppc32_linux)
sewardjd714d2e2005-07-08 18:24:04 +00001925 iters = 5;
sewardj59570ff2010-01-01 11:59:33 +00001926# elif defined(VGP_arm_linux)
1927 iters = 1;
sewardj17c11042006-10-15 01:26:40 +00001928# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1929 iters = 4;
njnf76d27a2009-05-28 01:53:07 +00001930# elif defined(VGO_darwin)
1931 iters = 3;
sewardj8211a572005-06-23 21:37:47 +00001932# else
sewardj17c11042006-10-15 01:26:40 +00001933# error "Unknown plat"
sewardj8211a572005-06-23 21:37:47 +00001934# endif
1935
1936 iters *= 1000*1000*1000;
1937 for (q = 0; q < iters; q++)
1938 ;
nethercote71980f02004-01-24 18:18:54 +00001939 }
1940
sewardjb5d320c2005-03-13 18:57:15 +00001941 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001942 // Search for file descriptors that are inherited from our parent
sewardj95d86c02007-12-18 01:49:23 +00001943 // p: main_process_cmd_line_options [for VG_(clo_track_fds)]
nethercote71980f02004-01-24 18:18:54 +00001944 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001945 if (VG_(clo_track_fds)) {
1946 VG_(debugLog)(1, "main", "Init preopened fds\n");
nethercote71980f02004-01-24 18:18:54 +00001947 VG_(init_preopened_fds)();
sewardj1fbc1a52005-04-25 02:05:54 +00001948 }
nethercote71980f02004-01-24 18:18:54 +00001949
1950 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001951 // Load debug info for the existing segments.
1952 // p: setup_code_redirect_table [so that redirs can be recorded]
1953 // p: mallocfree
1954 // p: probably: setup fds and process CLOs, so that logging works
sewardjf98e1c02008-10-25 16:22:41 +00001955 // p: initialise m_debuginfo
sewardj9c606bd2008-09-18 18:12:50 +00001956 //
1957 // While doing this, make a note of the debuginfo-handles that
1958 // come back from VG_(di_notify_mmap)/VG_(di_aix5_notify_segchange).
1959 // Later, in "Tell the tool about the initial client memory permissions"
1960 // (just below) we can then hand these handles off to the tool in
1961 // calls to VG_TRACK(new_mem_startup, ...). This gives the tool the
1962 // opportunity to make further queries to m_debuginfo before the
1963 // client is started, if it wants. We put this information into an
1964 // XArray, each handle along with the associated segment start address,
1965 // and search the XArray for the handles later, when calling
1966 // VG_TRACK(new_mem_startup, ...).
sewardj45f4e7c2005-09-27 19:20:21 +00001967 //--------------------------------------------------------------
1968 VG_(debugLog)(1, "main", "Load initial debug info\n");
sewardj9c606bd2008-09-18 18:12:50 +00001969
1970 tl_assert(!addr2dihandle);
1971 addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2",
1972 VG_(free), sizeof(Addr_n_ULong) );
1973 tl_assert(addr2dihandle);
1974
sewardj17c11042006-10-15 01:26:40 +00001975# if defined(VGO_linux)
sewardj45f4e7c2005-09-27 19:20:21 +00001976 { Addr* seg_starts;
1977 Int n_seg_starts;
sewardj9c606bd2008-09-18 18:12:50 +00001978 Addr_n_ULong anu;
sewardj45f4e7c2005-09-27 19:20:21 +00001979
njnac1e0332009-05-08 00:39:31 +00001980 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001981 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00001982
sewardjf72cced2005-11-08 00:45:47 +00001983 /* show them all to the debug info reader. allow_SkFileV has to
1984 be True here so that we read info from the valgrind executable
1985 itself. */
sewardj9c606bd2008-09-18 18:12:50 +00001986 for (i = 0; i < n_seg_starts; i++) {
1987 anu.ull = VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/ );
1988 /* anu.ull holds the debuginfo handle returned by di_notify_mmap,
1989 if any. */
1990 if (anu.ull > 0) {
1991 anu.a = seg_starts[i];
1992 VG_(addToXA)( addr2dihandle, &anu );
1993 }
1994 }
sewardj45f4e7c2005-09-27 19:20:21 +00001995
1996 VG_(free)( seg_starts );
1997 }
sewardj17c11042006-10-15 01:26:40 +00001998# elif defined(VGO_aix5)
1999 { AixCodeSegChange* changes;
2000 Int changes_size, changes_used;
sewardj9c606bd2008-09-18 18:12:50 +00002001 Addr_n_ULong anu;
sewardj17c11042006-10-15 01:26:40 +00002002
2003 /* Find out how many AixCodeSegChange records we will need,
2004 and acquire them. */
2005 changes_size = VG_(am_aix5_reread_procmap_howmany_directives)();
sewardj9c606bd2008-09-18 18:12:50 +00002006 changes = VG_(malloc)("main.vm.3", changes_size * sizeof(AixCodeSegChange));
sewardj17c11042006-10-15 01:26:40 +00002007 vg_assert(changes);
2008
2009 /* Now re-read /proc/<pid>/map and acquire a change set */
2010 VG_(am_aix5_reread_procmap)( changes, &changes_used );
2011 vg_assert(changes_used >= 0 && changes_used <= changes_size);
2012
2013 /* And notify m_debuginfo of the changes. */
sewardj9c606bd2008-09-18 18:12:50 +00002014 for (i = 0; i < changes_used; i++) {
2015 anu.ull = VG_(di_aix5_notify_segchange)(
2016 changes[i].code_start,
2017 changes[i].code_len,
2018 changes[i].data_start,
2019 changes[i].data_len,
2020 changes[i].file_name,
2021 changes[i].mem_name,
2022 changes[i].is_mainexe,
2023 changes[i].acquire
2024 );
2025 if (anu.ull > 0) {
2026 tl_assert(changes[i].acquire);
2027 anu.a = changes[i].code_start; /* is this correct? */
2028 VG_(addToXA)( addr2dihandle, &anu );
2029 }
2030 }
sewardj17c11042006-10-15 01:26:40 +00002031
2032 VG_(free)(changes);
2033 }
njnf76d27a2009-05-28 01:53:07 +00002034# elif defined(VGO_darwin)
2035 { Addr* seg_starts;
2036 Int n_seg_starts;
2037 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
2038 vg_assert(seg_starts && n_seg_starts >= 0);
2039
2040 /* show them all to the debug info reader.
2041 Don't read from V segments (unlike Linux) */
2042 // GrP fixme really?
2043 for (i = 0; i < n_seg_starts; i++)
2044 VG_(di_notify_mmap)( seg_starts[i], False/*don't allow_SkFileV*/ );
2045
2046 VG_(free)( seg_starts );
2047 }
sewardj17c11042006-10-15 01:26:40 +00002048# else
2049# error Unknown OS
2050# endif
sewardj45f4e7c2005-09-27 19:20:21 +00002051
2052 //--------------------------------------------------------------
2053 // Tell aspacem of ownership change of the asm helpers, so that
2054 // m_translate allows them to be translated. However, only do this
2055 // after the initial debug info read, since making a hole in the
2056 // address range for the stage2 binary confuses the debug info reader.
2057 // p: aspacem
2058 //--------------------------------------------------------------
2059 { Bool change_ownership_v_c_OK;
sewardj1a85f4f2006-01-12 21:15:35 +00002060 Addr co_start = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
2061 Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
sewardj45f4e7c2005-09-27 19:20:21 +00002062 VG_(debugLog)(1,"redir",
2063 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
2064 (ULong)co_start, (ULong)co_endPlus-1 );
2065
2066 change_ownership_v_c_OK
2067 = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
2068 vg_assert(change_ownership_v_c_OK);
2069 }
2070
2071 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002072 // Initialise the scheduler (phase 1) [generates tid_main]
2073 // p: none, afaics
2074 //--------------------------------------------------------------
2075 VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
2076 tid_main = VG_(scheduler_init_phase1)();
2077 vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
2078 && tid_main != VG_INVALID_THREADID);
2079 /* Tell the tool about tid_main */
2080 VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
2081
2082 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002083 // Tell the tool about the initial client memory permissions
2084 // p: aspacem
2085 // p: mallocfree
2086 // p: setup_client_stack
2087 // p: setup_client_dataseg
sewardj9c606bd2008-09-18 18:12:50 +00002088 //
2089 // For each segment we tell the client about, look up in
2090 // addr2dihandle as created above, to see if there's a debuginfo
2091 // handle associated with the segment, that we can hand along
2092 // to the tool, to be helpful.
sewardj45f4e7c2005-09-27 19:20:21 +00002093 //--------------------------------------------------------------
2094 VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
2095 { Addr* seg_starts;
2096 Int n_seg_starts;
sewardj45f4e7c2005-09-27 19:20:21 +00002097
sewardj9c606bd2008-09-18 18:12:50 +00002098 tl_assert(addr2dihandle);
2099
tom7c1a19a2008-01-02 10:13:04 +00002100 /* Mark the main thread as running while we tell the tool about
2101 the client memory so that the tool can associate that memory
2102 with the main thread. */
2103 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
2104 VG_(running_tid) = tid_main;
2105
njnac1e0332009-05-08 00:39:31 +00002106 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00002107 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00002108
2109 /* show interesting ones to the tool */
2110 for (i = 0; i < n_seg_starts; i++) {
sewardj9c606bd2008-09-18 18:12:50 +00002111 Word j, n;
sewardj12ab7652006-10-17 02:10:42 +00002112 NSegment const* seg
sewardj17c11042006-10-15 01:26:40 +00002113 = VG_(am_find_nsegment)( seg_starts[i] );
sewardj45f4e7c2005-09-27 19:20:21 +00002114 vg_assert(seg);
2115 if (seg->kind == SkFileC || seg->kind == SkAnonC) {
sewardjc6d86a32009-01-31 15:08:08 +00002116 /* This next assertion is tricky. If it is placed
2117 immediately before this 'if', it very occasionally fails.
2118 Why? Because previous iterations of the loop may have
2119 caused tools (via the new_mem_startup calls) to do
2120 dynamic memory allocation, and that may affect the mapped
2121 segments; in particular it may cause segment merging to
2122 happen. Hence we cannot assume that seg_starts[i], which
2123 reflects the state of the world before we started this
2124 loop, is the same as seg->start, as the latter reflects
2125 the state of the world (viz, mappings) at this particular
2126 iteration of the loop.
2127
2128 Why does moving it inside the 'if' make it safe? Because
2129 any dynamic memory allocation done by the tools will
2130 affect only the state of Valgrind-owned segments, not of
2131 Client-owned segments. And the 'if' guards against that
2132 -- we only get in here for Client-owned segments.
2133
2134 In other words: the loop may change the state of
2135 Valgrind-owned segments as it proceeds. But it should
2136 not cause the Client-owned segments to change. */
2137 vg_assert(seg->start == seg_starts[i]);
sewardj45f4e7c2005-09-27 19:20:21 +00002138 VG_(debugLog)(2, "main",
2139 "tell tool about %010lx-%010lx %c%c%c\n",
2140 seg->start, seg->end,
2141 seg->hasR ? 'r' : '-',
2142 seg->hasW ? 'w' : '-',
2143 seg->hasX ? 'x' : '-' );
sewardj9c606bd2008-09-18 18:12:50 +00002144 /* search addr2dihandle to see if we have an entry
2145 matching seg->start. */
2146 n = VG_(sizeXA)( addr2dihandle );
2147 for (j = 0; j < n; j++) {
2148 Addr_n_ULong* anl = VG_(indexXA)( addr2dihandle, j );
2149 if (anl->a == seg->start) {
2150 tl_assert(anl->ull > 0); /* check it's a valid handle */
2151 break;
2152 }
2153 }
2154 vg_assert(j >= 0 && j <= n);
sewardj45f4e7c2005-09-27 19:20:21 +00002155 VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
sewardj9c606bd2008-09-18 18:12:50 +00002156 seg->hasR, seg->hasW, seg->hasX,
2157 /* and the retrieved debuginfo handle, if any */
2158 j < n
2159 ? ((Addr_n_ULong*)VG_(indexXA)( addr2dihandle, j ))->ull
2160 : 0 );
sewardj45f4e7c2005-09-27 19:20:21 +00002161 }
2162 }
2163
2164 VG_(free)( seg_starts );
sewardj9c606bd2008-09-18 18:12:50 +00002165 VG_(deleteXA)( addr2dihandle );
sewardj45f4e7c2005-09-27 19:20:21 +00002166
2167 /* Also do the initial stack permissions. */
barte05b3a42010-09-07 16:32:53 +00002168 {
2169 SSizeT inaccessible_len;
2170 NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002171 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj17c11042006-10-15 01:26:40 +00002172 vg_assert(seg);
2173 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002174 vg_assert(the_iifii.initial_client_SP >= seg->start);
2175 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardj17c11042006-10-15 01:26:40 +00002176# if defined(VGO_aix5)
2177 VG_(clstk_base) = seg->start;
2178 VG_(clstk_end) = seg->end;
2179# endif
sewardj45f4e7c2005-09-27 19:20:21 +00002180
sewardj17c11042006-10-15 01:26:40 +00002181 /* Stuff below the initial SP is unaddressable. Take into
2182 account any ABI-mandated space below the stack pointer that
2183 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
2184 will have allocated an extra page if a red zone is required,
2185 to be on the safe side. */
barte05b3a42010-09-07 16:32:53 +00002186 inaccessible_len = the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
2187 - seg->start;
2188 vg_assert(inaccessible_len >= 0);
2189 if (inaccessible_len > 0)
2190 VG_TRACK( die_mem_stack,
2191 seg->start,
2192 inaccessible_len );
sewardj17c11042006-10-15 01:26:40 +00002193 VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
2194 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00002195 the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
sewardj17c11042006-10-15 01:26:40 +00002196 }
sewardj45f4e7c2005-09-27 19:20:21 +00002197
2198 /* Also the assembly helpers. */
2199 VG_TRACK( new_mem_startup,
2200 (Addr)&VG_(trampoline_stuff_start),
sewardjc6527d62006-02-13 17:54:31 +00002201 (Addr)&VG_(trampoline_stuff_end)
2202 - (Addr)&VG_(trampoline_stuff_start),
sewardj45f4e7c2005-09-27 19:20:21 +00002203 False, /* readable? */
2204 False, /* writable? */
sewardj9c606bd2008-09-18 18:12:50 +00002205 True /* executable? */,
2206 0 /* di_handle: no associated debug info */ );
tom7c1a19a2008-01-02 10:13:04 +00002207
2208 /* Clear the running thread indicator */
2209 VG_(running_tid) = VG_INVALID_THREADID;
2210 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
sewardj45f4e7c2005-09-27 19:20:21 +00002211 }
2212
2213 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002214 // Initialise the scheduler (phase 2)
2215 // p: Initialise the scheduler (phase 1) [for tid_main]
nethercote71980f02004-01-24 18:18:54 +00002216 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
sewardj45f4e7c2005-09-27 19:20:21 +00002217 // p: setup_client_stack
nethercote71980f02004-01-24 18:18:54 +00002218 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002219 VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
sewardj12ab7652006-10-17 02:10:42 +00002220 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002221 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj45f4e7c2005-09-27 19:20:21 +00002222 vg_assert(seg);
2223 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002224 vg_assert(the_iifii.initial_client_SP >= seg->start);
2225 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardjde764e82007-11-09 23:13:22 +00002226 VG_(scheduler_init_phase2)( tid_main,
2227 seg->end, the_iifii.clstack_max_size );
sewardj45f4e7c2005-09-27 19:20:21 +00002228 }
nethercote71980f02004-01-24 18:18:54 +00002229
2230 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00002231 // Set up state for the root thread
sewardjb5f6f512005-03-10 23:59:00 +00002232 // p: ?
sewardj17c11042006-10-15 01:26:40 +00002233 // setup_scheduler() [for sched-specific thread 1 stuff]
sewardjf9d2f9b2006-11-17 20:00:57 +00002234 // VG_(ii_create_image) [for 'the_iicii' initial info]
sewardj2a99cf62004-11-24 10:44:19 +00002235 //--------------------------------------------------------------
sewardjf9d2f9b2006-11-17 20:00:57 +00002236 VG_(debugLog)(1, "main", "Finalise initial image\n");
2237 VG_(ii_finalise_image)( the_iifii );
njnea4b28c2004-11-30 16:04:58 +00002238
sewardj2a99cf62004-11-24 10:44:19 +00002239 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002240 // Initialise the signal handling subsystem
sewardjb5f6f512005-03-10 23:59:00 +00002241 // p: n/a
nethercote71980f02004-01-24 18:18:54 +00002242 //--------------------------------------------------------------
2243 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
sewardj1fbc1a52005-04-25 02:05:54 +00002244 VG_(debugLog)(1, "main", "Initialise signal management\n");
njncda2f0f2009-05-18 02:12:08 +00002245 /* Check that the kernel-interface signal definitions look sane */
2246 VG_(vki_do_initial_consistency_checks)();
2247 /* .. and go on to use them. */
nethercote71980f02004-01-24 18:18:54 +00002248 VG_(sigstartup_actions)();
2249
2250 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002251 // Read suppression file
sewardj95d86c02007-12-18 01:49:23 +00002252 // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
nethercote71980f02004-01-24 18:18:54 +00002253 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00002254 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
2255 VG_(debugLog)(1, "main", "Load suppressions\n");
nethercote71980f02004-01-24 18:18:54 +00002256 VG_(load_suppressions)();
sewardj1fbc1a52005-04-25 02:05:54 +00002257 }
nethercote71980f02004-01-24 18:18:54 +00002258
2259 //--------------------------------------------------------------
rjwalsh0140af52005-06-04 20:42:33 +00002260 // register client stack
2261 //--------------------------------------------------------------
njn945ed2e2005-06-24 03:28:30 +00002262 VG_(clstk_id) = VG_(register_stack)(VG_(clstk_base), VG_(clstk_end));
rjwalsh0140af52005-06-04 20:42:33 +00002263
2264 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002265 // Show the address space state so far
2266 //--------------------------------------------------------------
2267 VG_(debugLog)(1, "main", "\n");
2268 VG_(debugLog)(1, "main", "\n");
2269 VG_(am_show_nsegments)(1,"Memory layout at client startup");
2270 VG_(debugLog)(1, "main", "\n");
2271 VG_(debugLog)(1, "main", "\n");
2272
2273 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002274 // Run!
2275 //--------------------------------------------------------------
sewardj71bc3cb2005-05-19 00:25:45 +00002276 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002277 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00002278 VG_(elapsed_wallclock_time)(buf);
sewardj738856f2009-07-15 14:48:32 +00002279 VG_(printf_xml_no_f_c)( "<status>\n"
2280 " <state>RUNNING</state>\n"
2281 " <time>%t</time>\n"
2282 "</status>\n",
2283 buf );
2284 VG_(printf_xml_no_f_c)( "\n" );
sewardj71bc3cb2005-05-19 00:25:45 +00002285 }
2286
sewardj1fbc1a52005-04-25 02:05:54 +00002287 VG_(debugLog)(1, "main", "Running thread 1\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002288
sewardj1d887112005-05-30 21:44:08 +00002289 /* As a result of the following call, the last thread standing
sewardj1ae3f3a2005-09-28 10:47:38 +00002290 eventually winds up running shutdown_actions_NORETURN
2291 just below. Unfortunately, simply exporting said function
2292 causes m_main to be part of a module cycle, which is pretty
2293 nonsensical. So instead of doing that, the address of said
2294 function is stored in a global variable 'owned' by m_syswrap,
2295 and it uses that function pointer to get back here when it needs
2296 to. */
2297
2298 /* Set continuation address. */
2299 VG_(address_of_m_main_shutdown_actions_NORETURN)
2300 = & shutdown_actions_NORETURN;
2301
2302 /* Run the first thread, eventually ending up at the continuation
2303 address. */
njnaf839f52005-06-23 03:27:57 +00002304 VG_(main_thread_wrapper_NORETURN)(1);
nethercote71980f02004-01-24 18:18:54 +00002305
sewardj1d887112005-05-30 21:44:08 +00002306 /*NOTREACHED*/
2307 vg_assert(0);
sewardjb5f6f512005-03-10 23:59:00 +00002308}
2309
sewardj17c11042006-10-15 01:26:40 +00002310/* Do everything which needs doing when the last thread exits or when
2311 a thread exits requesting a complete process exit (exit on AIX).
2312
2313 We enter here holding The Lock. For the case VgSrc_ExitProcess we
2314 must never release it, because to do so would allow other threads
2315 to continue after the system is ostensibly shut down. So we must
2316 go to our grave, so to speak, holding the lock.
2317
2318 In fact, there is never any point in releasing the lock at this
2319 point - we have it, we're shutting down the entire system, and
2320 for the case VgSrc_ExitProcess doing so positively causes trouble.
2321 So don't.
2322
2323 The final_tidyup call makes a bit of a nonsense of the ExitProcess
2324 case, since it will run the libc_freeres function, thus allowing
2325 other lurking threads to run again. Hmm. */
sewardjb5f6f512005-03-10 23:59:00 +00002326
sewardj1ae3f3a2005-09-28 10:47:38 +00002327static
2328void shutdown_actions_NORETURN( ThreadId tid,
2329 VgSchedReturnCode tids_schedretcode )
sewardjb5f6f512005-03-10 23:59:00 +00002330{
sewardj1d887112005-05-30 21:44:08 +00002331 VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
sewardj17c11042006-10-15 01:26:40 +00002332 VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
sewardj1d887112005-05-30 21:44:08 +00002333
sewardjb5f6f512005-03-10 23:59:00 +00002334 vg_assert(VG_(is_running_thread)(tid));
2335
sewardj12ab7652006-10-17 02:10:42 +00002336 vg_assert(tids_schedretcode == VgSrc_ExitThread
2337 || tids_schedretcode == VgSrc_ExitProcess
2338 || tids_schedretcode == VgSrc_FatalSig );
sewardjb5f6f512005-03-10 23:59:00 +00002339
sewardj12ab7652006-10-17 02:10:42 +00002340 if (tids_schedretcode == VgSrc_ExitThread) {
sewardjb5f6f512005-03-10 23:59:00 +00002341
sewardj17c11042006-10-15 01:26:40 +00002342 // We are the last surviving thread. Right?
2343 vg_assert( VG_(count_living_threads)() == 1 );
sewardjb5f6f512005-03-10 23:59:00 +00002344
sewardj17c11042006-10-15 01:26:40 +00002345 // Wait for all other threads to exit.
2346 // jrs: Huh? but they surely are already gone
2347 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002348
sewardj17c11042006-10-15 01:26:40 +00002349 // Clean the client up before the final report
2350 // this causes the libc_freeres function to run
2351 final_tidyup(tid);
2352
2353 /* be paranoid */
2354 vg_assert(VG_(is_running_thread)(tid));
2355 vg_assert(VG_(count_living_threads)() == 1);
2356
2357 } else {
2358
2359 // We may not be the last surviving thread. However, we
2360 // want to shut down the entire process. We hold the lock
2361 // and we need to keep hold of it all the way out, in order
2362 // that none of the other threads ever run again.
2363 vg_assert( VG_(count_living_threads)() >= 1 );
2364
sewardj17c11042006-10-15 01:26:40 +00002365 // Clean the client up before the final report
2366 // this causes the libc_freeres function to run
2367 // perhaps this is unsafe, as per comment above
2368 final_tidyup(tid);
2369
2370 /* be paranoid */
2371 vg_assert(VG_(is_running_thread)(tid));
2372 vg_assert(VG_(count_living_threads)() >= 1);
2373 }
sewardjb5f6f512005-03-10 23:59:00 +00002374
2375 VG_(threads)[tid].status = VgTs_Empty;
nethercote71980f02004-01-24 18:18:54 +00002376 //--------------------------------------------------------------
sewardj738856f2009-07-15 14:48:32 +00002377 // Finalisation: cleanup, messages, etc. Order not so important, only
nethercote71980f02004-01-24 18:18:54 +00002378 // affects what order the messages come.
2379 //--------------------------------------------------------------
njnb6267bd2009-08-12 00:14:16 +00002380 // First thing in the post-amble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00002381 if (VG_(clo_xml))
2382 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00002383 else if (VG_(clo_verbosity) > 0)
2384 VG_(message)(Vg_UserMsg, "\n");
nethercote71980f02004-01-24 18:18:54 +00002385
sewardj71bc3cb2005-05-19 00:25:45 +00002386 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002387 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00002388 VG_(elapsed_wallclock_time)(buf);
sewardj738856f2009-07-15 14:48:32 +00002389 VG_(printf_xml_no_f_c)( "<status>\n"
2390 " <state>FINISHED</state>\n"
2391 " <time>%t</time>\n"
njnb6267bd2009-08-12 00:14:16 +00002392 "</status>\n"
2393 "\n",
sewardj738856f2009-07-15 14:48:32 +00002394 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00002395 }
2396
nethercote71980f02004-01-24 18:18:54 +00002397 /* Print out file descriptor summary and stats. */
2398 if (VG_(clo_track_fds))
nethercote3a42fb82004-08-03 18:08:50 +00002399 VG_(show_open_fds)();
nethercote71980f02004-01-24 18:18:54 +00002400
sewardj2d9e8742009-08-07 15:46:56 +00002401 /* Call the tool's finalisation function. This makes Memcheck's
2402 leak checker run, and possibly chuck a bunch of leak errors into
2403 the error management machinery. */
2404 VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
nethercote71980f02004-01-24 18:18:54 +00002405
sewardj2d9e8742009-08-07 15:46:56 +00002406 /* Show the error counts. */
sewardj7ca100d2009-08-15 23:05:34 +00002407 if (VG_(clo_xml)
2408 && (VG_(needs).core_errors || VG_(needs).tool_errors)) {
sewardj2d9e8742009-08-07 15:46:56 +00002409 VG_(show_error_counts_as_XML)();
sewardj738856f2009-07-15 14:48:32 +00002410 }
sewardj2d9e8742009-08-07 15:46:56 +00002411
2412 /* In XML mode, this merely prints the used suppressions. */
2413 if (VG_(needs).core_errors || VG_(needs).tool_errors)
2414 VG_(show_all_errors)();
nethercote71980f02004-01-24 18:18:54 +00002415
sewardj71bc3cb2005-05-19 00:25:45 +00002416 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00002417 VG_(printf_xml)("\n");
2418 VG_(printf_xml)("</valgrindoutput>\n");
2419 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00002420 }
2421
nethercote885dd912004-08-03 23:14:00 +00002422 VG_(sanity_check_general)( True /*include expensive checks*/ );
nethercote71980f02004-01-24 18:18:54 +00002423
sewardj2d9e8742009-08-07 15:46:56 +00002424 if (VG_(clo_stats))
nethercote3a42fb82004-08-03 18:08:50 +00002425 print_all_stats();
nethercote71980f02004-01-24 18:18:54 +00002426
sewardj9c606bd2008-09-18 18:12:50 +00002427 /* Show a profile of the heap(s) at shutdown. Optionally, first
2428 throw away all the debug info, as that makes it easy to spot
2429 leaks in the debuginfo reader. */
2430 if (VG_(clo_profile_heap)) {
2431 if (0) VG_(di_discard_ALL_debuginfo)();
2432 VG_(print_arena_cc_analysis)();
2433 }
2434
njn2025cf92005-06-26 20:44:48 +00002435 if (VG_(clo_profile_flags) > 0) {
sewardj5471ec62006-10-17 13:58:17 +00002436 #define N_MAX 200
njn2025cf92005-06-26 20:44:48 +00002437 BBProfEntry tops[N_MAX];
2438 ULong score_total = VG_(get_BB_profile) (tops, N_MAX);
2439 show_BB_profile(tops, N_MAX, score_total);
2440 }
sewardjfa8ec112005-01-19 11:55:34 +00002441
sewardj8b635a42004-11-22 19:01:47 +00002442 /* Print Vex storage stats */
sewardjbf426512005-01-17 18:35:30 +00002443 if (0)
2444 LibVEX_ShowAllocStats();
sewardj1d887112005-05-30 21:44:08 +00002445
sewardj738856f2009-07-15 14:48:32 +00002446 /* Flush any output cached by previous calls to VG_(message). */
2447 VG_(message_flush)();
2448
njn8aa35852005-06-10 22:59:56 +00002449 /* Ok, finally exit in the os-specific way, according to the scheduler's
2450 return code. In short, if the (last) thread exited by calling
2451 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2452 signal, terminate the entire system with that same fatal signal. */
2453 VG_(debugLog)(1, "core_os",
njn7b85dd52005-06-12 17:26:29 +00002454 "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
njn8aa35852005-06-10 22:59:56 +00002455
njn8aa35852005-06-10 22:59:56 +00002456 switch (tids_schedretcode) {
sewardj12ab7652006-10-17 02:10:42 +00002457 case VgSrc_ExitThread: /* the normal way out (Linux) */
2458 case VgSrc_ExitProcess: /* the normal way out (AIX) */
sewardjb9779082006-05-12 23:50:15 +00002459 /* Change the application return code to user's return code,
2460 if an error was found */
2461 if (VG_(clo_error_exitcode) > 0
2462 && VG_(get_n_errs_found)() > 0) {
2463 VG_(exit)( VG_(clo_error_exitcode) );
2464 } else {
2465 /* otherwise, return the client's exit code, in the normal
2466 way. */
2467 VG_(exit)( VG_(threads)[tid].os_state.exitcode );
2468 }
njn8aa35852005-06-10 22:59:56 +00002469 /* NOT ALIVE HERE! */
sewardj17c11042006-10-15 01:26:40 +00002470 VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
njn8aa35852005-06-10 22:59:56 +00002471 break; /* what the hell :) */
2472
2473 case VgSrc_FatalSig:
2474 /* We were killed by a fatal signal, so replicate the effect */
2475 vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
2476 VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
njnf76d27a2009-05-28 01:53:07 +00002477 /* we shouldn't be alive at this point. But VG_(kill_self)
2478 sometimes fails with EPERM on Darwin, for unclear reasons. */
2479# if defined(VGO_darwin)
2480 VG_(debugLog)(0, "main", "VG_(kill_self) failed. Exiting normally.\n");
2481 VG_(exit)(0); /* bogus, but we really need to exit now */
2482 /* fall through .. */
2483# endif
njn8aa35852005-06-10 22:59:56 +00002484 VG_(core_panic)("main(): signal was supposed to be fatal");
2485 break;
2486
2487 default:
2488 VG_(core_panic)("main(): unexpected scheduler return code");
2489 }
njne96be672005-05-08 19:08:54 +00002490}
sewardj8b635a42004-11-22 19:01:47 +00002491
sewardj1ae3f3a2005-09-28 10:47:38 +00002492/* -------------------- */
2493
2494/* Final clean-up before terminating the process.
2495 Clean up the client by calling __libc_freeres() (if requested)
2496 This is Linux-specific?
njnf76d27a2009-05-28 01:53:07 +00002497 GrP fixme glibc-specific, anyway
sewardj1ae3f3a2005-09-28 10:47:38 +00002498*/
2499static void final_tidyup(ThreadId tid)
2500{
njnf76d27a2009-05-28 01:53:07 +00002501#if !defined(VGO_darwin)
sewardjcf951812006-01-17 02:22:21 +00002502# if defined(VGP_ppc64_linux)
2503 Addr r2;
2504# endif
sewardj0ec07f32006-01-12 12:32:32 +00002505 Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
sewardj1ae3f3a2005-09-28 10:47:38 +00002506
2507 vg_assert(VG_(is_running_thread)(tid));
2508
2509 if ( !VG_(needs).libc_freeres ||
2510 !VG_(clo_run_libc_freeres) ||
sewardj0ec07f32006-01-12 12:32:32 +00002511 0 == __libc_freeres_wrapper )
sewardj1ae3f3a2005-09-28 10:47:38 +00002512 return; /* can't/won't do it */
sewardj17c11042006-10-15 01:26:40 +00002513# if defined(VGO_aix5)
2514 return; /* inapplicable on non-Linux platforms */
2515# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002516
sewardjcf951812006-01-17 02:22:21 +00002517# if defined(VGP_ppc64_linux)
2518 r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
2519 if (r2 == 0) {
2520 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002521 "Caught __NR_exit, but can't run __libc_freeres()\n");
sewardjcf951812006-01-17 02:22:21 +00002522 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002523 " since cannot establish TOC pointer for it.\n");
sewardjcf951812006-01-17 02:22:21 +00002524 return;
2525 }
2526# endif
2527
sewardj1ae3f3a2005-09-28 10:47:38 +00002528 if (VG_(clo_verbosity) > 2 ||
2529 VG_(clo_trace_syscalls) ||
2530 VG_(clo_trace_sched))
2531 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00002532 "Caught __NR_exit; running __libc_freeres()\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002533
sewardj0ec07f32006-01-12 12:32:32 +00002534 /* set thread context to point to libc_freeres_wrapper */
sewardj1a85f4f2006-01-12 21:15:35 +00002535 /* ppc64-linux note: __libc_freeres_wrapper gives us the real
2536 function entry point, not a fn descriptor, so can use it
2537 directly. However, we need to set R2 (the toc pointer)
2538 appropriately. */
sewardj1ae3f3a2005-09-28 10:47:38 +00002539 VG_(set_IP)(tid, __libc_freeres_wrapper);
sewardjcf951812006-01-17 02:22:21 +00002540# if defined(VGP_ppc64_linux)
2541 VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
2542# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002543
2544 /* Block all blockable signals by copying the real block state into
2545 the thread's block state*/
2546 VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
2547 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
2548
2549 /* and restore handlers to default */
2550 VG_(set_default_handler)(VKI_SIGSEGV);
2551 VG_(set_default_handler)(VKI_SIGBUS);
2552 VG_(set_default_handler)(VKI_SIGILL);
2553 VG_(set_default_handler)(VKI_SIGFPE);
2554
2555 // We were exiting, so assert that...
2556 vg_assert(VG_(is_exiting)(tid));
2557 // ...but now we're not again
2558 VG_(threads)[tid].exitreason = VgSrc_None;
2559
2560 // run until client thread exits - ideally with LIBC_FREERES_DONE,
2561 // but exit/exitgroup/signal will do
2562 VG_(scheduler)(tid);
2563
2564 vg_assert(VG_(is_exiting)(tid));
njnf76d27a2009-05-28 01:53:07 +00002565#endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002566}
2567
sewardj45f4e7c2005-09-27 19:20:21 +00002568
2569/*====================================================================*/
njn49f80e82009-05-21 01:25:43 +00002570/*=== Getting to main() alive: LINUX ===*/
sewardj45f4e7c2005-09-27 19:20:21 +00002571/*====================================================================*/
2572
sewardj17c11042006-10-15 01:26:40 +00002573#if defined(VGO_linux)
2574
sewardj45f4e7c2005-09-27 19:20:21 +00002575/* If linking of the final executables is done with glibc present,
2576 then Valgrind starts at main() above as usual, and all of the
2577 following code is irrelevant.
2578
2579 However, this is not the intended mode of use. The plan is to
2580 avoid linking against glibc, by giving gcc the flags
2581 -nodefaultlibs -lgcc -nostartfiles at startup.
2582
2583 From this derive two requirements:
2584
2585 1. gcc may emit calls to memcpy and memset to deal with structure
2586 assignments etc. Since we have chosen to ignore all the
2587 "normal" supporting libraries, we have to provide our own
2588 implementations of them. No problem.
2589
2590 2. We have to provide a symbol "_start", to which the kernel
2591 hands control at startup. Hence the code below.
2592*/
2593
2594/* ---------------- Requirement 1 ---------------- */
2595
sewardj17c11042006-10-15 01:26:40 +00002596void* memcpy(void *dest, const void *src, SizeT n);
2597void* memcpy(void *dest, const void *src, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002598 return VG_(memcpy)(dest,src,n);
2599}
sewardj17c11042006-10-15 01:26:40 +00002600void* memset(void *s, int c, SizeT n);
2601void* memset(void *s, int c, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002602 return VG_(memset)(s,c,n);
2603}
2604
bart82616e12010-06-13 13:46:24 +00002605/* BVA: abort() for those platforms that need it (PPC and ARM). */
2606void abort(void);
2607void abort(void){
2608 VG_(printf)("Something called raise().\n");
2609 vg_assert(0);
2610}
2611
sewardj59570ff2010-01-01 11:59:33 +00002612/* EAZG: ARM's EABI will call floating point exception handlers in
2613 libgcc which boil down to an abort or raise, that's usually defined
2614 in libc. Instead, define them here. */
2615#if defined(VGP_arm_linux)
2616void raise(void);
2617void raise(void){
2618 VG_(printf)("Something called raise().\n");
2619 vg_assert(0);
2620}
2621
sewardj59570ff2010-01-01 11:59:33 +00002622void __aeabi_unwind_cpp_pr0(void);
2623void __aeabi_unwind_cpp_pr0(void){
2624 VG_(printf)("Something called __aeabi_unwind_cpp_pr0()\n");
2625 vg_assert(0);
2626}
sewardj38efe4b2010-08-22 12:23:01 +00002627
2628void __aeabi_unwind_cpp_pr1(void);
2629void __aeabi_unwind_cpp_pr1(void){
2630 VG_(printf)("Something called __aeabi_unwind_cpp_pr1()\n");
2631 vg_assert(0);
2632}
sewardj59570ff2010-01-01 11:59:33 +00002633#endif
2634
sewardj45f4e7c2005-09-27 19:20:21 +00002635/* ---------------- Requirement 2 ---------------- */
2636
2637/* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2638 comment, which explains how the stack looks right at process start
2639 (when _start is jumped to). Hence _start passes %esp to
sewardj17c11042006-10-15 01:26:40 +00002640 _start_in_C_linux, which extracts argc/argv/envp and starts up
sewardj45f4e7c2005-09-27 19:20:21 +00002641 correctly. */
2642
2643/* This is the canonical entry point, usually the first thing in the text
2644 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2645 point runs, most registers' values are unspecified, except for:
2646
2647 %edx Contains a function pointer to be registered with `atexit'.
2648 This is how the dynamic linker arranges to have DT_FINI
2649 functions called for shared libraries that have been loaded
2650 before this code runs.
2651
2652 %esp The stack contains the arguments and environment:
2653 0(%esp) argc
2654 4(%esp) argv[0]
2655 ...
2656 (4*argc)(%esp) NULL
2657 (4*(argc+1))(%esp) envp[0]
2658 ...
2659 NULL
2660*/
2661
2662/* The kernel hands control to _start, which extracts the initial
sewardj17c11042006-10-15 01:26:40 +00002663 stack pointer and calls onwards to _start_in_C_linux. This also switches
sewardja48a4932005-09-29 11:09:56 +00002664 the new stack. */
sewardj45f4e7c2005-09-27 19:20:21 +00002665#if defined(VGP_x86_linux)
2666asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002667 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002668 "\t.globl _start\n"
2669 "\t.type _start,@function\n"
2670 "_start:\n"
2671 /* set up the new stack in %eax */
sewardjfdf91b42005-09-28 00:53:09 +00002672 "\tmovl $vgPlain_interim_stack, %eax\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002673 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2674 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2675 "\tsubl $16, %eax\n"
2676 "\tandl $~15, %eax\n"
2677 /* install it, and collect the original one */
2678 "\txchgl %eax, %esp\n"
sewardj17c11042006-10-15 01:26:40 +00002679 /* call _start_in_C_linux, passing it the startup %esp */
sewardj45f4e7c2005-09-27 19:20:21 +00002680 "\tpushl %eax\n"
sewardj17c11042006-10-15 01:26:40 +00002681 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002682 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002683 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002684);
2685#elif defined(VGP_amd64_linux)
2686asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002687 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002688 "\t.globl _start\n"
2689 "\t.type _start,@function\n"
2690 "_start:\n"
2691 /* set up the new stack in %rdi */
sewardjfdf91b42005-09-28 00:53:09 +00002692 "\tmovq $vgPlain_interim_stack, %rdi\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002693 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2694 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2695 "\tandq $~15, %rdi\n"
2696 /* install it, and collect the original one */
2697 "\txchgq %rdi, %rsp\n"
sewardj17c11042006-10-15 01:26:40 +00002698 /* call _start_in_C_linux, passing it the startup %rsp */
2699 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002700 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002701 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002702);
sewardja48a4932005-09-29 11:09:56 +00002703#elif defined(VGP_ppc32_linux)
2704asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002705 ".text\n"
sewardja48a4932005-09-29 11:09:56 +00002706 "\t.globl _start\n"
2707 "\t.type _start,@function\n"
2708 "_start:\n"
2709 /* set up the new stack in r16 */
2710 "\tlis 16,vgPlain_interim_stack@ha\n"
2711 "\tla 16,vgPlain_interim_stack@l(16)\n"
2712 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2713 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2714 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2715 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2716 "\tadd 16,17,16\n"
2717 "\tadd 16,18,16\n"
2718 "\trlwinm 16,16,0,0,27\n"
2719 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2720 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2721 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002722 call _start_in_C_linux, passing it the initial SP. */
sewardja48a4932005-09-29 11:09:56 +00002723 "\tmr 3,1\n"
2724 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002725 "\tbl _start_in_C_linux\n"
sewardja48a4932005-09-29 11:09:56 +00002726 "\ttrap\n"
sewardj2fedc642005-11-19 02:02:57 +00002727 ".previous\n"
sewardja48a4932005-09-29 11:09:56 +00002728);
sewardj2c48c7b2005-11-29 13:05:56 +00002729#elif defined(VGP_ppc64_linux)
2730asm("\n"
cerion21082042005-12-06 19:07:08 +00002731 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2732 So we must have one, and that is what goes into the .opd section. */
cerion297c88f2005-12-22 15:53:12 +00002733 "\t.align 2\n"
cerion21082042005-12-06 19:07:08 +00002734 "\t.global _start\n"
2735 "\t.section \".opd\",\"aw\"\n"
2736 "\t.align 3\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002737 "_start:\n"
cerion21082042005-12-06 19:07:08 +00002738 "\t.quad ._start,.TOC.@tocbase,0\n"
2739 "\t.previous\n"
2740 "\t.type ._start,@function\n"
2741 "\t.global ._start\n"
2742 "._start:\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002743 /* set up the new stack in r16 */
2744 "\tlis 16, vgPlain_interim_stack@highest\n"
2745 "\tori 16,16,vgPlain_interim_stack@higher\n"
2746 "\tsldi 16,16,32\n"
2747 "\toris 16,16,vgPlain_interim_stack@h\n"
2748 "\tori 16,16,vgPlain_interim_stack@l\n"
2749 "\txor 17,17,17\n"
2750 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2751 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2752 "\txor 18,18,18\n"
2753 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2754 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2755 "\tadd 16,17,16\n"
2756 "\tadd 16,18,16\n"
2757 "\trldicr 16,16,0,59\n"
2758 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2759 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2760 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002761 call _start_in_C_linux, passing it the initial SP. */
sewardj2c48c7b2005-11-29 13:05:56 +00002762 "\tmr 3,1\n"
2763 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002764 "\tbl ._start_in_C_linux\n"
cerion21082042005-12-06 19:07:08 +00002765 "\tnop\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002766 "\ttrap\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002767);
sewardj59570ff2010-01-01 11:59:33 +00002768#elif defined(VGP_arm_linux)
2769asm("\n"
2770 "\t.align 2\n"
2771 "\t.global _start\n"
2772 "_start:\n"
2773 "\tldr r0, [pc, #36]\n"
2774 "\tldr r1, [pc, #36]\n"
2775 "\tadd r0, r1, r0\n"
2776 "\tldr r1, [pc, #32]\n"
2777 "\tadd r0, r1, r0\n"
2778 "\tmvn r1, #15\n"
2779 "\tand r0, r0, r1\n"
2780 "\tmov r1, sp\n"
2781 "\tmov sp, r0\n"
2782 "\tmov r0, r1\n"
2783 "\tb _start_in_C_linux\n"
2784 "\t.word vgPlain_interim_stack\n"
2785 "\t.word "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
2786 "\t.word "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
2787);
sewardj45f4e7c2005-09-27 19:20:21 +00002788#else
njn49f80e82009-05-21 01:25:43 +00002789# error "Unknown linux platform"
sewardj45f4e7c2005-09-27 19:20:21 +00002790#endif
2791
sewardje66f2e02006-12-30 17:45:08 +00002792/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
2793#define _GNU_SOURCE
2794#define _FILE_OFFSET_BITS 64
2795/* This is in order to get AT_NULL and AT_PAGESIZE. */
2796#include <elf.h>
2797/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
2798
sewardj45f4e7c2005-09-27 19:20:21 +00002799/* Avoid compiler warnings: this fn _is_ used, but labelling it
2800 'static' causes gcc to complain it isn't. */
sewardj17c11042006-10-15 01:26:40 +00002801void _start_in_C_linux ( UWord* pArgc );
2802void _start_in_C_linux ( UWord* pArgc )
sewardj45f4e7c2005-09-27 19:20:21 +00002803{
2804 Int r;
2805 Word argc = pArgc[0];
2806 HChar** argv = (HChar**)&pArgc[1];
2807 HChar** envp = (HChar**)&pArgc[1+argc+1];
sewardjf9d2f9b2006-11-17 20:00:57 +00002808
2809 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2810 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2811
2812 the_iicii.sp_at_startup = (Addr)pArgc;
2813
sewardje66f2e02006-12-30 17:45:08 +00002814# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
2815 {
2816 /* ppc/ppc64 can be configured with different page sizes.
2817 Determine this early. This is an ugly hack and really should
2818 be moved into valgrind_main. */
2819 UWord *sp = &pArgc[1+argc+1];
2820 while (*sp++ != 0)
2821 ;
2822 for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
2823 if (*sp == AT_PAGESZ) {
2824 VKI_PAGE_SIZE = sp[1];
2825 for (VKI_PAGE_SHIFT = 12;
2826 VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
2827 if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
2828 break;
2829 }
2830 }
2831# endif
2832
sewardjf9d2f9b2006-11-17 20:00:57 +00002833 r = valgrind_main( (Int)argc, argv, envp );
sewardj17c11042006-10-15 01:26:40 +00002834 /* NOTREACHED */
sewardj45f4e7c2005-09-27 19:20:21 +00002835 VG_(exit)(r);
2836}
2837
sewardj17c11042006-10-15 01:26:40 +00002838
2839/*====================================================================*/
2840/*=== Getting to main() alive: AIX5 ===*/
2841/*====================================================================*/
2842
njn49f80e82009-05-21 01:25:43 +00002843#elif defined(VGO_aix5)
sewardj17c11042006-10-15 01:26:40 +00002844
2845/* This is somewhat simpler than the Linux case. _start_valgrind
2846 receives control from the magic piece of code created in this
2847 process' address space by the launcher, via use of ptrace(). At
2848 the point of entry:
2849
2850 - the initial client process image is in memory and ready to roll,
2851 except that we've partially trashed its integer register state
2852 in order to get this far. So ..
2853
2854 - intregs37 holds the client's initial integer register state, so
2855 we can restore it before starting the client on the VCPU.
2856
2857 - we're on the client's stack. This is not good; therefore the
2858 first order of business is to switch to our temporary stack.
2859
2860 - the client's initial argc/v/envp is in r3/r4/r5 (32 bit mode) or
2861 r14/r15/r16 (64 bit mode). They are pulled out of the stashed
2862 integer register state and passed to our main().
2863
2864 The launcher will have played some games with argv. If the launcher
2865 ($prefix/bin/valgrind) was started like this
2866
2867 valgrind [args-for-V] app [args-for-app]
2868
2869 then the launcher will have started the client as
2870
2871 app [args-for-V] app [args-for-app]
2872
2873 m_initimg will have to mess with the client's initial r4/r5
2874 (32-bit) or r15/r16 (64-bit) so that it believes it was execd as
2875 "app [args-for-app]". Well, that's no big deal.
2876*/
2877
2878#include "launcher-aix5-bootblock.h"
2879
2880void _start_in_C_aix5 ( AIX5Bootblock* bootblock );
2881void _start_in_C_aix5 ( AIX5Bootblock* bootblock )
2882{
2883 Int r;
2884 ULong* intregs37;
2885 UWord argc, argv, envp;
2886 __NR_getpid = bootblock->__NR_getpid;
2887 __NR_write = bootblock->__NR_write;
2888 __NR_exit = bootblock->__NR_exit;
2889 __NR_open = bootblock->__NR_open;
2890 __NR_read = bootblock->__NR_read;
2891 __NR_close = bootblock->__NR_close;
sewardjf9d2f9b2006-11-17 20:00:57 +00002892
2893 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2894 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2895
sewardj17c11042006-10-15 01:26:40 +00002896 intregs37 = &bootblock->iregs_pc_cr_lr_ctr_xer[0];
sewardjf9d2f9b2006-11-17 20:00:57 +00002897 the_iicii.intregs37 = intregs37;
2898 the_iicii.bootblock = (void*)bootblock;
2899 the_iicii.adler32_exp = bootblock->adler32;
2900
2901 /* Not important on AIX. */
2902 the_iicii.sp_at_startup = (Addr)0x31415927ULL;
2903
sewardj17c11042006-10-15 01:26:40 +00002904# if defined(VGP_ppc32_aix5)
2905 argc = (UWord)intregs37[3]; /* client's r3 == argc */
2906 argv = (UWord)intregs37[4];
2907 envp = (UWord)intregs37[5];
2908# else /* defined(VGP_ppc64_aix5) */
2909 argc = (UWord)intregs37[14]; /* client's r14 == argc */
2910 argv = (UWord)intregs37[15];
2911 envp = (UWord)intregs37[16];
2912# endif
sewardjf9d2f9b2006-11-17 20:00:57 +00002913
2914 r = valgrind_main( (Int)argc, (HChar**)argv, (HChar**)envp );
2915
sewardj17c11042006-10-15 01:26:40 +00002916 /* NOTREACHED */
2917 VG_(exit)(r);
2918}
2919
2920/* THE ENTRY POINT */
2921void _start_valgrind ( AIX5Bootblock* bootblock );
2922void _start_valgrind ( AIX5Bootblock* bootblock )
2923{
2924 /* Switch immediately to our temporary stack, and continue. This
2925 is pretty dodgy in that it assumes that gcc does not place on
2926 the stack, anything needed to form the _start_in_C_aix5 call,
2927 since it will be on the old stack. */
2928 register UWord new_r1;
2929 new_r1 = (UWord)&VG_(interim_stack);
2930 new_r1 += VG_STACK_GUARD_SZB; /* step over lower guard page */
2931 new_r1 += VG_STACK_ACTIVE_SZB; /* step to top of active area */
2932 new_r1 -= 512; /* paranoia */
2933 __asm__ __volatile__("mr 1,%0" :/*wr*/
2934 :/*rd*/ "b"(new_r1)
2935 :/*trash*/"r1","memory");
2936 _start_in_C_aix5(bootblock);
2937 /*NOTREACHED*/
2938 VG_(exit)(0);
2939}
2940
sewardj61a1b052008-10-22 00:56:53 +00002941/* At some point in Oct 2008, static linking appeared to stop working
2942 on AIX 5.3. This breaks the build since we link statically. The
2943 linking fails citing absence of the following five symbols as the
2944 reason. In the absence of a better solution, here are stand-ins
2945 for them. Kludge appears to work; presumably said functions,
2946 assuming they are indeed functions, are never called. */
2947void encrypted_pw_passlen ( void ) { vg_assert(0); }
2948void crypt_r ( void ) { vg_assert(0); }
2949void max_history_size ( void ) { vg_assert(0); }
2950void getpass_auto ( void ) { vg_assert(0); }
2951void max_pw_passlen ( void ) { vg_assert(0); }
2952
njn49f80e82009-05-21 01:25:43 +00002953
njnf76d27a2009-05-28 01:53:07 +00002954/*====================================================================*/
2955/*=== Getting to main() alive: darwin ===*/
2956/*====================================================================*/
2957
2958#elif defined(VGO_darwin)
2959
njnea2d6fd2010-07-01 00:20:20 +00002960/*
2961 Memory layout established by kernel:
2962
2963 0(%esp) argc
2964 4(%esp) argv[0]
2965 ...
2966 argv[argc-1]
2967 NULL
2968 envp[0]
2969 ...
2970 envp[n]
2971 NULL
2972 executable name (presumably, a pointer to it)
2973 NULL
2974
2975 Ditto in the 64-bit case, except all offsets from SP are obviously
2976 twice as large.
2977*/
2978
2979/* The kernel hands control to _start, which extracts the initial
2980 stack pointer and calls onwards to _start_in_C_darwin. This also
2981 switches to the new stack. */
2982#if defined(VGP_x86_darwin)
2983asm("\n"
2984 ".text\n"
2985 ".align 2,0x90\n"
2986 "\t.globl __start\n"
2987 "__start:\n"
2988 /* set up the new stack in %eax */
2989 "\tmovl $_vgPlain_interim_stack, %eax\n"
2990 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2991 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2992 "\tsubl $16, %eax\n"
2993 "\tandl $~15, %eax\n"
2994 /* install it, and collect the original one */
2995 "\txchgl %eax, %esp\n"
2996 /* call _start_in_C_darwin, passing it the startup %esp */
2997 "\tpushl %eax\n"
2998 "\tcall __start_in_C_darwin\n"
2999 "\tint $3\n"
3000 "\tint $3\n"
3001);
3002#elif defined(VGP_amd64_darwin)
3003asm("\n"
3004 ".text\n"
3005 "\t.globl __start\n"
3006 ".align 3,0x90\n"
3007 "__start:\n"
3008 /* set up the new stack in %rdi */
3009 "\tmovabsq $_vgPlain_interim_stack, %rdi\n"
3010 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
3011 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
3012 "\tandq $~15, %rdi\n"
3013 /* install it, and collect the original one */
3014 "\txchgq %rdi, %rsp\n"
3015 /* call _start_in_C_darwin, passing it the startup %rsp */
3016 "\tcall __start_in_C_darwin\n"
3017 "\tint $3\n"
3018 "\tint $3\n"
3019);
3020#endif
3021
njnf76d27a2009-05-28 01:53:07 +00003022void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2);
3023void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2) {
3024 // skip check
3025 return VG_(memcpy)(dest,src,n);
3026}
3027void* __memset_chk(void *s, int c, SizeT n, SizeT n2);
3028void* __memset_chk(void *s, int c, SizeT n, SizeT n2) {
3029 // skip check
3030 return VG_(memset)(s,c,n);
3031}
3032void bzero(void *s, SizeT n);
3033void bzero(void *s, SizeT n) {
3034 VG_(memset)(s,0,n);
3035}
3036
3037void* memcpy(void *dest, const void *src, SizeT n);
3038void* memcpy(void *dest, const void *src, SizeT n) {
3039 return VG_(memcpy)(dest,src,n);
3040}
3041void* memset(void *s, int c, SizeT n);
3042void* memset(void *s, int c, SizeT n) {
3043 return VG_(memset)(s,c,n);
3044}
3045
njnf76d27a2009-05-28 01:53:07 +00003046/* Avoid compiler warnings: this fn _is_ used, but labelling it
3047 'static' causes gcc to complain it isn't. */
3048void _start_in_C_darwin ( UWord* pArgc );
3049void _start_in_C_darwin ( UWord* pArgc )
3050{
3051 Int r;
njnea2d6fd2010-07-01 00:20:20 +00003052 Int argc = *(Int *)pArgc; // not pArgc[0] on LP64
njnf76d27a2009-05-28 01:53:07 +00003053 HChar** argv = (HChar**)&pArgc[1];
3054 HChar** envp = (HChar**)&pArgc[1+argc+1];
3055
3056 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
3057 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
3058
3059 the_iicii.sp_at_startup = (Addr)pArgc;
3060
3061 r = valgrind_main( (Int)argc, argv, envp );
3062 /* NOTREACHED */
3063 VG_(exit)(r);
3064}
3065
3066
njn49f80e82009-05-21 01:25:43 +00003067#else
3068
3069# error "Unknown OS"
3070#endif
sewardj17c11042006-10-15 01:26:40 +00003071
3072
sewardj0af71bb2010-07-01 14:50:30 +00003073/*====================================================================*/
3074/*=== {u,}{div,mod}di3 replacements ===*/
3075/*====================================================================*/
njnea2d6fd2010-07-01 00:20:20 +00003076
3077/* For static linking on x86-darwin, we need to supply our own 64-bit
3078 integer division code, else the link dies thusly:
3079
3080 ld_classic: Undefined symbols:
3081 ___udivdi3
3082 ___umoddi3
3083*/
3084#if defined(VGP_x86_darwin)
3085
3086/* Routines for doing signed/unsigned 64 x 64 ==> 64 div and mod
3087 (udivdi3, umoddi3, divdi3, moddi3) using only 32 x 32 ==> 32
3088 division. Cobbled together from
3089
3090 http://www.hackersdelight.org/HDcode/divlu.c
3091 http://www.hackersdelight.org/HDcode/divls.c
3092 http://www.hackersdelight.org/HDcode/newCode/divDouble.c
3093
3094 The code from those three files is covered by the following license,
3095 as it appears at:
3096
3097 http://www.hackersdelight.org/permissions.htm
3098
3099 You are free to use, copy, and distribute any of the code on
3100 this web site, whether modified by you or not. You need not give
3101 attribution. This includes the algorithms (some of which appear
3102 in Hacker's Delight), the Hacker's Assistant, and any code
3103 submitted by readers. Submitters implicitly agree to this.
3104*/
3105
3106/* Long division, unsigned (64/32 ==> 32).
3107 This procedure performs unsigned "long division" i.e., division of a
310864-bit unsigned dividend by a 32-bit unsigned divisor, producing a
310932-bit quotient. In the overflow cases (divide by 0, or quotient
3110exceeds 32 bits), it returns a remainder of 0xFFFFFFFF (an impossible
3111value).
3112 The dividend is u1 and u0, with u1 being the most significant word.
3113The divisor is parameter v. The value returned is the quotient.
3114 Max line length is 57, to fit in hacker.book. */
3115
3116static Int nlz32(UInt x)
3117{
3118 Int n;
3119 if (x == 0) return(32);
3120 n = 0;
3121 if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
3122 if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
3123 if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
3124 if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
3125 if (x <= 0x7FFFFFFF) {n = n + 1;}
3126 return n;
3127}
3128
3129/* 64 x 32 ==> 32 unsigned division, using only 32 x 32 ==> 32
3130 division as a primitive. */
3131static UInt divlu2(UInt u1, UInt u0, UInt v, UInt *r)
3132{
3133 const UInt b = 65536; // Number base (16 bits).
3134 UInt un1, un0, // Norm. dividend LSD's.
3135 vn1, vn0, // Norm. divisor digits.
3136 q1, q0, // Quotient digits.
3137 un32, un21, un10, // Dividend digit pairs.
3138 rhat; // A remainder.
3139 Int s; // Shift amount for norm.
3140
3141 if (u1 >= v) { // If overflow, set rem.
3142 if (r != NULL) // to an impossible value,
3143 *r = 0xFFFFFFFF; // and return the largest
3144 return 0xFFFFFFFF;} // possible quotient.
3145
3146 s = nlz32(v); // 0 <= s <= 31.
3147 v = v << s; // Normalize divisor.
3148 vn1 = v >> 16; // Break divisor up into
3149 vn0 = v & 0xFFFF; // two 16-bit digits.
3150
3151 un32 = (u1 << s) | ((u0 >> (32 - s)) & (-s >> 31));
3152 un10 = u0 << s; // Shift dividend left.
3153
3154 un1 = un10 >> 16; // Break right half of
3155 un0 = un10 & 0xFFFF; // dividend into two digits.
3156
3157 q1 = un32/vn1; // Compute the first
3158 rhat = un32 - q1*vn1; // quotient digit, q1.
3159 again1:
3160 if (q1 >= b || q1*vn0 > b*rhat + un1) {
3161 q1 = q1 - 1;
3162 rhat = rhat + vn1;
3163 if (rhat < b) goto again1;}
3164
3165 un21 = un32*b + un1 - q1*v; // Multiply and subtract.
3166
3167 q0 = un21/vn1; // Compute the second
3168 rhat = un21 - q0*vn1; // quotient digit, q0.
3169 again2:
3170 if (q0 >= b || q0*vn0 > b*rhat + un0) {
3171 q0 = q0 - 1;
3172 rhat = rhat + vn1;
3173 if (rhat < b) goto again2;}
3174
3175 if (r != NULL) // If remainder is wanted,
3176 *r = (un21*b + un0 - q0*v) >> s; // return it.
3177 return q1*b + q0;
3178}
3179
3180
3181/* 64 x 32 ==> 32 signed division, using only 32 x 32 ==> 32 division
3182 as a primitive. */
3183static Int divls(Int u1, UInt u0, Int v, Int *r)
3184{
3185 Int q, uneg, vneg, diff, borrow;
3186
3187 uneg = u1 >> 31; // -1 if u < 0.
3188 if (uneg) { // Compute the absolute
3189 u0 = -u0; // value of the dividend u.
3190 borrow = (u0 != 0);
3191 u1 = -u1 - borrow;}
3192
3193 vneg = v >> 31; // -1 if v < 0.
3194 v = (v ^ vneg) - vneg; // Absolute value of v.
3195
3196 if ((UInt)u1 >= (UInt)v) goto overflow;
3197
3198 q = divlu2(u1, u0, v, (UInt *)r);
3199
3200 diff = uneg ^ vneg; // Negate q if signs of
3201 q = (q ^ diff) - diff; // u and v differed.
3202 if (uneg && r != NULL)
3203 *r = -*r;
3204
3205 if ((diff ^ q) < 0 && q != 0) { // If overflow,
3206 overflow: // set remainder
3207 if (r != NULL) // to an impossible value,
3208 *r = 0x80000000; // and return the largest
3209 q = 0x80000000;} // possible neg. quotient.
3210 return q;
3211}
3212
3213
3214
3215/* This file contains a program for doing 64/64 ==> 64 division, on a
3216machine that does not have that instruction but that does have
3217instructions for "long division" (64/32 ==> 32). Code for unsigned
3218division is given first, followed by a simple program for doing the
3219signed version by using the unsigned version.
3220 These programs are useful in implementing "long long" (64-bit)
3221arithmetic on a machine that has the long division instruction. It will
3222work on 64- and 32-bit machines, provided the compiler implements long
3223long's (64-bit integers). It is desirable that the machine have the
3224Count Leading Zeros instruction.
3225 In the GNU world, these programs are known as __divdi3 and __udivdi3,
3226and similar names are used here.
3227 This material is not in HD, but may be in a future edition.
3228Max line length is 57, to fit in hacker.book. */
3229
3230
3231static Int nlz64(ULong x)
3232{
3233 Int n;
3234 if (x == 0) return(64);
3235 n = 0;
3236 if (x <= 0x00000000FFFFFFFFULL) {n = n + 32; x = x << 32;}
3237 if (x <= 0x0000FFFFFFFFFFFFULL) {n = n + 16; x = x << 16;}
3238 if (x <= 0x00FFFFFFFFFFFFFFULL) {n = n + 8; x = x << 8;}
3239 if (x <= 0x0FFFFFFFFFFFFFFFULL) {n = n + 4; x = x << 4;}
3240 if (x <= 0x3FFFFFFFFFFFFFFFULL) {n = n + 2; x = x << 2;}
3241 if (x <= 0x7FFFFFFFFFFFFFFFULL) {n = n + 1;}
3242 return n;
3243}
3244
3245// ---------------------------- udivdi3 --------------------------------
3246
3247 /* The variables u0, u1, etc. take on only 32-bit values, but they
3248 are declared long long to avoid some compiler warning messages and to
3249 avoid some unnecessary EXTRs that the compiler would put in, to
3250 convert long longs to ints.
3251
3252 First the procedure takes care of the case in which the divisor is a
3253 32-bit quantity. There are two subcases: (1) If the left half of the
3254 dividend is less than the divisor, one execution of DIVU is all that
3255 is required (overflow is not possible). (2) Otherwise it does two
3256 divisions, using the grade school method, with variables used as
3257 suggested below.
3258
3259 q1 q0
3260 ________
3261 v) u1 u0
3262 q1*v
3263 ____
3264 k u0 */
3265
3266/* These macros must be used with arguments of the appropriate type
3267(unsigned long long for DIVU and long long for DIVS. They are
3268simulations of the presumed machines ops. I.e., they look at only the
3269low-order 32 bits of the divisor, they return garbage if the division
3270overflows, and they return garbage in the high-order half of the
3271quotient doubleword.
3272 In practice, these would be replaced with uses of the machine's DIVU
3273and DIVS instructions (e.g., by using the GNU "asm" facility). */
3274
3275static UInt DIVU ( ULong u, UInt v )
3276{
3277 UInt uHi = (UInt)(u >> 32);
3278 UInt uLo = (UInt)u;
3279 return divlu2(uHi, uLo, v, NULL);
3280}
3281
3282static Int DIVS ( Long u, Int v )
3283{
3284 Int uHi = (Int)(u >> 32);
3285 UInt uLo = (UInt)u;
3286 return divls(uHi, uLo, v, NULL);
3287}
3288
3289/* 64 x 64 ==> 64 unsigned division, using only 32 x 32 ==> 32
3290 division as a primitive. */
3291static ULong udivdi3(ULong u, ULong v)
3292{
3293 ULong u0, u1, v1, q0, q1, k, n;
3294
3295 if (v >> 32 == 0) { // If v < 2**32:
3296 if (u >> 32 < v) // If u/v cannot overflow,
3297 return DIVU(u, v) // just do one division.
3298 & 0xFFFFFFFF;
3299 else { // If u/v would overflow:
3300 u1 = u >> 32; // Break u up into two
3301 u0 = u & 0xFFFFFFFF; // halves.
3302 q1 = DIVU(u1, v) // First quotient digit.
3303 & 0xFFFFFFFF;
3304 k = u1 - q1*v; // First remainder, < v.
3305 q0 = DIVU((k << 32) + u0, v) // 2nd quot. digit.
3306 & 0xFFFFFFFF;
3307 return (q1 << 32) + q0;
3308 }
3309 }
3310 // Here v >= 2**32.
3311 n = nlz64(v); // 0 <= n <= 31.
3312 v1 = (v << n) >> 32; // Normalize the divisor
3313 // so its MSB is 1.
3314 u1 = u >> 1; // To ensure no overflow.
3315 q1 = DIVU(u1, v1) // Get quotient from
3316 & 0xFFFFFFFF; // divide unsigned insn.
3317 q0 = (q1 << n) >> 31; // Undo normalization and
3318 // division of u by 2.
3319 if (q0 != 0) // Make q0 correct or
3320 q0 = q0 - 1; // too small by 1.
3321 if ((u - q0*v) >= v)
3322 q0 = q0 + 1; // Now q0 is correct.
3323 return q0;
3324}
3325
3326
3327// ----------------------------- divdi3 --------------------------------
3328
3329/* This routine presumes that smallish cases (those which can be done in
3330one execution of DIVS) are common. If this is not the case, the test for
3331this case should be deleted.
3332 Note that the test for when DIVS can be used is not entirely
3333accurate. For example, DIVS is not used if v = 0xFFFFFFFF8000000,
3334whereas if could be (if u is sufficiently small in magnitude). */
3335
3336// ------------------------------ cut ----------------------------------
3337
3338static ULong my_llabs ( Long x )
3339{
3340 ULong t = x >> 63;
3341 return (x ^ t) - t;
3342}
3343
3344/* 64 x 64 ==> 64 signed division, using only 32 x 32 ==> 32 division
3345 as a primitive. */
3346static Long divdi3(Long u, Long v)
3347{
3348 ULong au, av;
3349 Long q, t;
3350 au = my_llabs(u);
3351 av = my_llabs(v);
3352 if (av >> 31 == 0) { // If |v| < 2**31 and
3353 // if (v << 32 >> 32 == v) { // If v is in range and
3354 if (au < av << 31) { // |u|/|v| cannot
3355 q = DIVS(u, v); // overflow, use DIVS.
3356 return (q << 32) >> 32;
3357 }
3358 }
3359 q = udivdi3(au,av); // Invoke udivdi3.
3360 t = (u ^ v) >> 63; // If u, v have different
3361 return (q ^ t) - t; // signs, negate q.
3362}
3363
3364// ---------------------------- end cut --------------------------------
3365
sewardj0af71bb2010-07-01 14:50:30 +00003366ULong __udivdi3 (ULong u, ULong v);
njnea2d6fd2010-07-01 00:20:20 +00003367ULong __udivdi3 (ULong u, ULong v)
3368{
3369 return udivdi3(u,v);
3370}
3371
sewardj0af71bb2010-07-01 14:50:30 +00003372Long __divdi3 (Long u, Long v);
njnea2d6fd2010-07-01 00:20:20 +00003373Long __divdi3 (Long u, Long v)
3374{
3375 return divdi3(u,v);
3376}
3377
sewardj0af71bb2010-07-01 14:50:30 +00003378ULong __umoddi3 (ULong u, ULong v);
njnea2d6fd2010-07-01 00:20:20 +00003379ULong __umoddi3 (ULong u, ULong v)
3380{
3381 ULong q = __udivdi3(u, v);
3382 ULong r = u - q * v;
3383 return r;
3384}
3385
sewardj0af71bb2010-07-01 14:50:30 +00003386Long __moddi3 (Long u, Long v);
njnea2d6fd2010-07-01 00:20:20 +00003387Long __moddi3 (Long u, Long v)
3388{
3389 Long q = __divdi3(u, v);
3390 Long r = u - q * v;
3391 return r;
3392}
3393
3394#endif
3395
3396
sewardjde4a1d02002-03-22 01:27:54 +00003397/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00003398/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00003399/*--------------------------------------------------------------------*/