diff options
| author | Marcin Bukat <marcin.bukat@gmail.com> | 2012-01-25 09:57:59 +0100 |
|---|---|---|
| committer | Marcin Bukat <marcin.bukat@gmail.com> | 2012-02-22 08:33:26 +0100 |
| commit | b4eab599513324dcaffa4c5693345ae11f3f9725 (patch) | |
| tree | 58d66298269d2cec58102724565b573f250b5153 /firmware/target | |
| parent | 680c6fcde1eabb45dd12c59718d708b2cda61f6a (diff) | |
| download | rockbox-b4eab599513324dcaffa4c5693345ae11f3f9725.zip rockbox-b4eab599513324dcaffa4c5693345ae11f3f9725.tar.gz rockbox-b4eab599513324dcaffa4c5693345ae11f3f9725.tar.bz2 rockbox-b4eab599513324dcaffa4c5693345ae11f3f9725.tar.xz | |
Arm stack unwinder
Simplified stack unwinder for ARM. This is port of
http://www.mcternan.me.uk/ArmStackUnwinding/
backtrace() is called from UIE() on native targets
and from panicf() on both native and ARM RaaA.
Change-Id: I8e4b3c02490dd60b30aa372fe842d193b8929ce0
Diffstat (limited to 'firmware/target')
| -rw-r--r-- | firmware/target/arm/system-arm.c | 19 | ||||
| -rw-r--r-- | firmware/target/hosted/ypr0/ypr0.make | 2 |
2 files changed, 17 insertions, 4 deletions
diff --git a/firmware/target/arm/system-arm.c b/firmware/target/arm/system-arm.c index 23ccfd1..c4692bb 100644 --- a/firmware/target/arm/system-arm.c +++ b/firmware/target/arm/system-arm.c @@ -25,6 +25,9 @@ #include "font.h" #include "gcc_extensions.h" +#include <get_sp.h> +#include <backtrace.h> + static const char* const uiename[] = { "Undefined instruction", "Prefetch abort", @@ -38,6 +41,12 @@ static const char* const uiename[] = { */ void NORETURN_ATTR UIE(unsigned int pc, unsigned int num) { + /* safe guard variable - we call backtrace() only on first + * UIE call. This prevent endless loop if backtrace() touches + * memory regions which cause abort + */ + static bool triggered = false; + #if LCD_DEPTH > 1 lcd_set_backdrop(NULL); lcd_set_drawmode(DRMODE_SOLID); @@ -49,9 +58,7 @@ void NORETURN_ATTR UIE(unsigned int pc, unsigned int num) lcd_setfont(FONT_SYSFIXED); lcd_set_viewport(NULL); lcd_clear_display(); - lcd_puts(0, line++, uiename[num]); - lcd_putsf(0, line++, "at %08x" IF_COP(" (%d)"), pc - IF_COP(, CURRENT_CORE)); + lcd_putsf(0, line++, "%s at %08x" IF_COP(" (%d)"), uiename[num], pc IF_COP(, CURRENT_CORE)); #if !defined(CPU_ARM7TDMI) && (CONFIG_CPU != RK27XX) /* arm7tdmi has no MPU/MMU */ if(num == 1 || num == 2) /* prefetch / data abort */ @@ -88,6 +95,12 @@ void NORETURN_ATTR UIE(unsigned int pc, unsigned int num) } /* num == 1 || num == 2 // prefetch/data abort */ #endif /* !defined(CPU_ARM7TDMI */ + if (!triggered) + { + triggered = true; + backtrace(pc, __get_sp(), &line); + } + lcd_update(); disable_interrupt(IRQ_FIQ_STATUS); diff --git a/firmware/target/hosted/ypr0/ypr0.make b/firmware/target/hosted/ypr0/ypr0.make index c211487..1b67054 100644 --- a/firmware/target/hosted/ypr0/ypr0.make +++ b/firmware/target/hosted/ypr0/ypr0.make @@ -14,7 +14,7 @@ SIMFLAGS += $(INCLUDES) $(DEFINES) -DHAVE_CONFIG_H $(GCCOPTS) .SECONDEXPANSION: # $$(OBJ) is not populated until after this -$(BUILDDIR)/rockbox.elf : $$(OBJ) $$(FIRMLIB) $$(VOICESPEEXLIB) $$(SKINLIB) +$(BUILDDIR)/rockbox.elf : $$(OBJ) $$(FIRMLIB) $$(VOICESPEEXLIB) $$(SKINLIB) $$(UNWARMINDER) $(call PRINTS,LD $(@F))$(CC) $(GCCOPTS) -Os -o $@ $(OBJ) \ -L$(BUILDDIR)/firmware -lfirmware \ -L$(BUILDDIR)/apps/codecs $(VOICESPEEXLIB:lib%.a=-l%) \ |