typedef
struct {
- /* These are parameters to the signal handler. */
- UInt retaddr; /* Sig handler's (bogus) return address */
- Int sigNo; /* The arg to the sig handler. */
- Addr psigInfo; /* ptr to siginfo_t; NULL for now. */
- Addr puContext; /* ptr to ucontext; NULL for now. */
+ /* These 4 are parameters to the signal handler. The order of
+ them is important, since this whole struct is pushed onto the
+ client's stack at delivery time. The first 4 words -- which
+ will be at the top of the stack -- constitute 4 arg words to
+ the handler. */
+
+ /* Sig handler's (bogus) 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;
+ /* ptr to siginfo_t; NULL for now. */
+ Addr psigInfo;
+ /* ptr to ucontext; NULL for now. */
+ Addr puContext;
+
+ /* The rest are private fields which the handler is unaware of. */
+
/* Sanity check word. */
UInt magicPI;
+ /* Safely-saved version of sigNo, as described above. */
+ Int sigNo_private;
/* Saved processor state. */
UInt fpustate[VG_SIZE_OF_FPUSTATE_W];
UInt eax;
frame->retaddr = (UInt)(&VG_(signalreturn_bogusRA));
frame->sigNo = sigNo;
+ frame->sigNo_private = sigNo;
frame->psigInfo = (Addr)NULL;
frame->puContext = (Addr)NULL;
frame->magicPI = 0x31415927;
tst->m_edi = frame->edi;
tst->m_eflags = frame->eflags;
tst->m_eip = frame->eip;
- sigNo = frame->sigNo;
+
+ /* don't use the copy exposed to the handler; it might have changed
+ it. */
+ sigNo = frame->sigNo_private;
/* And restore the thread's status to what it was before the signal
was delivered. */