From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3527 invoked by alias); 26 Jul 2010 14:53:18 -0000 Received: (qmail 3509 invoked by uid 22791); 26 Jul 2010 14:53:15 -0000 X-Spam-Check-By: sourceware.org Received: from aquarius.hirmke.de (HELO calimero.vinschen.de) (217.91.18.234) by sourceware.org (qpsmtpd/0.83/v0.83-20-g38e4449) with ESMTP; Mon, 26 Jul 2010 14:52:39 +0000 Received: by calimero.vinschen.de (Postfix, from userid 500) id 209066D42F4; Mon, 26 Jul 2010 16:52:36 +0200 (CEST) Date: Mon, 26 Jul 2010 14:53:00 -0000 From: Corinna Vinschen To: gdb-patches@sourceware.org Subject: [rfa] frame address size incorrect if address size != ptr size Message-ID: <20100726145236.GA16155@calimero.vinschen.de> Reply-To: gdb-patches@sourceware.org Mail-Followup-To: gdb-patches@sourceware.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-07/txt/msg00394.txt.bz2 Hi, while analyzing some problem in XStormy16, I came across a weird effect. Even though the dwarf2 frame unwinder is suppose to be preferred over the xstormy16 unwinder, the code almost always called the xstormy16_frame_prev_register function, rather than the dwarf2_frame_prev_register function. Debugging turned up that the "address_range" entry in almost all fde's was incorrect, so the dwarf2_frame_find_fde function almost never found a matching fde. More debugging then pointed to the decode_frame_entry_1 function. The storage size of address_range is supposed to be cie->addr_size. cie->addr_size is computed like this: /* The target address size. For .eh_frame FDEs this is considered equal to the size of a target pointer. For .dwarf_frame FDEs, this is supposed to be the target address size from the associated CU header. FIXME: We do not have a good way to determine the latter. Always use the target pointer size for now. */ cie->addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; [...] if (cie->version >= 4) { /* FIXME: check that this is the same as from the CU header. */ cie->addr_size = read_1_byte (unit->abfd, buf); ++buf; cie->segment_size = read_1_byte (unit->abfd, buf); ++buf; } else { cie->addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; cie->segment_size = 0; } This is not helpful for .dwarf_frame sections in case cie->version < 4. The address size of a target is not necessarily the size of a pointer. And that's exactly the problem in the XStormy16 case. The target is very size sensitive. The address range of the CPU is potentially 32 bit, so the address size for the target is 32 bit. However, the pointer size for this target is deliberately set to 16 bit, which allows for smaller code, and also pointers fit into a single 16 bit register. The effect is that the above statements set cie->addr_size to 2, because that's the size of a pointer. But the address size is 4 byte and the debug info has to use the address size to be able to cover the entire address space of the target. Consequentially GCC emits debug info using the address size of the XStormy16 target, 4 bytes. Therefore I propose the below patch. It continues to compute addr_size from gdbarch_ptr_bit for .eh_frame sections, but uses gdbarch_addr_bit in case of .dwarf_frame sections. Tested with XStormy16. Now the dwarf2 unwinder is actually preferred over the "manual" xstormy16 unwinder, because the dwarf2_frame_find_fde function actually finds matching FDEs now. Ok to apply? Thanks, Corinna * dwarf2-frame.c (decode_frame_entry_1): If addr_size isn't available in CIE, use address size rather than pointer size when decoding .dwarf_frame info. Index: dwarf2-frame.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v retrieving revision 1.114 diff -u -p -r1.114 dwarf2-frame.c --- dwarf2-frame.c 7 Jul 2010 17:26:38 -0000 1.114 +++ dwarf2-frame.c 26 Jul 2010 14:49:34 -0000 @@ -1736,8 +1736,12 @@ decode_frame_entry_1 (struct comp_unit * equal to the size of a target pointer. For .dwarf_frame FDEs, this is supposed to be the target address size from the associated CU header. FIXME: We do not have a good way to determine the - latter. Always use the target pointer size for now. */ - cie->addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; + latter. Always use the target address size for .dwarf_frame + sections for now. */ + if (eh_frame_p) + cie->addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; + else + cie->addr_size = gdbarch_addr_bit (gdbarch) / TARGET_CHAR_BIT; /* We'll determine the final value later, but we need to initialize it conservatively. */ @@ -1779,7 +1783,10 @@ decode_frame_entry_1 (struct comp_unit * } else { - cie->addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; + if (eh_frame_p) + cie->addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; + else + cie->addr_size = gdbarch_addr_bit (gdbarch) / TARGET_CHAR_BIT; cie->segment_size = 0; } -- Corinna Vinschen Cygwin Project Co-Leader Red Hat