|
From: <sv...@va...> - 2006-01-03 04:08:37
|
Author: sewardj
Date: 2006-01-03 04:08:32 +0000 (Tue, 03 Jan 2006)
New Revision: 5483
Log:
First cut at signal frame build/removal for ppc64-linux. Ghastly
stuff, but it does at least appear to do simple signal stuff
correctly.
Modified:
trunk/coregrind/m_sigframe/sigframe-ppc64-linux.c
Modified: trunk/coregrind/m_sigframe/sigframe-ppc64-linux.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_sigframe/sigframe-ppc64-linux.c 2006-01-02 20:47:26=
UTC (rev 5482)
+++ trunk/coregrind/m_sigframe/sigframe-ppc64-linux.c 2006-01-03 04:08:32=
UTC (rev 5483)
@@ -78,148 +78,95 @@
// A structure in which to save the application's registers
// during the execution of signal handlers.
=20
-// Linux has 2 signal frame structures: one for normal signal
-// deliveries, and one for SA_SIGINFO deliveries (also known as RT
-// signals).
-//
+// On ppc64-linux, rt_sigframe is used for all 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.
=20
+/* Many of these byzantine details derived from
+ linux-2.6.13/arch/ppc64/kernel/signal.c */
+
+#define TRAMP_SIZE 6 /* who knows why - it only needs to be 2. */
+
/* Structure containing bits of information that we want to save
on signal delivery. */
-//zz struct vg_sig_private {
-//zz UInt magicPI;
-//zz UInt sigNo_private;
-//zz VexGuestPPC32State shadow;
-//zz };
-//zz=20
-//zz /* Structure put on stack for signal handlers with SA_SIGINFO clear=
. */
-//zz struct nonrt_sigframe {
-//zz UInt gap1[16];
-//zz struct vki_sigcontext sigcontext;
-//zz struct vki_mcontext mcontext;
-//zz struct vg_sig_private priv;
-//zz unsigned char abigap[224];
-//zz };
-//zz=20
-//zz /* Structure put on stack for signal handlers with SA_SIGINFO set. =
*/
-//zz struct rt_sigframe {
-//zz UInt gap1[20];
-//zz vki_siginfo_t siginfo;
-//zz struct vki_ucontext ucontext;
-//zz struct vg_sig_private priv;
-//zz unsigned char abigap[224];
-//zz };
+struct vg_sig_private {
+ UInt magicPI;
+ UInt sigNo_private;
+ VexGuestPPC64State shadow;
+};
=20
+/* Structure put on stack for all signal handlers. */
+struct rt_sigframe {
+ struct vki_ucontext uc;
+ ULong _unused[2];
+ UInt tramp[TRAMP_SIZE];
+ struct vki_siginfo* pinfo;
+ void* puc;
+ vki_siginfo_t info;
+ struct vg_sig_private priv;
+ UChar abigap[288];
+};
+
#define SET_SIGNAL_LR(zztst, zzval) \
do { tst->arch.vex.guest_LR =3D (zzval); \
VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \
- offsetof(VexGuestPPC32State,guest_LR), \
+ offsetof(VexGuestPPC64State,guest_LR), \
sizeof(UWord) ); \
} while (0)
=20
#define SET_SIGNAL_GPR(zztst, zzn, zzval) \
do { tst->arch.vex.guest_GPR##zzn =3D (zzval); \
VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \
- offsetof(VexGuestPPC32State,guest_GPR##zzn), \
+ offsetof(VexGuestPPC64State,guest_GPR##zzn), \
sizeof(UWord) ); \
} while (0)
=20
=20
-static=20
-void stack_mcontext ( struct vki_mcontext *mc,=20
- ThreadState* tst,=20
- Int ret,
- UInt fault_addr )
-{
-// VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mco=
ntext",
-// (Addr)mc, sizeof(struct vki_pt_regs) );
-//
-//# define DO(gpr) mc->mc_gregs[VKI_PT_R0+gpr] =3D tst->arch.vex.guest=
_GPR##gpr
-// DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
-// DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
-// DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
-// DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
-//# undef DO
-//
-// mc->mc_gregs[VKI_PT_NIP] =3D tst->arch.vex.guest_CIA;
-// mc->mc_gregs[VKI_PT_MSR] =3D 0xf032; /* pretty arbitrary */
-// mc->mc_gregs[VKI_PT_ORIG_R3] =3D tst->arch.vex.guest_GPR3;
-// mc->mc_gregs[VKI_PT_CTR] =3D tst->arch.vex.guest_CTR;
-// mc->mc_gregs[VKI_PT_LNK] =3D tst->arch.vex.guest_LR;
-// mc->mc_gregs[VKI_PT_XER] =3D LibVEX_GuestPPC32_get_XER(&tst->ar=
ch.vex);
-// mc->mc_gregs[VKI_PT_CCR] =3D LibVEX_GuestPPC32_get_CR(&tst->arc=
h.vex);
-// mc->mc_gregs[VKI_PT_MQ] =3D 0;
-// mc->mc_gregs[VKI_PT_TRAP] =3D 0;
-// mc->mc_gregs[VKI_PT_DAR] =3D fault_addr;
-// mc->mc_gregs[VKI_PT_DSISR] =3D 0;
-// mc->mc_gregs[VKI_PT_RESULT] =3D 0;
-// VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,=20
-// (Addr)mc, sizeof(struct vki_pt_regs) );
-//
-// /* XXX should do FP and vector regs */
-//
-// /* set up signal return trampoline */
-// VG_TRACK(pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcon=
text",
-// (Addr)&mc->mc_pad, sizeof(mc->mc_pad));
-// mc->mc_pad[0] =3D 0x38000000U + ret; /* li 0,ret */
-// mc->mc_pad[1] =3D 0x44000002U; /* sc */
-// VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,=20
-// (Addr)&mc->mc_pad, sizeof(mc->mc_pad) );
-// /* invalidate any translation of this area */
-// VG_(discard_translations)( (Addr64)(Addr)&mc->mc_pad,=20
-// sizeof(mc->mc_pad), "stack_mcontext" ); =
=20
-//
-// /* set the signal handler to return to the trampoline */
-// SET_SIGNAL_LR(tst, (Addr) &mc->mc_pad[0]);
-}
-
-
/* Extend the stack segment downwards if needed so as to ensure the
new signal frames are mapped to something. Return a Bool
indicating whether or not the operation was successful.
*/
static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
{
- I_die_here;
-// ThreadId tid =3D tst->tid;
-// NSegment *stackseg =3D NULL;
-//
-// if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
-// stackseg =3D VG_(am_find_nsegment)(addr);
-// if (0 && stackseg)
-// VG_(printf)("frame=3D%p seg=3D%p-%p\n",
-// addr, stackseg->start, stackseg->end);
-// }
-//
-// if (stackseg =3D=3D NULL || !stackseg->hasR || !stackseg->hasW) {
-// VG_(message)(
-// Vg_UserMsg,
-// "Can't extend stack to %p during signal delivery for thread %=
d:",
-// addr, tid);
-// if (stackseg =3D=3D NULL)
-// VG_(message)(Vg_UserMsg, " no stack segment");
-// else
-// VG_(message)(Vg_UserMsg, " too small or bad protection modes=
");
-//
-// /* set SIGSEGV to default handler */
-// VG_(set_default_handler)(VKI_SIGSEGV);
-// 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 False;
-// }
-//
-// /* For tracking memory events, indicate the entire frame has been
-// allocated. */
-// VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
-// size + VG_STACK_REDZONE_SZB );
-//
-// return True;
+ ThreadId tid =3D tst->tid;
+ NSegment *stackseg =3D NULL;
+
+ if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
+ stackseg =3D VG_(am_find_nsegment)(addr);
+ if (0 && stackseg)
+ VG_(printf)("frame=3D%p seg=3D%p-%p\n",
+ addr, stackseg->start, stackseg->end);
+ }
+
+ if (stackseg =3D=3D NULL || !stackseg->hasR || !stackseg->hasW) {
+ VG_(message)(
+ Vg_UserMsg,
+ "Can't extend stack to %p during signal delivery for thread %d:=
",
+ addr, tid);
+ if (stackseg =3D=3D NULL)
+ VG_(message)(Vg_UserMsg, " no stack segment");
+ else
+ VG_(message)(Vg_UserMsg, " too small or bad protection modes")=
;
+
+ /* set SIGSEGV to default handler */
+ VG_(set_default_handler)(VKI_SIGSEGV);
+ 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 False;
+ }
+
+ /* For tracking memory events, indicate the entire frame has been
+ allocated. */
+ VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
+ size + VG_STACK_REDZONE_SZB );
+
+ return True;
}
=20
=20
@@ -232,107 +179,123 @@
const vki_sigset_t *mask,
void *restorer )
{
- I_die_here;
-// struct vg_sig_private *priv;
-// Addr sp;
-// ThreadState *tst;
-// Int sigNo =3D siginfo->si_signo;
-// Addr faultaddr;
-//
-// /* Stack must be 16-byte aligned */
-// sp_top_of_frame &=3D ~0xf;
-//
-// if (flags & VKI_SA_SIGINFO) {
-// sp =3D sp_top_of_frame - sizeof(struct rt_sigframe);
-// } else {
-// sp =3D sp_top_of_frame - sizeof(struct nonrt_sigframe);
-// }
-//
-// tst =3D VG_(get_ThreadState)(tid);
-//
-// if (!extend(tst, sp, sp_top_of_frame - sp))
-// return;
-//
-// vg_assert(VG_IS_16_ALIGNED(sp));
-//
-// /* Set up the stack chain pointer */
-// VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame"=
,
-// sp, sizeof(UWord) );
-// *(Addr *)sp =3D tst->arch.vex.guest_GPR1;
-// VG_TRACK( post_mem_write, Vg_CoreSignal, tid,=20
-// sp, sizeof(UWord) );
-//
-// faultaddr =3D (Addr)siginfo->_sifields._sigfault._addr;
-// if (sigNo =3D=3D VKI_SIGILL && siginfo->si_code > 0)
-// faultaddr =3D tst->arch.vex.guest_CIA;
-//
-// if (flags & VKI_SA_SIGINFO) {
-// struct rt_sigframe *frame =3D (struct rt_sigframe *) sp;
-// struct vki_ucontext *ucp =3D &frame->ucontext;
-//
-// VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame sigin=
fo",
-// (Addr)&frame->siginfo, sizeof(frame->siginfo) );
-// VG_(memcpy)(&frame->siginfo, siginfo, sizeof(*siginfo));
-// VG_TRACK( post_mem_write, Vg_CoreSignal, tid,=20
-// (Addr)&frame->siginfo, sizeof(frame->siginfo) );
-//
-// VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucont=
ext",
-// (Addr)ucp, offsetof(struct vki_ucontext, uc_pad) );
-// ucp->uc_flags =3D 0;
-// ucp->uc_link =3D 0;
-// ucp->uc_stack =3D tst->altstack;
-// VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp,
-// offsetof(struct vki_ucontext, uc_pad) );
-//
-// VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucont=
ext",
-// (Addr)&ucp->uc_regs,
-// sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) );
-// ucp->uc_regs =3D &ucp->uc_mcontext;
-// ucp->uc_sigmask =3D tst->sig_mask;
-// VG_TRACK( post_mem_write, Vg_CoreSignal, tid,=20
-// (Addr)&ucp->uc_regs,
-// sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) );
-//
-// stack_mcontext(&ucp->uc_mcontext, tst, __NR_rt_sigreturn, faulta=
ddr);
-// priv =3D &frame->priv;
-//
-// SET_SIGNAL_GPR(tid, 4, (Addr) &frame->siginfo);
-// SET_SIGNAL_GPR(tid, 5, (Addr) ucp);
-// /* the kernel sets this, though it doesn't seem to be in the ABI=
*/
-// SET_SIGNAL_GPR(tid, 6, (Addr) &frame->siginfo);
-//
-// } else {
-// /* non-RT signal delivery */
-// struct nonrt_sigframe *frame =3D (struct nonrt_sigframe *) sp;
-// struct vki_sigcontext *scp =3D &frame->sigcontext;
-//
-// VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame sigco=
ntext",
-// (Addr)&scp->_unused[3], sizeof(*scp) - 3 * sizeof(UInt=
) );
-// scp->signal =3D sigNo;
-// scp->handler =3D (Addr) handler;
-// scp->oldmask =3D tst->sig_mask.sig[0];
-// scp->_unused[3] =3D tst->sig_mask.sig[1];
-// VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
-// (Addr)&scp->_unused[3], sizeof(*scp) - 3 * sizeof(UInt=
) );
-//
-// stack_mcontext(&frame->mcontext, tst, __NR_sigreturn, faultaddr)=
;
-// priv =3D &frame->priv;
-//
-// SET_SIGNAL_GPR(tid, 4, (Addr) scp);
-// }
-//
-// priv->magicPI =3D 0x31415927;
-// priv->sigNo_private =3D sigNo;
-// priv->shadow =3D tst->arch.vex_shadow;
-//
-// SET_SIGNAL_GPR(tid, 1, sp);
-// SET_SIGNAL_GPR(tid, 3, sigNo);
-// tst->arch.vex.guest_CIA =3D (Addr) handler;
-//
-// if (0)
-// VG_(printf)("pushed signal frame; %R1 now =3D %p, "
-// "next %%CIA =3D %p, status=3D%d\n",=20
-// sp, tst->arch.vex.guest_CIA, tst->status);
+ struct vg_sig_private* priv;
+ Addr sp;
+ ThreadState* tst;
+ Int sigNo =3D siginfo->si_signo;
+ Addr faultaddr;
+ struct rt_sigframe* frame;
+
+ /* Stack must be 16-byte aligned */
+ vg_assert(VG_IS_16_ALIGNED(sizeof(struct rt_sigframe)));
+
+ sp_top_of_frame &=3D ~0xf;
+ sp =3D sp_top_of_frame - sizeof(struct rt_sigframe);
+
+ tst =3D VG_(get_ThreadState)(tid);
+ if (!extend(tst, sp, sp_top_of_frame - sp))
+ return;
+
+ vg_assert(VG_IS_16_ALIGNED(sp));
+
+ frame =3D (struct rt_sigframe *) sp;
+
+ /* clear it (conservatively) */
+ VG_(memset)(frame, 0, sizeof(*frame));
+
+ /////////
+ frame->pinfo =3D &frame->info;
+ frame->puc =3D &frame->uc;
+
+ frame->uc.uc_flags =3D 0;
+ frame->uc.uc_link =3D 0;
+ /////////
+
+ /* Set up the stack chain pointer */
+ VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame",
+ sp, sizeof(UWord) );
+ *(Addr *)sp =3D tst->arch.vex.guest_GPR1;
+ VG_TRACK( post_mem_write, Vg_CoreSignal, tid,=20
+ sp, sizeof(UWord) );
+
+ faultaddr =3D (Addr)siginfo->_sifields._sigfault._addr;
+ if (sigNo =3D=3D VKI_SIGILL && siginfo->si_code > 0)
+ faultaddr =3D tst->arch.vex.guest_CIA;
+
+ VG_(memcpy)(&frame->info, siginfo, sizeof(*siginfo));
+ VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+ (Addr)&frame->info, sizeof(frame->info) );
+
+ frame->uc.uc_flags =3D 0;
+ frame->uc.uc_link =3D 0;
+ frame->uc.uc_stack =3D tst->altstack;
+ frame->uc.uc_sigmask =3D tst->sig_mask;
+ VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+ (Addr)(&frame->uc), sizeof(frame->uc) );
+
+# define DO(gpr) frame->uc.uc_mcontext.gp_regs[VKI_PT_R0+gpr] \
+ =3D tst->arch.vex.guest_GPR##gpr=20
+ DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
+ DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
+ DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
+ DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
+# undef DO
+
+ frame->uc.uc_mcontext.gp_regs[VKI_PT_NIP] =3D tst->arch.vex.guest=
_CIA;
+ frame->uc.uc_mcontext.gp_regs[VKI_PT_MSR] =3D 0xf032; /* pretty=
arbitrary */
+ frame->uc.uc_mcontext.gp_regs[VKI_PT_ORIG_R3] =3D tst->arch.vex.guest=
_GPR3;
+ frame->uc.uc_mcontext.gp_regs[VKI_PT_CTR] =3D tst->arch.vex.guest=
_CTR;
+ frame->uc.uc_mcontext.gp_regs[VKI_PT_LNK] =3D tst->arch.vex.guest=
_LR;
+ frame->uc.uc_mcontext.gp_regs[VKI_PT_XER] =3D LibVEX_GuestPPC64_g=
et_XER(
+ &tst->arch.vex);
+ frame->uc.uc_mcontext.gp_regs[VKI_PT_CCR] =3D LibVEX_GuestPPC64_g=
et_CR(
+ &tst->arch.vex);
+ //mc->mc_gregs[VKI_PT_MQ] =3D 0;
+ //mc->mc_gregs[VKI_PT_TRAP] =3D 0;
+ //mc->mc_gregs[VKI_PT_DAR] =3D fault_addr;
+ //mc->mc_gregs[VKI_PT_DSISR] =3D 0;
+ //mc->mc_gregs[VKI_PT_RESULT] =3D 0;
+
+ /* XXX should do FP and vector regs */
+
+ /* set up signal return trampoline */
+ frame->tramp[0] =3D 0x38000000U + __NR_rt_sigreturn; /* li 0,__NR_rt_=
sigreturn */
+ frame->tramp[1] =3D 0x44000002U; /* sc */
+ VG_TRACK(post_mem_write, Vg_CoreSignal, tst->tid,
+ (Addr)&frame->tramp, sizeof(frame->tramp));
+
+ /* invalidate any translation of this area */
+ VG_(discard_translations)( (Addr64)&frame->tramp[0],=20
+ sizeof(frame->tramp), "stack_mcontext" ); =
=20
+
+ /* set the signal handler to return to the trampoline */
+ SET_SIGNAL_LR(tst, (Addr) &frame->tramp[0]);
+
+ /* Stack pointer for the handler .. (note, back chain set
+ earlier) */
+ SET_SIGNAL_GPR(tid, 1, sp);
+
+ /* Args for the handler .. */
+ SET_SIGNAL_GPR(tid, 3, sigNo);
+ SET_SIGNAL_GPR(tid, 4, (Addr) &frame->info);
+ SET_SIGNAL_GPR(tid, 5, (Addr) &frame->uc);
+ /* the kernel sets this, though it doesn't seem to be in the ABI */
+ SET_SIGNAL_GPR(tid, 6, (Addr) &frame->info);
+
+ /* Handler is in fact a standard ppc64-linux function descriptor,=20
+ so extract the function entry point and also the toc ptr to use. *=
/
+ SET_SIGNAL_GPR(tid, 2, (Addr) ((ULong*)handler)[1]);
+ tst->arch.vex.guest_CIA =3D (Addr) ((ULong*)handler)[0];
+
+ priv =3D &frame->priv;
+ priv->magicPI =3D 0x31415927;
+ priv->sigNo_private =3D sigNo;
+ priv->shadow =3D tst->arch.vex_shadow;
+
+ if (0)
+ VG_(printf)("pushed signal frame; %R1 now =3D %p, "
+ "next %%CIA =3D %p, status=3D%d\n",=20
+ sp, tst->arch.vex.guest_CIA, tst->status);
}
=20
=20
@@ -343,77 +306,65 @@
/* EXPORTED */
void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
{
- I_die_here;
-// ThreadState *tst;
-// struct vg_sig_private *priv;
-// Addr sp;
-// UInt frame_size;
-// struct vki_mcontext *mc;
-// Int sigNo;
-// Bool has_siginfo =3D isRT;
-//
-// vg_assert(VG_(is_valid_tid)(tid));
-// tst =3D VG_(get_ThreadState)(tid);
-//
-// /* Check that the stack frame looks valid */
-// sp =3D tst->arch.vex.guest_GPR1;
-// vg_assert(VG_IS_16_ALIGNED(sp));
-// /* JRS 17 Nov 05: This code used to check that *sp -- which should
-// have been set by the stwu at the start of the handler -- points
-// to just above the frame (ie, the previous frame). However, that
-// isn't valid when delivering signals on alt stacks. So I removed
-// it. The frame is still sanity-checked using the priv->magicPI
-// field. */
-//
-// if (has_siginfo) {
-// struct rt_sigframe *frame =3D (struct rt_sigframe *)sp;
-// frame_size =3D sizeof(*frame);
-// mc =3D &frame->ucontext.uc_mcontext;
-// priv =3D &frame->priv;
-// vg_assert(priv->magicPI =3D=3D 0x31415927);
-// tst->sig_mask =3D frame->ucontext.uc_sigmask;
-// } else {
-// struct nonrt_sigframe *frame =3D (struct nonrt_sigframe *)sp;
-// frame_size =3D sizeof(*frame);
-// mc =3D &frame->mcontext;
-// priv =3D &frame->priv;
-// vg_assert(priv->magicPI =3D=3D 0x31415927);
-// tst->sig_mask.sig[0] =3D frame->sigcontext.oldmask;
-// tst->sig_mask.sig[1] =3D frame->sigcontext._unused[3];
-// }
-// tst->tmp_sig_mask =3D tst->sig_mask;
-//
-// sigNo =3D priv->sigNo_private;
-//
-//# define DO(gpr) tst->arch.vex.guest_GPR##gpr =3D mc->mc_gregs[VKI_P=
T_R0+gpr]
-// DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
-// DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
-// DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
-// DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
-//# undef DO
-//
-// tst->arch.vex.guest_CIA =3D mc->mc_gregs[VKI_PT_NIP];
-//
-// // Umm ... ? (jrs 2005 July 8)
-// // tst->arch.m_orig_gpr3 =3D mc->mc_gregs[VKI_PT_ORIG_R3];
-//
-// LibVEX_GuestPPC32_put_CR( mc->mc_gregs[VKI_PT_CCR], &tst->arch.vex =
);
-//
-// tst->arch.vex.guest_LR =3D mc->mc_gregs[VKI_PT_LNK];
-// tst->arch.vex.guest_CTR =3D mc->mc_gregs[VKI_PT_CTR];
-// LibVEX_GuestPPC32_put_XER( mc->mc_gregs[VKI_PT_XER], &tst->arch.vex=
);
-//
-// tst->arch.vex_shadow =3D priv->shadow;
-//
-// VG_TRACK(die_mem_stack_signal, sp, frame_size);
-//
-// if (VG_(clo_trace_signals))
-// VG_(message)(Vg_DebugMsg,
-// "vg_pop_signal_frame (thread %d): isRT=3D%d valid m=
agic; EIP=3D%p",
-// tid, has_siginfo, tst->arch.vex.guest_CIA);
-//
-// /* tell the tools */
-// VG_TRACK( post_deliver_signal, tid, sigNo );
+ ThreadState *tst;
+ struct vg_sig_private *priv;
+ Addr sp;
+ UInt frame_size;
+ struct rt_sigframe *frame;
+ Int sigNo;
+ Bool has_siginfo =3D isRT;
+
+ vg_assert(VG_(is_valid_tid)(tid));
+ tst =3D VG_(get_ThreadState)(tid);
+
+ /* Check that the stack frame looks valid */
+ sp =3D tst->arch.vex.guest_GPR1;
+ vg_assert(VG_IS_16_ALIGNED(sp));
+ /* JRS 17 Nov 05: This code used to check that *sp -- which should
+ have been set by the stwu at the start of the handler -- points
+ to just above the frame (ie, the previous frame). However, that
+ isn't valid when delivering signals on alt stacks. So I removed
+ it. The frame is still sanity-checked using the priv->magicPI
+ field. */
+
+ frame =3D (struct rt_sigframe *)sp;
+ frame_size =3D sizeof(*frame);
+ priv =3D &frame->priv;
+ vg_assert(priv->magicPI =3D=3D 0x31415927);
+ tst->sig_mask =3D frame->uc.uc_sigmask;
+ tst->tmp_sig_mask =3D tst->sig_mask;
+
+ sigNo =3D priv->sigNo_private;
+
+# define DO(gpr) tst->arch.vex.guest_GPR##gpr \
+ =3D frame->uc.uc_mcontext.gp_regs[VKI_PT_R0+gpr]
+ DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
+ DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
+ DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
+ DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
+# undef DO
+
+ tst->arch.vex.guest_CIA =3D frame->uc.uc_mcontext.gp_regs[VKI_PT_NIP]=
;
+
+ LibVEX_GuestPPC64_put_CR( frame->uc.uc_mcontext.gp_regs[VKI_PT_CCR],=20
+ &tst->arch.vex );
+
+ tst->arch.vex.guest_LR =3D frame->uc.uc_mcontext.gp_regs[VKI_PT_LNK]=
;
+ tst->arch.vex.guest_CTR =3D frame->uc.uc_mcontext.gp_regs[VKI_PT_CTR]=
;
+ LibVEX_GuestPPC64_put_XER( frame->uc.uc_mcontext.gp_regs[VKI_PT_XER],=
=20
+ &tst->arch.vex );
+
+ tst->arch.vex_shadow =3D priv->shadow;
+
+ VG_TRACK(die_mem_stack_signal, sp, frame_size);
+
+ if (VG_(clo_trace_signals))
+ VG_(message)(Vg_DebugMsg,
+ "vg_pop_signal_frame (thread %d): isRT=3D%d valid mag=
ic; EIP=3D%p",
+ tid, has_siginfo, tst->arch.vex.guest_CIA);
+
+ /* tell the tools */
+ VG_TRACK( post_deliver_signal, tid, sigNo );
}
=20
/*--------------------------------------------------------------------*/
|