Improve the speed of scanning PE binaries for line number information.

PR binutils/18025
	* coff-bfd.h (struct coff_section_data): Add new fields:
	saved_bias and bias.
	* coffgen.c (coff_find_nearest_line_with_names): Cache the bias
	computed for PE binaries.
	* dwarf2.c (scan_unit_for_symbols): Only warn once about each
	missing abbrev.
This commit is contained in:
Nick Clifton 2017-03-29 12:27:44 +01:00
parent 7cc0cd2903
commit e643cb45bf
4 changed files with 60 additions and 12 deletions

View File

@ -1,3 +1,13 @@
2017-03-29 Nick Clifton <nickc@redhat.com>
PR binutils/18025
* coff-bfd.h (struct coff_section_data): Add new fields:
saved_bias and bias.
* coffgen.c (coff_find_nearest_line_with_names): Cache the bias
computed for PE binaries.
* dwarf2.c (scan_unit_for_symbols): Only warn once about each
missing abbrev.
2017-03-28 Hans-Peter Nilsson <hp@axis.com>
PR ld/16044

View File

@ -50,6 +50,8 @@ struct coff_section_tdata
/* If this is TRUE, the contents entry may not be freed. */
bfd_boolean keep_contents;
/* Information cached by coff_find_nearest_line. */
bfd_boolean saved_bias;
bfd_signed_vma bias;
bfd_vma offset;
unsigned int i;
const char *function;

View File

@ -2259,6 +2259,8 @@ coff_find_nearest_line_with_names (bfd *abfd,
&coff_data(abfd)->dwarf2_find_line_info))
return TRUE;
sec_data = coff_section_data (abfd, section);
/* 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
@ -2267,8 +2269,26 @@ coff_find_nearest_line_with_names (bfd *abfd,
{
bfd_signed_vma bias;
bias = _bfd_dwarf2_find_symbol_bias (symbols,
& coff_data (abfd)->dwarf2_find_line_info);
/* Create a cache of the result for the next call. */
if (sec_data == NULL && section->owner == abfd)
{
amt = sizeof (struct coff_section_tdata);
section->used_by_bfd = bfd_zalloc (abfd, amt);
sec_data = (struct coff_section_tdata *) section->used_by_bfd;
}
if (sec_data != NULL && sec_data->saved_bias)
bias = sec_data->saved_bias;
else
{
bias = _bfd_dwarf2_find_symbol_bias (symbols,
& coff_data (abfd)->dwarf2_find_line_info);
if (sec_data)
{
sec_data->saved_bias = TRUE;
sec_data->bias = bias;
}
}
if (bias
&& _bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section,
@ -2363,10 +2383,16 @@ coff_find_nearest_line_with_names (bfd *abfd,
}
}
/* Now wander though the raw linenumbers of the section. */
/* If we have been called on this section before, and the offset we
want is further down then we can prime the lookup loop. */
sec_data = coff_section_data (abfd, section);
if (section->lineno_count == 0)
{
*functionname_ptr = NULL;
*line_ptr = 0;
return TRUE;
}
/* Now wander though the raw linenumbers of the section.
If we have been called on this section before, and the offset
we want is further down then we can prime the lookup loop. */
if (sec_data != NULL
&& sec_data->i > 0
&& offset >= sec_data->offset)
@ -2395,6 +2421,7 @@ coff_find_nearest_line_with_names (bfd *abfd,
coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
if (coff->symbol.value > offset)
break;
*functionname_ptr = coff->symbol.name;
last_value = coff->symbol.value;
if (coff->native)
@ -2451,6 +2478,7 @@ coff_find_nearest_line_with_names (bfd *abfd,
section->used_by_bfd = bfd_zalloc (abfd, amt);
sec_data = (struct coff_section_tdata *) section->used_by_bfd;
}
if (sec_data != NULL)
{
sec_data->offset = offset;

View File

@ -2738,12 +2738,19 @@ scan_unit_for_symbols (struct comp_unit *unit)
continue;
}
abbrev = lookup_abbrev (abbrev_number,unit->abbrevs);
abbrev = lookup_abbrev (abbrev_number, unit->abbrevs);
if (! abbrev)
{
_bfd_error_handler
(_("Dwarf Error: Could not find abbrev number %u."),
abbrev_number);
static unsigned int previous_failed_abbrev = -1U;
/* Avoid multiple reports of the same missing abbrev. */
if (abbrev_number != previous_failed_abbrev)
{
_bfd_error_handler
(_("Dwarf Error: Could not find abbrev number %u."),
abbrev_number);
previous_failed_abbrev = abbrev_number;
}
bfd_set_error (bfd_error_bad_value);
goto fail;
}
@ -2760,7 +2767,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
func->tag = abbrev->tag;
func->prev_func = unit->function_table;
unit->function_table = func;
unit->number_of_functions++;
unit->number_of_functions++;
BFD_ASSERT (!unit->cached);
if (func->tag == DW_TAG_inlined_subroutine)
@ -2785,7 +2792,8 @@ scan_unit_for_symbols (struct comp_unit *unit)
var->stack = 1;
var->prev_var = unit->variable_table;
unit->variable_table = var;
BFD_ASSERT (!unit->cached);
/* PR 18205: Missing debug information can cause this
var to be attached to an already cached unit. */
}
/* No inline function in scope at this nesting level. */