dwarf: Also match abbrev base when searching abbrev list

A .debug_abbrev section can have multiple CUs.  When caching abbrev list,
we need to check abbrev base to support multiple CUs.

	PR binutils/26808
	* dwarf.c (abbrev_list): Add abbrev_base.
	(new_abbrev_list): Add an abbrev_base argument and record it.
	(find_abbrev_list_by_abbrev_offset): Add an abbrev_base argument
	and match it.
	(process_debug_info): Pass abbrev_base to new_abbrev_list and
	find_abbrev_list_by_abbrev_offset.
	(display_debug_abbrev): Pass 0 abbrev_base to new_abbrev_list
	and find_abbrev_list_by_abbrev_offset.
	* testsuite/binutils-all/x86-64/pr26808.dump: New file.
	* testsuite/binutils-all/x86-64/pr26808.dwp.bz2: Likewise.
	* testsuite/binutils-all/x86-64/x86-64.exp: Run PR binutils/26808
	test.
This commit is contained in:
H.J. Lu 2020-10-29 09:19:25 -07:00
parent cfaa8f7692
commit 76868f3606
5 changed files with 1517 additions and 22 deletions

View File

@ -1,3 +1,19 @@
2020-10-29 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/26808
* dwarf.c (abbrev_list): Add abbrev_base.
(new_abbrev_list): Add an abbrev_base argument and record it.
(find_abbrev_list_by_abbrev_offset): Add an abbrev_base argument
and match it.
(process_debug_info): Pass abbrev_base to new_abbrev_list and
find_abbrev_list_by_abbrev_offset.
(display_debug_abbrev): Pass 0 abbrev_base to new_abbrev_list
and find_abbrev_list_by_abbrev_offset.
* testsuite/binutils-all/x86-64/pr26808.dump: New file.
* testsuite/binutils-all/x86-64/pr26808.dwp.bz2: Likewise.
* testsuite/binutils-all/x86-64/x86-64.exp: Run PR binutils/26808
test.
2020-10-29 Nick Clifton <nickc@redhat.com>
PR 26805

View File

