From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30775 invoked by alias); 12 Jan 2005 17:26:39 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 30726 invoked from network); 12 Jan 2005 17:26:29 -0000 Received: from unknown (HELO sccrmhc13.comcast.net) (204.127.202.64) by sourceware.org with SMTP; 12 Jan 2005 17:26:29 -0000 Received: from lucon.org ([24.6.212.230]) by comcast.net (sccrmhc13) with ESMTP id <200501121726290160029d05e>; Wed, 12 Jan 2005 17:26:29 +0000 Received: by lucon.org (Postfix, from userid 1000) id B035C640F4; Wed, 12 Jan 2005 09:26:28 -0800 (PST) Date: Wed, 12 Jan 2005 17:26:00 -0000 From: "H. J. Lu" To: binutils@sources.redhat.com Subject: Re: PATCH: Support more than 1 comp unit Message-ID: <20050112172628.GA10871@lucon.org> References: <20050112015043.GA30123@lucon.org> <20050112015845.GA17796@nevyn.them.org> <20050112041818.GA32039@lucon.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20050112041818.GA32039@lucon.org> User-Agent: Mutt/1.4.1i X-SW-Source: 2005-01/txt/msg00118.txt.bz2 On Tue, Jan 11, 2005 at 08:18:18PM -0800, H. J. Lu wrote: > On Tue, Jan 11, 2005 at 08:58:45PM -0500, Daniel Jacobowitz wrote: > > On Tue, Jan 11, 2005 at 05:50:43PM -0800, H. J. Lu wrote: > > > _bfd_dwarf2_find_nearest_line doesn't support more than one comp unit. > > > > That's obviously not true. Could you be a little more specific about > > what the problem is that you are trying to solve? > > > > dwarf2_debug has > > /* Preserve the original value of info_ptr for the current > comp_unit so we can find a given entry by its reference. */ > char* info_ptr_unit; > > which is used by find_abstract_instance_name: > > info_ptr = unit->stash->info_ptr_unit + die_ref; > > The problem is there is only one info_ptr_unit per file for multiple > CUs. To work with more than one CU, info_ptr_unit has to be updated > for the current CU when find_abstract_instance_name is called. My > patch adds the CU offset to comp_unit, which can be used by > find_abstract_instance_name to adjust info_ptr_unit. > > BTW, I have a testcase of a several MB ia64 libc_pic.os generated by > "ld -r". > This is an updated patch. The last CU is alaway the first on the CU list. We just need to get the next CU offset from it. H.J. ---- 2005-01-12 H.J. Lu * dwarf2.c (comp_unit): Add unit_offset and unit_length. (read_unsigned_leb128): Removed. (read_signed_leb128): Removed. (find_abstract_instance_name): Use unit_offset to get the current comp unit. (parse_comp_unit): Accept unit_length and unit_length_size. (_bfd_dwarf2_find_nearest_line): Record unit_offset for each comp unit. * elf-eh-frame.c (read_unsigned_leb128): Moved to ... (read_signed_leb128): Moved to ... * libbfd.c: Here. * libbfd-in.h (read_unsigned_leb128): New prototype. (read_signed_leb128): Likewise. * libbfd.h: Regenerated. --- bfd/dwarf2.c.leb128 2005-01-05 09:07:58.000000000 -0800 +++ bfd/dwarf2.c 2005-01-12 08:44:56.195825163 -0800 @@ -155,6 +155,12 @@ struct comp_unit /* TRUE if there is a line number table associated with this comp. unit. */ int stmtlist; + /* The offset into .debug_info of the debug info table. */ + bfd_vma unit_offset; + + /* The total length of the comp unit. */ + bfd_vma unit_length; + /* The offset into .debug_line of the line number table. */ unsigned long line_offset; @@ -321,67 +327,6 @@ read_indirect_string (struct comp_unit* return buf; } -static unsigned int -read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED, - char *buf, - unsigned int *bytes_read_ptr) -{ - unsigned int result; - unsigned int num_read; - int shift; - unsigned char byte; - - result = 0; - shift = 0; - num_read = 0; - - do - { - byte = bfd_get_8 (abfd, buf); - buf ++; - num_read ++; - result |= ((byte & 0x7f) << shift); - shift += 7; - } - while (byte & 0x80); - - * bytes_read_ptr = num_read; - - return result; -} - -static int -read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED, - char *buf, - unsigned int * bytes_read_ptr) -{ - int result; - int shift; - int num_read; - unsigned char byte; - - result = 0; - shift = 0; - num_read = 0; - - do - { - byte = bfd_get_8 (abfd, buf); - buf ++; - num_read ++; - result |= ((byte & 0x7f) << shift); - shift += 7; - } - while (byte & 0x80); - - if ((shift < 32) && (byte & 0x40)) - result |= -(1 << shift); - - * bytes_read_ptr = num_read; - - return result; -} - /* END VERBATIM */ static bfd_uint64_t @@ -1332,7 +1277,7 @@ find_abstract_instance_name (struct comp struct attribute attr; char *name = 0; - info_ptr = unit->stash->info_ptr_unit + die_ref; + info_ptr = unit->stash->info_ptr_unit + unit->unit_offset + die_ref; abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; @@ -1478,6 +1423,8 @@ static struct comp_unit * parse_comp_unit (bfd *abfd, struct dwarf2_debug *stash, bfd_vma unit_length, + unsigned int unit_length_size, + bfd_vma unit_offset, unsigned int offset_size) { struct comp_unit* unit; @@ -1558,6 +1505,8 @@ parse_comp_unit (bfd *abfd, unit->abbrevs = abbrevs; unit->end_ptr = end_ptr; unit->stash = stash; + unit->unit_length = unit_length + unit_length_size; + unit->unit_offset = unit_offset; for (i = 0; i < abbrev->num_attrs; ++i) { @@ -1755,6 +1704,8 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd struct comp_unit* each; + bfd_vma unit_offset; + stash = *pinfo; addr = offset; if (section->output_section) @@ -1839,11 +1790,19 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd return FALSE; /* Check the previously read comp. units first. */ - for (each = stash->all_comp_units; each; each = each->next_unit) - if (comp_unit_contains_address (each, addr)) - return comp_unit_find_nearest_line (each, addr, filename_ptr, - functionname_ptr, linenumber_ptr, - stash); + each = stash->all_comp_units; + if (each) + { + /* The comp. unit list is in the descending order. */ + unit_offset = each->unit_length + each->unit_offset; + for (; each; each = each->next_unit) + if (comp_unit_contains_address (each, addr)) + return comp_unit_find_nearest_line (each, addr, filename_ptr, + functionname_ptr, + linenumber_ptr, stash); + } + else + unit_offset = 0; /* Read each remaining comp. units checking each as they are read. */ while (stash->info_ptr < stash->info_ptr_end) @@ -1851,6 +1810,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd bfd_vma length; bfd_boolean found; unsigned int offset_size = addr_size; + unsigned int length_size; length = read_4_bytes (abfd, stash->info_ptr); /* A 0xffffff length is the DWARF3 way of indicating we use @@ -1859,7 +1819,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd { offset_size = 8; length = read_8_bytes (abfd, stash->info_ptr + 4); - stash->info_ptr += 12; + length_size = 12; } /* A zero length is the IRIX way of indicating 64-bit offsets, mostly because the 64-bit length will generally fit in 32 @@ -1868,7 +1828,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd { offset_size = 8; length = read_4_bytes (abfd, stash->info_ptr + 4); - stash->info_ptr += 8; + length_size = 8; } /* In the absence of the hints above, we assume addr_size-sized offsets, for backward-compatibility with pre-DWARF3 64-bit @@ -1876,16 +1836,22 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd else if (addr_size == 8) { length = read_8_bytes (abfd, stash->info_ptr); - stash->info_ptr += 8; + length_size = 8; } else - stash->info_ptr += 4; + length_size = 4; + + stash->info_ptr += length_size; if (length > 0) { - each = parse_comp_unit (abfd, stash, length, offset_size); + each = parse_comp_unit (abfd, stash, length, length_size, + unit_offset, offset_size); stash->info_ptr += length; + /* Get the offset of the next comp unit. */ + unit_offset = each->unit_offset + each->unit_length; + if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr) == stash->sec->size) { @@ -1924,6 +1890,9 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd } } } + else + /* Update to the offset of the next comp unit. */ + unit_offset += length_size; } return FALSE; --- bfd/elf-eh-frame.c.leb128 2004-11-16 09:59:14.000000000 -0800 +++ bfd/elf-eh-frame.c 2005-01-11 11:41:02.000000000 -0800 @@ -26,64 +26,6 @@ #define EH_FRAME_HDR_SIZE 8 -/* Helper function for reading uleb128 encoded data. */ - -static bfd_vma -read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED, - char *buf, - unsigned int *bytes_read_ptr) -{ - bfd_vma result; - unsigned int num_read; - int shift; - unsigned char byte; - - result = 0; - shift = 0; - num_read = 0; - do - { - byte = bfd_get_8 (abfd, (bfd_byte *) buf); - buf++; - num_read++; - result |= (((bfd_vma) byte & 0x7f) << shift); - shift += 7; - } - while (byte & 0x80); - *bytes_read_ptr = num_read; - return result; -} - -/* Helper function for reading sleb128 encoded data. */ - -static bfd_signed_vma -read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED, - char *buf, - unsigned int * bytes_read_ptr) -{ - bfd_vma result; - int shift; - int num_read; - unsigned char byte; - - result = 0; - shift = 0; - num_read = 0; - do - { - byte = bfd_get_8 (abfd, (bfd_byte *) buf); - buf ++; - num_read ++; - result |= (((bfd_vma) byte & 0x7f) << shift); - shift += 7; - } - while (byte & 0x80); - if (byte & 0x40) - result |= (((bfd_vma) -1) << (shift - 7)) << 7; - *bytes_read_ptr = num_read; - return result; -} - #define read_uleb128(VAR, BUF) \ do \ { \ --- bfd/libbfd-in.h.leb128 2004-10-11 09:36:15.000000000 -0700 +++ bfd/libbfd-in.h 2005-01-11 11:43:33.000000000 -0800 @@ -686,3 +686,6 @@ extern void bfd_section_already_linked_t (bfd_boolean (*) (struct bfd_section_already_linked_hash_entry *, void *), void *); +extern bfd_vma read_unsigned_leb128 (bfd *, char *, unsigned int *); +extern bfd_signed_vma read_signed_leb128 (bfd *, char *, unsigned int *); + --- bfd/libbfd.c.leb128 2004-08-13 08:00:10.000000000 -0700 +++ bfd/libbfd.c 2005-01-11 11:37:17.000000000 -0800 @@ -860,3 +860,61 @@ warn_deprecated (const char *what, mask |= ~(size_t) func; } } + +/* Helper function for reading uleb128 encoded data. */ + +bfd_vma +read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED, + char *buf, + unsigned int *bytes_read_ptr) +{ + bfd_vma result; + unsigned int num_read; + int shift; + unsigned char byte; + + result = 0; + shift = 0; + num_read = 0; + do + { + byte = bfd_get_8 (abfd, (bfd_byte *) buf); + buf++; + num_read++; + result |= (((bfd_vma) byte & 0x7f) << shift); + shift += 7; + } + while (byte & 0x80); + *bytes_read_ptr = num_read; + return result; +} + +/* Helper function for reading sleb128 encoded data. */ + +bfd_signed_vma +read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED, + char *buf, + unsigned int * bytes_read_ptr) +{ + bfd_vma result; + int shift; + int num_read; + unsigned char byte; + + result = 0; + shift = 0; + num_read = 0; + do + { + byte = bfd_get_8 (abfd, (bfd_byte *) buf); + buf ++; + num_read ++; + result |= (((bfd_vma) byte & 0x7f) << shift); + shift += 7; + } + while (byte & 0x80); + if ((shift < 8 * sizeof (result)) && (byte & 0x40)) + result |= (((bfd_vma) -1) << shift); + *bytes_read_ptr = num_read; + return result; +}