summaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2001-08-08 11:17:34 +0000
committerAlexandre Oliva <aoliva@redhat.com>2001-08-08 11:17:34 +0000
commit4c18db9ddd9de813c07552e95908bcafe05cf7e2 (patch)
treeef53675f8a01ede502dec28eaaa73745be4f8e84 /bfd
parent5f5f140736b2cad9b9194835eac98c4ca8d0e06a (diff)
downloadgdb-4c18db9ddd9de813c07552e95908bcafe05cf7e2.tar.gz
* 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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog8
-rw-r--r--bfd/dwarf2.c84
2 files changed, 90 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a15c488a8b4..9429b0282ca 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2001-08-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * 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 <nickc@cambridge.redhat.com>
* coff-sh.c (sh_coff_reloc_type_lookup): Provide for sh-coff
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index 4a032732c98..23a51fa98c3 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;