blob: 386b72ec791a6900679d446e4cee98f9ec78bfbd [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00003/*--- Startup: the real stuff m_main.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00004/*--------------------------------------------------------------------*/
5
6/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjde4a1d02002-03-22 01:27:54 +00009
sewardj9eecbbb2010-05-03 21:37:12 +000010 Copyright (C) 2000-2010 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
njn25e49d8e72002-09-23 09:36:25 +000028 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000029*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000032#include "pub_core_vki.h"
sewardj17c11042006-10-15 01:26:40 +000033#include "pub_core_vkiscnums.h"
njnc7561b92005-06-19 01:24:32 +000034#include "pub_core_threadstate.h"
sewardj14c7cc52007-02-25 15:08:24 +000035#include "pub_core_xarray.h"
sewardj45f4e7c2005-09-27 19:20:21 +000036#include "pub_core_clientstate.h"
sewardj55f9d1a2005-04-25 11:11:44 +000037#include "pub_core_aspacemgr.h"
njnac1e0332009-05-08 00:39:31 +000038#include "pub_core_aspacehl.h"
sewardj45f4e7c2005-09-27 19:20:21 +000039#include "pub_core_commandline.h"
njn2521d322005-05-08 14:45:13 +000040#include "pub_core_debuglog.h"
41#include "pub_core_errormgr.h"
42#include "pub_core_execontext.h"
sewardj17c11042006-10-15 01:26:40 +000043#include "pub_core_initimg.h"
njn97405b22005-06-02 03:39:33 +000044#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000045#include "pub_core_libcassert.h"
njneb8896b2005-06-04 20:03:55 +000046#include "pub_core_libcfile.h"
njn36a20fa2005-06-03 03:08:39 +000047#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000048#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +000049#include "pub_core_libcsignal.h"
sewardj45f4e7c2005-09-27 19:20:21 +000050#include "pub_core_syscall.h" // VG_(strerror)
njnf76d27a2009-05-28 01:53:07 +000051#include "pub_core_mach.h"
njnf536bbb2005-06-13 04:21:38 +000052#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +000053#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000054#include "pub_core_options.h"
sewardjfdf91b42005-09-28 00:53:09 +000055#include "pub_core_debuginfo.h"
njnd1af0032005-05-29 17:01:48 +000056#include "pub_core_redir.h"
njnc7561b92005-06-19 01:24:32 +000057#include "pub_core_scheduler.h"
sewardjf9ebc392010-05-09 22:30:43 +000058#include "pub_core_seqmatch.h" // For VG_(string_match)
njn0c246472005-05-31 01:00:08 +000059#include "pub_core_signals.h"
njn2025cf92005-06-26 20:44:48 +000060#include "pub_core_stacks.h" // For VG_(register_stack)
njnc1b01812005-06-17 22:19:06 +000061#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +000062#include "pub_core_tooliface.h"
sewardj17c11042006-10-15 01:26:40 +000063#include "pub_core_translate.h" // For VG_(translate)
njna7598f62005-06-18 03:27:58 +000064#include "pub_core_trampoline.h"
njn8bddf582005-05-13 23:40:55 +000065#include "pub_core_transtab.h"
sewardj17c11042006-10-15 01:26:40 +000066
67/* Stuff for reading AIX5 /proc/<pid>/sysent files */
68#if defined(VGO_aix5)
69 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
70# include <sys/procfs.h> /* prsysent_t */
71 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
72# define VG_AIX5_SYSENT_SIZE 100000
73 static UChar aix5_sysent_buf[VG_AIX5_SYSENT_SIZE];
74#endif
nethercote71980f02004-01-24 18:18:54 +000075
sewardjb5f6f512005-03-10 23:59:00 +000076
nethercote71980f02004-01-24 18:18:54 +000077/*====================================================================*/
78/*=== Counters, for profiling purposes only ===*/
79/*====================================================================*/
sewardjde4a1d02002-03-22 01:27:54 +000080
nethercote3a42fb82004-08-03 18:08:50 +000081static void print_all_stats ( void )
nethercote71980f02004-01-24 18:18:54 +000082{
njn42c83552005-12-05 20:45:59 +000083 VG_(print_translation_stats)();
nethercote92e7b7f2004-08-07 17:52:25 +000084 VG_(print_tt_tc_stats)();
nethercote844e7122004-08-02 15:27:22 +000085 VG_(print_scheduler_stats)();
njn9271cbc2005-03-13 05:38:25 +000086 VG_(print_ExeContext_stats)();
sewardj12ab7652006-10-17 02:10:42 +000087 VG_(print_errormgr_stats)();
njn9271cbc2005-03-13 05:38:25 +000088
nethercote3a42fb82004-08-03 18:08:50 +000089 // Memory stats
nethercote885dd912004-08-03 23:14:00 +000090 if (VG_(clo_verbosity) > 2) {
sewardj738856f2009-07-15 14:48:32 +000091 VG_(message)(Vg_DebugMsg, "\n");
nethercote3a42fb82004-08-03 18:08:50 +000092 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +000093 "------ Valgrind's internal memory use stats follow ------\n" );
nethercote885dd912004-08-03 23:14:00 +000094 VG_(sanity_check_malloc_all)();
sewardj738856f2009-07-15 14:48:32 +000095 VG_(message)(Vg_DebugMsg, "------\n" );
nethercote3a42fb82004-08-03 18:08:50 +000096 VG_(print_all_arena_stats)();
sewardj738856f2009-07-15 14:48:32 +000097 VG_(message)(Vg_DebugMsg, "\n");
nethercote3a42fb82004-08-03 18:08:50 +000098 }
nethercote71980f02004-01-24 18:18:54 +000099}
100
101
102/*====================================================================*/
sewardj71bc3cb2005-05-19 00:25:45 +0000103/*=== Command-line: variables, processing, etc ===*/
104/*====================================================================*/
105
106// See pub_{core,tool}_options.h for explanations of all these.
107
sewardj45f4e7c2005-09-27 19:20:21 +0000108static void usage_NORETURN ( Bool debug_help )
njn7cf0bd32002-06-08 13:36:03 +0000109{
sewardj7839d112007-11-20 19:45:03 +0000110 /* 'usage1' contains a %s for the name of the GDB executable, which
111 must be supplied when it is VG_(printf)'d. */
njn25e49d8e72002-09-23 09:36:25 +0000112 Char* usage1 =
njn00cfcfc2005-11-12 18:53:50 +0000113"usage: valgrind [options] prog-and-args\n"
njn25e49d8e72002-09-23 09:36:25 +0000114"\n"
njn97db7612009-08-04 02:32:55 +0000115" tool-selection option, with default in [ ]:\n"
sewardjb5f6f512005-03-10 23:59:00 +0000116" --tool=<name> use the Valgrind tool named <name> [memcheck]\n"
njn97db7612009-08-04 02:32:55 +0000117"\n"
118" basic user options for all Valgrind tools, with defaults in [ ]:\n"
nethercotea76368b2004-06-16 11:56:29 +0000119" -h --help show this message\n"
nethercote6c999f22004-01-31 22:55:15 +0000120" --help-debug show this message, plus debugging options\n"
njn25e49d8e72002-09-23 09:36:25 +0000121" --version show version\n"
njn25e49d8e72002-09-23 09:36:25 +0000122" -q --quiet run silently; only print error msgs\n"
sewardj2d9e8742009-08-07 15:46:56 +0000123" -v --verbose be more verbose -- show misc extra info\n"
sewardj6e31f802007-11-17 22:29:25 +0000124" --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]\n"
sewardj06421272009-11-05 08:55:13 +0000125" --trace-children-skip=patt1,patt2,... specifies a list of executables\n"
126" that --trace-children=yes should not trace into\n"
njn97db7612009-08-04 02:32:55 +0000127" --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n"
nethercote0d588502004-06-21 13:27:11 +0000128" --track-fds=no|yes track open file descriptors? [no]\n"
thughes6233a382004-08-21 11:10:44 +0000129" --time-stamp=no|yes add timestamps to log messages? [no]\n"
njnce545552005-07-25 22:36:52 +0000130" --log-fd=<number> log messages to file descriptor [2=stderr]\n"
njn374a36d2007-11-23 01:41:32 +0000131" --log-file=<file> log messages to <file>\n"
njnce545552005-07-25 22:36:52 +0000132" --log-socket=ipaddr:port log messages to socket ipaddr:port\n"
nethercote2b0793f2003-12-02 10:41:18 +0000133"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000134" user options for Valgrind tools that report errors:\n"
sewardj738856f2009-07-15 14:48:32 +0000135" --xml=yes emit error output in XML (some tools only)\n"
136" --xml-fd=<number> XML output to file descriptor\n"
137" --xml-file=<file> XML output to <file>\n"
138" --xml-socket=ipaddr:port XML output to socket ipaddr:port\n"
139" --xml-user-comment=STR copy STR verbatim into XML output\n"
nethercote2b0793f2003-12-02 10:41:18 +0000140" --demangle=no|yes automatically demangle C++ names? [yes]\n"
njn20b4a152005-10-19 22:39:40 +0000141" --num-callers=<number> show <number> callers in stack traces [12]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000142" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
sewardjb9779082006-05-12 23:50:15 +0000143" --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000144" --show-below-main=no|yes continue stack traces below main() [no]\n"
145" --suppressions=<filename> suppress errors described in <filename>\n"
sewardjd153fae2005-01-10 17:24:47 +0000146" --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000147" --db-attach=no|yes start debugger when errors detected? [no]\n"
sewardj7839d112007-11-20 19:45:03 +0000148" --db-command=<command> command to start debugger [%s -nw %%f %%p]\n"
nethercote04d0fbc2004-01-26 16:48:06 +0000149" --input-fd=<number> file descriptor for input [0=stdin]\n"
njn97db7612009-08-04 02:32:55 +0000150" --dsymutil=no|yes run dsymutil on Mac OS X when helpful? [no]\n"
sewardj97724e52005-04-02 23:40:59 +0000151" --max-stackframe=<number> assume stack switch for SP changes larger\n"
152" than <number> bytes [2000000]\n"
sewardj95d86c02007-12-18 01:49:23 +0000153" --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
154" [use current 'ulimit' value]\n"
njn97db7612009-08-04 02:32:55 +0000155"\n"
156" user options for Valgrind tools that replace malloc:\n"
157" --alignment=<number> set minimum alignment of heap allocations [%ld]\n"
158"\n"
159" uncommon user options for all Valgrind tools:\n"
160" --smc-check=none|stack|all checks for self-modifying code: none,\n"
161" only for code found in stacks, or all [stack]\n"
162" --read-var-info=yes|no read debug info on stack and global variables\n"
163" and use it to print better error messages in\n"
164" tools that make use of it (Memcheck, Helgrind,\n"
bartf6122a02010-03-27 07:38:39 +0000165" DRD) [no]\n"
njn97db7612009-08-04 02:32:55 +0000166" --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
167" --sim-hints=hint1,hint2,... known hints:\n"
168" lax-ioctls, enable-outer [none]\n"
169" --kernel-variant=variant1,variant2,... known variants: bproc [none]\n"
170" handle non-standard kernel variants\n"
171" --show-emwarns=no|yes show warnings about emulation limits? [no]\n"
sewardjf9ebc392010-05-09 22:30:43 +0000172" --require-text-symbol=:sonamepattern:symbolpattern abort run if the\n"
173" stated shared object doesn't have the stated\n"
174" text symbol. Patterns can contain ? and *.\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000175"\n";
njn7cf0bd32002-06-08 13:36:03 +0000176
njn25e49d8e72002-09-23 09:36:25 +0000177 Char* usage2 =
178"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000179" debugging options for all Valgrind tools:\n"
njn97db7612009-08-04 02:32:55 +0000180" -d show verbose debugging output\n"
njnb1cc5d62010-07-06 04:05:23 +0000181" --stats=no|yes show tool and core statistics [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000182" --sanity-level=<number> level of sanity checking to do [1]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000183" --trace-flags=<XXXXXXXX> show generated code? (X = 0|1) [00000000]\n"
184" --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
sewardj33afdb52006-01-17 02:36:40 +0000185" --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
njn25e49d8e72002-09-23 09:36:25 +0000186" --trace-syscalls=no|yes show all system calls? [no]\n"
187" --trace-signals=no|yes show signal handling details? [no]\n"
188" --trace-symtab=no|yes show symbol table details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000189" --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
sewardjce058b02005-05-01 08:55:38 +0000190" --trace-cfi=no|yes show call-frame-info details? [no]\n"
sewardjf767d962007-02-12 17:47:14 +0000191" --debug-dump=syms mimic /usr/bin/readelf --syms\n"
192" --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
193" --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
sewardj0ec07f32006-01-12 12:32:32 +0000194" --trace-redir=no|yes show redirection details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000195" --trace-sched=no|yes show thread scheduler details? [no]\n"
sewardj9c606bd2008-09-18 18:12:50 +0000196" --profile-heap=no|yes profile Valgrind's own space use\n"
jsgf855d93d2003-10-13 22:26:55 +0000197" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
sewardj17c11042006-10-15 01:26:40 +0000198" --sym-offsets=yes|no show syms in form 'name+offset' ? [no]\n"
sewardjb5f6f512005-03-10 23:59:00 +0000199" --command-line-only=no|yes only use command line options [no]\n"
njn613812e2005-03-11 04:57:30 +0000200"\n"
njn97db7612009-08-04 02:32:55 +0000201" Vex options for all Valgrind tools:\n"
202" --vex-iropt-verbosity=<0..9> [0]\n"
203" --vex-iropt-level=<0..2> [2]\n"
204" --vex-iropt-precise-memory-exns=no|yes [no]\n"
205" --vex-iropt-unroll-thresh=<0..400> [120]\n"
206" --vex-guest-max-insns=<1..100> [50]\n"
207" --vex-guest-chase-thresh=<0..99> [10]\n"
sewardj540cc4a2010-01-15 10:57:57 +0000208" --vex-guest-chase-cond=no|yes [no]\n"
sewardjfa8ec112005-01-19 11:55:34 +0000209" --trace-flags and --profile-flags values (omit the middle space):\n"
sewardj2a99cf62004-11-24 10:44:19 +0000210" 1000 0000 show conversion into IR\n"
211" 0100 0000 show after initial opt\n"
212" 0010 0000 show after instrumentation\n"
213" 0001 0000 show after second opt\n"
214" 0000 1000 show after tree building\n"
215" 0000 0100 show selecting insns\n"
216" 0000 0010 show after reg-alloc\n"
217" 0000 0001 show final assembly\n"
njn33dbfce2006-06-02 22:58:34 +0000218" (Nb: you need --trace-notbelow with --trace-flags for full details)\n"
sewardj2a99cf62004-11-24 10:44:19 +0000219"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000220" debugging options for Valgrind tools that report errors\n"
221" --dump-error=<number> show translation for basic block associated\n"
222" with <number>'th error context [0=show none]\n"
njn97db7612009-08-04 02:32:55 +0000223"\n"
224" debugging options for Valgrind tools that replace malloc:\n"
225" --trace-malloc=no|yes show client malloc details? [no]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000226"\n";
njn3e884182003-04-15 13:03:23 +0000227
228 Char* usage3 =
229"\n"
nethercote71980f02004-01-24 18:18:54 +0000230" Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
njn25e49d8e72002-09-23 09:36:25 +0000231"\n"
njn10b9aea2009-07-14 06:55:05 +0000232" %s is %s\n"
sewardj9eecbbb2010-05-03 21:37:12 +0000233" Valgrind is Copyright (C) 2000-2010, and GNU GPL'd, by Julian Seward et al.\n"
234" LibVEX is Copyright (C) 2004-2010, and GNU GPL'd, by OpenWorks LLP.\n"
njnd04b7c62002-10-03 14:05:52 +0000235"\n"
njn10b9aea2009-07-14 06:55:05 +0000236" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
njn25e49d8e72002-09-23 09:36:25 +0000237"\n";
njn7cf0bd32002-06-08 13:36:03 +0000238
sewardj12373b12007-11-20 21:38:14 +0000239 Char* gdb_path = GDB_PATH;
sewardj12373b12007-11-20 21:38:14 +0000240
njnbe9b47b2005-05-15 16:22:58 +0000241 // Ensure the message goes to stdout
sewardj738856f2009-07-15 14:48:32 +0000242 VG_(log_output_sink).fd = 1;
243 VG_(log_output_sink).is_socket = False;
njnbe9b47b2005-05-15 16:22:58 +0000244
njn97db7612009-08-04 02:32:55 +0000245 /* 'usage1' expects one char* argument and one SizeT argument. */
246 VG_(printf)(usage1, gdb_path, VG_MIN_MALLOC_SZB);
fitzhardinge98abfc72003-12-16 02:05:15 +0000247 if (VG_(details).name) {
248 VG_(printf)(" user options for %s:\n", VG_(details).name);
fitzhardinge98abfc72003-12-16 02:05:15 +0000249 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000250 VG_TDICT_CALL(tool_print_usage);
fitzhardinge98abfc72003-12-16 02:05:15 +0000251 else
252 VG_(printf)(" (none)\n");
253 }
nethercote6c999f22004-01-31 22:55:15 +0000254 if (debug_help) {
sewardjbbaef872008-11-01 23:55:32 +0000255 VG_(printf)("%s", usage2);
fitzhardinge98abfc72003-12-16 02:05:15 +0000256
nethercote6c999f22004-01-31 22:55:15 +0000257 if (VG_(details).name) {
258 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
259
260 if (VG_(needs).command_line_options)
njn51d827b2005-05-09 01:02:08 +0000261 VG_TDICT_CALL(tool_print_debug_usage);
nethercote6c999f22004-01-31 22:55:15 +0000262 else
263 VG_(printf)(" (none)\n");
264 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000265 }
njn10b9aea2009-07-14 06:55:05 +0000266 VG_(printf)(usage3, VG_(details).name, VG_(details).copyright_author,
267 VG_BUGS_TO);
nethercotef4928da2004-06-15 10:54:40 +0000268 VG_(exit)(0);
njn7cf0bd32002-06-08 13:36:03 +0000269}
sewardjde4a1d02002-03-22 01:27:54 +0000270
sewardjde4a1d02002-03-22 01:27:54 +0000271
sewardj95d86c02007-12-18 01:49:23 +0000272/* Peer at previously set up VG_(args_for_valgrind) and do some
273 minimal command line processing that must happen early on:
sewardj45f4e7c2005-09-27 19:20:21 +0000274
sewardj95d86c02007-12-18 01:49:23 +0000275 - show the version string, if requested (-v)
276 - extract any request for help (--help, -h, --help-debug)
277 - get the toolname (--tool=)
278 - set VG_(clo_max_stackframe) (--max-stackframe=)
279 - set VG_(clo_main_stacksize) (--main-stacksize=)
280
281 That's all it does. The main command line processing is done below
282 by main_process_cmd_line_options. Note that
283 main_process_cmd_line_options has to handle but ignore the ones we
284 have handled here.
285*/
286static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
287 /*OUT*/HChar** tool )
sewardj45f4e7c2005-09-27 19:20:21 +0000288{
289 UInt i;
290 HChar* str;
sewardj8b635a42004-11-22 19:01:47 +0000291
sewardj14c7cc52007-02-25 15:08:24 +0000292 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000293
sewardj14c7cc52007-02-25 15:08:24 +0000294 /* parse the options we have (only the options we care about now) */
295 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
296
297 str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000298 vg_assert(str);
nethercote71980f02004-01-24 18:18:54 +0000299
njn83df0b62009-02-25 01:01:05 +0000300 // Nb: the version string goes to stdout.
sewardj738856f2009-07-15 14:48:32 +0000301 if VG_XACT_CLO(str, "--version", VG_(log_output_sink).fd, 1) {
302 VG_(log_output_sink).is_socket = False;
sewardj45f4e7c2005-09-27 19:20:21 +0000303 VG_(printf)("valgrind-" VERSION "\n");
304 VG_(exit)(0);
njn83df0b62009-02-25 01:01:05 +0000305 }
njncce38e62010-07-06 04:25:12 +0000306 else if VG_XACT_CLO(str, "--help", *need_help, *need_help+1) {}
307 else if VG_XACT_CLO(str, "-h", *need_help, *need_help+1) {}
sewardj45f4e7c2005-09-27 19:20:21 +0000308
njncce38e62010-07-06 04:25:12 +0000309 else if VG_XACT_CLO(str, "--help-debug", *need_help, *need_help+2) {}
nethercote71980f02004-01-24 18:18:54 +0000310
sewardj45f4e7c2005-09-27 19:20:21 +0000311 // The tool has already been determined, but we need to know the name
312 // here.
njn83df0b62009-02-25 01:01:05 +0000313 else if VG_STR_CLO(str, "--tool", *tool) {}
sewardj5bdfbd22007-12-15 22:13:05 +0000314
sewardj95d86c02007-12-18 01:49:23 +0000315 // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
316 // These are needed by VG_(ii_create_image), which happens
317 // before main_process_cmd_line_options().
njn83df0b62009-02-25 01:01:05 +0000318 else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
319 else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
nethercote71980f02004-01-24 18:18:54 +0000320 }
nethercote71980f02004-01-24 18:18:54 +0000321}
322
sewardj95d86c02007-12-18 01:49:23 +0000323/* The main processing for command line options. See comments above
sewardj738856f2009-07-15 14:48:32 +0000324 on early_process_cmd_line_options.
325
326 Comments on how the logging options are handled:
327
328 User can specify:
329 --log-fd= for a fd to write to (default setting, fd = 2)
330 --log-file= for a file name to write to
331 --log-socket= for a socket to write to
332
333 As a result of examining these and doing relevant socket/file
334 opening, a final fd is established. This is stored in
335 VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
336 specified, then STR, after expansion of %p and %q templates within
337 it, is stored in VG_(clo_log_fname_expanded), in m_options, just in
338 case anybody wants to know what it is.
339
340 When printing, VG_(log_output_sink) is consulted to find the
341 fd to send output to.
342
343 Exactly analogous actions are undertaken for the XML output
344 channel, with the one difference that the default fd is -1, meaning
345 the channel is disabled by default.
sewardj95d86c02007-12-18 01:49:23 +0000346*/
sewardj738856f2009-07-15 14:48:32 +0000347static
348void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
349 /*OUT*/Char** xml_fname_unexpanded,
350 const HChar* toolname )
nethercote71980f02004-01-24 18:18:54 +0000351{
njnda033f52005-12-19 21:27:58 +0000352 // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
353 // and we cannot change it until we know what we are changing it to is
354 // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
sewardj92645592005-07-23 09:18:34 +0000355 SysRes sres;
sewardj738856f2009-07-15 14:48:32 +0000356 Int i, tmp_log_fd, tmp_xml_fd;
sewardj92645592005-07-23 09:18:34 +0000357 Int toolname_len = VG_(strlen)(toolname);
njn83df0b62009-02-25 01:01:05 +0000358 Char* tmp_str; // Used in a couple of places.
njnbe9b47b2005-05-15 16:22:58 +0000359 enum {
360 VgLogTo_Fd,
361 VgLogTo_File,
njnbe9b47b2005-05-15 16:22:58 +0000362 VgLogTo_Socket
sewardj738856f2009-07-15 14:48:32 +0000363 } log_to = VgLogTo_Fd, // Where is logging output to be sent?
364 xml_to = VgLogTo_Fd; // Where is XML output to be sent?
sewardjde4a1d02002-03-22 01:27:54 +0000365
sewardj738856f2009-07-15 14:48:32 +0000366 /* Temporarily holds the string STR specified with
367 --{log,xml}-{name,socket}=STR. 'fs' stands for
368 file-or-socket. */
369 Char* log_fsname_unexpanded = NULL;
370 Char* xml_fsname_unexpanded = NULL;
371
372 /* Log to stderr by default, but usage message goes to stdout. XML
373 output is initially disabled. */
njnda033f52005-12-19 21:27:58 +0000374 tmp_log_fd = 2;
sewardj738856f2009-07-15 14:48:32 +0000375 tmp_xml_fd = -1;
376
sewardj19d81412002-06-03 01:10:40 +0000377 /* Check for sane path in ./configure --prefix=... */
fitzhardinge98abfc72003-12-16 02:05:15 +0000378 if (VG_LIBDIR[0] != '/')
sewardj17c11042006-10-15 01:26:40 +0000379 VG_(err_config_error)("Please use absolute paths in "
380 "./configure --prefix=... or --libdir=...");
sewardj38170912002-05-10 21:07:22 +0000381
sewardj14c7cc52007-02-25 15:08:24 +0000382 vg_assert( VG_(args_for_valgrind) );
nethercote71980f02004-01-24 18:18:54 +0000383
sewardj738856f2009-07-15 14:48:32 +0000384 /* BEGIN command-line processing loop */
385
sewardj14c7cc52007-02-25 15:08:24 +0000386 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
387
388 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
sewardj45f4e7c2005-09-27 19:20:21 +0000389 HChar* colon = arg;
nethercote71980f02004-01-24 18:18:54 +0000390
njn1274d242007-03-26 23:38:42 +0000391 // Look for a colon in the option name.
thughes3bfd5a02004-07-18 08:05:44 +0000392 while (*colon && *colon != ':' && *colon != '=')
393 colon++;
nethercote71980f02004-01-24 18:18:54 +0000394
njn1274d242007-03-26 23:38:42 +0000395 // Does it have the form "--toolname:foo"? We have to do it at the start
396 // in case someone has combined a prefix with a core-specific option,
397 // eg. "--memcheck:verbose".
thughes3bfd5a02004-07-18 08:05:44 +0000398 if (*colon == ':') {
njn83df0b62009-02-25 01:01:05 +0000399 if (VG_STREQN(2, arg, "--") &&
400 VG_STREQN(toolname_len, arg+2, toolname) &&
401 VG_STREQN(1, arg+2+toolname_len, ":"))
nethercote71980f02004-01-24 18:18:54 +0000402 {
njn1274d242007-03-26 23:38:42 +0000403 // Prefix matches, convert "--toolname:foo" to "--foo".
404 // Two things to note:
405 // - We cannot modify the option in-place. If we did, and then
406 // a child was spawned with --trace-children=yes, the
407 // now-non-prefixed option would be passed and could screw up
408 // the child.
409 // - We create copies, and never free them. Why? Non-prefixed
410 // options hang around forever, so tools need not make copies
411 // of strings within them. We need to have the same behaviour
412 // for prefixed options. The pointer to the copy will be lost
413 // once we leave this function (although a tool may keep a
414 // pointer into it), but the space wasted is insignificant.
415 // (In bug #142197, the copies were being freed, which caused
416 // problems for tools that reasonably assumed that arguments
417 // wouldn't disappear on them.)
nethercote71980f02004-01-24 18:18:54 +0000418 if (0)
419 VG_(printf)("tool-specific arg: %s\n", arg);
sewardj9c606bd2008-09-18 18:12:50 +0000420 arg = VG_(strdup)("main.mpclo.1", arg + toolname_len + 1);
nethercote71980f02004-01-24 18:18:54 +0000421 arg[0] = '-';
422 arg[1] = '-';
423
424 } else {
425 // prefix doesn't match, skip to next arg
426 continue;
427 }
428 }
429
fitzhardinge98abfc72003-12-16 02:05:15 +0000430 /* Ignore these options - they've already been handled */
njn83df0b62009-02-25 01:01:05 +0000431 if VG_STREQN( 7, arg, "--tool=") {}
432 else if VG_STREQN(20, arg, "--command-line-only=") {}
433 else if VG_STREQ( arg, "--") {}
434 else if VG_STREQ( arg, "-d") {}
435 else if VG_STREQN(16, arg, "--max-stackframe") {}
436 else if VG_STREQN(16, arg, "--main-stacksize") {}
437 else if VG_STREQN(14, arg, "--profile-heap") {}
nethercote27fec902004-06-16 21:26:32 +0000438
njn83df0b62009-02-25 01:01:05 +0000439 // These options are new.
440 else if (VG_STREQ(arg, "-v") ||
441 VG_STREQ(arg, "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000442 VG_(clo_verbosity)++;
nethercote27fec902004-06-16 21:26:32 +0000443
njn83df0b62009-02-25 01:01:05 +0000444 else if (VG_STREQ(arg, "-q") ||
445 VG_STREQ(arg, "--quiet"))
sewardjde4a1d02002-03-22 01:27:54 +0000446 VG_(clo_verbosity)--;
447
sewardj2d9e8742009-08-07 15:46:56 +0000448 else if VG_BOOL_CLO(arg, "--stats", VG_(clo_stats)) {}
njn83df0b62009-02-25 01:01:05 +0000449 else if VG_BOOL_CLO(arg, "--xml", VG_(clo_xml)) {}
450 else if VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach)) {}
451 else if VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle)) {}
452 else if VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit)) {}
453 else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
454 else if VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns)) {}
sewardj95d86c02007-12-18 01:49:23 +0000455
njn83df0b62009-02-25 01:01:05 +0000456 else if VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres)) {}
457 else if VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main)) {}
458 else if VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp)) {}
459 else if VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds)) {}
460 else if VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children)) {}
461 else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
462 VG_(clo_child_silent_after_fork)) {}
463 else if VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched)) {}
464 else if VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals)) {}
465 else if VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab)) {}
466 else if VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt)) {}
467 else if VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi)) {}
468 else if VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms),
469 True) {}
470 else if VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line),
471 True) {}
472 else if VG_XACT_CLO(arg, "--debug-dump=frames",
473 VG_(clo_debug_dump_frames), True) {}
474 else if VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir)) {}
sewardj95d86c02007-12-18 01:49:23 +0000475
njn83df0b62009-02-25 01:01:05 +0000476 else if VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls)) {}
477 else if VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb)) {}
478 else if VG_STR_CLO (arg, "--db-command", VG_(clo_db_command)) {}
479 else if VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints)) {}
480 else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
481 else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
sewardjf767d962007-02-12 17:47:14 +0000482
njn83df0b62009-02-25 01:01:05 +0000483 else if VG_INT_CLO (arg, "--dump-error", VG_(clo_dump_error)) {}
484 else if VG_INT_CLO (arg, "--input-fd", VG_(clo_input_fd)) {}
485 else if VG_INT_CLO (arg, "--sanity-level", VG_(clo_sanity_level)) {}
486 else if VG_BINT_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
487 VG_DEEPEST_BACKTRACE) {}
sewardjde4a1d02002-03-22 01:27:54 +0000488
njn83df0b62009-02-25 01:01:05 +0000489 else if VG_XACT_CLO(arg, "--smc-check=none", VG_(clo_smc_check),
490 Vg_SmcNone);
491 else if VG_XACT_CLO(arg, "--smc-check=stack", VG_(clo_smc_check),
492 Vg_SmcStack);
493 else if VG_XACT_CLO(arg, "--smc-check=all", VG_(clo_smc_check),
494 Vg_SmcAll);
sewardjde4a1d02002-03-22 01:27:54 +0000495
njn97db7612009-08-04 02:32:55 +0000496 else if VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant)) {}
sewardj26412bd2005-07-07 10:05:05 +0000497
njn97db7612009-08-04 02:32:55 +0000498 else if VG_BOOL_CLO(arg, "--dsymutil", VG_(clo_dsymutil)) {}
njnf76d27a2009-05-28 01:53:07 +0000499
sewardj06421272009-11-05 08:55:13 +0000500 else if VG_STR_CLO (arg, "--trace-children-skip", VG_(clo_trace_children_skip)) {}
501
njn83df0b62009-02-25 01:01:05 +0000502 else if VG_BINT_CLO(arg, "--vex-iropt-verbosity",
503 VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
504 else if VG_BINT_CLO(arg, "--vex-iropt-level",
505 VG_(clo_vex_control).iropt_level, 0, 2) {}
506 else if VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
507 VG_(clo_vex_control).iropt_precise_memory_exns) {}
508 else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
509 VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
510 else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
511 VG_(clo_vex_control).guest_max_insns, 1, 100) {}
512 else if VG_BINT_CLO(arg, "--vex-guest-chase-thresh",
513 VG_(clo_vex_control).guest_chase_thresh, 0, 99) {}
sewardj540cc4a2010-01-15 10:57:57 +0000514 else if VG_BOOL_CLO(arg, "--vex-guest-chase-cond",
515 VG_(clo_vex_control).guest_chase_cond) {}
sewardj94c8eb42008-09-19 20:13:39 +0000516
njn83df0b62009-02-25 01:01:05 +0000517 else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
518 log_to = VgLogTo_Fd;
sewardj738856f2009-07-15 14:48:32 +0000519 log_fsname_unexpanded = NULL;
520 }
521 else if VG_INT_CLO(arg, "--xml-fd", tmp_xml_fd) {
522 xml_to = VgLogTo_Fd;
523 xml_fsname_unexpanded = NULL;
sewardj4cf05692002-10-27 20:28:29 +0000524 }
525
sewardj738856f2009-07-15 14:48:32 +0000526 else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000527 log_to = VgLogTo_File;
sewardj4cf05692002-10-27 20:28:29 +0000528 }
sewardj738856f2009-07-15 14:48:32 +0000529 else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) {
530 xml_to = VgLogTo_File;
531 }
532
533 else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) {
njn83df0b62009-02-25 01:01:05 +0000534 log_to = VgLogTo_Socket;
sewardj73cf3bc2002-11-03 03:20:15 +0000535 }
sewardj738856f2009-07-15 14:48:32 +0000536 else if VG_STR_CLO(arg, "--xml-socket", xml_fsname_unexpanded) {
537 xml_to = VgLogTo_Socket;
538 }
sewardj73cf3bc2002-11-03 03:20:15 +0000539
njn83df0b62009-02-25 01:01:05 +0000540 else if VG_STR_CLO(arg, "--xml-user-comment",
541 VG_(clo_xml_user_comment)) {}
sewardj768db0e2005-07-19 14:18:56 +0000542
njn83df0b62009-02-25 01:01:05 +0000543 else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
sewardjde4a1d02002-03-22 01:27:54 +0000544 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njnb1cc5d62010-07-06 04:05:23 +0000545 VG_(fmsg_bad_option)(arg,
546 "Too many suppression files specified.\n"
547 "Increase VG_CLO_MAX_SFILES and recompile.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000548 }
njn83df0b62009-02-25 01:01:05 +0000549 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = tmp_str;
sewardjde4a1d02002-03-22 01:27:54 +0000550 VG_(clo_n_suppressions)++;
551 }
sewardjde4a1d02002-03-22 01:27:54 +0000552
sewardjf9ebc392010-05-09 22:30:43 +0000553 else if VG_STR_CLO(arg, "--require-text-symbol", tmp_str) {
554 if (VG_(clo_n_req_tsyms) >= VG_CLO_MAX_REQ_TSYMS) {
njnb1cc5d62010-07-06 04:05:23 +0000555 VG_(fmsg_bad_option)(arg,
556 "Too many --require-text-symbol= specifications.\n"
557 "Increase VG_CLO_MAX_REQ_TSYMS and recompile.\n");
sewardjf9ebc392010-05-09 22:30:43 +0000558 }
559 /* String needs to be of the form C?*C?*, where C is any
560 character, but is the same both times. Having it in this
561 form facilitates finding the boundary between the sopatt
562 and the fnpatt just by looking for the second occurrence
563 of C, without hardwiring any assumption about what C
564 is. */
565 Char patt[7];
566 Bool ok = True;
567 ok = tmp_str && VG_(strlen)(tmp_str) > 0;
568 if (ok) {
569 patt[0] = patt[3] = tmp_str[0];
570 patt[1] = patt[4] = '?';
571 patt[2] = patt[5] = '*';
572 patt[6] = 0;
573 ok = VG_(string_match)(patt, tmp_str);
574 }
575 if (!ok) {
njnb1cc5d62010-07-06 04:05:23 +0000576 VG_(fmsg_bad_option)(arg,
577 "Invalid --require-text-symbol= specification.\n");
sewardjf9ebc392010-05-09 22:30:43 +0000578 }
579 VG_(clo_req_tsyms)[VG_(clo_n_req_tsyms)] = tmp_str;
580 VG_(clo_n_req_tsyms)++;
581 }
582
sewardjfa8ec112005-01-19 11:55:34 +0000583 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000584 else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
sewardjfa8ec112005-01-19 11:55:34 +0000585 Int j;
sewardjfa8ec112005-01-19 11:55:34 +0000586
njn83df0b62009-02-25 01:01:05 +0000587 if (8 != VG_(strlen)(tmp_str)) {
njnb1cc5d62010-07-06 04:05:23 +0000588 VG_(fmsg_bad_option)(arg,
589 "--trace-flags argument must have 8 digits\n");
sewardjfa8ec112005-01-19 11:55:34 +0000590 }
591 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000592 if ('0' == tmp_str[j]) { /* do nothing */ }
593 else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
sewardjfa8ec112005-01-19 11:55:34 +0000594 else {
njnb1cc5d62010-07-06 04:05:23 +0000595 VG_(fmsg_bad_option)(arg,
596 "--trace-flags argument can only contain 0s and 1s\n");
sewardjfa8ec112005-01-19 11:55:34 +0000597 }
598 }
599 }
600
601 /* "stuvwxyz" --> stuvwxyz (binary) */
njn83df0b62009-02-25 01:01:05 +0000602 else if VG_STR_CLO(arg, "--profile-flags", tmp_str) {
njn25e49d8e72002-09-23 09:36:25 +0000603 Int j;
njn25e49d8e72002-09-23 09:36:25 +0000604
njn83df0b62009-02-25 01:01:05 +0000605 if (8 != VG_(strlen)(tmp_str)) {
njnb1cc5d62010-07-06 04:05:23 +0000606 VG_(fmsg_bad_option)(arg,
607 "--profile-flags argument must have 8 digits\n");
njn25e49d8e72002-09-23 09:36:25 +0000608 }
sewardj8b635a42004-11-22 19:01:47 +0000609 for (j = 0; j < 8; j++) {
njn83df0b62009-02-25 01:01:05 +0000610 if ('0' == tmp_str[j]) { /* do nothing */ }
611 else if ('1' == tmp_str[j]) VG_(clo_profile_flags) |= (1 << (7-j));
njn25e49d8e72002-09-23 09:36:25 +0000612 else {
njnb1cc5d62010-07-06 04:05:23 +0000613 VG_(fmsg_bad_option)(arg,
614 "--profile-flags argument can only contain 0s and 1s\n");
njn25e49d8e72002-09-23 09:36:25 +0000615 }
616 }
617 }
sewardjde4a1d02002-03-22 01:27:54 +0000618
njn83df0b62009-02-25 01:01:05 +0000619 else if VG_INT_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow)) {}
sewardjc771b292004-11-30 18:55:21 +0000620
njn83df0b62009-02-25 01:01:05 +0000621 else if VG_XACT_CLO(arg, "--gen-suppressions=no",
622 VG_(clo_gen_suppressions), 0) {}
623 else if VG_XACT_CLO(arg, "--gen-suppressions=yes",
624 VG_(clo_gen_suppressions), 1) {}
625 else if VG_XACT_CLO(arg, "--gen-suppressions=all",
626 VG_(clo_gen_suppressions), 2) {}
sewardjd153fae2005-01-10 17:24:47 +0000627
nethercote71980f02004-01-24 18:18:54 +0000628 else if ( ! VG_(needs).command_line_options
njn51d827b2005-05-09 01:02:08 +0000629 || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
njnb1cc5d62010-07-06 04:05:23 +0000630 VG_(fmsg_bad_option)(arg, "");
njn25e49d8e72002-09-23 09:36:25 +0000631 }
sewardjde4a1d02002-03-22 01:27:54 +0000632 }
633
sewardj738856f2009-07-15 14:48:32 +0000634 /* END command-line processing loop */
635
sewardj998d40d2004-12-06 14:24:52 +0000636 /* Make VEX control parameters sane */
637
638 if (VG_(clo_vex_control).guest_chase_thresh
639 >= VG_(clo_vex_control).guest_max_insns)
640 VG_(clo_vex_control).guest_chase_thresh
641 = VG_(clo_vex_control).guest_max_insns - 1;
642
643 if (VG_(clo_vex_control).guest_chase_thresh < 0)
644 VG_(clo_vex_control).guest_chase_thresh = 0;
645
646 /* Check various option values */
nethercote27fec902004-06-16 21:26:32 +0000647
njnf9ebf672003-05-12 21:41:30 +0000648 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +0000649 VG_(clo_verbosity) = 0;
650
njnbe9b47b2005-05-15 16:22:58 +0000651 if (VG_(clo_gen_suppressions) > 0 &&
652 !VG_(needs).core_errors && !VG_(needs).tool_errors) {
njnb1cc5d62010-07-06 04:05:23 +0000653 VG_(fmsg_bad_option)("--gen-suppressions=yes",
654 "Can't use --gen-suppressions= with %s\n"
655 "because it doesn't generate errors.\n", VG_(details).name);
njnbe9b47b2005-05-15 16:22:58 +0000656 }
657
sewardj738856f2009-07-15 14:48:32 +0000658 /* If XML output is requested, check that the tool actually
659 supports it. */
660 if (VG_(clo_xml) && !VG_(needs).xml_output) {
661 VG_(clo_xml) = False;
njnb1cc5d62010-07-06 04:05:23 +0000662 VG_(fmsg_bad_option)("--xml=yes",
sewardj738856f2009-07-15 14:48:32 +0000663 "%s does not support XML output.\n", VG_(details).name);
sewardj738856f2009-07-15 14:48:32 +0000664 /*NOTREACHED*/
665 }
666
667 vg_assert( VG_(clo_gen_suppressions) >= 0 );
668 vg_assert( VG_(clo_gen_suppressions) <= 2 );
669
sewardj71bc3cb2005-05-19 00:25:45 +0000670 /* If we've been asked to emit XML, mash around various other
671 options so as to constrain the output somewhat, and to remove
sewardj738856f2009-07-15 14:48:32 +0000672 any need for user input during the run.
673 */
sewardj71bc3cb2005-05-19 00:25:45 +0000674 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +0000675
676 /* We can't allow --gen-suppressions=yes, since that requires us
677 to print the error and then ask the user if she wants a
678 suppression for it, but in XML mode we won't print it until
679 we know whether we also need to print a suppression. Hence a
680 circular dependency. So disallow this.
681 (--gen-suppressions=all is still OK since we don't need any
682 user interaction in this case.) */
683 if (VG_(clo_gen_suppressions) == 1) {
njnb1cc5d62010-07-06 04:05:23 +0000684 VG_(fmsg_bad_option)(
685 "--xml=yes together with --gen-suppressions=yes",
686 "When --xml=yes is specified, --gen-suppressions=no\n"
687 "or --gen-suppressions=all is allowed, but not "
sewardj738856f2009-07-15 14:48:32 +0000688 "--gen-suppressions=yes.\n");
sewardj738856f2009-07-15 14:48:32 +0000689 }
690
691 /* We can't allow DB attaching (or we maybe could, but results
692 could be chaotic ..) since it requires user input. Hence
693 disallow. */
694 if (VG_(clo_db_attach)) {
njnb1cc5d62010-07-06 04:05:23 +0000695 VG_(fmsg_bad_option)(
696 "--xml=yes together with --db-attach=yes",
697 "--db-attach=yes is not allowed with --xml=yes\n"
698 "because it would require user input.\n");
sewardj738856f2009-07-15 14:48:32 +0000699 }
700
701 /* Disallow dump_error in XML mode; sounds like a recipe for
702 chaos. No big deal; dump_error is a flag for debugging V
703 itself. */
704 if (VG_(clo_dump_error) > 0) {
njnb1cc5d62010-07-06 04:05:23 +0000705 VG_(fmsg_bad_option)("--xml=yes together with --dump-error", "");
sewardj738856f2009-07-15 14:48:32 +0000706 }
707
sewardj71bc3cb2005-05-19 00:25:45 +0000708 /* Disable error limits (this might be a bad idea!) */
709 VG_(clo_error_limit) = False;
710 /* Disable emulation warnings */
sewardj738856f2009-07-15 14:48:32 +0000711
sewardj71bc3cb2005-05-19 00:25:45 +0000712 /* Also, we want to set options for the leak checker, but that
713 will have to be done in Memcheck's flag-handling code, not
714 here. */
715 }
716
njnbe9b47b2005-05-15 16:22:58 +0000717 /* All non-logging-related options have been checked. If the logging
718 option specified is ok, we can switch to it, as we know we won't
719 have to generate any other command-line-related error messages.
720 (So far we should be still attached to stderr, so we can show on
721 the terminal any problems to do with processing command line
722 opts.)
723
sewardj738856f2009-07-15 14:48:32 +0000724 So set up logging now. After this is done, VG_(log_output_sink)
725 and (if relevant) VG_(xml_output_sink) should be connected to
726 whatever sink has been selected, and we indiscriminately chuck
727 stuff into it without worrying what the nature of it is. Oh the
728 wonder of Unix streams. */
sewardj4cf05692002-10-27 20:28:29 +0000729
sewardj738856f2009-07-15 14:48:32 +0000730 vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
731 vg_assert(VG_(log_output_sink).is_socket == False);
732 vg_assert(VG_(clo_log_fname_expanded) == NULL);
733
734 vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
735 vg_assert(VG_(xml_output_sink).is_socket == False);
736 vg_assert(VG_(clo_xml_fname_expanded) == NULL);
737
738 /* --- set up the normal text output channel --- */
sewardj4cf05692002-10-27 20:28:29 +0000739
njnbe9b47b2005-05-15 16:22:58 +0000740 switch (log_to) {
sewardj73cf3bc2002-11-03 03:20:15 +0000741
sewardj4cf05692002-10-27 20:28:29 +0000742 case VgLogTo_Fd:
sewardj738856f2009-07-15 14:48:32 +0000743 vg_assert(log_fsname_unexpanded == NULL);
sewardj4cf05692002-10-27 20:28:29 +0000744 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000745
sewardj4cf05692002-10-27 20:28:29 +0000746 case VgLogTo_File: {
njn374a36d2007-11-23 01:41:32 +0000747 Char* logfilename;
jsgff3c3f1a2003-10-14 22:13:28 +0000748
sewardj738856f2009-07-15 14:48:32 +0000749 vg_assert(log_fsname_unexpanded != NULL);
750 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +0000751
njn374a36d2007-11-23 01:41:32 +0000752 // Nb: we overwrite an existing file of this name without asking
753 // any questions.
sewardj738856f2009-07-15 14:48:32 +0000754 logfilename = VG_(expand_file_name)("--log-file",
755 log_fsname_unexpanded);
njn374a36d2007-11-23 01:41:32 +0000756 sres = VG_(open)(logfilename,
njnda033f52005-12-19 21:27:58 +0000757 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
758 VKI_S_IRUSR|VKI_S_IWUSR);
njncda2f0f2009-05-18 02:12:08 +0000759 if (!sr_isError(sres)) {
760 tmp_log_fd = sr_Res(sres);
sewardj738856f2009-07-15 14:48:32 +0000761 VG_(clo_log_fname_expanded) = logfilename;
njnbe9b47b2005-05-15 16:22:58 +0000762 } else {
njnb1cc5d62010-07-06 04:05:23 +0000763 VG_(fmsg)("can't create log file '%s': %s\n",
764 logfilename, VG_(strerror)(sr_Err(sres)));
765 VG_(exit)(1);
sewardj603d4102005-01-11 14:01:02 +0000766 /*NOTREACHED*/
njn374a36d2007-11-23 01:41:32 +0000767 }
sewardj738856f2009-07-15 14:48:32 +0000768 break;
sewardj73cf3bc2002-11-03 03:20:15 +0000769 }
770
771 case VgLogTo_Socket: {
sewardj738856f2009-07-15 14:48:32 +0000772 vg_assert(log_fsname_unexpanded != NULL);
773 vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
774 tmp_log_fd = VG_(connect_via_socket)( log_fsname_unexpanded );
njnda033f52005-12-19 21:27:58 +0000775 if (tmp_log_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +0000776 VG_(fmsg)("Invalid --log-socket spec of '%s'\n",
777 log_fsname_unexpanded);
778 VG_(exit)(1);
njnbe9b47b2005-05-15 16:22:58 +0000779 /*NOTREACHED*/
sewardj4cf05692002-10-27 20:28:29 +0000780 }
njnda033f52005-12-19 21:27:58 +0000781 if (tmp_log_fd == -2) {
njnb1cc5d62010-07-06 04:05:23 +0000782 VG_(umsg)("failed to connect to logging server '%s'.\n"
783 "Log messages will sent to stderr instead.\n",
784 log_fsname_unexpanded );
785
sewardj570f8902002-11-03 11:44:36 +0000786 /* We don't change anything here. */
sewardj738856f2009-07-15 14:48:32 +0000787 vg_assert(VG_(log_output_sink).fd == 2);
njnda033f52005-12-19 21:27:58 +0000788 tmp_log_fd = 2;
sewardj570f8902002-11-03 11:44:36 +0000789 } else {
njnda033f52005-12-19 21:27:58 +0000790 vg_assert(tmp_log_fd > 0);
sewardj738856f2009-07-15 14:48:32 +0000791 VG_(log_output_sink).is_socket = True;
sewardj570f8902002-11-03 11:44:36 +0000792 }
sewardj73cf3bc2002-11-03 03:20:15 +0000793 break;
794 }
sewardj4cf05692002-10-27 20:28:29 +0000795 }
796
sewardj738856f2009-07-15 14:48:32 +0000797 /* --- set up the XML output channel --- */
sewardj71bc3cb2005-05-19 00:25:45 +0000798
sewardj738856f2009-07-15 14:48:32 +0000799 switch (xml_to) {
800
801 case VgLogTo_Fd:
802 vg_assert(xml_fsname_unexpanded == NULL);
803 break;
804
805 case VgLogTo_File: {
806 Char* xmlfilename;
807
808 vg_assert(xml_fsname_unexpanded != NULL);
809 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
810
811 // Nb: we overwrite an existing file of this name without asking
812 // any questions.
813 xmlfilename = VG_(expand_file_name)("--xml-file",
814 xml_fsname_unexpanded);
815 sres = VG_(open)(xmlfilename,
816 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
817 VKI_S_IRUSR|VKI_S_IWUSR);
818 if (!sr_isError(sres)) {
819 tmp_xml_fd = sr_Res(sres);
820 VG_(clo_xml_fname_expanded) = xmlfilename;
821 /* strdup here is probably paranoid overkill, but ... */
822 *xml_fname_unexpanded = VG_(strdup)( "main.mpclo.2",
823 xml_fsname_unexpanded );
824 } else {
njnb1cc5d62010-07-06 04:05:23 +0000825 VG_(fmsg)("can't create XML file '%s': %s\n",
826 xmlfilename, VG_(strerror)(sr_Err(sres)));
827 VG_(exit)(1);
sewardj738856f2009-07-15 14:48:32 +0000828 /*NOTREACHED*/
829 }
830 break;
831 }
832
833 case VgLogTo_Socket: {
834 vg_assert(xml_fsname_unexpanded != NULL);
835 vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
836 tmp_xml_fd = VG_(connect_via_socket)( xml_fsname_unexpanded );
837 if (tmp_xml_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +0000838 VG_(fmsg)("Invalid --xml-socket spec of '%s'\n",
839 xml_fsname_unexpanded );
840 VG_(exit)(1);
sewardj738856f2009-07-15 14:48:32 +0000841 /*NOTREACHED*/
842 }
843 if (tmp_xml_fd == -2) {
njnb1cc5d62010-07-06 04:05:23 +0000844 VG_(umsg)("failed to connect to XML logging server '%s'.\n"
845 "XML output will sent to stderr instead.\n",
846 xml_fsname_unexpanded);
sewardj738856f2009-07-15 14:48:32 +0000847 /* We don't change anything here. */
848 vg_assert(VG_(xml_output_sink).fd == 2);
849 tmp_xml_fd = 2;
850 } else {
851 vg_assert(tmp_xml_fd > 0);
852 VG_(xml_output_sink).is_socket = True;
853 }
854 break;
855 }
sewardj71bc3cb2005-05-19 00:25:45 +0000856 }
857
sewardj738856f2009-07-15 14:48:32 +0000858 /* If we've got this far, and XML mode was requested, but no XML
859 output channel appears to have been specified, just stop. We
860 could continue, and XML output will simply vanish into nowhere,
861 but that is likely to confuse the hell out of users, which is
862 distinctly Ungood. */
863 if (VG_(clo_xml) && tmp_xml_fd == -1) {
njnb1cc5d62010-07-06 04:05:23 +0000864 VG_(fmsg_bad_option)(
865 "--xml=yes, but no XML destination specified",
sewardj738856f2009-07-15 14:48:32 +0000866 "--xml=yes has been specified, but there is no XML output\n"
867 "destination. You must specify an XML output destination\n"
njnb1cc5d62010-07-06 04:05:23 +0000868 "using --xml-fd, --xml-file or --xml-socket.\n"
869 );
sewardj738856f2009-07-15 14:48:32 +0000870 }
871
872 // Finalise the output fds: the log fd ..
873
njnda033f52005-12-19 21:27:58 +0000874 if (tmp_log_fd >= 0) {
sewardj738856f2009-07-15 14:48:32 +0000875 // Move log_fd into the safe range, so it doesn't conflict with
876 // any app fds.
njnda033f52005-12-19 21:27:58 +0000877 tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
878 if (tmp_log_fd < 0) {
sewardj738856f2009-07-15 14:48:32 +0000879 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd "
880 "into safe range, using stderr\n");
881 VG_(log_output_sink).fd = 2; // stderr
882 VG_(log_output_sink).is_socket = False;
njnda033f52005-12-19 21:27:58 +0000883 } else {
sewardj738856f2009-07-15 14:48:32 +0000884 VG_(log_output_sink).fd = tmp_log_fd;
885 VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
njnda033f52005-12-19 21:27:58 +0000886 }
887 } else {
888 // If they said --log-fd=-1, don't print anything. Plausible for use in
889 // regression testing suites that use client requests to count errors.
sewardj738856f2009-07-15 14:48:32 +0000890 VG_(log_output_sink).fd = -1;
891 VG_(log_output_sink).is_socket = False;
jsgf855d93d2003-10-13 22:26:55 +0000892 }
893
sewardj738856f2009-07-15 14:48:32 +0000894 // Finalise the output fds: and the XML fd ..
895
896 if (tmp_xml_fd >= 0) {
897 // Move xml_fd into the safe range, so it doesn't conflict with
898 // any app fds.
899 tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
900 if (tmp_xml_fd < 0) {
901 VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd "
902 "into safe range, using stderr\n");
903 VG_(xml_output_sink).fd = 2; // stderr
904 VG_(xml_output_sink).is_socket = False;
905 } else {
906 VG_(xml_output_sink).fd = tmp_xml_fd;
907 VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
908 }
909 } else {
910 // If they said --xml-fd=-1, don't print anything. Plausible for use in
911 // regression testing suites that use client requests to count errors.
912 VG_(xml_output_sink).fd = -1;
913 VG_(xml_output_sink).is_socket = False;
914 }
915
916 // Suppressions related stuff
917
sewardj45f4e7c2005-09-27 19:20:21 +0000918 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
919 (VG_(needs).core_errors || VG_(needs).tool_errors)) {
920 /* If we haven't reached the max number of suppressions, load
921 the default one. */
922 static const Char default_supp[] = "default.supp";
923 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
sewardj738856f2009-07-15 14:48:32 +0000924 Char *buf = VG_(arena_malloc)(VG_AR_CORE, "main.mpclo.3", len);
sewardj45f4e7c2005-09-27 19:20:21 +0000925 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
926 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
927 VG_(clo_n_suppressions)++;
928 }
sewardjde4a1d02002-03-22 01:27:54 +0000929
sewardj738856f2009-07-15 14:48:32 +0000930 *logging_to_fd = log_to == VgLogTo_Fd || log_to == VgLogTo_Socket;
sewardj45f4e7c2005-09-27 19:20:21 +0000931}
932
sewardj4efbaa72008-06-04 06:51:58 +0000933// Write the name and value of log file qualifiers to the xml file.
934static void print_file_vars(Char* format)
935{
936 Int i = 0;
937
938 while (format[i]) {
939 if (format[i] == '%') {
940 // We saw a '%'. What's next...
941 i++;
942 if ('q' == format[i]) {
943 i++;
944 if ('{' == format[i]) {
945 // Get the env var name, print its contents.
946 Char* qualname;
947 Char* qual;
948 i++;
949 qualname = &format[i];
950 while (True) {
951 if ('}' == format[i]) {
952 // Temporarily replace the '}' with NUL to extract var
953 // name.
954 format[i] = 0;
955 qual = VG_(getenv)(qualname);
956 break;
957 }
958 i++;
959 }
960
sewardj7ca100d2009-08-15 23:05:34 +0000961 VG_(printf_xml_no_f_c)(
962 "<logfilequalifier> <var>%t</var> "
963 "<value>%t</value> </logfilequalifier>\n",
964 qualname,qual
965 );
sewardj4efbaa72008-06-04 06:51:58 +0000966 format[i] = '}';
967 i++;
968 }
969 }
970 } else {
971 i++;
972 }
973 }
974}
975
sewardj45f4e7c2005-09-27 19:20:21 +0000976
977/*====================================================================*/
978/*=== Printing the preamble ===*/
979/*====================================================================*/
980
njnf8a11cf2009-08-02 23:03:06 +0000981// Print the command, escaping any chars that require it.
barta3054f52010-06-14 18:12:56 +0000982static void umsg_or_xml_arg(const Char* arg,
njnf8a11cf2009-08-02 23:03:06 +0000983 UInt (*umsg_or_xml)( const HChar*, ... ) )
984{
985 SizeT len = VG_(strlen)(arg);
986 Char* special = " \\<>";
987 Int i;
988 for (i = 0; i < len; i++) {
989 if (VG_(strchr)(special, arg[i])) {
990 umsg_or_xml("\\"); // escape with a backslash if necessary
991 }
992 umsg_or_xml("%c", arg[i]);
993 }
994}
995
sewardj45f4e7c2005-09-27 19:20:21 +0000996/* Ok, the logging sink is running now. Print a suitable preamble.
997 If logging to file or a socket, write details of parent PID and
998 command line args, to help people trying to interpret the
999 results of a run which encompasses multiple processes. */
sewardj738856f2009-07-15 14:48:32 +00001000static void print_preamble ( Bool logging_to_fd,
1001 Char* xml_fname_unexpanded,
1002 const HChar* toolname )
sewardj45f4e7c2005-09-27 19:20:21 +00001003{
sewardj738856f2009-07-15 14:48:32 +00001004 Int i;
tom60a4b0b2005-10-12 10:45:27 +00001005 HChar* xpre = VG_(clo_xml) ? " <line>" : "";
1006 HChar* xpost = VG_(clo_xml) ? "</line>" : "";
sewardj738856f2009-07-15 14:48:32 +00001007 UInt (*umsg_or_xml)( const HChar*, ... )
1008 = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
tom60a4b0b2005-10-12 10:45:27 +00001009
sewardj14c7cc52007-02-25 15:08:24 +00001010 vg_assert( VG_(args_for_client) );
1011 vg_assert( VG_(args_for_valgrind) );
sewardj99a2ceb2007-11-09 12:30:36 +00001012 vg_assert( toolname );
sewardj14c7cc52007-02-25 15:08:24 +00001013
sewardj71bc3cb2005-05-19 00:25:45 +00001014 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001015 VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
1016 VG_(printf_xml)("\n");
1017 VG_(printf_xml)("<valgrindoutput>\n");
1018 VG_(printf_xml)("\n");
1019 VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
1020 VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", toolname);
1021 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001022 }
1023
sewardj738856f2009-07-15 14:48:32 +00001024 if (VG_(clo_xml) || VG_(clo_verbosity > 0)) {
sewardjd7bddad2005-06-13 16:48:32 +00001025
1026 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001027 VG_(printf_xml)("<preamble>\n");
sewardjd7bddad2005-06-13 16:48:32 +00001028
nethercote996901a2004-08-03 13:29:09 +00001029 /* Tool details */
njnb6267bd2009-08-12 00:14:16 +00001030 umsg_or_xml( "%s%s%s%s, %s%s\n",
sewardj71bc3cb2005-05-19 00:25:45 +00001031 xpre,
njnd04b7c62002-10-03 14:05:52 +00001032 VG_(details).name,
njnb9c427c2004-12-01 14:14:42 +00001033 NULL == VG_(details).version ? "" : "-",
njnd04b7c62002-10-03 14:05:52 +00001034 NULL == VG_(details).version
1035 ? (Char*)"" : VG_(details).version,
sewardj71bc3cb2005-05-19 00:25:45 +00001036 VG_(details).description,
sewardj738856f2009-07-15 14:48:32 +00001037 xpost );
sewardj99a2ceb2007-11-09 12:30:36 +00001038
njn10b9aea2009-07-14 06:55:05 +00001039 if (VG_(strlen)(toolname) >= 4 && VG_STREQN(4, toolname, "exp-")) {
sewardj738856f2009-07-15 14:48:32 +00001040 umsg_or_xml(
njnb6267bd2009-08-12 00:14:16 +00001041 "%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
sewardj99a2ceb2007-11-09 12:30:36 +00001042 xpre, xpost
1043 );
1044 }
1045
njnf3977a32009-08-04 00:27:56 +00001046 umsg_or_xml("%s%s%s\n", xpre, VG_(details).copyright_author, xpost);
sewardj3b2736a2002-03-24 12:18:35 +00001047
njnd04b7c62002-10-03 14:05:52 +00001048 /* Core details */
sewardj738856f2009-07-15 14:48:32 +00001049 umsg_or_xml(
njnf73d87f2009-07-24 04:47:04 +00001050 "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
1051 xpre, VERSION, xpost
sewardj738856f2009-07-15 14:48:32 +00001052 );
sewardj45f4e7c2005-09-27 19:20:21 +00001053
njnf3977a32009-08-04 00:27:56 +00001054 // Print the command line. At one point we wrapped at 80 chars and
1055 // printed a '\' as a line joiner, but that makes it hard to cut and
1056 // paste the command line (because of the "==pid==" prefixes), so we now
1057 // favour utility and simplicity over aesthetics.
1058 umsg_or_xml("%sCommand: ", xpre);
njn53162bf2009-07-29 23:34:49 +00001059 if (VG_(args_the_exename))
njnf8a11cf2009-08-02 23:03:06 +00001060 umsg_or_xml_arg(VG_(args_the_exename), umsg_or_xml);
njn53162bf2009-07-29 23:34:49 +00001061 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1062 HChar* s = *(HChar**)VG_(indexXA)( VG_(args_for_client), i );
njnf8a11cf2009-08-02 23:03:06 +00001063 umsg_or_xml(" ");
1064 umsg_or_xml_arg(s, umsg_or_xml);
njn53162bf2009-07-29 23:34:49 +00001065 }
njnf3977a32009-08-04 00:27:56 +00001066 umsg_or_xml("%s\n", xpost);
njn53162bf2009-07-29 23:34:49 +00001067
sewardjd7bddad2005-06-13 16:48:32 +00001068 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001069 VG_(printf_xml)("</preamble>\n");
njnd04b7c62002-10-03 14:05:52 +00001070 }
1071
njnb6267bd2009-08-12 00:14:16 +00001072 // Print the parent PID, and other stuff, if necessary.
sewardj45f4e7c2005-09-27 19:20:21 +00001073 if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
njn305dc002009-07-30 23:36:43 +00001074 VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
sewardj4cf05692002-10-27 20:28:29 +00001075 }
sewardj71bc3cb2005-05-19 00:25:45 +00001076 else
1077 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00001078 VG_(printf_xml)("\n");
1079 VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
1080 VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
1081 VG_(printf_xml_no_f_c)("<tool>%t</tool>\n", toolname);
1082 if (xml_fname_unexpanded)
1083 print_file_vars(xml_fname_unexpanded);
sewardj768db0e2005-07-19 14:18:56 +00001084 if (VG_(clo_xml_user_comment)) {
1085 /* Note: the user comment itself is XML and is therefore to
1086 be passed through verbatim (%s) rather than escaped
1087 (%t). */
sewardj738856f2009-07-15 14:48:32 +00001088 VG_(printf_xml)("<usercomment>%s</usercomment>\n",
1089 VG_(clo_xml_user_comment));
sewardj768db0e2005-07-19 14:18:56 +00001090 }
sewardj738856f2009-07-15 14:48:32 +00001091 VG_(printf_xml)("\n");
1092 VG_(printf_xml)("<args>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001093
sewardj738856f2009-07-15 14:48:32 +00001094 VG_(printf_xml)(" <vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001095 if (VG_(name_of_launcher))
sewardj738856f2009-07-15 14:48:32 +00001096 VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
1097 VG_(name_of_launcher));
sewardj125fd4f2007-03-08 19:56:14 +00001098 else
njnb1cc5d62010-07-06 04:05:23 +00001099 VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
1100 "(launcher name unknown)");
sewardj14c7cc52007-02-25 15:08:24 +00001101 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
sewardj738856f2009-07-15 14:48:32 +00001102 VG_(printf_xml_no_f_c)(
1103 " <arg>%t</arg>\n",
1104 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1105 );
sewardjb8a3dac2005-07-19 12:39:11 +00001106 }
sewardj738856f2009-07-15 14:48:32 +00001107 VG_(printf_xml)(" </vargv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001108
sewardj738856f2009-07-15 14:48:32 +00001109 VG_(printf_xml)(" <argv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001110 if (VG_(args_the_exename))
sewardj738856f2009-07-15 14:48:32 +00001111 VG_(printf_xml_no_f_c)(" <exe>%t</exe>\n",
1112 VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001113 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
sewardj738856f2009-07-15 14:48:32 +00001114 VG_(printf_xml_no_f_c)(
1115 " <arg>%t</arg>\n",
1116 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1117 );
sewardj8665d8e2005-06-01 17:35:23 +00001118 }
sewardj738856f2009-07-15 14:48:32 +00001119 VG_(printf_xml)(" </argv>\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001120
sewardj738856f2009-07-15 14:48:32 +00001121 VG_(printf_xml)("</args>\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001122 }
sewardj4cf05692002-10-27 20:28:29 +00001123
njnb6267bd2009-08-12 00:14:16 +00001124 // Last thing in the preamble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00001125 if (VG_(clo_xml))
1126 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00001127 else if (VG_(clo_verbosity) > 0)
1128 VG_(umsg)("\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001129
sewardjde4a1d02002-03-22 01:27:54 +00001130 if (VG_(clo_verbosity) > 1) {
sewardj92645592005-07-23 09:18:34 +00001131 SysRes fd;
sewardj1f0bbc72005-11-16 03:51:02 +00001132 VexArch vex_arch;
1133 VexArchInfo vex_archinfo;
sewardj45f4e7c2005-09-27 19:20:21 +00001134 if (!logging_to_fd)
sewardj738856f2009-07-15 14:48:32 +00001135 VG_(message)(Vg_DebugMsg, "\n");
njna3311642009-08-10 01:29:14 +00001136 VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
sewardj14c7cc52007-02-25 15:08:24 +00001137 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
1138 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001139 " %s\n",
sewardj14c7cc52007-02-25 15:08:24 +00001140 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
sewardjde4a1d02002-03-22 01:27:54 +00001141 }
nethercotea70f7352004-04-18 12:08:46 +00001142
sewardj738856f2009-07-15 14:48:32 +00001143 VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
nethercotea70f7352004-04-18 12:08:46 +00001144 fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
njncda2f0f2009-05-18 02:12:08 +00001145 if (sr_isError(fd)) {
sewardj738856f2009-07-15 14:48:32 +00001146 VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
nethercotea70f7352004-04-18 12:08:46 +00001147 } else {
sewardj71bc3cb2005-05-19 00:25:45 +00001148# define BUF_LEN 256
nethercotea70f7352004-04-18 12:08:46 +00001149 Char version_buf[BUF_LEN];
njnf3977a32009-08-04 00:27:56 +00001150 Int n = VG_(read) ( sr_Res(fd), version_buf, BUF_LEN );
1151 vg_assert(n <= BUF_LEN);
1152 if (n > 0) {
1153 version_buf[n-1] = '\0';
sewardj738856f2009-07-15 14:48:32 +00001154 VG_(message)(Vg_DebugMsg, " %s\n", version_buf);
nethercotea70f7352004-04-18 12:08:46 +00001155 } else {
sewardj738856f2009-07-15 14:48:32 +00001156 VG_(message)(Vg_DebugMsg, " (empty?)\n");
nethercotea70f7352004-04-18 12:08:46 +00001157 }
njncda2f0f2009-05-18 02:12:08 +00001158 VG_(close)(sr_Res(fd));
sewardj71bc3cb2005-05-19 00:25:45 +00001159# undef BUF_LEN
nethercotea70f7352004-04-18 12:08:46 +00001160 }
sewardj1f0bbc72005-11-16 03:51:02 +00001161
1162 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001163 VG_(message)(
1164 Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001165 "Arch and hwcaps: %s, %s\n",
sewardje3121f32006-01-27 21:23:23 +00001166 LibVEX_ppVexArch ( vex_arch ),
1167 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1168 );
sewardje66f2e02006-12-30 17:45:08 +00001169 VG_(message)(
1170 Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00001171 "Page sizes: currently %d, max supported %d\n",
sewardje66f2e02006-12-30 17:45:08 +00001172 (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
1173 );
sewardj738856f2009-07-15 14:48:32 +00001174 VG_(message)(Vg_DebugMsg,
1175 "Valgrind library directory: %s\n", VG_(libdir));
sewardjde4a1d02002-03-22 01:27:54 +00001176 }
nethercotef6a1d502004-08-09 12:21:57 +00001177}
1178
sewardjde4a1d02002-03-22 01:27:54 +00001179
nethercote71980f02004-01-24 18:18:54 +00001180/*====================================================================*/
1181/*=== File descriptor setup ===*/
1182/*====================================================================*/
1183
sewardj5f229e22005-09-28 01:36:01 +00001184/* Number of file descriptors that Valgrind tries to reserve for
1185 it's own use - just a small constant. */
1186#define N_RESERVED_FDS (10)
1187
nethercote71980f02004-01-24 18:18:54 +00001188static void setup_file_descriptors(void)
1189{
1190 struct vki_rlimit rl;
sewardj17c11042006-10-15 01:26:40 +00001191 Bool show = False;
nethercote71980f02004-01-24 18:18:54 +00001192
1193 /* Get the current file descriptor limits. */
1194 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
1195 rl.rlim_cur = 1024;
1196 rl.rlim_max = 1024;
1197 }
1198
njnf76d27a2009-05-28 01:53:07 +00001199# if defined(VGO_darwin)
1200 /* Darwin lies. It reports file max as RLIM_INFINITY but
1201 silently disallows anything bigger than 10240. */
1202 if (rl.rlim_cur >= 10240 && rl.rlim_max == 0x7fffffffffffffffULL) {
1203 rl.rlim_max = 10240;
1204 }
1205# endif
1206
sewardj17c11042006-10-15 01:26:40 +00001207 if (show)
njn8a7b41b2007-09-23 00:51:24 +00001208 VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001209 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001210
1211# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1212 /* I don't know why this kludge is needed; however if rl.rlim_cur
1213 is RLIM_INFINITY, then VG_(safe_fd)'s attempts using VG_(fcntl)
1214 to lift V's file descriptors above the threshold RLIM_INFINITY -
1215 N_RESERVED_FDS fail. So just use a relatively conservative
1216 value in this case. */
1217 if (rl.rlim_cur > 1024)
1218 rl.rlim_cur = 1024;
1219# endif
1220
nethercote71980f02004-01-24 18:18:54 +00001221 /* Work out where to move the soft limit to. */
njn14319cc2005-03-13 06:26:22 +00001222 if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
1223 rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001224 } else {
1225 rl.rlim_cur = rl.rlim_max;
1226 }
1227
1228 /* Reserve some file descriptors for our use. */
njn14319cc2005-03-13 06:26:22 +00001229 VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
1230 VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
nethercote71980f02004-01-24 18:18:54 +00001231
1232 /* Update the soft limit. */
1233 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
1234
sewardj17c11042006-10-15 01:26:40 +00001235 if (show) {
njn8a7b41b2007-09-23 00:51:24 +00001236 VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
sewardja8ffda62008-07-18 18:23:24 +00001237 (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
sewardj17c11042006-10-15 01:26:40 +00001238 VG_(printf)("fd limits: guest : cur %u max %u\n",
1239 VG_(fd_soft_limit), VG_(fd_hard_limit));
1240 }
1241
sewardj45f4e7c2005-09-27 19:20:21 +00001242 if (VG_(cl_exec_fd) != -1)
1243 VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
nethercote71980f02004-01-24 18:18:54 +00001244}
1245
sewardjde4a1d02002-03-22 01:27:54 +00001246
njn2da73352005-06-18 01:35:16 +00001247/*====================================================================*/
njn2025cf92005-06-26 20:44:48 +00001248/*=== BB profiling ===*/
1249/*====================================================================*/
1250
1251static
1252void show_BB_profile ( BBProfEntry tops[], UInt n_tops, ULong score_total )
1253{
1254 ULong score_cumul, score_here;
1255 Char buf_cumul[10], buf_here[10];
1256 Char name[64];
1257 Int r;
1258
1259 VG_(printf)("\n");
1260 VG_(printf)("-----------------------------------------------------------\n");
1261 VG_(printf)("--- BEGIN BB Profile (summary of scores) ---\n");
1262 VG_(printf)("-----------------------------------------------------------\n");
1263 VG_(printf)("\n");
1264
1265 VG_(printf)("Total score = %lld\n\n", score_total);
1266
1267 score_cumul = 0;
1268 for (r = 0; r < n_tops; r++) {
1269 if (tops[r].addr == 0)
1270 continue;
1271 name[0] = 0;
1272 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1273 name[63] = 0;
1274 score_here = tops[r].score;
1275 score_cumul += score_here;
1276 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1277 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1278 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1279 r,
1280 score_cumul, buf_cumul,
1281 score_here, buf_here, tops[r].addr, name );
1282 }
1283
1284 VG_(printf)("\n");
1285 VG_(printf)("-----------------------------------------------------------\n");
1286 VG_(printf)("--- BB Profile (BB details) ---\n");
1287 VG_(printf)("-----------------------------------------------------------\n");
1288 VG_(printf)("\n");
1289
1290 score_cumul = 0;
1291 for (r = 0; r < n_tops; r++) {
1292 if (tops[r].addr == 0)
1293 continue;
1294 name[0] = 0;
1295 VG_(get_fnname_w_offset)(tops[r].addr, name, 64);
1296 name[63] = 0;
1297 score_here = tops[r].score;
1298 score_cumul += score_here;
1299 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul);
1300 VG_(percentify)(score_here, score_total, 2, 6, buf_here);
1301 VG_(printf)("\n");
1302 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin BB rank %d "
1303 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1304 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n",
1305 r,
1306 score_cumul, buf_cumul,
1307 score_here, buf_here, tops[r].addr, name );
1308 VG_(printf)("\n");
sewardjbcccbc02007-04-09 22:24:57 +00001309 VG_(discard_translations)(tops[r].addr, 1, "bb profile");
sewardj0ec07f32006-01-12 12:32:32 +00001310 VG_(translate)(0, tops[r].addr, True, VG_(clo_profile_flags), 0, True);
njn2025cf92005-06-26 20:44:48 +00001311 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= end BB rank %d "
1312 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r);
1313 }
1314
1315 VG_(printf)("\n");
1316 VG_(printf)("-----------------------------------------------------------\n");
1317 VG_(printf)("--- END BB Profile ---\n");
1318 VG_(printf)("-----------------------------------------------------------\n");
1319 VG_(printf)("\n");
1320}
1321
1322
1323/*====================================================================*/
nethercote71980f02004-01-24 18:18:54 +00001324/*=== main() ===*/
1325/*====================================================================*/
1326
sewardjfdf91b42005-09-28 00:53:09 +00001327/* When main() is entered, we should be on the following stack, not
1328 the one the kernel gave us. We will run on this stack until
1329 simulation of the root thread is started, at which point a transfer
1330 is made to a dynamically allocated stack. This is for the sake of
1331 uniform overflow detection for all Valgrind threads. This is
1332 marked global even though it isn't, because assembly code below
1333 needs to reference the name. */
1334
1335/*static*/ VgStack VG_(interim_stack);
1336
sewardjf9d2f9b2006-11-17 20:00:57 +00001337/* These are the structures used to hold info for creating the initial
1338 client image.
1339
1340 'iicii' mostly holds important register state present at system
1341 startup (_start_valgrind). valgrind_main() then fills in the rest
1342 of it and passes it to VG_(ii_create_image)(). That produces
1343 'iifii', which is later handed to VG_(ii_finalise_image). */
1344
1345/* In all OS-instantiations, the_iicii has a field .sp_at_startup.
1346 This should get some address inside the stack on which we gained
sewardjfdf91b42005-09-28 00:53:09 +00001347 control (eg, it could be the SP at startup). It doesn't matter
1348 exactly where in the stack it is. This value is passed to the
sewardjf9d2f9b2006-11-17 20:00:57 +00001349 address space manager at startup. On Linux, aspacem then uses it
1350 to identify the initial stack segment and hence the upper end of
1351 the usable address space. */
sewardjfdf91b42005-09-28 00:53:09 +00001352
sewardjf9d2f9b2006-11-17 20:00:57 +00001353static IICreateImageInfo the_iicii;
1354static IIFinaliseImageInfo the_iifii;
1355
sewardjfdf91b42005-09-28 00:53:09 +00001356
sewardj9c606bd2008-09-18 18:12:50 +00001357/* A simple pair structure, used for conveying debuginfo handles to
1358 calls to VG_TRACK(new_mem_startup, ...). */
1359typedef struct { Addr a; ULong ull; } Addr_n_ULong;
1360
1361
sewardj1ae3f3a2005-09-28 10:47:38 +00001362/* --- Forwards decls to do with shutdown --- */
1363
1364static void final_tidyup(ThreadId tid);
1365
1366/* Do everything which needs doing when the last thread exits */
1367static
1368void shutdown_actions_NORETURN( ThreadId tid,
1369 VgSchedReturnCode tids_schedretcode );
1370
1371/* --- end of Forwards decls to do with shutdown --- */
sewardjfdf91b42005-09-28 00:53:09 +00001372
1373
sewardjf9d2f9b2006-11-17 20:00:57 +00001374/* By the time we get to valgrind_main, the_iicii should already have
1375 been filled in with any important details as required by whatever
1376 OS we have been built for.
1377*/
sewardj17c11042006-10-15 01:26:40 +00001378static
sewardjf9d2f9b2006-11-17 20:00:57 +00001379Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
nethercote71980f02004-01-24 18:18:54 +00001380{
sewardj13247ca2005-12-30 22:52:20 +00001381 HChar* toolname = "memcheck"; // default to Memcheck
sewardj13247ca2005-12-30 22:52:20 +00001382 Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
sewardjde764e82007-11-09 23:13:22 +00001383 ThreadId tid_main = VG_INVALID_THREADID;
sewardj738856f2009-07-15 14:48:32 +00001384 Bool logging_to_fd = False;
1385 Char* xml_fname_unexpanded = NULL;
sewardj45f4e7c2005-09-27 19:20:21 +00001386 Int loglevel, i;
nethercote73b526f2004-10-31 18:48:21 +00001387 struct vki_rlimit zero = { 0, 0 };
sewardj9c606bd2008-09-18 18:12:50 +00001388 XArray* addr2dihandle = NULL;
sewardj17c11042006-10-15 01:26:40 +00001389
nethercote71980f02004-01-24 18:18:54 +00001390 //============================================================
nethercote71980f02004-01-24 18:18:54 +00001391 //
sewardj45f4e7c2005-09-27 19:20:21 +00001392 // Nb: startup is complex. Prerequisites are shown at every step.
nethercote71980f02004-01-24 18:18:54 +00001393 // *** Be very careful when messing with the order ***
sewardj45f4e7c2005-09-27 19:20:21 +00001394 //
1395 // The first order of business is to get debug logging, the address
1396 // space manager and the dynamic memory manager up and running.
1397 // Once that's done, we can relax a bit.
1398 //
nethercote71980f02004-01-24 18:18:54 +00001399 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001400
1401 /* This is needed to make VG_(getenv) usable early. */
1402 VG_(client_envp) = (Char**)envp;
nethercote71980f02004-01-24 18:18:54 +00001403
sewardj1cf558c2005-04-25 01:36:56 +00001404 //--------------------------------------------------------------
njnf76d27a2009-05-28 01:53:07 +00001405 // Start up Mach kernel interface, if any
1406 // p: none
1407 //--------------------------------------------------------------
1408# if defined(VGO_darwin)
1409 VG_(mach_init)();
1410# endif
1411
1412 //--------------------------------------------------------------
sewardj1cf558c2005-04-25 01:36:56 +00001413 // Start up the logging mechanism
1414 // p: none
1415 //--------------------------------------------------------------
1416 /* Start the debugging-log system ASAP. First find out how many
njn83df0b62009-02-25 01:01:05 +00001417 "-d"s were specified. This is a pre-scan of the command line. Also
1418 get --profile-heap=yes which is needed by the time we start up dynamic
1419 memory management. */
sewardj1cf558c2005-04-25 01:36:56 +00001420 loglevel = 0;
1421 for (i = 1; i < argc; i++) {
njn83df0b62009-02-25 01:01:05 +00001422 if (argv[i][0] != '-') break;
1423 if VG_STREQ(argv[i], "--") break;
1424 if VG_STREQ(argv[i], "-d") loglevel++;
1425 if VG_BOOL_CLO(argv[i], "--profile-heap", VG_(clo_profile_heap)) {}
sewardj1cf558c2005-04-25 01:36:56 +00001426 }
1427
1428 /* ... and start the debug logger. Now we can safely emit logging
1429 messages all through startup. */
sewardj10759312005-05-30 23:52:47 +00001430 VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
sewardj45f4e7c2005-09-27 19:20:21 +00001431 VG_(debugLog)(1, "main", "Welcome to Valgrind version "
1432 VERSION " debug logging\n");
1433
1434 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001435 // AIX5 only: register the system call numbers
1436 // p: logging
1437 // p: that the initial few syscall numbers stated in the
1438 // bootblock have been installed (else we can't
1439 // open/read/close).
1440 //--------------------------------------------------------------
1441# if defined(VGO_aix5)
1442 VG_(debugLog)(1, "main", "aix5: registering syscalls ..\n");
1443 { UChar sysent_name[50];
1444 SysRes fd;
1445 Bool ok;
1446 Int n_unregd, sysent_used = 0;
1447 prsysent_t* sysent_hdr;
1448
1449 VG_(sprintf)(sysent_name, "/proc/%d/sysent", VG_(getpid)());
1450 fd = VG_(open)(sysent_name, VKI_O_RDONLY, 0);
1451 if (fd.isError)
1452 VG_(err_config_error)("aix5: can't open /proc/<pid>/sysent");
1453
1454 sysent_used = VG_(read)(fd.res, aix5_sysent_buf, VG_AIX5_SYSENT_SIZE);
1455 if (sysent_used < 0)
1456 VG_(err_config_error)("aix5: error reading /proc/<pid>/sysent");
1457 if (sysent_used >= VG_AIX5_SYSENT_SIZE)
1458 VG_(err_config_error)("aix5: VG_AIX5_SYSENT_SIZE is too low; "
1459 "increase and recompile");
1460 VG_(close)(fd.res);
1461
1462 vg_assert(sysent_used > 0 && sysent_used < VG_AIX5_SYSENT_SIZE);
1463
1464 sysent_hdr = (prsysent_t*)&aix5_sysent_buf[0];
1465
1466 n_unregd = 0;
1467 for (i = 0; i < sysent_hdr->pr_nsyscalls; i++) {
1468 UChar* name = &aix5_sysent_buf[ sysent_hdr
1469 ->pr_syscall[i].pr_nameoff ];
1470 UInt nmbr = sysent_hdr->pr_syscall[i].pr_number;
1471 VG_(debugLog)(3, "main", "aix5: bind syscall %d to \"%s\"\n",
1472 nmbr, name);
1473 ok = VG_(aix5_register_syscall)(nmbr, name);
1474 if (!ok)
1475 n_unregd++;
1476 if (!ok)
1477 VG_(debugLog)(3, "main",
1478 "aix5: bind FAILED: %d to \"%s\"\n",
1479 nmbr, name);
1480 }
1481 VG_(debugLog)(1, "main", "aix5: .. %d syscalls known, %d unknown\n",
1482 sysent_hdr->pr_nsyscalls - n_unregd, n_unregd );
1483 VG_(debugLog)(1, "main", "aix5: __NR_AIX5_FAKE_SIGRETURN = %d\n",
1484 __NR_AIX5_FAKE_SIGRETURN );
1485 }
1486# endif
1487
1488 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001489 // Ensure we're on a plausible stack.
1490 // p: logging
1491 //--------------------------------------------------------------
1492 VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
sewardjfdf91b42005-09-28 00:53:09 +00001493 { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
1494 HChar* limHi = limLo + sizeof(VG_(interim_stack));
sewardj45f4e7c2005-09-27 19:20:21 +00001495 HChar* aLocal = (HChar*)&zero; /* any auto local will do */
1496 if (aLocal < limLo || aLocal >= limHi) {
1497 /* something's wrong. Stop. */
1498 VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
1499 limLo, limHi, aLocal );
1500 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1501 "Initial stack switched failed.\n");
1502 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1503 VG_(exit)(1);
1504 }
1505 }
1506
1507 //--------------------------------------------------------------
1508 // Ensure we have a plausible pointer to the stack on which
1509 // we gained control (not the current stack!)
1510 // p: logging
1511 //--------------------------------------------------------------
1512 VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
sewardjf9d2f9b2006-11-17 20:00:57 +00001513 if (the_iicii.sp_at_startup == 0) {
sewardj45f4e7c2005-09-27 19:20:21 +00001514 VG_(debugLog)(0, "main", "Valgrind: FATAL: "
1515 "Initial stack was not noted.\n");
1516 VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
1517 VG_(exit)(1);
1518 }
1519
1520 //--------------------------------------------------------------
1521 // Start up the address space manager, and determine the
1522 // approximate location of the client's stack
njnea2d6fd2010-07-01 00:20:20 +00001523 // p: logging, plausible-stack
sewardj45f4e7c2005-09-27 19:20:21 +00001524 //--------------------------------------------------------------
1525 VG_(debugLog)(1, "main", "Starting the address space manager\n");
sewardje66f2e02006-12-30 17:45:08 +00001526 vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536);
1527 vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536);
1528 vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
1529 vg_assert(VKI_PAGE_SIZE == (1 << VKI_PAGE_SHIFT));
1530 vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
sewardjf9d2f9b2006-11-17 20:00:57 +00001531 the_iicii.clstack_top = VG_(am_startup)( the_iicii.sp_at_startup );
sewardj45f4e7c2005-09-27 19:20:21 +00001532 VG_(debugLog)(1, "main", "Address space manager is running\n");
1533
1534 //--------------------------------------------------------------
1535 // Start up the dynamic memory manager
1536 // p: address space management
njn83df0b62009-02-25 01:01:05 +00001537 // p: getting --profile-heap
sewardj45f4e7c2005-09-27 19:20:21 +00001538 // In fact m_mallocfree is self-initialising, so there's no
1539 // initialisation call to do. Instead, try a simple malloc/
1540 // free pair right now to check that nothing is broken.
1541 //--------------------------------------------------------------
1542 VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
sewardj9c606bd2008-09-18 18:12:50 +00001543 { void* p = VG_(malloc)( "main.vm.1", 12345 );
sewardj45f4e7c2005-09-27 19:20:21 +00001544 if (p) VG_(free)( p );
1545 }
1546 VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
sewardj1cf558c2005-04-25 01:36:56 +00001547
nethercotef4928da2004-06-15 10:54:40 +00001548 //============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001549 //
1550 // Dynamic memory management is now available.
1551 //
nethercotef4928da2004-06-15 10:54:40 +00001552 //============================================================
1553
sewardj45f4e7c2005-09-27 19:20:21 +00001554 //--------------------------------------------------------------
sewardjf98e1c02008-10-25 16:22:41 +00001555 // Initialise m_debuginfo
1556 // p: dynamic memory allocation
1557 VG_(debugLog)(1, "main", "Initialise m_debuginfo\n");
1558 VG_(di_initialise)();
1559
1560 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001561 // Look for alternative libdir
1562 { HChar *cp = VG_(getenv)(VALGRIND_LIB);
1563 if (cp != NULL)
1564 VG_(libdir) = cp;
njncde90d32009-07-22 22:41:38 +00001565 VG_(debugLog)(1, "main", "VG_(libdir) = %s\n", VG_(libdir));
sewardj45f4e7c2005-09-27 19:20:21 +00001566 }
1567
1568 //--------------------------------------------------------------
1569 // Extract the launcher name from the environment.
njna842d792009-05-21 01:15:18 +00001570 VG_(debugLog)(1, "main", "Getting launcher's name ...\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001571 VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
1572 if (VG_(name_of_launcher) == NULL) {
1573 VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
1574 VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
1575 VG_(exit)(1);
1576 }
njna842d792009-05-21 01:15:18 +00001577 VG_(debugLog)(1, "main", "... %s\n", VG_(name_of_launcher));
sewardj45f4e7c2005-09-27 19:20:21 +00001578
1579 //--------------------------------------------------------------
fitzhardingeb50068f2004-02-24 23:42:55 +00001580 // Get the current process datasize rlimit, and set it to zero.
1581 // This prevents any internal uses of brk() from having any effect.
1582 // We remember the old value so we can restore it on exec, so that
1583 // child processes will have a reasonable brk value.
1584 VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1585 zero.rlim_max = VG_(client_rlimit_data).rlim_max;
1586 VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
thughesc37184f2004-09-11 14:16:57 +00001587
1588 // Get the current process stack rlimit.
1589 VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
1590
sewardje2d1e672005-11-12 23:10:48 +00001591 //--------------------------------------------------------------
1592 // Figure out what sort of CPU we're on, and whether it is
1593 // able to run V.
1594 VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
1595 { VexArch vex_arch;
1596 VexArchInfo vex_archinfo;
1597 Bool ok = VG_(machine_get_hwcaps)();
1598 if (!ok) {
1599 VG_(printf)("\n");
1600 VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
1601 VG_(printf)(" Supported CPUs are:\n");
1602 VG_(printf)(" * x86 (practically any; Pentium-I or above), "
1603 "AMD Athlon or above)\n");
1604 VG_(printf)(" * AMD Athlon64/Opteron\n");
1605 VG_(printf)(" * PowerPC (most; ppc405 and above)\n");
1606 VG_(printf)("\n");
1607 VG_(exit)(1);
1608 }
1609 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
sewardje3121f32006-01-27 21:23:23 +00001610 VG_(debugLog)(
1611 1, "main", "... arch = %s, hwcaps = %s\n",
1612 LibVEX_ppVexArch ( vex_arch ),
1613 LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
1614 );
sewardje2d1e672005-11-12 23:10:48 +00001615 }
1616
sewardj198f34f2007-07-09 23:13:07 +00001617 //--------------------------------------------------------------
1618 // Record the working directory at startup
1619 // p: none (Linux), getenv and sys_getpid work (AIX)
1620 VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
1621 { Bool ok = VG_(record_startup_wd)();
1622 if (!ok)
1623 VG_(err_config_error)( "Can't establish current working "
1624 "directory at startup");
1625 }
1626 { Char buf[VKI_PATH_MAX+1];
1627 Bool ok = VG_(get_startup_wd)( buf, sizeof(buf) );
1628 vg_assert(ok);
1629 buf[VKI_PATH_MAX] = 0;
1630 VG_(debugLog)(1, "main", "... %s\n", buf );
1631 }
1632
sewardj45f4e7c2005-09-27 19:20:21 +00001633 //============================================================
1634 // Command line argument handling order:
1635 // * If --help/--help-debug are present, show usage message
1636 // (including the tool-specific usage)
1637 // * (If no --tool option given, default to Memcheck)
1638 // * Then, if client is missing, abort with error msg
1639 // * Then, if any cmdline args are bad, abort with error msg
1640 //============================================================
1641
1642 //--------------------------------------------------------------
1643 // Split up argv into: C args, V args, V extra args, and exename.
1644 // p: dynamic memory allocation
1645 //--------------------------------------------------------------
1646 VG_(debugLog)(1, "main", "Split up command line\n");
1647 VG_(split_up_argv)( argc, argv );
sewardj14c7cc52007-02-25 15:08:24 +00001648 vg_assert( VG_(args_for_valgrind) );
1649 vg_assert( VG_(args_for_client) );
sewardj45f4e7c2005-09-27 19:20:21 +00001650 if (0) {
sewardj14c7cc52007-02-25 15:08:24 +00001651 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
1652 VG_(printf)(
1653 "varg %s\n",
1654 * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
1655 );
sewardj45f4e7c2005-09-27 19:20:21 +00001656 VG_(printf)(" exe %s\n", VG_(args_the_exename));
sewardj14c7cc52007-02-25 15:08:24 +00001657 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
1658 VG_(printf)(
1659 "carg %s\n",
1660 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
1661 );
nethercote71980f02004-01-24 18:18:54 +00001662 }
1663
sewardj948a6fc2007-03-19 18:38:55 +00001664# if defined(VGO_aix5)
1665 /* Tolerate ptraced-based launchers. They can't run 'no program'
1666 if the user types "valgrind --help", so they run a do-nothing
1667 program $prefix/bin/no_op_client_for_valgrind, and we catch that
1668 here and turn it the exe name back into NULL. Then --help,
1669 --version etc work as they should. */
1670 if (VG_(args_the_exename)
1671 && VG_(strstr)( VG_(args_the_exename), "/no_op_client_for_valgrind" )) {
1672 VG_(args_the_exename) = NULL;
1673 }
1674# endif
1675
nethercote71980f02004-01-24 18:18:54 +00001676 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001677 // Extract tool name and whether help has been requested.
1678 // Note we can't print the help message yet, even if requested,
1679 // because the tool has not been initialised.
1680 // p: split_up_argv [for VG_(args_for_valgrind)]
nethercote71980f02004-01-24 18:18:54 +00001681 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001682 VG_(debugLog)(1, "main",
1683 "(early_) Process Valgrind's command line options\n");
1684 early_process_cmd_line_options(&need_help, &toolname);
nethercote71980f02004-01-24 18:18:54 +00001685
sewardj45f4e7c2005-09-27 19:20:21 +00001686 // Set default vex control params
1687 LibVEX_default_VexControl(& VG_(clo_vex_control));
nethercote71980f02004-01-24 18:18:54 +00001688
1689 //--------------------------------------------------------------
1690 // Load client executable, finding in $PATH if necessary
njn83df0b62009-02-25 01:01:05 +00001691 // p: early_process_cmd_line_options() [for 'exec', 'need_help',
1692 // clo_max_stackframe,
1693 // clo_main_stacksize]
sewardj95d86c02007-12-18 01:49:23 +00001694 // p: layout_remaining_space [so there's space]
sewardj17c11042006-10-15 01:26:40 +00001695 //
nethercote71980f02004-01-24 18:18:54 +00001696 // Set up client's environment
sewardj95d86c02007-12-18 01:49:23 +00001697 // p: set-libdir [for VG_(libdir)]
1698 // p: early_process_cmd_line_options [for toolname]
sewardj17c11042006-10-15 01:26:40 +00001699 //
nethercote5ee67ca2004-06-22 14:00:09 +00001700 // Setup client stack, eip, and VG_(client_arg[cv])
nethercote71980f02004-01-24 18:18:54 +00001701 // p: load_client() [for 'info']
1702 // p: fix_environment() [for 'env']
sewardj17c11042006-10-15 01:26:40 +00001703 //
sewardj45f4e7c2005-09-27 19:20:21 +00001704 // Setup client data (brk) segment. Initially a 1-page segment
1705 // which abuts a shrinkable reservation.
1706 // p: load_client() [for 'info' and hence VG_(brk_base)]
sewardjf9d2f9b2006-11-17 20:00:57 +00001707 //
1708 // p: _start_in_C (for zeroing out the_iicii and putting some
1709 // initial values into it)
sewardj45f4e7c2005-09-27 19:20:21 +00001710 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00001711 if (!need_help) {
sewardjf9d2f9b2006-11-17 20:00:57 +00001712 VG_(debugLog)(1, "main", "Create initial image\n");
1713
njnf76d27a2009-05-28 01:53:07 +00001714# if defined(VGO_linux) || defined(VGO_darwin)
sewardjf9d2f9b2006-11-17 20:00:57 +00001715 the_iicii.argv = argv;
1716 the_iicii.envp = envp;
1717 the_iicii.toolname = toolname;
1718# elif defined(VGO_aix5)
1719 /* the_iicii.intregs37 already set up */
1720 /* the_iicii.bootblock already set up */
1721 /* the_iicii.adler32_exp already set up */
1722 /* the_iicii.sp_at_startup is irrelevant */
1723 /* the_iicii.clstack_top is irrelevant */
1724 the_iicii.toolname = toolname;
1725# else
njna842d792009-05-21 01:15:18 +00001726# error "Unknown platform"
sewardjf9d2f9b2006-11-17 20:00:57 +00001727# endif
1728
sewardjdc2f79e2007-12-22 14:14:04 +00001729 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001730 the_iifii = VG_(ii_create_image)( the_iicii );
1731
sewardj17c11042006-10-15 01:26:40 +00001732# if defined(VGO_aix5)
sewardj17c11042006-10-15 01:26:40 +00001733 /* Tell aspacem where the initial client stack is, so that it
1734 can later produce a faked-up NSegment in response to
1735 VG_(am_find_nsegment) for that address range, if asked. */
sewardjdc2f79e2007-12-22 14:14:04 +00001736 /* NOTE: this call reads VG_(clo_main_stacksize). */
sewardjf9d2f9b2006-11-17 20:00:57 +00001737 VG_(am_aix5_set_initial_client_sp)( the_iifii.initial_client_SP );
1738 /* Now have a look at said fake segment, so we can find out
1739 the size of it. */
1740 { SizeT sz;
1741 NSegment const* seg
1742 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
1743 vg_assert(seg);
1744 sz = seg->end - seg->start + 1;
sewardjc9d33832007-12-22 14:12:42 +00001745 vg_assert(sz >= 0 && sz <= (256+1)*1024*1024); /* stay sane */
sewardjf9d2f9b2006-11-17 20:00:57 +00001746 the_iifii.clstack_max_size = sz;
1747 }
sewardj17c11042006-10-15 01:26:40 +00001748# endif
sewardj45f4e7c2005-09-27 19:20:21 +00001749 }
nethercote71980f02004-01-24 18:18:54 +00001750
1751 //==============================================================
sewardj45f4e7c2005-09-27 19:20:21 +00001752 //
1753 // Finished loading/setting up the client address space.
1754 //
nethercote71980f02004-01-24 18:18:54 +00001755 //==============================================================
1756
1757 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001758 // setup file descriptors
1759 // p: n/a
1760 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001761 VG_(debugLog)(1, "main", "Setup file descriptors\n");
nethercote71980f02004-01-24 18:18:54 +00001762 setup_file_descriptors();
1763
1764 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001765 // create the fake /proc/<pid>/cmdline file and then unlink it,
1766 // but hold onto the fd, so we can hand it out to the client
1767 // when it tries to open /proc/<pid>/cmdline for itself.
1768 // p: setup file descriptors
nethercotec314eba2004-07-15 12:59:41 +00001769 //--------------------------------------------------------------
bart9b533f82009-08-25 20:15:41 +00001770#if !defined(VGO_linux)
1771 // client shouldn't be using /proc!
1772 VG_(cl_cmdline_fd) = -1;
1773#else
1774 if (!need_help) {
1775 HChar buf[50], buf2[50+64];
1776 HChar nul[1];
1777 Int fd, r;
barta3054f52010-06-14 18:12:56 +00001778 const HChar* exename;
nethercotec314eba2004-07-15 12:59:41 +00001779
bart9b533f82009-08-25 20:15:41 +00001780 VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
sewardj45f4e7c2005-09-27 19:20:21 +00001781
bart9b533f82009-08-25 20:15:41 +00001782 VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
1783 fd = VG_(mkstemp)( buf, buf2 );
1784 if (fd == -1)
1785 VG_(err_config_error)("Can't create client cmdline file in /tmp.");
sewardj45f4e7c2005-09-27 19:20:21 +00001786
bart9b533f82009-08-25 20:15:41 +00001787 nul[0] = 0;
1788 exename = VG_(args_the_exename) ? VG_(args_the_exename)
1789 : "unknown_exename";
1790 VG_(write)(fd, VG_(args_the_exename),
1791 VG_(strlen)( VG_(args_the_exename) ));
1792 VG_(write)(fd, nul, 1);
1793
1794 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
1795 HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
1796 VG_(write)(fd, arg, VG_(strlen)( arg ));
sewardj45f4e7c2005-09-27 19:20:21 +00001797 VG_(write)(fd, nul, 1);
1798 }
bart9b533f82009-08-25 20:15:41 +00001799
1800 /* Don't bother to seek the file back to the start; instead do
1801 it every time a copy of it is given out (by PRE(sys_open)).
1802 That is probably more robust across fork() etc. */
1803
1804 /* Now delete it, but hang on to the fd. */
1805 r = VG_(unlink)( buf2 );
1806 if (r)
1807 VG_(err_config_error)("Can't delete client cmdline file in /tmp.");
1808
1809 VG_(cl_cmdline_fd) = fd;
sewardj45f4e7c2005-09-27 19:20:21 +00001810 }
bart9b533f82009-08-25 20:15:41 +00001811#endif
nethercotec314eba2004-07-15 12:59:41 +00001812
1813 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001814 // Init tool part 1: pre_clo_init
nethercotec314eba2004-07-15 12:59:41 +00001815 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
nethercotec314eba2004-07-15 12:59:41 +00001816 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
nethercote71980f02004-01-24 18:18:54 +00001817 //--------------------------------------------------------------
sewardj7cf4e6b2008-05-01 20:24:26 +00001818 VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
njn08ce7b32009-02-27 03:38:28 +00001819 VG_(tl_pre_clo_init)();
nethercote71980f02004-01-24 18:18:54 +00001820
sewardj45f4e7c2005-09-27 19:20:21 +00001821 //--------------------------------------------------------------
nethercotef4928da2004-06-15 10:54:40 +00001822 // If --tool and --help/--help-debug was given, now give the core+tool
1823 // help message
sewardj95d86c02007-12-18 01:49:23 +00001824 // p: early_process_cmd_line_options() [for 'need_help']
1825 // p: tl_pre_clo_init [for 'VG_(tdict).usage']
sewardj45f4e7c2005-09-27 19:20:21 +00001826 //--------------------------------------------------------------
1827 VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
nethercotef4928da2004-06-15 10:54:40 +00001828 if (need_help) {
njncce38e62010-07-06 04:25:12 +00001829 usage_NORETURN(/*--help-debug?*/need_help >= 2);
nethercotef4928da2004-06-15 10:54:40 +00001830 }
nethercotec314eba2004-07-15 12:59:41 +00001831
sewardj45f4e7c2005-09-27 19:20:21 +00001832 //--------------------------------------------------------------
1833 // Process command line options to Valgrind + tool
1834 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1835 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1836 //--------------------------------------------------------------
sewardj95d86c02007-12-18 01:49:23 +00001837 VG_(debugLog)(1, "main",
1838 "(main_) Process Valgrind's command line options, "
1839 "setup logging\n");
sewardj738856f2009-07-15 14:48:32 +00001840 main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded,
1841 toolname );
sewardj45f4e7c2005-09-27 19:20:21 +00001842
1843 //--------------------------------------------------------------
sewardj592ae092005-11-08 19:01:44 +00001844 // Zeroise the millisecond counter by doing a first read of it.
1845 // p: none
1846 //--------------------------------------------------------------
1847 (void) VG_(read_millisecond_timer)();
1848
1849 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001850 // Print the preamble
1851 // p: tl_pre_clo_init [for 'VG_(details).name' and friends]
sewardj738856f2009-07-15 14:48:32 +00001852 // p: main_process_cmd_line_options()
1853 // [for VG_(clo_verbosity), VG_(clo_xml),
1854 // logging_to_fd, xml_fname_unexpanded]
sewardj45f4e7c2005-09-27 19:20:21 +00001855 //--------------------------------------------------------------
1856 VG_(debugLog)(1, "main", "Print the preamble...\n");
sewardj738856f2009-07-15 14:48:32 +00001857 print_preamble(logging_to_fd, xml_fname_unexpanded, toolname);
sewardj45f4e7c2005-09-27 19:20:21 +00001858 VG_(debugLog)(1, "main", "...finished the preamble\n");
1859
1860 //--------------------------------------------------------------
1861 // Init tool part 2: post_clo_init
1862 // p: setup_client_stack() [for 'VG_(client_arg[cv]']
1863 // p: setup_file_descriptors() [for 'VG_(fd_xxx_limit)']
1864 // p: print_preamble() [so any warnings printed in post_clo_init
1865 // are shown after the preamble]
1866 //--------------------------------------------------------------
1867 VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
njn51d827b2005-05-09 01:02:08 +00001868 VG_TDICT_CALL(tool_post_clo_init);
sewardj7cf4e6b2008-05-01 20:24:26 +00001869 {
1870 /* The tool's "needs" will by now be finalised, since it has no
1871 further opportunity to specify them. So now sanity check
1872 them. */
1873 Char* s;
1874 Bool ok;
1875 ok = VG_(sanity_check_needs)( &s );
1876 if (!ok) {
1877 VG_(tool_panic)(s);
1878 }
1879 }
nethercotef4928da2004-06-15 10:54:40 +00001880
1881 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001882 // Initialise translation table and translation cache
1883 // p: aspacem [??]
1884 // p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
nethercote71980f02004-01-24 18:18:54 +00001885 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001886 VG_(debugLog)(1, "main", "Initialise TT/TC\n");
1887 VG_(init_tt_tc)();
sewardjb5f6f512005-03-10 23:59:00 +00001888
sewardj45f4e7c2005-09-27 19:20:21 +00001889 //--------------------------------------------------------------
1890 // Initialise the redirect table.
1891 // p: init_tt_tc [so it can call VG_(search_transtab) safely]
1892 // p: aspacem [so can change ownership of sysinfo pages]
1893 //--------------------------------------------------------------
1894 VG_(debugLog)(1, "main", "Initialise redirects\n");
sewardj0ec07f32006-01-12 12:32:32 +00001895 VG_(redir_initialise)();
nethercote71980f02004-01-24 18:18:54 +00001896
1897 //--------------------------------------------------------------
1898 // Allow GDB attach
sewardj95d86c02007-12-18 01:49:23 +00001899 // p: main_process_cmd_line_options() [for VG_(clo_wait_for_gdb)]
nethercote71980f02004-01-24 18:18:54 +00001900 //--------------------------------------------------------------
1901 /* Hook to delay things long enough so we can get the pid and
1902 attach GDB in another shell. */
1903 if (VG_(clo_wait_for_gdb)) {
sewardj95611ff2007-02-16 13:57:07 +00001904 Long iters;
1905 volatile Long q;
sewardj1fbc1a52005-04-25 02:05:54 +00001906 VG_(debugLog)(1, "main", "Wait for GDB\n");
sewardj93ab8572005-02-06 14:10:40 +00001907 VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
sewardj8211a572005-06-23 21:37:47 +00001908
1909# if defined(VGP_x86_linux)
1910 iters = 5;
sewardj2c48c7b2005-11-29 13:05:56 +00001911# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
sewardj8211a572005-06-23 21:37:47 +00001912 iters = 10;
1913# elif defined(VGP_ppc32_linux)
sewardjd714d2e2005-07-08 18:24:04 +00001914 iters = 5;
sewardj59570ff2010-01-01 11:59:33 +00001915# elif defined(VGP_arm_linux)
1916 iters = 1;
sewardj17c11042006-10-15 01:26:40 +00001917# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1918 iters = 4;
njnf76d27a2009-05-28 01:53:07 +00001919# elif defined(VGO_darwin)
1920 iters = 3;
sewardj8211a572005-06-23 21:37:47 +00001921# else
sewardj17c11042006-10-15 01:26:40 +00001922# error "Unknown plat"
sewardj8211a572005-06-23 21:37:47 +00001923# endif
1924
1925 iters *= 1000*1000*1000;
1926 for (q = 0; q < iters; q++)
1927 ;
nethercote71980f02004-01-24 18:18:54 +00001928 }
1929
sewardjb5d320c2005-03-13 18:57:15 +00001930 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00001931 // Search for file descriptors that are inherited from our parent
sewardj95d86c02007-12-18 01:49:23 +00001932 // p: main_process_cmd_line_options [for VG_(clo_track_fds)]
nethercote71980f02004-01-24 18:18:54 +00001933 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00001934 if (VG_(clo_track_fds)) {
1935 VG_(debugLog)(1, "main", "Init preopened fds\n");
nethercote71980f02004-01-24 18:18:54 +00001936 VG_(init_preopened_fds)();
sewardj1fbc1a52005-04-25 02:05:54 +00001937 }
nethercote71980f02004-01-24 18:18:54 +00001938
1939 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00001940 // Load debug info for the existing segments.
1941 // p: setup_code_redirect_table [so that redirs can be recorded]
1942 // p: mallocfree
1943 // p: probably: setup fds and process CLOs, so that logging works
sewardjf98e1c02008-10-25 16:22:41 +00001944 // p: initialise m_debuginfo
sewardj9c606bd2008-09-18 18:12:50 +00001945 //
1946 // While doing this, make a note of the debuginfo-handles that
1947 // come back from VG_(di_notify_mmap)/VG_(di_aix5_notify_segchange).
1948 // Later, in "Tell the tool about the initial client memory permissions"
1949 // (just below) we can then hand these handles off to the tool in
1950 // calls to VG_TRACK(new_mem_startup, ...). This gives the tool the
1951 // opportunity to make further queries to m_debuginfo before the
1952 // client is started, if it wants. We put this information into an
1953 // XArray, each handle along with the associated segment start address,
1954 // and search the XArray for the handles later, when calling
1955 // VG_TRACK(new_mem_startup, ...).
sewardj45f4e7c2005-09-27 19:20:21 +00001956 //--------------------------------------------------------------
1957 VG_(debugLog)(1, "main", "Load initial debug info\n");
sewardj9c606bd2008-09-18 18:12:50 +00001958
1959 tl_assert(!addr2dihandle);
1960 addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2",
1961 VG_(free), sizeof(Addr_n_ULong) );
1962 tl_assert(addr2dihandle);
1963
sewardj17c11042006-10-15 01:26:40 +00001964# if defined(VGO_linux)
sewardj45f4e7c2005-09-27 19:20:21 +00001965 { Addr* seg_starts;
1966 Int n_seg_starts;
sewardj9c606bd2008-09-18 18:12:50 +00001967 Addr_n_ULong anu;
sewardj45f4e7c2005-09-27 19:20:21 +00001968
njnac1e0332009-05-08 00:39:31 +00001969 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00001970 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00001971
sewardjf72cced2005-11-08 00:45:47 +00001972 /* show them all to the debug info reader. allow_SkFileV has to
1973 be True here so that we read info from the valgrind executable
1974 itself. */
sewardj9c606bd2008-09-18 18:12:50 +00001975 for (i = 0; i < n_seg_starts; i++) {
1976 anu.ull = VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/ );
1977 /* anu.ull holds the debuginfo handle returned by di_notify_mmap,
1978 if any. */
1979 if (anu.ull > 0) {
1980 anu.a = seg_starts[i];
1981 VG_(addToXA)( addr2dihandle, &anu );
1982 }
1983 }
sewardj45f4e7c2005-09-27 19:20:21 +00001984
1985 VG_(free)( seg_starts );
1986 }
sewardj17c11042006-10-15 01:26:40 +00001987# elif defined(VGO_aix5)
1988 { AixCodeSegChange* changes;
1989 Int changes_size, changes_used;
sewardj9c606bd2008-09-18 18:12:50 +00001990 Addr_n_ULong anu;
sewardj17c11042006-10-15 01:26:40 +00001991
1992 /* Find out how many AixCodeSegChange records we will need,
1993 and acquire them. */
1994 changes_size = VG_(am_aix5_reread_procmap_howmany_directives)();
sewardj9c606bd2008-09-18 18:12:50 +00001995 changes = VG_(malloc)("main.vm.3", changes_size * sizeof(AixCodeSegChange));
sewardj17c11042006-10-15 01:26:40 +00001996 vg_assert(changes);
1997
1998 /* Now re-read /proc/<pid>/map and acquire a change set */
1999 VG_(am_aix5_reread_procmap)( changes, &changes_used );
2000 vg_assert(changes_used >= 0 && changes_used <= changes_size);
2001
2002 /* And notify m_debuginfo of the changes. */
sewardj9c606bd2008-09-18 18:12:50 +00002003 for (i = 0; i < changes_used; i++) {
2004 anu.ull = VG_(di_aix5_notify_segchange)(
2005 changes[i].code_start,
2006 changes[i].code_len,
2007 changes[i].data_start,
2008 changes[i].data_len,
2009 changes[i].file_name,
2010 changes[i].mem_name,
2011 changes[i].is_mainexe,
2012 changes[i].acquire
2013 );
2014 if (anu.ull > 0) {
2015 tl_assert(changes[i].acquire);
2016 anu.a = changes[i].code_start; /* is this correct? */
2017 VG_(addToXA)( addr2dihandle, &anu );
2018 }
2019 }
sewardj17c11042006-10-15 01:26:40 +00002020
2021 VG_(free)(changes);
2022 }
njnf76d27a2009-05-28 01:53:07 +00002023# elif defined(VGO_darwin)
2024 { Addr* seg_starts;
2025 Int n_seg_starts;
2026 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
2027 vg_assert(seg_starts && n_seg_starts >= 0);
2028
2029 /* show them all to the debug info reader.
2030 Don't read from V segments (unlike Linux) */
2031 // GrP fixme really?
2032 for (i = 0; i < n_seg_starts; i++)
2033 VG_(di_notify_mmap)( seg_starts[i], False/*don't allow_SkFileV*/ );
2034
2035 VG_(free)( seg_starts );
2036 }
sewardj17c11042006-10-15 01:26:40 +00002037# else
2038# error Unknown OS
2039# endif
sewardj45f4e7c2005-09-27 19:20:21 +00002040
2041 //--------------------------------------------------------------
2042 // Tell aspacem of ownership change of the asm helpers, so that
2043 // m_translate allows them to be translated. However, only do this
2044 // after the initial debug info read, since making a hole in the
2045 // address range for the stage2 binary confuses the debug info reader.
2046 // p: aspacem
2047 //--------------------------------------------------------------
2048 { Bool change_ownership_v_c_OK;
sewardj1a85f4f2006-01-12 21:15:35 +00002049 Addr co_start = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
2050 Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
sewardj45f4e7c2005-09-27 19:20:21 +00002051 VG_(debugLog)(1,"redir",
2052 "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
2053 (ULong)co_start, (ULong)co_endPlus-1 );
2054
2055 change_ownership_v_c_OK
2056 = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
2057 vg_assert(change_ownership_v_c_OK);
2058 }
2059
2060 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002061 // Initialise the scheduler (phase 1) [generates tid_main]
2062 // p: none, afaics
2063 //--------------------------------------------------------------
2064 VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
2065 tid_main = VG_(scheduler_init_phase1)();
2066 vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
2067 && tid_main != VG_INVALID_THREADID);
2068 /* Tell the tool about tid_main */
2069 VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
2070
2071 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002072 // Tell the tool about the initial client memory permissions
2073 // p: aspacem
2074 // p: mallocfree
2075 // p: setup_client_stack
2076 // p: setup_client_dataseg
sewardj9c606bd2008-09-18 18:12:50 +00002077 //
2078 // For each segment we tell the client about, look up in
2079 // addr2dihandle as created above, to see if there's a debuginfo
2080 // handle associated with the segment, that we can hand along
2081 // to the tool, to be helpful.
sewardj45f4e7c2005-09-27 19:20:21 +00002082 //--------------------------------------------------------------
2083 VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
2084 { Addr* seg_starts;
2085 Int n_seg_starts;
sewardj45f4e7c2005-09-27 19:20:21 +00002086
sewardj9c606bd2008-09-18 18:12:50 +00002087 tl_assert(addr2dihandle);
2088
tom7c1a19a2008-01-02 10:13:04 +00002089 /* Mark the main thread as running while we tell the tool about
2090 the client memory so that the tool can associate that memory
2091 with the main thread. */
2092 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
2093 VG_(running_tid) = tid_main;
2094
njnac1e0332009-05-08 00:39:31 +00002095 seg_starts = VG_(get_segment_starts)( &n_seg_starts );
sewardj17c11042006-10-15 01:26:40 +00002096 vg_assert(seg_starts && n_seg_starts >= 0);
sewardj45f4e7c2005-09-27 19:20:21 +00002097
2098 /* show interesting ones to the tool */
2099 for (i = 0; i < n_seg_starts; i++) {
sewardj9c606bd2008-09-18 18:12:50 +00002100 Word j, n;
sewardj12ab7652006-10-17 02:10:42 +00002101 NSegment const* seg
sewardj17c11042006-10-15 01:26:40 +00002102 = VG_(am_find_nsegment)( seg_starts[i] );
sewardj45f4e7c2005-09-27 19:20:21 +00002103 vg_assert(seg);
2104 if (seg->kind == SkFileC || seg->kind == SkAnonC) {
sewardjc6d86a32009-01-31 15:08:08 +00002105 /* This next assertion is tricky. If it is placed
2106 immediately before this 'if', it very occasionally fails.
2107 Why? Because previous iterations of the loop may have
2108 caused tools (via the new_mem_startup calls) to do
2109 dynamic memory allocation, and that may affect the mapped
2110 segments; in particular it may cause segment merging to
2111 happen. Hence we cannot assume that seg_starts[i], which
2112 reflects the state of the world before we started this
2113 loop, is the same as seg->start, as the latter reflects
2114 the state of the world (viz, mappings) at this particular
2115 iteration of the loop.
2116
2117 Why does moving it inside the 'if' make it safe? Because
2118 any dynamic memory allocation done by the tools will
2119 affect only the state of Valgrind-owned segments, not of
2120 Client-owned segments. And the 'if' guards against that
2121 -- we only get in here for Client-owned segments.
2122
2123 In other words: the loop may change the state of
2124 Valgrind-owned segments as it proceeds. But it should
2125 not cause the Client-owned segments to change. */
2126 vg_assert(seg->start == seg_starts[i]);
sewardj45f4e7c2005-09-27 19:20:21 +00002127 VG_(debugLog)(2, "main",
2128 "tell tool about %010lx-%010lx %c%c%c\n",
2129 seg->start, seg->end,
2130 seg->hasR ? 'r' : '-',
2131 seg->hasW ? 'w' : '-',
2132 seg->hasX ? 'x' : '-' );
sewardj9c606bd2008-09-18 18:12:50 +00002133 /* search addr2dihandle to see if we have an entry
2134 matching seg->start. */
2135 n = VG_(sizeXA)( addr2dihandle );
2136 for (j = 0; j < n; j++) {
2137 Addr_n_ULong* anl = VG_(indexXA)( addr2dihandle, j );
2138 if (anl->a == seg->start) {
2139 tl_assert(anl->ull > 0); /* check it's a valid handle */
2140 break;
2141 }
2142 }
2143 vg_assert(j >= 0 && j <= n);
sewardj45f4e7c2005-09-27 19:20:21 +00002144 VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
sewardj9c606bd2008-09-18 18:12:50 +00002145 seg->hasR, seg->hasW, seg->hasX,
2146 /* and the retrieved debuginfo handle, if any */
2147 j < n
2148 ? ((Addr_n_ULong*)VG_(indexXA)( addr2dihandle, j ))->ull
2149 : 0 );
sewardj45f4e7c2005-09-27 19:20:21 +00002150 }
2151 }
2152
2153 VG_(free)( seg_starts );
sewardj9c606bd2008-09-18 18:12:50 +00002154 VG_(deleteXA)( addr2dihandle );
sewardj45f4e7c2005-09-27 19:20:21 +00002155
2156 /* Also do the initial stack permissions. */
sewardj12ab7652006-10-17 02:10:42 +00002157 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002158 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj17c11042006-10-15 01:26:40 +00002159 vg_assert(seg);
2160 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002161 vg_assert(the_iifii.initial_client_SP >= seg->start);
2162 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardj17c11042006-10-15 01:26:40 +00002163# if defined(VGO_aix5)
2164 VG_(clstk_base) = seg->start;
2165 VG_(clstk_end) = seg->end;
2166# endif
sewardj45f4e7c2005-09-27 19:20:21 +00002167
sewardj17c11042006-10-15 01:26:40 +00002168 /* Stuff below the initial SP is unaddressable. Take into
2169 account any ABI-mandated space below the stack pointer that
2170 is required (VG_STACK_REDZONE_SZB). setup_client_stack()
2171 will have allocated an extra page if a red zone is required,
2172 to be on the safe side. */
sewardjf9d2f9b2006-11-17 20:00:57 +00002173 vg_assert(the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
2174 >= seg->start);
sewardj17c11042006-10-15 01:26:40 +00002175 VG_TRACK( die_mem_stack,
2176 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00002177 the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
2178 - seg->start );
sewardj17c11042006-10-15 01:26:40 +00002179 VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
2180 seg->start,
sewardjf9d2f9b2006-11-17 20:00:57 +00002181 the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
sewardj17c11042006-10-15 01:26:40 +00002182 }
sewardj45f4e7c2005-09-27 19:20:21 +00002183
2184 /* Also the assembly helpers. */
2185 VG_TRACK( new_mem_startup,
2186 (Addr)&VG_(trampoline_stuff_start),
sewardjc6527d62006-02-13 17:54:31 +00002187 (Addr)&VG_(trampoline_stuff_end)
2188 - (Addr)&VG_(trampoline_stuff_start),
sewardj45f4e7c2005-09-27 19:20:21 +00002189 False, /* readable? */
2190 False, /* writable? */
sewardj9c606bd2008-09-18 18:12:50 +00002191 True /* executable? */,
2192 0 /* di_handle: no associated debug info */ );
tom7c1a19a2008-01-02 10:13:04 +00002193
2194 /* Clear the running thread indicator */
2195 VG_(running_tid) = VG_INVALID_THREADID;
2196 tl_assert(VG_(running_tid) == VG_INVALID_THREADID);
sewardj45f4e7c2005-09-27 19:20:21 +00002197 }
2198
2199 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002200 // Initialise the scheduler (phase 2)
2201 // p: Initialise the scheduler (phase 1) [for tid_main]
nethercote71980f02004-01-24 18:18:54 +00002202 // p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
sewardj45f4e7c2005-09-27 19:20:21 +00002203 // p: setup_client_stack
nethercote71980f02004-01-24 18:18:54 +00002204 //--------------------------------------------------------------
sewardjde764e82007-11-09 23:13:22 +00002205 VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
sewardj12ab7652006-10-17 02:10:42 +00002206 { NSegment const* seg
sewardjf9d2f9b2006-11-17 20:00:57 +00002207 = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
sewardj45f4e7c2005-09-27 19:20:21 +00002208 vg_assert(seg);
2209 vg_assert(seg->kind == SkAnonC);
sewardjf9d2f9b2006-11-17 20:00:57 +00002210 vg_assert(the_iifii.initial_client_SP >= seg->start);
2211 vg_assert(the_iifii.initial_client_SP <= seg->end);
sewardjde764e82007-11-09 23:13:22 +00002212 VG_(scheduler_init_phase2)( tid_main,
2213 seg->end, the_iifii.clstack_max_size );
sewardj45f4e7c2005-09-27 19:20:21 +00002214 }
nethercote71980f02004-01-24 18:18:54 +00002215
2216 //--------------------------------------------------------------
sewardj17c11042006-10-15 01:26:40 +00002217 // Set up state for the root thread
sewardjb5f6f512005-03-10 23:59:00 +00002218 // p: ?
sewardj17c11042006-10-15 01:26:40 +00002219 // setup_scheduler() [for sched-specific thread 1 stuff]
sewardjf9d2f9b2006-11-17 20:00:57 +00002220 // VG_(ii_create_image) [for 'the_iicii' initial info]
sewardj2a99cf62004-11-24 10:44:19 +00002221 //--------------------------------------------------------------
sewardjf9d2f9b2006-11-17 20:00:57 +00002222 VG_(debugLog)(1, "main", "Finalise initial image\n");
2223 VG_(ii_finalise_image)( the_iifii );
njnea4b28c2004-11-30 16:04:58 +00002224
sewardj2a99cf62004-11-24 10:44:19 +00002225 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002226 // Initialise the signal handling subsystem
sewardjb5f6f512005-03-10 23:59:00 +00002227 // p: n/a
nethercote71980f02004-01-24 18:18:54 +00002228 //--------------------------------------------------------------
2229 // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
sewardj1fbc1a52005-04-25 02:05:54 +00002230 VG_(debugLog)(1, "main", "Initialise signal management\n");
njncda2f0f2009-05-18 02:12:08 +00002231 /* Check that the kernel-interface signal definitions look sane */
2232 VG_(vki_do_initial_consistency_checks)();
2233 /* .. and go on to use them. */
nethercote71980f02004-01-24 18:18:54 +00002234 VG_(sigstartup_actions)();
2235
2236 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002237 // Read suppression file
sewardj95d86c02007-12-18 01:49:23 +00002238 // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
nethercote71980f02004-01-24 18:18:54 +00002239 //--------------------------------------------------------------
sewardj1fbc1a52005-04-25 02:05:54 +00002240 if (VG_(needs).core_errors || VG_(needs).tool_errors) {
2241 VG_(debugLog)(1, "main", "Load suppressions\n");
nethercote71980f02004-01-24 18:18:54 +00002242 VG_(load_suppressions)();
sewardj1fbc1a52005-04-25 02:05:54 +00002243 }
nethercote71980f02004-01-24 18:18:54 +00002244
2245 //--------------------------------------------------------------
rjwalsh0140af52005-06-04 20:42:33 +00002246 // register client stack
2247 //--------------------------------------------------------------
njn945ed2e2005-06-24 03:28:30 +00002248 VG_(clstk_id) = VG_(register_stack)(VG_(clstk_base), VG_(clstk_end));
rjwalsh0140af52005-06-04 20:42:33 +00002249
2250 //--------------------------------------------------------------
sewardj45f4e7c2005-09-27 19:20:21 +00002251 // Show the address space state so far
2252 //--------------------------------------------------------------
2253 VG_(debugLog)(1, "main", "\n");
2254 VG_(debugLog)(1, "main", "\n");
2255 VG_(am_show_nsegments)(1,"Memory layout at client startup");
2256 VG_(debugLog)(1, "main", "\n");
2257 VG_(debugLog)(1, "main", "\n");
2258
2259 //--------------------------------------------------------------
nethercote71980f02004-01-24 18:18:54 +00002260 // Run!
2261 //--------------------------------------------------------------
sewardj71bc3cb2005-05-19 00:25:45 +00002262 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002263 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00002264 VG_(elapsed_wallclock_time)(buf);
sewardj738856f2009-07-15 14:48:32 +00002265 VG_(printf_xml_no_f_c)( "<status>\n"
2266 " <state>RUNNING</state>\n"
2267 " <time>%t</time>\n"
2268 "</status>\n",
2269 buf );
2270 VG_(printf_xml_no_f_c)( "\n" );
sewardj71bc3cb2005-05-19 00:25:45 +00002271 }
2272
sewardj1fbc1a52005-04-25 02:05:54 +00002273 VG_(debugLog)(1, "main", "Running thread 1\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002274
sewardj1d887112005-05-30 21:44:08 +00002275 /* As a result of the following call, the last thread standing
sewardj1ae3f3a2005-09-28 10:47:38 +00002276 eventually winds up running shutdown_actions_NORETURN
2277 just below. Unfortunately, simply exporting said function
2278 causes m_main to be part of a module cycle, which is pretty
2279 nonsensical. So instead of doing that, the address of said
2280 function is stored in a global variable 'owned' by m_syswrap,
2281 and it uses that function pointer to get back here when it needs
2282 to. */
2283
2284 /* Set continuation address. */
2285 VG_(address_of_m_main_shutdown_actions_NORETURN)
2286 = & shutdown_actions_NORETURN;
2287
2288 /* Run the first thread, eventually ending up at the continuation
2289 address. */
njnaf839f52005-06-23 03:27:57 +00002290 VG_(main_thread_wrapper_NORETURN)(1);
nethercote71980f02004-01-24 18:18:54 +00002291
sewardj1d887112005-05-30 21:44:08 +00002292 /*NOTREACHED*/
2293 vg_assert(0);
sewardjb5f6f512005-03-10 23:59:00 +00002294}
2295
sewardj17c11042006-10-15 01:26:40 +00002296/* Do everything which needs doing when the last thread exits or when
2297 a thread exits requesting a complete process exit (exit on AIX).
2298
2299 We enter here holding The Lock. For the case VgSrc_ExitProcess we
2300 must never release it, because to do so would allow other threads
2301 to continue after the system is ostensibly shut down. So we must
2302 go to our grave, so to speak, holding the lock.
2303
2304 In fact, there is never any point in releasing the lock at this
2305 point - we have it, we're shutting down the entire system, and
2306 for the case VgSrc_ExitProcess doing so positively causes trouble.
2307 So don't.
2308
2309 The final_tidyup call makes a bit of a nonsense of the ExitProcess
2310 case, since it will run the libc_freeres function, thus allowing
2311 other lurking threads to run again. Hmm. */
sewardjb5f6f512005-03-10 23:59:00 +00002312
sewardj1ae3f3a2005-09-28 10:47:38 +00002313static
2314void shutdown_actions_NORETURN( ThreadId tid,
2315 VgSchedReturnCode tids_schedretcode )
sewardjb5f6f512005-03-10 23:59:00 +00002316{
sewardj1d887112005-05-30 21:44:08 +00002317 VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
sewardj17c11042006-10-15 01:26:40 +00002318 VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
sewardj1d887112005-05-30 21:44:08 +00002319
sewardjb5f6f512005-03-10 23:59:00 +00002320 vg_assert(VG_(is_running_thread)(tid));
2321
sewardj12ab7652006-10-17 02:10:42 +00002322 vg_assert(tids_schedretcode == VgSrc_ExitThread
2323 || tids_schedretcode == VgSrc_ExitProcess
2324 || tids_schedretcode == VgSrc_FatalSig );
sewardjb5f6f512005-03-10 23:59:00 +00002325
sewardj12ab7652006-10-17 02:10:42 +00002326 if (tids_schedretcode == VgSrc_ExitThread) {
sewardjb5f6f512005-03-10 23:59:00 +00002327
sewardj17c11042006-10-15 01:26:40 +00002328 // We are the last surviving thread. Right?
2329 vg_assert( VG_(count_living_threads)() == 1 );
sewardjb5f6f512005-03-10 23:59:00 +00002330
sewardj17c11042006-10-15 01:26:40 +00002331 // Wait for all other threads to exit.
2332 // jrs: Huh? but they surely are already gone
2333 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002334
sewardj17c11042006-10-15 01:26:40 +00002335 // Clean the client up before the final report
2336 // this causes the libc_freeres function to run
2337 final_tidyup(tid);
2338
2339 /* be paranoid */
2340 vg_assert(VG_(is_running_thread)(tid));
2341 vg_assert(VG_(count_living_threads)() == 1);
2342
2343 } else {
2344
2345 // We may not be the last surviving thread. However, we
2346 // want to shut down the entire process. We hold the lock
2347 // and we need to keep hold of it all the way out, in order
2348 // that none of the other threads ever run again.
2349 vg_assert( VG_(count_living_threads)() >= 1 );
2350
sewardj17c11042006-10-15 01:26:40 +00002351 // Clean the client up before the final report
2352 // this causes the libc_freeres function to run
2353 // perhaps this is unsafe, as per comment above
2354 final_tidyup(tid);
2355
2356 /* be paranoid */
2357 vg_assert(VG_(is_running_thread)(tid));
2358 vg_assert(VG_(count_living_threads)() >= 1);
2359 }
sewardjb5f6f512005-03-10 23:59:00 +00002360
2361 VG_(threads)[tid].status = VgTs_Empty;
nethercote71980f02004-01-24 18:18:54 +00002362 //--------------------------------------------------------------
sewardj738856f2009-07-15 14:48:32 +00002363 // Finalisation: cleanup, messages, etc. Order not so important, only
nethercote71980f02004-01-24 18:18:54 +00002364 // affects what order the messages come.
2365 //--------------------------------------------------------------
njnb6267bd2009-08-12 00:14:16 +00002366 // First thing in the post-amble is a blank line.
sewardj738856f2009-07-15 14:48:32 +00002367 if (VG_(clo_xml))
2368 VG_(printf_xml)("\n");
njnb6267bd2009-08-12 00:14:16 +00002369 else if (VG_(clo_verbosity) > 0)
2370 VG_(message)(Vg_UserMsg, "\n");
nethercote71980f02004-01-24 18:18:54 +00002371
sewardj71bc3cb2005-05-19 00:25:45 +00002372 if (VG_(clo_xml)) {
sewardj68cde6f2005-07-19 12:17:51 +00002373 HChar buf[50];
sewardj592ae092005-11-08 19:01:44 +00002374 VG_(elapsed_wallclock_time)(buf);
sewardj738856f2009-07-15 14:48:32 +00002375 VG_(printf_xml_no_f_c)( "<status>\n"
2376 " <state>FINISHED</state>\n"
2377 " <time>%t</time>\n"
njnb6267bd2009-08-12 00:14:16 +00002378 "</status>\n"
2379 "\n",
sewardj738856f2009-07-15 14:48:32 +00002380 buf);
sewardj71bc3cb2005-05-19 00:25:45 +00002381 }
2382
nethercote71980f02004-01-24 18:18:54 +00002383 /* Print out file descriptor summary and stats. */
2384 if (VG_(clo_track_fds))
nethercote3a42fb82004-08-03 18:08:50 +00002385 VG_(show_open_fds)();
nethercote71980f02004-01-24 18:18:54 +00002386
sewardj2d9e8742009-08-07 15:46:56 +00002387 /* Call the tool's finalisation function. This makes Memcheck's
2388 leak checker run, and possibly chuck a bunch of leak errors into
2389 the error management machinery. */
2390 VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
nethercote71980f02004-01-24 18:18:54 +00002391
sewardj2d9e8742009-08-07 15:46:56 +00002392 /* Show the error counts. */
sewardj7ca100d2009-08-15 23:05:34 +00002393 if (VG_(clo_xml)
2394 && (VG_(needs).core_errors || VG_(needs).tool_errors)) {
sewardj2d9e8742009-08-07 15:46:56 +00002395 VG_(show_error_counts_as_XML)();
sewardj738856f2009-07-15 14:48:32 +00002396 }
sewardj2d9e8742009-08-07 15:46:56 +00002397
2398 /* In XML mode, this merely prints the used suppressions. */
2399 if (VG_(needs).core_errors || VG_(needs).tool_errors)
2400 VG_(show_all_errors)();
nethercote71980f02004-01-24 18:18:54 +00002401
sewardj71bc3cb2005-05-19 00:25:45 +00002402 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +00002403 VG_(printf_xml)("\n");
2404 VG_(printf_xml)("</valgrindoutput>\n");
2405 VG_(printf_xml)("\n");
sewardj71bc3cb2005-05-19 00:25:45 +00002406 }
2407
nethercote885dd912004-08-03 23:14:00 +00002408 VG_(sanity_check_general)( True /*include expensive checks*/ );
nethercote71980f02004-01-24 18:18:54 +00002409
sewardj2d9e8742009-08-07 15:46:56 +00002410 if (VG_(clo_stats))
nethercote3a42fb82004-08-03 18:08:50 +00002411 print_all_stats();
nethercote71980f02004-01-24 18:18:54 +00002412
sewardj9c606bd2008-09-18 18:12:50 +00002413 /* Show a profile of the heap(s) at shutdown. Optionally, first
2414 throw away all the debug info, as that makes it easy to spot
2415 leaks in the debuginfo reader. */
2416 if (VG_(clo_profile_heap)) {
2417 if (0) VG_(di_discard_ALL_debuginfo)();
2418 VG_(print_arena_cc_analysis)();
2419 }
2420
njn2025cf92005-06-26 20:44:48 +00002421 if (VG_(clo_profile_flags) > 0) {
sewardj5471ec62006-10-17 13:58:17 +00002422 #define N_MAX 200
njn2025cf92005-06-26 20:44:48 +00002423 BBProfEntry tops[N_MAX];
2424 ULong score_total = VG_(get_BB_profile) (tops, N_MAX);
2425 show_BB_profile(tops, N_MAX, score_total);
2426 }
sewardjfa8ec112005-01-19 11:55:34 +00002427
sewardj8b635a42004-11-22 19:01:47 +00002428 /* Print Vex storage stats */
sewardjbf426512005-01-17 18:35:30 +00002429 if (0)
2430 LibVEX_ShowAllocStats();
sewardj1d887112005-05-30 21:44:08 +00002431
sewardj738856f2009-07-15 14:48:32 +00002432 /* Flush any output cached by previous calls to VG_(message). */
2433 VG_(message_flush)();
2434
njn8aa35852005-06-10 22:59:56 +00002435 /* Ok, finally exit in the os-specific way, according to the scheduler's
2436 return code. In short, if the (last) thread exited by calling
2437 sys_exit, do likewise; if the (last) thread stopped due to a fatal
2438 signal, terminate the entire system with that same fatal signal. */
2439 VG_(debugLog)(1, "core_os",
njn7b85dd52005-06-12 17:26:29 +00002440 "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
njn8aa35852005-06-10 22:59:56 +00002441
njn8aa35852005-06-10 22:59:56 +00002442 switch (tids_schedretcode) {
sewardj12ab7652006-10-17 02:10:42 +00002443 case VgSrc_ExitThread: /* the normal way out (Linux) */
2444 case VgSrc_ExitProcess: /* the normal way out (AIX) */
sewardjb9779082006-05-12 23:50:15 +00002445 /* Change the application return code to user's return code,
2446 if an error was found */
2447 if (VG_(clo_error_exitcode) > 0
2448 && VG_(get_n_errs_found)() > 0) {
2449 VG_(exit)( VG_(clo_error_exitcode) );
2450 } else {
2451 /* otherwise, return the client's exit code, in the normal
2452 way. */
2453 VG_(exit)( VG_(threads)[tid].os_state.exitcode );
2454 }
njn8aa35852005-06-10 22:59:56 +00002455 /* NOT ALIVE HERE! */
sewardj17c11042006-10-15 01:26:40 +00002456 VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
njn8aa35852005-06-10 22:59:56 +00002457 break; /* what the hell :) */
2458
2459 case VgSrc_FatalSig:
2460 /* We were killed by a fatal signal, so replicate the effect */
2461 vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
2462 VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
njnf76d27a2009-05-28 01:53:07 +00002463 /* we shouldn't be alive at this point. But VG_(kill_self)
2464 sometimes fails with EPERM on Darwin, for unclear reasons. */
2465# if defined(VGO_darwin)
2466 VG_(debugLog)(0, "main", "VG_(kill_self) failed. Exiting normally.\n");
2467 VG_(exit)(0); /* bogus, but we really need to exit now */
2468 /* fall through .. */
2469# endif
njn8aa35852005-06-10 22:59:56 +00002470 VG_(core_panic)("main(): signal was supposed to be fatal");
2471 break;
2472
2473 default:
2474 VG_(core_panic)("main(): unexpected scheduler return code");
2475 }
njne96be672005-05-08 19:08:54 +00002476}
sewardj8b635a42004-11-22 19:01:47 +00002477
sewardj1ae3f3a2005-09-28 10:47:38 +00002478/* -------------------- */
2479
2480/* Final clean-up before terminating the process.
2481 Clean up the client by calling __libc_freeres() (if requested)
2482 This is Linux-specific?
njnf76d27a2009-05-28 01:53:07 +00002483 GrP fixme glibc-specific, anyway
sewardj1ae3f3a2005-09-28 10:47:38 +00002484*/
2485static void final_tidyup(ThreadId tid)
2486{
njnf76d27a2009-05-28 01:53:07 +00002487#if !defined(VGO_darwin)
sewardjcf951812006-01-17 02:22:21 +00002488# if defined(VGP_ppc64_linux)
2489 Addr r2;
2490# endif
sewardj0ec07f32006-01-12 12:32:32 +00002491 Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
sewardj1ae3f3a2005-09-28 10:47:38 +00002492
2493 vg_assert(VG_(is_running_thread)(tid));
2494
2495 if ( !VG_(needs).libc_freeres ||
2496 !VG_(clo_run_libc_freeres) ||
sewardj0ec07f32006-01-12 12:32:32 +00002497 0 == __libc_freeres_wrapper )
sewardj1ae3f3a2005-09-28 10:47:38 +00002498 return; /* can't/won't do it */
sewardj17c11042006-10-15 01:26:40 +00002499# if defined(VGO_aix5)
2500 return; /* inapplicable on non-Linux platforms */
2501# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002502
sewardjcf951812006-01-17 02:22:21 +00002503# if defined(VGP_ppc64_linux)
2504 r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
2505 if (r2 == 0) {
2506 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002507 "Caught __NR_exit, but can't run __libc_freeres()\n");
sewardjcf951812006-01-17 02:22:21 +00002508 VG_(message)(Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00002509 " since cannot establish TOC pointer for it.\n");
sewardjcf951812006-01-17 02:22:21 +00002510 return;
2511 }
2512# endif
2513
sewardj1ae3f3a2005-09-28 10:47:38 +00002514 if (VG_(clo_verbosity) > 2 ||
2515 VG_(clo_trace_syscalls) ||
2516 VG_(clo_trace_sched))
2517 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +00002518 "Caught __NR_exit; running __libc_freeres()\n");
sewardj1ae3f3a2005-09-28 10:47:38 +00002519
sewardj0ec07f32006-01-12 12:32:32 +00002520 /* set thread context to point to libc_freeres_wrapper */
sewardj1a85f4f2006-01-12 21:15:35 +00002521 /* ppc64-linux note: __libc_freeres_wrapper gives us the real
2522 function entry point, not a fn descriptor, so can use it
2523 directly. However, we need to set R2 (the toc pointer)
2524 appropriately. */
sewardj1ae3f3a2005-09-28 10:47:38 +00002525 VG_(set_IP)(tid, __libc_freeres_wrapper);
sewardjcf951812006-01-17 02:22:21 +00002526# if defined(VGP_ppc64_linux)
2527 VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
2528# endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002529
2530 /* Block all blockable signals by copying the real block state into
2531 the thread's block state*/
2532 VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
2533 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
2534
2535 /* and restore handlers to default */
2536 VG_(set_default_handler)(VKI_SIGSEGV);
2537 VG_(set_default_handler)(VKI_SIGBUS);
2538 VG_(set_default_handler)(VKI_SIGILL);
2539 VG_(set_default_handler)(VKI_SIGFPE);
2540
2541 // We were exiting, so assert that...
2542 vg_assert(VG_(is_exiting)(tid));
2543 // ...but now we're not again
2544 VG_(threads)[tid].exitreason = VgSrc_None;
2545
2546 // run until client thread exits - ideally with LIBC_FREERES_DONE,
2547 // but exit/exitgroup/signal will do
2548 VG_(scheduler)(tid);
2549
2550 vg_assert(VG_(is_exiting)(tid));
njnf76d27a2009-05-28 01:53:07 +00002551#endif
sewardj1ae3f3a2005-09-28 10:47:38 +00002552}
2553
sewardj45f4e7c2005-09-27 19:20:21 +00002554
2555/*====================================================================*/
njn49f80e82009-05-21 01:25:43 +00002556/*=== Getting to main() alive: LINUX ===*/
sewardj45f4e7c2005-09-27 19:20:21 +00002557/*====================================================================*/
2558
sewardj17c11042006-10-15 01:26:40 +00002559#if defined(VGO_linux)
2560
sewardj45f4e7c2005-09-27 19:20:21 +00002561/* If linking of the final executables is done with glibc present,
2562 then Valgrind starts at main() above as usual, and all of the
2563 following code is irrelevant.
2564
2565 However, this is not the intended mode of use. The plan is to
2566 avoid linking against glibc, by giving gcc the flags
2567 -nodefaultlibs -lgcc -nostartfiles at startup.
2568
2569 From this derive two requirements:
2570
2571 1. gcc may emit calls to memcpy and memset to deal with structure
2572 assignments etc. Since we have chosen to ignore all the
2573 "normal" supporting libraries, we have to provide our own
2574 implementations of them. No problem.
2575
2576 2. We have to provide a symbol "_start", to which the kernel
2577 hands control at startup. Hence the code below.
2578*/
2579
2580/* ---------------- Requirement 1 ---------------- */
2581
sewardj17c11042006-10-15 01:26:40 +00002582void* memcpy(void *dest, const void *src, SizeT n);
2583void* memcpy(void *dest, const void *src, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002584 return VG_(memcpy)(dest,src,n);
2585}
sewardj17c11042006-10-15 01:26:40 +00002586void* memset(void *s, int c, SizeT n);
2587void* memset(void *s, int c, SizeT n) {
sewardj45f4e7c2005-09-27 19:20:21 +00002588 return VG_(memset)(s,c,n);
2589}
2590
bart82616e12010-06-13 13:46:24 +00002591/* BVA: abort() for those platforms that need it (PPC and ARM). */
2592void abort(void);
2593void abort(void){
2594 VG_(printf)("Something called raise().\n");
2595 vg_assert(0);
2596}
2597
sewardj59570ff2010-01-01 11:59:33 +00002598/* EAZG: ARM's EABI will call floating point exception handlers in
2599 libgcc which boil down to an abort or raise, that's usually defined
2600 in libc. Instead, define them here. */
2601#if defined(VGP_arm_linux)
2602void raise(void);
2603void raise(void){
2604 VG_(printf)("Something called raise().\n");
2605 vg_assert(0);
2606}
2607
sewardj59570ff2010-01-01 11:59:33 +00002608void __aeabi_unwind_cpp_pr0(void);
2609void __aeabi_unwind_cpp_pr0(void){
2610 VG_(printf)("Something called __aeabi_unwind_cpp_pr0()\n");
2611 vg_assert(0);
2612}
2613#endif
2614
sewardj45f4e7c2005-09-27 19:20:21 +00002615/* ---------------- Requirement 2 ---------------- */
2616
2617/* Glibc's sysdeps/i386/elf/start.S has the following gem of a
2618 comment, which explains how the stack looks right at process start
2619 (when _start is jumped to). Hence _start passes %esp to
sewardj17c11042006-10-15 01:26:40 +00002620 _start_in_C_linux, which extracts argc/argv/envp and starts up
sewardj45f4e7c2005-09-27 19:20:21 +00002621 correctly. */
2622
2623/* This is the canonical entry point, usually the first thing in the text
2624 segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
2625 point runs, most registers' values are unspecified, except for:
2626
2627 %edx Contains a function pointer to be registered with `atexit'.
2628 This is how the dynamic linker arranges to have DT_FINI
2629 functions called for shared libraries that have been loaded
2630 before this code runs.
2631
2632 %esp The stack contains the arguments and environment:
2633 0(%esp) argc
2634 4(%esp) argv[0]
2635 ...
2636 (4*argc)(%esp) NULL
2637 (4*(argc+1))(%esp) envp[0]
2638 ...
2639 NULL
2640*/
2641
2642/* The kernel hands control to _start, which extracts the initial
sewardj17c11042006-10-15 01:26:40 +00002643 stack pointer and calls onwards to _start_in_C_linux. This also switches
sewardja48a4932005-09-29 11:09:56 +00002644 the new stack. */
sewardj45f4e7c2005-09-27 19:20:21 +00002645#if defined(VGP_x86_linux)
2646asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002647 ".text\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002648 "\t.globl _start\n"
2649 "\t.type _start,@function\n"
2650 "_start:\n"
2651 /* set up the new stack in %eax */
sewardjfdf91b42005-09-28 00:53:09 +00002652 "\tmovl $vgPlain_interim_stack, %eax\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002653 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2654 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2655 "\tsubl $16, %eax\n"
2656 "\tandl $~15, %eax\n"
2657 /* install it, and collect the original one */
2658 "\txchgl %eax, %esp\n"
sewardj17c11042006-10-15 01:26:40 +00002659 /* call _start_in_C_linux, passing it the startup %esp */
sewardj45f4e7c2005-09-27 19:20:21 +00002660 "\tpushl %eax\n"
sewardj17c11042006-10-15 01:26:40 +00002661 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002662 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002663 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002664);
2665#elif defined(VGP_amd64_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 %rdi */
sewardjfdf91b42005-09-28 00:53:09 +00002672 "\tmovq $vgPlain_interim_stack, %rdi\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002673 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2674 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2675 "\tandq $~15, %rdi\n"
2676 /* install it, and collect the original one */
2677 "\txchgq %rdi, %rsp\n"
sewardj17c11042006-10-15 01:26:40 +00002678 /* call _start_in_C_linux, passing it the startup %rsp */
2679 "\tcall _start_in_C_linux\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002680 "\thlt\n"
sewardj2fedc642005-11-19 02:02:57 +00002681 ".previous\n"
sewardj45f4e7c2005-09-27 19:20:21 +00002682);
sewardja48a4932005-09-29 11:09:56 +00002683#elif defined(VGP_ppc32_linux)
2684asm("\n"
sewardjd9fc3822005-11-18 23:50:43 +00002685 ".text\n"
sewardja48a4932005-09-29 11:09:56 +00002686 "\t.globl _start\n"
2687 "\t.type _start,@function\n"
2688 "_start:\n"
2689 /* set up the new stack in r16 */
2690 "\tlis 16,vgPlain_interim_stack@ha\n"
2691 "\tla 16,vgPlain_interim_stack@l(16)\n"
2692 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2693 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2694 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2695 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2696 "\tadd 16,17,16\n"
2697 "\tadd 16,18,16\n"
2698 "\trlwinm 16,16,0,0,27\n"
2699 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2700 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2701 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002702 call _start_in_C_linux, passing it the initial SP. */
sewardja48a4932005-09-29 11:09:56 +00002703 "\tmr 3,1\n"
2704 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002705 "\tbl _start_in_C_linux\n"
sewardja48a4932005-09-29 11:09:56 +00002706 "\ttrap\n"
sewardj2fedc642005-11-19 02:02:57 +00002707 ".previous\n"
sewardja48a4932005-09-29 11:09:56 +00002708);
sewardj2c48c7b2005-11-29 13:05:56 +00002709#elif defined(VGP_ppc64_linux)
2710asm("\n"
cerion21082042005-12-06 19:07:08 +00002711 /* PPC64 ELF ABI says '_start' points to a function descriptor.
2712 So we must have one, and that is what goes into the .opd section. */
cerion297c88f2005-12-22 15:53:12 +00002713 "\t.align 2\n"
cerion21082042005-12-06 19:07:08 +00002714 "\t.global _start\n"
2715 "\t.section \".opd\",\"aw\"\n"
2716 "\t.align 3\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002717 "_start:\n"
cerion21082042005-12-06 19:07:08 +00002718 "\t.quad ._start,.TOC.@tocbase,0\n"
2719 "\t.previous\n"
2720 "\t.type ._start,@function\n"
2721 "\t.global ._start\n"
2722 "._start:\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002723 /* set up the new stack in r16 */
2724 "\tlis 16, vgPlain_interim_stack@highest\n"
2725 "\tori 16,16,vgPlain_interim_stack@higher\n"
2726 "\tsldi 16,16,32\n"
2727 "\toris 16,16,vgPlain_interim_stack@h\n"
2728 "\tori 16,16,vgPlain_interim_stack@l\n"
2729 "\txor 17,17,17\n"
2730 "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
2731 "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
2732 "\txor 18,18,18\n"
2733 "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
2734 "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
2735 "\tadd 16,17,16\n"
2736 "\tadd 16,18,16\n"
2737 "\trldicr 16,16,0,59\n"
2738 /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
2739 VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
2740 boundary. And r1 is the original SP. Set the SP to r16 and
sewardj17c11042006-10-15 01:26:40 +00002741 call _start_in_C_linux, passing it the initial SP. */
sewardj2c48c7b2005-11-29 13:05:56 +00002742 "\tmr 3,1\n"
2743 "\tmr 1,16\n"
sewardj17c11042006-10-15 01:26:40 +00002744 "\tbl ._start_in_C_linux\n"
cerion21082042005-12-06 19:07:08 +00002745 "\tnop\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002746 "\ttrap\n"
sewardj2c48c7b2005-11-29 13:05:56 +00002747);
sewardj59570ff2010-01-01 11:59:33 +00002748#elif defined(VGP_arm_linux)
2749asm("\n"
2750 "\t.align 2\n"
2751 "\t.global _start\n"
2752 "_start:\n"
2753 "\tldr r0, [pc, #36]\n"
2754 "\tldr r1, [pc, #36]\n"
2755 "\tadd r0, r1, r0\n"
2756 "\tldr r1, [pc, #32]\n"
2757 "\tadd r0, r1, r0\n"
2758 "\tmvn r1, #15\n"
2759 "\tand r0, r0, r1\n"
2760 "\tmov r1, sp\n"
2761 "\tmov sp, r0\n"
2762 "\tmov r0, r1\n"
2763 "\tb _start_in_C_linux\n"
2764 "\t.word vgPlain_interim_stack\n"
2765 "\t.word "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
2766 "\t.word "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
2767);
sewardj45f4e7c2005-09-27 19:20:21 +00002768#else
njn49f80e82009-05-21 01:25:43 +00002769# error "Unknown linux platform"
sewardj45f4e7c2005-09-27 19:20:21 +00002770#endif
2771
sewardje66f2e02006-12-30 17:45:08 +00002772/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
2773#define _GNU_SOURCE
2774#define _FILE_OFFSET_BITS 64
2775/* This is in order to get AT_NULL and AT_PAGESIZE. */
2776#include <elf.h>
2777/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
2778
sewardj45f4e7c2005-09-27 19:20:21 +00002779/* Avoid compiler warnings: this fn _is_ used, but labelling it
2780 'static' causes gcc to complain it isn't. */
sewardj17c11042006-10-15 01:26:40 +00002781void _start_in_C_linux ( UWord* pArgc );
2782void _start_in_C_linux ( UWord* pArgc )
sewardj45f4e7c2005-09-27 19:20:21 +00002783{
2784 Int r;
2785 Word argc = pArgc[0];
2786 HChar** argv = (HChar**)&pArgc[1];
2787 HChar** envp = (HChar**)&pArgc[1+argc+1];
sewardjf9d2f9b2006-11-17 20:00:57 +00002788
2789 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2790 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2791
2792 the_iicii.sp_at_startup = (Addr)pArgc;
2793
sewardje66f2e02006-12-30 17:45:08 +00002794# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
2795 {
2796 /* ppc/ppc64 can be configured with different page sizes.
2797 Determine this early. This is an ugly hack and really should
2798 be moved into valgrind_main. */
2799 UWord *sp = &pArgc[1+argc+1];
2800 while (*sp++ != 0)
2801 ;
2802 for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
2803 if (*sp == AT_PAGESZ) {
2804 VKI_PAGE_SIZE = sp[1];
2805 for (VKI_PAGE_SHIFT = 12;
2806 VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
2807 if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
2808 break;
2809 }
2810 }
2811# endif
2812
sewardjf9d2f9b2006-11-17 20:00:57 +00002813 r = valgrind_main( (Int)argc, argv, envp );
sewardj17c11042006-10-15 01:26:40 +00002814 /* NOTREACHED */
sewardj45f4e7c2005-09-27 19:20:21 +00002815 VG_(exit)(r);
2816}
2817
sewardj17c11042006-10-15 01:26:40 +00002818
2819/*====================================================================*/
2820/*=== Getting to main() alive: AIX5 ===*/
2821/*====================================================================*/
2822
njn49f80e82009-05-21 01:25:43 +00002823#elif defined(VGO_aix5)
sewardj17c11042006-10-15 01:26:40 +00002824
2825/* This is somewhat simpler than the Linux case. _start_valgrind
2826 receives control from the magic piece of code created in this
2827 process' address space by the launcher, via use of ptrace(). At
2828 the point of entry:
2829
2830 - the initial client process image is in memory and ready to roll,
2831 except that we've partially trashed its integer register state
2832 in order to get this far. So ..
2833
2834 - intregs37 holds the client's initial integer register state, so
2835 we can restore it before starting the client on the VCPU.
2836
2837 - we're on the client's stack. This is not good; therefore the
2838 first order of business is to switch to our temporary stack.
2839
2840 - the client's initial argc/v/envp is in r3/r4/r5 (32 bit mode) or
2841 r14/r15/r16 (64 bit mode). They are pulled out of the stashed
2842 integer register state and passed to our main().
2843
2844 The launcher will have played some games with argv. If the launcher
2845 ($prefix/bin/valgrind) was started like this
2846
2847 valgrind [args-for-V] app [args-for-app]
2848
2849 then the launcher will have started the client as
2850
2851 app [args-for-V] app [args-for-app]
2852
2853 m_initimg will have to mess with the client's initial r4/r5
2854 (32-bit) or r15/r16 (64-bit) so that it believes it was execd as
2855 "app [args-for-app]". Well, that's no big deal.
2856*/
2857
2858#include "launcher-aix5-bootblock.h"
2859
2860void _start_in_C_aix5 ( AIX5Bootblock* bootblock );
2861void _start_in_C_aix5 ( AIX5Bootblock* bootblock )
2862{
2863 Int r;
2864 ULong* intregs37;
2865 UWord argc, argv, envp;
2866 __NR_getpid = bootblock->__NR_getpid;
2867 __NR_write = bootblock->__NR_write;
2868 __NR_exit = bootblock->__NR_exit;
2869 __NR_open = bootblock->__NR_open;
2870 __NR_read = bootblock->__NR_read;
2871 __NR_close = bootblock->__NR_close;
sewardjf9d2f9b2006-11-17 20:00:57 +00002872
2873 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
2874 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
2875
sewardj17c11042006-10-15 01:26:40 +00002876 intregs37 = &bootblock->iregs_pc_cr_lr_ctr_xer[0];
sewardjf9d2f9b2006-11-17 20:00:57 +00002877 the_iicii.intregs37 = intregs37;
2878 the_iicii.bootblock = (void*)bootblock;
2879 the_iicii.adler32_exp = bootblock->adler32;
2880
2881 /* Not important on AIX. */
2882 the_iicii.sp_at_startup = (Addr)0x31415927ULL;
2883
sewardj17c11042006-10-15 01:26:40 +00002884# if defined(VGP_ppc32_aix5)
2885 argc = (UWord)intregs37[3]; /* client's r3 == argc */
2886 argv = (UWord)intregs37[4];
2887 envp = (UWord)intregs37[5];
2888# else /* defined(VGP_ppc64_aix5) */
2889 argc = (UWord)intregs37[14]; /* client's r14 == argc */
2890 argv = (UWord)intregs37[15];
2891 envp = (UWord)intregs37[16];
2892# endif
sewardjf9d2f9b2006-11-17 20:00:57 +00002893
2894 r = valgrind_main( (Int)argc, (HChar**)argv, (HChar**)envp );
2895
sewardj17c11042006-10-15 01:26:40 +00002896 /* NOTREACHED */
2897 VG_(exit)(r);
2898}
2899
2900/* THE ENTRY POINT */
2901void _start_valgrind ( AIX5Bootblock* bootblock );
2902void _start_valgrind ( AIX5Bootblock* bootblock )
2903{
2904 /* Switch immediately to our temporary stack, and continue. This
2905 is pretty dodgy in that it assumes that gcc does not place on
2906 the stack, anything needed to form the _start_in_C_aix5 call,
2907 since it will be on the old stack. */
2908 register UWord new_r1;
2909 new_r1 = (UWord)&VG_(interim_stack);
2910 new_r1 += VG_STACK_GUARD_SZB; /* step over lower guard page */
2911 new_r1 += VG_STACK_ACTIVE_SZB; /* step to top of active area */
2912 new_r1 -= 512; /* paranoia */
2913 __asm__ __volatile__("mr 1,%0" :/*wr*/
2914 :/*rd*/ "b"(new_r1)
2915 :/*trash*/"r1","memory");
2916 _start_in_C_aix5(bootblock);
2917 /*NOTREACHED*/
2918 VG_(exit)(0);
2919}
2920
sewardj61a1b052008-10-22 00:56:53 +00002921/* At some point in Oct 2008, static linking appeared to stop working
2922 on AIX 5.3. This breaks the build since we link statically. The
2923 linking fails citing absence of the following five symbols as the
2924 reason. In the absence of a better solution, here are stand-ins
2925 for them. Kludge appears to work; presumably said functions,
2926 assuming they are indeed functions, are never called. */
2927void encrypted_pw_passlen ( void ) { vg_assert(0); }
2928void crypt_r ( void ) { vg_assert(0); }
2929void max_history_size ( void ) { vg_assert(0); }
2930void getpass_auto ( void ) { vg_assert(0); }
2931void max_pw_passlen ( void ) { vg_assert(0); }
2932
njn49f80e82009-05-21 01:25:43 +00002933
njnf76d27a2009-05-28 01:53:07 +00002934/*====================================================================*/
2935/*=== Getting to main() alive: darwin ===*/
2936/*====================================================================*/
2937
2938#elif defined(VGO_darwin)
2939
njnea2d6fd2010-07-01 00:20:20 +00002940/*
2941 Memory layout established by kernel:
2942
2943 0(%esp) argc
2944 4(%esp) argv[0]
2945 ...
2946 argv[argc-1]
2947 NULL
2948 envp[0]
2949 ...
2950 envp[n]
2951 NULL
2952 executable name (presumably, a pointer to it)
2953 NULL
2954
2955 Ditto in the 64-bit case, except all offsets from SP are obviously
2956 twice as large.
2957*/
2958
2959/* The kernel hands control to _start, which extracts the initial
2960 stack pointer and calls onwards to _start_in_C_darwin. This also
2961 switches to the new stack. */
2962#if defined(VGP_x86_darwin)
2963asm("\n"
2964 ".text\n"
2965 ".align 2,0x90\n"
2966 "\t.globl __start\n"
2967 "__start:\n"
2968 /* set up the new stack in %eax */
2969 "\tmovl $_vgPlain_interim_stack, %eax\n"
2970 "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
2971 "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
2972 "\tsubl $16, %eax\n"
2973 "\tandl $~15, %eax\n"
2974 /* install it, and collect the original one */
2975 "\txchgl %eax, %esp\n"
2976 /* call _start_in_C_darwin, passing it the startup %esp */
2977 "\tpushl %eax\n"
2978 "\tcall __start_in_C_darwin\n"
2979 "\tint $3\n"
2980 "\tint $3\n"
2981);
2982#elif defined(VGP_amd64_darwin)
2983asm("\n"
2984 ".text\n"
2985 "\t.globl __start\n"
2986 ".align 3,0x90\n"
2987 "__start:\n"
2988 /* set up the new stack in %rdi */
2989 "\tmovabsq $_vgPlain_interim_stack, %rdi\n"
2990 "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
2991 "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
2992 "\tandq $~15, %rdi\n"
2993 /* install it, and collect the original one */
2994 "\txchgq %rdi, %rsp\n"
2995 /* call _start_in_C_darwin, passing it the startup %rsp */
2996 "\tcall __start_in_C_darwin\n"
2997 "\tint $3\n"
2998 "\tint $3\n"
2999);
3000#endif
3001
njnf76d27a2009-05-28 01:53:07 +00003002void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2);
3003void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2) {
3004 // skip check
3005 return VG_(memcpy)(dest,src,n);
3006}
3007void* __memset_chk(void *s, int c, SizeT n, SizeT n2);
3008void* __memset_chk(void *s, int c, SizeT n, SizeT n2) {
3009 // skip check
3010 return VG_(memset)(s,c,n);
3011}
3012void bzero(void *s, SizeT n);
3013void bzero(void *s, SizeT n) {
3014 VG_(memset)(s,0,n);
3015}
3016
3017void* memcpy(void *dest, const void *src, SizeT n);
3018void* memcpy(void *dest, const void *src, SizeT n) {
3019 return VG_(memcpy)(dest,src,n);
3020}
3021void* memset(void *s, int c, SizeT n);
3022void* memset(void *s, int c, SizeT n) {
3023 return VG_(memset)(s,c,n);
3024}
3025
njnf76d27a2009-05-28 01:53:07 +00003026/* Avoid compiler warnings: this fn _is_ used, but labelling it
3027 'static' causes gcc to complain it isn't. */
3028void _start_in_C_darwin ( UWord* pArgc );
3029void _start_in_C_darwin ( UWord* pArgc )
3030{
3031 Int r;
njnea2d6fd2010-07-01 00:20:20 +00003032 Int argc = *(Int *)pArgc; // not pArgc[0] on LP64
njnf76d27a2009-05-28 01:53:07 +00003033 HChar** argv = (HChar**)&pArgc[1];
3034 HChar** envp = (HChar**)&pArgc[1+argc+1];
3035
3036 VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
3037 VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
3038
3039 the_iicii.sp_at_startup = (Addr)pArgc;
3040
3041 r = valgrind_main( (Int)argc, argv, envp );
3042 /* NOTREACHED */
3043 VG_(exit)(r);
3044}
3045
3046
njn49f80e82009-05-21 01:25:43 +00003047#else
3048
3049# error "Unknown OS"
3050#endif
sewardj17c11042006-10-15 01:26:40 +00003051
3052
sewardj0af71bb2010-07-01 14:50:30 +00003053/*====================================================================*/
3054/*=== {u,}{div,mod}di3 replacements ===*/
3055/*====================================================================*/
njnea2d6fd2010-07-01 00:20:20 +00003056
3057/* For static linking on x86-darwin, we need to supply our own 64-bit
3058 integer division code, else the link dies thusly:
3059
3060 ld_classic: Undefined symbols:
3061 ___udivdi3
3062 ___umoddi3
3063*/
3064#if defined(VGP_x86_darwin)
3065
3066/* Routines for doing signed/unsigned 64 x 64 ==> 64 div and mod
3067 (udivdi3, umoddi3, divdi3, moddi3) using only 32 x 32 ==> 32
3068 division. Cobbled together from
3069
3070 http://www.hackersdelight.org/HDcode/divlu.c
3071 http://www.hackersdelight.org/HDcode/divls.c
3072 http://www.hackersdelight.org/HDcode/newCode/divDouble.c
3073
3074 The code from those three files is covered by the following license,
3075 as it appears at:
3076
3077 http://www.hackersdelight.org/permissions.htm
3078
3079 You are free to use, copy, and distribute any of the code on
3080 this web site, whether modified by you or not. You need not give
3081 attribution. This includes the algorithms (some of which appear
3082 in Hacker's Delight), the Hacker's Assistant, and any code
3083 submitted by readers. Submitters implicitly agree to this.
3084*/
3085
3086/* Long division, unsigned (64/32 ==> 32).
3087 This procedure performs unsigned "long division" i.e., division of a
308864-bit unsigned dividend by a 32-bit unsigned divisor, producing a
308932-bit quotient. In the overflow cases (divide by 0, or quotient
3090exceeds 32 bits), it returns a remainder of 0xFFFFFFFF (an impossible
3091value).
3092 The dividend is u1 and u0, with u1 being the most significant word.
3093The divisor is parameter v. The value returned is the quotient.
3094 Max line length is 57, to fit in hacker.book. */
3095
3096static Int nlz32(UInt x)
3097{
3098 Int n;
3099 if (x == 0) return(32);
3100 n = 0;
3101 if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
3102 if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
3103 if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
3104 if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
3105 if (x <= 0x7FFFFFFF) {n = n + 1;}
3106 return n;
3107}
3108
3109/* 64 x 32 ==> 32 unsigned division, using only 32 x 32 ==> 32
3110 division as a primitive. */
3111static UInt divlu2(UInt u1, UInt u0, UInt v, UInt *r)
3112{
3113 const UInt b = 65536; // Number base (16 bits).
3114 UInt un1, un0, // Norm. dividend LSD's.
3115 vn1, vn0, // Norm. divisor digits.
3116 q1, q0, // Quotient digits.
3117 un32, un21, un10, // Dividend digit pairs.
3118 rhat; // A remainder.
3119 Int s; // Shift amount for norm.
3120
3121 if (u1 >= v) { // If overflow, set rem.
3122 if (r != NULL) // to an impossible value,
3123 *r = 0xFFFFFFFF; // and return the largest
3124 return 0xFFFFFFFF;} // possible quotient.
3125
3126 s = nlz32(v); // 0 <= s <= 31.
3127 v = v << s; // Normalize divisor.
3128 vn1 = v >> 16; // Break divisor up into
3129 vn0 = v & 0xFFFF; // two 16-bit digits.
3130
3131 un32 = (u1 << s) | ((u0 >> (32 - s)) & (-s >> 31));
3132 un10 = u0 << s; // Shift dividend left.
3133
3134 un1 = un10 >> 16; // Break right half of
3135 un0 = un10 & 0xFFFF; // dividend into two digits.
3136
3137 q1 = un32/vn1; // Compute the first
3138 rhat = un32 - q1*vn1; // quotient digit, q1.
3139 again1:
3140 if (q1 >= b || q1*vn0 > b*rhat + un1) {
3141 q1 = q1 - 1;
3142 rhat = rhat + vn1;
3143 if (rhat < b) goto again1;}
3144
3145 un21 = un32*b + un1 - q1*v; // Multiply and subtract.
3146
3147 q0 = un21/vn1; // Compute the second
3148 rhat = un21 - q0*vn1; // quotient digit, q0.
3149 again2:
3150 if (q0 >= b || q0*vn0 > b*rhat + un0) {
3151 q0 = q0 - 1;
3152 rhat = rhat + vn1;
3153 if (rhat < b) goto again2;}
3154
3155 if (r != NULL) // If remainder is wanted,
3156 *r = (un21*b + un0 - q0*v) >> s; // return it.
3157 return q1*b + q0;
3158}
3159
3160
3161/* 64 x 32 ==> 32 signed division, using only 32 x 32 ==> 32 division
3162 as a primitive. */
3163static Int divls(Int u1, UInt u0, Int v, Int *r)
3164{
3165 Int q, uneg, vneg, diff, borrow;
3166
3167 uneg = u1 >> 31; // -1 if u < 0.
3168 if (uneg) { // Compute the absolute
3169 u0 = -u0; // value of the dividend u.
3170 borrow = (u0 != 0);
3171 u1 = -u1 - borrow;}
3172
3173 vneg = v >> 31; // -1 if v < 0.
3174 v = (v ^ vneg) - vneg; // Absolute value of v.
3175
3176 if ((UInt)u1 >= (UInt)v) goto overflow;
3177
3178 q = divlu2(u1, u0, v, (UInt *)r);
3179
3180 diff = uneg ^ vneg; // Negate q if signs of
3181 q = (q ^ diff) - diff; // u and v differed.
3182 if (uneg && r != NULL)
3183 *r = -*r;
3184
3185 if ((diff ^ q) < 0 && q != 0) { // If overflow,
3186 overflow: // set remainder
3187 if (r != NULL) // to an impossible value,
3188 *r = 0x80000000; // and return the largest
3189 q = 0x80000000;} // possible neg. quotient.
3190 return q;
3191}
3192
3193
3194
3195/* This file contains a program for doing 64/64 ==> 64 division, on a
3196machine that does not have that instruction but that does have
3197instructions for "long division" (64/32 ==> 32). Code for unsigned
3198division is given first, followed by a simple program for doing the
3199signed version by using the unsigned version.
3200 These programs are useful in implementing "long long" (64-bit)
3201arithmetic on a machine that has the long division instruction. It will
3202work on 64- and 32-bit machines, provided the compiler implements long
3203long's (64-bit integers). It is desirable that the machine have the
3204Count Leading Zeros instruction.
3205 In the GNU world, these programs are known as __divdi3 and __udivdi3,
3206and similar names are used here.
3207 This material is not in HD, but may be in a future edition.
3208Max line length is 57, to fit in hacker.book. */
3209
3210
3211static Int nlz64(ULong x)
3212{
3213 Int n;
3214 if (x == 0) return(64);
3215 n = 0;
3216 if (x <= 0x00000000FFFFFFFFULL) {n = n + 32; x = x << 32;}
3217 if (x <= 0x0000FFFFFFFFFFFFULL) {n = n + 16; x = x << 16;}
3218 if (x <= 0x00FFFFFFFFFFFFFFULL) {n = n + 8; x = x << 8;}
3219 if (x <= 0x0FFFFFFFFFFFFFFFULL) {n = n + 4; x = x << 4;}
3220 if (x <= 0x3FFFFFFFFFFFFFFFULL) {n = n + 2; x = x << 2;}
3221 if (x <= 0x7FFFFFFFFFFFFFFFULL) {n = n + 1;}
3222 return n;
3223}
3224
3225// ---------------------------- udivdi3 --------------------------------
3226
3227 /* The variables u0, u1, etc. take on only 32-bit values, but they
3228 are declared long long to avoid some compiler warning messages and to
3229 avoid some unnecessary EXTRs that the compiler would put in, to
3230 convert long longs to ints.
3231
3232 First the procedure takes care of the case in which the divisor is a
3233 32-bit quantity. There are two subcases: (1) If the left half of the
3234 dividend is less than the divisor, one execution of DIVU is all that
3235 is required (overflow is not possible). (2) Otherwise it does two
3236 divisions, using the grade school method, with variables used as
3237 suggested below.
3238
3239 q1 q0
3240 ________
3241 v) u1 u0
3242 q1*v
3243 ____
3244 k u0 */
3245
3246/* These macros must be used with arguments of the appropriate type
3247(unsigned long long for DIVU and long long for DIVS. They are
3248simulations of the presumed machines ops. I.e., they look at only the
3249low-order 32 bits of the divisor, they return garbage if the division
3250overflows, and they return garbage in the high-order half of the
3251quotient doubleword.
3252 In practice, these would be replaced with uses of the machine's DIVU
3253and DIVS instructions (e.g., by using the GNU "asm" facility). */
3254
3255static UInt DIVU ( ULong u, UInt v )
3256{
3257 UInt uHi = (UInt)(u >> 32);
3258 UInt uLo = (UInt)u;
3259 return divlu2(uHi, uLo, v, NULL);
3260}
3261
3262static Int DIVS ( Long u, Int v )
3263{
3264 Int uHi = (Int)(u >> 32);
3265 UInt uLo = (UInt)u;
3266 return divls(uHi, uLo, v, NULL);
3267}
3268
3269/* 64 x 64 ==> 64 unsigned division, using only 32 x 32 ==> 32
3270 division as a primitive. */
3271static ULong udivdi3(ULong u, ULong v)
3272{
3273 ULong u0, u1, v1, q0, q1, k, n;
3274
3275 if (v >> 32 == 0) { // If v < 2**32:
3276 if (u >> 32 < v) // If u/v cannot overflow,
3277 return DIVU(u, v) // just do one division.
3278 & 0xFFFFFFFF;
3279 else { // If u/v would overflow:
3280 u1 = u >> 32; // Break u up into two
3281 u0 = u & 0xFFFFFFFF; // halves.
3282 q1 = DIVU(u1, v) // First quotient digit.
3283 & 0xFFFFFFFF;
3284 k = u1 - q1*v; // First remainder, < v.
3285 q0 = DIVU((k << 32) + u0, v) // 2nd quot. digit.
3286 & 0xFFFFFFFF;
3287 return (q1 << 32) + q0;
3288 }
3289 }
3290 // Here v >= 2**32.
3291 n = nlz64(v); // 0 <= n <= 31.
3292 v1 = (v << n) >> 32; // Normalize the divisor
3293 // so its MSB is 1.
3294 u1 = u >> 1; // To ensure no overflow.
3295 q1 = DIVU(u1, v1) // Get quotient from
3296 & 0xFFFFFFFF; // divide unsigned insn.
3297 q0 = (q1 << n) >> 31; // Undo normalization and
3298 // division of u by 2.
3299 if (q0 != 0) // Make q0 correct or
3300 q0 = q0 - 1; // too small by 1.
3301 if ((u - q0*v) >= v)
3302 q0 = q0 + 1; // Now q0 is correct.
3303 return q0;
3304}
3305
3306
3307// ----------------------------- divdi3 --------------------------------
3308
3309/* This routine presumes that smallish cases (those which can be done in
3310one execution of DIVS) are common. If this is not the case, the test for
3311this case should be deleted.
3312 Note that the test for when DIVS can be used is not entirely
3313accurate. For example, DIVS is not used if v = 0xFFFFFFFF8000000,
3314whereas if could be (if u is sufficiently small in magnitude). */
3315
3316// ------------------------------ cut ----------------------------------
3317
3318static ULong my_llabs ( Long x )
3319{
3320 ULong t = x >> 63;
3321 return (x ^ t) - t;
3322}
3323
3324/* 64 x 64 ==> 64 signed division, using only 32 x 32 ==> 32 division
3325 as a primitive. */
3326static Long divdi3(Long u, Long v)
3327{
3328 ULong au, av;
3329 Long q, t;
3330 au = my_llabs(u);
3331 av = my_llabs(v);
3332 if (av >> 31 == 0) { // If |v| < 2**31 and
3333 // if (v << 32 >> 32 == v) { // If v is in range and
3334 if (au < av << 31) { // |u|/|v| cannot
3335 q = DIVS(u, v); // overflow, use DIVS.
3336 return (q << 32) >> 32;
3337 }
3338 }
3339 q = udivdi3(au,av); // Invoke udivdi3.
3340 t = (u ^ v) >> 63; // If u, v have different
3341 return (q ^ t) - t; // signs, negate q.
3342}
3343
3344// ---------------------------- end cut --------------------------------
3345
sewardj0af71bb2010-07-01 14:50:30 +00003346ULong __udivdi3 (ULong u, ULong v);
njnea2d6fd2010-07-01 00:20:20 +00003347ULong __udivdi3 (ULong u, ULong v)
3348{
3349 return udivdi3(u,v);
3350}
3351
sewardj0af71bb2010-07-01 14:50:30 +00003352Long __divdi3 (Long u, Long v);
njnea2d6fd2010-07-01 00:20:20 +00003353Long __divdi3 (Long u, Long v)
3354{
3355 return divdi3(u,v);
3356}
3357
sewardj0af71bb2010-07-01 14:50:30 +00003358ULong __umoddi3 (ULong u, ULong v);
njnea2d6fd2010-07-01 00:20:20 +00003359ULong __umoddi3 (ULong u, ULong v)
3360{
3361 ULong q = __udivdi3(u, v);
3362 ULong r = u - q * v;
3363 return r;
3364}
3365
sewardj0af71bb2010-07-01 14:50:30 +00003366Long __moddi3 (Long u, Long v);
njnea2d6fd2010-07-01 00:20:20 +00003367Long __moddi3 (Long u, Long v)
3368{
3369 Long q = __divdi3(u, v);
3370 Long r = u - q * v;
3371 return r;
3372}
3373
3374#endif
3375
3376
sewardjde4a1d02002-03-22 01:27:54 +00003377/*--------------------------------------------------------------------*/
njn04e16982005-05-31 00:23:43 +00003378/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00003379/*--------------------------------------------------------------------*/