|
From: Jeremy F. <je...@go...> - 2005-01-15 02:08:02
|
CVS commit by fitzhardinge:
Use sigreturn/rt_sigreturn to finish a signal handler rather than
using a client request. This allows clients to use SA_RESTORER, and
it helps gdb understand the signal stack frames Valgrind generates.
M +3 -5 core.h 1.61
M +3 -6 vg_scheduler.c 1.209
M +2 -24 vg_signals.c 1.110
M +5 -0 x86/core_arch.h 1.18
M +16 -17 x86/helpers.S 1.3
M +272 -184 x86/signal.c 1.10
M +32 -2 x86-linux/syscalls.c 1.12
--- valgrind/coregrind/x86/helpers.S #1.2:1.3
@@ -29,4 +29,5 @@
#include "core_asm.h"
+#include "vki_unistd.h"
/* ------------------ SIMULATED CPU HELPERS ------------------ */
@@ -45,24 +46,20 @@
.global VG_(trampoline_code_length)
.global VG_(tramp_sigreturn_offset)
+.global VG_(tramp_rt_sigreturn_offset)
.global VG_(tramp_syscall_offset)
VG_(trampoline_code_start):
-sigreturn_start:
- subl $20, %esp # allocate arg block
- movl %esp, %edx # %edx == &_zzq_args[0]
- movl $VG_USERREQ__SIGNAL_RETURNS, 0(%edx) # request
- movl $0, 4(%edx) # arg1
- movl $0, 8(%edx) # arg2
- movl $0, 12(%edx) # arg3
- movl $0, 16(%edx) # arg4
- movl %edx, %eax
- # and now the magic sequence itself:
- roll $29, %eax
- roll $3, %eax
- rorl $27, %eax
- rorl $5, %eax
- roll $13, %eax
- roll $19, %eax
- # should never get here
+sigreturn_start:
+ /* This is a very specific sequence which GDB uses to
+ recognize signal handler frames. */
+ popl %eax
+ movl $__NR_sigreturn, %eax
+ int $0x80
+ ud2
+
+rt_sigreturn_start:
+ /* Likewise for rt signal frames */
+ movl $__NR_rt_sigreturn, %eax
+ int $0x80
ud2
@@ -79,4 +76,6 @@
VG_(tramp_sigreturn_offset):
.long sigreturn_start - VG_(trampoline_code_start)
+VG_(tramp_rt_sigreturn_offset):
+ .long rt_sigreturn_start - VG_(trampoline_code_start)
VG_(tramp_syscall_offset):
.long syscall_start - VG_(trampoline_code_start)
--- valgrind/coregrind/x86/signal.c #1.9:1.10
@@ -38,37 +38,17 @@
// during the execution of signal handlers.
-typedef
- struct {
- /* There are two different stack frame formats, depending on
- whether the client set the SA_SIGINFO flag for the handler.
- This structure is put onto the client's stack as part of
- signal delivery, and therefore appears as the signal
- handler's arguments.
-
- The first two words are common for both frame formats -
- they're the return address and the signal number. */
-
- /* Sig handler's return address */
- Addr retaddr;
- /* The arg to the sig handler. We need to inspect this after
- the handler returns, but it's unreasonable to assume that the
- handler won't change it. So we keep a second copy of it in
- sigNo_private. */
- Int sigNo;
-
- /* This is where the two frames start differing. */
- union {
- struct { /* set SA_SIGINFO */
- /* ptr to siginfo_t. */
- Addr psigInfo;
-
- /* ptr to ucontext */
- Addr puContext;
- } sigInfo;
- struct vki_sigcontext sigContext; /* did not set SA_SIGINFO */
- } handlerArgs;
-
- /* The rest are private fields which the handler is unaware of. */
+// Linux has 2 signal frame structures: one for normal signal
+// deliveries, and one for SA_SIGINFO deliveries (also known as RT
+// signals).
+//
+// In theory, so long as we get the arguments to the handler function
+// right, it doesn't matter what the exact layout of the rest of the
+// frame is. Unfortunately, things like gcc's exception unwinding
+// make assumptions about the locations of various parts of the frame,
+// so we need to duplicate it exactly.
+/* Valgrind-specific parts of the signal frame */
+struct vg_sigframe
+{
/* Sanity check word. */
UInt magicPI;
@@ -76,9 +56,4 @@ typedef
UInt handlerflags; /* flags for signal handler */
- /* pointed to by psigInfo */
- vki_siginfo_t sigInfo;
- /* pointed to by puContext */
- struct vki_ucontext uContext;
- struct _vki_fpstate fpstate;
/* Safely-saved version of sigNo, as described above. */
@@ -103,6 +78,38 @@ typedef
move!*/
UInt magicE;
- }
- VgSigFrame;
+};
+
+struct sigframe
+{
+ /* Sig handler's return address */
+ Addr retaddr;
+ Int sigNo;
+
+ struct vki_sigcontext sigContext;
+ struct _vki_fpstate fpstate;
+
+ struct vg_sigframe vg;
+};
+
+struct rt_sigframe
+{
+ /* Sig handler's return address */
+ Addr retaddr;
+ Int sigNo;
+
+ /* ptr to siginfo_t. */
+ Addr psigInfo;
+
+ /* ptr to ucontext */
+ Addr puContext;
+ /* pointed to by psigInfo */
+ vki_siginfo_t sigInfo;
+
+ /* pointed to by puContext */
+ struct vki_ucontext uContext;
+ struct _vki_fpstate fpstate;
+
+ struct vg_sigframe vg;
+};
/*------------------------------------------------------------*/
@@ -343,31 +350,21 @@ static void synth_ucontext(ThreadId tid,
post_reg_write_deliver_signal)
-void VGA_(push_signal_frame)(ThreadId tid, Addr esp_top_of_frame,
- const vki_siginfo_t *siginfo,
- void *handler, UInt flags,
- const vki_sigset_t *mask)
+static Bool extend(ThreadState *tst, Addr addr, SizeT size)
{
- Addr esp;
- ThreadState* tst = VG_(get_ThreadState)(tid);
- VgSigFrame* frame;
- Int sigNo = siginfo->si_signo;
+ ThreadId tid = tst->tid;
Segment *stackseg = NULL;
- esp = esp_top_of_frame;
- esp -= sizeof(VgSigFrame);
- frame = (VgSigFrame*)esp;
-
- if (VG_(extend_stack)((Addr)frame, tst->stack_size)) {
- stackseg = VG_(find_segment)((Addr)frame);
+ if (VG_(extend_stack)(addr, tst->stack_size)) {
+ stackseg = VG_(find_segment)(addr);
if (0 && stackseg)
VG_(printf)("frame=%p seg=%p-%p\n",
- frame, stackseg->addr, stackseg->addr+stackseg->len);
+ addr, stackseg->addr, stackseg->addr+stackseg->len);
}
if (stackseg == NULL ||
- !VG_(is_addressable)((Addr)frame, sizeof(*frame), VKI_PROT_READ|VKI_PROT_WRITE)) {
+ !VG_(is_addressable)(addr, size, VKI_PROT_READ|VKI_PROT_WRITE)) {
VG_(message)(Vg_UserMsg,
"Can't extend stack to %p during signal delivery for thread %d:",
- frame, tid);
+ addr, tid);
if (stackseg == NULL)
VG_(message)(Vg_UserMsg, " no stack segment");
@@ -377,67 +374,26 @@ void VGA_(push_signal_frame)(ThreadId ti
/* set SIGSEGV to default handler */
VG_(set_default_handler)(VKI_SIGSEGV);
- VG_(synth_fault_mapping)(tid, (Addr)frame);
+ VG_(synth_fault_mapping)(tid, addr);
/* The whole process should be about to die, since the default
action of SIGSEGV to kill the whole process. */
- return;
+ return False;
}
/* For tracking memory events, indicate the entire frame has been
- * allocated, but pretend that only the first four words are written */
- VG_TRACK( new_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) );
+ allocated. */
+ VG_TRACK( new_mem_stack_signal, addr, size );
- /* Assert that the frame is placed correctly. */
- vg_assert( (sizeof(VgSigFrame) & 0x3) == 0 );
- vg_assert( ((Char*)(&frame->magicE)) + sizeof(UInt)
- == ((Char*)(esp_top_of_frame)) );
+ return True;
+}
- /* retaddr, sigNo, psigInfo, puContext fields are to be written */
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame",
- (Addr)frame, offsetof(VgSigFrame, handlerArgs) );
- frame->retaddr = (UInt)VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
- frame->sigNo = sigNo;
+static void build_vg_sigframe(struct vg_sigframe *frame,
+ ThreadState *tst,
+ const vki_sigset_t *mask,
+ UInt flags,
+ Int sigNo)
+{
frame->sigNo_private = sigNo;
- VG_TRACK( post_mem_write, (Addr)frame, offsetof(VgSigFrame, handlerArgs) );
-
- if (flags & VKI_SA_SIGINFO) {
- /* if the client asked for a siginfo delivery, then build the stack that way */
-
- /* pointers to siginfo and ucontext */
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)",
- (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
- frame->handlerArgs.sigInfo.psigInfo = (Addr)&frame->sigInfo;
- frame->handlerArgs.sigInfo.puContext = (Addr)&frame->uContext;
- VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
-
- /* siginfo */
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)",
- (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
- VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
- VG_TRACK( post_mem_write, (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
-
- /* ucontext */
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (ucontext)",
- (Addr)&frame->uContext, sizeof(frame->uContext) );
- synth_ucontext(tid, siginfo, mask, &frame->uContext, &frame->fpstate);
- VG_TRACK( post_mem_write, (Addr)&frame->uContext, sizeof(frame->uContext) );
- } else {
- struct vki_ucontext uc;
-
- /* non-siginfo: just put the sigcontext there */
-
- synth_ucontext(tid, siginfo, mask, &uc, &frame->fpstate);
-
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (sigcontext)",
- (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigContext) );
- VG_(memcpy)(&frame->handlerArgs.sigContext, &uc.uc_mcontext,
- sizeof(struct vki_sigcontext));
- VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs,
- sizeof(frame->handlerArgs.sigContext) );
-
- frame->handlerArgs.sigContext.oldmask = tst->sig_mask.sig[0];
- }
-
frame->magicPI = 0x31415927;
@@ -459,7 +415,112 @@ void VGA_(push_signal_frame)(ThreadId ti
frame->magicE = 0x27182818;
+}
+
+static Addr build_sigframe(ThreadState *tst,
+ Addr esp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ void *handler, UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer)
+{
+ struct sigframe *frame;
+ Addr esp = esp_top_of_frame;
+ Int sigNo = siginfo->si_signo;
+ struct vki_ucontext uc;
+
+ esp -= sizeof(*frame);
+ esp = ROUNDDN(esp, 16);
+ frame = (struct sigframe *)esp;
+
+ if (!extend(tst, esp, sizeof(*frame)))
+ return esp_top_of_frame;
+
+ /* retaddr, sigNo, siguContext fields are to be written */
+ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
+ esp, offsetof(struct sigframe, vg) );
+
+ frame->sigNo = sigNo;
+
+ if (flags & VKI_SA_RESTORER)
+ frame->retaddr = (Addr)restorer;
+ else {
+ if (flags & VKI_SA_SIGINFO)
+ frame->retaddr = (UInt)VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
+ else
+ frame->retaddr = (UInt)VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
+ }
+
+ synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate);
+
+ VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,
+ sizeof(struct vki_sigcontext));
+ frame->sigContext.oldmask = tst->sig_mask.sig[0];
+
+ VG_TRACK( post_mem_write, esp, offsetof(struct sigframe, vg) );
+
+ build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
+
+ return esp;
+}
+
+static Addr build_rt_sigframe(ThreadState *tst,
+ Addr esp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ void *handler, UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer)
+{
+ struct rt_sigframe *frame;
+ Addr esp = esp_top_of_frame;
+ Int sigNo = siginfo->si_signo;
+
+ esp -= sizeof(*frame);
+ esp = ROUNDDN(esp, 16);
+ frame = (struct rt_sigframe *)esp;
+
+ if (!extend(tst, esp, sizeof(*frame)))
+ return esp_top_of_frame;
+
+ /* retaddr, sigNo, pSiginfo, puContext fields are to be written */
+ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame",
+ esp, offsetof(struct rt_sigframe, vg) );
+
+ frame->sigNo = sigNo;
+
+ if (flags & VKI_SA_RESTORER)
+ frame->retaddr = (Addr)restorer;
+ else {
+ if (flags & VKI_SA_SIGINFO)
+ frame->retaddr = (UInt)VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
+ else
+ frame->retaddr = (UInt)VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
+ }
+
+ frame->psigInfo = (Addr)&frame->sigInfo;
+ frame->puContext = (Addr)&frame->uContext;
+ VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
+ synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate);
+
+ VG_TRACK( post_mem_write, esp, offsetof(struct rt_sigframe, vg) );
+
+ build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
+
+ return esp;
+}
+
+void VGA_(push_signal_frame)(ThreadId tid, Addr esp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ void *handler, UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer)
+{
+ Addr esp;
+ ThreadState* tst = VG_(get_ThreadState)(tid);
+
+ if (flags & VKI_SA_SIGINFO)
+ esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo, handler, flags, mask, restorer);
+ else
+ esp = build_sigframe(tst, esp_top_of_frame, siginfo, handler, flags, mask, restorer);
- /* Ensure 'tid' and 'tst' correspond */
- vg_assert(& VG_(threads)[tid] == tst);
/* Set the thread so it will next run the handler. */
/* tst->m_esp = esp; */
@@ -476,32 +537,38 @@ void VGA_(push_signal_frame)(ThreadId ti
}
-Int VGA_(pop_signal_frame)(ThreadId tid)
+static Bool restore_vg_sigframe(ThreadState *tst, struct vg_sigframe *frame, Int *sigNo)
{
- Addr esp;
- VgSigFrame* frame;
- ThreadState* tst;
- struct vki_sigcontext *sc;
-
- vg_assert(VG_(is_valid_tid)(tid));
- tst = & VG_(threads)[tid];
+ if (frame->magicPI != 0x31415927 ||
+ frame->magicE != 0x27182818) {
+ VG_(message)(Vg_UserMsg, "Thread %d return signal frame corrupted. Killing process.",
+ tst->tid);
+ VG_(set_default_handler)(VKI_SIGSEGV);
+ VG_(synth_fault)(tst->tid);
+ *sigNo = VKI_SIGSEGV;
+ return False;
+ }
- /* Correctly reestablish the frame base address. */
- esp = tst->arch.m_esp;
- frame = (VgSigFrame*)
- (esp -4 /* because the handler's RET pops the RA */
- +20 /* because signalreturn_bogusRA pushes 5 words */);
+ tst->sig_mask = frame->mask;
- vg_assert(frame->magicPI == 0x31415927);
- vg_assert(frame->magicE == 0x27182818);
+ if (VG_(needs).shadow_regs) {
+ tst->arch.sh_eax = frame->sh_eax;
+ tst->arch.sh_ecx = frame->sh_ecx;
+ tst->arch.sh_edx = frame->sh_edx;
+ tst->arch.sh_ebx = frame->sh_ebx;
+ tst->arch.sh_ebp = frame->sh_ebp;
+ tst->arch.sh_esp = frame->sh_esp;
+ tst->arch.sh_esi = frame->sh_esi;
+ tst->arch.sh_edi = frame->sh_edi;
+ tst->arch.sh_eflags = frame->sh_eflags;
+ }
- /* Mark the frame structure as nonaccessible. */
- VG_TRACK( die_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) );
+ *sigNo = frame->sigNo_private;
- /* restore machine state */
- if (frame->handlerflags & VKI_SA_SIGINFO)
- sc = &frame->uContext.uc_mcontext;
- else
- sc = &frame->handlerArgs.sigContext;
+ return True;
+}
+static void restore_sigcontext(ThreadState *tst, struct vki_sigcontext *sc,
+ struct _vki_fpstate *fpstate)
+{
tst->arch.m_eax = sc->eax;
tst->arch.m_ecx = sc->ecx;
@@ -522,28 +589,49 @@ Int VGA_(pop_signal_frame)(ThreadId tid)
tst->arch.m_gs = sc->gs;
- restore_i387(&tst->arch, &frame->fpstate);
+ restore_i387(&tst->arch, fpstate);
+}
- if (VG_(needs).shadow_regs) {
- tst->arch.sh_eax = frame->sh_eax;
- tst->arch.sh_ecx = frame->sh_ecx;
- tst->arch.sh_edx = frame->sh_edx;
- tst->arch.sh_ebx = frame->sh_ebx;
- tst->arch.sh_ebp = frame->sh_ebp;
- tst->arch.sh_esp = frame->sh_esp;
- tst->arch.sh_esi = frame->sh_esi;
- tst->arch.sh_edi = frame->sh_edi;
- tst->arch.sh_eflags = frame->sh_eflags;
- }
+static SizeT restore_sigframe(ThreadState *tst, struct sigframe *frame, Int *sigNo)
+{
+ if (restore_vg_sigframe(tst, &frame->vg, sigNo))
+ restore_sigcontext(tst, &frame->sigContext, &frame->fpstate);
+
+ return sizeof(*frame);
+}
+
+static SizeT restore_rt_sigframe(ThreadState *tst, struct rt_sigframe *frame, Int *sigNo)
+{
+ if (restore_vg_sigframe(tst, &frame->vg, sigNo))
+ restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
+
+ return sizeof(*frame);
+}
+
+void VGA_(signal_return)(ThreadId tid, Bool isRT)
+{
+ Addr esp;
+ ThreadState* tst;
+ SizeT size;
+ Int sigNo;
+
+ tst = VG_(get_ThreadState)(tid);
+
+ /* Correctly reestablish the frame base address. */
+ esp = tst->arch.m_esp;
+
+ if (!isRT)
+ size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo);
+ else
+ size = restore_rt_sigframe(tst, (struct rt_sigframe *)esp, &sigNo);
+
+ VG_TRACK( die_mem_stack_signal, esp, size );
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugMsg,
- "vg_pop_signal_frame (thread %d): valid magic; EIP=%p",
- tid, sc->eip);
-
- tst->sig_mask = frame->mask;
+ "vg_pop_signal_frame (thread %d): isRT=%d valid magic; EIP=%p",
+ tid, isRT, tst->arch.m_eip);
- /* don't use the copy exposed to the handler; it might have changed
- it. */
- return frame->sigNo_private;
+ /* tell the tools */
+ VG_TRACK( post_deliver_signal, tid, sigNo );
}
--- valgrind/coregrind/x86/core_arch.h #1.17:1.18
@@ -351,4 +351,9 @@ struct arch_thread_aux {
/* ---------------------------------------------------------------------
+ Signal stuff (should be plat)
+ ------------------------------------------------------------------ */
+void VGA_(signal_return)(ThreadId tid, Bool isRT);
+
+/* ---------------------------------------------------------------------
Miscellaneous constants
------------------------------------------------------------------ */
--- valgrind/coregrind/core.h #1.60:1.61
@@ -869,7 +869,4 @@ extern void VG_(do_pthread_sigmask_SCSS_
vki_sigset_t* oldset );
-/* Restore thread's state on return from a signal handler */
-extern void VG_(signal_returns) ( ThreadId tid );
-
/* Handy utilities to block/restore all host signals. */
extern void VG_(block_all_host_signals)
@@ -1667,4 +1664,5 @@ extern const Char VG_(trampoline_code_st
extern const Int VG_(trampoline_code_length);
extern const Int VG_(tramp_sigreturn_offset);
+extern const Int VG_(tramp_rt_sigreturn_offset);
extern const Int VG_(tramp_syscall_offset);
@@ -1764,6 +1762,6 @@ extern void VGA_(push_signal_frame) ( Th
const vki_siginfo_t *siginfo,
void *handler, UInt flags,
- const vki_sigset_t *mask);
-extern Int VGA_(pop_signal_frame) ( ThreadId tid );
+ const vki_sigset_t *mask,
+ void *restorer );
#define MY__STRING(__str) #__str
--- valgrind/coregrind/vg_scheduler.c #1.208:1.209
@@ -536,5 +536,5 @@ UInt run_thread_for_a_while ( ThreadId t
if (VG_(is_VCPU_thread)(tid))
VG_(save_thread_state) ( tid );
- else
+
vg_assert(VG_(get_VCPU_tid)() == VG_INVALID_THREADID);
@@ -983,8 +983,4 @@ void do_client_request ( ThreadId tid )
break;
- case VG_USERREQ__SIGNAL_RETURNS:
- VG_(signal_returns)(tid);
- break;
-
case VG_USERREQ__PRINTF: {
int count =
@@ -1097,4 +1093,5 @@ void do_client_request ( ThreadId tid )
case VG_USERREQ__GET_SIGRT_MAX:
case VG_USERREQ__ALLOC_RTSIG:
+ case VG_USERREQ__SIGNAL_RETURNS: /* not pthreads, but obsolete */
VG_(message)(Vg_UserMsg, "It looks like you've got an old libpthread.so* ");
VG_(message)(Vg_UserMsg, "installed in \"%s\".", VG_(libdir));
--- valgrind/coregrind/vg_signals.c #1.109:1.110
@@ -749,31 +749,9 @@ void vg_push_signal_frame ( ThreadId tid
vg_scss.scss_per_sig[sigNo].scss_handler,
vg_scss.scss_per_sig[sigNo].scss_flags,
- &vg_scss.scss_per_sig[sigNo].scss_mask);
-}
-
-/* Clear the signal frame created by vg_push_signal_frame, restore the
- simulated machine state. */
-static
-void vg_pop_signal_frame ( ThreadId tid )
-{
- Int sigNo = VGA_(pop_signal_frame)(tid);
-
- /* Notify tools */
- VG_TRACK( post_deliver_signal, tid, sigNo );
+ &vg_scss.scss_per_sig[sigNo].scss_mask,
+ vg_scss.scss_per_sig[sigNo].scss_restorer);
}
-/* A handler is returning. Restore the machine state from the stacked
- VgSigContext and continue with whatever was going on before the
- handler ran. Returns the SA_RESTART syscall-restartability-status
- of the delivered signal. */
-
-void VG_(signal_returns) ( ThreadId tid )
-{
- /* Pop the signal frame and restore tid's status to what it was
- before the signal was delivered. */
- vg_pop_signal_frame(tid);
-}
-
static const Char *signame(Int sigNo)
{
--- valgrind/coregrind/x86-linux/syscalls.c #1.11:1.12
@@ -463,4 +463,34 @@ PRE(sys_clone, Special)
}
+PRE(sys_sigreturn, Special)
+{
+ PRINT("sigreturn ( )");
+
+ /* Adjust esp to point to start of frame; skip back up over
+ sigreturn sequence's "popl %eax" and handler ret addr */
+ tst->arch.m_esp -= sizeof(Addr)+sizeof(Word);
+
+ /* This is only so that the EIP is (might be) useful to report if
+ something goes wrong in the sigreturn */
+ restart_syscall(&tst->arch);
+
+ VGA_(signal_return)(tid, False);
+}
+
+PRE(sys_rt_sigreturn, Special)
+{
+ PRINT("rt_sigreturn ( )");
+
+ /* Adjust esp to point to start of frame; skip back up over handler
+ ret addr */
+ tst->arch.m_esp -= sizeof(Addr);
+
+ /* This is only so that the EIP is (might be) useful to report if
+ something goes wrong in the sigreturn */
+ restart_syscall(&tst->arch);
+
+ VGA_(signal_return)(tid, True);
+}
+
PRE(sys_modify_ldt, Special)
{
@@ -698,5 +728,5 @@ const struct SyscallTableEntry VGA_(sysc
GENXY(__NR_ipc, sys_ipc), // 117
GENX_(__NR_fsync, sys_fsync), // 118
- // (__NR_sigreturn, sys_sigreturn), // 119 ?/Linux
+ PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux
PLAX_(__NR_clone, sys_clone), // 120
@@ -765,5 +795,5 @@ const struct SyscallTableEntry VGA_(sysc
LINXY(__NR_getresgid, sys_getresgid16), // 171
LINX_(__NR_prctl, sys_prctl), // 172
- // (__NR_rt_sigreturn, sys_rt_sigreturn), // 173 x86/Linux only?
+ PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 173 x86/Linux only?
GENXY(__NR_rt_sigaction, sys_rt_sigaction), // 174
|