188 lines
6.7 KiB
Diff
188 lines
6.7 KiB
Diff
From 76868f3606fb9de04f49c441c1e3cdd3e943a34d Mon Sep 17 00:00:00 2001
|
|
From: "H.J. Lu" <hjl.tools@gmail.com>
|
|
Date: Thu, 29 Oct 2020 09:19:25 -0700
|
|
Subject: [PATCH] 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.
|
|
---
|
|
binutils/dwarf.c | 52 +-
|
|
.../testsuite/binutils-all/x86-64/x86-64.exp | 31 +
|
|
2 files changed, 61 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
|
|
index 5cfa528594ff..14a7791c8cc4 100644
|
|
--- a/binutils/dwarf.c
|
|
+++ b/binutils/dwarf.c
|
|
@@ -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;
|
|
}
|
|
diff --git a/binutils/testsuite/binutils-all/x86-64/x86-64.exp b/binutils/testsuite/binutils-all/x86-64/x86-64.exp
|
|
index 7bd49ab619df..5f02ed35ade7 100644
|
|
--- a/binutils/testsuite/binutils-all/x86-64/x86-64.exp
|
|
+++ b/binutils/testsuite/binutils-all/x86-64/x86-64.exp
|
|
@@ -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)"
|
|
+ }
|
|
+ }
|
|
+}
|