summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2004-11-05 23:53:02 +0000
committercognet <cognet@FreeBSD.org>2004-11-05 23:53:02 +0000
commit0008c63bf13c49ee25b6411234c9ca0beefd2b32 (patch)
tree9eff7d57a1a288f8782c38df2e224bc2d179c1f4 /lib/libc
parent5ee799d6b4708a9b00d399a19ef36ab7682ef336 (diff)
downloadFreeBSD-src-0008c63bf13c49ee25b6411234c9ca0beefd2b32.zip
FreeBSD-src-0008c63bf13c49ee25b6411234c9ca0beefd2b32.tar.gz
Fix signalcontext and makecontext.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/arm/gen/_ctx_start.S5
-rw-r--r--lib/libc/arm/gen/makecontext.c10
-rw-r--r--lib/libc/arm/gen/signalcontext.c16
3 files changed, 17 insertions, 14 deletions
diff --git a/lib/libc/arm/gen/_ctx_start.S b/lib/libc/arm/gen/_ctx_start.S
index 8187d74..fbde357 100644
--- a/lib/libc/arm/gen/_ctx_start.S
+++ b/lib/libc/arm/gen/_ctx_start.S
@@ -2,7 +2,8 @@
.ident "$FreeBSD$"
ENTRY(_ctx_start)
- mov pc, r0
- mov r0, r1
+ mov lr, pc
+ mov pc, r4
+ mov r0, r5
bl _C_LABEL(ctx_done)
bl _C_LABEL(abort)
diff --git a/lib/libc/arm/gen/makecontext.c b/lib/libc/arm/gen/makecontext.c
index 18aadf1..4fd3953 100644
--- a/lib/libc/arm/gen/makecontext.c
+++ b/lib/libc/arm/gen/makecontext.c
@@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
#include <stdarg.h>
-extern void _ctx_start(ucontext_t *, int argc, ...);
+extern void _ctx_start(void);
void
ctx_done(ucontext_t *ucp)
@@ -72,7 +72,8 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
/* Compute and align stack pointer. */
sp = (unsigned int *)
- (((uintptr_t)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & ~7);
+ (((uintptr_t)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size -
+ sizeof(double)) & ~7);
/* Allocate necessary stack space for arguments exceeding r0-3. */
if (argc > 4)
sp -= argc - 4;
@@ -80,8 +81,9 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
/* Wipe out frame pointer. */
gr[_REG_FP] = 0;
/* Arrange for return via the trampoline code. */
- gr[_REG_LR] = (__greg_t)_ctx_start;
- gr[_REG_PC] = (__greg_t)func;
+ gr[_REG_PC] = (__greg_t)_ctx_start;
+ gr[_REG_R4] = (__greg_t)func;
+ gr[_REG_R5] = (__greg_t)ucp;
va_start(ap, argc);
/* Pass up to four arguments in r0-3. */
diff --git a/lib/libc/arm/gen/signalcontext.c b/lib/libc/arm/gen/signalcontext.c
index 35108fd..bb9a54d 100644
--- a/lib/libc/arm/gen/signalcontext.c
+++ b/lib/libc/arm/gen/signalcontext.c
@@ -51,11 +51,8 @@ __signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func)
struct sigframe *sfp;
__greg_t *gr = ucp->uc_mcontext.__gregs;
unsigned int *sp;
- mcontext_t *mc;
- mc = &ucp->uc_mcontext;
- sp = (unsigned int *)
- (((uintptr_t)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & ~7);
+ sp = (unsigned int *)gr[_REG_SP];
sfp = (struct sigframe *)sp - 1;
@@ -63,13 +60,16 @@ __signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func)
bcopy(ucp, &sfp->sf_uc, sizeof(*ucp));
sfp->sf_si.si_signo = sig;
- gr[_REG_SP] = (__greg_t)sp;
+ gr[_REG_SP] = (__greg_t)sfp;
/* Wipe out frame pointer. */
gr[_REG_FP] = 0;
/* Arrange for return via the trampoline code. */
- gr[_REG_LR] = (__greg_t)_ctx_start;
- gr[_REG_PC] = (__greg_t)func;
- gr[_REG_R0] = (__greg_t)ucp;
+ gr[_REG_PC] = (__greg_t)_ctx_start;
+ gr[_REG_R4] = (__greg_t)func;
+ gr[_REG_R5] = (__greg_t)ucp;
+ gr[_REG_R0] = (__greg_t)sig;
+ gr[_REG_R1] = (__greg_t)&sfp->sf_si;
+ gr[_REG_R2] = (__greg_t)&sfp->sf_uc;
ucp->uc_link = &sfp->sf_uc;
sigdelset(&ucp->uc_sigmask, sig);
OpenPOWER on IntegriCloud