Add a function to print frame pointers depending on symbols
CONFIG_(SPL)_FRAMEPOINTER.

Signed-off-by: Heinrich Schuchardt <heinrich.schucha...@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

Reply via email to