Frederic Riss | 7c41c64 | 2014-11-20 16:21:06 +0000 | [diff] [blame] | 1 | //===--- DWARFAcceleratorTable.cpp ----------------------------------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
Zachary Turner | 82af943 | 2015-01-30 18:07:45 +0000 | [diff] [blame] | 10 | #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" |
Frederic Riss | e837ec2 | 2014-11-14 16:15:53 +0000 | [diff] [blame] | 11 | #include "llvm/Support/Dwarf.h" |
| 12 | #include "llvm/Support/Format.h" |
| 13 | #include "llvm/Support/raw_ostream.h" |
| 14 | |
| 15 | namespace llvm { |
| 16 | |
| 17 | bool DWARFAcceleratorTable::extract() { |
| 18 | uint32_t Offset = 0; |
| 19 | |
| 20 | // Check that we can at least read the header. |
| 21 | if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength)+4)) |
| 22 | return false; |
| 23 | |
| 24 | Hdr.Magic = AccelSection.getU32(&Offset); |
| 25 | Hdr.Version = AccelSection.getU16(&Offset); |
| 26 | Hdr.HashFunction = AccelSection.getU16(&Offset); |
| 27 | Hdr.NumBuckets = AccelSection.getU32(&Offset); |
| 28 | Hdr.NumHashes = AccelSection.getU32(&Offset); |
| 29 | Hdr.HeaderDataLength = AccelSection.getU32(&Offset); |
| 30 | |
| 31 | // Check that we can read all the hashes and offsets from the |
| 32 | // section (see SourceLevelDebugging.rst for the structure of the index). |
| 33 | if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength + |
| 34 | Hdr.NumBuckets*4 + Hdr.NumHashes*8)) |
| 35 | return false; |
| 36 | |
| 37 | HdrData.DIEOffsetBase = AccelSection.getU32(&Offset); |
| 38 | uint32_t NumAtoms = AccelSection.getU32(&Offset); |
| 39 | |
| 40 | for (unsigned i = 0; i < NumAtoms; ++i) { |
| 41 | uint16_t AtomType = AccelSection.getU16(&Offset); |
Frederic Riss | 77a0743 | 2014-11-20 16:21:11 +0000 | [diff] [blame] | 42 | uint16_t AtomForm = AccelSection.getU16(&Offset); |
Frederic Riss | e837ec2 | 2014-11-14 16:15:53 +0000 | [diff] [blame] | 43 | HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm)); |
| 44 | } |
| 45 | |
| 46 | return true; |
| 47 | } |
| 48 | |
Frederic Riss | 77a0743 | 2014-11-20 16:21:11 +0000 | [diff] [blame] | 49 | void DWARFAcceleratorTable::dump(raw_ostream &OS) const { |
Frederic Riss | e837ec2 | 2014-11-14 16:15:53 +0000 | [diff] [blame] | 50 | // Dump the header. |
| 51 | OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n' |
| 52 | << "Version = " << format("0x%04x", Hdr.Version) << '\n' |
| 53 | << "Hash function = " << format("0x%08x", Hdr.HashFunction) << '\n' |
| 54 | << "Bucket count = " << Hdr.NumBuckets << '\n' |
| 55 | << "Hashes count = " << Hdr.NumHashes << '\n' |
| 56 | << "HeaderData length = " << Hdr.HeaderDataLength << '\n' |
| 57 | << "DIE offset base = " << HdrData.DIEOffsetBase << '\n' |
| 58 | << "Number of atoms = " << HdrData.Atoms.size() << '\n'; |
| 59 | |
| 60 | unsigned i = 0; |
Frederic Riss | 77a0743 | 2014-11-20 16:21:11 +0000 | [diff] [blame] | 61 | SmallVector<DWARFFormValue, 3> AtomForms; |
Frederic Riss | e837ec2 | 2014-11-14 16:15:53 +0000 | [diff] [blame] | 62 | for (const auto &Atom: HdrData.Atoms) { |
| 63 | OS << format("Atom[%d] Type: ", i++); |
Mehdi Amini | 2bcac0f | 2016-10-05 01:04:02 +0000 | [diff] [blame^] | 64 | if (const char *TypeString = dwarf::AtomTypeString(Atom.first)) |
Frederic Riss | e837ec2 | 2014-11-14 16:15:53 +0000 | [diff] [blame] | 65 | OS << TypeString; |
| 66 | else |
| 67 | OS << format("DW_ATOM_Unknown_0x%x", Atom.first); |
| 68 | OS << " Form: "; |
Mehdi Amini | 2bcac0f | 2016-10-05 01:04:02 +0000 | [diff] [blame^] | 69 | if (const char *FormString = dwarf::FormEncodingString(Atom.second)) |
Frederic Riss | e837ec2 | 2014-11-14 16:15:53 +0000 | [diff] [blame] | 70 | OS << FormString; |
| 71 | else |
Frederic Riss | 77a0743 | 2014-11-20 16:21:11 +0000 | [diff] [blame] | 72 | OS << format("DW_FORM_Unknown_0x%x", Atom.second); |
Frederic Riss | e837ec2 | 2014-11-14 16:15:53 +0000 | [diff] [blame] | 73 | OS << '\n'; |
Frederic Riss | 77a0743 | 2014-11-20 16:21:11 +0000 | [diff] [blame] | 74 | AtomForms.push_back(DWARFFormValue(Atom.second)); |
Frederic Riss | e837ec2 | 2014-11-14 16:15:53 +0000 | [diff] [blame] | 75 | } |
| 76 | |
| 77 | // Now go through the actual tables and dump them. |
| 78 | uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength; |
| 79 | unsigned HashesBase = Offset + Hdr.NumBuckets * 4; |
| 80 | unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4; |
| 81 | |
| 82 | for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) { |
| 83 | unsigned Index = AccelSection.getU32(&Offset); |
| 84 | |
| 85 | OS << format("Bucket[%d]\n", Bucket); |
| 86 | if (Index == UINT32_MAX) { |
| 87 | OS << " EMPTY\n"; |
| 88 | continue; |
| 89 | } |
| 90 | |
| 91 | for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) { |
| 92 | unsigned HashOffset = HashesBase + HashIdx*4; |
| 93 | unsigned OffsetsOffset = OffsetsBase + HashIdx*4; |
| 94 | uint32_t Hash = AccelSection.getU32(&HashOffset); |
| 95 | |
| 96 | if (Hash % Hdr.NumBuckets != Bucket) |
| 97 | break; |
| 98 | |
| 99 | unsigned DataOffset = AccelSection.getU32(&OffsetsOffset); |
| 100 | OS << format(" Hash = 0x%08x Offset = 0x%08x\n", Hash, DataOffset); |
| 101 | if (!AccelSection.isValidOffset(DataOffset)) { |
| 102 | OS << " Invalid section offset\n"; |
| 103 | continue; |
| 104 | } |
Frederic Riss | 7c50047 | 2014-11-14 19:30:08 +0000 | [diff] [blame] | 105 | while (AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) { |
| 106 | unsigned StringOffset = AccelSection.getU32(&DataOffset); |
| 107 | RelocAddrMap::const_iterator Reloc = Relocs.find(DataOffset-4); |
| 108 | if (Reloc != Relocs.end()) |
| 109 | StringOffset += Reloc->second.second; |
| 110 | if (!StringOffset) |
| 111 | break; |
Frederic Riss | e837ec2 | 2014-11-14 16:15:53 +0000 | [diff] [blame] | 112 | OS << format(" Name: %08x \"%s\"\n", StringOffset, |
| 113 | StringSection.getCStr(&StringOffset)); |
| 114 | unsigned NumData = AccelSection.getU32(&DataOffset); |
| 115 | for (unsigned Data = 0; Data < NumData; ++Data) { |
| 116 | OS << format(" Data[%d] => ", Data); |
| 117 | unsigned i = 0; |
Frederic Riss | 77a0743 | 2014-11-20 16:21:11 +0000 | [diff] [blame] | 118 | for (auto &Atom : AtomForms) { |
Frederic Riss | e837ec2 | 2014-11-14 16:15:53 +0000 | [diff] [blame] | 119 | OS << format("{Atom[%d]: ", i++); |
Frederic Riss | 77a0743 | 2014-11-20 16:21:11 +0000 | [diff] [blame] | 120 | if (Atom.extractValue(AccelSection, &DataOffset, nullptr)) |
| 121 | Atom.dump(OS, nullptr); |
Frederic Riss | e837ec2 | 2014-11-14 16:15:53 +0000 | [diff] [blame] | 122 | else |
| 123 | OS << "Error extracting the value"; |
| 124 | OS << "} "; |
| 125 | } |
| 126 | OS << '\n'; |
| 127 | } |
| 128 | } |
| 129 | } |
| 130 | } |
| 131 | } |
Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 132 | } |