|
From: <sv...@va...> - 2009-04-03 19:41:26
|
Author: sewardj
Date: 2009-04-03 20:40:46 +0100 (Fri, 03 Apr 2009)
New Revision: 9512
Log:
Handle sys_sigreturn in an extremely kludgey and broken way; but at least
there's some documentation about what it is and how to do better.
Modified:
branches/DARWIN/coregrind/m_syswrap/priv_syswrap-darwin.h
branches/DARWIN/coregrind/m_syswrap/syswrap-darwin.c
branches/DARWIN/coregrind/m_syswrap/syswrap-x86-darwin.c
branches/DARWIN/include/vki/vki-darwin.h
Modified: branches/DARWIN/coregrind/m_syswrap/priv_syswrap-darwin.h
===================================================================
--- branches/DARWIN/coregrind/m_syswrap/priv_syswrap-darwin.h 2009-04-02 07:19:25 UTC (rev 9511)
+++ branches/DARWIN/coregrind/m_syswrap/priv_syswrap-darwin.h 2009-04-03 19:40:46 UTC (rev 9512)
@@ -145,6 +145,7 @@
DECL_TEMPLATE(darwin, sys_ioctl);
DECL_TEMPLATE(darwin, sys_futimes);
DECL_TEMPLATE(darwin, sys_FAKE_SIGRETURN);
+DECL_TEMPLATE(darwin, sys_sigreturn);
// Mach message helpers
DECL_TEMPLATE(darwin, host_info);
Modified: branches/DARWIN/coregrind/m_syswrap/syswrap-darwin.c
===================================================================
--- branches/DARWIN/coregrind/m_syswrap/syswrap-darwin.c 2009-04-02 07:19:25 UTC (rev 9511)
+++ branches/DARWIN/coregrind/m_syswrap/syswrap-darwin.c 2009-04-03 19:40:46 UTC (rev 9512)
@@ -6693,6 +6693,7 @@
an explanation of what follows. */
/* This handles the fake signal-return system call created by
sigframe-x86-darwin.c. */
+ /* See also comments just below on PRE(sys_sigreturn). */
PRINT("FAKE_SIGRETURN ( )");
@@ -6714,6 +6715,82 @@
}
+PRE(sys_sigreturn)
+{
+ /* This is the "real" sigreturn. But because we construct all the
+ signal frames ourselves (of course, in m_sigframe), this cannot
+ happen as a result of normal signal delivery. I think it
+ happens only when doing siglongjmp, in which case Darwin's Libc
+ appears to use it for two different purposes: to mess with the
+ per-thread sigaltstack flags (as per arg 2), or to restore the
+ thread's state from a ucontext* (as per arg 1). */
+
+ PRINT("sigreturn ( uctx=%#lx, infostyle=%#lx )", ARG1, ARG2);
+
+ vg_assert(VG_(is_valid_tid)(tid));
+ vg_assert(tid >= 1 && tid < VG_N_THREADS);
+ vg_assert(VG_(is_running_thread)(tid));
+
+ if (ARG2 == VKI_UC_SET_ALT_STACK) {
+ /* This is confusing .. the darwin kernel sources imply there is
+ a per-thread on-altstack/not-on-altstack flag, which is set
+ by this flag. Just ignore it and claim success for the time
+ being. */
+ VG_(debugLog)(0, "syswrap-darwin",
+ "WARNING: Ignoring sys_sigreturn( ..., "
+ "UC_SET_ALT_STACK );\n");
+ SET_STATUS_Success(0);
+ return;
+ }
+ if (ARG2 == VKI_UC_RESET_ALT_STACK) {
+ /* Ditto */
+ VG_(debugLog)(0, "syswrap-darwin",
+ "WARNING: Ignoring sys_sigreturn( ..., "
+ "UC_RESET_ALT_STACK );\n");
+ SET_STATUS_Success(0);
+ return;
+ }
+
+ /* Otherwise claim this isn't supported. (Could be
+ catastrophic).
+
+ What do we have to do if we do need to support it?
+
+ 1. Change the second argument of VG_(sigframe_destroy) from
+ "Bool isRT" to "UInt sysno", so we can pass the syscall
+ number, so it can distinguish this case from the
+ __NR_DARWIN_FAKE_SIGRETURN case.
+
+ 2. In VG_(sigframe_destroy), look at sysno to distinguish the
+ cases. For __NR_DARWIN_FAKE_SIGRETURN, behave as at present.
+ For this case, restore the thread's CPU state (or at least
+ the integer regs) from the ucontext in ARG1 (and do all the
+ other "signal-returns" stuff too).
+
+ 3. For (2), how do we know where the ucontext is? One way is to
+ temporarily copy ARG1 into this thread's guest_EBX (or any
+ other int reg), and have VG_(sigframe_destroy) read
+ guest_EBX. Why is it ok to trash guest_EBX (or any other int
+ reg)? Because VG_(sigframe_destroy) is just about to
+ overwrite all the regs anyway -- since the primary purpose of
+ calling it is to restore the register state from the ucontext
+ pointed to by ARG1.
+
+ Hey, it's uggerly. But at least it's documented.
+ */
+ /* But in the meantime ... */
+ VG_(debugLog)(0, "syswrap-darwin",
+ "WARNING: Ignoring sys_sigreturn( uctx=..., 0 );\n");
+ VG_(debugLog)(0, "syswrap-darwin",
+ "WARNING: Thread/program/Valgrind "
+ "will likely segfault now.\n");
+ VG_(debugLog)(0, "syswrap-darwin",
+ "WARNING: Please file a bug report at "
+ "http://www.valgrind.org.\n");
+ SET_STATUS_Failure( VKI_ENOSYS );
+}
+
+
/* ---------------------------------------------------------------------
machine-dependent traps
------------------------------------------------------------------ */
@@ -6991,7 +7068,7 @@
GENX_(__NR_setgid, sys_setgid),
MACX_(__NR_setegid, sys_setegid),
MACX_(__NR_seteuid, sys_seteuid),
-// _____(__NR_sigreturn),
+ MACX_(__NR_sigreturn, sys_sigreturn),
// _____(__NR_chud),
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(186)), // ???
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(187)), // ???
Modified: branches/DARWIN/coregrind/m_syswrap/syswrap-x86-darwin.c
===================================================================
--- branches/DARWIN/coregrind/m_syswrap/syswrap-x86-darwin.c 2009-04-02 07:19:25 UTC (rev 9511)
+++ branches/DARWIN/coregrind/m_syswrap/syswrap-x86-darwin.c 2009-04-03 19:40:46 UTC (rev 9512)
@@ -46,7 +46,6 @@
#include "pub_core_mallocfree.h"
#include "pub_core_options.h"
#include "pub_core_scheduler.h"
-#include "pub_core_sigframe.h" // For VG_(sigframe_destroy)()
#include "pub_core_signals.h"
#include "pub_core_syscall.h"
#include "pub_core_syswrap.h"
Modified: branches/DARWIN/include/vki/vki-darwin.h
===================================================================
--- branches/DARWIN/include/vki/vki-darwin.h 2009-04-02 07:19:25 UTC (rev 9511)
+++ branches/DARWIN/include/vki/vki-darwin.h 2009-04-03 19:40:46 UTC (rev 9512)
@@ -504,7 +504,10 @@
#define VKI_SA_ONESHOT SA_RESETHAND
#define VKI_SA_NOMASK SA_NODEFER
+#define VKI_UC_SET_ALT_STACK 0x40000000
+#define VKI_UC_RESET_ALT_STACK 0x80000000
+
#include <sys/errno.h>
#define VKI_EPERM EPERM
|