I started looking into why CONFIG_BACKTRACE_SELF_TEST=y shows uncomplete/wrong/broken backtraces. To me it seems, that the unwind tables are broken when using newer gcc/binutils versions. I'm running hppa-linux-gcc (GCC) 4.3.3, and GNU ld (GNU Binutils) 2.19.51.20090704. hppa-linux-objdump -d vmlinux gives: vmlinux: file format elf32-hppa-linux Disassembly of section .text: 10100000 <stext-0x700>: 10100000: 20 2f e2 06 ldil L%103df000,r1 10100004: e0 20 28 82 be,n 440(sr4,r1) 10100008: 20 38 42 02 ldil L%10170000,r1 1010000c: e0 20 23 da be,n 1ec(sr4,r1) 10100010: 20 32 62 02 ldil L%10165000,r1 10100014: e0 20 2a 0a be,n 504(sr4,r1) 10100018: 20 34 42 06 ldil L%10368000,r1 1010001c: e0 20 27 12 be,n 388(sr4,r1) 10100020: 20 33 f2 04 ldil L%102e7800,r1 10100024: e0 20 22 ea be,n 174(sr4,r1) 10100028: 20 35 22 06 ldil L%1032b000,r1 1010002c: e0 20 2e 2a be,n 714(sr4,r1) (and continuing) I assume this is a jump-table generated by the linker to resolve long-distance calls? and later: ... 10100700 <stext>: 10100700: 00 00 38 20 mtsp r0,sr4 10100704: 00 00 78 20 mtsp r0,sr5 10100708: 00 00 b8 20 mtsp r0,sr6 1010070c: 00 00 f8 20 mtsp r0,sr7 10100710: 20 69 80 0c ldil L%692000,r3 10100714: 34 63 00 00 ldo 0(r3),r3 10100718: 20 93 f0 0c ldil L%6e7800,r4 1010071c: 34 84 0f 58 ldo 7ac(r4),r4 10100720 <$bss_loop>: 10100720: 80 83 9f f7 cmpb,<<,n r3,r4,10100720 <$bss_loop> 10100724: 0c 60 12 a8 stw,ma r0,4(r3) .... but the unwind table when running the kernel with the attached patch (see below) shows: ... unwind_init: start = 0x105fb3c0, end = 0x10634f30, entries = 14775 unwind 1: 100ff900 - 100ffa80, len=385 unwind 2: 100ffa84 - 100ffad4, len=81 unwind 3: 100ffad8 - 100ffb2c, len=85 unwind 4: 100ffb30 - 100ffbc8, len=153 unwind 5: 100ffbcc - 100ffc38, len=109 unwind 6: 100ffc3c - 100ffc9c, len=97 unwind 7: 100ffca0 - 100ffd00, len=97 unwind 8: 100ffd04 - 100ffd64, len=97 unwind 9: 100ffd68 - 100ffdc8, len=97 unwind 10: 100ffdcc - 100ffdec, len=33 From this table I don't even understand the values of the very first entry (unwind 1: 100ff900 - 100ffa80). This does not resolve to any entry in the assembly. My assumption: When the linker creates the long-distance jump table, it does not adjusts the values in the unwind table. Second, when the linker discards attribute-weak functions, it doesn't deletes/adjusts the unwind table entries of the deleted functions either. Question: Might my analysis be correct? Helge
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index 69dad5a..d7c7241 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -94,6 +94,10 @@ unwind_table_init(struct unwind_table *table, const char *name, struct unwind_table_entry *start = table_start; struct unwind_table_entry *end = (struct unwind_table_entry *)table_end - 1; + int nr = 0; + + extern void stext(); + // base_addr += ((unsigned long)&stext) - KERNEL_START; // HELGE table->name = name; table->base_addr = base_addr; @@ -112,6 +116,15 @@ unwind_table_init(struct unwind_table *table, const char *name, start->region_start += base_addr; start->region_end += base_addr; + if (nr<10) { + nr++; + printk("unwind %d: %x - %x, len=%d\n", + nr, + start->region_start, + start->region_end, + start->region_end - start->region_start + 1); + + } } }