From patchwork Mon Jul 6 21:58:47 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helge Deller X-Patchwork-Id: 34342 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n66Lwqi9022554 for ; Mon, 6 Jul 2009 21:58:53 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753057AbZGFV6r (ORCPT ); Mon, 6 Jul 2009 17:58:47 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753348AbZGFV6r (ORCPT ); Mon, 6 Jul 2009 17:58:47 -0400 Received: from mail.gmx.net ([213.165.64.20]:56615 "HELO mail.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1753057AbZGFV6r (ORCPT ); Mon, 6 Jul 2009 17:58:47 -0400 Received: (qmail invoked by alias); 06 Jul 2009 21:58:48 -0000 Received: from p4FDB2ECF.dip0.t-ipconnect.de (EHLO halden.box) [79.219.46.207] by mail.gmx.net (mp068) with SMTP; 06 Jul 2009 23:58:48 +0200 X-Authenticated: #1045983 X-Provags-ID: V01U2FsdGVkX19rmT0+V4JrMfZq0cpGQ8vac9S3Dz7vB8z8P5tZ+l VLUq15SdyfTPGa Message-ID: <4A527397.7060306@gmx.de> Date: Mon, 06 Jul 2009 23:58:47 +0200 From: Helge Deller User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1b3pre) Gecko/20090513 Fedora/3.0-2.3.beta2.fc11 Thunderbird/3.0b2 MIME-Version: 1.0 To: linux-parisc , John David Anglin , "Carlos O'Donell" , Randolph Chung Subject: parisc: unwind tables and backtraces broken? X-Y-GMX-Trusted: 0 X-FuHaFi: 0.5 Sender: linux-parisc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-parisc@vger.kernel.org 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 : 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 : 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); + + } } }