Line data Source code
1 : //===- DWARFContext.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 :
10 : #include "llvm/DebugInfo/DWARF/DWARFContext.h"
11 : #include "llvm/ADT/STLExtras.h"
12 : #include "llvm/ADT/SmallString.h"
13 : #include "llvm/ADT/SmallVector.h"
14 : #include "llvm/ADT/StringRef.h"
15 : #include "llvm/ADT/StringSwitch.h"
16 : #include "llvm/BinaryFormat/Dwarf.h"
17 : #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
18 : #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
19 : #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
20 : #include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
21 : #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
22 : #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
23 : #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
24 : #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
25 : #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
26 : #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
27 : #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
28 : #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
29 : #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
30 : #include "llvm/DebugInfo/DWARF/DWARFDie.h"
31 : #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
32 : #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
33 : #include "llvm/DebugInfo/DWARF/DWARFSection.h"
34 : #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
35 : #include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
36 : #include "llvm/MC/MCRegisterInfo.h"
37 : #include "llvm/Object/Decompressor.h"
38 : #include "llvm/Object/MachO.h"
39 : #include "llvm/Object/ObjectFile.h"
40 : #include "llvm/Object/RelocVisitor.h"
41 : #include "llvm/Support/Casting.h"
42 : #include "llvm/Support/DataExtractor.h"
43 : #include "llvm/Support/Error.h"
44 : #include "llvm/Support/Format.h"
45 : #include "llvm/Support/MemoryBuffer.h"
46 : #include "llvm/Support/Path.h"
47 : #include "llvm/Support/TargetRegistry.h"
48 : #include "llvm/Support/WithColor.h"
49 : #include "llvm/Support/raw_ostream.h"
50 : #include <algorithm>
51 : #include <cstdint>
52 : #include <deque>
53 : #include <map>
54 : #include <string>
55 : #include <utility>
56 : #include <vector>
57 :
58 : using namespace llvm;
59 : using namespace dwarf;
60 : using namespace object;
61 :
62 : #define DEBUG_TYPE "dwarf"
63 :
64 : using DWARFLineTable = DWARFDebugLine::LineTable;
65 : using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
66 : using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
67 :
68 1544 : DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj,
69 1544 : std::string DWPName)
70 4632 : : DIContext(CK_DWARF), DWPName(std::move(DWPName)), DObj(std::move(DObj)) {}
71 :
72 : DWARFContext::~DWARFContext() = default;
73 :
74 : /// Dump the UUID load command.
75 207 : static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) {
76 : auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
77 : if (!MachO)
78 : return;
79 424 : for (auto LC : MachO->load_commands()) {
80 : raw_ostream::uuid_t UUID;
81 356 : if (LC.C.cmd == MachO::LC_UUID) {
82 29 : if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) {
83 0 : OS << "error: UUID load command is too short.\n";
84 0 : return;
85 : }
86 29 : OS << "UUID: ";
87 29 : memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
88 29 : OS.write_uuid(UUID);
89 29 : Triple T = MachO->getArchTriple();
90 29 : OS << " (" << T.getArchName() << ')';
91 29 : OS << ' ' << MachO->getFileName() << '\n';
92 : }
93 : }
94 : }
95 :
96 : using ContributionCollection =
97 : std::vector<Optional<StrOffsetsContributionDescriptor>>;
98 :
99 : // Collect all the contributions to the string offsets table from all units,
100 : // sort them by their starting offsets and remove duplicates.
101 : static ContributionCollection
102 29 : collectContributionData(DWARFContext::unit_iterator_range Units) {
103 : ContributionCollection Contributions;
104 84 : for (const auto &U : Units)
105 55 : Contributions.push_back(U->getStringOffsetsTableContribution());
106 : // Sort the contributions so that any invalid ones are placed at
107 : // the start of the contributions vector. This way they are reported
108 : // first.
109 : llvm::sort(Contributions,
110 : [](const Optional<StrOffsetsContributionDescriptor> &L,
111 : const Optional<StrOffsetsContributionDescriptor> &R) {
112 0 : if (L && R)
113 0 : return L->Base < R->Base;
114 0 : return R.hasValue();
115 : });
116 :
117 : // Uniquify contributions, as it is possible that units (specifically
118 : // type units in dwo or dwp files) share contributions. We don't want
119 : // to report them more than once.
120 : Contributions.erase(
121 : std::unique(Contributions.begin(), Contributions.end(),
122 : [](const Optional<StrOffsetsContributionDescriptor> &L,
123 : const Optional<StrOffsetsContributionDescriptor> &R) {
124 0 : if (L && R)
125 0 : return L->Base == R->Base && L->Size == R->Size;
126 : return false;
127 29 : }),
128 : Contributions.end());
129 29 : return Contributions;
130 : }
131 :
132 29 : static void dumpDWARFv5StringOffsetsSection(
133 : raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj,
134 : const DWARFSection &StringOffsetsSection, StringRef StringSection,
135 : DWARFContext::unit_iterator_range Units, bool LittleEndian) {
136 29 : auto Contributions = collectContributionData(Units);
137 : DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
138 : DataExtractor StrData(StringSection, LittleEndian, 0);
139 : uint64_t SectionSize = StringOffsetsSection.Data.size();
140 29 : uint32_t Offset = 0;
141 60 : for (auto &Contribution : Contributions) {
142 : // Report an ill-formed contribution.
143 36 : if (!Contribution) {
144 4 : OS << "error: invalid contribution to string offsets table in section ."
145 4 : << SectionName << ".\n";
146 4 : return;
147 : }
148 :
149 32 : dwarf::DwarfFormat Format = Contribution->getFormat();
150 32 : uint16_t Version = Contribution->getVersion();
151 32 : uint64_t ContributionHeader = Contribution->Base;
152 : // In DWARF v5 there is a contribution header that immediately precedes
153 : // the string offsets base (the location we have previously retrieved from
154 : // the CU DIE's DW_AT_str_offsets attribute). The header is located either
155 : // 8 or 16 bytes before the base, depending on the contribution's format.
156 32 : if (Version >= 5)
157 33 : ContributionHeader -= Format == DWARF32 ? 8 : 16;
158 :
159 : // Detect overlapping contributions.
160 32 : if (Offset > ContributionHeader) {
161 : OS << "error: overlapping contributions to string offsets table in "
162 1 : "section ."
163 1 : << SectionName << ".\n";
164 1 : return;
165 : }
166 : // Report a gap in the table.
167 31 : if (Offset < ContributionHeader) {
168 4 : OS << format("0x%8.8x: Gap, length = ", Offset);
169 4 : OS << (ContributionHeader - Offset) << "\n";
170 : }
171 62 : OS << format("0x%8.8x: ", (uint32_t)ContributionHeader);
172 : // In DWARF v5 the contribution size in the descriptor does not equal
173 : // the originally encoded length (it does not contain the length of the
174 : // version field and the padding, a total of 4 bytes). Add them back in
175 : // for reporting.
176 61 : OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
177 33 : << ", Format = " << (Format == DWARF32 ? "DWARF32" : "DWARF64")
178 62 : << ", Version = " << Version << "\n";
179 :
180 31 : Offset = Contribution->Base;
181 31 : unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
182 480 : while (Offset - Contribution->Base < Contribution->Size) {
183 449 : OS << format("0x%8.8x: ", Offset);
184 : // FIXME: We can only extract strings if the offset fits in 32 bits.
185 : uint64_t StringOffset =
186 449 : StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
187 : // Extract the string if we can and display it. Otherwise just report
188 : // the offset.
189 449 : if (StringOffset <= std::numeric_limits<uint32_t>::max()) {
190 449 : uint32_t StringOffset32 = (uint32_t)StringOffset;
191 449 : OS << format("%8.8x ", StringOffset32);
192 449 : const char *S = StrData.getCStr(&StringOffset32);
193 449 : if (S)
194 449 : OS << format("\"%s\"", S);
195 : } else
196 0 : OS << format("%16.16" PRIx64 " ", StringOffset);
197 449 : OS << "\n";
198 : }
199 : }
200 : // Report a gap at the end of the table.
201 24 : if (Offset < SectionSize) {
202 0 : OS << format("0x%8.8x: Gap, length = ", Offset);
203 0 : OS << (SectionSize - Offset) << "\n";
204 : }
205 : }
206 :
207 : // Dump a DWARF string offsets section. This may be a DWARF v5 formatted
208 : // string offsets section, where each compile or type unit contributes a
209 : // number of entries (string offsets), with each contribution preceded by
210 : // a header containing size and version number. Alternatively, it may be a
211 : // monolithic series of string offsets, as generated by the pre-DWARF v5
212 : // implementation of split DWARF.
213 50 : static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
214 : const DWARFObject &Obj,
215 : const DWARFSection &StringOffsetsSection,
216 : StringRef StringSection,
217 : DWARFContext::unit_iterator_range Units,
218 : bool LittleEndian, unsigned MaxVersion) {
219 : // If we have at least one (compile or type) unit with DWARF v5 or greater,
220 : // we assume that the section is formatted like a DWARF v5 string offsets
221 : // section.
222 50 : if (MaxVersion >= 5)
223 58 : dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection,
224 : StringSection, Units, LittleEndian);
225 : else {
226 : DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
227 21 : uint32_t offset = 0;
228 : uint64_t size = StringOffsetsSection.Data.size();
229 : // Ensure that size is a multiple of the size of an entry.
230 21 : if (size & ((uint64_t)(sizeof(uint32_t) - 1))) {
231 1 : OS << "error: size of ." << SectionName << " is not a multiple of "
232 1 : << sizeof(uint32_t) << ".\n";
233 1 : size &= -(uint64_t)sizeof(uint32_t);
234 : }
235 : DataExtractor StrData(StringSection, LittleEndian, 0);
236 264 : while (offset < size) {
237 243 : OS << format("0x%8.8x: ", offset);
238 243 : uint32_t StringOffset = strOffsetExt.getU32(&offset);
239 243 : OS << format("%8.8x ", StringOffset);
240 243 : const char *S = StrData.getCStr(&StringOffset);
241 243 : if (S)
242 243 : OS << format("\"%s\"", S);
243 243 : OS << "\n";
244 : }
245 : }
246 50 : }
247 :
248 : // Dump the .debug_addr section.
249 28 : static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
250 : DIDumpOptions DumpOpts, uint16_t Version,
251 : uint8_t AddrSize) {
252 28 : uint32_t Offset = 0;
253 106 : while (AddrData.isValidOffset(Offset)) {
254 : DWARFDebugAddrTable AddrTable;
255 : uint32_t TableOffset = Offset;
256 30 : if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
257 60 : DWARFContext::dumpWarning)) {
258 20 : WithColor::error() << toString(std::move(Err)) << '\n';
259 : // Keep going after an error, if we can, assuming that the length field
260 : // could be read. If it couldn't, stop reading the section.
261 10 : if (!AddrTable.hasValidLength())
262 : break;
263 5 : uint64_t Length = AddrTable.getLength();
264 5 : Offset = TableOffset + Length;
265 : } else {
266 20 : AddrTable.dump(OS, DumpOpts);
267 : }
268 : }
269 28 : }
270 :
271 : // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
272 9 : static void dumpRnglistsSection(raw_ostream &OS,
273 : DWARFDataExtractor &rnglistData,
274 : DIDumpOptions DumpOpts) {
275 9 : uint32_t Offset = 0;
276 82 : while (rnglistData.isValidOffset(Offset)) {
277 : llvm::DWARFDebugRnglistTable Rnglists;
278 : uint32_t TableOffset = Offset;
279 68 : if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
280 38 : WithColor::error() << toString(std::move(Err)) << '\n';
281 : uint64_t Length = Rnglists.length();
282 : // Keep going after an error, if we can, assuming that the length field
283 : // could be read. If it couldn't, stop reading the section.
284 19 : if (Length == 0)
285 : break;
286 17 : Offset = TableOffset + Length;
287 : } else {
288 15 : Rnglists.dump(OS, DumpOpts);
289 : }
290 : }
291 9 : }
292 :
293 689 : void DWARFContext::dump(
294 : raw_ostream &OS, DIDumpOptions DumpOpts,
295 : std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
296 :
297 : Optional<uint64_t> DumpOffset;
298 689 : uint64_t DumpType = DumpOpts.DumpType;
299 :
300 689 : StringRef Extension = sys::path::extension(DObj->getFileName());
301 : bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");
302 :
303 : // Print UUID header.
304 689 : const auto *ObjFile = DObj->getFile();
305 689 : if (DumpType & DIDT_UUID)
306 207 : dumpUUID(OS, *ObjFile);
307 :
308 : // Print a header for each explicitly-requested section.
309 : // Otherwise just print one for non-empty sections.
310 : // Only print empty .dwo section headers when dumping a .dwo file.
311 689 : bool Explicit = DumpType != DIDT_All && !IsDWO;
312 689 : bool ExplicitDWO = Explicit && IsDWO;
313 : auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
314 : StringRef Section) {
315 : DumpOffset = DumpOffsets[ID];
316 : unsigned Mask = 1U << ID;
317 : bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
318 : if (Should)
319 : OS << "\n" << Name << " contents:\n";
320 : return Should;
321 689 : };
322 :
323 : // Dump individual sections.
324 689 : if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,
325 689 : DObj->getAbbrevSection()))
326 185 : getDebugAbbrev()->dump(OS);
327 689 : if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
328 689 : DObj->getAbbrevDWOSection()))
329 32 : getDebugAbbrevDWO()->dump(OS);
330 :
331 : auto dumpDebugInfo = [&](unit_iterator_range Units) {
332 : if (DumpOffset)
333 : getDIEForOffset(DumpOffset.getValue())
334 : .dump(OS, 0, DumpOpts.noImplicitRecursion());
335 : else
336 : for (const auto &U : Units)
337 : U->dump(OS, DumpOpts);
338 689 : };
339 689 : if (shouldDump(Explicit, ".debug_info", DIDT_ID_DebugInfo,
340 689 : DObj->getInfoSection().Data))
341 507 : dumpDebugInfo(info_section_units());
342 689 : if (shouldDump(ExplicitDWO, ".debug_info.dwo", DIDT_ID_DebugInfo,
343 689 : DObj->getInfoDWOSection().Data))
344 42 : dumpDebugInfo(dwo_info_section_units());
345 :
346 : auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
347 : OS << '\n' << Name << " contents:\n";
348 : DumpOffset = DumpOffsets[DIDT_ID_DebugTypes];
349 : for (const auto &U : Units)
350 : if (DumpOffset)
351 : U->getDIEForOffset(*DumpOffset)
352 : .dump(OS, 0, DumpOpts.noImplicitRecursion());
353 : else
354 : U->dump(OS, DumpOpts);
355 689 : };
356 689 : if ((DumpType & DIDT_DebugTypes)) {
357 414 : if (Explicit || getNumTypeUnits())
358 18 : dumpDebugType(".debug_types", types_section_units());
359 420 : if (ExplicitDWO || getNumDWOTypeUnits())
360 14 : dumpDebugType(".debug_types.dwo", dwo_types_section_units());
361 : }
362 :
363 689 : if (shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
364 689 : DObj->getLocSection().Data)) {
365 100 : getDebugLoc()->dump(OS, getRegisterInfo(), DumpOffset);
366 : }
367 689 : if (shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
368 689 : DObj->getLocDWOSection().Data)) {
369 6 : getDebugLocDWO()->dump(OS, getRegisterInfo(), DumpOffset);
370 : }
371 :
372 689 : if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
373 689 : DObj->getDebugFrameSection()))
374 100 : getDebugFrame()->dump(OS, getRegisterInfo(), DumpOffset);
375 :
376 689 : if (shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
377 689 : DObj->getEHFrameSection()))
378 182 : getEHFrame()->dump(OS, getRegisterInfo(), DumpOffset);
379 :
380 689 : if (DumpType & DIDT_DebugMacro) {
381 205 : if (Explicit || !getDebugMacro()->empty()) {
382 2 : OS << "\n.debug_macinfo contents:\n";
383 2 : getDebugMacro()->dump(OS);
384 : }
385 : }
386 :
387 689 : if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
388 689 : DObj->getARangeSection())) {
389 37 : uint32_t offset = 0;
390 37 : DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0);
391 : DWARFDebugArangeSet set;
392 126 : while (set.extract(arangesData, &offset))
393 89 : set.dump(OS);
394 : }
395 :
396 : auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
397 : DIDumpOptions DumpOpts) {
398 : while (!Parser.done()) {
399 : if (DumpOffset && Parser.getOffset() != *DumpOffset) {
400 : Parser.skip(dumpWarning);
401 : continue;
402 : }
403 : OS << "debug_line[" << format("0x%8.8x", Parser.getOffset()) << "]\n";
404 : if (DumpOpts.Verbose) {
405 : Parser.parseNext(dumpWarning, dumpWarning, &OS);
406 : } else {
407 : DWARFDebugLine::LineTable LineTable =
408 : Parser.parseNext(dumpWarning, dumpWarning);
409 : LineTable.dump(OS, DumpOpts);
410 : }
411 : }
412 689 : };
413 :
414 689 : if (shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
415 689 : DObj->getLineSection().Data)) {
416 223 : DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
417 223 : 0);
418 : DWARFDebugLine::SectionParser Parser(LineData, *this, compile_units(),
419 223 : type_units());
420 446 : DumpLineSection(Parser, DumpOpts);
421 : }
422 :
423 689 : if (shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
424 689 : DObj->getLineDWOSection().Data)) {
425 18 : DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
426 18 : isLittleEndian(), 0);
427 : DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_compile_units(),
428 18 : dwo_type_units());
429 36 : DumpLineSection(Parser, DumpOpts);
430 : }
431 :
432 689 : if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
433 689 : DObj->getCUIndexSection())) {
434 10 : getCUIndex().dump(OS);
435 : }
436 :
437 689 : if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,
438 689 : DObj->getTUIndexSection())) {
439 6 : getTUIndex().dump(OS);
440 : }
441 :
442 689 : if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
443 689 : DObj->getStringSection())) {
444 174 : DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0);
445 174 : uint32_t offset = 0;
446 : uint32_t strOffset = 0;
447 2339 : while (const char *s = strData.getCStr(&offset)) {
448 2165 : OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
449 2165 : strOffset = offset;
450 2165 : }
451 : }
452 689 : if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
453 689 : DObj->getStringDWOSection())) {
454 31 : DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0);
455 31 : uint32_t offset = 0;
456 : uint32_t strDWOOffset = 0;
457 332 : while (const char *s = strDWOData.getCStr(&offset)) {
458 301 : OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
459 301 : strDWOOffset = offset;
460 301 : }
461 : }
462 689 : if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
463 689 : DObj->getLineStringSection())) {
464 20 : DataExtractor strData(DObj->getLineStringSection(), isLittleEndian(), 0);
465 20 : uint32_t offset = 0;
466 : uint32_t strOffset = 0;
467 82 : while (const char *s = strData.getCStr(&offset)) {
468 62 : OS << format("0x%8.8x: \"", strOffset);
469 62 : OS.write_escaped(s);
470 62 : OS << "\"\n";
471 62 : strOffset = offset;
472 62 : }
473 : }
474 :
475 689 : if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
476 689 : DObj->getAddrSection().Data)) {
477 28 : DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
478 28 : isLittleEndian(), 0);
479 28 : dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
480 : }
481 :
482 689 : if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
483 689 : DObj->getRangeSection().Data)) {
484 32 : uint8_t savedAddressByteSize = getCUAddrSize();
485 32 : DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
486 32 : isLittleEndian(), savedAddressByteSize);
487 32 : uint32_t offset = 0;
488 : DWARFDebugRangeList rangeList;
489 96 : while (rangesData.isValidOffset(offset)) {
490 66 : if (Error E = rangeList.extract(rangesData, &offset)) {
491 2 : WithColor::error() << toString(std::move(E)) << '\n';
492 : break;
493 : }
494 32 : rangeList.dump(OS);
495 : }
496 : }
497 :
498 689 : if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
499 689 : DObj->getRnglistsSection().Data)) {
500 9 : DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
501 9 : isLittleEndian(), 0);
502 9 : dumpRnglistsSection(OS, RnglistData, DumpOpts);
503 : }
504 :
505 689 : if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
506 689 : DObj->getRnglistsDWOSection().Data)) {
507 0 : DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
508 0 : isLittleEndian(), 0);
509 0 : dumpRnglistsSection(OS, RnglistData, DumpOpts);
510 : }
511 :
512 689 : if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
513 689 : DObj->getPubNamesSection()))
514 333 : DWARFDebugPubTable(DObj->getPubNamesSection(), isLittleEndian(), false)
515 111 : .dump(OS);
516 :
517 689 : if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
518 689 : DObj->getPubTypesSection()))
519 318 : DWARFDebugPubTable(DObj->getPubTypesSection(), isLittleEndian(), false)
520 106 : .dump(OS);
521 :
522 689 : if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
523 689 : DObj->getGnuPubNamesSection()))
524 12 : DWARFDebugPubTable(DObj->getGnuPubNamesSection(), isLittleEndian(),
525 : true /* GnuStyle */)
526 4 : .dump(OS);
527 :
528 689 : if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
529 689 : DObj->getGnuPubTypesSection()))
530 12 : DWARFDebugPubTable(DObj->getGnuPubTypesSection(), isLittleEndian(),
531 : true /* GnuStyle */)
532 4 : .dump(OS);
533 :
534 689 : if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
535 689 : DObj->getStringOffsetSection().Data))
536 44 : dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj,
537 22 : DObj->getStringOffsetSection(),
538 22 : DObj->getStringSection(), normal_units(),
539 : isLittleEndian(), getMaxVersion());
540 689 : if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
541 689 : DObj->getStringOffsetDWOSection().Data))
542 56 : dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj,
543 28 : DObj->getStringOffsetDWOSection(),
544 28 : DObj->getStringDWOSection(), dwo_units(),
545 : isLittleEndian(), getMaxDWOVersion());
546 :
547 689 : if (shouldDump(Explicit, ".gnu_index", DIDT_ID_GdbIndex,
548 689 : DObj->getGdbIndexSection())) {
549 7 : getGdbIndex().dump(OS);
550 : }
551 :
552 689 : if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
553 689 : DObj->getAppleNamesSection().Data))
554 66 : getAppleNames().dump(OS);
555 :
556 689 : if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
557 689 : DObj->getAppleTypesSection().Data))
558 67 : getAppleTypes().dump(OS);
559 :
560 689 : if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,
561 689 : DObj->getAppleNamespacesSection().Data))
562 65 : getAppleNamespaces().dump(OS);
563 :
564 689 : if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,
565 689 : DObj->getAppleObjCSection().Data))
566 65 : getAppleObjC().dump(OS);
567 689 : if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
568 689 : DObj->getDebugNamesSection().Data))
569 28 : getDebugNames().dump(OS);
570 689 : }
571 :
572 20 : DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
573 20 : parseDWOUnits(LazyParse);
574 :
575 20 : if (const auto &CUI = getCUIndex()) {
576 4 : if (const auto *R = CUI.getFromHash(Hash))
577 4 : return dyn_cast_or_null<DWARFCompileUnit>(
578 : DWOUnits.getUnitForIndexEntry(*R));
579 : return nullptr;
580 : }
581 :
582 : // If there's no index, just search through the CUs in the DWO - there's
583 : // probably only one unless this is something like LTO - though an in-process
584 : // built/cached lookup table could be used in that case to improve repeated
585 : // lookups of different CUs in the DWO.
586 19 : for (const auto &DWOCU : dwo_compile_units()) {
587 : // Might not have parsed DWO ID yet.
588 19 : if (!DWOCU->getDWOId()) {
589 0 : if (Optional<uint64_t> DWOId =
590 0 : toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
591 0 : DWOCU->setDWOId(*DWOId);
592 : else
593 : // No DWO ID?
594 : continue;
595 : }
596 : if (DWOCU->getDWOId() == Hash)
597 : return dyn_cast<DWARFCompileUnit>(DWOCU.get());
598 : }
599 : return nullptr;
600 : }
601 :
602 724 : DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
603 724 : parseNormalUnits();
604 724 : if (auto *CU = NormalUnits.getUnitForOffset(Offset))
605 722 : return CU->getDIEForOffset(Offset);
606 2 : return DWARFDie();
607 : }
608 :
609 75 : bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) {
610 : bool Success = true;
611 : DWARFVerifier verifier(OS, *this, DumpOpts);
612 :
613 75 : Success &= verifier.handleDebugAbbrev();
614 75 : if (DumpOpts.DumpType & DIDT_DebugInfo)
615 64 : Success &= verifier.handleDebugInfo();
616 75 : if (DumpOpts.DumpType & DIDT_DebugLine)
617 31 : Success &= verifier.handleDebugLine();
618 75 : Success &= verifier.handleAccelTables();
619 75 : return Success;
620 : }
621 :
622 119 : const DWARFUnitIndex &DWARFContext::getCUIndex() {
623 119 : if (CUIndex)
624 : return *CUIndex;
625 :
626 62 : DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
627 :
628 62 : CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
629 62 : CUIndex->parse(CUIndexData);
630 62 : return *CUIndex;
631 : }
632 :
633 33 : const DWARFUnitIndex &DWARFContext::getTUIndex() {
634 33 : if (TUIndex)
635 : return *TUIndex;
636 :
637 14 : DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
638 :
639 14 : TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
640 14 : TUIndex->parse(TUIndexData);
641 14 : return *TUIndex;
642 : }
643 :
644 7 : DWARFGdbIndex &DWARFContext::getGdbIndex() {
645 7 : if (GdbIndex)
646 : return *GdbIndex;
647 :
648 7 : DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
649 7 : GdbIndex = llvm::make_unique<DWARFGdbIndex>();
650 7 : GdbIndex->parse(GdbIndexData);
651 7 : return *GdbIndex;
652 : }
653 :
654 2083 : const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
655 2083 : if (Abbrev)
656 : return Abbrev.get();
657 :
658 1412 : DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0);
659 :
660 1412 : Abbrev.reset(new DWARFDebugAbbrev());
661 1412 : Abbrev->extract(abbrData);
662 1412 : return Abbrev.get();
663 : }
664 :
665 339 : const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
666 339 : if (AbbrevDWO)
667 : return AbbrevDWO.get();
668 :
669 275 : DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0);
670 275 : AbbrevDWO.reset(new DWARFDebugAbbrev());
671 275 : AbbrevDWO->extract(abbrData);
672 275 : return AbbrevDWO.get();
673 : }
674 :
675 63 : const DWARFDebugLoc *DWARFContext::getDebugLoc() {
676 63 : if (Loc)
677 : return Loc.get();
678 :
679 57 : Loc.reset(new DWARFDebugLoc);
680 : // Assume all units have the same address byte size.
681 57 : if (getNumCompileUnits()) {
682 56 : DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
683 56 : getUnitAtIndex(0)->getAddressByteSize());
684 56 : Loc->parse(LocData);
685 : }
686 57 : return Loc.get();
687 : }
688 :
689 3 : const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
690 3 : if (LocDWO)
691 : return LocDWO.get();
692 :
693 3 : LocDWO.reset(new DWARFDebugLocDWO());
694 : // Assume all compile units have the same address byte size.
695 : // FIXME: We don't need AddressSize for split DWARF since relocatable
696 : // addresses cannot appear there. At the moment DWARFExpression requires it.
697 3 : DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 4);
698 3 : LocDWO->parse(LocData);
699 3 : return LocDWO.get();
700 : }
701 :
702 1374 : const DWARFDebugAranges *DWARFContext::getDebugAranges() {
703 1374 : if (Aranges)
704 : return Aranges.get();
705 :
706 218 : Aranges.reset(new DWARFDebugAranges());
707 218 : Aranges->generate(this);
708 218 : return Aranges.get();
709 : }
710 :
711 50 : const DWARFDebugFrame *DWARFContext::getDebugFrame() {
712 50 : if (DebugFrame)
713 : return DebugFrame.get();
714 :
715 : // There's a "bug" in the DWARFv3 standard with respect to the target address
716 : // size within debug frame sections. While DWARF is supposed to be independent
717 : // of its container, FDEs have fields with size being "target address size",
718 : // which isn't specified in DWARF in general. It's only specified for CUs, but
719 : // .eh_frame can appear without a .debug_info section. Follow the example of
720 : // other tools (libdwarf) and extract this from the container (ObjectFile
721 : // provides this information). This problem is fixed in DWARFv4
722 : // See this dwarf-discuss discussion for more details:
723 : // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
724 50 : DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
725 100 : isLittleEndian(), DObj->getAddressSize());
726 50 : DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
727 50 : DebugFrame->parse(debugFrameData);
728 50 : return DebugFrame.get();
729 : }
730 :
731 91 : const DWARFDebugFrame *DWARFContext::getEHFrame() {
732 91 : if (EHFrame)
733 : return EHFrame.get();
734 :
735 91 : DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
736 182 : DObj->getAddressSize());
737 91 : DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
738 91 : DebugFrame->parse(debugFrameData);
739 91 : return DebugFrame.get();
740 : }
741 :
742 206 : const DWARFDebugMacro *DWARFContext::getDebugMacro() {
743 206 : if (Macro)
744 : return Macro.get();
745 :
746 205 : DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0);
747 205 : Macro.reset(new DWARFDebugMacro());
748 205 : Macro->parse(MacinfoData);
749 205 : return Macro.get();
750 : }
751 :
752 : template <typename T>
753 363 : static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
754 : const DWARFSection &Section, StringRef StringSection,
755 : bool IsLittleEndian) {
756 363 : if (Cache)
757 : return *Cache;
758 : DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0);
759 : DataExtractor StrData(StringSection, IsLittleEndian, 0);
760 351 : Cache.reset(new T(AccelSection, StrData));
761 702 : if (Error E = Cache->extract())
762 48 : llvm::consumeError(std::move(E));
763 351 : return *Cache;
764 : }
765 317 :
766 : const DWARFDebugNames &DWARFContext::getDebugNames() {
767 : return getAccelTable(Names, *DObj, DObj->getDebugNamesSection(),
768 317 : DObj->getStringSection(), isLittleEndian());
769 : }
770 :
771 : const AppleAcceleratorTable &DWARFContext::getAppleNames() {
772 308 : return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
773 616 : DObj->getStringSection(), isLittleEndian());
774 48 : }
775 308 :
776 : const AppleAcceleratorTable &DWARFContext::getAppleTypes() {
777 46 : return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
778 : DObj->getStringSection(), isLittleEndian());
779 : }
780 46 :
781 : const AppleAcceleratorTable &DWARFContext::getAppleNamespaces() {
782 : return getAccelTable(AppleNamespaces, *DObj,
783 : DObj->getAppleNamespacesSection(),
784 43 : DObj->getStringSection(), isLittleEndian());
785 86 : }
786 0 :
787 43 : const AppleAcceleratorTable &DWARFContext::getAppleObjC() {
788 : return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
789 : DObj->getStringSection(), isLittleEndian());
790 46 : }
791 92 :
792 92 : const DWARFDebugLine::LineTable *
793 : DWARFContext::getLineTableForUnit(DWARFUnit *U) {
794 : Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable =
795 84 : getLineTableForUnit(U, dumpWarning);
796 168 : if (!ExpectedLineTable) {
797 168 : dumpWarning(ExpectedLineTable.takeError());
798 : return nullptr;
799 : }
800 85 : return *ExpectedLineTable;
801 170 : }
802 170 :
803 : Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
804 : DWARFUnit *U, std::function<void(Error)> RecoverableErrorCallback) {
805 83 : if (!Line)
806 83 : Line.reset(new DWARFDebugLine);
807 83 :
808 166 : auto UnitDIE = U->getUnitDIE();
809 : if (!UnitDIE)
810 : return nullptr;
811 65 :
812 130 : auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
813 130 : if (!Offset)
814 : return nullptr; // No line table for this compile unit.
815 :
816 : uint32_t stmtOffset = *Offset + U->getLineTableOffset();
817 3766 : // See if the line table is cached.
818 : if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
819 7532 : return lt;
820 3766 :
821 0 : // Make sure the offset is good before we try to parse.
822 0 : if (stmtOffset >= U->getLineSection().Data.size())
823 : return nullptr;
824 3766 :
825 : // We have to parse it first.
826 : DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
827 3792 : U->getAddressByteSize());
828 : return Line->getOrParseLineTable(lineData, stmtOffset, *this, U,
829 3792 : RecoverableErrorCallback);
830 721 : }
831 :
832 3792 : void DWARFContext::parseNormalUnits() {
833 : if (!NormalUnits.empty())
834 : return;
835 : NormalUnits.addUnitsForSection(*this, DObj->getInfoSection(), DW_SECT_INFO);
836 3792 : NormalUnits.finishedInfoUnits();
837 3792 : DObj->forEachTypesSections([&](const DWARFSection &S) {
838 : NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES);
839 : });
840 3602 : }
841 :
842 3590 : void DWARFContext::parseDWOUnits(bool Lazy) {
843 : if (!DWOUnits.empty())
844 : return;
845 : DWOUnits.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO,
846 1722 : Lazy);
847 : DWOUnits.finishedInfoUnits();
848 : DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
849 : DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy);
850 : });
851 839 : }
852 :
853 1678 : DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
854 : parseNormalUnits();
855 : return dyn_cast_or_null<DWARFCompileUnit>(
856 4790 : NormalUnits.getUnitForOffset(Offset));
857 4790 : }
858 :
859 3138 : DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
860 : // First, get the offset of the compile unit.
861 1569 : uint32_t CUOffset = getDebugAranges()->findAddress(Address);
862 36 : // Retrieve the compile unit.
863 1569 : return getCompileUnitForOffset(CUOffset);
864 : }
865 :
866 421 : DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
867 421 : DIEsForAddress Result;
868 :
869 582 : DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
870 : if (!CU)
871 : return Result;
872 291 :
873 14 : Result.CompileUnit = CU;
874 291 : Result.FunctionDIE = CU->getSubroutineForAddress(Address);
875 :
876 : std::vector<DWARFDie> Worklist;
877 1380 : Worklist.push_back(Result.FunctionDIE);
878 1380 : while (!Worklist.empty()) {
879 1380 : DWARFDie DIE = Worklist.back();
880 1380 : Worklist.pop_back();
881 :
882 : if (DIE.getTag() == DW_TAG_lexical_block &&
883 1374 : DIE.addressRangeContainsAddress(Address)) {
884 : Result.BlockDIE = DIE;
885 1374 : break;
886 : }
887 1374 :
888 : for (auto Child : DIE)
889 : Worklist.push_back(Child);
890 6 : }
891 6 :
892 : return Result;
893 6 : }
894 6 :
895 : static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
896 : uint64_t Address,
897 3 : FunctionNameKind Kind,
898 3 : std::string &FunctionName,
899 : uint32_t &StartLine) {
900 : // The address may correspond to instruction in some inlined function,
901 3 : // so we have to build the chain of inlined functions and take the
902 8 : // name of the topmost function in it.
903 7 : SmallVector<DWARFDie, 4> InlinedChain;
904 : CU->getInlinedChainForAddress(Address, InlinedChain);
905 : if (InlinedChain.empty())
906 10 : return false;
907 3 :
908 2 : const DWARFDie &DIE = InlinedChain[0];
909 2 : bool FoundResult = false;
910 : const char *Name = nullptr;
911 : if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
912 5 : FunctionName = Name;
913 4 : FoundResult = true;
914 : }
915 : if (auto DeclLineResult = DIE.getDeclLine()) {
916 : StartLine = DeclLineResult;
917 : FoundResult = true;
918 : }
919 451 :
920 : return FoundResult;
921 : }
922 :
923 : DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
924 : DILineInfoSpecifier Spec) {
925 : DILineInfo Result;
926 :
927 : DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
928 451 : if (!CU)
929 451 : return Result;
930 : getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind,
931 : Result.FunctionName,
932 : Result.StartLine);
933 : if (Spec.FLIKind != FileLineInfoKind::None) {
934 : if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
935 432 : LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
936 : Spec.FLIKind, Result);
937 : }
938 : return Result;
939 432 : }
940 432 :
941 : DILineInfoTable
942 : DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
943 : DILineInfoSpecifier Spec) {
944 : DILineInfoTable Lines;
945 : DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
946 : if (!CU)
947 675 : return Lines;
948 :
949 675 : std::string FunctionName = "<invalid>";
950 : uint32_t StartLine = 0;
951 675 : getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName,
952 675 : StartLine);
953 :
954 425 : // If the Specifier says we don't need FileLineInfo, just
955 425 : // return the top-most function at the starting address.
956 425 : if (Spec.FLIKind == FileLineInfoKind::None) {
957 425 : DILineInfo Result;
958 425 : Result.FunctionName = FunctionName;
959 425 : Result.StartLine = StartLine;
960 : Lines.push_back(std::make_pair(Address, Result));
961 : return Lines;
962 : }
963 :
964 : const DWARFLineTable *LineTable = getLineTableForUnit(CU);
965 :
966 26 : // Get the index of row we're looking for in the line table.
967 : std::vector<uint32_t> RowVector;
968 : if (!LineTable->lookupAddressRange(Address, Size, RowVector))
969 26 : return Lines;
970 26 :
971 : for (uint32_t RowIndex : RowVector) {
972 : // Take file number and line/column from the row.
973 26 : const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
974 26 : DILineInfo Result;
975 26 : LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
976 : Spec.FLIKind, Result.FileName);
977 : Result.FunctionName = FunctionName;
978 : Result.Line = Row.Line;
979 : Result.Column = Row.Column;
980 26 : Result.StartLine = StartLine;
981 0 : Lines.push_back(std::make_pair(Row.Address, Result));
982 : }
983 0 :
984 0 : return Lines;
985 : }
986 :
987 : DIInliningInfo
988 26 : DWARFContext::getInliningInfoForAddress(uint64_t Address,
989 : DILineInfoSpecifier Spec) {
990 : DIInliningInfo InliningInfo;
991 :
992 26 : DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
993 : if (!CU)
994 : return InliningInfo;
995 142 :
996 : const DWARFLineTable *LineTable = nullptr;
997 116 : SmallVector<DWARFDie, 4> InlinedChain;
998 116 : CU->getInlinedChainForAddress(Address, InlinedChain);
999 116 : if (InlinedChain.size() == 0) {
1000 : // If there is no DIE for address (e.g. it is in unavailable .dwo file),
1001 : // try to at least get file/line info from symbol table.
1002 116 : if (Spec.FLIKind != FileLineInfoKind::None) {
1003 116 : DILineInfo Frame;
1004 116 : LineTable = getLineTableForUnit(CU);
1005 232 : if (LineTable &&
1006 : LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
1007 : Spec.FLIKind, Frame))
1008 : InliningInfo.addFrame(Frame);
1009 : }
1010 : return InliningInfo;
1011 : }
1012 667 :
1013 : uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
1014 : for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
1015 : DWARFDie &FunctionDIE = InlinedChain[i];
1016 667 : DILineInfo Frame;
1017 667 : // Get function name if necessary.
1018 : if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
1019 : Frame.FunctionName = Name;
1020 : if (auto DeclLineResult = FunctionDIE.getDeclLine())
1021 : Frame.StartLine = DeclLineResult;
1022 281 : if (Spec.FLIKind != FileLineInfoKind::None) {
1023 281 : if (i == 0) {
1024 : // For the topmost frame, initialize the line table of this
1025 : // compile unit and fetch file/line info from it.
1026 21 : LineTable = getLineTableForUnit(CU);
1027 42 : // For the topmost routine, get file/line info from line table.
1028 21 : if (LineTable)
1029 42 : LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
1030 21 : Spec.FLIKind, Frame);
1031 : } else {
1032 : // Otherwise, use call file, call line and call column from
1033 : // previous DIE in inlined chain.
1034 : if (LineTable)
1035 : LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
1036 : Spec.FLIKind, Frame.FileName);
1037 260 : Frame.Line = CallLine;
1038 575 : Frame.Column = CallColumn;
1039 315 : Frame.Discriminator = CallDiscriminator;
1040 630 : }
1041 : // Get call file/line/column of a current DIE.
1042 315 : if (i + 1 < n) {
1043 : FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
1044 315 : CallDiscriminator);
1045 284 : }
1046 315 : }
1047 315 : InliningInfo.addFrame(Frame);
1048 : }
1049 : return InliningInfo;
1050 260 : }
1051 :
1052 260 : std::shared_ptr<DWARFContext>
1053 260 : DWARFContext::getDWOContext(StringRef AbsolutePath) {
1054 : if (auto S = DWP.lock()) {
1055 : DWARFContext *Ctxt = S->Context.get();
1056 : return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1057 : }
1058 55 :
1059 55 : std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
1060 :
1061 55 : if (auto S = Entry->lock()) {
1062 55 : DWARFContext *Ctxt = S->Context.get();
1063 55 : return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1064 : }
1065 :
1066 315 : Expected<OwningBinary<ObjectFile>> Obj = [&] {
1067 55 : if (!CheckedForDWP) {
1068 : SmallString<128> DWPName;
1069 : auto Obj = object::ObjectFile::createObjectFile(
1070 : this->DWPName.empty()
1071 : ? (DObj->getFileName() + ".dwp").toStringRef(DWPName)
1072 : : StringRef(this->DWPName));
1073 : if (Obj) {
1074 : Entry = &DWP;
1075 : return Obj;
1076 : } else {
1077 32 : CheckedForDWP = true;
1078 32 : // TODO: Should this error be handled (maybe in a high verbosity mode)
1079 : // before falling back to .dwo files?
1080 : consumeError(Obj.takeError());
1081 : }
1082 : }
1083 32 :
1084 : return object::ObjectFile::createObjectFile(AbsolutePath);
1085 32 : }();
1086 :
1087 : if (!Obj) {
1088 : // TODO: Actually report errors helpfully.
1089 : consumeError(Obj.takeError());
1090 : return nullptr;
1091 : }
1092 :
1093 : auto S = std::make_shared<DWOFile>();
1094 : S->File = std::move(Obj.get());
1095 : S->Context = DWARFContext::create(*S->File.getBinary());
1096 : *Entry = S;
1097 : auto *Ctxt = S->Context.get();
1098 : return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1099 : }
1100 :
1101 : static Error createError(const Twine &Reason, llvm::Error E) {
1102 : return make_error<StringError>(Reason + toString(std::move(E)),
1103 : inconvertibleErrorCode());
1104 : }
1105 :
1106 : /// SymInfo contains information about symbol: it's address
1107 : /// and section index which is -1LL for absolute symbols.
1108 : struct SymInfo {
1109 64 : uint64_t Address;
1110 : uint64_t SectionIndex;
1111 32 : };
1112 :
1113 26 : /// Returns the address of symbol relocation used against and a section index.
1114 : /// Used for futher relocations computation. Symbol's section load address is
1115 : static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj,
1116 : const RelocationRef &Reloc,
1117 : const LoadedObjectInfo *L,
1118 19 : std::map<SymbolRef, SymInfo> &Cache) {
1119 38 : SymInfo Ret = {0, (uint64_t)-1LL};
1120 19 : object::section_iterator RSec = Obj.section_end();
1121 : object::symbol_iterator Sym = Reloc.getSymbol();
1122 :
1123 : std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
1124 : // First calculate the address of the symbol or section as it appears
1125 20 : // in the object file
1126 40 : if (Sym != Obj.symbol_end()) {
1127 40 : bool New;
1128 : std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
1129 : if (!New)
1130 : return CacheIt->second;
1131 :
1132 : Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
1133 : if (!SymAddrOrErr)
1134 : return createError("failed to compute symbol address: ",
1135 : SymAddrOrErr.takeError());
1136 :
1137 : // Also remember what section this symbol is in for later
1138 : auto SectOrErr = Sym->getSection();
1139 12334 : if (!SectOrErr)
1140 : return createError("failed to get symbol section: ",
1141 : SectOrErr.takeError());
1142 :
1143 : RSec = *SectOrErr;
1144 12334 : Ret.Address = *SymAddrOrErr;
1145 12334 : } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1146 : RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
1147 12334 : Ret.Address = RSec->getAddress();
1148 : }
1149 :
1150 12334 : if (RSec != Obj.section_end())
1151 : Ret.SectionIndex = RSec->getIndex();
1152 12294 :
1153 12294 : // If we are given load addresses for the sections, we need to adjust:
1154 9078 : // SymAddr = (Address of Symbol Or Section in File) -
1155 : // (Address of Section in File) +
1156 : // (Load Address of Section)
1157 3216 : // RSec is now either the section being targeted or the section
1158 0 : // containing the symbol being targeted. In either case,
1159 0 : // we need to perform the same computation.
1160 : if (L && RSec != Obj.section_end())
1161 : if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1162 : Ret.Address += SectionLoadAddress - RSec->getAddress();
1163 3216 :
1164 0 : if (CacheIt != Cache.end())
1165 0 : CacheIt->second = Ret;
1166 :
1167 3216 : return Ret;
1168 3216 : }
1169 :
1170 13 : static bool isRelocScattered(const object::ObjectFile &Obj,
1171 13 : const RelocationRef &Reloc) {
1172 : const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
1173 : if (!MachObj)
1174 3256 : return false;
1175 2662 : // MachO also has relocations that point to sections and
1176 : // scattered relocations.
1177 : auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
1178 : return MachObj->isRelocationScattered(RelocInfo);
1179 : }
1180 :
1181 : ErrorPolicy DWARFContext::defaultErrorHandler(Error E) {
1182 : WithColor::error() << toString(std::move(E)) << '\n';
1183 : return ErrorPolicy::Continue;
1184 3256 : }
1185 27 :
1186 21 : namespace {
1187 : struct DWARFSectionMap final : public DWARFSection {
1188 3256 : RelocAddrMap Relocs;
1189 3216 : };
1190 :
1191 : class DWARFObjInMemory final : public DWARFObject {
1192 : bool IsLittleEndian;
1193 : uint8_t AddressSize;
1194 12334 : StringRef FileName;
1195 : const object::ObjectFile *Obj = nullptr;
1196 : std::vector<SectionName> SectionNames;
1197 :
1198 : using TypeSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
1199 : std::map<object::SectionRef, unsigned>>;
1200 :
1201 13 : TypeSectionMap TypesSections;
1202 13 : TypeSectionMap TypesDWOSections;
1203 :
1204 : DWARFSectionMap InfoSection;
1205 17 : DWARFSectionMap LocSection;
1206 34 : DWARFSectionMap LineSection;
1207 17 : DWARFSectionMap RangeSection;
1208 : DWARFSectionMap RnglistsSection;
1209 : DWARFSectionMap StringOffsetSection;
1210 : DWARFSectionMap InfoDWOSection;
1211 1479 : DWARFSectionMap LineDWOSection;
1212 : DWARFSectionMap LocDWOSection;
1213 : DWARFSectionMap StringOffsetDWOSection;
1214 : DWARFSectionMap RangeDWOSection;
1215 0 : DWARFSectionMap RnglistsDWOSection;
1216 : DWARFSectionMap AddrSection;
1217 : DWARFSectionMap AppleNamesSection;
1218 : DWARFSectionMap AppleTypesSection;
1219 : DWARFSectionMap AppleNamespacesSection;
1220 : DWARFSectionMap AppleObjCSection;
1221 : DWARFSectionMap DebugNamesSection;
1222 :
1223 : DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
1224 : return StringSwitch<DWARFSectionMap *>(Name)
1225 : .Case("debug_info", &InfoSection)
1226 : .Case("debug_loc", &LocSection)
1227 : .Case("debug_line", &LineSection)
1228 : .Case("debug_str_offsets", &StringOffsetSection)
1229 : .Case("debug_ranges", &RangeSection)
1230 : .Case("debug_rnglists", &RnglistsSection)
1231 : .Case("debug_info.dwo", &InfoDWOSection)
1232 : .Case("debug_loc.dwo", &LocDWOSection)
1233 : .Case("debug_line.dwo", &LineDWOSection)
1234 : .Case("debug_names", &DebugNamesSection)
1235 : .Case("debug_rnglists.dwo", &RnglistsDWOSection)
1236 : .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
1237 : .Case("debug_addr", &AddrSection)
1238 : .Case("apple_names", &AppleNamesSection)
1239 : .Case("apple_types", &AppleTypesSection)
1240 : .Case("apple_namespaces", &AppleNamespacesSection)
1241 : .Case("apple_namespac", &AppleNamespacesSection)
1242 : .Case("apple_objc", &AppleObjCSection)
1243 : .Default(nullptr);
1244 : }
1245 :
1246 : StringRef AbbrevSection;
1247 23905 : StringRef ARangeSection;
1248 23905 : StringRef DebugFrameSection;
1249 23905 : StringRef EHFrameSection;
1250 23905 : StringRef StringSection;
1251 23905 : StringRef MacinfoSection;
1252 23905 : StringRef PubNamesSection;
1253 23905 : StringRef PubTypesSection;
1254 23905 : StringRef GnuPubNamesSection;
1255 23905 : StringRef AbbrevDWOSection;
1256 23905 : StringRef StringDWOSection;
1257 23905 : StringRef GnuPubTypesSection;
1258 23905 : StringRef CUIndexSection;
1259 23905 : StringRef GdbIndexSection;
1260 23905 : StringRef TUIndexSection;
1261 23905 : StringRef LineStringSection;
1262 23905 :
1263 23905 : // A deque holding section data whose iterators are not invalidated when
1264 23905 : // new decompressed sections are inserted at the end.
1265 : std::deque<SmallString<0>> UncompressedSections;
1266 23905 :
1267 23905 : StringRef *mapSectionToMember(StringRef Name) {
1268 : if (DWARFSection *Sec = mapNameToDWARFSection(Name))
1269 : return &Sec->Data;
1270 : return StringSwitch<StringRef *>(Name)
1271 : .Case("debug_abbrev", &AbbrevSection)
1272 : .Case("debug_aranges", &ARangeSection)
1273 : .Case("debug_frame", &DebugFrameSection)
1274 : .Case("eh_frame", &EHFrameSection)
1275 : .Case("debug_str", &StringSection)
1276 : .Case("debug_macinfo", &MacinfoSection)
1277 : .Case("debug_pubnames", &PubNamesSection)
1278 : .Case("debug_pubtypes", &PubTypesSection)
1279 : .Case("debug_gnu_pubnames", &GnuPubNamesSection)
1280 : .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
1281 : .Case("debug_abbrev.dwo", &AbbrevDWOSection)
1282 : .Case("debug_str.dwo", &StringDWOSection)
1283 : .Case("debug_cu_index", &CUIndexSection)
1284 : .Case("debug_tu_index", &TUIndexSection)
1285 : .Case("gdb_index", &GdbIndexSection)
1286 : .Case("debug_line_str", &LineStringSection)
1287 : // Any more debug info sections go here.
1288 : .Default(nullptr);
1289 : }
1290 :
1291 21744 : /// If Sec is compressed section, decompresses and updates its contents
1292 21744 : /// provided by Data. Otherwise leaves it unchanged.
1293 5474 : Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
1294 16270 : StringRef &Data) {
1295 16270 : if (!Decompressor::isCompressed(Sec))
1296 16270 : return Error::success();
1297 16270 :
1298 16270 : Expected<Decompressor> Decompressor =
1299 16270 : Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
1300 16270 : if (!Decompressor)
1301 16270 : return Decompressor.takeError();
1302 16270 :
1303 16270 : SmallString<0> Out;
1304 16270 : if (auto Err = Decompressor->resizeAndDecompress(Out))
1305 16270 : return Err;
1306 16270 :
1307 16270 : UncompressedSections.push_back(std::move(Out));
1308 16270 : Data = UncompressedSections.back();
1309 16270 :
1310 27558 : return Error::success();
1311 : }
1312 :
1313 : public:
1314 : DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1315 : uint8_t AddrSize, bool IsLittleEndian)
1316 : : IsLittleEndian(IsLittleEndian) {
1317 21688 : for (const auto &SecIt : Sections) {
1318 : if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
1319 21688 : *SectionData = SecIt.second->getBuffer();
1320 : }
1321 : }
1322 : DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
1323 42 : function_ref<ErrorPolicy(Error)> HandleError)
1324 42 : : IsLittleEndian(Obj.isLittleEndian()),
1325 : AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
1326 : Obj(&Obj) {
1327 :
1328 76 : StringMap<unsigned> SectionAmountMap;
1329 : for (const SectionRef &Section : Obj.sections()) {
1330 : StringRef Name;
1331 37 : Section.getName(Name);
1332 37 : ++SectionAmountMap[Name];
1333 : SectionNames.push_back({ Name, true });
1334 :
1335 : // Skip BSS and Virtual sections, they aren't interesting.
1336 : if (Section.isBSS() || Section.isVirtual())
1337 : continue;
1338 19 :
1339 : // Skip sections stripped by dsymutil.
1340 57 : if (Section.isStripped())
1341 99 : continue;
1342 61 :
1343 61 : StringRef Data;
1344 : section_iterator RelocatedSection = Section.getRelocatedSection();
1345 19 : // Try to obtain an already relocated version of this section.
1346 1330 : // Else use the unrelocated section from the object file. We'll have to
1347 : // apply relocations ourselves later.
1348 1330 : if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data))
1349 2660 : Section.getContents(Data);
1350 2660 :
1351 : if (auto Err = maybeDecompress(Section, Name, Data)) {
1352 1328 : ErrorPolicy EP = HandleError(createError(
1353 23840 : "failed to decompress '" + Name + "', ", std::move(Err)));
1354 22512 : if (EP == ErrorPolicy::Halt)
1355 22512 : return;
1356 22512 : continue;
1357 22512 : }
1358 :
1359 : // Compressed sections names in GNU style starts from ".z",
1360 22512 : // at this point section is decompressed and we drop compression prefix.
1361 21559 : Name = Name.substr(
1362 : Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1363 :
1364 22029 : // Map platform specific debug section names to DWARF standard section
1365 : // names.
1366 : Name = Obj.mapDebugSectionName(Name);
1367 21688 :
1368 21688 : if (StringRef *SectionData = mapSectionToMember(Name)) {
1369 : *SectionData = Data;
1370 : if (Name == "debug_ranges") {
1371 : // FIXME: Use the other dwo range section when we emit it.
1372 21688 : RangeDWOSection.Data = Data;
1373 21688 : }
1374 : } else if (Name == "debug_types") {
1375 43376 : // Find debug_types data by section rather than name as there are
1376 5 : // multiple, comdat grouped, debug_types sections.
1377 5 : TypesSections[Section].Data = Data;
1378 5 : } else if (Name == "debug_types.dwo") {
1379 : TypesDWOSections[Section].Data = Data;
1380 : }
1381 :
1382 : if (RelocatedSection == Obj.section_end())
1383 : continue;
1384 :
1385 : StringRef RelSecName;
1386 21683 : StringRef RelSecData;
1387 : RelocatedSection->getName(RelSecName);
1388 :
1389 : // If the section we're relocating was relocated already by the JIT,
1390 21683 : // then we used the relocated version above, so we do not need to process
1391 : // relocations for it now.
1392 21683 : if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
1393 10431 : continue;
1394 :
1395 : // In Mach-o files, the relocations do not need to be applied if
1396 449 : // there is no load offset to apply. The value read at the
1397 : // relocation point already factors in the section address
1398 : // (actually applying the relocations will produce wrong results
1399 : // as the section address will be added twice).
1400 : if (!L && isa<MachOObjectFile>(&Obj))
1401 37 : continue;
1402 :
1403 15 : RelSecName = RelSecName.substr(
1404 : RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
1405 :
1406 21683 : // TODO: Add support for relocations in other sections as needed.
1407 : // Record relocations for the debug_info and debug_line sections.
1408 : DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
1409 8577 : RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
1410 8577 : if (!Map) {
1411 8577 : // Find debug_types relocs by section rather than name as there are
1412 : // multiple, comdat grouped, debug_types sections.
1413 : if (RelSecName == "debug_types")
1414 : Map =
1415 : &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
1416 8577 : .Relocs;
1417 : else if (RelSecName == "debug_types.dwo")
1418 : Map = &static_cast<DWARFSectionMap &>(
1419 : TypesDWOSections[*RelocatedSection])
1420 : .Relocs;
1421 : else
1422 : continue;
1423 : }
1424 8577 :
1425 : if (Section.relocation_begin() == Section.relocation_end())
1426 : continue;
1427 :
1428 2161 : // Symbol to [address, section index] cache mapping.
1429 : std::map<SymbolRef, SymInfo> AddrCache;
1430 : for (const RelocationRef &Reloc : Section.relocations()) {
1431 : // FIXME: it's not clear how to correctly handle scattered
1432 2161 : // relocations.
1433 2161 : if (isRelocScattered(Obj, Reloc))
1434 : continue;
1435 :
1436 : Expected<SymInfo> SymInfoOrErr =
1437 : getSymbolInfo(Obj, Reloc, L, AddrCache);
1438 36 : if (!SymInfoOrErr) {
1439 36 : if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
1440 : return;
1441 : continue;
1442 4 : }
1443 4 :
1444 : object::RelocVisitor V(Obj);
1445 : uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
1446 : if (V.error()) {
1447 : SmallString<32> Type;
1448 : Reloc.getTypeName(Type);
1449 989 : ErrorPolicy EP = HandleError(
1450 : createError("failed to compute relocation: " + Type + ", ",
1451 : errorCodeToError(object_error::parse_failed)));
1452 : if (EP == ErrorPolicy::Halt)
1453 : return;
1454 13285 : continue;
1455 : }
1456 : RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
1457 12334 : Map->insert({Reloc.getOffset(), Rel});
1458 15 : }
1459 : }
1460 :
1461 12334 : for (SectionName &S : SectionNames)
1462 12334 : if (SectionAmountMap[S.Name] > 1)
1463 0 : S.IsNameUnique = false;
1464 : }
1465 :
1466 : Optional<RelocAddrEntry> find(const DWARFSection &S,
1467 : uint64_t Pos) const override {
1468 : auto &Sec = static_cast<const DWARFSectionMap &>(S);
1469 12334 : RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
1470 12333 : if (AI == Sec.Relocs.end())
1471 : return None;
1472 15 : return AI->second;
1473 15 : }
1474 30 :
1475 15 : const object::ObjectFile *getFile() const override { return Obj; }
1476 15 :
1477 : ArrayRef<SectionName> getSectionNames() const override {
1478 : return SectionNames;
1479 : }
1480 12318 :
1481 12318 : bool isLittleEndian() const override { return IsLittleEndian; }
1482 : StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
1483 : const DWARFSection &getLineDWOSection() const override {
1484 : return LineDWOSection;
1485 23831 : }
1486 22503 : const DWARFSection &getLocDWOSection() const override {
1487 161 : return LocDWOSection;
1488 : }
1489 : StringRef getStringDWOSection() const override { return StringDWOSection; }
1490 73418 : const DWARFSection &getStringOffsetDWOSection() const override {
1491 : return StringOffsetDWOSection;
1492 : }
1493 73418 : const DWARFSection &getRangeDWOSection() const override {
1494 73418 : return RangeDWOSection;
1495 : }
1496 : const DWARFSection &getRnglistsDWOSection() const override {
1497 : return RnglistsDWOSection;
1498 : }
1499 689 : const DWARFSection &getAddrSection() const override { return AddrSection; }
1500 : StringRef getCUIndexSection() const override { return CUIndexSection; }
1501 32 : StringRef getGdbIndexSection() const override { return GdbIndexSection; }
1502 32 : StringRef getTUIndexSection() const override { return TUIndexSection; }
1503 :
1504 : // DWARF v5
1505 9487 : const DWARFSection &getStringOffsetSection() const override {
1506 1039 : return StringOffsetSection;
1507 1012 : }
1508 1012 : StringRef getLineStringSection() const override { return LineStringSection; }
1509 :
1510 863 : // Sections for DWARF5 split dwarf proposal.
1511 863 : const DWARFSection &getInfoDWOSection() const override {
1512 : return InfoDWOSection;
1513 1053 : }
1514 1022 : void forEachTypesDWOSections(
1515 1022 : function_ref<void(const DWARFSection &)> F) const override {
1516 : for (auto &P : TypesDWOSections)
1517 305 : F(P.second);
1518 305 : }
1519 :
1520 710 : StringRef getAbbrevSection() const override { return AbbrevSection; }
1521 710 : const DWARFSection &getLocSection() const override { return LocSection; }
1522 : StringRef getARangeSection() const override { return ARangeSection; }
1523 2430 : StringRef getDebugFrameSection() const override { return DebugFrameSection; }
1524 751 : StringRef getEHFrameSection() const override { return EHFrameSection; }
1525 696 : const DWARFSection &getLineSection() const override { return LineSection; }
1526 703 : StringRef getStringSection() const override { return StringSection; }
1527 : const DWARFSection &getRangeSection() const override { return RangeSection; }
1528 : const DWARFSection &getRnglistsSection() const override {
1529 2213 : return RnglistsSection;
1530 2213 : }
1531 : StringRef getMacinfoSection() const override { return MacinfoSection; }
1532 928 : StringRef getPubNamesSection() const override { return PubNamesSection; }
1533 : StringRef getPubTypesSection() const override { return PubTypesSection; }
1534 : StringRef getGnuPubNamesSection() const override {
1535 980 : return GnuPubNamesSection;
1536 980 : }
1537 : StringRef getGnuPubTypesSection() const override {
1538 291 : return GnuPubTypesSection;
1539 : }
1540 305 : const DWARFSection &getAppleNamesSection() const override {
1541 14 : return AppleNamesSection;
1542 291 : }
1543 : const DWARFSection &getAppleTypesSection() const override {
1544 1980 : return AppleTypesSection;
1545 940 : }
1546 976 : const DWARFSection &getAppleNamespacesSection() const override {
1547 886 : return AppleNamespacesSection;
1548 780 : }
1549 2895 : const DWARFSection &getAppleObjCSection() const override {
1550 3386 : return AppleObjCSection;
1551 2407 : }
1552 778 : const DWARFSection &getDebugNamesSection() const override {
1553 778 : return DebugNamesSection;
1554 : }
1555 205 :
1556 832 : StringRef getFileName() const override { return FileName; }
1557 827 : uint8_t getAddressSize() const override { return AddressSize; }
1558 725 : const DWARFSection &getInfoSection() const override { return InfoSection; }
1559 725 : void forEachTypesSections(
1560 : function_ref<void(const DWARFSection &)> F) const override {
1561 725 : for (auto &P : TypesSections)
1562 725 : F(P.second);
1563 : }
1564 1031 : };
1565 1031 : } // namespace
1566 :
1567 869 : std::unique_ptr<DWARFContext>
1568 869 : DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
1569 : function_ref<ErrorPolicy(Error)> HandleError,
1570 866 : std::string DWPName) {
1571 866 : auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
1572 : return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
1573 941 : }
1574 941 :
1575 : std::unique_ptr<DWARFContext>
1576 1004 : DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1577 1004 : uint8_t AddrSize, bool isLittleEndian) {
1578 : auto DObj =
1579 : llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
1580 711 : return llvm::make_unique<DWARFContext>(std::move(DObj), "");
1581 478 : }
1582 2157 :
1583 1436 : Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
1584 : // Detect the architecture from the object file. We usually don't need OS
1585 1473 : // info to lookup a target and create register info.
1586 37 : Triple TT;
1587 1436 : TT.setArch(Triple::ArchType(Obj.getArch()));
1588 : TT.setVendor(Triple::UnknownVendor);
1589 : TT.setOS(Triple::UnknownOS);
1590 : std::string TargetLookupError;
1591 : const Target *TheTarget =
1592 1330 : TargetRegistry::lookupTarget(TT.str(), TargetLookupError);
1593 : if (!TargetLookupError.empty())
1594 : return createStringError(errc::invalid_argument,
1595 2659 : TargetLookupError.c_str());
1596 1329 : RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
1597 : return Error::success();
1598 : }
1599 :
1600 19 : uint8_t DWARFContext::getCUAddrSize() {
1601 : // In theory, different compile units may have different address byte
1602 : // sizes, but for simplicity we just use the address byte size of the
1603 19 : // last compile unit. In practice the address size field is repeated across
1604 19 : // various DWARF headers (at least in version 5) to make it easier to dump
1605 : // them independently, not to enable varying the address size.
1606 : uint8_t Addr = 0;
1607 728 : for (const auto &CU : compile_units()) {
1608 : Addr = CU->getAddressByteSize();
1609 : break;
1610 : }
1611 728 : return Addr;
1612 728 : }
1613 728 :
1614 : void DWARFContext::dumpWarning(Error Warning) {
1615 : handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
1616 728 : WithColor::warning() << Info.message() << '\n';
1617 728 : });
1618 : }
|