Fix Yet Another 16 byte stack alignment bug. Thankfully, this one is

solved by a simple 'make world'.  The signalcontext function was going
to the trouble of generating an even 16 byte alignment, but in fact it
needed to be odd aligned to simulate the 8-byte return address having
been pushed by the caller.  This fixes yet another group of crashes in
applications using libpthread.  And yet again, it was my fault all along.

While here, rename the duplicate internal ctx_wrapper() functions to
makectx_wrapper() and sigctx_wrapper() so that traces aren't ambiguous.
This commit is contained in:
Peter Wemm 2004-03-31 07:27:31 +00:00
parent 220ee8be37
commit 3726033348
2 changed files with 10 additions and 10 deletions

View File

@ -36,7 +36,7 @@ typedef void (*func_t)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t);
/* Prototypes */
static void ctx_wrapper(ucontext_t *ucp, func_t func, uint64_t *args);
static void makectx_wrapper(ucontext_t *ucp, func_t func, uint64_t *args);
__weak_reference(__makecontext, makecontext);
@ -91,11 +91,11 @@ __makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...)
ucp->uc_mcontext.mc_rbp = (register_t)sp;
ucp->uc_mcontext.mc_rbx = (register_t)sp;
ucp->uc_mcontext.mc_rsp = (register_t)sp;
ucp->uc_mcontext.mc_rip = (register_t)ctx_wrapper;
ucp->uc_mcontext.mc_rip = (register_t)makectx_wrapper;
}
static void
ctx_wrapper(ucontext_t *ucp, func_t func, uint64_t *args)
makectx_wrapper(ucontext_t *ucp, func_t func, uint64_t *args)
{
(*func)(args[0], args[1], args[2], args[3], args[4], args[5]);
if (ucp->uc_link == NULL)

View File

@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
typedef void (*handler_t)(uint64_t, uint64_t, uint64_t);
/* Prototypes */
static void ctx_wrapper(ucontext_t *ucp, handler_t func, uint64_t *args);
static void sigctx_wrapper(ucontext_t *ucp, handler_t func, uint64_t *args);
__weak_reference(__signalcontext, signalcontext);
@ -54,8 +54,9 @@ __signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func)
/*
* Build a signal frame and copy the arguments of signal handler
* 'func' onto the stack. We only need 3 arguments, but we
* create room for 4 so that we are 16-byte aligned.
* 'func' onto the stack and do the funky stack alignment.
* This means that we need an 8-byte-odd alignment since the ABI expects
* the return address to be pushed, thus breaking the 16 byte alignment.
*/
sp = (ucp->uc_mcontext.mc_rsp - sizeof(ucontext_t)) & ~15UL;
sig_uc = (ucontext_t *)sp;
@ -64,12 +65,11 @@ __signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func)
sig_si = (siginfo_t *)sp;
bzero(sig_si, sizeof(*sig_si));
sig_si->si_signo = sig;
sp -= 4 * sizeof(uint64_t);
sp -= 3 * sizeof(uint64_t);
args = (uint64_t *)sp;
args[0] = sig;
args[1] = (intptr_t)sig_si;
args[2] = (intptr_t)sig_uc;
args[3] = 0;
sp -= 16;
/*
@ -86,12 +86,12 @@ __signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func)
ucp->uc_mcontext.mc_rbp = (register_t)sp;
ucp->uc_mcontext.mc_rbx = (register_t)sp;
ucp->uc_mcontext.mc_rsp = (register_t)sp;
ucp->uc_mcontext.mc_rip = (register_t)ctx_wrapper;
ucp->uc_mcontext.mc_rip = (register_t)sigctx_wrapper;
return (0);
}
static void
ctx_wrapper(ucontext_t *ucp, handler_t func, uint64_t *args)
sigctx_wrapper(ucontext_t *ucp, handler_t func, uint64_t *args)
{
(*func)(args[0], args[1], args[2]);