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:
Samuel Thibault 2019-08-30 01:48:38 +02:00
parent c9536b7b9d
commit a644a4b213
2 changed files with 47 additions and 26 deletions

View File

@ -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

View File

@ -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 */