From f2363ce55b29c5c6aa37be2b5e6f4de9aa685203 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 8 Aug 2001 11:17:34 +0000 Subject: [PATCH] * dwarf2.c (struct dwarf2_debug): Add sec, sec_info_ptr and syms. (find_rela_addend): New function. (parse_comp_unit): Call it to find the abbrev offset addend. (_bfd_dwarf2_find_nearest_line): Initialize and maintain the new members of dwarf2_debug as debugging information is read. --- bfd/ChangeLog | 8 +++++ bfd/dwarf2.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a15c488a8b..9429b0282c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2001-08-08 Alexandre Oliva + + * dwarf2.c (struct dwarf2_debug): Add sec, sec_info_ptr and syms. + (find_rela_addend): New function. + (parse_comp_unit): Call it to find the abbrev offset addend. + (_bfd_dwarf2_find_nearest_line): Initialize and maintain the new + members of dwarf2_debug as debugging information is read. + 2001-08-07 Nick Clifton * coff-sh.c (sh_coff_reloc_type_lookup): Provide for sh-coff diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index 4a032732c9..23a51fa98c 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -96,6 +96,14 @@ struct dwarf2_debug /* Pointer to the end of the .debug_info section memory buffer. */ char* info_ptr_end; + /* Pointer to the section and address of the beginning of the + section. */ + asection* sec; + char* sec_info_ptr; + + /* Pointer to the symbol table. */ + asymbol** syms; + /* Pointer to the .debug_abbrev section loaded into memory. */ char* dwarf_abbrev_buffer; @@ -1219,6 +1227,60 @@ scan_unit_for_functions (unit) return true; } +/* Look for a RELA relocation to be applied on OFFSET of section SEC, + and return the addend if such a relocation is found. Since this is + only used to find relocations referring to the .debug_abbrev + section, we make sure the relocation refers to this section, but + this is not strictly necessary, and it can probably be safely + removed if needed. However, it is important to note that this + function only returns the addend, it doesn't serve the purpose of + applying a generic relocation. + + If no suitable relocation is found, or if it is not a real RELA + relocation, this function returns 0. */ + +static bfd_vma +find_rela_addend (abfd, sec, offset, syms) + bfd* abfd; + asection* sec; + bfd_size_type offset; + asymbol** syms; +{ + long reloc_size = bfd_get_reloc_upper_bound (abfd, sec); + arelent **relocs = NULL; + long reloc_count, relc; + + if (reloc_size <= 0) + return 0; + + relocs = (arelent **) bfd_malloc ((size_t) reloc_size); + if (relocs == NULL) + return 0; + + reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms); + + if (reloc_count <= 0) + { + free (relocs); + return 0; + } + + for (relc = 0; relc < reloc_count; relc++) + if (relocs[relc]->address == offset + && (*relocs[relc]->sym_ptr_ptr)->flags & BSF_SECTION_SYM + && strcmp ((*relocs[relc]->sym_ptr_ptr)->name, + ".debug_abbrev") == 0) + { + bfd_vma addend = (relocs[relc]->howto->partial_inplace + ? 0 : relocs[relc]->addend); + free (relocs); + return addend; + } + + free (relocs); + return 0; +} + /* Parse a DWARF2 compilation unit starting at INFO_PTR. This includes the compilation unit header that proceeds the DIE's, but does not include the length field that preceeds each compilation @@ -1259,6 +1321,13 @@ parse_comp_unit (abfd, stash, unit_length, abbrev_length) abbrev_offset = read_4_bytes (abfd, info_ptr); else if (abbrev_length == 8) abbrev_offset = read_8_bytes (abfd, info_ptr); + /* The abbrev offset is generally a relocation pointing to + .debug_abbrev+offset. On RELA targets, we have to find the + relocation and extract the addend to obtain the actual + abbrev_offset, so do it here. */ + abbrev_offset += find_rela_addend (abfd, stash->sec, + info_ptr - stash->sec_info_ptr, + stash->syms); info_ptr += abbrev_length; addr_size = read_1_byte (abfd, info_ptr); info_ptr += 1; @@ -1498,7 +1567,7 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, addr_size, pinfo) bfd *abfd; asection *section; - asymbol **symbols ATTRIBUTE_UNUSED; + asymbol **symbols; bfd_vma offset; const char **filename_ptr; const char **functionname_ptr; @@ -1584,7 +1653,11 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, stash->info_ptr_end = stash->info_ptr + start + size; } - BFD_ASSERT (stash->info_ptr_end = stash->info_ptr + total_size); + BFD_ASSERT (stash->info_ptr_end == stash->info_ptr + total_size); + + stash->sec = find_debug_info (abfd, NULL); + stash->sec_info_ptr = stash->info_ptr; + stash->syms = symbols; } /* FIXME: There is a problem with the contents of the @@ -1632,6 +1705,13 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, each = parse_comp_unit (abfd, stash, length, addr_size); stash->info_ptr += length; + if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr) + == stash->sec->_raw_size) + { + stash->sec = find_debug_info (abfd, stash->sec); + stash->sec_info_ptr = stash->info_ptr; + } + if (each) { each->next_unit = stash->all_comp_units;