mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 07:31:53 +00:00
[llvm-dwp] Support debug_tu_index
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254827 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8893466777
commit
543e02b438
@ -118,6 +118,7 @@ protected:
|
||||
|
||||
// These are for Fission DWP files.
|
||||
MCSection *DwarfCUIndexSection;
|
||||
MCSection *DwarfTUIndexSection;
|
||||
|
||||
/// Section for newer gnu pubnames.
|
||||
MCSection *DwarfGnuPubNamesSection;
|
||||
@ -266,6 +267,7 @@ public:
|
||||
MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; }
|
||||
MCSection *getDwarfAddrSection() const { return DwarfAddrSection; }
|
||||
MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; }
|
||||
MCSection *getDwarfTUIndexSection() const { return DwarfTUIndexSection; }
|
||||
|
||||
MCSection *getCOFFDebugSymbolsSection() const {
|
||||
return COFFDebugSymbolsSection;
|
||||
|
@ -262,6 +262,9 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) {
|
||||
DwarfCUIndexSection =
|
||||
Ctx->getMachOSection("__DWARF", "__debug_cu_index", MachO::S_ATTR_DEBUG,
|
||||
SectionKind::getMetadata());
|
||||
DwarfTUIndexSection =
|
||||
Ctx->getMachOSection("__DWARF", "__debug_tu_index", MachO::S_ATTR_DEBUG,
|
||||
SectionKind::getMetadata());
|
||||
StackMapSection = Ctx->getMachOSection("__LLVM_STACKMAPS", "__llvm_stackmaps",
|
||||
0, SectionKind::getMetadata());
|
||||
|
||||
@ -537,6 +540,8 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
|
||||
// DWP Sections
|
||||
DwarfCUIndexSection =
|
||||
Ctx->getELFSection(".debug_cu_index", ELF::SHT_PROGBITS, 0);
|
||||
DwarfTUIndexSection =
|
||||
Ctx->getELFSection(".debug_tu_index", ELF::SHT_PROGBITS, 0);
|
||||
|
||||
StackMapSection =
|
||||
Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
|
||||
@ -725,6 +730,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(Triple T) {
|
||||
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
|
||||
COFF::IMAGE_SCN_MEM_READ,
|
||||
SectionKind::getMetadata());
|
||||
DwarfTUIndexSection = Ctx->getCOFFSection(
|
||||
".debug_tu_index",
|
||||
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
|
||||
COFF::IMAGE_SCN_MEM_READ,
|
||||
SectionKind::getMetadata());
|
||||
DwarfAccelNamesSection = Ctx->getCOFFSection(
|
||||
".apple_names",
|
||||
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
|
||||
|
Binary file not shown.
Binary file not shown.
@ -13,48 +13,73 @@ b.cpp:
|
||||
void b(bar) {
|
||||
}
|
||||
|
||||
CHECK: .debug_abbrev.dwo contents:
|
||||
CHECK: Abbrev table for offset: 0x00000000
|
||||
CHECK-LABEL: .debug_abbrev.dwo contents:
|
||||
CHECK-LABEL: Abbrev table for offset:
|
||||
CHECK: 0x0000[[AAOFF:.*]]
|
||||
CHECK: DW_TAG_compile_unit
|
||||
CHECK: DW_TAG_variable
|
||||
CHECK: DW_TAG_structure_type
|
||||
CHECK: Abbrev table for offset: 0x00000031
|
||||
CHECK-LABEL: Abbrev table for offset:
|
||||
CHECK: 0x0000[[BAOFF:.*]]
|
||||
CHECK: DW_TAG_compile_unit
|
||||
CHECK: DW_TAG_structure_type
|
||||
CHECK: DW_TAG_subprogram
|
||||
CHECK: DW_TAG_formal_parameter
|
||||
|
||||
CHECK: .debug_info.dwo contents:
|
||||
CHECK: 0x00000000: Compile Unit: length = 0x00000025 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000029)
|
||||
CHECK: [[AOFF:0x[0-9a-f]*]]:
|
||||
CHECK-LABEL: Compile Unit: length = 0x00000029 version = 0x0004 abbr_offset =
|
||||
CHECK: 0x[[AAOFF]] addr_size = 0x08 (next unit at [[BOFF:.*]])
|
||||
CHECK: DW_TAG_compile_unit
|
||||
CHECK: DW_AT_name {{.*}} "a.cpp"
|
||||
CHECK: DW_AT_GNU_dwo_id {{.*}} ([[DWOA:.*]])
|
||||
CHECK: DW_TAG_variable
|
||||
CHECK: DW_AT_name {{.*}} "a"
|
||||
CHECK: DW_TAG_structure_type
|
||||
CHECK: DW_AT_name {{.*}} "foo"
|
||||
CHECK: DW_AT_signature {{.*}} ([[FOOSIG:.*]])
|
||||
|
||||
CHECK: 0x00000029: Compile Unit: length = 0x00000031 version = 0x0004 abbr_offset = 0x0031 addr_size = 0x08 (next unit at 0x0000005e)
|
||||
CHECK: [[BOFF]]:
|
||||
CHECK-LABEL: Compile Unit: length = 0x00000035 version = 0x0004 abbr_offset =
|
||||
CHECK: 0x[[BAOFF]] addr_size = 0x08 (next unit at [[XOFF:.*]])
|
||||
CHECK: DW_AT_name {{.*}} "b.cpp"
|
||||
CHECK: DW_AT_GNU_dwo_id {{.*}} ([[DWOB:.*]])
|
||||
CHECK: DW_TAG_structure_type
|
||||
CHECK: DW_AT_name {{.*}} "bar"
|
||||
CHECK: DW_AT_signature {{.*}} ([[BARSIG:.*]])
|
||||
CHECK: DW_TAG_subprogram
|
||||
CHECK: DW_AT_name {{.*}} "b"
|
||||
CHECK: DW_TAG_formal_parameter
|
||||
|
||||
CHECK: .debug_cu_index contents:
|
||||
CHECK: Index Signature INFO ABBREV LINE STR_OFFSETS
|
||||
CHECK: 3 [[DWOA]] [0x00000000, 0x00000029) [0x00000000, 0x00000031) [0x00000000, 0x00000011) [0x00000000, 0x00000010)
|
||||
CHECK: 4 [[DWOB]] [0x00000029, 0x0000005e) [0x00000031, 0x00000075) [0x00000011, 0x00000022) [0x00000010, 0x00000024)
|
||||
CHECK-LABEL: .debug_types.dwo contents:
|
||||
CHECK: [[FOOUOFF:0x[0-9a-f]*]]:
|
||||
CHECK-LABEL: Type Unit: length = 0x00000020 version = 0x0004 abbr_offset =
|
||||
CHECK: 0x[[AAOFF]] addr_size = 0x08 type_signature = [[FOOSIG]] type_offset = 0x[[FOOOFF:.*]] (next unit at [[BARUOFF:.*]])
|
||||
CHECK: DW_TAG_type_unit
|
||||
CHECK: [[FOOOFF]]: DW_TAG_structure_type
|
||||
CHECK: DW_AT_name {{.*}} "foo"
|
||||
CHECK: [[BARUOFF]]:
|
||||
CHECK-LABEL: Type Unit: length = 0x00000020 version = 0x0004 abbr_offset =
|
||||
CHECK: 0x[[BAOFF]] addr_size = 0x08 type_signature = [[BARSIG]] type_offset = 0x001e (next unit at [[XUOFF:.*]])
|
||||
CHECK: DW_TAG_type_unit
|
||||
CHECK: 0x00000042: DW_TAG_structure_type
|
||||
CHECK: DW_AT_name {{.*}} "bar"
|
||||
|
||||
CHECK: .debug_str.dwo contents:
|
||||
CHECK-LABEL: .debug_cu_index contents:
|
||||
CHECK: Index Signature INFO ABBREV LINE STR_OFFSETS
|
||||
CHECK: 1 [[DWOA]] {{\[}}[[AOFF]], [[BOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000000, 0x0000001a) [0x00000000, 0x00000010)
|
||||
CHECK: 3 [[DWOB]] {{\[}}[[BOFF]], [[XOFF]]) [0x0000[[BAOFF]], 0x00000099) [0x0000001a, 0x00000034) [0x00000010, 0x00000024)
|
||||
|
||||
CHECK-LABEL: .debug_tu_index contents:
|
||||
CHECK: Index Signature TYPES ABBREV LINE STR_OFFSETS
|
||||
CHECK: 1 [[FOOSIG]] {{\[}}[[FOOUOFF]], [[BARUOFF]]) [0x0000[[AAOFF]], 0x0000[[BAOFF]]) [0x00000000, 0x0000001a) [0x00000000, 0x00000010)
|
||||
CHECK: 4 [[BARSIG]] {{\[}}[[BARUOFF]], [[XUOFF]]) [0x0000[[BAOFF]], 0x00000099) [0x0000001a, 0x00000034) [0x00000010, 0x00000024)
|
||||
|
||||
CHECK-LABEL: .debug_str.dwo contents:
|
||||
CHECK: "clang version
|
||||
CHECK: 0x[[ACPP:.*]]: "a.cpp"
|
||||
CHECK-NOT: "clang version
|
||||
CHECK: 0x[[BCPP:.*]]: "b.cpp"
|
||||
|
||||
CHECK: .debug_str_offsets.dwo contents:
|
||||
CHECK-LABEL: .debug_str_offsets.dwo contents:
|
||||
CHECK: : 00000000
|
||||
CHECK: : [[ACPP]]
|
||||
CHECK: : 00000000
|
||||
|
@ -130,6 +130,90 @@ static uint64_t getCUSignature(StringRef Abbrev, StringRef Info) {
|
||||
return InfoData.getU64(&Offset);
|
||||
}
|
||||
|
||||
struct UnitIndexEntry {
|
||||
uint64_t Signature;
|
||||
DWARFUnitIndex::Entry::SectionContribution Contributions[8];
|
||||
};
|
||||
|
||||
static void addAllTypes(std::vector<UnitIndexEntry> &TypeIndexEntries,
|
||||
uint32_t OutTypesOffset, StringRef Types,
|
||||
const UnitIndexEntry &CUEntry) {
|
||||
uint32_t Offset = 0;
|
||||
DataExtractor Data(Types, true, 0);
|
||||
while (Data.isValidOffset(Offset)) {
|
||||
TypeIndexEntries.push_back(CUEntry);
|
||||
auto &Entry = TypeIndexEntries.back();
|
||||
// Zero out the debug_info contribution
|
||||
Entry.Contributions[0] = {};
|
||||
auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO];
|
||||
C.Offset = OutTypesOffset + Offset;
|
||||
auto PrevOffset = Offset;
|
||||
// Length of the unit, including the 4 byte length field.
|
||||
C.Length = Data.getU32(&Offset) + 4;
|
||||
|
||||
Data.getU16(&Offset); // Version
|
||||
Data.getU32(&Offset); // Abbrev offset
|
||||
Data.getU8(&Offset); // Address size
|
||||
Entry.Signature = Data.getU64(&Offset);
|
||||
Offset = PrevOffset + C.Length;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
writeIndexTable(MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets,
|
||||
ArrayRef<UnitIndexEntry> IndexEntries,
|
||||
uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field) {
|
||||
for (const auto &E : IndexEntries)
|
||||
for (size_t i = 0; i != array_lengthof(E.Contributions); ++i)
|
||||
if (ContributionOffsets[i])
|
||||
Out.EmitIntValue(E.Contributions[i].*Field, 4);
|
||||
}
|
||||
|
||||
static void writeIndex(MCStreamer &Out, MCSection *Section,
|
||||
ArrayRef<unsigned> ContributionOffsets,
|
||||
ArrayRef<UnitIndexEntry> IndexEntries) {
|
||||
unsigned Columns = 0;
|
||||
for (auto &C : ContributionOffsets)
|
||||
if (C)
|
||||
++Columns;
|
||||
|
||||
std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2));
|
||||
uint64_t Mask = Buckets.size() - 1;
|
||||
for (size_t i = 0; i != IndexEntries.size(); ++i) {
|
||||
auto S = IndexEntries[i].Signature;
|
||||
auto H = S & Mask;
|
||||
while (Buckets[H])
|
||||
H += ((S >> 32) & Mask) | 1;
|
||||
Buckets[H] = i + 1;
|
||||
}
|
||||
|
||||
Out.SwitchSection(Section);
|
||||
Out.EmitIntValue(2, 4); // Version
|
||||
Out.EmitIntValue(Columns, 4); // Columns
|
||||
Out.EmitIntValue(IndexEntries.size(), 4); // Num Units
|
||||
Out.EmitIntValue(Buckets.size(), 4); // Num Buckets
|
||||
|
||||
// Write the signatures.
|
||||
for (const auto &I : Buckets)
|
||||
Out.EmitIntValue(I ? IndexEntries[I - 1].Signature : 0, 8);
|
||||
|
||||
// Write the indexes.
|
||||
for (const auto &I : Buckets)
|
||||
Out.EmitIntValue(I, 4);
|
||||
|
||||
// Write the column headers (which sections will appear in the table)
|
||||
for (size_t i = 0; i != ContributionOffsets.size(); ++i)
|
||||
if (ContributionOffsets[i])
|
||||
Out.EmitIntValue(i + DW_SECT_INFO, 4);
|
||||
|
||||
// Write the offsets.
|
||||
writeIndexTable(Out, ContributionOffsets, IndexEntries,
|
||||
&DWARFUnitIndex::Entry::SectionContribution::Offset);
|
||||
|
||||
// Write the lengths.
|
||||
writeIndexTable(Out, ContributionOffsets, IndexEntries,
|
||||
&DWARFUnitIndex::Entry::SectionContribution::Length);
|
||||
}
|
||||
static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
|
||||
const auto &MCOFI = *Out.getContext().getObjectFileInfo();
|
||||
MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
|
||||
@ -143,12 +227,8 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
|
||||
{"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
|
||||
{"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}};
|
||||
|
||||
struct UnitIndexEntry {
|
||||
uint64_t Signature;
|
||||
DWARFUnitIndex::Entry::SectionContribution Contributions[8];
|
||||
};
|
||||
|
||||
std::vector<UnitIndexEntry> IndexEntries;
|
||||
std::vector<UnitIndexEntry> TypeIndexEntries;
|
||||
|
||||
StringMap<uint32_t> Strings;
|
||||
uint32_t StringOffset = 0;
|
||||
@ -167,6 +247,9 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
|
||||
StringRef CurStrOffsetSection;
|
||||
StringRef InfoSection;
|
||||
StringRef AbbrevSection;
|
||||
StringRef TypesSection;
|
||||
|
||||
auto TypesOffset = ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO];
|
||||
|
||||
for (const auto &Section : ErrOrObj->getBinary()->sections()) {
|
||||
StringRef Name;
|
||||
@ -188,12 +271,18 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
|
||||
ContributionOffsets[Index] +=
|
||||
(CurEntry.Contributions[Index].Length = Contents.size());
|
||||
|
||||
if (Kind == DW_SECT_INFO) {
|
||||
assert(InfoSection.empty());
|
||||
switch (Kind) {
|
||||
case DW_SECT_INFO:
|
||||
InfoSection = Contents;
|
||||
} else if (Kind == DW_SECT_ABBREV) {
|
||||
assert(AbbrevSection.empty());
|
||||
break;
|
||||
case DW_SECT_ABBREV:
|
||||
AbbrevSection = Contents;
|
||||
break;
|
||||
case DW_SECT_TYPES:
|
||||
TypesSection = Contents;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,6 +300,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
|
||||
assert(!AbbrevSection.empty());
|
||||
assert(!InfoSection.empty());
|
||||
CurEntry.Signature = getCUSignature(AbbrevSection, InfoSection);
|
||||
addAllTypes(TypeIndexEntries, TypesOffset, TypesSection, CurEntry);
|
||||
|
||||
if (auto Err = writeStringsAndOffsets(Out, Strings, StringOffset,
|
||||
StrSection, StrOffsetSection,
|
||||
@ -218,52 +308,19 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
|
||||
return Err;
|
||||
}
|
||||
|
||||
unsigned Columns = 0;
|
||||
for (auto &C : ContributionOffsets)
|
||||
if (C)
|
||||
++Columns;
|
||||
// Lie about there being no info contributions so the TU index only includes
|
||||
// the type unit contribution
|
||||
ContributionOffsets[0] = 0;
|
||||
writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets,
|
||||
TypeIndexEntries);
|
||||
|
||||
std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2));
|
||||
uint64_t Mask = Buckets.size() - 1;
|
||||
for (size_t i = 0; i != IndexEntries.size(); ++i) {
|
||||
auto S = IndexEntries[i].Signature;
|
||||
auto H = S & Mask;
|
||||
while (Buckets[H])
|
||||
H += ((S >> 32) & Mask) | 1;
|
||||
Buckets[H] = i + 1;
|
||||
}
|
||||
// Lie about the type contribution
|
||||
ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO] = 0;
|
||||
// Unlie about the info contribution
|
||||
ContributionOffsets[0] = 1;
|
||||
|
||||
Out.SwitchSection(MCOFI.getDwarfCUIndexSection());
|
||||
Out.EmitIntValue(2, 4); // Version
|
||||
Out.EmitIntValue(Columns, 4); // Columns
|
||||
Out.EmitIntValue(IndexEntries.size(), 4); // Num Units
|
||||
// FIXME: This is not the right number of buckets for a real hash.
|
||||
Out.EmitIntValue(Buckets.size(), 4); // Num Buckets
|
||||
|
||||
// Write the signatures.
|
||||
for (const auto &I : Buckets)
|
||||
Out.EmitIntValue(I ? IndexEntries[I - 1].Signature : 0, 8);
|
||||
|
||||
// Write the indexes.
|
||||
for (const auto &I : Buckets)
|
||||
Out.EmitIntValue(I, 4);
|
||||
|
||||
// Write the column headers (which sections will appear in the table)
|
||||
for (size_t i = 0; i != array_lengthof(ContributionOffsets); ++i)
|
||||
if (ContributionOffsets[i])
|
||||
Out.EmitIntValue(i + DW_SECT_INFO, 4);
|
||||
|
||||
// Write the offsets.
|
||||
for (const auto &E : IndexEntries)
|
||||
for (size_t i = 0; i != array_lengthof(E.Contributions); ++i)
|
||||
if (ContributionOffsets[i])
|
||||
Out.EmitIntValue(E.Contributions[i].Offset, 4);
|
||||
|
||||
// Write the lengths.
|
||||
for (const auto &E : IndexEntries)
|
||||
for (size_t i = 0; i != array_lengthof(E.Contributions); ++i)
|
||||
if (ContributionOffsets[i])
|
||||
Out.EmitIntValue(E.Contributions[i].Length, 4);
|
||||
writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets,
|
||||
IndexEntries);
|
||||
|
||||
return std::error_code();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user