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.
This commit is contained in:
Peter Grehan 2004-07-22 01:28:51 +00:00
parent 82ab2f48a4
commit bddfaa895c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=132520
6 changed files with 16 additions and 2 deletions

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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));

View file

@ -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

View file

@ -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;