summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2004-07-22 01:28:51 +0000
committergrehan <grehan@FreeBSD.org>2004-07-22 01:28:51 +0000
commit1248963e47812a7f285dfb3ada018e469fa03db7 (patch)
treebccb0e20c741ec49a9846bd18235002beb0acfe4 /sys/powerpc
parente77cc66588643df786ee7ef6cb0d0ef8a54ccc7f (diff)
downloadFreeBSD-src-1248963e47812a7f285dfb3ada018e469fa03db7.zip
FreeBSD-src-1248963e47812a7f285dfb3ada018e469fa03db7.tar.gz
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.
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/aim/swtch.S5
-rw-r--r--sys/powerpc/aim/vm_machdep.c2
-rw-r--r--sys/powerpc/include/frame.h2
-rw-r--r--sys/powerpc/powerpc/genassym.c2
-rw-r--r--sys/powerpc/powerpc/swtch.S5
-rw-r--r--sys/powerpc/powerpc/vm_machdep.c2
6 files changed, 16 insertions, 2 deletions
diff --git a/sys/powerpc/aim/swtch.S b/sys/powerpc/aim/swtch.S
index 6e3bfdd..12bb488 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 4e8c803..3b19213 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 6b75e46..ae0103b 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 38de0c2b..1aa26ef 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 6e3bfdd..12bb488 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 4e8c803..3b19213 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;
OpenPOWER on IntegriCloud