137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===--- DWARFAcceleratorTable.cpp ----------------------------------------===// 237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// The LLVM Compiler Infrastructure 437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// This file is distributed under the University of Illinois Open Source 637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// License. See LICENSE.TXT for details. 737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===// 937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" 1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Dwarf.h" 1237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Format.h" 1337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/raw_ostream.h" 1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesnamespace llvm { 1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool DWARFAcceleratorTable::extract() { 1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t Offset = 0; 1937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 2037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Check that we can at least read the header. 2137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength)+4)) 2237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 2337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 2437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Hdr.Magic = AccelSection.getU32(&Offset); 2537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Hdr.Version = AccelSection.getU16(&Offset); 2637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Hdr.HashFunction = AccelSection.getU16(&Offset); 2737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Hdr.NumBuckets = AccelSection.getU32(&Offset); 2837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Hdr.NumHashes = AccelSection.getU32(&Offset); 2937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Hdr.HeaderDataLength = AccelSection.getU32(&Offset); 3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 3137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Check that we can read all the hashes and offsets from the 3237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // section (see SourceLevelDebugging.rst for the structure of the index). 3337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength + 3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Hdr.NumBuckets*4 + Hdr.NumHashes*8)) 3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 3737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines HdrData.DIEOffsetBase = AccelSection.getU32(&Offset); 3837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t NumAtoms = AccelSection.getU32(&Offset); 3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (unsigned i = 0; i < NumAtoms; ++i) { 4137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint16_t AtomType = AccelSection.getU16(&Offset); 4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint16_t AtomForm = AccelSection.getU16(&Offset); 4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm)); 4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return true; 4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid DWARFAcceleratorTable::dump(raw_ostream &OS) const { 5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Dump the header. 5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n' 5237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "Version = " << format("0x%04x", Hdr.Version) << '\n' 5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "Hash function = " << format("0x%08x", Hdr.HashFunction) << '\n' 5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "Bucket count = " << Hdr.NumBuckets << '\n' 5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "Hashes count = " << Hdr.NumHashes << '\n' 5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "HeaderData length = " << Hdr.HeaderDataLength << '\n' 5737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "DIE offset base = " << HdrData.DIEOffsetBase << '\n' 5837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "Number of atoms = " << HdrData.Atoms.size() << '\n'; 5937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned i = 0; 6137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallVector<DWARFFormValue, 3> AtomForms; 6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &Atom: HdrData.Atoms) { 6337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << format("Atom[%d] Type: ", i++); 6437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (const char *TypeString = dwarf::AtomTypeString(Atom.first)) 6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << TypeString; 6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << format("DW_ATOM_Unknown_0x%x", Atom.first); 6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << " Form: "; 6937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (const char *FormString = dwarf::FormEncodingString(Atom.second)) 7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << FormString; 7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << format("DW_FORM_Unknown_0x%x", Atom.second); 7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << '\n'; 7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AtomForms.push_back(DWARFFormValue(Atom.second)); 7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Now go through the actual tables and dump them. 7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength; 7937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned HashesBase = Offset + Hdr.NumBuckets * 4; 8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4; 8137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 8237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) { 8337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned Index = AccelSection.getU32(&Offset); 8437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << format("Bucket[%d]\n", Bucket); 8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Index == UINT32_MAX) { 8737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << " EMPTY\n"; 8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; 8937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 9037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) { 9237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned HashOffset = HashesBase + HashIdx*4; 9337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned OffsetsOffset = OffsetsBase + HashIdx*4; 9437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t Hash = AccelSection.getU32(&HashOffset); 9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Hash % Hdr.NumBuckets != Bucket) 9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 9837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned DataOffset = AccelSection.getU32(&OffsetsOffset); 10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << format(" Hash = 0x%08x Offset = 0x%08x\n", Hash, DataOffset); 10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!AccelSection.isValidOffset(DataOffset)) { 10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << " Invalid section offset\n"; 10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; 10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines while (AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) { 10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned StringOffset = AccelSection.getU32(&DataOffset); 10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RelocAddrMap::const_iterator Reloc = Relocs.find(DataOffset-4); 10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Reloc != Relocs.end()) 10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringOffset += Reloc->second.second; 11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!StringOffset) 11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << format(" Name: %08x \"%s\"\n", StringOffset, 11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringSection.getCStr(&StringOffset)); 11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned NumData = AccelSection.getU32(&DataOffset); 11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (unsigned Data = 0; Data < NumData; ++Data) { 11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << format(" Data[%d] => ", Data); 11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned i = 0; 11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto &Atom : AtomForms) { 11937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << format("{Atom[%d]: ", i++); 12037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Atom.extractValue(AccelSection, &DataOffset, nullptr)) 12137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Atom.dump(OS, nullptr); 12237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 12337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << "Error extracting the value"; 12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << "} "; 12537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 12637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OS << '\n'; 12737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 12837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 12937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 13037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 13237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 133