parisc: Consolidate unwind initialization calls
Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
parent
54c770da99
commit
9e0d5c451f
@ -73,8 +73,10 @@ unwind_table_remove(struct unwind_table *table);
|
||||
|
||||
void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
|
||||
struct pt_regs *regs);
|
||||
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);
|
||||
void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info,
|
||||
struct task_struct *t);
|
||||
void unwind_frame_init_task(struct unwind_frame_info *info,
|
||||
struct task_struct *task, struct pt_regs *regs);
|
||||
int unwind_once(struct unwind_frame_info *info);
|
||||
int unwind_to_user(struct unwind_frame_info *info);
|
||||
|
||||
|
@ -16,20 +16,7 @@ static void dump_trace(struct task_struct *task, struct stack_trace *trace)
|
||||
{
|
||||
struct unwind_frame_info info;
|
||||
|
||||
/* initialize unwind info */
|
||||
if (task == current) {
|
||||
unsigned long sp;
|
||||
struct pt_regs r;
|
||||
HERE:
|
||||
asm volatile ("copy %%r30, %0" : "=r"(sp));
|
||||
memset(&r, 0, sizeof(struct pt_regs));
|
||||
r.iaoq[0] = (unsigned long)&&HERE;
|
||||
r.gr[2] = (unsigned long)__builtin_return_address(0);
|
||||
r.gr[30] = sp;
|
||||
unwind_frame_init(&info, task, &r);
|
||||
} else {
|
||||
unwind_frame_init_from_blocked_task(&info, task);
|
||||
}
|
||||
unwind_frame_init_task(&info, task, NULL);
|
||||
|
||||
/* unwind stack and save entries in stack_trace struct */
|
||||
trace->nr_entries = 0;
|
||||
|
@ -45,7 +45,7 @@
|
||||
|
||||
#include "../math-emu/math-emu.h" /* for handle_fpe() */
|
||||
|
||||
static void parisc_show_stack(struct task_struct *task, unsigned long *sp,
|
||||
static void parisc_show_stack(struct task_struct *task,
|
||||
struct pt_regs *regs);
|
||||
|
||||
static int printbinary(char *buf, unsigned long x, int nbits)
|
||||
@ -152,7 +152,7 @@ void show_regs(struct pt_regs *regs)
|
||||
printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]);
|
||||
printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]);
|
||||
|
||||
parisc_show_stack(current, NULL, regs);
|
||||
parisc_show_stack(current, regs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,44 +185,19 @@ static void do_show_stack(struct unwind_frame_info *info)
|
||||
printk(KERN_CRIT "\n");
|
||||
}
|
||||
|
||||
static void parisc_show_stack(struct task_struct *task, unsigned long *sp,
|
||||
static void parisc_show_stack(struct task_struct *task,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
struct unwind_frame_info info;
|
||||
struct task_struct *t;
|
||||
|
||||
t = task ? task : current;
|
||||
if (regs) {
|
||||
unwind_frame_init(&info, t, regs);
|
||||
goto show_stack;
|
||||
}
|
||||
unwind_frame_init_task(&info, task, regs);
|
||||
|
||||
if (t == current) {
|
||||
unsigned long sp;
|
||||
|
||||
HERE:
|
||||
asm volatile ("copy %%r30, %0" : "=r"(sp));
|
||||
{
|
||||
struct pt_regs r;
|
||||
|
||||
memset(&r, 0, sizeof(struct pt_regs));
|
||||
r.iaoq[0] = (unsigned long)&&HERE;
|
||||
r.gr[2] = (unsigned long)__builtin_return_address(0);
|
||||
r.gr[30] = sp;
|
||||
|
||||
unwind_frame_init(&info, current, &r);
|
||||
}
|
||||
} else {
|
||||
unwind_frame_init_from_blocked_task(&info, t);
|
||||
}
|
||||
|
||||
show_stack:
|
||||
do_show_stack(&info);
|
||||
}
|
||||
|
||||
void show_stack(struct task_struct *t, unsigned long *sp)
|
||||
{
|
||||
return parisc_show_stack(t, sp, NULL);
|
||||
parisc_show_stack(t, NULL);
|
||||
}
|
||||
|
||||
int is_valid_bugaddr(unsigned long iaoq)
|
||||
|
@ -403,9 +403,31 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct
|
||||
kfree(r2);
|
||||
}
|
||||
|
||||
void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs)
|
||||
#define get_parisc_stackpointer() ({ \
|
||||
unsigned long sp; \
|
||||
__asm__("copy %%r30, %0" : "=r"(sp)); \
|
||||
(sp); \
|
||||
})
|
||||
|
||||
void unwind_frame_init_task(struct unwind_frame_info *info,
|
||||
struct task_struct *task, struct pt_regs *regs)
|
||||
{
|
||||
unwind_frame_init(info, current, regs);
|
||||
task = task ? task : current;
|
||||
|
||||
if (task == current) {
|
||||
struct pt_regs r;
|
||||
|
||||
if (!regs) {
|
||||
memset(&r, 0, sizeof(r));
|
||||
r.iaoq[0] = _THIS_IP_;
|
||||
r.gr[2] = _RET_IP_;
|
||||
r.gr[30] = get_parisc_stackpointer();
|
||||
regs = &r;
|
||||
}
|
||||
unwind_frame_init(info, task, &r);
|
||||
} else {
|
||||
unwind_frame_init_from_blocked_task(info, task);
|
||||
}
|
||||
}
|
||||
|
||||
int unwind_once(struct unwind_frame_info *next_frame)
|
||||
@ -442,19 +464,12 @@ int unwind_to_user(struct unwind_frame_info *info)
|
||||
unsigned long return_address(unsigned int level)
|
||||
{
|
||||
struct unwind_frame_info info;
|
||||
struct pt_regs r;
|
||||
unsigned long sp;
|
||||
|
||||
/* initialize unwind info */
|
||||
asm volatile ("copy %%r30, %0" : "=r"(sp));
|
||||
memset(&r, 0, sizeof(struct pt_regs));
|
||||
r.iaoq[0] = _THIS_IP_;
|
||||
r.gr[2] = _RET_IP_;
|
||||
r.gr[30] = sp;
|
||||
unwind_frame_init(&info, current, &r);
|
||||
unwind_frame_init_task(&info, current, NULL);
|
||||
|
||||
/* unwind stack */
|
||||
++level;
|
||||
level += 2;
|
||||
do {
|
||||
if (unwind_once(&info) < 0 || info.ip == 0)
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user