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);
{
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;
#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)
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);
}
}
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;
- }
-
- 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);
- }
+ unwind_frame_init_task(&info, task, regs);
-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)
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)
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;