[DebugInfo] Fix reading location tables of v5 units in DWP.

Without the patch, all version 5 compile units in a DWP file read
location tables from the beginning of a .debug_loclists.dwo section.
The patch fixes that by adjusting the reading offset the same way as
for pre-v5 units. The section identifier to find the contribution
entry corresponds to the version of the unit.

Differential revision: https://reviews.llvm.org/D77145
This commit is contained in:
Igor Kudrin 2020-03-20 23:33:19 +07:00
parent 714324b79a
commit 49737df767
3 changed files with 210 additions and 9 deletions

View File

@ -181,20 +181,17 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
if (IsDWO) { if (IsDWO) {
// If we are reading a package file, we need to adjust the location list // If we are reading a package file, we need to adjust the location list
// data based on the index entries. // data based on the index entries.
StringRef Data = LocSection->Data; StringRef Data = Header.getVersion() >= 5
? Context.getDWARFObj().getLoclistsDWOSection().Data
: LocSection->Data;
if (auto *IndexEntry = Header.getIndexEntry()) if (auto *IndexEntry = Header.getIndexEntry())
if (const auto *C = IndexEntry->getContribution(DW_SECT_EXT_LOC)) if (const auto *C = IndexEntry->getContribution(
Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
Data = Data.substr(C->Offset, C->Length); Data = Data.substr(C->Offset, C->Length);
DWARFDataExtractor DWARFData = DWARFDataExtractor DWARFData(Data, isLittleEndian, getAddressByteSize());
Header.getVersion() >= 5
? DWARFDataExtractor(Context.getDWARFObj(),
Context.getDWARFObj().getLoclistsDWOSection(),
isLittleEndian, getAddressByteSize())
: DWARFDataExtractor(Data, isLittleEndian, getAddressByteSize());
LocTable = LocTable =
std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion()); std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
} else if (Header.getVersion() >= 5) { } else if (Header.getVersion() >= 5) {
LocTable = std::make_unique<DWARFDebugLoclists>( LocTable = std::make_unique<DWARFDebugLoclists>(
DWARFDataExtractor(Context.getDWARFObj(), DWARFDataExtractor(Context.getDWARFObj(),

View File

@ -0,0 +1,94 @@
## The test checks that pre-v5 compile units in package files read their
## location tables from .debug_loc.dwo sections.
## See dwp-v5-loclists.s for v5 units.
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
# RUN: llvm-dwarfdump -debug-info -debug-loc - | \
# RUN: FileCheck %s
# CHECK: .debug_info.dwo contents:
# CHECK: DW_TAG_compile_unit
# CHECK-NEXT: DW_AT_GNU_dwo_id (0x1100001122222222)
# CHECK: DW_TAG_variable
# CHECK-NEXT: DW_AT_name ("a")
# CHECK-NEXT: DW_AT_location (0x00000000:
# CHECK-NEXT: DW_LLE_startx_length (0x0000000000000001, 0x0000000000000010): DW_OP_reg5 RDI)
# CHECK: .debug_loc.dwo contents:
# CHECK: 0x00000013:
# CHECK-NEXT: DW_LLE_startx_length (0x00000001, 0x00000010): DW_OP_reg5 RDI
.section .debug_abbrev.dwo, "e", @progbits
.LAbbrevBegin:
.uleb128 1 # Abbreviation Code
.uleb128 17 # DW_TAG_compile_unit
.byte 1 # DW_CHILDREN_yes
.uleb128 0x2131 # DW_AT_GNU_dwo_id
.uleb128 7 # DW_FORM_data8
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.uleb128 2 # Abbreviation Code
.uleb128 52 # DW_TAG_variable
.byte 0 # DW_CHILDREN_no
.uleb128 3 # DW_AT_name
.uleb128 8 # DW_FORM_string
.uleb128 2 # DW_AT_location
.uleb128 23 # DW_FORM_sec_offset
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)
.LAbbrevEnd:
.section .debug_info.dwo, "e", @progbits
.LCUBegin:
.long .LCUEnd-.LCUVersion # Length of Unit
.LCUVersion:
.short 4 # Version
.long 0 # Abbrev offset
.byte 8 # Address size
.uleb128 1 # Abbrev [1] DW_TAG_compile_unit
.quad 0x1100001122222222 # DW_AT_GNU_dwo_id
.uleb128 2 # Abbrev [2] DW_TAG_variable
.asciz "a" # DW_AT_name
.long 0 # DW_AT_location
.byte 0 # End Of Children Mark
.LCUEnd:
.section .debug_loc.dwo, "e", @progbits
## Start the section with a number of dummy DW_LLE_end_of_list entries to check
## that the reading offset is correctly adjusted.
.zero 0x13
.LLocBegin:
.byte 3 # DW_LLE_startx_length
.uleb128 1 # Index
.long 0x10 # Length
.short 1 # Loc expr size
.byte 85 # DW_OP_reg5
.byte 0 # DW_LLE_end_of_list
.LLocEnd:
.section .debug_cu_index, "", @progbits
## Header:
.long 2 # Version
.long 3 # Section count
.long 1 # Unit count
.long 2 # Slot count
## Hash Table of Signatures:
.quad 0x1100001122222222
.quad 0
## Parallel Table of Indexes:
.long 1
.long 0
## Table of Section Offsets:
## Row 0:
.long 1 # DW_SECT_INFO
.long 3 # DW_SECT_ABBREV
.long 5 # DW_SECT_LOC
## Row 1:
.long 0 # Offset in .debug_info.dwo
.long 0 # Offset in .debug_abbrev.dwo
.long .LLocBegin-.debug_loc.dwo # Offset in .debug_loc.dwo
## Table of Section Sizes:
.long .LCUEnd-.LCUBegin # Size in .debug_info.dwo
.long .LAbbrevEnd-.LAbbrevBegin # Size in .debug_abbrev.dwo
.long .LLocEnd-.LLocBegin # Size in .debug_loc.dwo

View File

@ -0,0 +1,110 @@
## The test checks that v5 compile units in package files read their
## location tables from .debug_loclists.dwo sections.
## See dwp-v2-loc.s for pre-v5 units.
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
# RUN: llvm-dwarfdump -debug-info -debug-loclists - | \
# RUN: FileCheck %s
# CHECK: .debug_info.dwo contents:
# CHECK: DW_TAG_compile_unit
# CHECK: DW_TAG_variable
# CHECK-NEXT: DW_AT_name ("a")
# CHECK-NEXT: DW_AT_location (0x{{[0-9a-f]+}}:
# CHECK-NEXT: DW_LLE_startx_length (0x0000000000000001, 0x0000000000000010): DW_OP_reg5 RDI)
# CHECK: .debug_loclists.dwo contents:
# CHECK: locations list header:
# CHECK: locations list header:
# CHECK: 0x{{[0-9a-f]+}}:
# CHECK-NEXT: DW_LLE_startx_length (0x0000000000000001, 0x0000000000000010): DW_OP_reg5 RDI
.section .debug_abbrev.dwo, "e", @progbits
.LAbbrevBegin:
.uleb128 1 # Abbreviation Code
.uleb128 17 # DW_TAG_compile_unit
.byte 1 # DW_CHILDREN_yes
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.uleb128 2 # Abbreviation Code
.uleb128 52 # DW_TAG_variable
.byte 0 # DW_CHILDREN_no
.uleb128 3 # DW_AT_name
.uleb128 8 # DW_FORM_string
.uleb128 2 # DW_AT_location
.uleb128 23 # DW_FORM_sec_offset
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)
.LAbbrevEnd:
.section .debug_info.dwo, "e", @progbits
.LCUBegin:
.long .LCUEnd-.LCUVersion # Length of Unit
.LCUVersion:
.short 5 # Version
.byte 5 # DW_UT_split_compile
.byte 8 # Address size
.long 0 # Abbrev offset
.quad 0x1100001122222222 # DWO id
.uleb128 1 # Abbrev [1] DW_TAG_compile_unit
.uleb128 2 # Abbrev [2] DW_TAG_variable
.asciz "a" # DW_AT_name
.long .LLL0-.LLLBegin # DW_AT_location
.byte 0 # End Of Children Mark
.LCUEnd:
.section .debug_loclists.dwo, "e", @progbits
## Start the section with an unused table to check that the reading offset
## of the real table is correctly adjusted.
.long .LLLDummyEnd-.LLLDummyVersion # Length of Unit
.LLLDummyVersion:
.short 5 # Version
.byte 8 # Address size
.byte 0 # Segment selector size
.long 0 # Offset entry count
.byte 0 # DW_LLE_end_of_list
.LLLDummyEnd:
.LLLBegin:
.long .LLLEnd-.LLLVersion # Length of Unit
.LLLVersion:
.short 5 # Version
.byte 8 # Address size
.byte 0 # Segment selector size
.long 0 # Offset entry count
.LLL0:
.byte 3 # DW_LLE_startx_length
.uleb128 1 # Index
.uleb128 0x10 # Length
.uleb128 1 # Loc expr size
.byte 85 # DW_OP_reg5
.byte 0 # DW_LLE_end_of_list
.LLLEnd:
.section .debug_cu_index, "", @progbits
## Header:
.short 5 # Version
.space 2 # Padding
.long 3 # Section count
.long 1 # Unit count
.long 2 # Slot count
## Hash Table of Signatures:
.quad 0x1100001122222222
.quad 0
## Parallel Table of Indexes:
.long 1
.long 0
## Table of Section Offsets:
## Row 0:
.long 1 # DW_SECT_INFO
.long 3 # DW_SECT_ABBREV
.long 5 # DW_SECT_LOCLISTS
## Row 1:
.long 0 # Offset in .debug_info.dwo
.long 0 # Offset in .debug_abbrev.dwo
.long .LLLBegin-.debug_loclists.dwo # Offset in .debug_loclists.dwo
## Table of Section Sizes:
.long .LCUEnd-.LCUBegin # Size in .debug_info.dwo
.long .LAbbrevEnd-.LAbbrevBegin # Size in .debug_abbrev.dwo
.long .LLLEnd-.LLLBegin # Size in .debug_loclists.dwo