Allows the binutils to cope with PE binaries where the section addresses have been changed, but the DWARF debug info has not been altered.
PR binutils/18025 * coffgen.c (coff_find_nearest_line_with_names): If the dwarf2 lookup fails, check for an address bias in the dwarf info, and if one exists, retry the lookup with the biased value. * dwarf2.c (_bfd_dwarf2_find_symbol_bias): New function. Determines if a bias exists bewteen the addresses of functions based on DWARF information vs symbol table information. * libbfd-in.h (_bfd_dwarf2_find_symbol_bias): Prototype. * libbfd.h: Regenerate.
This commit is contained in:
parent
f5771b1d96
commit
425bd9e1bb
5 changed files with 91 additions and 0 deletions
|
@ -1,3 +1,15 @@
|
|||
2015-03-05 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR binutils/18025
|
||||
* coffgen.c (coff_find_nearest_line_with_names): If the dwarf2
|
||||
lookup fails, check for an address bias in the dwarf info, and if
|
||||
one exists, retry the lookup with the biased value.
|
||||
* dwarf2.c (_bfd_dwarf2_find_symbol_bias): New function.
|
||||
Determines if a bias exists bewteen the addresses of functions
|
||||
based on DWARF information vs symbol table information.
|
||||
* libbfd-in.h (_bfd_dwarf2_find_symbol_bias): Prototype.
|
||||
* libbfd.h: Regenerate.
|
||||
|
||||
2015-03-04 Marcus Shawcroft <marcus.shawcroft@arm.com>
|
||||
|
||||
* elfxx-aarch64.c (decode_add_imm, decode_movw_imm)
|
||||
|
|
|
@ -2245,6 +2245,26 @@ coff_find_nearest_line_with_names (bfd *abfd,
|
|||
&coff_data(abfd)->dwarf2_find_line_info))
|
||||
return TRUE;
|
||||
|
||||
/* If the DWARF lookup failed, but there is DWARF information available
|
||||
then the problem might be that the file has been rebased. This tool
|
||||
changes the VMAs of all the sections, but it does not update the DWARF
|
||||
information. So try again, using a bias against the address sought. */
|
||||
if (coff_data (abfd)->dwarf2_find_line_info != NULL)
|
||||
{
|
||||
bfd_signed_vma bias;
|
||||
|
||||
bias = _bfd_dwarf2_find_symbol_bias (symbols,
|
||||
& coff_data (abfd)->dwarf2_find_line_info);
|
||||
|
||||
if (bias
|
||||
&& _bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section,
|
||||
offset + bias,
|
||||
filename_ptr, functionname_ptr,
|
||||
line_ptr, NULL, debug_sections, 0,
|
||||
&coff_data(abfd)->dwarf2_find_line_info))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*filename_ptr = 0;
|
||||
*functionname_ptr = 0;
|
||||
*line_ptr = 0;
|
||||
|
|
51
bfd/dwarf2.c
51
bfd/dwarf2.c
|
@ -3788,6 +3788,57 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Scan the debug information in PINFO looking for a DW_TAG_subprogram
|
||||
abbrev with a DW_AT_low_pc attached to it. Then lookup that same
|
||||
symbol in SYMBOLS and return the difference between the low_pc and
|
||||
the symbol's address. Returns 0 if no suitable symbol could be found. */
|
||||
|
||||
bfd_signed_vma
|
||||
_bfd_dwarf2_find_symbol_bias (asymbol ** symbols, void ** pinfo)
|
||||
{
|
||||
struct dwarf2_debug *stash;
|
||||
struct comp_unit * unit;
|
||||
|
||||
stash = (struct dwarf2_debug *) *pinfo;
|
||||
|
||||
if (stash == NULL)
|
||||
return 0;
|
||||
|
||||
for (unit = stash->all_comp_units; unit; unit = unit->next_unit)
|
||||
{
|
||||
struct funcinfo * func;
|
||||
|
||||
if (unit->function_table == NULL)
|
||||
{
|
||||
if (unit->line_table == NULL)
|
||||
unit->line_table = decode_line_info (unit, stash);
|
||||
if (unit->line_table != NULL)
|
||||
scan_unit_for_symbols (unit);
|
||||
}
|
||||
|
||||
for (func = unit->function_table; func != NULL; func = func->prev_func)
|
||||
if (func->name && func->arange.low)
|
||||
{
|
||||
asymbol ** psym;
|
||||
|
||||
/* FIXME: Do we need to scan the aranges looking for the lowest pc value ? */
|
||||
|
||||
for (psym = symbols; * psym != NULL; psym++)
|
||||
{
|
||||
asymbol * sym = * psym;
|
||||
|
||||
if (sym->flags & BSF_FUNCTION
|
||||
&& sym->section != NULL
|
||||
&& strcmp (sym->name, func->name) == 0)
|
||||
return ((bfd_signed_vma) func->arange.low) -
|
||||
((bfd_signed_vma) (sym->value + sym->section->vma));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find the source code location of SYMBOL. If SYMBOL is NULL
|
||||
then find the nearest source code location corresponding to
|
||||
the address SECTION + OFFSET.
|
||||
|
|
|
@ -551,6 +551,10 @@ extern bfd_boolean _bfd_dwarf2_find_nearest_line
|
|||
const char **, const char **, unsigned int *, unsigned int *,
|
||||
const struct dwarf_debug_section *, unsigned int, void **);
|
||||
|
||||
/* Find the bias between DWARF addresses and real addresses. */
|
||||
extern bfd_signed_vma _bfd_dwarf2_find_symbol_bias
|
||||
(asymbol **, void **);
|
||||
|
||||
/* Find inliner info after calling bfd_find_nearest_line. */
|
||||
extern bfd_boolean _bfd_dwarf2_find_inliner_info
|
||||
(bfd *, const char **, const char **, unsigned int *, void **);
|
||||
|
|
|
@ -556,6 +556,10 @@ extern bfd_boolean _bfd_dwarf2_find_nearest_line
|
|||
const char **, const char **, unsigned int *, unsigned int *,
|
||||
const struct dwarf_debug_section *, unsigned int, void **);
|
||||
|
||||
/* Find the bias between DWARF addresses and real addresses. */
|
||||
extern bfd_signed_vma _bfd_dwarf2_find_symbol_bias
|
||||
(asymbol **, void **);
|
||||
|
||||
/* Find inliner info after calling bfd_find_nearest_line. */
|
||||
extern bfd_boolean _bfd_dwarf2_find_inliner_info
|
||||
(bfd *, const char **, const char **, unsigned int *, void **);
|
||||
|
|
Loading…
Reference in a new issue