* [PATCH] ARM stack unwinding support
@ 2011-03-08 11:24 Sascha Hauer
2011-03-08 11:24 ` [PATCH 1/3] ARM: create a second level page table entry for the exception vectors Sascha Hauer
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Sascha Hauer @ 2011-03-08 11:24 UTC (permalink / raw)
To: barebox
Hi All,
The following patches enable stack unwinding support on ARM. With
this we can get nice backtraces like this:
barebox@Freescale i.MX51 PDK:/ md 0x1
data abort
pc : [<97f24f04>] lr : [<97f24ed4>]
sp : 95effde8 ip : 97f26184 fp : 00000000
r10: 00000000 r9 : 00000000 r8 : 00000000
r7 : 95f02f18 r6 : 00000004 r5 : 95f02f18 r4 : 00000001
r3 : 00000020 r2 : 00000002 r1 : 00000004 r0 : 00000040
Flags: nZCv IRQs off FIQs off Mode SVC_32
[<97f24f04>] (memcpy_sz+0x5c/0x74) from [<97f261c0>] (mem_read+0x3c/0x4c)
[<97f261c0>] (mem_read+0x3c/0x4c) from [<97f24b94>] (cdev_read+0x30/0x34)
[<97f24b94>] (cdev_read+0x30/0x34) from [<97f24bbc>] (devfs_read+0x24/0x28)
[<97f24bbc>] (devfs_read+0x24/0x28) from [<97f2535c>] (read+0x74/0x98)
[<97f2535c>] (read+0x74/0x98) from [<97f19e04>] (do_mem_md+0xd8/0x16c)
[<97f19e04>] (do_mem_md+0xd8/0x16c) from [<97f05b18>] (execute_command+0x30/0x60)
[<97f05b18>] (execute_command+0x30/0x60) from [<97f037fc>] (run_list_real+0x6a0/0x768)
[<97f037fc>] (run_list_real+0x6a0/0x768) from [<97f03a1c>] (parse_stream_outer+0x158/0x27c)
[<97f03a1c>] (parse_stream_outer+0x158/0x27c) from [<97f03d6c>] (run_shell+0x3c/0x4c)
[<97f03d6c>] (run_shell+0x3c/0x4c) from [<97f06a90>] (start_barebox+0xd8/0x114)
[<97f06a90>] (start_barebox+0xd8/0x114) from [<90002080>] (0x90002080)
Resetting CPU ...
Furthermore, the setup of the exception vectors is reworked in a board
independent way. We only supported section mapping which only works
on 1MB boundaries, so we had to put the exception vectors on a 1MB
boundary also. The following patches allow to create 4Kb pages, which
is used to copy the exception vectors to 0x0 using a page.
Sascha
Sascha Hauer (3):
ARM: create a second level page table entry for the exception vectors
ARM: Add stack unwinding support
kallsyms/printk: enable symbol printing support (%pS)
Makefile | 2 +-
arch/arm/Kconfig | 10 +
arch/arm/Makefile | 4 +
arch/arm/boards/chumby_falconwing/falconwing.c | 5 -
arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c | 5 -
arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c | 5 -
arch/arm/boards/freescale-mx51-pdk/board.c | 6 -
arch/arm/boards/guf-cupid/board.c | 6 -
arch/arm/boards/guf-neso/board.c | 5 -
arch/arm/boards/karo-tx28/tx28.c | 5 -
arch/arm/boards/pcm037/pcm037.c | 5 -
arch/arm/boards/pcm038/pcm038.c | 5 -
arch/arm/boards/pcm043/pcm043.c | 6 -
arch/arm/boards/phycard-i.MX27/pca100.c | 5 -
arch/arm/cpu/interrupts.c | 4 +
arch/arm/cpu/mmu.c | 48 +++
arch/arm/lib/Makefile | 2 +-
arch/arm/lib/barebox.lds.S | 16 +
arch/arm/lib/unwind.c | 344 +++++++++++++++++++++
common/Kconfig | 3 -
common/kallsyms.c | 148 +++++++++-
include/kallsyms.h | 5 +
lib/vsprintf.c | 1 +
23 files changed, 581 insertions(+), 64 deletions(-)
create mode 100644 arch/arm/lib/unwind.c
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] ARM: create a second level page table entry for the exception vectors
2011-03-08 11:24 [PATCH] ARM stack unwinding support Sascha Hauer
@ 2011-03-08 11:24 ` Sascha Hauer
2011-03-08 11:24 ` [PATCH 2/3] ARM: Add stack unwinding support Sascha Hauer
2011-03-08 11:24 ` [PATCH 3/3] kallsyms/printk: enable symbol printing support (%pS) Sascha Hauer
2 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2011-03-08 11:24 UTC (permalink / raw)
To: barebox
Often enough the exception vectors are not on TEXT_BASE (for example
on i.MX SoCs in internal boot mode), so the board specific code did
not map the exception vectors to 0x0 but whatever happens to be on
TEXT_BASE. Also, the current section-only mapping requires the
exception vectors to be on a 1MB boundary.
Instead, create the possibility to create second level tables and
use this to map a copy of the exception vectors in a board
independent way.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/boards/chumby_falconwing/falconwing.c | 5 --
arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c | 5 --
arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c | 5 --
arch/arm/boards/freescale-mx51-pdk/board.c | 6 ---
arch/arm/boards/guf-cupid/board.c | 6 ---
arch/arm/boards/guf-neso/board.c | 5 --
arch/arm/boards/karo-tx28/tx28.c | 5 --
arch/arm/boards/pcm037/pcm037.c | 5 --
arch/arm/boards/pcm038/pcm038.c | 5 --
arch/arm/boards/pcm043/pcm043.c | 6 ---
arch/arm/boards/phycard-i.MX27/pca100.c | 5 --
arch/arm/cpu/mmu.c | 48 +++++++++++++++++++++
12 files changed, 48 insertions(+), 58 deletions(-)
diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
index d46431c..6de8e28 100644
--- a/arch/arm/boards/chumby_falconwing/falconwing.c
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -292,11 +292,6 @@ static int falconwing_mmu_init(void)
setup_dma_coherent(0x10000000);
-#if TEXT_BASE & (0x100000 - 1)
-#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
-#else
- arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
-#endif
mmu_enable();
return 0;
diff --git a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
index 4567cba..a7e9951 100644
--- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
+++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
@@ -153,11 +153,6 @@ static void eukrea_cpuimx27_mmu_init(void)
setup_dma_coherent(0x10000000);
-#if TEXT_BASE & (0x100000 - 1)
-#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
-#else
- arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
-#endif
mmu_enable();
}
#else
diff --git a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
index f377793..73bb2e1 100644
--- a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
+++ b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
@@ -161,11 +161,6 @@ static int eukrea_cpuimx35_mmu_init(void)
setup_dma_coherent(0x10000000);
-#if TEXT_BASE & (0x100000 - 1)
-#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
-#else
- arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
-#endif
mmu_enable();
#ifdef CONFIG_CACHE_L2X0
diff --git a/arch/arm/boards/freescale-mx51-pdk/board.c b/arch/arm/boards/freescale-mx51-pdk/board.c
index ff779ca..35d6153 100644
--- a/arch/arm/boards/freescale-mx51-pdk/board.c
+++ b/arch/arm/boards/freescale-mx51-pdk/board.c
@@ -96,12 +96,6 @@ static void babbage_mmu_init(void)
setup_dma_coherent(0x20000000);
-#if TEXT_BASE & (0x100000 - 1)
-#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
-#else
- arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
-#endif
-
mmu_enable();
}
#else
diff --git a/arch/arm/boards/guf-cupid/board.c b/arch/arm/boards/guf-cupid/board.c
index e30f8e5..d04af78 100644
--- a/arch/arm/boards/guf-cupid/board.c
+++ b/arch/arm/boards/guf-cupid/board.c
@@ -145,12 +145,6 @@ static int cupid_mmu_init(void)
setup_dma_coherent(0x10000000);
-#if TEXT_BASE & (0x100000 - 1)
-#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
-#else
- arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
-#endif
-
mmu_enable();
#ifdef CONFIG_CACHE_L2X0
diff --git a/arch/arm/boards/guf-neso/board.c b/arch/arm/boards/guf-neso/board.c
index d371dd6..c4b2fa1 100644
--- a/arch/arm/boards/guf-neso/board.c
+++ b/arch/arm/boards/guf-neso/board.c
@@ -167,11 +167,6 @@ static void neso_mmu_init(void)
setup_dma_coherent(0x10000000);
-#if TEXT_BASE & (0x100000 - 1)
-#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
-#else
- arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
-#endif
mmu_enable();
}
#else
diff --git a/arch/arm/boards/karo-tx28/tx28.c b/arch/arm/boards/karo-tx28/tx28.c
index 5692171..1f47a8d 100644
--- a/arch/arm/boards/karo-tx28/tx28.c
+++ b/arch/arm/boards/karo-tx28/tx28.c
@@ -93,11 +93,6 @@ static int tx28_mmu_init(void)
setup_dma_coherent(0x10000000);
-#if TEXT_BASE & (0x100000 - 1)
-#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
-#else
- arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
-#endif
mmu_enable();
return 0;
diff --git a/arch/arm/boards/pcm037/pcm037.c b/arch/arm/boards/pcm037/pcm037.c
index ffecec2..cb4ffe6 100644
--- a/arch/arm/boards/pcm037/pcm037.c
+++ b/arch/arm/boards/pcm037/pcm037.c
@@ -239,11 +239,6 @@ static void pcm037_mmu_init(void)
setup_dma_coherent(0x10000000);
-#if TEXT_BASE & (0x100000 - 1)
-#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
-#else
- arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
-#endif
mmu_enable();
#ifdef CONFIG_CACHE_L2X0
diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c
index 1dbc6b6..3ca6650 100644
--- a/arch/arm/boards/pcm038/pcm038.c
+++ b/arch/arm/boards/pcm038/pcm038.c
@@ -179,11 +179,6 @@ static void pcm038_mmu_init(void)
setup_dma_coherent(0x10000000);
-#if TEXT_BASE & (0x100000 - 1)
-#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
-#else
- arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
-#endif
mmu_enable();
}
#else
diff --git a/arch/arm/boards/pcm043/pcm043.c b/arch/arm/boards/pcm043/pcm043.c
index 36bde45..7db3c83 100644
--- a/arch/arm/boards/pcm043/pcm043.c
+++ b/arch/arm/boards/pcm043/pcm043.c
@@ -133,12 +133,6 @@ static int pcm043_mmu_init(void)
setup_dma_coherent(0x10000000);
-#if TEXT_BASE & (0x100000 - 1)
-#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
-#else
- arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
-#endif
-
mmu_enable();
#ifdef CONFIG_CACHE_L2X0
diff --git a/arch/arm/boards/phycard-i.MX27/pca100.c b/arch/arm/boards/phycard-i.MX27/pca100.c
index c539ea1..89c0a14 100644
--- a/arch/arm/boards/phycard-i.MX27/pca100.c
+++ b/arch/arm/boards/phycard-i.MX27/pca100.c
@@ -106,11 +106,6 @@ static void pca100_mmu_init(void)
setup_dma_coherent(0x10000000);
-#if TEXT_BASE & (0x100000 - 1)
-#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
-#else
- arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
-#endif
mmu_enable();
}
#else
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index df664f6..593e39c 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -24,6 +24,52 @@ void arm_create_section(unsigned long virt, unsigned long phys, int size_m,
}
/*
+ * Create a second level translation table for the given virtual address.
+ * We initially create a flat uncached mapping on it.
+ * Not yet exported, but may be later if someone finds use for it.
+ */
+static u32 *arm_create_pte(unsigned long virt)
+{
+ u32 *table;
+ int i;
+
+ table = memalign(0x400, 0x400);
+
+ ttb[virt] = (unsigned long)table | PMD_TYPE_TABLE;
+
+ for (i = 0; i < 256; i++)
+ table[i] = virt | PTE_TYPE_SMALL | PTE_SMALL_AP_UNO_SRW;
+
+ return table;
+}
+
+/*
+ * We have 8 exception vectors and the table consists of absolute
+ * jumps, so we need 8 * 4 bytes for the instructions and another
+ * 8 * 4 bytes for the addresses.
+ */
+#define ARM_VECTORS_SIZE (sizeof(u32) * 8 * 2)
+
+/*
+ * Allocate a page, map it to the zero page and copy our exception
+ * vectors there.
+ */
+static void vectors_init(void)
+{
+ u32 *exc;
+ void *vectors;
+ extern unsigned long exception_vectors;
+
+ exc = arm_create_pte(0x0);
+
+ vectors = xmemalign(PAGE_SIZE, PAGE_SIZE);
+ memset(vectors, 0, PAGE_SIZE);
+ memcpy(vectors, &exception_vectors, ARM_VECTORS_SIZE);
+
+ exc[0] = (u32)vectors | PTE_TYPE_SMALL | PTE_SMALL_AP_UNO_SRW;
+}
+
+/*
* Prepare MMU for usage and create a flat mapping. Board
* code is responsible to remap the SDRAM cached
*/
@@ -43,6 +89,8 @@ void mmu_init(void)
/* create a flat mapping */
arm_create_section(0, 0, 4096, PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT);
+
+ vectors_init();
}
/*
--
1.7.2.3
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/3] ARM: Add stack unwinding support
2011-03-08 11:24 [PATCH] ARM stack unwinding support Sascha Hauer
2011-03-08 11:24 ` [PATCH 1/3] ARM: create a second level page table entry for the exception vectors Sascha Hauer
@ 2011-03-08 11:24 ` Sascha Hauer
2011-03-08 11:37 ` Baruch Siach
2011-03-08 15:14 ` Sascha Hauer
2011-03-08 11:24 ` [PATCH 3/3] kallsyms/printk: enable symbol printing support (%pS) Sascha Hauer
2 siblings, 2 replies; 7+ messages in thread
From: Sascha Hauer @ 2011-03-08 11:24 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/Kconfig | 10 ++
arch/arm/Makefile | 4 +
arch/arm/cpu/interrupts.c | 4 +
arch/arm/lib/Makefile | 2 +-
arch/arm/lib/barebox.lds.S | 16 ++
arch/arm/lib/unwind.c | 344 ++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 379 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/lib/unwind.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bc54e58..aae0e99 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -115,6 +115,16 @@ config ARM_OPTIMZED_STRING_FUNCTIONS
These functions work much faster than the normal versions but
increase your binary size.
+config ARM_UNWIND
+ bool "enable stack unwinding support"
+ depends on AEABI
+ help
+ This option enables stack unwinding support in barebox
+ using the information automatically generated by the
+ compiler. The resulting kernel image is slightly bigger but
+ the performance is not affected. Currently, this feature
+ only works with EABI compilers. If unsure say Y.
+
endmenu
source common/Kconfig
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index d075efd..697c783 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -34,6 +34,10 @@ else
CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
endif
+ifeq ($(CONFIG_ARM_UNWIND),y)
+CFLAGS_ABI +=-funwind-tables
+endif
+
CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y)
AFLAGS += -include asm/unified.h
diff --git a/arch/arm/cpu/interrupts.c b/arch/arm/cpu/interrupts.c
index 4a0b3f8..5168921 100644
--- a/arch/arm/cpu/interrupts.c
+++ b/arch/arm/cpu/interrupts.c
@@ -27,6 +27,7 @@
#include <common.h>
#include <asm/ptrace.h>
+#include <asm/unwind.h>
void do_undefined_instruction (struct pt_regs *pt_regs);
void do_software_interrupt (struct pt_regs *pt_regs);
@@ -115,6 +116,9 @@ void show_regs (struct pt_regs *regs)
fast_interrupts_enabled (regs) ? "on" : "off",
processor_modes[processor_mode (regs)],
thumb_mode (regs) ? " (T)" : "");
+#ifdef CONFIG_ARM_UNWIND
+ unwind_backtrace(regs);
+#endif
}
/**
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 89cb72b..3a01083 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -14,7 +14,7 @@ obj-y += ashldi3.o
obj-y += lshrdi3.o
obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memcpy.o
obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o
-
+obj-$(CONFIG_ARM_UNWIND) += unwind.o
obj-$(CONFIG_MODULES) += module.o
extra-$(CONFIG_GENERIC_LINKER_SCRIPT) += barebox.lds
diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S
index cc74b2f..7683f73 100644
--- a/arch/arm/lib/barebox.lds.S
+++ b/arch/arm/lib/barebox.lds.S
@@ -51,6 +51,22 @@ SECTIONS
. = ALIGN(4);
.rodata : { *(.rodata*) }
+#ifdef CONFIG_ARM_UNWIND
+ /*
+ * Stack unwinding tables
+ */
+ . = ALIGN(8);
+ .ARM.unwind_idx : {
+ __start_unwind_idx = .;
+ *(.ARM.exidx*)
+ __stop_unwind_idx = .;
+ }
+ .ARM.unwind_tab : {
+ __start_unwind_tab = .;
+ *(.ARM.extab*)
+ __stop_unwind_tab = .;
+ }
+#endif
_etext = .; /* End of text and rodata section */
. = ALIGN(4);
diff --git a/arch/arm/lib/unwind.c b/arch/arm/lib/unwind.c
new file mode 100644
index 0000000..62d26af
--- /dev/null
+++ b/arch/arm/lib/unwind.c
@@ -0,0 +1,344 @@
+#include <common.h>
+#include <init.h>
+#include <asm/stacktrace.h>
+#include <asm/unwind.h>
+#include <asm-generic/sections.h>
+
+/* Dummy functions to avoid linker complaints */
+void __aeabi_unwind_cpp_pr0(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr0);
+
+void __aeabi_unwind_cpp_pr1(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr1);
+
+void __aeabi_unwind_cpp_pr2(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2);
+
+struct unwind_ctrl_block {
+ unsigned long vrs[16]; /* virtual register set */
+ unsigned long *insn; /* pointer to the current instructions word */
+ int entries; /* number of entries left to interpret */
+ int byte; /* current byte number in the instructions word */
+};
+
+enum regs {
+ FP = 11,
+ SP = 13,
+ LR = 14,
+ PC = 15
+};
+
+#define THREAD_SIZE 8192
+
+extern struct unwind_idx __start_unwind_idx[];
+extern struct unwind_idx __stop_unwind_idx[];
+
+/* Convert a prel31 symbol to an absolute address */
+#define prel31_to_addr(ptr) \
+({ \
+ /* sign-extend to 32 bits */ \
+ long offset = (((long)*(ptr)) << 1) >> 1; \
+ (unsigned long)(ptr) + offset; \
+})
+
+static inline int is_kernel_text(unsigned long addr)
+{
+ if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext))
+ return 1;
+ return 0;
+}
+
+void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
+{
+#ifdef CONFIG_KALLSYMS
+ printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
+#else
+ printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
+#endif
+}
+
+/*
+ * Binary search in the unwind index. The entries entries are
+ * guaranteed to be sorted in ascending order by the linker.
+ */
+static struct unwind_idx *search_index(unsigned long addr,
+ struct unwind_idx *first,
+ struct unwind_idx *last)
+{
+ pr_debug("%s(%08lx, %p, %p)\n", __func__, addr, first, last);
+
+ if (addr < first->addr) {
+ pr_warning("unwind: Unknown symbol address %08lx\n", addr);
+ return NULL;
+ } else if (addr >= last->addr)
+ return last;
+
+ while (first < last - 1) {
+ struct unwind_idx *mid = first + ((last - first + 1) >> 1);
+
+ if (addr < mid->addr)
+ last = mid;
+ else
+ first = mid;
+ }
+
+ return first;
+}
+
+static struct unwind_idx *unwind_find_idx(unsigned long addr)
+{
+ struct unwind_idx *idx = NULL;
+
+ pr_debug("%s(%08lx)\n", __func__, addr);
+
+ if (is_kernel_text(addr))
+ /* main unwind table */
+ idx = search_index(addr, __start_unwind_idx,
+ __stop_unwind_idx - 1);
+ else {
+ /* module unwinding not supported */
+ }
+
+ pr_debug("%s: idx = %p\n", __func__, idx);
+ return idx;
+}
+
+static unsigned long unwind_get_byte(struct unwind_ctrl_block *ctrl)
+{
+ unsigned long ret;
+
+ if (ctrl->entries <= 0) {
+ pr_warning("unwind: Corrupt unwind table\n");
+ return 0;
+ }
+
+ ret = (*ctrl->insn >> (ctrl->byte * 8)) & 0xff;
+
+ if (ctrl->byte == 0) {
+ ctrl->insn++;
+ ctrl->entries--;
+ ctrl->byte = 3;
+ } else
+ ctrl->byte--;
+
+ return ret;
+}
+
+/*
+ * Execute the current unwind instruction.
+ */
+static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
+{
+ unsigned long insn = unwind_get_byte(ctrl);
+
+ pr_debug("%s: insn = %08lx\n", __func__, insn);
+
+ if ((insn & 0xc0) == 0x00)
+ ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4;
+ else if ((insn & 0xc0) == 0x40)
+ ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
+ else if ((insn & 0xf0) == 0x80) {
+ unsigned long mask;
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int load_sp, reg = 4;
+
+ insn = (insn << 8) | unwind_get_byte(ctrl);
+ mask = insn & 0x0fff;
+ if (mask == 0) {
+ pr_warning("unwind: 'Refuse to unwind' instruction %04lx\n",
+ insn);
+ return -URC_FAILURE;
+ }
+
+ /* pop R4-R15 according to mask */
+ load_sp = mask & (1 << (13 - 4));
+ while (mask) {
+ if (mask & 1)
+ ctrl->vrs[reg] = *vsp++;
+ mask >>= 1;
+ reg++;
+ }
+ if (!load_sp)
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if ((insn & 0xf0) == 0x90 &&
+ (insn & 0x0d) != 0x0d)
+ ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
+ else if ((insn & 0xf0) == 0xa0) {
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int reg;
+
+ /* pop R4-R[4+bbb] */
+ for (reg = 4; reg <= 4 + (insn & 7); reg++)
+ ctrl->vrs[reg] = *vsp++;
+ if (insn & 0x80)
+ ctrl->vrs[14] = *vsp++;
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if (insn == 0xb0) {
+ if (ctrl->vrs[PC] == 0)
+ ctrl->vrs[PC] = ctrl->vrs[LR];
+ /* no further processing */
+ ctrl->entries = 0;
+ } else if (insn == 0xb1) {
+ unsigned long mask = unwind_get_byte(ctrl);
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int reg = 0;
+
+ if (mask == 0 || mask & 0xf0) {
+ pr_warning("unwind: Spare encoding %04lx\n",
+ (insn << 8) | mask);
+ return -URC_FAILURE;
+ }
+
+ /* pop R0-R3 according to mask */
+ while (mask) {
+ if (mask & 1)
+ ctrl->vrs[reg] = *vsp++;
+ mask >>= 1;
+ reg++;
+ }
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if (insn == 0xb2) {
+ unsigned long uleb128 = unwind_get_byte(ctrl);
+
+ ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
+ } else {
+ pr_warning("unwind: Unhandled instruction %02lx\n", insn);
+ return -URC_FAILURE;
+ }
+
+ pr_debug("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx\n", __func__,
+ ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]);
+
+ return URC_OK;
+}
+
+/*
+ * Unwind a single frame starting with *sp for the symbol at *pc. It
+ * updates the *pc and *sp with the new values.
+ */
+int unwind_frame(struct stackframe *frame)
+{
+ unsigned long high, low;
+ struct unwind_idx *idx;
+ struct unwind_ctrl_block ctrl;
+
+ /* only go to a higher address on the stack */
+ low = frame->sp;
+ high = ALIGN(low, THREAD_SIZE);
+
+ pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
+ frame->pc, frame->lr, frame->sp);
+
+ if (!is_kernel_text(frame->pc))
+ return -URC_FAILURE;
+
+ idx = unwind_find_idx(frame->pc);
+ if (!idx) {
+ pr_warning("unwind: Index not found %08lx\n", frame->pc);
+ return -URC_FAILURE;
+ }
+
+ ctrl.vrs[FP] = frame->fp;
+ ctrl.vrs[SP] = frame->sp;
+ ctrl.vrs[LR] = frame->lr;
+ ctrl.vrs[PC] = 0;
+
+ if (idx->insn == 1)
+ /* can't unwind */
+ return -URC_FAILURE;
+ else if ((idx->insn & 0x80000000) == 0)
+ /* prel31 to the unwind table */
+ ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);
+ else if ((idx->insn & 0xff000000) == 0x80000000)
+ /* only personality routine 0 supported in the index */
+ ctrl.insn = &idx->insn;
+ else {
+ pr_warning("unwind: Unsupported personality routine %08lx in the index at %p\n",
+ idx->insn, idx);
+ return -URC_FAILURE;
+ }
+
+ /* check the personality routine */
+ if ((*ctrl.insn & 0xff000000) == 0x80000000) {
+ ctrl.byte = 2;
+ ctrl.entries = 1;
+ } else if ((*ctrl.insn & 0xff000000) == 0x81000000) {
+ ctrl.byte = 1;
+ ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16);
+ } else {
+ pr_warning("unwind: Unsupported personality routine %08lx at %p\n",
+ *ctrl.insn, ctrl.insn);
+ return -URC_FAILURE;
+ }
+
+ while (ctrl.entries > 0) {
+ int urc = unwind_exec_insn(&ctrl);
+ if (urc < 0)
+ return urc;
+ if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
+ return -URC_FAILURE;
+ }
+
+ if (ctrl.vrs[PC] == 0)
+ ctrl.vrs[PC] = ctrl.vrs[LR];
+
+ /* check for infinite loop */
+ if (frame->pc == ctrl.vrs[PC])
+ return -URC_FAILURE;
+
+ frame->fp = ctrl.vrs[FP];
+ frame->sp = ctrl.vrs[SP];
+ frame->lr = ctrl.vrs[LR];
+ frame->pc = ctrl.vrs[PC];
+
+ return URC_OK;
+}
+
+void unwind_backtrace(struct pt_regs *regs)
+{
+ struct stackframe frame;
+ register unsigned long current_sp asm ("sp");
+
+ pr_debug("%s\n", __func__);
+
+ if (regs) {
+ frame.fp = regs->ARM_fp;
+ frame.sp = regs->ARM_sp;
+ frame.lr = regs->ARM_lr;
+ /* PC might be corrupted, use LR in that case. */
+ frame.pc = is_kernel_text(regs->ARM_pc)
+ ? regs->ARM_pc : regs->ARM_lr;
+ } else {
+ frame.sp = current_sp;
+ frame.lr = (unsigned long)__builtin_return_address(0);
+ frame.pc = (unsigned long)unwind_backtrace;
+ }
+
+ while (1) {
+ int urc;
+ unsigned long where = frame.pc;
+
+ urc = unwind_frame(&frame);
+ if (urc < 0)
+ break;
+ dump_backtrace_entry(where, frame.pc, frame.sp - 4);
+ }
+}
+
+static int unwind_init(void)
+{
+ struct unwind_idx *idx;
+
+ /* Convert the symbol addresses to absolute values */
+ for (idx = __start_unwind_idx; idx < __stop_unwind_idx; idx++)
+ idx->addr = prel31_to_addr(&idx->addr);
+
+ return 0;
+}
+core_initcall(unwind_init);
--
1.7.2.3
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/3] kallsyms/printk: enable symbol printing support (%pS)
2011-03-08 11:24 [PATCH] ARM stack unwinding support Sascha Hauer
2011-03-08 11:24 ` [PATCH 1/3] ARM: create a second level page table entry for the exception vectors Sascha Hauer
2011-03-08 11:24 ` [PATCH 2/3] ARM: Add stack unwinding support Sascha Hauer
@ 2011-03-08 11:24 ` Sascha Hauer
2 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2011-03-08 11:24 UTC (permalink / raw)
To: barebox
With this kallsyms finally start working at least on ARM. This
enables us resolving addresses into symbols which is particularly
useful in combination with stack unwinding support. As kallsyms
now compile and work we can remove the depends on BROKEN.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Makefile | 2 +-
common/Kconfig | 3 -
common/kallsyms.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++-
include/kallsyms.h | 5 ++
lib/vsprintf.c | 1 +
5 files changed, 154 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile
index 1a4a54e..55c83cc 100644
--- a/Makefile
+++ b/Makefile
@@ -599,7 +599,7 @@ endef
# Generate .S file with all kernel symbols
quiet_cmd_kallsyms = KSYM $@
- cmd_kallsyms = $(NM) -g -n $< | $(KALLSYMS) > $@
+ cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) --all-symbols > $@
.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
$(call if_changed_dep,as_o_S)
diff --git a/common/Kconfig b/common/Kconfig
index 02bc67e..9e30579 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -148,13 +148,10 @@ config MODULES
config KALLSYMS
depends on HAS_KALLSYMS
- depends on BROKEN
bool "kallsyms"
help
With Kallsyms enabled all symbols are compiled into the barebox image.
This is useful to print a nice backtrace when an exception occurs.
- No architecture supports backtraces at the moment, so this option
- is quite useless at the moment
config RELOCATABLE
depends on PPC
diff --git a/common/kallsyms.c b/common/kallsyms.c
index 490adb9..0218991 100644
--- a/common/kallsyms.c
+++ b/common/kallsyms.c
@@ -1,6 +1,7 @@
#include <common.h>
#include <init.h>
#include <kallsyms.h>
+#include <asm-generic/sections.h>
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -16,6 +17,13 @@ extern const unsigned long kallsyms_markers[] __attribute__((weak));
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+static inline int is_kernel_text(unsigned long addr)
+{
+ if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext))
+ return 1;
+ return 0;
+}
+
/* expand a compressed symbol data into the resulting uncompressed string,
given the offset to where the symbol is in the compressed stream */
static unsigned int kallsyms_expand_symbol(unsigned int off, char *result)
@@ -55,6 +63,33 @@ static unsigned int kallsyms_expand_symbol(unsigned int off, char *result)
return off;
}
+/*
+ * Find the offset on the compressed stream given and index in the
+ * kallsyms array.
+ */
+static unsigned int get_symbol_offset(unsigned long pos)
+{
+ const u8 *name;
+ int i;
+
+ /*
+ * Use the closest marker we have. We have markers every 256 positions,
+ * so that should be close enough.
+ */
+ name = &kallsyms_names[kallsyms_markers[pos >> 8]];
+
+ /*
+ * Sequentially scan all the symbols up to the point we're searching
+ * for. Every symbol is stored in a [<len>][<len> bytes of data] format,
+ * so we just need to add the len to the current pointer for every
+ * symbol we wish to skip.
+ */
+ for (i = 0; i < (pos & 0xFF); i++)
+ name = name + (*name) + 1;
+
+ return name - kallsyms_names;
+}
+
/* Lookup the address for this symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name)
{
@@ -68,6 +103,117 @@ unsigned long kallsyms_lookup_name(const char *name)
if (strcmp(namebuf, name) == 0)
return kallsyms_addresses[i];
}
-// return module_kallsyms_lookup_name(name);
+
+ /* module kallsyms not yet supported */
return 0;
}
+
+static unsigned long get_symbol_pos(unsigned long addr,
+ unsigned long *symbolsize,
+ unsigned long *offset)
+{
+ unsigned long symbol_start = 0, symbol_end = 0;
+ unsigned long i, low, high, mid;
+
+ /* This kernel should never had been booted. */
+ BUG_ON(!kallsyms_addresses);
+
+ /* Do a binary search on the sorted kallsyms_addresses array. */
+ low = 0;
+ high = kallsyms_num_syms;
+
+ while (high - low > 1) {
+ mid = low + (high - low) / 2;
+ if (kallsyms_addresses[mid] <= addr)
+ low = mid;
+ else
+ high = mid;
+ }
+
+ /*
+ * Search for the first aliased symbol. Aliased
+ * symbols are symbols with the same address.
+ */
+ while (low && kallsyms_addresses[low-1] == kallsyms_addresses[low])
+ --low;
+
+ symbol_start = kallsyms_addresses[low];
+
+ /* Search for next non-aliased symbol. */
+ for (i = low + 1; i < kallsyms_num_syms; i++) {
+ if (kallsyms_addresses[i] > symbol_start) {
+ symbol_end = kallsyms_addresses[i];
+ break;
+ }
+ }
+
+ /* If we found no next symbol, we use the end of the section. */
+ if (!symbol_end) {
+ symbol_end = (unsigned long)_etext;
+ }
+
+ if (symbolsize)
+ *symbolsize = symbol_end - symbol_start;
+ if (offset)
+ *offset = addr - symbol_start;
+
+ return low;
+}
+
+/*
+ * Lookup an address
+ * - modname is set to NULL if it's in the kernel.
+ * - We guarantee that the returned name is valid until we reschedule even if.
+ * It resides in a module.
+ * - We also guarantee that modname will be valid until rescheduled.
+ */
+const char *kallsyms_lookup(unsigned long addr,
+ unsigned long *symbolsize,
+ unsigned long *offset,
+ char **modname, char *namebuf)
+{
+ namebuf[KSYM_NAME_LEN - 1] = 0;
+ namebuf[0] = 0;
+
+ if (is_kernel_text(addr)) {
+ unsigned long pos;
+
+ pos = get_symbol_pos(addr, symbolsize, offset);
+ /* Grab name */
+ kallsyms_expand_symbol(get_symbol_offset(pos), namebuf);
+ if (modname)
+ *modname = NULL;
+ return namebuf;
+ }
+
+ /* moduled not yet supported in kallsyms */
+ return NULL;
+}
+
+/* Look up a kernel symbol and return it in a text buffer. */
+int sprint_symbol(char *buffer, unsigned long address)
+{
+ char *modname;
+ const char *name;
+ unsigned long offset, size;
+ int len;
+
+ name = kallsyms_lookup(address, &size, &offset, &modname, buffer);
+ if (!name)
+ return sprintf(buffer, "0x%lx", address);
+
+ if (name != buffer)
+ strcpy(buffer, name);
+ len = strlen(buffer);
+ buffer += len;
+
+ if (modname)
+ len += sprintf(buffer, "+%#lx/%#lx [%s]",
+ offset, size, modname);
+ else
+ len += sprintf(buffer, "+%#lx/%#lx", offset, size);
+
+ return len;
+}
+EXPORT_SYMBOL_GPL(sprint_symbol);
+
diff --git a/include/kallsyms.h b/include/kallsyms.h
index 5117be2..69b84d2 100644
--- a/include/kallsyms.h
+++ b/include/kallsyms.h
@@ -2,6 +2,11 @@
#define __KALLSYMS_H
#define KSYM_NAME_LEN 128
+#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
+ 2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
unsigned long kallsyms_lookup_name(const char *name);
+/* Look up a kernel symbol and return it in a text buffer. */
+int sprint_symbol(char *buffer, unsigned long address);
+
#endif /* __KALLSYMS_H */
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index fec87ba..ccccc5d 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -15,6 +15,7 @@
#include <linux/ctype.h>
#include <asm-generic/div64.h>
#include <malloc.h>
+#include <kallsyms.h>
#include <common.h>
#include <led.h>
--
1.7.2.3
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] ARM: Add stack unwinding support
2011-03-08 11:24 ` [PATCH 2/3] ARM: Add stack unwinding support Sascha Hauer
@ 2011-03-08 11:37 ` Baruch Siach
2011-03-08 11:40 ` Sascha Hauer
2011-03-08 15:14 ` Sascha Hauer
1 sibling, 1 reply; 7+ messages in thread
From: Baruch Siach @ 2011-03-08 11:37 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
Hi Sascha,
On Tue, Mar 08, 2011 at 12:24:51PM +0100, Sascha Hauer wrote:
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> arch/arm/Kconfig | 10 ++
> arch/arm/Makefile | 4 +
> arch/arm/cpu/interrupts.c | 4 +
> arch/arm/lib/Makefile | 2 +-
> arch/arm/lib/barebox.lds.S | 16 ++
> arch/arm/lib/unwind.c | 344 ++++++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 379 insertions(+), 1 deletions(-)
> create mode 100644 arch/arm/lib/unwind.c
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index bc54e58..aae0e99 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -115,6 +115,16 @@ config ARM_OPTIMZED_STRING_FUNCTIONS
> These functions work much faster than the normal versions but
> increase your binary size.
>
> +config ARM_UNWIND
> + bool "enable stack unwinding support"
> + depends on AEABI
> + help
> + This option enables stack unwinding support in barebox
> + using the information automatically generated by the
> + compiler. The resulting kernel image is slightly bigger but
s/kernel/barebox/
baruch
--
~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch@tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] ARM: Add stack unwinding support
2011-03-08 11:37 ` Baruch Siach
@ 2011-03-08 11:40 ` Sascha Hauer
0 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2011-03-08 11:40 UTC (permalink / raw)
To: Baruch Siach; +Cc: barebox
On Tue, Mar 08, 2011 at 01:37:21PM +0200, Baruch Siach wrote:
> Hi Sascha,
>
> On Tue, Mar 08, 2011 at 12:24:51PM +0100, Sascha Hauer wrote:
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > arch/arm/Kconfig | 10 ++
> > arch/arm/Makefile | 4 +
> > arch/arm/cpu/interrupts.c | 4 +
> > arch/arm/lib/Makefile | 2 +-
> > arch/arm/lib/barebox.lds.S | 16 ++
> > arch/arm/lib/unwind.c | 344 ++++++++++++++++++++++++++++++++++++++++++++
> > 6 files changed, 379 insertions(+), 1 deletions(-)
> > create mode 100644 arch/arm/lib/unwind.c
> >
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index bc54e58..aae0e99 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -115,6 +115,16 @@ config ARM_OPTIMZED_STRING_FUNCTIONS
> > These functions work much faster than the normal versions but
> > increase your binary size.
> >
> > +config ARM_UNWIND
> > + bool "enable stack unwinding support"
> > + depends on AEABI
> > + help
> > + This option enables stack unwinding support in barebox
> > + using the information automatically generated by the
> > + compiler. The resulting kernel image is slightly bigger but
>
> s/kernel/barebox/
gna. At least I catched the first 'kernel' :)
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] ARM: Add stack unwinding support
2011-03-08 11:24 ` [PATCH 2/3] ARM: Add stack unwinding support Sascha Hauer
2011-03-08 11:37 ` Baruch Siach
@ 2011-03-08 15:14 ` Sascha Hauer
1 sibling, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2011-03-08 15:14 UTC (permalink / raw)
To: barebox
On Tue, Mar 08, 2011 at 12:24:51PM +0100, Sascha Hauer wrote:
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> arch/arm/Kconfig | 10 ++
> arch/arm/Makefile | 4 +
> arch/arm/cpu/interrupts.c | 4 +
> arch/arm/lib/Makefile | 2 +-
> arch/arm/lib/barebox.lds.S | 16 ++
> arch/arm/lib/unwind.c | 344 ++++++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 379 insertions(+), 1 deletions(-)
> create mode 100644 arch/arm/lib/unwind.c
And here are the missing pieces...
8<--------------------------------------
commit 41059912043f6ce6209eb6460f5b8509aa956c60
Author: Sascha Hauer <s.hauer@pengutronix.de>
Date: Tue Mar 8 16:13:25 2011 +0100
add to stacktrace support
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
new file mode 100644
index 0000000..10f70e1
--- /dev/null
+++ b/arch/arm/include/asm/stacktrace.h
@@ -0,0 +1,16 @@
+#ifndef __ASM_STACKTRACE_H
+#define __ASM_STACKTRACE_H
+
+struct stackframe {
+ unsigned long fp;
+ unsigned long sp;
+ unsigned long lr;
+ unsigned long pc;
+};
+
+extern int unwind_frame(struct stackframe *frame);
+extern void walk_stackframe(struct stackframe *frame,
+ int (*fn)(struct stackframe *, void *), void *data);
+
+#endif /* __ASM_STACKTRACE_H */
+
diff --git a/arch/arm/include/asm/unwind.h b/arch/arm/include/asm/unwind.h
new file mode 100644
index 0000000..1bc2a7c
--- /dev/null
+++ b/arch/arm/include/asm/unwind.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/include/asm/unwind.h
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_UNWIND_H
+#define __ASM_UNWIND_H
+
+#ifndef __ASSEMBLY__
+
+/* Unwind reason code according the the ARM EABI documents */
+enum unwind_reason_code {
+ URC_OK = 0, /* operation completed successfully */
+ URC_CONTINUE_UNWIND = 8,
+ URC_FAILURE = 9 /* unspecified failure of some kind */
+};
+
+struct unwind_idx {
+ unsigned long addr;
+ unsigned long insn;
+};
+
+struct unwind_table {
+ struct list_head list;
+ struct unwind_idx *start;
+ struct unwind_idx *stop;
+ unsigned long begin_addr;
+ unsigned long end_addr;
+};
+
+extern struct unwind_table *unwind_table_add(unsigned long start,
+ unsigned long size,
+ unsigned long text_addr,
+ unsigned long text_size);
+extern void unwind_table_del(struct unwind_table *tab);
+extern void unwind_backtrace(struct pt_regs *regs);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_UNWIND_H */
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2011-03-08 15:14 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-08 11:24 [PATCH] ARM stack unwinding support Sascha Hauer
2011-03-08 11:24 ` [PATCH 1/3] ARM: create a second level page table entry for the exception vectors Sascha Hauer
2011-03-08 11:24 ` [PATCH 2/3] ARM: Add stack unwinding support Sascha Hauer
2011-03-08 11:37 ` Baruch Siach
2011-03-08 11:40 ` Sascha Hauer
2011-03-08 15:14 ` Sascha Hauer
2011-03-08 11:24 ` [PATCH 3/3] kallsyms/printk: enable symbol printing support (%pS) Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox