From aeb757d841ec5f3f1806f265ec7dc7b6501bd95d Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 31 Mar 2004 07:27:31 +0000 Subject: [PATCH] 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. --- lib/libc/amd64/gen/makecontext.c | 6 +++--- lib/libc/amd64/gen/signalcontext.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/libc/amd64/gen/makecontext.c b/lib/libc/amd64/gen/makecontext.c index 74eb68a88a14..c44e3369913b 100644 --- a/lib/libc/amd64/gen/makecontext.c +++ b/lib/libc/amd64/gen/makecontext.c @@ -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) diff --git a/lib/libc/amd64/gen/signalcontext.c b/lib/libc/amd64/gen/signalcontext.c index 5722fe313f2d..4eb1919c4cc0 100644 --- a/lib/libc/amd64/gen/signalcontext.c +++ b/lib/libc/amd64/gen/signalcontext.c @@ -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]);