mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[DebugInfo][DWARF64] Fix dumping pre-standard .debug_str_offsets.dwo sections.
The sizes of offsets in the `.debug_str_offsets.dwo` section depend on the format of compilation or type units referencing them: 4 bytes for DWARF32 units and 8 bytes for DWARF64 ones. The fix uses parsed units to determine the actual size of offsets in the corresponding part of the `.debug_str_offsets.dwo` section. Differential Revision: https://reviews.llvm.org/D78555
This commit is contained in:
parent
904fe61e2d
commit
ecb37ccd0f
@ -133,11 +133,21 @@ collectContributionData(DWARFContext::unit_iterator_range Units) {
|
||||
return Contributions;
|
||||
}
|
||||
|
||||
static void dumpDWARFv5StringOffsetsSection(
|
||||
raw_ostream &OS, DIDumpOptions DumpOpts, StringRef SectionName,
|
||||
const DWARFObject &Obj, const DWARFSection &StringOffsetsSection,
|
||||
StringRef StringSection, DWARFContext::unit_iterator_range Units,
|
||||
bool LittleEndian) {
|
||||
// Dump a DWARF string offsets section. This may be a DWARF v5 formatted
|
||||
// string offsets section, where each compile or type unit contributes a
|
||||
// number of entries (string offsets), with each contribution preceded by
|
||||
// a header containing size and version number. Alternatively, it may be a
|
||||
// monolithic series of string offsets, as generated by the pre-DWARF v5
|
||||
// implementation of split DWARF; however, in that case we still need to
|
||||
// collect contributions of units because the size of the offsets (4 or 8
|
||||
// bytes) depends on the format of the referencing unit (DWARF32 or DWARF64).
|
||||
static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
StringRef SectionName,
|
||||
const DWARFObject &Obj,
|
||||
const DWARFSection &StringOffsetsSection,
|
||||
StringRef StringSection,
|
||||
DWARFContext::unit_iterator_range Units,
|
||||
bool LittleEndian) {
|
||||
auto Contributions = collectContributionData(Units);
|
||||
DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
|
||||
DataExtractor StrData(StringSection, LittleEndian, 0);
|
||||
@ -202,49 +212,6 @@ static void dumpDWARFv5StringOffsetsSection(
|
||||
}
|
||||
}
|
||||
|
||||
// Dump a DWARF string offsets section. This may be a DWARF v5 formatted
|
||||
// string offsets section, where each compile or type unit contributes a
|
||||
// number of entries (string offsets), with each contribution preceded by
|
||||
// a header containing size and version number. Alternatively, it may be a
|
||||
// monolithic series of string offsets, as generated by the pre-DWARF v5
|
||||
// implementation of split DWARF.
|
||||
static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
StringRef SectionName,
|
||||
const DWARFObject &Obj,
|
||||
const DWARFSection &StringOffsetsSection,
|
||||
StringRef StringSection,
|
||||
DWARFContext::unit_iterator_range Units,
|
||||
bool LittleEndian, unsigned MaxVersion) {
|
||||
// If we have at least one (compile or type) unit with DWARF v5 or greater,
|
||||
// we assume that the section is formatted like a DWARF v5 string offsets
|
||||
// section.
|
||||
if (MaxVersion >= 5)
|
||||
dumpDWARFv5StringOffsetsSection(OS, DumpOpts, SectionName, Obj,
|
||||
StringOffsetsSection, StringSection, Units,
|
||||
LittleEndian);
|
||||
else {
|
||||
DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
|
||||
uint64_t offset = 0;
|
||||
uint64_t size = StringOffsetsSection.Data.size();
|
||||
// Ensure that size is a multiple of the size of an entry.
|
||||
if (size & ((uint64_t)(sizeof(uint32_t) - 1))) {
|
||||
OS << "error: size of ." << SectionName << " is not a multiple of "
|
||||
<< sizeof(uint32_t) << ".\n";
|
||||
size &= -(uint64_t)sizeof(uint32_t);
|
||||
}
|
||||
DataExtractor StrData(StringSection, LittleEndian, 0);
|
||||
while (offset < size) {
|
||||
OS << format("0x%8.8" PRIx64 ": ", offset);
|
||||
uint64_t StringOffset = strOffsetExt.getU32(&offset);
|
||||
OS << format("%8.8" PRIx64 " ", StringOffset);
|
||||
const char *S = StrData.getCStr(&StringOffset);
|
||||
if (S)
|
||||
OS << format("\"%s\"", S);
|
||||
OS << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dump the .debug_addr section.
|
||||
static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
|
||||
DIDumpOptions DumpOpts, uint16_t Version,
|
||||
@ -660,16 +627,15 @@ void DWARFContext::dump(
|
||||
|
||||
if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
|
||||
DObj->getStrOffsetsSection().Data))
|
||||
dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets", *DObj,
|
||||
DObj->getStrOffsetsSection(),
|
||||
DObj->getStrSection(), normal_units(),
|
||||
isLittleEndian(), getMaxVersion());
|
||||
dumpStringOffsetsSection(
|
||||
OS, DumpOpts, "debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),
|
||||
DObj->getStrSection(), normal_units(), isLittleEndian());
|
||||
if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
|
||||
DObj->getStrOffsetsDWOSection().Data))
|
||||
dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets.dwo", *DObj,
|
||||
DObj->getStrOffsetsDWOSection(),
|
||||
DObj->getStrDWOSection(), dwo_units(),
|
||||
isLittleEndian(), getMaxDWOVersion());
|
||||
isLittleEndian());
|
||||
|
||||
if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
|
||||
DObj->getGdbIndexSection())) {
|
||||
|
@ -996,11 +996,10 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) {
|
||||
// index table (in a package file). In a .dwo file it is simply
|
||||
// the length of the string offsets section.
|
||||
if (!IndexEntry)
|
||||
return {
|
||||
Optional<StrOffsetsContributionDescriptor>(
|
||||
{0, StringOffsetSection.Data.size(), 4, DWARF32})};
|
||||
return {Optional<StrOffsetsContributionDescriptor>(
|
||||
{0, StringOffsetSection.Data.size(), 4, Header.getFormat()})};
|
||||
if (C)
|
||||
return {Optional<StrOffsetsContributionDescriptor>(
|
||||
{C->Offset, C->Length, 4, DWARF32})};
|
||||
{C->Offset, C->Length, 4, Header.getFormat()})};
|
||||
return None;
|
||||
}
|
||||
|
@ -9,6 +9,5 @@
|
||||
# A degenerate section, not enough for a single entry.
|
||||
.byte 2
|
||||
|
||||
# INVALIDSECTIONLENGTH: .debug_str_offsets contents:
|
||||
# INVALIDSECTIONLENGTH-NOT: contents:
|
||||
# INVALIDSECTIONLENGTH: error: size of .debug_str_offsets is not a multiple of 4.
|
||||
# INVALIDSECTIONLENGTH: .debug_str_offsets contents:
|
||||
# INVALIDSECTIONLENGTH: 0x00000000: Gap, length = 1
|
||||
|
95
test/DebugInfo/X86/dwarfdump-str-offsets-v4-dwarf64-dwo.s
Normal file
95
test/DebugInfo/X86/dwarfdump-str-offsets-v4-dwarf64-dwo.s
Normal file
@ -0,0 +1,95 @@
|
||||
## This tests dumping a .debug_str_offsets.dwo section which is referenced by
|
||||
## DWARF64 pre-v5 units and dumping attributes in such units which use the
|
||||
## DW_FORM_strx form.
|
||||
|
||||
# RUN: llvm-mc -triple x86_64 %s -filetype=obj -o - | \
|
||||
# RUN: llvm-dwarfdump -v - | \
|
||||
# RUN: FileCheck %s
|
||||
|
||||
# CHECK: .debug_info.dwo contents:
|
||||
# CHECK: Compile Unit:
|
||||
# CHECK: DW_TAG_compile_unit [1]
|
||||
# CHECK-NEXT: DW_AT_name [DW_FORM_strx] (indexed (00000000) string = "Compilation Unit")
|
||||
|
||||
# CHECK: .debug_types.dwo contents:
|
||||
# CHECK: Type Unit:
|
||||
# CHECK: DW_TAG_type_unit [2] *
|
||||
# CHECK-NEXT: DW_AT_name [DW_FORM_strx] (indexed (00000001) string = "Type Unit")
|
||||
# CHECK: DW_TAG_structure_type [3]
|
||||
# CHECK-NEXT: DW_AT_name [DW_FORM_strx] (indexed (00000002) string = "Structure")
|
||||
|
||||
# CHECK: .debug_str.dwo contents:
|
||||
# CHECK-NEXT: 0x00000000: "Compilation Unit"
|
||||
# CHECK-NEXT: 0x00000011: "Type Unit"
|
||||
# CHECK-NEXT: 0x0000001b: "Structure"
|
||||
|
||||
# CHECK: .debug_str_offsets.dwo contents:
|
||||
# CHECK-NEXT: 0x00000000: Contribution size = 24, Format = DWARF64, Version = 4
|
||||
# CHECK-NEXT: 0x00000000: 00000000 "Compilation Unit"
|
||||
# CHECK-NEXT: 0x00000008: 00000011 "Type Unit"
|
||||
# CHECK-NEXT: 0x00000010: 0000001b "Structure"
|
||||
|
||||
.section .debug_str.dwo, "MSe", @progbits, 1
|
||||
.LStr0:
|
||||
.asciz "Compilation Unit"
|
||||
.LStr1:
|
||||
.asciz "Type Unit"
|
||||
.LStr2:
|
||||
.asciz "Structure"
|
||||
|
||||
.section .debug_str_offsets.dwo, "e", @progbits
|
||||
.quad .LStr0-.debug_str.dwo # 0: "Compilation Unit"
|
||||
.quad .LStr1-.debug_str.dwo # 1: "Type Unit"
|
||||
.quad .LStr2-.debug_str.dwo # 2: "Structure"
|
||||
|
||||
.section .debug_abbrev.dwo, "e", @progbits
|
||||
.uleb128 0x01 # Abbrev code
|
||||
.uleb128 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.uleb128 0x03 # DW_AT_name
|
||||
.uleb128 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.uleb128 0x02 # Abbrev code
|
||||
.uleb128 0x41 # DW_TAG_type_unit
|
||||
.byte 0x01 # DW_CHILDREN_yes
|
||||
.uleb128 0x03 # DW_AT_name
|
||||
.uleb128 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.uleb128 0x03 # Abbrev code
|
||||
.uleb128 0x13 # DW_TAG_structure_type
|
||||
.byte 0x00 # DW_CHILDREN_no (no members)
|
||||
.uleb128 0x03 # DW_AT_name
|
||||
.uleb128 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
|
||||
.section .debug_info.dwo, "e", @progbits
|
||||
.long 0xffffffff # DWARF64 mark
|
||||
.quad .LCUEnd-.LCUVer # Length
|
||||
.LCUVer:
|
||||
.short 4 # Version
|
||||
.quad 0 # Abbrev. offset
|
||||
.byte 8 # Address size
|
||||
.uleb128 1 # Abbrev [1] DW_TAG_compile_unit
|
||||
.uleb128 0 # DW_AT_name ("Compilation Unit")
|
||||
.LCUEnd:
|
||||
|
||||
.section .debug_types.dwo, "e", @progbits
|
||||
.LTU:
|
||||
.long 0xffffffff # DWARF64 mark
|
||||
.quad .LTUEnd-.LTUVer # Length
|
||||
.LTUVer:
|
||||
.short 4 # Version
|
||||
.quad 0 # Abbrev. offset
|
||||
.byte 8 # Address size
|
||||
.quad 0x11110022ffffffff # Type Signature
|
||||
.quad .LTUType-.LTU # Type offset
|
||||
.uleb128 2 # Abbrev [2] DW_TAG_type_unit
|
||||
.uleb128 1 # DW_AT_name ("Type Unit")
|
||||
.LTUType:
|
||||
.uleb128 3 # Abbrev [3] DW_TAG_structure_type
|
||||
.uleb128 2 # DW_AT_name ("Structure")
|
||||
.LTUEnd:
|
140
test/DebugInfo/X86/dwarfdump-str-offsets-v4-dwarf64-dwp.s
Normal file
140
test/DebugInfo/X86/dwarfdump-str-offsets-v4-dwarf64-dwp.s
Normal file
@ -0,0 +1,140 @@
|
||||
## This tests dumping a .debug_str_offsets.dwo section in a DWP file when it is
|
||||
## referenced by units in different formats: one unit is DWARF32 and another
|
||||
## is DWARF64, thus the .debug_str_offsets.dwo section has contributions with
|
||||
## different sizes of offsets.
|
||||
## This also checks that attributes in the units which use the DW_FORM_strx form
|
||||
## are dumped correctly.
|
||||
|
||||
# RUN: llvm-mc -triple x86_64 %s -filetype=obj -o - | \
|
||||
# RUN: llvm-dwarfdump -v - | \
|
||||
# RUN: FileCheck %s
|
||||
|
||||
# CHECK: .debug_info.dwo contents:
|
||||
# CHECK: Compile Unit:
|
||||
# CHECK: DW_TAG_compile_unit [1]
|
||||
# CHECK-NEXT: DW_AT_producer [DW_FORM_strx] (indexed (00000000) string = "CU0 Producer")
|
||||
# CHECK-NEXT: DW_AT_name [DW_FORM_strx] (indexed (00000001) string = "CU0 Name")
|
||||
# CHECK: Compile Unit:
|
||||
# CHECK: DW_TAG_compile_unit [1]
|
||||
# CHECK-NEXT: DW_AT_producer [DW_FORM_strx] (indexed (00000000) string = "CU1 Producer")
|
||||
# CHECK-NEXT: DW_AT_name [DW_FORM_strx] (indexed (00000001) string = "CU1 Name")
|
||||
|
||||
# CHECK: .debug_str.dwo contents:
|
||||
# CHECK-NEXT: 0x00000000: "CU0 Producer"
|
||||
# CHECK-NEXT: 0x0000000d: "CU0 Name"
|
||||
# CHECK-NEXT: 0x00000016: "CU1 Producer"
|
||||
# CHECK-NEXT: 0x00000023: "CU1 Name"
|
||||
|
||||
# CHECK: .debug_str_offsets.dwo contents:
|
||||
# CHECK-NEXT: 0x00000000: Contribution size = 8, Format = DWARF32, Version = 4
|
||||
# CHECK-NEXT: 0x00000000: 00000000 "CU0 Producer"
|
||||
# CHECK-NEXT: 0x00000004: 0000000d "CU0 Name"
|
||||
# CHECK-NEXT: 0x00000008: Contribution size = 16, Format = DWARF64, Version = 4
|
||||
# CHECK-NEXT: 0x00000008: 00000016 "CU1 Producer"
|
||||
# CHECK-NEXT: 0x00000010: 00000023 "CU1 Name"
|
||||
|
||||
.section .debug_str.dwo, "MSe", @progbits, 1
|
||||
.LStr0:
|
||||
.asciz "CU0 Producer"
|
||||
.LStr1:
|
||||
.asciz "CU0 Name"
|
||||
.LStr2:
|
||||
.asciz "CU1 Producer"
|
||||
.LStr3:
|
||||
.asciz "CU1 Name"
|
||||
|
||||
.section .debug_str_offsets.dwo, "e", @progbits
|
||||
## The contribution of CU0 (DWARF32)
|
||||
.LSO0:
|
||||
.long .LStr0-.debug_str.dwo # 0: "CU0 Producer"
|
||||
.long .LStr1-.debug_str.dwo # 1: "CU0 Name"
|
||||
.LSO0End:
|
||||
## The contribution of CU1 (DWARF64)
|
||||
.LSO1:
|
||||
.quad .LStr2-.debug_str.dwo # 0: "CU1 Producer"
|
||||
.quad .LStr3-.debug_str.dwo # 1: "CU1 Name"
|
||||
.LSO1End:
|
||||
|
||||
.section .debug_abbrev.dwo, "e", @progbits
|
||||
## For simplicity and to make the test shorter, both compilation units share
|
||||
## the same abbreviations table.
|
||||
.LAbbr:
|
||||
.uleb128 0x01 # Abbrev code
|
||||
.uleb128 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.uleb128 0x25 # DW_AT_producer
|
||||
.uleb128 0x1a # DW_FORM_strx
|
||||
.uleb128 0x03 # DW_AT_name
|
||||
.uleb128 0x1a # DW_FORM_strx
|
||||
.uleb128 0x2131 # DW_AT_GNU_dwo_id
|
||||
.uleb128 0x07 # DW_FORM_data8
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
.LAbbrEnd:
|
||||
|
||||
.section .debug_info.dwo, "e", @progbits
|
||||
## CU0 uses the 32-bit DWARF format.
|
||||
.LCU0:
|
||||
.long .LCU0End-.LCU0Ver # Length
|
||||
.LCU0Ver:
|
||||
.short 4 # Version
|
||||
.long 0 # Abbrev. offset
|
||||
.byte 8 # Address size
|
||||
.uleb128 1 # Abbrev [1] DW_TAG_compile_unit
|
||||
.uleb128 0 # DW_AT_producer ("CU0 Producer")
|
||||
.uleb128 1 # DW_AT_name ("CU0 Name")
|
||||
.quad 0x1100001122222222 # DW_AT_GNU_dwo_id
|
||||
.LCU0End:
|
||||
## CU1 uses the 64-bit DWARF format.
|
||||
.LCU1:
|
||||
.long 0xffffffff # DWARF64 mark
|
||||
.quad .LCU1End-.LCU1Ver # Length
|
||||
.LCU1Ver:
|
||||
.short 4 # Version
|
||||
.quad 0 # Abbrev. offset
|
||||
.byte 8 # Address size
|
||||
.uleb128 1 # Abbrev [1] DW_TAG_compile_unit
|
||||
.uleb128 0 # DW_AT_producer ("CU1 Producer")
|
||||
.uleb128 1 # DW_AT_name ("CU1 Name")
|
||||
.quad 0x1100001133333333 # DW_AT_GNU_dwo_id
|
||||
.LCU1End:
|
||||
|
||||
.section .debug_cu_index, "", @progbits
|
||||
## Header:
|
||||
.long 2 # Version
|
||||
.long 3 # Section count
|
||||
.long 2 # Unit count
|
||||
.long 4 # Slot count
|
||||
## Hash Table of Signatures:
|
||||
.quad 0
|
||||
.quad 0
|
||||
.quad 0x1100001122222222 # DWO Id of CU0
|
||||
.quad 0x1100001133333333 # DWO Id of CU1
|
||||
## Parallel Table of Indexes:
|
||||
.long 0
|
||||
.long 0
|
||||
.long 1
|
||||
.long 2
|
||||
## Table of Section Offsets:
|
||||
## Row 0:
|
||||
.long 1 # DW_SECT_INFO
|
||||
.long 3 # DW_SECT_ABBREV
|
||||
.long 6 # DW_SECT_STR_OFFSETS
|
||||
## Row 1, offsets of contributions of CU0:
|
||||
.long .LCU0-.debug_info.dwo
|
||||
.long .LAbbr-.debug_abbrev.dwo
|
||||
.long .LSO0-.debug_str_offsets.dwo
|
||||
## Row 2, offsets of contributions of CU1:
|
||||
.long .LCU1-.debug_info.dwo
|
||||
.long .LAbbr-.debug_abbrev.dwo
|
||||
.long .LSO1-.debug_str_offsets.dwo
|
||||
## Table of Section Sizes:
|
||||
## Row 1, sizes of contributions of CU0:
|
||||
.long .LCU0End-.LCU0
|
||||
.long .LAbbrEnd-.LAbbr
|
||||
.long .LSO0End-.LSO0
|
||||
## Row 2, sizes of contributions of CU1:
|
||||
.long .LCU1End-.LCU1
|
||||
.long .LAbbrEnd-.LAbbr
|
||||
.long .LSO1End-.LSO1
|
Loading…
x
Reference in New Issue
Block a user