From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23917 invoked by alias); 20 Jun 2006 19:53:40 -0000 Received: (qmail 23899 invoked by uid 22791); 20 Jun 2006 19:53:39 -0000 X-Spam-Check-By: sourceware.org Received: from potter.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 20 Jun 2006 19:53:37 +0000 Received: (qmail 17981 invoked from network); 20 Jun 2006 19:53:35 -0000 Received: from unknown (HELO localhost) (jimb@127.0.0.2) by mail.codesourcery.com with ESMTPA; 20 Jun 2006 19:53:35 -0000 To: gdb-patches@sourceware.org Subject: RFC: Support DW_FORM_ref_addr as described in DWARF 3 References: <4488A920.9090705@codesourcery.com> <20060608235912.GA6545@nevyn.them.org> From: Jim Blandy Date: Tue, 20 Jun 2006 19:53:00 -0000 In-Reply-To: <20060608235912.GA6545@nevyn.them.org> (Daniel Jacobowitz's message of "Thu, 8 Jun 2006 19:59:12 -0400") Message-ID: User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-06/txt/msg00286.txt.bz2 Daniel Jacobowitz writes: > On Thu, Jun 08, 2006 at 04:25:42PM -0700, Jim Blandy wrote: >> I think this patch is right. It's true that GDB doesn't support all >> of DWARF 3, but GDB's general philosophy is to garner as much >> information as it can, and punt the rest, which works well with >> DWARF's philosophy. So GDB shouldn't just punt entire compilation >> units because they're marked as DWARF 3. > > I agree. > > There seems to be one structural change in .debug_info tied to the > version number (there's also the initial lengths, but we already > support that). That is: > > References that use the attribute form DW_FORM_ref_addr are specified > to be four bytes in the DWARF 32-bit format and eight bytes in the > DWARF 64-bit format, while DWARF Version 2 specifies that such > references have the same size as anaddress on the target system (see > Sections 7.4 and 7.5.4). > > I see two places (skip_one_die and read_attribute_value) that are > affected. So, this should be an easy item to fix. Here's a patch for this, as promised; how does it look? 2006-06-20 Jim Blandy Support DW_FORM_ref_addr as described in DWARF 3. * dwarf2read.c (struct comp_unit_head): New field, ref_addr_size. (read_comp_unit_head): Initialize CU's ref_addr_size field. (skip_one_die): Use ref_addr_size for DW_FORM_ref_addr attributes. (read_ref_addr): New function. (read_attribute_value): Call it. Index: gdb/dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.199 diff -u -p -r1.199 dwarf2read.c --- gdb/dwarf2read.c 14 Jun 2006 15:06:35 -0000 1.199 +++ gdb/dwarf2read.c 20 Jun 2006 18:18:46 -0000 @@ -233,6 +233,19 @@ struct comp_unit_head /* Size of the length field; either 4 or 12. */ unsigned int initial_length_size; + /* The size of a DW_FORM_ref_addr attribute. This depends on + VERSION, above. + + - For versions 2 and earlier, DW_FORM_ref_addr is the size of an + address, as given in the 'address size' field of the compilation + unit header. + + - For versions 3 and later, a DW_FORM_ref_addr value is four bytes + in the 32-bit DWARF format, and eight bytes in the 64-bit DWARF + format --- in other words, it matches whatever size offset is + otherwise used to index the debugging info. */ + unsigned int ref_addr_size; + /* Offset to the first byte of this compilation unit header in the .debug_info section, for resolving relative reference dies. */ unsigned int offset; @@ -804,6 +817,9 @@ static CORE_ADDR read_address (bfd *, gd static LONGEST read_initial_length (bfd *, gdb_byte *, struct comp_unit_head *, unsigned int *); +static LONGEST read_ref_addr (bfd *, gdb_byte *, const struct comp_unit_head *, + unsigned int *); + static LONGEST read_offset (bfd *, gdb_byte *, const struct comp_unit_head *, unsigned int *); @@ -1293,6 +1309,12 @@ read_comp_unit_head (struct comp_unit_he internal_error (__FILE__, __LINE__, _("read_comp_unit_head: dwarf from non elf file")); cu_header->signed_addr_p = signed_addr; + + if (cu_header->version < 3) + cu_header->ref_addr_size = cu_header->addr_size; + else + cu_header->ref_addr_size = cu_header->offset_size; + return info_ptr; } @@ -2224,7 +2246,7 @@ skip_one_die (gdb_byte *info_ptr, struct { case DW_FORM_addr: case DW_FORM_ref_addr: - info_ptr += cu->header.addr_size; + info_ptr += cu->header.ref_addr_size; break; case DW_FORM_data1: case DW_FORM_ref1: @@ -5733,7 +5755,7 @@ read_attribute_value (struct attribute * { case DW_FORM_addr: case DW_FORM_ref_addr: - DW_ADDR (attr) = read_address (abfd, info_ptr, cu, &bytes_read); + DW_ADDR (attr) = read_ref_addr (abfd, info_ptr, &cu->header, &bytes_read); info_ptr += bytes_read; break; case DW_FORM_block2: @@ -6027,6 +6049,32 @@ read_initial_length (bfd *abfd, gdb_byte return length; } + +static LONGEST +read_ref_addr (bfd *abfd, gdb_byte *buf, const struct comp_unit_head *cu_header, + unsigned int *bytes_read) +{ + LONGEST retval = 0; + + switch (cu_header->ref_addr_size) + { + case 4: + retval = bfd_get_32 (abfd, buf); + *bytes_read = 4; + break; + case 8: + retval = bfd_get_64 (abfd, buf); + *bytes_read = 8; + break; + default: + internal_error (__FILE__, __LINE__, + _("read_ref_addr: bad switch [in module %s]"), + bfd_get_filename (abfd)); + } + + return retval; +} + /* Read an offset from the data stream. The size of the offset is given by cu_header->offset_size. */