diff options
author | Neal H. Walfield <neal@gnu.org> | 2009-02-19 19:15:59 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@gnu.org> | 2009-02-19 19:15:59 +0100 |
commit | ee4b520e643c9f51fdb51a5267a988a0e50937eb (patch) | |
tree | dcaac962c5620c03f51dab5680412abec1d39ed5 | |
parent | 9af34e63adeda0004857d0d32a90d1272ce07d50 (diff) |
Fix signal handling.
-rw-r--r-- | libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c | 61 | ||||
-rw-r--r-- | ruth/ruth.c | 9 |
2 files changed, 44 insertions, 26 deletions
diff --git a/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c b/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c index 5f235de..7e2e367 100644 --- a/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c +++ b/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c @@ -43,6 +43,9 @@ extern char _signal_dispatch_entry; /* Stack layout: x86 x86-64 + \ + > sig_info_t structure. + 8 14 / 7 13 rflags 6 12 dx 5 11 cx @@ -121,38 +124,45 @@ __asm__ (".globl _signal_dispatch_entry\n\t" /* Set dx to the interrupted context's sp. */ "pop "R(dx)"\n\t" - "and "R(cx)", "R(cx)"\n\t" - "jz after_move\n\t" - /* We need to move the remaining state to the interrupted stack. */ - /* Make some space on that stack (which may be this stack!). */ - "sub $(4*"WS"), "R(dx)"\n\t" + /* Make some space on that stack. As that stack may be this + stack, we need to be careful: this will overwrite the + siginfo structure and possibly part of the first save + area. */ + "sub $(3*"WS"), "R(dx)"\n\t" - /* Move the saved registers to the user stack. */ - /* ax. */ - "pop 0*"WS"("R(dx)")\n\t" - /* cx. */ - "pop 1*"WS"("R(dx)")\n\t" - /* dx. */ - "pop 2*"WS"("R(dx)")\n\t" - /* Flags. */ - "pop 3*"WS"("R(dx)")\n\t" + /* Move the saved flags, dx and cx to the user stack and + restore ax. */ + /* flags. */ + "mov 3*"WS"("R(sp)"), "R(ax)"\n\t" + "mov "R(ax)", 2*"WS"("R(dx)")\n\t" + + /* dx. */ + "mov 2*"WS"("R(sp)"), "R(ax)"\n\t" + "mov "R(ax)", 1*"WS"("R(dx)")\n\t" + + /* We don't need rax any more. We can restore it. */ + "pop "R(ax)"\n\t" + /* cx. */ + "pop 0*"WS"("R(dx)")\n\t" /* Restore the interrupted context's sp - 5 * WS (the four saved registers above and the interrupted context's IP). */ "mov "R(dx)", "R(sp)"\n\t" - /* Clear the SA_ONSTACK flag. */ + /* Clear the SA_ONSTACK flag, if required (i.e., &SS_FLAGS is + not NULL). */ + "and "R(cx)", "R(cx)"\n\t" + "jz after_clear\n\t" "lock; and $~1, 0("R(cx)")\n\t" + "after_clear:\n\t" - "after_move:\n\t" - /* Restore the flag register, the scratch regs and the - original sp and ip. */ - "pop "R(ax)"\n\t" + /* Restore the flag register, cx, dx, and the original sp and + ip. */ "pop "R(cx)"\n\t" "pop "R(dx)"\n\t" "popf\n\t" @@ -255,7 +265,13 @@ signal_dispatch_lowlevel (struct signal_state *ss, pthread_t tid, /* Set up the call frame for a call to signal_dispatch_entry. */ - /* Allocate save area 1. */ + /* Copy the signinfo structure onto the target stack. */ + siginfo_t *sip; + sp -= (sizeof (si) + sizeof (uintptr_t) - 1) / sizeof (uintptr_t); + sip = sp; + * sip = si; + + /* Allocate save area 1, which requires space for 4 registers. */ sp -= 4; /* The interrupted context's sp - WS. (In the case where INTR_SP is @@ -269,13 +285,14 @@ signal_dispatch_lowlevel (struct signal_state *ss, pthread_t tid, else * -- sp = 0; - /* Allocate save area 2. */ + /* Allocate save area 2, which requires space for 6 registers on + x86-64. */ #ifdef __x86_64 sp -= 6; #endif /* A pointer to the siginfo structure. */ - * -- sp = (uintptr_t) &si; + * -- sp = (uintptr_t) sip; /* The ss. */ * -- sp = (uintptr_t) ss; diff --git a/ruth/ruth.c b/ruth/ruth.c index ed7f554..039a24f 100644 --- a/ruth/ruth.c +++ b/ruth/ruth.c @@ -226,7 +226,8 @@ main (int argc, char *argv[]) assert (ret); assert (shadow); - storage_free (vg_addr_chop (VG_PTR_TO_ADDR (shadow), PAGESIZE_LOG2), 1); + storage_free (vg_addr_chop (VG_PTR_TO_ADDR (shadow), PAGESIZE_LOG2), + true); } as_free (root, 1); @@ -311,6 +312,7 @@ main (int argc, char *argv[]) printf ("ok.\n"); } +#if 0 { static volatile int done; char stack[0x1000]; @@ -362,6 +364,7 @@ main (int argc, char *argv[]) printf ("ok.\n"); } +#endif { printf ("Checking pthread library... "); @@ -430,10 +433,9 @@ main (int argc, char *argv[]) printf ("ok.\n"); } -#if 0 { printf ("Checking signals... "); - int d = 0; + int d = 5; pthread_t thread; @@ -640,7 +642,6 @@ main (int argc, char *argv[]) printf ("ok.\n"); } -#endif { printf ("Checking activity creation... "); |