diff --git a/core/exceptions.c b/core/exceptions.c index c50db822df08..4ff7a9e4b1b6 100644 --- a/core/exceptions.c +++ b/core/exceptions.c @@ -112,7 +112,7 @@ void exception_entry(struct stack_frame *stack) l += snprintf(buf + l, EXCEPTION_MAX_STR - l, " MSR "REG, msr); prerror("%s\n", buf); dump_regs(stack); - backtrace(); + backtrace_r1((uint64_t)stack); if (platform.terminate) platform.terminate(buf); for (;;) ; @@ -129,7 +129,7 @@ void exception_entry(struct stack_frame *stack) l += snprintf(buf + l, EXCEPTION_MAX_STR - l, " MSR "REG, msr); prerror("%s\n", buf); dump_regs(stack); - backtrace(); + backtrace_r1((uint64_t)stack); if (fatal) { if (platform.terminate) platform.terminate(buf); diff --git a/core/stack.c b/core/stack.c index 711761b207f0..b94d115186dd 100644 --- a/core/stack.c +++ b/core/stack.c @@ -17,13 +17,13 @@ static struct bt_entry bt_buf[STACK_BUF_ENTRIES]; /* Dumps backtrace to buffer */ -void __nomcount backtrace_create(struct bt_entry *entries, +static void __nomcount __backtrace_create(struct bt_entry *entries, unsigned int max_ents, - struct bt_metadata *metadata) + struct bt_metadata *metadata, + struct stack_frame *eframe) { - unsigned long *fp = __builtin_frame_address(0); + unsigned long *fp = (unsigned long *)eframe; unsigned long top_adj = top_of_ram; - struct stack_frame *eframe = (struct stack_frame *)fp; /* Assume one stack for early backtraces */ if (top_of_ram == SKIBOOT_BASE + SKIBOOT_SIZE) @@ -52,6 +52,16 @@ void __nomcount backtrace_create(struct bt_entry *entries, metadata->pir = mfspr(SPR_PIR); } +void __nomcount backtrace_create(struct bt_entry *entries, + unsigned int max_ents, + struct bt_metadata *metadata) +{ + unsigned long *fp = __builtin_frame_address(0); + struct stack_frame *eframe = (struct stack_frame *)fp; + + __backtrace_create(entries, max_ents, metadata, eframe); +} + void backtrace_print(struct bt_entry *entries, struct bt_metadata *metadata, char *out_buf, unsigned int *len, bool symbols) { @@ -124,6 +134,18 @@ void backtrace(void) unlock(&bt_lock); } +void backtrace_r1(uint64_t r1) +{ + struct bt_metadata metadata; + + lock(&bt_lock); + + __backtrace_create(bt_buf, STACK_BUF_ENTRIES, &metadata, (struct stack_frame *)r1); + backtrace_print(bt_buf, &metadata, NULL, NULL, true); + + unlock(&bt_lock); +} + void __nomcount __stack_chk_fail(void); void __nomcount __stack_chk_fail(void) { diff --git a/include/stack.h b/include/stack.h index 9a1d18b04954..3ad52d64c0b4 100644 --- a/include/stack.h +++ b/include/stack.h @@ -123,6 +123,9 @@ extern void backtrace_print(struct bt_entry *entries, /* For use by debug code, create and print backtrace, uses a static buffer */ extern void backtrace(void); +/* For use by exception debug code, supply an r1 */ +extern void backtrace_r1(uint64_t r1); + #ifdef STACK_CHECK_ENABLED extern void check_stacks(void); #else