aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2019-09-25 11:01:36 +1000
committerOliver O'Halloran <oohall@gmail.com>2019-10-03 09:55:58 +1000
commit1785745d5a7eaefd7d0c135f2a3b0f5d86aefec5 (patch)
tree057d8ffaae6b01276485e5a86b0fc46664086199
parent216433af16cdc441ef2b3d5bb0510570a1403e1c (diff)
downloadskiboot-1785745d5a7eaefd7d0c135f2a3b0f5d86aefec5.zip
skiboot-1785745d5a7eaefd7d0c135f2a3b0f5d86aefec5.tar.gz
skiboot-1785745d5a7eaefd7d0c135f2a3b0f5d86aefec5.tar.bz2
core/exceptions.c: do not include handler code in exception backtrace
Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
-rw-r--r--core/exceptions.c4
-rw-r--r--core/stack.c30
-rw-r--r--include/stack.h3
3 files changed, 31 insertions, 6 deletions
diff --git a/core/exceptions.c b/core/exceptions.c
index c50db82..4ff7a9e 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 711761b..b94d115 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 9a1d18b..3ad52d6 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