summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h11
-rw-r--r--llvm/include/llvm/MC/MCObjectFileInfo.h4
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp16
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp12
-rw-r--r--llvm/lib/MC/MCObjectFileInfo.cpp12
-rw-r--r--llvm/test/tools/llvm-dwp/X86/simple.test13
-rw-r--r--llvm/tools/llvm-dwp/llvm-dwp.cpp103
7 files changed, 128 insertions, 43 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
index 83da6fef441..a85c2f9f0a2 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
@@ -41,12 +41,15 @@ class DWARFUnitIndex {
public:
class Entry {
- const DWARFUnitIndex *Index;
- uint64_t Signature;
+ public:
struct SectionContribution {
uint32_t Offset;
uint32_t Length;
};
+
+ private:
+ const DWARFUnitIndex *Index;
+ uint64_t Signature;
std::unique_ptr<SectionContribution[]> Contributions;
friend class DWARFUnitIndex;
@@ -58,14 +61,18 @@ public:
private:
struct Header Header;
+ DWARFSectionKind InfoColumnKind;
int InfoColumn = -1;
std::unique_ptr<DWARFSectionKind[]> ColumnKinds;
std::unique_ptr<Entry[]> Rows;
static StringRef getColumnHeader(DWARFSectionKind DS);
+ bool parseImpl(DataExtractor IndexData);
public:
bool parse(DataExtractor IndexData);
+ DWARFUnitIndex(DWARFSectionKind InfoColumnKind)
+ : InfoColumnKind(InfoColumnKind) {}
void dump(raw_ostream &OS) const;
const Entry *getFromOffset(uint32_t Offset) const;
};
diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index eaca3833dc8..388a208fb4a 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -116,6 +116,9 @@ protected:
MCSection *DwarfStrOffDWOSection;
MCSection *DwarfAddrSection;
+ // These are for Fission DWP files.
+ MCSection *DwarfCUIndexSection;
+
/// Section for newer gnu pubnames.
MCSection *DwarfGnuPubNamesSection;
/// Section for newer gnu pubtypes.
@@ -262,6 +265,7 @@ public:
MCSection *getDwarfLocDWOSection() const { return DwarfLocDWOSection; }
MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; }
MCSection *getDwarfAddrSection() const { return DwarfAddrSection; }
+ MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; }
MCSection *getCOFFDebugSymbolsSection() const {
return COFFDebugSymbolsSection;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 2165d353ba0..a4195b75c47 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -163,20 +163,12 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
if (DumpType == DIDT_All || DumpType == DIDT_CUIndex) {
OS << "\n.debug_cu_index contents:\n";
- DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(),
- savedAddressByteSize);
- DWARFUnitIndex CUIndex;
- if (CUIndex.parse(CUIndexData))
- CUIndex.dump(OS);
+ getCUIndex().dump(OS);
}
if (DumpType == DIDT_All || DumpType == DIDT_TUIndex) {
OS << "\n.debug_tu_index contents:\n";
- DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(),
- savedAddressByteSize);
- DWARFUnitIndex TUIndex;
- if (TUIndex.parse(TUIndexData))
- TUIndex.dump(OS);
+ getTUIndex().dump(OS);
}
if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
@@ -280,7 +272,7 @@ const DWARFUnitIndex &DWARFContext::getCUIndex() {
DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0);
- CUIndex = llvm::make_unique<DWARFUnitIndex>();
+ CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
CUIndex->parse(CUIndexData);
return *CUIndex;
}
@@ -291,7 +283,7 @@ const DWARFUnitIndex &DWARFContext::getTUIndex() {
DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0);
- TUIndex = llvm::make_unique<DWARFUnitIndex>();
+ TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
TUIndex->parse(TUIndexData);
return *TUIndex;
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
index baefed30f36..e8e7441d976 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
@@ -30,6 +30,13 @@ void DWARFUnitIndex::Header::dump(raw_ostream &OS) const {
}
bool DWARFUnitIndex::parse(DataExtractor IndexData) {
+ bool b = parseImpl(IndexData);
+ if (!b)
+ *this = DWARFUnitIndex(InfoColumnKind);
+ return b;
+}
+
+bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
uint32_t Offset = 0;
if (!Header.parse(IndexData, &Offset))
return false;
@@ -62,7 +69,7 @@ bool DWARFUnitIndex::parse(DataExtractor IndexData) {
// Read the Column Headers
for (unsigned i = 0; i != Header.NumColumns; ++i) {
ColumnKinds[i] = static_cast<DWARFSectionKind>(IndexData.getU32(&Offset));
- if (ColumnKinds[i] == DW_SECT_INFO || ColumnKinds[i] == DW_SECT_TYPES) {
+ if (ColumnKinds[i] == InfoColumnKind) {
if (InfoColumn != -1)
return false;
InfoColumn = i;
@@ -107,6 +114,9 @@ StringRef DWARFUnitIndex::getColumnHeader(DWARFSectionKind DS) {
}
void DWARFUnitIndex::dump(raw_ostream &OS) const {
+ if (!Header.NumBuckets)
+ return;
+
Header.dump(OS);
OS << "Index Signature ";
for (unsigned i = 0; i != Header.NumColumns; ++i)
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 8b75457a246..41e28698b1c 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -259,6 +259,9 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) {
DwarfDebugInlineSection =
Ctx->getMachOSection("__DWARF", "__debug_inlined", MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
+ DwarfCUIndexSection =
+ Ctx->getMachOSection("__DWARF", "__debug_cu_index", MachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
StackMapSection = Ctx->getMachOSection("__LLVM_STACKMAPS", "__llvm_stackmaps",
0, SectionKind::getMetadata());
@@ -531,6 +534,10 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
DwarfAddrSection =
Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0, "addr_sec");
+ // DWP Sections
+ DwarfCUIndexSection =
+ Ctx->getELFSection(".debug_cu_index", ELF::SHT_PROGBITS, 0);
+
StackMapSection =
Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
@@ -713,6 +720,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata(), "addr_sec");
+ DwarfCUIndexSection = Ctx->getCOFFSection(
+ ".debug_cu_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 |
diff --git a/llvm/test/tools/llvm-dwp/X86/simple.test b/llvm/test/tools/llvm-dwp/X86/simple.test
index 754450f13f3..aa5ae40dc2b 100644
--- a/llvm/test/tools/llvm-dwp/X86/simple.test
+++ b/llvm/test/tools/llvm-dwp/X86/simple.test
@@ -33,12 +33,13 @@ CHECK: DW_AT_name {{.*}} "a"
CHECK: DW_TAG_structure_type
CHECK: DW_AT_name {{.*}} "foo"
-FIXME: Using cu_index, identify that abbr_offset is 0x0031, not 0x0000
-CHECK: 0x00000029: Compile Unit: length = 0x00000031 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x0000005e)
-FIXME: Using cu_index, use strings based on the right str index offset
-CHECK: DW_AT_name {{.*}} "a.cpp"
-FIXME: Using cu_index to find the right abbrevs at abbr_offset, this abbrevation should actually be structure_type
-CHECK: DW_TAG_variable
+CHECK: 0x00000029: Compile Unit: length = 0x00000031 version = 0x0004 abbr_offset = 0x0031 addr_size = 0x08 (next unit at 0x0000005e)
+CHECK: DW_AT_name {{.*}} "b.cpp"
+CHECK: DW_TAG_structure_type
+CHECK: DW_AT_name {{.*}} "bar"
+CHECK: DW_TAG_subprogram
+CHECK: DW_AT_name {{.*}} "b"
+CHECK: DW_TAG_formal_parameter
CHECK: .debug_cu_index contents:
FIXME: Emit and verify the cu_index contents
diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp
index 9ce37ec2cee..6617b0b23ae 100644
--- a/llvm/tools/llvm-dwp/llvm-dwp.cpp
+++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp
@@ -17,6 +17,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
#include <memory>
#include <list>
#include <unordered_set>
@@ -85,48 +86,106 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
const auto &MCOFI = *Out.getContext().getObjectFileInfo();
MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
- const StringMap<MCSection *> KnownSections = {
- {"debug_info.dwo", MCOFI.getDwarfInfoDWOSection()},
- {"debug_types.dwo", MCOFI.getDwarfTypesDWOSection()},
- {"debug_str_offsets.dwo", StrOffsetSection},
- {"debug_str.dwo", StrSection},
- {"debug_loc.dwo", MCOFI.getDwarfLocDWOSection()},
- {"debug_abbrev.dwo", MCOFI.getDwarfAbbrevDWOSection()}};
+ const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
+ {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
+ {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_TYPES}},
+ {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
+ {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
+ {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_LOC}},
+ {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}};
+
+ struct UnitIndexEntry {
+ uint64_t Signature;
+ DWARFUnitIndex::Entry::SectionContribution Contributions[8];
+ };
+
+ std::vector<UnitIndexEntry> IndexEntries;
StringMap<uint32_t> Strings;
uint32_t StringOffset = 0;
+ uint64_t UnitIndex = 0;
+ uint32_t ContributionOffsets[8] = {};
+
for (const auto &Input : Inputs) {
auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
if (!ErrOrObj)
return ErrOrObj.getError();
- const auto *Obj = ErrOrObj->getBinary();
+
+ IndexEntries.emplace_back();
+ UnitIndexEntry &CurEntry = IndexEntries.back();
+ CurEntry.Signature = UnitIndex++;
+
StringRef CurStrSection;
StringRef CurStrOffsetSection;
- for (const auto &Section : Obj->sections()) {
+
+ for (const auto &Section : ErrOrObj->getBinary()->sections()) {
StringRef Name;
if (std::error_code Err = Section.getName(Name))
return Err;
- if (MCSection *OutSection =
- KnownSections.lookup(Name.substr(Name.find_first_not_of("._")))) {
- StringRef Contents;
- if (auto Err = Section.getContents(Contents))
- return Err;
- if (OutSection == StrOffsetSection)
- CurStrOffsetSection = Contents;
- else if (OutSection == StrSection)
- CurStrSection = Contents;
- else {
- Out.SwitchSection(OutSection);
- Out.EmitBytes(Contents);
- }
+
+ auto SectionPair =
+ KnownSections.find(Name.substr(Name.find_first_not_of("._")));
+ if (SectionPair == KnownSections.end())
+ continue;
+
+ StringRef Contents;
+ if (auto Err = Section.getContents(Contents))
+ return Err;
+
+ if (DWARFSectionKind Kind = SectionPair->second.second) {
+ auto Index = Kind - DW_SECT_INFO;
+ CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
+ ContributionOffsets[Index] +=
+ (CurEntry.Contributions[Index].Length = Contents.size());
+ }
+
+ MCSection *OutSection = SectionPair->second.first;
+ if (OutSection == StrOffsetSection)
+ CurStrOffsetSection = Contents;
+ else if (OutSection == StrSection)
+ CurStrSection = Contents;
+ else {
+ Out.SwitchSection(OutSection);
+ Out.EmitBytes(Contents);
}
}
+
if (auto Err = writeStringsAndOffsets(Out, Strings, StringOffset,
StrSection, StrOffsetSection,
CurStrSection, CurStrOffsetSection))
return Err;
}
+
+ Out.SwitchSection(MCOFI.getDwarfCUIndexSection());
+ Out.EmitIntValue(2, 4); // Version
+ Out.EmitIntValue(8, 4); // Columns
+ Out.EmitIntValue(IndexEntries.size(), 4); // Num Units
+ // FIXME: This is not the right number of buckets for a real hash.
+ Out.EmitIntValue(IndexEntries.size(), 4); // Num Buckets
+
+ // Write the signatures.
+ for (const auto &E : IndexEntries)
+ Out.EmitIntValue(E.Signature, 8);
+
+ // Write the indexes.
+ for (size_t i = 0; i != IndexEntries.size(); ++i)
+ Out.EmitIntValue(i + 1, 4);
+
+ // Write the column headers (which sections will appear in the table)
+ for (size_t i = 1; i != 9; ++i)
+ Out.EmitIntValue(i, 4);
+
+ // Write the offsets.
+ for (const auto &E : IndexEntries)
+ for (const auto &C : E.Contributions)
+ Out.EmitIntValue(C.Offset, 4);
+
+ // Write the lengths.
+ for (const auto &E : IndexEntries)
+ for (const auto &C : E.Contributions)
+ Out.EmitIntValue(C.Length, 4);
+
return std::error_code();
}
OpenPOWER on IntegriCloud