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:
Nick Clifton 2015-03-05 12:14:26 +00:00
parent f5771b1d96
commit 425bd9e1bb
5 changed files with 91 additions and 0 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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.

View file

@ -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 **);

View file

@ -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 **);