diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/DebugInfo/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARFAcceleratorTable.cpp | 110 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARFAcceleratorTable.h | 38 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARFContext.cpp | 33 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARFContext.h | 12 |
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; } |