@ -876,6 +876,7 @@ typedef struct abbrev_list
{
abbrev_entry * first_abbrev;
abbrev_entry * last_abbrev;
dwarf_vma abbrev_base;
dwarf_vma abbrev_offset;
struct abbrev_list * next;
unsigned char * start_of_next_abbrevs;
@ -955,10 +956,11 @@ free_all_abbrevs (void)
}
static abbrev_list *
new_abbrev_list (dwarf_vma abbrev_offset)
new_abbrev_list (dwarf_vma abbrev_base, dwarf_vma abbrev_offset)
{
abbrev_list * list = (abbrev_list *) xcalloc (sizeof * list, 1);
list->abbrev_base = abbrev_base;
list->abbrev_offset = abbrev_offset;
list->next = abbrev_lists;
@ -968,12 +970,14 @@ new_abbrev_list (dwarf_vma abbrev_offset)
}
static abbrev_list *
find_abbrev_list_by_abbrev_offset (dwarf_vma abbrev_offset)
find_abbrev_list_by_abbrev_offset (dwarf_vma abbrev_base,
dwarf_vma abbrev_offset)
{
abbrev_list * list;
for (list = abbrev_lists; list != NULL; list = list->next)
if (list->abbrev_offset == abbrev_offset)
if (list->abbrev_base == abbrev_base
&& list->abbrev_offset == abbrev_offset)
return list;
return NULL;
@ -3455,6 +3459,8 @@ process_debug_info (struct dwarf_section * section,
{
DWARF2_Internal_CompUnit compunit;
unsigned char * hdrptr;
dwarf_vma abbrev_base;
size_t abbrev_size;
dwarf_vma cu_offset;
unsigned int offset_size;
unsigned int initial_length_size;
@ -3499,25 +3505,25 @@ process_debug_info (struct dwarf_section * section,
SAFE_BYTE_GET_AND_INC (compunit.cu_abbrev_offset, hdrptr, offset_size, end);
list = find_abbrev_list_by_abbrev_offset (compunit.cu_abbrev_offset);
if (this_set == NULL)
{
abbrev_base = 0;
abbrev_size = debug_displays [abbrev_sec].section.size;
}
else
{
abbrev_base = this_set->section_offsets [DW_SECT_ABBREV];
abbrev_size = this_set->section_sizes [DW_SECT_ABBREV];
}
list = find_abbrev_list_by_abbrev_offset (abbrev_base,
compunit.cu_abbrev_offset);
if (list == NULL)
{
dwarf_vma abbrev_base;
size_t abbrev_size;
unsigned char * next;
if (this_set == NULL)
{
abbrev_base = 0;
abbrev_size = debug_displays [abbrev_sec].section.size;
}
else
{
abbrev_base = this_set->section_offsets [DW_SECT_ABBREV];
abbrev_size = this_set->section_sizes [DW_SECT_ABBREV];
}
list = new_abbrev_list (compunit.cu_abbrev_offset);
list = new_abbrev_list (abbrev_base,
compunit.cu_abbrev_offset);
next = process_abbrev_set
(((unsigned char *) debug_displays [abbrev_sec].section.start
+ abbrev_base + compunit.cu_abbrev_offset),
@ -3739,12 +3745,14 @@ process_debug_info (struct dwarf_section * section,
(unsigned long) debug_displays [abbrev_sec].section.size);
else
{
list = find_abbrev_list_by_abbrev_offset (compunit.cu_abbrev_offset);
list = find_abbrev_list_by_abbrev_offset (abbrev_base,
compunit.cu_abbrev_offset);
if (list == NULL)
{
unsigned char * next;
list = new_abbrev_list (compunit.cu_abbrev_offset);
list = new_abbrev_list (abbrev_base,
compunit.cu_abbrev_offset);
next = process_abbrev_set
(((unsigned char *) debug_displays [abbrev_sec].section.start
+ abbrev_base + compunit.cu_abbrev_offset),
@ -6071,10 +6079,10 @@ display_debug_abbrev (struct dwarf_section *section,
dwarf_vma offset;
offset = start - section->start;
list = find_abbrev_list_by_abbrev_offset (offset);
list = find_abbrev_list_by_abbrev_offset (0, offset);
if (list == NULL)
{
list = new_abbrev_list (offset);
list = new_abbrev_list (0, offset);
start = process_abbrev_set (start, end, list);
list->start_of_next_abbrevs = start;
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -27,3 +27,34 @@ foreach t $test_list {
verbose [file rootname $t]
run_dump_test [file rootname $t]
}
set t $srcdir/$subdir/pr26808.dwp.bz2
# We need to strip the ".bz2", but can leave the dirname.
set test $subdir/[file tail $t]
set testname [file rootname $test]
verbose $testname
if {[catch "system \"bzip2 -dc $t > $tempfile\""] != 0} {
untested "bzip2 -dc ($testname)"
} else {
send_log "$READELF -wi $tempfile > tmpdir/pr26808.out 2> /dev/null\n"
verbose "$READELF -wi $tempfile > tmpdir/pr26808.out 2> /dev/null" 1
set got [catch "system \"$READELF -wi $tempfile > tmpdir/pr26808.out 2> /dev/null\""]
if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]]} then {
fail $testname
} else {
send_log "cmp tmpdir/pr26808.out $srcdir/$subdir/pr26808.dump\n"
verbose "cmp tmpdir/pr26808.out $srcdir/$subdir/pr26808.dump" 1
set status [remote_exec build cmp "tmpdir/pr26808.out $srcdir/$subdir/pr26808.dump"]
set exec_output [lindex $status 1]
set exec_output [prune_warnings $exec_output]
if [string match "" $exec_output] then {
pass "readelf -wi ($testname)"
} else {
send_log "$exec_output\n"
verbose "$exec_output" 1
fail "readelf -wi ($testname)"
}
}
}