LLVM: lib/DebugInfo/DWARF/DWARFUnitIndex.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
16#include
17#include
18
19using namespace llvm;
20
21namespace {
22
23enum class DWARFSectionKindV2 {
24 DW_SECT_INFO = 1,
25 DW_SECT_TYPES = 2,
26 DW_SECT_ABBREV = 3,
27 DW_SECT_LINE = 4,
28 DW_SECT_LOC = 5,
29 DW_SECT_STR_OFFSETS = 6,
30 DW_SECT_MACINFO = 7,
31 DW_SECT_MACRO = 8,
32};
33
34}
35
36
38 return ID >= DW_SECT_INFO && ID <= DW_SECT_RNGLISTS &&
40}
41
43 unsigned IndexVersion) {
44 if (IndexVersion == 5) {
46 return static_cast<uint32_t>(Kind);
47 }
48 assert(IndexVersion == 2);
49 switch (Kind) {
50#define CASE(S,T) \
51 case DW_SECT_##S: \
52 return static_cast<uint32_t>(DWARFSectionKindV2::DW_SECT_##T)
53 CASE(INFO, INFO);
55 CASE(ABBREV, ABBREV);
56 CASE(LINE, LINE);
57 CASE(EXT_LOC, LOC);
58 CASE(STR_OFFSETS, STR_OFFSETS);
59 CASE(EXT_MACINFO, MACINFO);
60 CASE(MACRO, MACRO);
61#undef CASE
62 default:
63
65 }
66}
67
69 unsigned IndexVersion) {
70 if (IndexVersion == 5)
74 assert(IndexVersion == 2);
75 switch (static_cast<DWARFSectionKindV2>(Value)) {
76#define CASE(S,T) \
77 case DWARFSectionKindV2::DW_SECT_##S: \
78 return DW_SECT_##T
79 CASE(INFO, INFO);
81 CASE(ABBREV, ABBREV);
82 CASE(LINE, LINE);
83 CASE(LOC, EXT_LOC);
84 CASE(STR_OFFSETS, STR_OFFSETS);
85 CASE(MACINFO, EXT_MACINFO);
86 CASE(MACRO, MACRO);
87#undef CASE
88 }
90}
91
92bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
94 const uint64_t BeginOffset = *OffsetPtr;
96 return false;
97
98
99
100
101 Version = IndexData.getU32(OffsetPtr);
102 if (Version != 2) {
103 *OffsetPtr = BeginOffset;
104 Version = IndexData.getU16(OffsetPtr);
105 if (Version != 5)
106 return false;
107 *OffsetPtr += 2;
108 }
109 NumColumns = IndexData.getU32(OffsetPtr);
110 NumUnits = IndexData.getU32(OffsetPtr);
111 NumBuckets = IndexData.getU32(OffsetPtr);
112 return true;
113}
114
115void DWARFUnitIndex::Header::dump(raw_ostream &OS) const {
116 OS << format("version = %u, units = %u, slots = %u\n\n", Version, NumUnits, NumBuckets);
117}
118
120 bool b = parseImpl(IndexData);
121 if (!b) {
122
123 Header.NumBuckets = 0;
124
125 ColumnKinds.reset();
126 Rows.reset();
127 }
128 return b;
129}
130
131bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
133 if (!Header.parse(IndexData, &Offset))
134 return false;
135
136
137 if (Header.Version == 5)
138 InfoColumnKind = DW_SECT_INFO;
139
141 Offset, Header.NumBuckets * (8 + 4) +
142 (2 * Header.NumUnits + 1) * 4 * Header.NumColumns))
143 return false;
144
145 Rows = std::make_unique<Entry[]>(Header.NumBuckets);
146 auto Contribs =
147 std::make_unique<Entry::SectionContribution *[]>(Header.NumUnits);
148 ColumnKinds = std::make_unique<DWARFSectionKind[]>(Header.NumColumns);
149 RawSectionIds = std::make_unique<uint32_t[]>(Header.NumColumns);
150
151
152 for (unsigned i = 0; i != Header.NumBuckets; ++i)
153 Rows[i].Signature = IndexData.getU64(&Offset);
154
155
156 for (unsigned i = 0; i != Header.NumBuckets; ++i) {
158 if (!Index)
159 continue;
160 Rows[i].Index = this;
161 Rows[i].Contributions =
162 std::make_uniqueEntry::SectionContribution\[\](Header.NumColumns);
163 Contribs[Index - 1] = Rows[i].Contributions.get();
164 }
165
166
167 for (unsigned i = 0; i != Header.NumColumns; ++i) {
168 RawSectionIds[i] = IndexData.getU32(&Offset);
170 if (ColumnKinds[i] == InfoColumnKind) {
171 if (InfoColumn != -1)
172 return false;
173 InfoColumn = i;
174 }
175 }
176
177 if (InfoColumn == -1)
178 return false;
179
180
181 for (unsigned i = 0; i != Header.NumUnits; ++i) {
182 auto *Contrib = Contribs[i];
183 for (unsigned i = 0; i != Header.NumColumns; ++i)
184 Contrib[i].setOffset(IndexData.getU32(&Offset));
185 }
186
187
188 for (unsigned i = 0; i != Header.NumUnits; ++i) {
189 auto *Contrib = Contribs[i];
190 for (unsigned i = 0; i != Header.NumColumns; ++i)
191 Contrib[i].setLength(IndexData.getU32(&Offset));
192 }
193
194 return true;
195}
196
197StringRef DWARFUnitIndex::getColumnHeader(DWARFSectionKind DS) {
198 switch (DS) {
199#define HANDLE_DW_SECT(ID, NAME) \
200 case DW_SECT_##NAME: \
201 return #NAME;
202#include "llvm/BinaryFormat/Dwarf.def"
204 return "TYPES";
206 return "LOC";
208 return "MACINFO";
210 return StringRef();
211 }
213}
214
216 if (!*this)
217 return;
218
219 Header.dump(OS);
220 OS << "Index Signature ";
221 for (unsigned i = 0; i != Header.NumColumns; ++i) {
223 StringRef Name = getColumnHeader(Kind);
224 if (!Name.empty())
225 OS << ' '
227 Kind == DWARFSectionKind::DW_SECT_INFO ? 40 : 24);
228 else
229 OS << format(" Unknown: %-15" PRIu32, RawSectionIds[i]);
230 }
231 OS << "\n----- ------------------";
232 for (unsigned i = 0; i != Header.NumColumns; ++i) {
234 if (Kind == DWARFSectionKind::DW_SECT_INFO ||
236 OS << " ----------------------------------------";
237 else
238 OS << " ------------------------";
239 }
240 OS << '\n';
241 for (unsigned i = 0; i != Header.NumBuckets; ++i) {
242 auto &Row = Rows[i];
243 if (auto *Contribs = Row.Contributions.get()) {
244 OS << format("%5u 0x%016" PRIx64 " ", i + 1, Row.Signature);
245 for (unsigned i = 0; i != Header.NumColumns; ++i) {
246 auto &Contrib = Contribs[i];
248 if (Kind == DWARFSectionKind::DW_SECT_INFO ||
250 OS << format("[0x%016" PRIx64 ", 0x%016" PRIx64 ") ",
251 Contrib.getOffset(),
252 Contrib.getOffset() + Contrib.getLength());
253 else
254 OS << format("[0x%08" PRIx32 ", 0x%08" PRIx32 ") ",
255 Contrib.getOffset32(),
256 Contrib.getOffset32() + Contrib.getLength32());
257 }
258 OS << '\n';
259 }
260 }
261}
262
266 for (; i != Index->Header.NumColumns; ++i)
267 if (Index->ColumnKinds[i] == Sec)
268 return &Contributions[i];
269 return nullptr;
270}
271
274 return Contributions[Index->InfoColumn];
275}
276
279 return &Contributions[Index->InfoColumn];
280}
281
284 if (OffsetLookup.empty()) {
285 for (uint32_t i = 0; i != Header.NumBuckets; ++i)
286 if (Rows[i].Contributions)
287 OffsetLookup.push_back(&Rows[i]);
289 return E1->Contributions[InfoColumn].getOffset() <
290 E2->Contributions[InfoColumn].getOffset();
291 });
292 }
294 return E2->Contributions[InfoColumn].getOffset() <= Offset;
295 });
296 if (I == OffsetLookup.begin())
297 return nullptr;
298 --I;
299 const auto *E = *I;
300 const auto &InfoContrib = E->Contributions[InfoColumn];
301 if ((InfoContrib.getOffset() + InfoContrib.getLength()) <= Offset)
302 return nullptr;
303 return E;
304}
305
307 uint64_t Mask = Header.NumBuckets - 1;
308
309 auto H = S & Mask;
310 auto HP = ((S >> 32) & Mask) | 1;
311
312
313 while (Rows[H].getSignature() != S && Rows[H].Index != nullptr)
315
316
317
318 if (Rows[H].Index == nullptr)
319 return nullptr;
320
321 return &Rows[H];
322}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
constexpr bool isKnownV5SectionID(uint32_t ID)
Definition DWARFUnitIndex.cpp:37
static std::string getSignature(FunctionType *FTy)
LLVM_ABI const SectionContribution * getContribution() const
Definition DWARFUnitIndex.cpp:278
LLVM_ABI void dump(raw_ostream &OS) const
Definition DWARFUnitIndex.cpp:215
LLVM_ABI bool parse(DataExtractor IndexData)
Definition DWARFUnitIndex.cpp:119
LLVM_ABI const Entry * getFromHash(uint64_t Offset) const
Definition DWARFUnitIndex.cpp:306
LLVM_ABI const Entry * getFromOffset(uint64_t Offset) const
Definition DWARFUnitIndex.cpp:283
StringRef - Represent a constant reference to a string, i.e.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
LLVM_ABI DWARFSectionKind deserializeSectionKind(uint32_t Value, unsigned IndexVersion)
Convert a value read from an index section to the internal representation.
Definition DWARFUnitIndex.cpp:68
DWARFSectionKind
The enum of section identifiers to be used in internal interfaces.
@ DW_SECT_EXT_unknown
Denotes a value read from an index section that does not correspond to any of the supported standards...
LLVM_ABI uint32_t serializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion)
Convert the internal value for a section kind to an on-disk value.
Definition DWARFUnitIndex.cpp:42
FunctionAddr VTableAddr uintptr_t uintptr_t Version
void sort(IteratorTy Start, IteratorTy End)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
FormattedString left_justify(StringRef Str, unsigned Width)
left_justify - append spaces after string so total output is Width characters.