aboutsummaryrefslogtreecommitdiff
path: root/coregrind/m_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'coregrind/m_main.c')
-rw-r--r--coregrind/m_main.c215
1 files changed, 165 insertions, 50 deletions
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 9f98e11a7..1821c9412 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -7,7 +7,7 @@
This file is part of Valgrind, a dynamic binary instrumentation
framework.
- Copyright (C) 2000-2013 Julian Seward
+ Copyright (C) 2000-2015 Julian Seward
jseward@acm.org
This program is free software; you can redistribute it and/or
@@ -133,11 +133,8 @@ static void usage_NORETURN ( Bool debug_help )
" load default suppressions [yes]\n"
" --suppressions=<filename> suppress errors described in <filename>\n"
" --gen-suppressions=no|yes|all print suppressions for errors? [no]\n"
-" --db-attach=no|yes start debugger when errors detected? [no]\n"
-" Note: deprecated feature\n"
-" --db-command=<command> command to start debugger [%s -nw %%f %%p]\n"
" --input-fd=<number> file descriptor for input [0=stdin]\n"
-" --dsymutil=no|yes run dsymutil on Mac OS X when helpful? [no]\n"
+" --dsymutil=no|yes run dsymutil on Mac OS X when helpful? [yes]\n"
" --max-stackframe=<number> assume stack switch for SP changes larger\n"
" than <number> bytes [2000000]\n"
" --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
@@ -163,13 +160,13 @@ static void usage_NORETURN ( Bool debug_help )
" --allow-mismatched-debuginfo=no|yes [no]\n"
" for the above two flags only, accept debuginfo\n"
" objects that don't \"match\" the main object\n"
-" --smc-check=none|stack|all|all-non-file [stack]\n"
+" --smc-check=none|stack|all|all-non-file [all-non-file]\n"
" checks for self-modifying code: none, only for\n"
" code found in stacks, for all code, or for all\n"
" code except that from file-backed mappings\n"
" --read-inline-info=yes|no read debug info about inlined function calls\n"
" and use it to do better stack traces. [yes]\n"
-" on Linux/Android for Memcheck/Helgrind/DRD\n"
+" on Linux/Android/Solaris for Memcheck/Helgrind/DRD\n"
" only. [no] for all other tools and platforms.\n"
" --read-var-info=yes|no read debug info on stack and global variables\n"
" and use it to print better error messages in\n"
@@ -181,7 +178,7 @@ static void usage_NORETURN ( Bool debug_help )
" --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
" --sim-hints=hint1,hint2,... activate unusual sim behaviours [none] \n"
" where hint is one of:\n"
-" lax-ioctls fuse-compatible enable-outer\n"
+" lax-ioctls lax-doors fuse-compatible enable-outer\n"
" no-inner-prefix no-nptl-pthread-stackcache none\n"
" --fair-sched=no|yes|try schedule threads fairly on multicore systems [no]\n"
" --kernel-variant=variant1,variant2,...\n"
@@ -295,13 +292,12 @@ static void usage_NORETURN ( Bool debug_help )
" Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
"\n"
" %s is %s\n"
-" Valgrind is Copyright (C) 2000-2013, and GNU GPL'd, by Julian Seward et al.\n"
-" LibVEX is Copyright (C) 2004-2013, and GNU GPL'd, by OpenWorks LLP et al.\n"
+" Valgrind is Copyright (C) 2000-2015, and GNU GPL'd, by Julian Seward et al.\n"
+" LibVEX is Copyright (C) 2004-2015, and GNU GPL'd, by OpenWorks LLP et al.\n"
"\n"
" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
"\n";
- const HChar* gdb_path = GDB_PATH;
HChar default_alignment[30]; // large enough
HChar default_redzone_size[30]; // large enough
@@ -319,7 +315,6 @@ static void usage_NORETURN ( Bool debug_help )
/* 'usage1' a type as described after each arg. */
VG_(printf)(usage1,
VG_(clo_vgdb_error) /* int */,
- gdb_path /* char* */,
default_alignment /* char* */,
default_redzone_size /* char* */,
VG_(clo_vgdb_poll) /* int */,
@@ -410,7 +405,7 @@ static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
// running in an outer, to have "no-inner-prefix" enabled
// as early as possible.
else if VG_USETX_CLO (str, "--sim-hints",
- "lax-ioctls,fuse-compatible,"
+ "lax-ioctls,lax-doors,fuse-compatible,"
"enable-outer,no-inner-prefix,"
"no-nptl-pthread-stackcache",
VG_(clo_sim_hints)) {}
@@ -617,7 +612,6 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
}
else if VG_BOOL_CLO(arg, "--vgdb-shadow-registers",
VG_(clo_vgdb_shadow_registers)) {}
- else if VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach)) {}
else if VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle)) {}
else if VG_STR_CLO (arg, "--soname-synonyms",VG_(clo_soname_synonyms)) {}
else if VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit)) {}
@@ -682,7 +676,6 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
else if VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls)) {}
else if VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb)) {}
- else if VG_STR_CLO (arg, "--db-command", VG_(clo_db_command)) {}
else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
else if VG_BOOL_CLO(arg, "--read-inline-info", VG_(clo_read_inline_info)) {}
else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
@@ -902,11 +895,7 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
/* END command-line processing loop */
- /* Notify about deprecated features */
- if (VG_(clo_db_attach))
- VG_(umsg)
- ("\nWarning: --db-attach is a deprecated feature which will be\n"
- " removed in the next release. Use --vgdb-error=1 instead\n\n");
+ /* Notify about deprecated features here. */
/* Determine the path prefix for vgdb */
if (VG_(clo_vgdb_prefix) == NULL)
@@ -998,16 +987,6 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
"--gen-suppressions=yes.\n");
}
- /* We can't allow DB attaching (or we maybe could, but results
- could be chaotic ..) since it requires user input. Hence
- disallow. */
- if (VG_(clo_db_attach)) {
- VG_(fmsg_bad_option)(
- "--xml=yes together with --db-attach=yes",
- "--db-attach=yes is not allowed with --xml=yes\n"
- "because it would require user input.\n");
- }
-
/* Disallow dump_error in XML mode; sounds like a recipe for
chaos. No big deal; dump_error is a flag for debugging V
itself. */
@@ -1443,7 +1422,7 @@ static void print_preamble ( Bool logging_to_fd,
VG_(umsg)("\n");
if (VG_(clo_verbosity) > 1) {
-# if !defined(VGO_darwin)
+# if defined(VGO_linux)
SysRes fd;
# endif
VexArch vex_arch;
@@ -1457,7 +1436,7 @@ static void print_preamble ( Bool logging_to_fd,
* (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
}
-# if !defined(VGO_darwin)
+# if defined(VGO_linux)
VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
if (sr_isError(fd)) {
@@ -1479,7 +1458,7 @@ static void print_preamble ( Bool logging_to_fd,
VG_(message)(Vg_DebugMsg, "\n");
VG_(close)(fdno);
}
-# else
+# elif defined(VGO_darwin)
VG_(message)(Vg_DebugMsg, "Output from sysctl({CTL_KERN,KERN_VERSION}):\n");
/* Note: preferable to use sysctlbyname("kern.version", kernelVersion, &len, NULL, 0)
however that syscall is OS X 10.10+ only. */
@@ -1490,6 +1469,20 @@ static void print_preamble ( Bool logging_to_fd,
VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), kernelVersion, &len, NULL, 0);
VG_(message)(Vg_DebugMsg, " %s\n", kernelVersion);
VG_(free)( kernelVersion );
+# elif defined(VGO_solaris)
+ /* There is no /proc/version file on Solaris so we try to get some
+ system information using the uname(2) syscall. */
+ {
+ struct vki_utsname uts;
+
+ VG_(message)(Vg_DebugMsg, "System information:\n");
+ SysRes res = VG_(do_syscall1)(__NR_uname, (UWord)&uts);
+ if (sr_isError(res))
+ VG_(message)(Vg_DebugMsg, " uname() failed\n");
+ else
+ VG_(message)(Vg_DebugMsg, " %s %s %s %s\n",
+ uts.sysname, uts.release, uts.version, uts.machine);
+ }
# endif
VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
@@ -1539,8 +1532,8 @@ static void setup_file_descriptors(void)
# endif
if (show)
- VG_(printf)("fd limits: host, before: cur %lu max %lu\n",
- (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
+ VG_(printf)("fd limits: host, before: cur %llu max %llu\n",
+ (ULong)rl.rlim_cur, (ULong)rl.rlim_max);
/* Work out where to move the soft limit to. */
if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
@@ -1559,7 +1552,7 @@ static void setup_file_descriptors(void)
if (show) {
VG_(printf)("fd limits: host, after: cur %lu max %lu\n",
(UWord)rl.rlim_cur, (UWord)rl.rlim_max);
- VG_(printf)("fd limits: guest : cur %u max %u\n",
+ VG_(printf)("fd limits: guest : cur %d max %d\n",
VG_(fd_soft_limit), VG_(fd_hard_limit));
}
@@ -1945,7 +1938,7 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
if (!need_help) {
VG_(debugLog)(1, "main", "Create initial image\n");
-# if defined(VGO_linux) || defined(VGO_darwin)
+# if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris)
the_iicii.argv = argv;
the_iicii.envp = envp;
the_iicii.toolname = toolname;
@@ -1978,16 +1971,21 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
// p: setup file descriptors
// p: ii_create_image for VG_(client_auxv) setup.
//--------------------------------------------------------------
-#if !defined(VGO_linux)
- // client shouldn't be using /proc!
VG_(cl_cmdline_fd) = -1;
VG_(cl_auxv_fd) = -1;
-#else
+#if defined(VGO_solaris)
+ VG_(cl_psinfo_fd) = -1;
+#endif
+
+#if defined(VGO_linux) || defined(VGO_solaris)
if (!need_help) {
HChar buf[50]; // large enough
HChar buf2[VG_(mkstemp_fullname_bufsz)(sizeof buf - 1)];
- HChar nul[1];
Int fd, r;
+
+#if defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE)
+ /* Fake /proc/<pid>/cmdline only on Linux and Solaris if supported. */
+ HChar nul[1];
const HChar* exename;
VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
@@ -2009,8 +2007,8 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
}
/* Don't bother to seek the file back to the start; instead do
- it every time a copy of it is given out (by PRE(sys_open)).
- That is probably more robust across fork() etc. */
+ it every time a copy of it is given out (by PRE(sys_open) or
+ PRE(sys_openat)). That is probably more robust across fork() etc. */
/* Now delete it, but hang on to the fd. */
r = VG_(unlink)( buf2 );
@@ -2018,7 +2016,9 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
VG_(err_config_error)("Can't delete client cmdline file in %s\n", buf2);
VG_(cl_cmdline_fd) = fd;
+#endif // defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE)
+ /* Fake /proc/<pid>/auxv on both Linux and Solaris. */
VG_(debugLog)(1, "main", "Create fake /proc/<pid>/auxv\n");
VG_(sprintf)(buf, "proc_%d_auxv", VG_(getpid)());
@@ -2047,6 +2047,24 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
VG_(err_config_error)("Can't delete client auxv file in %s\n", buf2);
VG_(cl_auxv_fd) = fd;
+
+#if defined(VGO_solaris)
+ /* Fake /proc/<pid>/psinfo on Solaris.
+ * Contents will be fetched and partially faked later on the fly. */
+ VG_(debugLog)(1, "main", "Create fake /proc/<pid>/psinfo\n");
+
+ VG_(sprintf)(buf, "proc_%d_psinfo", VG_(getpid)());
+ fd = VG_(mkstemp)( buf, buf2 );
+ if (fd == -1)
+ VG_(err_config_error)("Can't create client psinfo file in %s\n", buf2);
+
+ /* Now delete it, but hang on to the fd. */
+ r = VG_(unlink)( buf2 );
+ if (r)
+ VG_(err_config_error)("Can't delete client psinfo file in %s\n", buf2);
+
+ VG_(cl_psinfo_fd) = fd;
+#endif /* VGO_solaris */
}
#endif
@@ -2165,6 +2183,8 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
iters = 10;
# elif defined(VGO_darwin)
iters = 3;
+# elif defined(VGO_solaris)
+ iters = 10;
# else
# error "Unknown plat"
# endif
@@ -2183,6 +2203,10 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
VG_(init_preopened_fds)();
}
+#if defined(VGO_solaris)
+ VG_(syswrap_init)();
+#endif
+
//--------------------------------------------------------------
// Load debug info for the existing segments.
// p: setup_code_redirect_table [so that redirs can be recorded]
@@ -2207,7 +2231,7 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2",
VG_(free), sizeof(Addr_n_ULong) );
-# if defined(VGO_linux)
+# if defined(VGO_linux) || defined(VGO_solaris)
{ Addr* seg_starts;
Int n_seg_starts;
Addr_n_ULong anu;
@@ -2445,7 +2469,19 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
// VG_(ii_create_image) [for 'the_iicii' initial info]
//--------------------------------------------------------------
VG_(debugLog)(1, "main", "Finalise initial image\n");
- VG_(ii_finalise_image)( the_iifii );
+ { /* Mark the main thread as running while we tell the tool about
+ the client memory which could be tracked during initial image
+ finalisation. So the tool can associate that memory with the
+ main thread. */
+ vg_assert(VG_(running_tid) == VG_INVALID_THREADID);
+ VG_(running_tid) = tid_main;
+
+ VG_(ii_finalise_image)( the_iifii );
+
+ /* Clear the running thread indicator */
+ VG_(running_tid) = VG_INVALID_THREADID;
+ vg_assert(VG_(running_tid) == VG_INVALID_THREADID);
+ }
//--------------------------------------------------------------
// Initialise the signal handling subsystem
@@ -2662,10 +2698,10 @@ void shutdown_actions_NORETURN( ThreadId tid,
sys_exit, do likewise; if the (last) thread stopped due to a fatal
signal, terminate the entire system with that same fatal signal. */
VG_(debugLog)(1, "core_os",
- "VG_(terminate_NORETURN)(tid=%lld)\n", (ULong)tid);
+ "VG_(terminate_NORETURN)(tid=%u)\n", tid);
switch (tids_schedretcode) {
- case VgSrc_ExitThread: /* the normal way out (Linux) */
+ case VgSrc_ExitThread: /* the normal way out (Linux, Solaris) */
case VgSrc_ExitProcess: /* the normal way out (Darwin) */
/* Change the application return code to user's return code,
if an error was found */
@@ -3431,13 +3467,92 @@ void _start_in_C_darwin ( UWord* pArgc )
VG_(exit)(r);
}
-
+/*====================================================================*/
+/*=== Getting to main() alive: Solaris ===*/
+/*====================================================================*/
+#elif defined(VGO_solaris)
+#if defined(VGP_x86_solaris)
+/* The kernel hands control to _start, which extracts the initial stack
+ pointer and calls onwards to _start_in_C_solaris. This also switches to
+ the new stack. */
+asm("\n"
+ "\t.text\n"
+ "\t.globl _start\n"
+ "\t.type _start, @function\n"
+ "_start:\n"
+ /* Set up the new stack in %eax. */
+ "\tmovl $vgPlain_interim_stack, %eax\n"
+ "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
+ "\taddl $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)", %eax\n"
+ "\tandl $~15, %eax\n"
+ /* Install it, and collect the original one. */
+ "\txchgl %eax, %esp\n"
+ "\tsubl $12, %esp\n" /* Keep stack 16-byte aligned. */
+ /* Call _start_in_C_solaris, passing it the startup %esp. */
+ "\tpushl %eax\n"
+ "\tcall _start_in_C_solaris\n"
+ /* NOTREACHED */
+ "\thlt\n"
+ "\t.previous\n"
+);
+#elif defined(VGP_amd64_solaris)
+asm("\n"
+ ".text\n"
+ "\t.globl _start\n"
+ "\t.type _start, @function\n"
+ "_start:\n"
+ /* Set up the new stack in %rdi. */
+ "\tmovq $vgPlain_interim_stack, %rdi\n"
+ "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
+ "\taddq $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)", %rdi\n"
+ "\tandq $~15, %rdi\n"
+ /* Install it, and collect the original one. */
+ "\txchgq %rdi, %rsp\n"
+ /* Call _start_in_C_solaris, passing it the startup %rsp. */
+ "\tcall _start_in_C_solaris\n"
+ /* NOTREACHED */
+ "\thlt\n"
+ ".previous\n"
+);
#else
+# error "Unknown Solaris platform"
+#endif
+
+void *memcpy(void *dest, const void *src, size_t n);
+void *memcpy(void *dest, const void *src, size_t n) {
+ return VG_(memcpy)(dest, src, n);
+}
+
+__attribute__ ((used))
+void _start_in_C_solaris ( UWord* pArgc );
+__attribute__ ((used))
+void _start_in_C_solaris ( UWord* pArgc )
+{
+ Int r;
+ Word argc = pArgc[0];
+ HChar** argv = (HChar**)&pArgc[1];
+ HChar** envp = (HChar**)&pArgc[1 + argc + 1];
+
+ VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
+ VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
+ the_iicii.sp_at_startup = (Addr)pArgc;
+
+ r = valgrind_main((Int)argc, argv, envp);
+ /* NOTREACHED */
+ VG_(exit)(r);
+}
+
+#else
# error "Unknown OS"
#endif
+Addr VG_(get_initial_client_SP)( void )
+{
+ return the_iifii.initial_client_SP;
+}
+
/*====================================================================*/
/*=== {u,}{div,mod}di3 replacements ===*/
/*====================================================================*/
@@ -3864,9 +3979,9 @@ __fixunsdfdi(double a)
/*=== Dummy _voucher_mach_msg_set for OSX 10.10 ===*/
/*====================================================================*/
-#if defined(VGO_darwin) && DARWIN_VERS == DARWIN_10_10
+#if defined(VGO_darwin) && DARWIN_VERS >= DARWIN_10_10
-/* Builds on MacOSX 10.10 seem to need this for some reason. */
+/* Builds on MacOSX 10.10+ seem to need this for some reason. */
/* extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg)
__attribute__((weak_import));
I haven't a clue what the return value means, so just return 0.