summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/DWARFAcceleratorTable.cpp110
-rw-r--r--llvm/lib/DebugInfo/DWARFAcceleratorTable.h38
-rw-r--r--llvm/lib/DebugInfo/DWARFContext.cpp33
-rw-r--r--llvm/lib/DebugInfo/DWARFContext.h12
5 files changed, 194 insertions, 0 deletions
diff --git a/llvm/lib/DebugInfo/CMakeLists.txt b/llvm/lib/DebugInfo/CMakeLists.txt
index 61a3fb066d1..81fc84d4a80 100644
--- a/llvm/lib/DebugInfo/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/CMakeLists.txt
@@ -1,6 +1,7 @@
add_llvm_library(LLVMDebugInfo
DIContext.cpp
DWARFAbbreviationDeclaration.cpp
+ DWARFAcceleratorTable.cpp
DWARFCompileUnit.cpp
DWARFContext.cpp
DWARFDebugAbbrev.cpp
diff --git a/llvm/lib/DebugInfo/DWARFAcceleratorTable.cpp b/llvm/lib/DebugInfo/DWARFAcceleratorTable.cpp
new file mode 100644
index 00000000000..c984769598f
--- /dev/null
+++ b/llvm/lib/DebugInfo/DWARFAcceleratorTable.cpp
@@ -0,0 +1,110 @@
+#include "DWARFAcceleratorTable.h"
+
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+bool DWARFAcceleratorTable::extract() {
+ uint32_t Offset = 0;
+
+ // Check that we can at least read the header.
+ if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength)+4))
+ return false;
+
+ Hdr.Magic = AccelSection.getU32(&Offset);
+ Hdr.Version = AccelSection.getU16(&Offset);
+ Hdr.HashFunction = AccelSection.getU16(&Offset);
+ Hdr.NumBuckets = AccelSection.getU32(&Offset);
+ Hdr.NumHashes = AccelSection.getU32(&Offset);
+ Hdr.HeaderDataLength = AccelSection.getU32(&Offset);
+
+ // Check that we can read all the hashes and offsets from the
+ // section (see SourceLevelDebugging.rst for the structure of the index).
+ if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
+ Hdr.NumBuckets*4 + Hdr.NumHashes*8))
+ return false;
+
+ HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
+ uint32_t NumAtoms = AccelSection.getU32(&Offset);
+
+ for (unsigned i = 0; i < NumAtoms; ++i) {
+ auto Atom = std::make_pair(AccelSection.getU16(&Offset),
+ DWARFFormValue(AccelSection.getU16(&Offset)));
+ HdrData.Atoms.push_back(Atom);
+ }
+
+ return true;
+}
+
+void DWARFAcceleratorTable::dump(raw_ostream &OS) {
+ // Dump the header.
+ OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n';
+ OS << "Version = " << format("0x%04x", Hdr.Version) << '\n';
+ OS << "Hash function = " << format("0x%08x", Hdr.HashFunction) << '\n';
+ OS << "Bucket count = " << Hdr.NumBuckets << '\n';
+ OS << "Hashes count = " << Hdr.NumHashes << '\n';
+ OS << "HeaderData length = " << Hdr.HeaderDataLength << '\n';
+ OS << "DIE offset base = " << HdrData.DIEOffsetBase << '\n';
+ OS << "Number of atoms = " << HdrData.Atoms.size() << '\n';
+
+ unsigned i = 0;
+ for (const auto &Atom: HdrData.Atoms) {
+ OS << format("Atom[%d] ", i++);
+ OS << " Type: " << dwarf::AtomTypeString(Atom.first);
+ OS << " Form: " << dwarf::FormEncodingString(Atom.second.getForm());
+ OS << "\n";
+ }
+
+ // Now go through the actual tables and dump them.
+ uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
+ unsigned HashesBase = Offset + Hdr.NumBuckets * 4;
+ unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4;
+
+ for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) {
+ unsigned Index;
+ Index = AccelSection.getU32(&Offset);
+
+ OS << format("Bucket[%d]\n", Bucket);
+ if (Index == UINT32_MAX) {
+ OS << " EMPTY\n";
+ continue;
+ }
+
+ for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) {
+ unsigned HashOffset = HashesBase + HashIdx*4;
+ unsigned OffsetsOffset = OffsetsBase + HashIdx*4;
+ uint32_t Hash = AccelSection.getU32(&HashOffset);
+
+ if (Hash % Hdr.NumBuckets != Bucket)
+ break;
+
+ unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
+ OS << format(" Hash = 0x%08x Offset = 0x%08x\n", Hash, DataOffset);
+ if (!AccelSection.isValidOffset(DataOffset)) {
+ OS << " Invalid section offset\n";
+ continue;
+ }
+ while (unsigned StringOffset = AccelSection.getU32(&DataOffset)) {
+ OS << format(" Name: %08x \"%s\"\n", StringOffset,
+ StringSection.getCStr(&StringOffset));
+ unsigned NumData = AccelSection.getU32(&DataOffset);
+ for (unsigned Data = 0; Data < NumData; ++Data) {
+ OS << format(" Data[%d] => ", Data);
+ unsigned i = 0;
+ for (auto &Atom : HdrData.Atoms) {
+ OS << format("{Atom[%d]: ", i++);
+ if (Atom.second.extractValue(AccelSection, &DataOffset, nullptr))
+ Atom.second.dump(OS, nullptr);
+ else
+ OS << "Error extracting the value";
+ OS << "} ";
+ }
+ OS << '\n';
+ }
+ }
+ }
+ }
+}
+}
diff --git a/llvm/lib/DebugInfo/DWARFAcceleratorTable.h b/llvm/lib/DebugInfo/DWARFAcceleratorTable.h
new file mode 100644
index 00000000000..bb25917b47d
--- /dev/null
+++ b/llvm/lib/DebugInfo/DWARFAcceleratorTable.h
@@ -0,0 +1,38 @@
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/DWARFFormValue.h"
+
+#include <cstdint>
+
+namespace llvm {
+
+class DWARFAcceleratorTable {
+
+ struct Header {
+ uint32_t Magic;
+ uint16_t Version;
+ uint16_t HashFunction;
+ uint32_t NumBuckets;
+ uint32_t NumHashes;
+ uint32_t HeaderDataLength;
+ };
+
+ struct HeaderData {
+ typedef uint16_t AtomType;
+ uint32_t DIEOffsetBase;
+ SmallVector<std::pair<AtomType, DWARFFormValue>, 1> Atoms;
+ };
+
+ struct Header Hdr;
+ struct HeaderData HdrData;
+ DataExtractor AccelSection;
+ DataExtractor StringSection;
+public:
+ DWARFAcceleratorTable(DataExtractor AccelSection, DataExtractor StringSection)
+ : AccelSection(AccelSection), StringSection(StringSection) {}
+
+ bool extract();
+ void dump(raw_ostream &OS);
+};
+
+}
diff --git a/llvm/lib/DebugInfo/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARFContext.cpp
index aa86f6aac03..845718d195d 100644
--- a/llvm/lib/DebugInfo/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARFContext.cpp
@@ -9,6 +9,7 @@
#include "DWARFContext.h"
#include "DWARFDebugArangeSet.h"
+#include "DWARFAcceleratorTable.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
@@ -59,6 +60,17 @@ static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
}
}
+static void dumpAccelSection(raw_ostream &OS, StringRef Name, StringRef Data,
+ StringRef StringSection, bool LittleEndian) {
+ DataExtractor AccelSection(Data, LittleEndian, 0);
+ DataExtractor StrData(StringSection, LittleEndian, 0);
+ OS << "\n." << Name << " contents:\n";
+ DWARFAcceleratorTable Accel(AccelSection, StrData);
+ if (!Accel.extract())
+ return;
+ Accel.dump(OS);
+}
+
void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
OS << ".debug_abbrev contents:\n";
@@ -218,6 +230,22 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
}
}
+
+ if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
+ dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
+ getStringSection(), isLittleEndian());
+
+ if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
+ dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
+ getStringSection(), isLittleEndian());
+
+ if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
+ dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
+ getStringSection(), isLittleEndian());
+
+ if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
+ dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
+ getStringSection(), isLittleEndian());
}
const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
@@ -565,6 +593,11 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj)
.Case("debug_str.dwo", &StringDWOSection)
.Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
.Case("debug_addr", &AddrSection)
+ .Case("apple_names", &AppleNamesSection)
+ .Case("apple_types", &AppleTypesSection)
+ .Case("apple_namespaces", &AppleNamespacesSection)
+ .Case("apple_namespac", &AppleNamespacesSection)
+ .Case("apple_objc", &AppleObjCSection)
// Any more debug info sections go here.
.Default(nullptr);
if (SectionData) {
diff --git a/llvm/lib/DebugInfo/DWARFContext.h b/llvm/lib/DebugInfo/DWARFContext.h
index c4586b0d4c1..926f7c39bd3 100644
--- a/llvm/lib/DebugInfo/DWARFContext.h
+++ b/llvm/lib/DebugInfo/DWARFContext.h
@@ -192,6 +192,10 @@ public:
virtual StringRef getStringOffsetDWOSection() = 0;
virtual StringRef getRangeDWOSection() = 0;
virtual StringRef getAddrSection() = 0;
+ virtual StringRef getAppleNamesSection() = 0;
+ virtual StringRef getAppleTypesSection() = 0;
+ virtual StringRef getAppleNamespacesSection() = 0;
+ virtual StringRef getAppleObjCSection() = 0;
static bool isSupportedVersion(unsigned version) {
return version == 2 || version == 3 || version == 4;
@@ -236,6 +240,10 @@ class DWARFContextInMemory : public DWARFContext {
StringRef StringOffsetDWOSection;
StringRef RangeDWOSection;
StringRef AddrSection;
+ StringRef AppleNamesSection;
+ StringRef AppleTypesSection;
+ StringRef AppleNamespacesSection;
+ StringRef AppleObjCSection;
SmallVector<SmallString<32>, 4> UncompressedSections;
@@ -256,6 +264,10 @@ public:
StringRef getPubTypesSection() override { return PubTypesSection; }
StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; }
StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; }
+ StringRef getAppleNamesSection() override { return AppleNamesSection; }
+ StringRef getAppleTypesSection() override { return AppleTypesSection; }
+ StringRef getAppleNamespacesSection() override { return AppleNamespacesSection; }
+ StringRef getAppleObjCSection() override { return AppleObjCSection; }
// Sections for DWARF5 split dwarf proposal.
const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
OpenPOWER on IntegriCloud