This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
_bfd_dwarf2_find_nearest_line returns wrong filename
- From: Andreas Schwab <schwab at suse dot de>
- To: binutils at sources dot redhat dot com
- Date: 23 Dec 2002 23:55:09 +0100
- Subject: _bfd_dwarf2_find_nearest_line returns wrong filename
On RELA targets the indirect string pointers in the DWARF2 debugging
sections need to be relocated. Otherwise you'll get nonsensical file
names in _bfd_dwarf2_find_nearest_line.
Andreas.
2002-12-23 Andreas Schwab <schwab@suse.de>
* dwarf2.c (struct dwarf2_debug): Add relocs and reloc_count.
(find_rela_addend): Take pointer to struct dwarf2_debug instead of
section and symbols. Cache reloc section there. Don't check
section in reloc, just compare offset.
(read_indirect_string): Use find_rela_addend to relocate string
offset.
(parse_comp_unit): Adjust call to find_rela_addend. Don't
advance to next debug section until after
comp_unit_find_nearest_line has been called.
--- bfd/dwarf2.c.~1.42.~ 2002-12-12 23:42:14.000000000 +0100
+++ bfd/dwarf2.c 2002-12-23 23:46:16.000000000 +0100
@@ -104,6 +104,10 @@ struct dwarf2_debug
/* Pointer to the symbol table. */
asymbol** syms;
+ /* Pointer to reloc section and number of relocs. */
+ arelent **relocs;
+ long reloc_count;
+
/* Pointer to the .debug_abbrev section loaded into memory. */
char* dwarf_abbrev_buffer;
@@ -246,7 +250,7 @@ static bfd_boolean lookup_address_in_fun
PARAMS ((struct funcinfo *, bfd_vma, struct funcinfo **, const char **));
static bfd_boolean scan_unit_for_functions PARAMS ((struct comp_unit *));
static bfd_vma find_rela_addend
- PARAMS ((bfd *, asection *, bfd_size_type, asymbol**));
+ PARAMS ((bfd *, struct dwarf2_debug *, bfd_size_type));
static struct comp_unit *parse_comp_unit
PARAMS ((bfd *, struct dwarf2_debug *, bfd_vma, unsigned int));
static bfd_boolean comp_unit_contains_address
@@ -369,6 +373,7 @@ read_indirect_string (unit, buf, bytes_r
else
offset = read_8_bytes (unit->abfd, buf);
*bytes_read_ptr = unit->offset_size;
+ offset += find_rela_addend (unit->abfd, stash, buf - stash->sec_info_ptr);
if (! stash->dwarf_str_buffer)
{
@@ -1521,57 +1526,50 @@ 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.
+/* Look for a RELA relocation to be applied on OFFSET of section
+ STASH->sec, and return the addend if such a relocation is found.
+ 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)
+find_rela_addend (abfd, stash, offset)
bfd* abfd;
- asection* sec;
+ struct dwarf2_debug* stash;
bfd_size_type offset;
- asymbol** syms;
{
- long reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
- arelent **relocs = NULL;
- long reloc_count, relc;
+ long relc;
- if (reloc_size <= 0)
- return 0;
+ if (stash->relocs == NULL)
+ {
+ long reloc_size = bfd_get_reloc_upper_bound (abfd, stash->sec);
- relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
- if (relocs == NULL)
- return 0;
+ if (reloc_size <= 0)
+ return 0;
- reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms);
+ stash->relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
+ if (stash->relocs == NULL)
+ return 0;
- if (reloc_count <= 0)
- {
- free (relocs);
- return 0;
+ stash->reloc_count = bfd_canonicalize_reloc (abfd, stash->sec,
+ stash->relocs,
+ stash->syms);
+
+ if (stash->reloc_count <= 0)
+ 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)
+ for (relc = 0; relc < stash->reloc_count; relc++)
+ if (stash->relocs[relc]->address == offset)
{
- bfd_vma addend = (relocs[relc]->howto->partial_inplace
- ? 0 : relocs[relc]->addend);
- free (relocs);
+ bfd_vma addend = (stash->relocs[relc]->howto->partial_inplace
+ ? 0 : stash->relocs[relc]->addend);
return addend;
}
- free (relocs);
return 0;
}
@@ -1616,7 +1614,7 @@ parse_comp_unit (abfd, stash, unit_lengt
relocation and extract the addend to obtain the actual
abbrev_offset, so do it here. */
off = info_ptr - stash->sec_info_ptr;
- abbrev_offset += find_rela_addend (abfd, stash->sec, off, stash->syms);
+ abbrev_offset += find_rela_addend (abfd, stash, off);
info_ptr += offset_size;
addr_size = read_1_byte (abfd, info_ptr);
info_ptr += 1;
@@ -1951,6 +1949,7 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
stash->sec = find_debug_info (abfd, NULL);
stash->sec_info_ptr = stash->info_ptr;
stash->syms = symbols;
+ stash->relocs = NULL;
}
/* FIXME: There is a problem with the contents of the
@@ -1984,7 +1983,7 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
while (stash->info_ptr < stash->info_ptr_end)
{
bfd_vma length;
- bfd_boolean found;
+ bfd_boolean found = FALSE;
unsigned int offset_size = addr_size;
if (addr_size == 4)
@@ -2013,13 +2012,6 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
each = parse_comp_unit (abfd, stash, length, offset_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;
@@ -2033,11 +2025,11 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
if (each->arange.high > 0)
{
if (comp_unit_contains_address (each, addr))
- return comp_unit_find_nearest_line (each, addr,
- filename_ptr,
- functionname_ptr,
- linenumber_ptr,
- stash);
+ found = comp_unit_find_nearest_line (each, addr,
+ filename_ptr,
+ functionname_ptr,
+ linenumber_ptr,
+ stash);
}
else
{
@@ -2046,11 +2038,22 @@ _bfd_dwarf2_find_nearest_line (abfd, sec
functionname_ptr,
linenumber_ptr,
stash);
- if (found)
- return TRUE;
}
}
}
+
+ 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 (stash->relocs)
+ free (stash->relocs);
+ stash->relocs = NULL;
+ }
+
+ if (found)
+ return TRUE;
}
return FALSE;