[parisc-linux-cvs] linux-2.6 tausq
Randolph Chung
randolph at tausq.org
Fri Aug 6 15:46:46 MDT 2004
> Modified files:
> arch/parisc/kernel: unwind.c traps.c
> include/asm-parisc: unwind.h
>
> Log message:
> handle unwinding from inside a function prologue.
Index: arch/parisc/kernel/unwind.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/unwind.c,v
retrieving revision 1.4
diff -u -p -r1.4 unwind.c
--- arch/parisc/kernel/unwind.c 6 Aug 2004 19:18:24 -0000 1.4
+++ arch/parisc/kernel/unwind.c 6 Aug 2004 21:45:01 -0000
@@ -240,19 +240,21 @@ static void unwind_frame_regs(struct unw
info->prev_sp = info->sp - frame_size;
if (rpoffset)
- info->prev_ip = *(unsigned long *)(info->prev_sp - rpoffset);
+ info->rp = *(unsigned long *)(info->prev_sp - rpoffset);
+ info->prev_ip = info->rp;
dbg("analyzing func @ %lx, setting prev_sp=%lx prev_ip=%lx\n", info->ip, info->prev_sp, info->prev_ip);
}
}
void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
- unsigned long sp, unsigned long ip)
+ unsigned long sp, unsigned long ip, unsigned long rp)
{
memset(info, 0, sizeof(struct unwind_frame_info));
info->t = t;
info->sp = sp;
info->ip = ip;
+ info->rp = rp;
dbg("(%d) Start unwind from sp=%08lx ip=%08lx\n", t ? (int)t->pid : 0, info->sp, info->ip);
}
@@ -260,12 +262,13 @@ void unwind_frame_init(struct unwind_fra
void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t)
{
struct pt_regs *regs = &t->thread.regs;
- unwind_frame_init(info, t, regs->ksp, regs->kpc);
+ unwind_frame_init(info, t, regs->ksp, regs->kpc, 0);
}
void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs)
{
- unwind_frame_init(info, current, regs->gr[30], regs->iaoq[0]);
+ unwind_frame_init(info, current, regs->gr[30], regs->iaoq[0],
+ regs->gr[2]);
}
int unwind_once(struct unwind_frame_info *next_frame)
Index: arch/parisc/kernel/traps.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/traps.c,v
retrieving revision 1.16
diff -u -p -r1.16 traps.c
--- arch/parisc/kernel/traps.c 6 Aug 2004 19:18:24 -0000 1.16
+++ arch/parisc/kernel/traps.c 6 Aug 2004 21:45:01 -0000
@@ -141,12 +141,13 @@ void show_stack(struct task_struct *task
struct unwind_frame_info info;
if (!task) {
- unsigned long sp, ip;
+ unsigned long sp, ip, rp;
HERE:
sp = (unsigned long)&i;
ip = (unsigned long)&&HERE;
- unwind_frame_init(&info, current, sp, ip);
+ rp = (unsigned long)__builtin_return_address(0);
+ unwind_frame_init(&info, current, sp, ip, rp);
} else {
unwind_frame_init_from_blocked_task(&info, task);
}
Index: include/asm-parisc/unwind.h
===================================================================
RCS file: /var/cvs/linux-2.6/include/asm-parisc/unwind.h,v
retrieving revision 1.3
diff -u -p -r1.3 unwind.h
--- include/asm-parisc/unwind.h 6 Aug 2004 19:18:24 -0000 1.3
+++ include/asm-parisc/unwind.h 6 Aug 2004 21:45:01 -0000
@@ -50,13 +50,12 @@ struct unwind_table {
};
struct unwind_frame_info {
- unsigned long sp;
- unsigned long ip;
struct task_struct *t;
/* Eventually we would like to be able to get at any of the registers
available; but for now we only try to get the sp and ip for each
frame */
/* struct pt_regs regs; */
+ unsigned long sp, ip, rp;
unsigned long prev_sp, prev_ip;
};
@@ -64,7 +63,7 @@ void * unwind_table_add(const char *name
unsigned long gp,
void *start, void *end);
void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
- unsigned long sp, unsigned long ip);
+ unsigned long sp, unsigned long ip, unsigned long rp);
void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t);
void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs);
int unwind_once(struct unwind_frame_info *info);
More information about the parisc-linux-cvs
mailing list