mirror of
git://sourceware.org/git/glibc.git
synced 2025-01-30 12:31:53 +08:00
hurd: Fix SS_ONSTACK support
* sysdeps/mach/hurd/i386/sigreturn.c (__sigreturn2): New function, unlocks SS and returns to the saved PC. (__sigreturn): Do not unlock SS, and "return" into __sigreturn2 on the thread stack instead of the saved PC.
This commit is contained in:
parent
c9536b7b9d
commit
a644a4b213
@ -24,6 +24,11 @@
|
||||
* sysdeps/mach/hurd/mmap.c (__mmap): Remove optimizing anonymous maps
|
||||
as __vm_allocate.
|
||||
|
||||
* sysdeps/mach/hurd/i386/sigreturn.c (__sigreturn2): New function,
|
||||
unlocks SS and returns to the saved PC.
|
||||
(__sigreturn): Do not unlock SS, and "return" into __sigreturn2 on the
|
||||
thread stack instead of the saved PC.
|
||||
|
||||
2019-08-30 Richard Braun <rbraun@sceen.net>
|
||||
|
||||
* hurd/hurdselect.c (_hurd_select): Always call __io_select with no
|
||||
|
@ -24,6 +24,36 @@ register int *sp asm ("%esp");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* This is run on the thread stack after restoring it, to be able to
|
||||
unlock SS off sigstack. */
|
||||
static void
|
||||
__sigreturn2 (int *usp)
|
||||
{
|
||||
struct hurd_sigstate *ss = _hurd_self_sigstate ();
|
||||
__spin_unlock (ss);
|
||||
|
||||
sp = usp;
|
||||
#define A(line) asm volatile (#line)
|
||||
/* The members in the sigcontext are arranged in this order
|
||||
so we can pop them easily. */
|
||||
|
||||
/* Pop the segment registers (except %cs and %ss, done last). */
|
||||
A (popl %gs);
|
||||
A (popl %fs);
|
||||
A (popl %es);
|
||||
A (popl %ds);
|
||||
/* Pop the general registers. */
|
||||
A (popa);
|
||||
/* Pop the processor flags. */
|
||||
A (popf);
|
||||
/* Return to the saved PC. */
|
||||
A (ret);
|
||||
|
||||
/* Firewall. */
|
||||
A (hlt);
|
||||
#undef A
|
||||
}
|
||||
|
||||
int
|
||||
__sigreturn (struct sigcontext *scp)
|
||||
{
|
||||
@ -67,13 +97,7 @@ __sigreturn (struct sigcontext *scp)
|
||||
}
|
||||
|
||||
if (scp->sc_onstack)
|
||||
{
|
||||
ss->sigaltstack.ss_flags &= ~SS_ONSTACK;
|
||||
/* XXX cannot unlock until off sigstack */
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
__spin_unlock (&ss->lock);
|
||||
|
||||
/* Destroy the MiG reply port used by the signal handler, and restore the
|
||||
reply port in use by the thread when interrupted. */
|
||||
@ -108,27 +132,19 @@ __sigreturn (struct sigcontext *scp)
|
||||
*--usp = scp->sc_efl;
|
||||
memcpy (usp -= 12, &scp->sc_i386_thread_state, 12 * sizeof (int));
|
||||
|
||||
/* Pass usp to __sigreturn2 so it can unwind itself easily. */
|
||||
*(usp-1) = (int) usp;
|
||||
--usp;
|
||||
/* Bogus return address for __sigreturn2 */
|
||||
*--usp = 0;
|
||||
*--usp = (int) __sigreturn2;
|
||||
|
||||
/* Restore thread stack */
|
||||
sp = usp;
|
||||
|
||||
#define A(line) asm volatile (#line)
|
||||
/* The members in the sigcontext are arranged in this order
|
||||
so we can pop them easily. */
|
||||
|
||||
/* Pop the segment registers (except %cs and %ss, done last). */
|
||||
A (popl %gs);
|
||||
A (popl %fs);
|
||||
A (popl %es);
|
||||
A (popl %ds);
|
||||
/* Pop the general registers. */
|
||||
A (popa);
|
||||
/* Pop the processor flags. */
|
||||
A (popf);
|
||||
/* Return to the saved PC. */
|
||||
A (ret);
|
||||
|
||||
/* Return into __sigreturn2. */
|
||||
asm volatile ("ret");
|
||||
/* Firewall. */
|
||||
A (hlt);
|
||||
#undef A
|
||||
asm volatile ("hlt");
|
||||
}
|
||||
|
||||
/* NOTREACHED */
|
||||
|
Loading…
Reference in New Issue
Block a user