[PATCH 3/5] arm64: implement printing backtraces
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Thu Jul 3 07:19:49 CEST 2025
Add a function to print frame pointers depending on symbols
CONFIG_(SPL)_FRAMEPOINTER.
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
---
arch/arm/Makefile | 9 ++++++-
arch/arm/lib/interrupts_64.c | 46 ++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 5ecadb2ef1b..41e75b5bcb1 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -33,6 +33,13 @@ endif
# Evaluate arch cc-option calls now
arch-y := $(arch-y)
+ifeq ($(CONFIG_$(PHASE_)FRAMEPOINTER),y)
+ ARCH_FLAGS += -fno-omit-frame-pointer
+endif
+
+PLATFORM_CPPFLAGS += $(ARCH_FLAGS)
+CFLAGS_EFI += $(ARCH_FLAGS)
+
# This selects how we optimise for the processor.
tune-$(CONFIG_CPU_ARM720T) =-mtune=arm7tdmi
tune-$(CONFIG_CPU_ARM920T) =
@@ -47,7 +54,7 @@ tune-$(CONFIG_ARM64) =
# Evaluate tune cc-option calls now
tune-y := $(tune-y)
-PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
+PLATFORM_CPPFLAGS += $(ARCH_FLAGS) $(arch-y) $(tune-y)
# Machine directory name. This list is sorted alphanumerically
# by CONFIG_* macro name.
diff --git a/arch/arm/lib/interrupts_64.c b/arch/arm/lib/interrupts_64.c
index b3024ba514e..970f8b6831f 100644
--- a/arch/arm/lib/interrupts_64.c
+++ b/arch/arm/lib/interrupts_64.c
@@ -98,6 +98,35 @@ void show_regs(struct pt_regs *regs)
dump_instr(regs);
}
+/**
+ * show_backtrace() - show backtrace using frame pointers
+ *
+ * @regs - registers
+ */
+static void show_backtrace(struct pt_regs *regs)
+{
+ void **fp = (void **)regs->regs[29];
+ unsigned int count = 0;
+ void *lr;
+
+ printf("\nbacktrace:\n");
+
+ while (fp) {
+ lr = fp[1];
+ printf("%3d: fp: %p lr: %p",
+ count, fp, lr);
+
+ if (gd && gd->flags & GD_FLG_RELOC)
+ printf(" - %p (reloc)\n", lr - gd->reloc_off);
+ else
+ printf("\n");
+
+ fp = fp[0];
+ ++count;
+ }
+ printf("\n");
+}
+
/*
* Try to "emulate" a semihosting call in the event that we don't have a
* debugger attached.
@@ -149,6 +179,8 @@ void do_bad_sync(struct pt_regs *pt_regs)
printf("Bad mode in \"Synchronous Abort\" handler, esr 0x%08lx\n",
pt_regs->esr);
show_regs(pt_regs);
+ if (CONFIG_IS_ENABLED(FRAMEPOINTER))
+ show_backtrace(pt_regs);
show_efi_loaded_images(pt_regs);
panic("Resetting CPU ...\n");
}
@@ -161,6 +193,8 @@ void do_bad_irq(struct pt_regs *pt_regs)
efi_restore_gd();
printf("Bad mode in \"Irq\" handler, esr 0x%08lx\n", pt_regs->esr);
show_regs(pt_regs);
+ if (CONFIG_IS_ENABLED(FRAMEPOINTER))
+ show_backtrace(pt_regs);
show_efi_loaded_images(pt_regs);
panic("Resetting CPU ...\n");
}
@@ -173,6 +207,8 @@ void do_bad_fiq(struct pt_regs *pt_regs)
efi_restore_gd();
printf("Bad mode in \"Fiq\" handler, esr 0x%08lx\n", pt_regs->esr);
show_regs(pt_regs);
+ if (CONFIG_IS_ENABLED(FRAMEPOINTER))
+ show_backtrace(pt_regs);
show_efi_loaded_images(pt_regs);
panic("Resetting CPU ...\n");
}
@@ -185,6 +221,8 @@ void do_bad_error(struct pt_regs *pt_regs)
efi_restore_gd();
printf("Bad mode in \"Error\" handler, esr 0x%08lx\n", pt_regs->esr);
show_regs(pt_regs);
+ if (CONFIG_IS_ENABLED(FRAMEPOINTER))
+ show_backtrace(pt_regs);
show_efi_loaded_images(pt_regs);
panic("Resetting CPU ...\n");
}
@@ -202,6 +240,8 @@ void do_sync(struct pt_regs *pt_regs)
dump_far(pt_regs->esr);
printf("\n");
show_regs(pt_regs);
+ if (CONFIG_IS_ENABLED(FRAMEPOINTER))
+ show_backtrace(pt_regs);
show_efi_loaded_images(pt_regs);
panic("Resetting CPU ...\n");
}
@@ -214,6 +254,8 @@ void do_irq(struct pt_regs *pt_regs)
efi_restore_gd();
printf("\"Irq\" handler, esr 0x%08lx\n", pt_regs->esr);
show_regs(pt_regs);
+ if (CONFIG_IS_ENABLED(FRAMEPOINTER))
+ show_backtrace(pt_regs);
show_efi_loaded_images(pt_regs);
panic("Resetting CPU ...\n");
}
@@ -226,6 +268,8 @@ void do_fiq(struct pt_regs *pt_regs)
efi_restore_gd();
printf("\"Fiq\" handler, esr 0x%08lx\n", pt_regs->esr);
show_regs(pt_regs);
+ if (CONFIG_IS_ENABLED(FRAMEPOINTER))
+ show_backtrace(pt_regs);
show_efi_loaded_images(pt_regs);
panic("Resetting CPU ...\n");
}
@@ -241,6 +285,8 @@ void __weak do_error(struct pt_regs *pt_regs)
efi_restore_gd();
printf("\"Error\" handler, esr 0x%08lx\n", pt_regs->esr);
show_regs(pt_regs);
+ if (CONFIG_IS_ENABLED(FRAMEPOINTER))
+ show_backtrace(pt_regs);
show_efi_loaded_images(pt_regs);
panic("Resetting CPU ...\n");
}
--
2.48.1
More information about the U-Boot
mailing list