Skip to content

Commit

Permalink
[dwarfdump] Add support for dumping accelerator tables.
Browse files Browse the repository at this point in the history
The class used for the dump only allows to dump for the moment, but
it can (and will) be easily extended to support search also.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221836 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
fredriss committed Nov 12, 2014
1 parent 0275be3 commit 931e22f
Show file tree
Hide file tree
Showing 9 changed files with 359 additions and 1 deletion.
6 changes: 5 additions & 1 deletion include/llvm/DebugInfo/DIContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ enum DIDumpType {
DIDT_GnuPubtypes,
DIDT_Str,
DIDT_StrDwo,
DIDT_StrOffsetsDwo
DIDT_StrOffsetsDwo,
DIDT_AppleNames,
DIDT_AppleTypes,
DIDT_AppleNamespaces,
DIDT_AppleObjC
};

// In place of applying the relocations to the data we've read from disk we use
Expand Down
1 change: 1 addition & 0 deletions lib/DebugInfo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_llvm_library(LLVMDebugInfo
DIContext.cpp
DWARFAbbreviationDeclaration.cpp
DWARFAcceleratorTable.cpp
DWARFCompileUnit.cpp
DWARFContext.cpp
DWARFDebugAbbrev.cpp
Expand Down
110 changes: 110 additions & 0 deletions lib/DebugInfo/DWARFAcceleratorTable.cpp
Original file line number Diff line number Diff line change
@@ -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';
}
}
}
}
}
}
38 changes: 38 additions & 0 deletions lib/DebugInfo/DWARFAcceleratorTable.h
Original file line number Diff line number Diff line change
@@ -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);
};

}
33 changes: 33 additions & 0 deletions lib/DebugInfo/DWARFContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "DWARFContext.h"
#include "DWARFDebugArangeSet.h"
#include "DWARFAcceleratorTable.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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) {
Expand Down
12 changes: 12 additions & 0 deletions lib/DebugInfo/DWARFContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ class DWARFContext : public DIContext {
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;
Expand Down Expand Up @@ -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;

Expand All @@ -256,6 +264,10 @@ class DWARFContextInMemory : public DWARFContext {
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; }
Expand Down
2 changes: 2 additions & 0 deletions test/DebugInfo/Inputs/gmlt.ll
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
; CHECK: .debug_pubtypes contents:
; CHECK-NOT: Offset

; CHECK: .apple{{.*}} contents:

; Function Attrs: nounwind uwtable
define void @_Z2f1v() #0 {
entry:
Expand Down
Loading

0 comments on commit 931e22f

Please sign in to comment.