mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-30 20:24:32 +00:00
Reapply "[dwarfdump] Add support for dumping accelerator tables."
This reverts commit r221842 which was a revert of r221836 and of the test parts of r221837. This new version fixes an UB bug pointed out by David (along with addressing some other review comments), makes some dumping more resilient to broken input data and forces the accelerator tables to be dumped in the tests where we use them (this decision is platform specific otherwise). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222003 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
116
lib/DebugInfo/DWARFAcceleratorTable.cpp
Normal file
116
lib/DebugInfo/DWARFAcceleratorTable.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#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) {
|
||||
uint16_t AtomType = AccelSection.getU16(&Offset);
|
||||
DWARFFormValue AtomForm(AccelSection.getU16(&Offset));
|
||||
HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DWARFAcceleratorTable::dump(raw_ostream &OS) {
|
||||
// Dump the header.
|
||||
OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n'
|
||||
<< "Version = " << format("0x%04x", Hdr.Version) << '\n'
|
||||
<< "Hash function = " << format("0x%08x", Hdr.HashFunction) << '\n'
|
||||
<< "Bucket count = " << Hdr.NumBuckets << '\n'
|
||||
<< "Hashes count = " << Hdr.NumHashes << '\n'
|
||||
<< "HeaderData length = " << Hdr.HeaderDataLength << '\n'
|
||||
<< "DIE offset base = " << HdrData.DIEOffsetBase << '\n'
|
||||
<< "Number of atoms = " << HdrData.Atoms.size() << '\n';
|
||||
|
||||
unsigned i = 0;
|
||||
for (const auto &Atom: HdrData.Atoms) {
|
||||
OS << format("Atom[%d] Type: ", i++);
|
||||
if (const char *TypeString = dwarf::AtomTypeString(Atom.first))
|
||||
OS << TypeString;
|
||||
else
|
||||
OS << format("DW_ATOM_Unknown_0x%x", Atom.first);
|
||||
OS << " Form: ";
|
||||
if (const char *FormString = dwarf::FormEncodingString(Atom.second.getForm()))
|
||||
OS << FormString;
|
||||
else
|
||||
OS << format("DW_FORM_Unknown_0x%x", 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 = 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';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user