blob: a12f8adfafe5107fb174d3f5485003758f01637a [file] [log] [blame]
Eugene Zelenkoe94042c2017-02-27 23:43:14 +00001//===- DWARFAcceleratorTable.cpp ------------------------------------------===//
Frederic Riss7c41c642014-11-20 16:21:06 +00002//
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
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000010#include "llvm/ADT/SmallVector.h"
Zachary Turner82af9432015-01-30 18:07:45 +000011#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
George Rimarf8a96422017-04-21 09:12:18 +000012#include "llvm/DebugInfo/DWARF/DWARFContext.h"
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000013#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
14#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
Frederic Risse837ec22014-11-14 16:15:53 +000015#include "llvm/Support/Dwarf.h"
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000016#include "llvm/Support/Compiler.h"
Frederic Risse837ec22014-11-14 16:15:53 +000017#include "llvm/Support/Format.h"
18#include "llvm/Support/raw_ostream.h"
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000019#include <cstddef>
20#include <cstdint>
21#include <utility>
Frederic Risse837ec22014-11-14 16:15:53 +000022
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000023using namespace llvm;
Frederic Risse837ec22014-11-14 16:15:53 +000024
25bool DWARFAcceleratorTable::extract() {
26 uint32_t Offset = 0;
27
28 // Check that we can at least read the header.
29 if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength)+4))
30 return false;
31
32 Hdr.Magic = AccelSection.getU32(&Offset);
33 Hdr.Version = AccelSection.getU16(&Offset);
34 Hdr.HashFunction = AccelSection.getU16(&Offset);
35 Hdr.NumBuckets = AccelSection.getU32(&Offset);
36 Hdr.NumHashes = AccelSection.getU32(&Offset);
37 Hdr.HeaderDataLength = AccelSection.getU32(&Offset);
38
39 // Check that we can read all the hashes and offsets from the
40 // section (see SourceLevelDebugging.rst for the structure of the index).
41 if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
42 Hdr.NumBuckets*4 + Hdr.NumHashes*8))
43 return false;
44
45 HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
46 uint32_t NumAtoms = AccelSection.getU32(&Offset);
47
48 for (unsigned i = 0; i < NumAtoms; ++i) {
49 uint16_t AtomType = AccelSection.getU16(&Offset);
Greg Clayton6c273762016-10-27 16:32:04 +000050 auto AtomForm = static_cast<dwarf::Form>(AccelSection.getU16(&Offset));
Frederic Risse837ec22014-11-14 16:15:53 +000051 HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
52 }
53
54 return true;
55}
56
Matthias Braun8c209aa2017-01-28 02:02:38 +000057LLVM_DUMP_METHOD void DWARFAcceleratorTable::dump(raw_ostream &OS) const {
Frederic Risse837ec22014-11-14 16:15:53 +000058 // Dump the header.
59 OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n'
60 << "Version = " << format("0x%04x", Hdr.Version) << '\n'
61 << "Hash function = " << format("0x%08x", Hdr.HashFunction) << '\n'
62 << "Bucket count = " << Hdr.NumBuckets << '\n'
63 << "Hashes count = " << Hdr.NumHashes << '\n'
64 << "HeaderData length = " << Hdr.HeaderDataLength << '\n'
65 << "DIE offset base = " << HdrData.DIEOffsetBase << '\n'
66 << "Number of atoms = " << HdrData.Atoms.size() << '\n';
67
68 unsigned i = 0;
Frederic Riss77a07432014-11-20 16:21:11 +000069 SmallVector<DWARFFormValue, 3> AtomForms;
Frederic Risse837ec22014-11-14 16:15:53 +000070 for (const auto &Atom: HdrData.Atoms) {
71 OS << format("Atom[%d] Type: ", i++);
Mehdi Amini149f6ea2016-10-05 05:59:29 +000072 auto TypeString = dwarf::AtomTypeString(Atom.first);
73 if (!TypeString.empty())
Frederic Risse837ec22014-11-14 16:15:53 +000074 OS << TypeString;
75 else
76 OS << format("DW_ATOM_Unknown_0x%x", Atom.first);
77 OS << " Form: ";
Mehdi Amini149f6ea2016-10-05 05:59:29 +000078 auto FormString = dwarf::FormEncodingString(Atom.second);
79 if (!FormString.empty())
Frederic Risse837ec22014-11-14 16:15:53 +000080 OS << FormString;
81 else
Frederic Riss77a07432014-11-20 16:21:11 +000082 OS << format("DW_FORM_Unknown_0x%x", Atom.second);
Frederic Risse837ec22014-11-14 16:15:53 +000083 OS << '\n';
Frederic Riss77a07432014-11-20 16:21:11 +000084 AtomForms.push_back(DWARFFormValue(Atom.second));
Frederic Risse837ec22014-11-14 16:15:53 +000085 }
86
87 // Now go through the actual tables and dump them.
88 uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
89 unsigned HashesBase = Offset + Hdr.NumBuckets * 4;
90 unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4;
91
92 for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) {
93 unsigned Index = AccelSection.getU32(&Offset);
94
95 OS << format("Bucket[%d]\n", Bucket);
96 if (Index == UINT32_MAX) {
97 OS << " EMPTY\n";
98 continue;
99 }
100
101 for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) {
102 unsigned HashOffset = HashesBase + HashIdx*4;
103 unsigned OffsetsOffset = OffsetsBase + HashIdx*4;
104 uint32_t Hash = AccelSection.getU32(&HashOffset);
105
106 if (Hash % Hdr.NumBuckets != Bucket)
107 break;
108
109 unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
110 OS << format(" Hash = 0x%08x Offset = 0x%08x\n", Hash, DataOffset);
111 if (!AccelSection.isValidOffset(DataOffset)) {
112 OS << " Invalid section offset\n";
113 continue;
114 }
Frederic Riss7c500472014-11-14 19:30:08 +0000115 while (AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
George Rimarf8a96422017-04-21 09:12:18 +0000116 unsigned StringOffset =
117 getRelocatedValue(AccelSection, 4, &DataOffset, &Relocs);
Frederic Riss7c500472014-11-14 19:30:08 +0000118 if (!StringOffset)
119 break;
Frederic Risse837ec22014-11-14 16:15:53 +0000120 OS << format(" Name: %08x \"%s\"\n", StringOffset,
121 StringSection.getCStr(&StringOffset));
122 unsigned NumData = AccelSection.getU32(&DataOffset);
123 for (unsigned Data = 0; Data < NumData; ++Data) {
124 OS << format(" Data[%d] => ", Data);
125 unsigned i = 0;
Frederic Riss77a07432014-11-20 16:21:11 +0000126 for (auto &Atom : AtomForms) {
Frederic Risse837ec22014-11-14 16:15:53 +0000127 OS << format("{Atom[%d]: ", i++);
Frederic Riss77a07432014-11-20 16:21:11 +0000128 if (Atom.extractValue(AccelSection, &DataOffset, nullptr))
Greg Claytoncddab272016-10-31 16:46:02 +0000129 Atom.dump(OS);
Frederic Risse837ec22014-11-14 16:15:53 +0000130 else
131 OS << "Error extracting the value";
132 OS << "} ";
133 }
134 OS << '\n';
135 }
136 }
137 }
138 }
139}