From bddfaa895c1abd5d2ceb6ea2be6efb1f8bc26cd0 Mon Sep 17 00:00:00 2001 From: Peter Grehan Date: Thu, 22 Jul 2004 01:28:51 +0000 Subject: [PATCH] Update the callframe structure to leave space for the frame pointer and saved link register as per the ABI call sequence. Update code that uses this (fork_trampoline etc) to use the correct genassym'd offsets. This fixes the 'invalid LR' message when backtracing kernel threads in DDB. --- sys/powerpc/aim/swtch.S | 5 ++++- sys/powerpc/aim/vm_machdep.c | 2 ++ sys/powerpc/include/frame.h | 2 ++ sys/powerpc/powerpc/genassym.c | 2 ++ sys/powerpc/powerpc/swtch.S | 5 ++++- sys/powerpc/powerpc/vm_machdep.c | 2 ++ 6 files changed, 16 insertions(+), 2 deletions(-) diff --git a/sys/powerpc/aim/swtch.S b/sys/powerpc/aim/swtch.S index 6e3bfdd636d3..12bb488a326d 100644 --- a/sys/powerpc/aim/swtch.S +++ b/sys/powerpc/aim/swtch.S @@ -147,5 +147,8 @@ ENTRY(fork_trampoline) lwz %r4,CF_ARG0(%r1) lwz %r5,CF_ARG1(%r1) bl fork_exit - addi %r1,%r1,4 + addi %r1,%r1,CF_SIZE-FSP /* Allow 8 bytes in front of + trapframe to simulate FRAME_SETUP + does when allocating space for + a frame pointer/saved LR */ b trapexit diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c index 4e8c80354416..3b1921364fb7 100644 --- a/sys/powerpc/aim/vm_machdep.c +++ b/sys/powerpc/aim/vm_machdep.c @@ -146,6 +146,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) td2->td_frame = tf; cf = (struct callframe *)tf - 1; + memset(cf, 0, sizeof(struct callframe)); cf->cf_func = (register_t)fork_return; cf->cf_arg0 = (register_t)td2; cf->cf_arg1 = (register_t)tf; @@ -321,6 +322,7 @@ cpu_set_upcall(struct thread *td, struct thread *td0) /* Set registers for trampoline to user mode. */ cf = (struct callframe *)tf - 1; + memset(cf, 0, sizeof(struct callframe)); cf->cf_func = (register_t)fork_return; cf->cf_arg0 = (register_t)td; cf->cf_arg1 = (register_t)tf; diff --git a/sys/powerpc/include/frame.h b/sys/powerpc/include/frame.h index 6b75e46565f5..ae0103bb6926 100644 --- a/sys/powerpc/include/frame.h +++ b/sys/powerpc/include/frame.h @@ -85,6 +85,8 @@ struct clockframe { * Call frame for PowerPC used during fork. */ struct callframe { + register_t cf_dummy_fp; /* dummy frame pointer */ + register_t cf_lr; /* space for link register save */ register_t cf_func; register_t cf_arg0; register_t cf_arg1; diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c index 38de0c2b53f9..1aa26efbb267 100644 --- a/sys/powerpc/powerpc/genassym.c +++ b/sys/powerpc/powerpc/genassym.c @@ -79,6 +79,7 @@ ASSYM(PM_KERNELSR, offsetof(struct pmap, pm_sr[KERNEL_SR])); ASSYM(PM_USRSR, offsetof(struct pmap, pm_sr[USER_SR])); ASSYM(PM_SR, offsetof(struct pmap, pm_sr)); +ASSYM(FSP, 8); ASSYM(FRAMELEN, FRAMELEN); ASSYM(FRAME_0, offsetof(struct trapframe, fixreg[0])); ASSYM(FRAME_1, offsetof(struct trapframe, fixreg[1])); @@ -164,6 +165,7 @@ ASSYM(SPFRAME_R0, offsetof(struct spillframe, r0)); ASSYM(CF_FUNC, offsetof(struct callframe, cf_func)); ASSYM(CF_ARG0, offsetof(struct callframe, cf_arg0)); ASSYM(CF_ARG1, offsetof(struct callframe, cf_arg1)); +ASSYM(CF_SIZE, sizeof(struct callframe)); ASSYM(PCB_CONTEXT, offsetof(struct pcb, pcb_context)); ASSYM(PCB_CR, offsetof(struct pcb, pcb_cr)); diff --git a/sys/powerpc/powerpc/swtch.S b/sys/powerpc/powerpc/swtch.S index 6e3bfdd636d3..12bb488a326d 100644 --- a/sys/powerpc/powerpc/swtch.S +++ b/sys/powerpc/powerpc/swtch.S @@ -147,5 +147,8 @@ ENTRY(fork_trampoline) lwz %r4,CF_ARG0(%r1) lwz %r5,CF_ARG1(%r1) bl fork_exit - addi %r1,%r1,4 + addi %r1,%r1,CF_SIZE-FSP /* Allow 8 bytes in front of + trapframe to simulate FRAME_SETUP + does when allocating space for + a frame pointer/saved LR */ b trapexit diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c index 4e8c80354416..3b1921364fb7 100644 --- a/sys/powerpc/powerpc/vm_machdep.c +++ b/sys/powerpc/powerpc/vm_machdep.c @@ -146,6 +146,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) td2->td_frame = tf; cf = (struct callframe *)tf - 1; + memset(cf, 0, sizeof(struct callframe)); cf->cf_func = (register_t)fork_return; cf->cf_arg0 = (register_t)td2; cf->cf_arg1 = (register_t)tf; @@ -321,6 +322,7 @@ cpu_set_upcall(struct thread *td, struct thread *td0) /* Set registers for trampoline to user mode. */ cf = (struct callframe *)tf - 1; + memset(cf, 0, sizeof(struct callframe)); cf->cf_func = (register_t)fork_return; cf->cf_arg0 = (register_t)td; cf->cf_arg1 = (register_t)tf;