1 //===- DWARFContext.cpp ---------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/SmallVector.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/BinaryFormat/Dwarf.h"
16 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
17 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
18 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
19 #include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
20 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
21 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
22 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
23 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
24 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
25 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
26 #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
27 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
28 #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
29 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
30 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
31 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
32 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
33 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
34 #include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
35 #include "llvm/MC/MCRegisterInfo.h"
36 #include "llvm/Object/Decompressor.h"
37 #include "llvm/Object/MachO.h"
38 #include "llvm/Object/ObjectFile.h"
39 #include "llvm/Object/RelocationResolver.h"
40 #include "llvm/Support/Casting.h"
41 #include "llvm/Support/DataExtractor.h"
42 #include "llvm/Support/Error.h"
43 #include "llvm/Support/Format.h"
44 #include "llvm/Support/LEB128.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"
59 using namespace dwarf
;
60 using namespace object
;
62 #define DEBUG_TYPE "dwarf"
64 using DWARFLineTable
= DWARFDebugLine::LineTable
;
65 using FileLineInfoKind
= DILineInfoSpecifier::FileLineInfoKind
;
66 using FunctionNameKind
= DILineInfoSpecifier::FunctionNameKind
;
68 DWARFContext::DWARFContext(std::unique_ptr
<const DWARFObject
> DObj
,
70 : DIContext(CK_DWARF
), DWPName(std::move(DWPName
)), DObj(std::move(DObj
)) {}
72 DWARFContext::~DWARFContext() = default;
74 /// Dump the UUID load command.
75 static void dumpUUID(raw_ostream
&OS
, const ObjectFile
&Obj
) {
76 auto *MachO
= dyn_cast
<MachOObjectFile
>(&Obj
);
79 for (auto LC
: MachO
->load_commands()) {
80 raw_ostream::uuid_t UUID
;
81 if (LC
.C
.cmd
== MachO::LC_UUID
) {
82 if (LC
.C
.cmdsize
< sizeof(UUID
) + sizeof(LC
.C
)) {
83 OS
<< "error: UUID load command is too short.\n";
87 memcpy(&UUID
, LC
.Ptr
+sizeof(LC
.C
), sizeof(UUID
));
89 Triple T
= MachO
->getArchTriple();
90 OS
<< " (" << T
.getArchName() << ')';
91 OS
<< ' ' << MachO
->getFileName() << '\n';
96 using ContributionCollection
=
97 std::vector
<Optional
<StrOffsetsContributionDescriptor
>>;
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 collectContributionData(DWARFContext::unit_iterator_range Units
) {
103 ContributionCollection Contributions
;
104 for (const auto &U
: Units
)
105 if (const auto &C
= U
->getStringOffsetsTableContribution())
106 Contributions
.push_back(C
);
107 // Sort the contributions so that any invalid ones are placed at
108 // the start of the contributions vector. This way they are reported
110 llvm::sort(Contributions
,
111 [](const Optional
<StrOffsetsContributionDescriptor
> &L
,
112 const Optional
<StrOffsetsContributionDescriptor
> &R
) {
114 return L
->Base
< R
->Base
;
118 // Uniquify contributions, as it is possible that units (specifically
119 // type units in dwo or dwp files) share contributions. We don't want
120 // to report them more than once.
122 std::unique(Contributions
.begin(), Contributions
.end(),
123 [](const Optional
<StrOffsetsContributionDescriptor
> &L
,
124 const Optional
<StrOffsetsContributionDescriptor
> &R
) {
126 return L
->Base
== R
->Base
&& L
->Size
== R
->Size
;
129 Contributions
.end());
130 return Contributions
;
133 static void dumpDWARFv5StringOffsetsSection(
134 raw_ostream
&OS
, StringRef SectionName
, const DWARFObject
&Obj
,
135 const DWARFSection
&StringOffsetsSection
, StringRef StringSection
,
136 DWARFContext::unit_iterator_range Units
, bool LittleEndian
) {
137 auto Contributions
= collectContributionData(Units
);
138 DWARFDataExtractor
StrOffsetExt(Obj
, StringOffsetsSection
, LittleEndian
, 0);
139 DataExtractor
StrData(StringSection
, LittleEndian
, 0);
140 uint64_t SectionSize
= StringOffsetsSection
.Data
.size();
142 for (auto &Contribution
: Contributions
) {
143 // Report an ill-formed contribution.
145 OS
<< "error: invalid contribution to string offsets table in section ."
146 << SectionName
<< ".\n";
150 dwarf::DwarfFormat Format
= Contribution
->getFormat();
151 uint16_t Version
= Contribution
->getVersion();
152 uint64_t ContributionHeader
= Contribution
->Base
;
153 // In DWARF v5 there is a contribution header that immediately precedes
154 // the string offsets base (the location we have previously retrieved from
155 // the CU DIE's DW_AT_str_offsets attribute). The header is located either
156 // 8 or 16 bytes before the base, depending on the contribution's format.
158 ContributionHeader
-= Format
== DWARF32
? 8 : 16;
160 // Detect overlapping contributions.
161 if (Offset
> ContributionHeader
) {
163 << "overlapping contributions to string offsets table in section ."
164 << SectionName
<< ".\n";
167 // Report a gap in the table.
168 if (Offset
< ContributionHeader
) {
169 OS
<< format("0x%8.8" PRIx64
": Gap, length = ", Offset
);
170 OS
<< (ContributionHeader
- Offset
) << "\n";
172 OS
<< format("0x%8.8" PRIx64
": ", ContributionHeader
);
173 // In DWARF v5 the contribution size in the descriptor does not equal
174 // the originally encoded length (it does not contain the length of the
175 // version field and the padding, a total of 4 bytes). Add them back in
177 OS
<< "Contribution size = " << (Contribution
->Size
+ (Version
< 5 ? 0 : 4))
178 << ", Format = " << (Format
== DWARF32
? "DWARF32" : "DWARF64")
179 << ", Version = " << Version
<< "\n";
181 Offset
= Contribution
->Base
;
182 unsigned EntrySize
= Contribution
->getDwarfOffsetByteSize();
183 while (Offset
- Contribution
->Base
< Contribution
->Size
) {
184 OS
<< format("0x%8.8" PRIx64
": ", Offset
);
185 uint64_t StringOffset
=
186 StrOffsetExt
.getRelocatedValue(EntrySize
, &Offset
);
187 OS
<< format("%8.8" PRIx64
" ", StringOffset
);
188 const char *S
= StrData
.getCStr(&StringOffset
);
190 OS
<< format("\"%s\"", S
);
194 // Report a gap at the end of the table.
195 if (Offset
< SectionSize
) {
196 OS
<< format("0x%8.8" PRIx64
": Gap, length = ", Offset
);
197 OS
<< (SectionSize
- Offset
) << "\n";
201 // Dump a DWARF string offsets section. This may be a DWARF v5 formatted
202 // string offsets section, where each compile or type unit contributes a
203 // number of entries (string offsets), with each contribution preceded by
204 // a header containing size and version number. Alternatively, it may be a
205 // monolithic series of string offsets, as generated by the pre-DWARF v5
206 // implementation of split DWARF.
207 static void dumpStringOffsetsSection(raw_ostream
&OS
, StringRef SectionName
,
208 const DWARFObject
&Obj
,
209 const DWARFSection
&StringOffsetsSection
,
210 StringRef StringSection
,
211 DWARFContext::unit_iterator_range Units
,
212 bool LittleEndian
, unsigned MaxVersion
) {
213 // If we have at least one (compile or type) unit with DWARF v5 or greater,
214 // we assume that the section is formatted like a DWARF v5 string offsets
217 dumpDWARFv5StringOffsetsSection(OS
, SectionName
, Obj
, StringOffsetsSection
,
218 StringSection
, Units
, LittleEndian
);
220 DataExtractor
strOffsetExt(StringOffsetsSection
.Data
, LittleEndian
, 0);
222 uint64_t size
= StringOffsetsSection
.Data
.size();
223 // Ensure that size is a multiple of the size of an entry.
224 if (size
& ((uint64_t)(sizeof(uint32_t) - 1))) {
225 OS
<< "error: size of ." << SectionName
<< " is not a multiple of "
226 << sizeof(uint32_t) << ".\n";
227 size
&= -(uint64_t)sizeof(uint32_t);
229 DataExtractor
StrData(StringSection
, LittleEndian
, 0);
230 while (offset
< size
) {
231 OS
<< format("0x%8.8" PRIx64
": ", offset
);
232 uint64_t StringOffset
= strOffsetExt
.getU32(&offset
);
233 OS
<< format("%8.8" PRIx64
" ", StringOffset
);
234 const char *S
= StrData
.getCStr(&StringOffset
);
236 OS
<< format("\"%s\"", S
);
242 // Dump the .debug_addr section.
243 static void dumpAddrSection(raw_ostream
&OS
, DWARFDataExtractor
&AddrData
,
244 DIDumpOptions DumpOpts
, uint16_t Version
,
247 while (AddrData
.isValidOffset(Offset
)) {
248 DWARFDebugAddrTable AddrTable
;
249 uint64_t TableOffset
= Offset
;
250 if (Error Err
= AddrTable
.extract(AddrData
, &Offset
, Version
, AddrSize
,
251 DWARFContext::dumpWarning
)) {
252 WithColor::error() << toString(std::move(Err
)) << '\n';
253 // Keep going after an error, if we can, assuming that the length field
254 // could be read. If it couldn't, stop reading the section.
255 if (!AddrTable
.hasValidLength())
257 Offset
= TableOffset
+ AddrTable
.getLength();
259 AddrTable
.dump(OS
, DumpOpts
);
264 // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
265 static void dumpRnglistsSection(
266 raw_ostream
&OS
, DWARFDataExtractor
&rnglistData
,
267 llvm::function_ref
<Optional
<object::SectionedAddress
>(uint32_t)>
269 DIDumpOptions DumpOpts
) {
271 while (rnglistData
.isValidOffset(Offset
)) {
272 llvm::DWARFDebugRnglistTable Rnglists
;
273 uint64_t TableOffset
= Offset
;
274 if (Error Err
= Rnglists
.extract(rnglistData
, &Offset
)) {
275 WithColor::error() << toString(std::move(Err
)) << '\n';
276 uint64_t Length
= Rnglists
.length();
277 // Keep going after an error, if we can, assuming that the length field
278 // could be read. If it couldn't, stop reading the section.
281 Offset
= TableOffset
+ Length
;
283 Rnglists
.dump(OS
, LookupPooledAddress
, DumpOpts
);
288 static void dumpLoclistsSection(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
289 DWARFDataExtractor Data
,
290 const MCRegisterInfo
*MRI
,
291 Optional
<uint64_t> DumpOffset
) {
294 while (Data
.isValidOffset(Offset
)) {
295 DWARFListTableHeader
Header(".debug_loclists", "locations");
296 if (Error E
= Header
.extract(Data
, &Offset
)) {
297 WithColor::error() << toString(std::move(E
)) << '\n';
301 Header
.dump(OS
, DumpOpts
);
302 DataExtractor
LocData(Data
.getData(),
303 Data
.isLittleEndian(), Header
.getAddrSize());
305 DWARFDebugLoclists Loclists
;
306 uint64_t EndOffset
= Header
.length() + Header
.getHeaderOffset();
307 Loclists
.parse(LocData
, Offset
, EndOffset
, Header
.getVersion());
308 Loclists
.dump(OS
, 0, MRI
, DumpOpts
, DumpOffset
);
313 void DWARFContext::dump(
314 raw_ostream
&OS
, DIDumpOptions DumpOpts
,
315 std::array
<Optional
<uint64_t>, DIDT_ID_Count
> DumpOffsets
) {
317 uint64_t DumpType
= DumpOpts
.DumpType
;
319 StringRef Extension
= sys::path::extension(DObj
->getFileName());
320 bool IsDWO
= (Extension
== ".dwo") || (Extension
== ".dwp");
322 // Print UUID header.
323 const auto *ObjFile
= DObj
->getFile();
324 if (DumpType
& DIDT_UUID
)
325 dumpUUID(OS
, *ObjFile
);
327 // Print a header for each explicitly-requested section.
328 // Otherwise just print one for non-empty sections.
329 // Only print empty .dwo section headers when dumping a .dwo file.
330 bool Explicit
= DumpType
!= DIDT_All
&& !IsDWO
;
331 bool ExplicitDWO
= Explicit
&& IsDWO
;
332 auto shouldDump
= [&](bool Explicit
, const char *Name
, unsigned ID
,
333 StringRef Section
) -> Optional
<uint64_t> * {
334 unsigned Mask
= 1U << ID
;
335 bool Should
= (DumpType
& Mask
) && (Explicit
|| !Section
.empty());
338 OS
<< "\n" << Name
<< " contents:\n";
339 return &DumpOffsets
[ID
];
342 // Dump individual sections.
343 if (shouldDump(Explicit
, ".debug_abbrev", DIDT_ID_DebugAbbrev
,
344 DObj
->getAbbrevSection()))
345 getDebugAbbrev()->dump(OS
);
346 if (shouldDump(ExplicitDWO
, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev
,
347 DObj
->getAbbrevDWOSection()))
348 getDebugAbbrevDWO()->dump(OS
);
350 auto dumpDebugInfo
= [&](const char *Name
, unit_iterator_range Units
) {
351 OS
<< '\n' << Name
<< " contents:\n";
352 if (auto DumpOffset
= DumpOffsets
[DIDT_ID_DebugInfo
])
353 for (const auto &U
: Units
)
354 U
->getDIEForOffset(DumpOffset
.getValue())
355 .dump(OS
, 0, DumpOpts
.noImplicitRecursion());
357 for (const auto &U
: Units
)
358 U
->dump(OS
, DumpOpts
);
360 if ((DumpType
& DIDT_DebugInfo
)) {
361 if (Explicit
|| getNumCompileUnits())
362 dumpDebugInfo(".debug_info", info_section_units());
363 if (ExplicitDWO
|| getNumDWOCompileUnits())
364 dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
367 auto dumpDebugType
= [&](const char *Name
, unit_iterator_range Units
) {
368 OS
<< '\n' << Name
<< " contents:\n";
369 for (const auto &U
: Units
)
370 if (auto DumpOffset
= DumpOffsets
[DIDT_ID_DebugTypes
])
371 U
->getDIEForOffset(*DumpOffset
)
372 .dump(OS
, 0, DumpOpts
.noImplicitRecursion());
374 U
->dump(OS
, DumpOpts
);
376 if ((DumpType
& DIDT_DebugTypes
)) {
377 if (Explicit
|| getNumTypeUnits())
378 dumpDebugType(".debug_types", types_section_units());
379 if (ExplicitDWO
|| getNumDWOTypeUnits())
380 dumpDebugType(".debug_types.dwo", dwo_types_section_units());
383 if (const auto *Off
= shouldDump(Explicit
, ".debug_loc", DIDT_ID_DebugLoc
,
384 DObj
->getLocSection().Data
)) {
385 getDebugLoc()->dump(OS
, getRegisterInfo(), DumpOpts
, *Off
);
387 if (const auto *Off
=
388 shouldDump(Explicit
, ".debug_loclists", DIDT_ID_DebugLoclists
,
389 DObj
->getLoclistsSection().Data
)) {
390 DWARFDataExtractor
Data(*DObj
, DObj
->getLoclistsSection(), isLittleEndian(),
392 dumpLoclistsSection(OS
, DumpOpts
, Data
, getRegisterInfo(), *Off
);
394 if (const auto *Off
=
395 shouldDump(ExplicitDWO
, ".debug_loc.dwo", DIDT_ID_DebugLoc
,
396 DObj
->getLocDWOSection().Data
)) {
397 getDebugLocDWO()->dump(OS
, 0, getRegisterInfo(), DumpOpts
, *Off
);
400 if (const auto *Off
= shouldDump(Explicit
, ".debug_frame", DIDT_ID_DebugFrame
,
401 DObj
->getFrameSection().Data
))
402 getDebugFrame()->dump(OS
, getRegisterInfo(), *Off
);
404 if (const auto *Off
= shouldDump(Explicit
, ".eh_frame", DIDT_ID_DebugFrame
,
405 DObj
->getEHFrameSection().Data
))
406 getEHFrame()->dump(OS
, getRegisterInfo(), *Off
);
408 if (DumpType
& DIDT_DebugMacro
) {
409 if (Explicit
|| !getDebugMacro()->empty()) {
410 OS
<< "\n.debug_macinfo contents:\n";
411 getDebugMacro()->dump(OS
);
415 if (shouldDump(Explicit
, ".debug_aranges", DIDT_ID_DebugAranges
,
416 DObj
->getArangesSection())) {
418 DataExtractor
arangesData(DObj
->getArangesSection(), isLittleEndian(), 0);
419 DWARFDebugArangeSet set
;
420 while (set
.extract(arangesData
, &offset
))
424 auto DumpLineSection
= [&](DWARFDebugLine::SectionParser Parser
,
425 DIDumpOptions DumpOpts
,
426 Optional
<uint64_t> DumpOffset
) {
427 while (!Parser
.done()) {
428 if (DumpOffset
&& Parser
.getOffset() != *DumpOffset
) {
429 Parser
.skip(dumpWarning
);
432 OS
<< "debug_line[" << format("0x%8.8" PRIx64
, Parser
.getOffset())
434 if (DumpOpts
.Verbose
) {
435 Parser
.parseNext(dumpWarning
, dumpWarning
, &OS
);
437 DWARFDebugLine::LineTable LineTable
=
438 Parser
.parseNext(dumpWarning
, dumpWarning
);
439 LineTable
.dump(OS
, DumpOpts
);
444 if (const auto *Off
= shouldDump(Explicit
, ".debug_line", DIDT_ID_DebugLine
,
445 DObj
->getLineSection().Data
)) {
446 DWARFDataExtractor
LineData(*DObj
, DObj
->getLineSection(), isLittleEndian(),
448 DWARFDebugLine::SectionParser
Parser(LineData
, *this, compile_units(),
450 DumpLineSection(Parser
, DumpOpts
, *Off
);
453 if (const auto *Off
=
454 shouldDump(ExplicitDWO
, ".debug_line.dwo", DIDT_ID_DebugLine
,
455 DObj
->getLineDWOSection().Data
)) {
456 DWARFDataExtractor
LineData(*DObj
, DObj
->getLineDWOSection(),
457 isLittleEndian(), 0);
458 DWARFDebugLine::SectionParser
Parser(LineData
, *this, dwo_compile_units(),
460 DumpLineSection(Parser
, DumpOpts
, *Off
);
463 if (shouldDump(Explicit
, ".debug_cu_index", DIDT_ID_DebugCUIndex
,
464 DObj
->getCUIndexSection())) {
465 getCUIndex().dump(OS
);
468 if (shouldDump(Explicit
, ".debug_tu_index", DIDT_ID_DebugTUIndex
,
469 DObj
->getTUIndexSection())) {
470 getTUIndex().dump(OS
);
473 if (shouldDump(Explicit
, ".debug_str", DIDT_ID_DebugStr
,
474 DObj
->getStrSection())) {
475 DataExtractor
strData(DObj
->getStrSection(), isLittleEndian(), 0);
477 uint64_t strOffset
= 0;
478 while (const char *s
= strData
.getCStr(&offset
)) {
479 OS
<< format("0x%8.8" PRIx64
": \"%s\"\n", strOffset
, s
);
483 if (shouldDump(ExplicitDWO
, ".debug_str.dwo", DIDT_ID_DebugStr
,
484 DObj
->getStrDWOSection())) {
485 DataExtractor
strDWOData(DObj
->getStrDWOSection(), isLittleEndian(), 0);
487 uint64_t strDWOOffset
= 0;
488 while (const char *s
= strDWOData
.getCStr(&offset
)) {
489 OS
<< format("0x%8.8" PRIx64
": \"%s\"\n", strDWOOffset
, s
);
490 strDWOOffset
= offset
;
493 if (shouldDump(Explicit
, ".debug_line_str", DIDT_ID_DebugLineStr
,
494 DObj
->getLineStrSection())) {
495 DataExtractor
strData(DObj
->getLineStrSection(), isLittleEndian(), 0);
497 uint64_t strOffset
= 0;
498 while (const char *s
= strData
.getCStr(&offset
)) {
499 OS
<< format("0x%8.8" PRIx64
": \"", strOffset
);
506 if (shouldDump(Explicit
, ".debug_addr", DIDT_ID_DebugAddr
,
507 DObj
->getAddrSection().Data
)) {
508 DWARFDataExtractor
AddrData(*DObj
, DObj
->getAddrSection(),
509 isLittleEndian(), 0);
510 dumpAddrSection(OS
, AddrData
, DumpOpts
, getMaxVersion(), getCUAddrSize());
513 if (shouldDump(Explicit
, ".debug_ranges", DIDT_ID_DebugRanges
,
514 DObj
->getRangesSection().Data
)) {
515 uint8_t savedAddressByteSize
= getCUAddrSize();
516 DWARFDataExtractor
rangesData(*DObj
, DObj
->getRangesSection(),
517 isLittleEndian(), savedAddressByteSize
);
519 DWARFDebugRangeList rangeList
;
520 while (rangesData
.isValidOffset(offset
)) {
521 if (Error E
= rangeList
.extract(rangesData
, &offset
)) {
522 WithColor::error() << toString(std::move(E
)) << '\n';
529 auto LookupPooledAddress
= [&](uint32_t Index
) -> Optional
<SectionedAddress
> {
530 const auto &CUs
= compile_units();
531 auto I
= CUs
.begin();
534 return (*I
)->getAddrOffsetSectionItem(Index
);
537 if (shouldDump(Explicit
, ".debug_rnglists", DIDT_ID_DebugRnglists
,
538 DObj
->getRnglistsSection().Data
)) {
539 DWARFDataExtractor
RnglistData(*DObj
, DObj
->getRnglistsSection(),
540 isLittleEndian(), 0);
541 dumpRnglistsSection(OS
, RnglistData
, LookupPooledAddress
, DumpOpts
);
544 if (shouldDump(ExplicitDWO
, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists
,
545 DObj
->getRnglistsDWOSection().Data
)) {
546 DWARFDataExtractor
RnglistData(*DObj
, DObj
->getRnglistsDWOSection(),
547 isLittleEndian(), 0);
548 dumpRnglistsSection(OS
, RnglistData
, LookupPooledAddress
, DumpOpts
);
551 if (shouldDump(Explicit
, ".debug_pubnames", DIDT_ID_DebugPubnames
,
552 DObj
->getPubnamesSection().Data
))
553 DWARFDebugPubTable(*DObj
, DObj
->getPubnamesSection(), isLittleEndian(), false)
556 if (shouldDump(Explicit
, ".debug_pubtypes", DIDT_ID_DebugPubtypes
,
557 DObj
->getPubtypesSection().Data
))
558 DWARFDebugPubTable(*DObj
, DObj
->getPubtypesSection(), isLittleEndian(), false)
561 if (shouldDump(Explicit
, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames
,
562 DObj
->getGnuPubnamesSection().Data
))
563 DWARFDebugPubTable(*DObj
, DObj
->getGnuPubnamesSection(), isLittleEndian(),
567 if (shouldDump(Explicit
, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes
,
568 DObj
->getGnuPubtypesSection().Data
))
569 DWARFDebugPubTable(*DObj
, DObj
->getGnuPubtypesSection(), isLittleEndian(),
573 if (shouldDump(Explicit
, ".debug_str_offsets", DIDT_ID_DebugStrOffsets
,
574 DObj
->getStrOffsetsSection().Data
))
575 dumpStringOffsetsSection(OS
, "debug_str_offsets", *DObj
,
576 DObj
->getStrOffsetsSection(),
577 DObj
->getStrSection(), normal_units(),
578 isLittleEndian(), getMaxVersion());
579 if (shouldDump(ExplicitDWO
, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets
,
580 DObj
->getStrOffsetsDWOSection().Data
))
581 dumpStringOffsetsSection(OS
, "debug_str_offsets.dwo", *DObj
,
582 DObj
->getStrOffsetsDWOSection(),
583 DObj
->getStrDWOSection(), dwo_units(),
584 isLittleEndian(), getMaxDWOVersion());
586 if (shouldDump(Explicit
, ".gdb_index", DIDT_ID_GdbIndex
,
587 DObj
->getGdbIndexSection())) {
588 getGdbIndex().dump(OS
);
591 if (shouldDump(Explicit
, ".apple_names", DIDT_ID_AppleNames
,
592 DObj
->getAppleNamesSection().Data
))
593 getAppleNames().dump(OS
);
595 if (shouldDump(Explicit
, ".apple_types", DIDT_ID_AppleTypes
,
596 DObj
->getAppleTypesSection().Data
))
597 getAppleTypes().dump(OS
);
599 if (shouldDump(Explicit
, ".apple_namespaces", DIDT_ID_AppleNamespaces
,
600 DObj
->getAppleNamespacesSection().Data
))
601 getAppleNamespaces().dump(OS
);
603 if (shouldDump(Explicit
, ".apple_objc", DIDT_ID_AppleObjC
,
604 DObj
->getAppleObjCSection().Data
))
605 getAppleObjC().dump(OS
);
606 if (shouldDump(Explicit
, ".debug_names", DIDT_ID_DebugNames
,
607 DObj
->getNamesSection().Data
))
608 getDebugNames().dump(OS
);
611 DWARFCompileUnit
*DWARFContext::getDWOCompileUnitForHash(uint64_t Hash
) {
612 parseDWOUnits(LazyParse
);
614 if (const auto &CUI
= getCUIndex()) {
615 if (const auto *R
= CUI
.getFromHash(Hash
))
616 return dyn_cast_or_null
<DWARFCompileUnit
>(
617 DWOUnits
.getUnitForIndexEntry(*R
));
621 // If there's no index, just search through the CUs in the DWO - there's
622 // probably only one unless this is something like LTO - though an in-process
623 // built/cached lookup table could be used in that case to improve repeated
624 // lookups of different CUs in the DWO.
625 for (const auto &DWOCU
: dwo_compile_units()) {
626 // Might not have parsed DWO ID yet.
627 if (!DWOCU
->getDWOId()) {
628 if (Optional
<uint64_t> DWOId
=
629 toUnsigned(DWOCU
->getUnitDIE().find(DW_AT_GNU_dwo_id
)))
630 DWOCU
->setDWOId(*DWOId
);
635 if (DWOCU
->getDWOId() == Hash
)
636 return dyn_cast
<DWARFCompileUnit
>(DWOCU
.get());
641 DWARFDie
DWARFContext::getDIEForOffset(uint64_t Offset
) {
643 if (auto *CU
= NormalUnits
.getUnitForOffset(Offset
))
644 return CU
->getDIEForOffset(Offset
);
648 bool DWARFContext::verify(raw_ostream
&OS
, DIDumpOptions DumpOpts
) {
650 DWARFVerifier
verifier(OS
, *this, DumpOpts
);
652 Success
&= verifier
.handleDebugAbbrev();
653 if (DumpOpts
.DumpType
& DIDT_DebugInfo
)
654 Success
&= verifier
.handleDebugInfo();
655 if (DumpOpts
.DumpType
& DIDT_DebugLine
)
656 Success
&= verifier
.handleDebugLine();
657 Success
&= verifier
.handleAccelTables();
661 const DWARFUnitIndex
&DWARFContext::getCUIndex() {
665 DataExtractor
CUIndexData(DObj
->getCUIndexSection(), isLittleEndian(), 0);
667 CUIndex
= std::make_unique
<DWARFUnitIndex
>(DW_SECT_INFO
);
668 CUIndex
->parse(CUIndexData
);
672 const DWARFUnitIndex
&DWARFContext::getTUIndex() {
676 DataExtractor
TUIndexData(DObj
->getTUIndexSection(), isLittleEndian(), 0);
678 TUIndex
= std::make_unique
<DWARFUnitIndex
>(DW_SECT_TYPES
);
679 TUIndex
->parse(TUIndexData
);
683 DWARFGdbIndex
&DWARFContext::getGdbIndex() {
687 DataExtractor
GdbIndexData(DObj
->getGdbIndexSection(), true /*LE*/, 0);
688 GdbIndex
= std::make_unique
<DWARFGdbIndex
>();
689 GdbIndex
->parse(GdbIndexData
);
693 const DWARFDebugAbbrev
*DWARFContext::getDebugAbbrev() {
697 DataExtractor
abbrData(DObj
->getAbbrevSection(), isLittleEndian(), 0);
699 Abbrev
.reset(new DWARFDebugAbbrev());
700 Abbrev
->extract(abbrData
);
704 const DWARFDebugAbbrev
*DWARFContext::getDebugAbbrevDWO() {
706 return AbbrevDWO
.get();
708 DataExtractor
abbrData(DObj
->getAbbrevDWOSection(), isLittleEndian(), 0);
709 AbbrevDWO
.reset(new DWARFDebugAbbrev());
710 AbbrevDWO
->extract(abbrData
);
711 return AbbrevDWO
.get();
714 const DWARFDebugLoc
*DWARFContext::getDebugLoc() {
718 Loc
.reset(new DWARFDebugLoc
);
719 // Assume all units have the same address byte size.
720 if (getNumCompileUnits()) {
721 DWARFDataExtractor
LocData(*DObj
, DObj
->getLocSection(), isLittleEndian(),
722 getUnitAtIndex(0)->getAddressByteSize());
728 const DWARFDebugLoclists
*DWARFContext::getDebugLocDWO() {
732 LocDWO
.reset(new DWARFDebugLoclists());
733 // Assume all compile units have the same address byte size.
734 // FIXME: We don't need AddressSize for split DWARF since relocatable
735 // addresses cannot appear there. At the moment DWARFExpression requires it.
736 DataExtractor
LocData(DObj
->getLocDWOSection().Data
, isLittleEndian(), 4);
737 // Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and
738 // that means we are parsing the new style .debug_loc (pre-standatized version
739 // of the .debug_loclists).
740 LocDWO
->parse(LocData
, 0, LocData
.getData().size(), 4 /* Version */);
744 const DWARFDebugAranges
*DWARFContext::getDebugAranges() {
746 return Aranges
.get();
748 Aranges
.reset(new DWARFDebugAranges());
749 Aranges
->generate(this);
750 return Aranges
.get();
753 const DWARFDebugFrame
*DWARFContext::getDebugFrame() {
755 return DebugFrame
.get();
757 // There's a "bug" in the DWARFv3 standard with respect to the target address
758 // size within debug frame sections. While DWARF is supposed to be independent
759 // of its container, FDEs have fields with size being "target address size",
760 // which isn't specified in DWARF in general. It's only specified for CUs, but
761 // .eh_frame can appear without a .debug_info section. Follow the example of
762 // other tools (libdwarf) and extract this from the container (ObjectFile
763 // provides this information). This problem is fixed in DWARFv4
764 // See this dwarf-discuss discussion for more details:
765 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
766 DWARFDataExtractor
debugFrameData(*DObj
, DObj
->getFrameSection(),
767 isLittleEndian(), DObj
->getAddressSize());
768 DebugFrame
.reset(new DWARFDebugFrame(getArch(), false /* IsEH */));
769 DebugFrame
->parse(debugFrameData
);
770 return DebugFrame
.get();
773 const DWARFDebugFrame
*DWARFContext::getEHFrame() {
775 return EHFrame
.get();
777 DWARFDataExtractor
debugFrameData(*DObj
, DObj
->getEHFrameSection(),
778 isLittleEndian(), DObj
->getAddressSize());
779 DebugFrame
.reset(new DWARFDebugFrame(getArch(), true /* IsEH */));
780 DebugFrame
->parse(debugFrameData
);
781 return DebugFrame
.get();
784 const DWARFDebugMacro
*DWARFContext::getDebugMacro() {
788 DataExtractor
MacinfoData(DObj
->getMacinfoSection(), isLittleEndian(), 0);
789 Macro
.reset(new DWARFDebugMacro());
790 Macro
->parse(MacinfoData
);
794 template <typename T
>
795 static T
&getAccelTable(std::unique_ptr
<T
> &Cache
, const DWARFObject
&Obj
,
796 const DWARFSection
&Section
, StringRef StringSection
,
797 bool IsLittleEndian
) {
800 DWARFDataExtractor
AccelSection(Obj
, Section
, IsLittleEndian
, 0);
801 DataExtractor
StrData(StringSection
, IsLittleEndian
, 0);
802 Cache
.reset(new T(AccelSection
, StrData
));
803 if (Error E
= Cache
->extract())
804 llvm::consumeError(std::move(E
));
808 const DWARFDebugNames
&DWARFContext::getDebugNames() {
809 return getAccelTable(Names
, *DObj
, DObj
->getNamesSection(),
810 DObj
->getStrSection(), isLittleEndian());
813 const AppleAcceleratorTable
&DWARFContext::getAppleNames() {
814 return getAccelTable(AppleNames
, *DObj
, DObj
->getAppleNamesSection(),
815 DObj
->getStrSection(), isLittleEndian());
818 const AppleAcceleratorTable
&DWARFContext::getAppleTypes() {
819 return getAccelTable(AppleTypes
, *DObj
, DObj
->getAppleTypesSection(),
820 DObj
->getStrSection(), isLittleEndian());
823 const AppleAcceleratorTable
&DWARFContext::getAppleNamespaces() {
824 return getAccelTable(AppleNamespaces
, *DObj
,
825 DObj
->getAppleNamespacesSection(),
826 DObj
->getStrSection(), isLittleEndian());
829 const AppleAcceleratorTable
&DWARFContext::getAppleObjC() {
830 return getAccelTable(AppleObjC
, *DObj
, DObj
->getAppleObjCSection(),
831 DObj
->getStrSection(), isLittleEndian());
834 const DWARFDebugLine::LineTable
*
835 DWARFContext::getLineTableForUnit(DWARFUnit
*U
) {
836 Expected
<const DWARFDebugLine::LineTable
*> ExpectedLineTable
=
837 getLineTableForUnit(U
, dumpWarning
);
838 if (!ExpectedLineTable
) {
839 dumpWarning(ExpectedLineTable
.takeError());
842 return *ExpectedLineTable
;
845 Expected
<const DWARFDebugLine::LineTable
*> DWARFContext::getLineTableForUnit(
846 DWARFUnit
*U
, std::function
<void(Error
)> RecoverableErrorCallback
) {
848 Line
.reset(new DWARFDebugLine
);
850 auto UnitDIE
= U
->getUnitDIE();
854 auto Offset
= toSectionOffset(UnitDIE
.find(DW_AT_stmt_list
));
856 return nullptr; // No line table for this compile unit.
858 uint64_t stmtOffset
= *Offset
+ U
->getLineTableOffset();
859 // See if the line table is cached.
860 if (const DWARFLineTable
*lt
= Line
->getLineTable(stmtOffset
))
863 // Make sure the offset is good before we try to parse.
864 if (stmtOffset
>= U
->getLineSection().Data
.size())
867 // We have to parse it first.
868 DWARFDataExtractor
lineData(*DObj
, U
->getLineSection(), isLittleEndian(),
869 U
->getAddressByteSize());
870 return Line
->getOrParseLineTable(lineData
, stmtOffset
, *this, U
,
871 RecoverableErrorCallback
);
874 void DWARFContext::parseNormalUnits() {
875 if (!NormalUnits
.empty())
877 DObj
->forEachInfoSections([&](const DWARFSection
&S
) {
878 NormalUnits
.addUnitsForSection(*this, S
, DW_SECT_INFO
);
880 NormalUnits
.finishedInfoUnits();
881 DObj
->forEachTypesSections([&](const DWARFSection
&S
) {
882 NormalUnits
.addUnitsForSection(*this, S
, DW_SECT_TYPES
);
886 void DWARFContext::parseDWOUnits(bool Lazy
) {
887 if (!DWOUnits
.empty())
889 DObj
->forEachInfoDWOSections([&](const DWARFSection
&S
) {
890 DWOUnits
.addUnitsForDWOSection(*this, S
, DW_SECT_INFO
, Lazy
);
892 DWOUnits
.finishedInfoUnits();
893 DObj
->forEachTypesDWOSections([&](const DWARFSection
&S
) {
894 DWOUnits
.addUnitsForDWOSection(*this, S
, DW_SECT_TYPES
, Lazy
);
898 DWARFCompileUnit
*DWARFContext::getCompileUnitForOffset(uint64_t Offset
) {
900 return dyn_cast_or_null
<DWARFCompileUnit
>(
901 NormalUnits
.getUnitForOffset(Offset
));
904 DWARFCompileUnit
*DWARFContext::getCompileUnitForAddress(uint64_t Address
) {
905 // First, get the offset of the compile unit.
906 uint64_t CUOffset
= getDebugAranges()->findAddress(Address
);
907 // Retrieve the compile unit.
908 return getCompileUnitForOffset(CUOffset
);
911 DWARFContext::DIEsForAddress
DWARFContext::getDIEsForAddress(uint64_t Address
) {
912 DIEsForAddress Result
;
914 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
);
918 Result
.CompileUnit
= CU
;
919 Result
.FunctionDIE
= CU
->getSubroutineForAddress(Address
);
921 std::vector
<DWARFDie
> Worklist
;
922 Worklist
.push_back(Result
.FunctionDIE
);
923 while (!Worklist
.empty()) {
924 DWARFDie DIE
= Worklist
.back();
930 if (DIE
.getTag() == DW_TAG_lexical_block
&&
931 DIE
.addressRangeContainsAddress(Address
)) {
932 Result
.BlockDIE
= DIE
;
936 for (auto Child
: DIE
)
937 Worklist
.push_back(Child
);
943 /// TODO: change input parameter from "uint64_t Address"
944 /// into "SectionedAddress Address"
945 static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit
*CU
,
947 FunctionNameKind Kind
,
948 std::string
&FunctionName
,
949 uint32_t &StartLine
) {
950 // The address may correspond to instruction in some inlined function,
951 // so we have to build the chain of inlined functions and take the
952 // name of the topmost function in it.
953 SmallVector
<DWARFDie
, 4> InlinedChain
;
954 CU
->getInlinedChainForAddress(Address
, InlinedChain
);
955 if (InlinedChain
.empty())
958 const DWARFDie
&DIE
= InlinedChain
[0];
959 bool FoundResult
= false;
960 const char *Name
= nullptr;
961 if (Kind
!= FunctionNameKind::None
&& (Name
= DIE
.getSubroutineName(Kind
))) {
965 if (auto DeclLineResult
= DIE
.getDeclLine()) {
966 StartLine
= DeclLineResult
;
973 static Optional
<uint64_t> getTypeSize(DWARFDie Type
, uint64_t PointerSize
) {
974 if (auto SizeAttr
= Type
.find(DW_AT_byte_size
))
975 if (Optional
<uint64_t> Size
= SizeAttr
->getAsUnsignedConstant())
978 switch (Type
.getTag()) {
979 case DW_TAG_pointer_type
:
980 case DW_TAG_reference_type
:
981 case DW_TAG_rvalue_reference_type
:
983 case DW_TAG_ptr_to_member_type
: {
984 if (DWARFDie BaseType
= Type
.getAttributeValueAsReferencedDie(DW_AT_type
))
985 if (BaseType
.getTag() == DW_TAG_subroutine_type
)
986 return 2 * PointerSize
;
989 case DW_TAG_const_type
:
990 case DW_TAG_volatile_type
:
991 case DW_TAG_restrict_type
:
992 case DW_TAG_typedef
: {
993 if (DWARFDie BaseType
= Type
.getAttributeValueAsReferencedDie(DW_AT_type
))
994 return getTypeSize(BaseType
, PointerSize
);
997 case DW_TAG_array_type
: {
998 DWARFDie BaseType
= Type
.getAttributeValueAsReferencedDie(DW_AT_type
);
1000 return Optional
<uint64_t>();
1001 Optional
<uint64_t> BaseSize
= getTypeSize(BaseType
, PointerSize
);
1003 return Optional
<uint64_t>();
1004 uint64_t Size
= *BaseSize
;
1005 for (DWARFDie Child
: Type
) {
1006 if (Child
.getTag() != DW_TAG_subrange_type
)
1009 if (auto ElemCountAttr
= Child
.find(DW_AT_count
))
1010 if (Optional
<uint64_t> ElemCount
=
1011 ElemCountAttr
->getAsUnsignedConstant())
1013 if (auto UpperBoundAttr
= Child
.find(DW_AT_upper_bound
))
1014 if (Optional
<int64_t> UpperBound
=
1015 UpperBoundAttr
->getAsSignedConstant()) {
1016 int64_t LowerBound
= 0;
1017 if (auto LowerBoundAttr
= Child
.find(DW_AT_lower_bound
))
1018 LowerBound
= LowerBoundAttr
->getAsSignedConstant().getValueOr(0);
1019 Size
*= *UpperBound
- LowerBound
+ 1;
1027 return Optional
<uint64_t>();
1030 void DWARFContext::addLocalsForDie(DWARFCompileUnit
*CU
, DWARFDie Subprogram
,
1031 DWARFDie Die
, std::vector
<DILocal
> &Result
) {
1032 if (Die
.getTag() == DW_TAG_variable
||
1033 Die
.getTag() == DW_TAG_formal_parameter
) {
1035 if (auto NameAttr
= Subprogram
.find(DW_AT_name
))
1036 if (Optional
<const char *> Name
= NameAttr
->getAsCString())
1037 Local
.FunctionName
= *Name
;
1038 if (auto LocationAttr
= Die
.find(DW_AT_location
))
1039 if (Optional
<ArrayRef
<uint8_t>> Location
= LocationAttr
->getAsBlock())
1040 if (!Location
->empty() && (*Location
)[0] == DW_OP_fbreg
)
1042 decodeSLEB128(Location
->data() + 1, nullptr, Location
->end());
1043 if (auto TagOffsetAttr
= Die
.find(DW_AT_LLVM_tag_offset
))
1044 Local
.TagOffset
= TagOffsetAttr
->getAsUnsignedConstant();
1047 Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
1049 if (auto NameAttr
= Die
.find(DW_AT_name
))
1050 if (Optional
<const char *> Name
= NameAttr
->getAsCString())
1052 if (auto Type
= Die
.getAttributeValueAsReferencedDie(DW_AT_type
))
1053 Local
.Size
= getTypeSize(Type
, getCUAddrSize());
1054 if (auto DeclFileAttr
= Die
.find(DW_AT_decl_file
)) {
1055 if (const auto *LT
= CU
->getContext().getLineTableForUnit(CU
))
1056 LT
->getFileNameByIndex(
1057 DeclFileAttr
->getAsUnsignedConstant().getValue(),
1058 CU
->getCompilationDir(),
1059 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
,
1062 if (auto DeclLineAttr
= Die
.find(DW_AT_decl_line
))
1063 Local
.DeclLine
= DeclLineAttr
->getAsUnsignedConstant().getValue();
1065 Result
.push_back(Local
);
1069 if (Die
.getTag() == DW_TAG_inlined_subroutine
)
1071 Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
1072 Subprogram
= Origin
;
1074 for (auto Child
: Die
)
1075 addLocalsForDie(CU
, Subprogram
, Child
, Result
);
1078 std::vector
<DILocal
>
1079 DWARFContext::getLocalsForAddress(object::SectionedAddress Address
) {
1080 std::vector
<DILocal
> Result
;
1081 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1085 DWARFDie Subprogram
= CU
->getSubroutineForAddress(Address
.Address
);
1086 if (Subprogram
.isValid())
1087 addLocalsForDie(CU
, Subprogram
, Subprogram
, Result
);
1091 DILineInfo
DWARFContext::getLineInfoForAddress(object::SectionedAddress Address
,
1092 DILineInfoSpecifier Spec
) {
1095 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1099 getFunctionNameAndStartLineForAddress(CU
, Address
.Address
, Spec
.FNKind
,
1100 Result
.FunctionName
, Result
.StartLine
);
1101 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1102 if (const DWARFLineTable
*LineTable
= getLineTableForUnit(CU
)) {
1103 LineTable
->getFileLineInfoForAddress(
1104 {Address
.Address
, Address
.SectionIndex
}, CU
->getCompilationDir(),
1105 Spec
.FLIKind
, Result
);
1111 DILineInfoTable
DWARFContext::getLineInfoForAddressRange(
1112 object::SectionedAddress Address
, uint64_t Size
, DILineInfoSpecifier Spec
) {
1113 DILineInfoTable Lines
;
1114 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1118 uint32_t StartLine
= 0;
1119 std::string
FunctionName(DILineInfo::BadString
);
1120 getFunctionNameAndStartLineForAddress(CU
, Address
.Address
, Spec
.FNKind
,
1121 FunctionName
, StartLine
);
1123 // If the Specifier says we don't need FileLineInfo, just
1124 // return the top-most function at the starting address.
1125 if (Spec
.FLIKind
== FileLineInfoKind::None
) {
1127 Result
.FunctionName
= FunctionName
;
1128 Result
.StartLine
= StartLine
;
1129 Lines
.push_back(std::make_pair(Address
.Address
, Result
));
1133 const DWARFLineTable
*LineTable
= getLineTableForUnit(CU
);
1135 // Get the index of row we're looking for in the line table.
1136 std::vector
<uint32_t> RowVector
;
1137 if (!LineTable
->lookupAddressRange({Address
.Address
, Address
.SectionIndex
},
1142 for (uint32_t RowIndex
: RowVector
) {
1143 // Take file number and line/column from the row.
1144 const DWARFDebugLine::Row
&Row
= LineTable
->Rows
[RowIndex
];
1146 LineTable
->getFileNameByIndex(Row
.File
, CU
->getCompilationDir(),
1147 Spec
.FLIKind
, Result
.FileName
);
1148 Result
.FunctionName
= FunctionName
;
1149 Result
.Line
= Row
.Line
;
1150 Result
.Column
= Row
.Column
;
1151 Result
.StartLine
= StartLine
;
1152 Lines
.push_back(std::make_pair(Row
.Address
.Address
, Result
));
1159 DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address
,
1160 DILineInfoSpecifier Spec
) {
1161 DIInliningInfo InliningInfo
;
1163 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1165 return InliningInfo
;
1167 const DWARFLineTable
*LineTable
= nullptr;
1168 SmallVector
<DWARFDie
, 4> InlinedChain
;
1169 CU
->getInlinedChainForAddress(Address
.Address
, InlinedChain
);
1170 if (InlinedChain
.size() == 0) {
1171 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
1172 // try to at least get file/line info from symbol table.
1173 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1175 LineTable
= getLineTableForUnit(CU
);
1176 if (LineTable
&& LineTable
->getFileLineInfoForAddress(
1177 {Address
.Address
, Address
.SectionIndex
},
1178 CU
->getCompilationDir(), Spec
.FLIKind
, Frame
))
1179 InliningInfo
.addFrame(Frame
);
1181 return InliningInfo
;
1184 uint32_t CallFile
= 0, CallLine
= 0, CallColumn
= 0, CallDiscriminator
= 0;
1185 for (uint32_t i
= 0, n
= InlinedChain
.size(); i
!= n
; i
++) {
1186 DWARFDie
&FunctionDIE
= InlinedChain
[i
];
1188 // Get function name if necessary.
1189 if (const char *Name
= FunctionDIE
.getSubroutineName(Spec
.FNKind
))
1190 Frame
.FunctionName
= Name
;
1191 if (auto DeclLineResult
= FunctionDIE
.getDeclLine())
1192 Frame
.StartLine
= DeclLineResult
;
1193 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1195 // For the topmost frame, initialize the line table of this
1196 // compile unit and fetch file/line info from it.
1197 LineTable
= getLineTableForUnit(CU
);
1198 // For the topmost routine, get file/line info from line table.
1200 LineTable
->getFileLineInfoForAddress(
1201 {Address
.Address
, Address
.SectionIndex
}, CU
->getCompilationDir(),
1202 Spec
.FLIKind
, Frame
);
1204 // Otherwise, use call file, call line and call column from
1205 // previous DIE in inlined chain.
1207 LineTable
->getFileNameByIndex(CallFile
, CU
->getCompilationDir(),
1208 Spec
.FLIKind
, Frame
.FileName
);
1209 Frame
.Line
= CallLine
;
1210 Frame
.Column
= CallColumn
;
1211 Frame
.Discriminator
= CallDiscriminator
;
1213 // Get call file/line/column of a current DIE.
1215 FunctionDIE
.getCallerFrame(CallFile
, CallLine
, CallColumn
,
1219 InliningInfo
.addFrame(Frame
);
1221 return InliningInfo
;
1224 std::shared_ptr
<DWARFContext
>
1225 DWARFContext::getDWOContext(StringRef AbsolutePath
) {
1226 if (auto S
= DWP
.lock()) {
1227 DWARFContext
*Ctxt
= S
->Context
.get();
1228 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1231 std::weak_ptr
<DWOFile
> *Entry
= &DWOFiles
[AbsolutePath
];
1233 if (auto S
= Entry
->lock()) {
1234 DWARFContext
*Ctxt
= S
->Context
.get();
1235 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1238 Expected
<OwningBinary
<ObjectFile
>> Obj
= [&] {
1239 if (!CheckedForDWP
) {
1240 SmallString
<128> DWPName
;
1241 auto Obj
= object::ObjectFile::createObjectFile(
1242 this->DWPName
.empty()
1243 ? (DObj
->getFileName() + ".dwp").toStringRef(DWPName
)
1244 : StringRef(this->DWPName
));
1249 CheckedForDWP
= true;
1250 // TODO: Should this error be handled (maybe in a high verbosity mode)
1251 // before falling back to .dwo files?
1252 consumeError(Obj
.takeError());
1256 return object::ObjectFile::createObjectFile(AbsolutePath
);
1260 // TODO: Actually report errors helpfully.
1261 consumeError(Obj
.takeError());
1265 auto S
= std::make_shared
<DWOFile
>();
1266 S
->File
= std::move(Obj
.get());
1267 S
->Context
= DWARFContext::create(*S
->File
.getBinary());
1269 auto *Ctxt
= S
->Context
.get();
1270 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1273 static Error
createError(const Twine
&Reason
, llvm::Error E
) {
1274 return make_error
<StringError
>(Reason
+ toString(std::move(E
)),
1275 inconvertibleErrorCode());
1278 /// SymInfo contains information about symbol: it's address
1279 /// and section index which is -1LL for absolute symbols.
1282 uint64_t SectionIndex
;
1285 /// Returns the address of symbol relocation used against and a section index.
1286 /// Used for futher relocations computation. Symbol's section load address is
1287 static Expected
<SymInfo
> getSymbolInfo(const object::ObjectFile
&Obj
,
1288 const RelocationRef
&Reloc
,
1289 const LoadedObjectInfo
*L
,
1290 std::map
<SymbolRef
, SymInfo
> &Cache
) {
1291 SymInfo Ret
= {0, (uint64_t)-1LL};
1292 object::section_iterator RSec
= Obj
.section_end();
1293 object::symbol_iterator Sym
= Reloc
.getSymbol();
1295 std::map
<SymbolRef
, SymInfo
>::iterator CacheIt
= Cache
.end();
1296 // First calculate the address of the symbol or section as it appears
1297 // in the object file
1298 if (Sym
!= Obj
.symbol_end()) {
1300 std::tie(CacheIt
, New
) = Cache
.insert({*Sym
, {0, 0}});
1302 return CacheIt
->second
;
1304 Expected
<uint64_t> SymAddrOrErr
= Sym
->getAddress();
1306 return createError("failed to compute symbol address: ",
1307 SymAddrOrErr
.takeError());
1309 // Also remember what section this symbol is in for later
1310 auto SectOrErr
= Sym
->getSection();
1312 return createError("failed to get symbol section: ",
1313 SectOrErr
.takeError());
1316 Ret
.Address
= *SymAddrOrErr
;
1317 } else if (auto *MObj
= dyn_cast
<MachOObjectFile
>(&Obj
)) {
1318 RSec
= MObj
->getRelocationSection(Reloc
.getRawDataRefImpl());
1319 Ret
.Address
= RSec
->getAddress();
1322 if (RSec
!= Obj
.section_end())
1323 Ret
.SectionIndex
= RSec
->getIndex();
1325 // If we are given load addresses for the sections, we need to adjust:
1326 // SymAddr = (Address of Symbol Or Section in File) -
1327 // (Address of Section in File) +
1328 // (Load Address of Section)
1329 // RSec is now either the section being targeted or the section
1330 // containing the symbol being targeted. In either case,
1331 // we need to perform the same computation.
1332 if (L
&& RSec
!= Obj
.section_end())
1333 if (uint64_t SectionLoadAddress
= L
->getSectionLoadAddress(*RSec
))
1334 Ret
.Address
+= SectionLoadAddress
- RSec
->getAddress();
1336 if (CacheIt
!= Cache
.end())
1337 CacheIt
->second
= Ret
;
1342 static bool isRelocScattered(const object::ObjectFile
&Obj
,
1343 const RelocationRef
&Reloc
) {
1344 const MachOObjectFile
*MachObj
= dyn_cast
<MachOObjectFile
>(&Obj
);
1347 // MachO also has relocations that point to sections and
1348 // scattered relocations.
1349 auto RelocInfo
= MachObj
->getRelocation(Reloc
.getRawDataRefImpl());
1350 return MachObj
->isRelocationScattered(RelocInfo
);
1353 ErrorPolicy
DWARFContext::defaultErrorHandler(Error E
) {
1354 WithColor::error() << toString(std::move(E
)) << '\n';
1355 return ErrorPolicy::Continue
;
1359 struct DWARFSectionMap final
: public DWARFSection
{
1360 RelocAddrMap Relocs
;
1363 class DWARFObjInMemory final
: public DWARFObject
{
1364 bool IsLittleEndian
;
1365 uint8_t AddressSize
;
1367 const object::ObjectFile
*Obj
= nullptr;
1368 std::vector
<SectionName
> SectionNames
;
1370 using InfoSectionMap
= MapVector
<object::SectionRef
, DWARFSectionMap
,
1371 std::map
<object::SectionRef
, unsigned>>;
1373 InfoSectionMap InfoSections
;
1374 InfoSectionMap TypesSections
;
1375 InfoSectionMap InfoDWOSections
;
1376 InfoSectionMap TypesDWOSections
;
1378 DWARFSectionMap LocSection
;
1379 DWARFSectionMap LoclistsSection
;
1380 DWARFSectionMap LineSection
;
1381 DWARFSectionMap RangesSection
;
1382 DWARFSectionMap RnglistsSection
;
1383 DWARFSectionMap StrOffsetsSection
;
1384 DWARFSectionMap LineDWOSection
;
1385 DWARFSectionMap FrameSection
;
1386 DWARFSectionMap EHFrameSection
;
1387 DWARFSectionMap LocDWOSection
;
1388 DWARFSectionMap StrOffsetsDWOSection
;
1389 DWARFSectionMap RangesDWOSection
;
1390 DWARFSectionMap RnglistsDWOSection
;
1391 DWARFSectionMap AddrSection
;
1392 DWARFSectionMap AppleNamesSection
;
1393 DWARFSectionMap AppleTypesSection
;
1394 DWARFSectionMap AppleNamespacesSection
;
1395 DWARFSectionMap AppleObjCSection
;
1396 DWARFSectionMap NamesSection
;
1397 DWARFSectionMap PubnamesSection
;
1398 DWARFSectionMap PubtypesSection
;
1399 DWARFSectionMap GnuPubnamesSection
;
1400 DWARFSectionMap GnuPubtypesSection
;
1402 DWARFSectionMap
*mapNameToDWARFSection(StringRef Name
) {
1403 return StringSwitch
<DWARFSectionMap
*>(Name
)
1404 .Case("debug_loc", &LocSection
)
1405 .Case("debug_loclists", &LoclistsSection
)
1406 .Case("debug_line", &LineSection
)
1407 .Case("debug_frame", &FrameSection
)
1408 .Case("eh_frame", &EHFrameSection
)
1409 .Case("debug_str_offsets", &StrOffsetsSection
)
1410 .Case("debug_ranges", &RangesSection
)
1411 .Case("debug_rnglists", &RnglistsSection
)
1412 .Case("debug_loc.dwo", &LocDWOSection
)
1413 .Case("debug_line.dwo", &LineDWOSection
)
1414 .Case("debug_names", &NamesSection
)
1415 .Case("debug_rnglists.dwo", &RnglistsDWOSection
)
1416 .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection
)
1417 .Case("debug_addr", &AddrSection
)
1418 .Case("apple_names", &AppleNamesSection
)
1419 .Case("debug_pubnames", &PubnamesSection
)
1420 .Case("debug_pubtypes", &PubtypesSection
)
1421 .Case("debug_gnu_pubnames", &GnuPubnamesSection
)
1422 .Case("debug_gnu_pubtypes", &GnuPubtypesSection
)
1423 .Case("apple_types", &AppleTypesSection
)
1424 .Case("apple_namespaces", &AppleNamespacesSection
)
1425 .Case("apple_namespac", &AppleNamespacesSection
)
1426 .Case("apple_objc", &AppleObjCSection
)
1430 StringRef AbbrevSection
;
1431 StringRef ArangesSection
;
1432 StringRef StrSection
;
1433 StringRef MacinfoSection
;
1434 StringRef AbbrevDWOSection
;
1435 StringRef StrDWOSection
;
1436 StringRef CUIndexSection
;
1437 StringRef GdbIndexSection
;
1438 StringRef TUIndexSection
;
1439 StringRef LineStrSection
;
1441 // A deque holding section data whose iterators are not invalidated when
1442 // new decompressed sections are inserted at the end.
1443 std::deque
<SmallString
<0>> UncompressedSections
;
1445 StringRef
*mapSectionToMember(StringRef Name
) {
1446 if (DWARFSection
*Sec
= mapNameToDWARFSection(Name
))
1448 return StringSwitch
<StringRef
*>(Name
)
1449 .Case("debug_abbrev", &AbbrevSection
)
1450 .Case("debug_aranges", &ArangesSection
)
1451 .Case("debug_str", &StrSection
)
1452 .Case("debug_macinfo", &MacinfoSection
)
1453 .Case("debug_abbrev.dwo", &AbbrevDWOSection
)
1454 .Case("debug_str.dwo", &StrDWOSection
)
1455 .Case("debug_cu_index", &CUIndexSection
)
1456 .Case("debug_tu_index", &TUIndexSection
)
1457 .Case("gdb_index", &GdbIndexSection
)
1458 .Case("debug_line_str", &LineStrSection
)
1459 // Any more debug info sections go here.
1463 /// If Sec is compressed section, decompresses and updates its contents
1464 /// provided by Data. Otherwise leaves it unchanged.
1465 Error
maybeDecompress(const object::SectionRef
&Sec
, StringRef Name
,
1467 if (!Decompressor::isCompressed(Sec
))
1468 return Error::success();
1470 Expected
<Decompressor
> Decompressor
=
1471 Decompressor::create(Name
, Data
, IsLittleEndian
, AddressSize
== 8);
1473 return Decompressor
.takeError();
1476 if (auto Err
= Decompressor
->resizeAndDecompress(Out
))
1479 UncompressedSections
.push_back(std::move(Out
));
1480 Data
= UncompressedSections
.back();
1482 return Error::success();
1486 DWARFObjInMemory(const StringMap
<std::unique_ptr
<MemoryBuffer
>> &Sections
,
1487 uint8_t AddrSize
, bool IsLittleEndian
)
1488 : IsLittleEndian(IsLittleEndian
) {
1489 for (const auto &SecIt
: Sections
) {
1490 if (StringRef
*SectionData
= mapSectionToMember(SecIt
.first()))
1491 *SectionData
= SecIt
.second
->getBuffer();
1492 else if (SecIt
.first() == "debug_info")
1493 // Find debug_info and debug_types data by section rather than name as
1494 // there are multiple, comdat grouped, of these sections.
1495 InfoSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1496 else if (SecIt
.first() == "debug_info.dwo")
1497 InfoDWOSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1498 else if (SecIt
.first() == "debug_types")
1499 TypesSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1500 else if (SecIt
.first() == "debug_types.dwo")
1501 TypesDWOSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1504 DWARFObjInMemory(const object::ObjectFile
&Obj
, const LoadedObjectInfo
*L
,
1505 function_ref
<ErrorPolicy(Error
)> HandleError
)
1506 : IsLittleEndian(Obj
.isLittleEndian()),
1507 AddressSize(Obj
.getBytesInAddress()), FileName(Obj
.getFileName()),
1510 StringMap
<unsigned> SectionAmountMap
;
1511 for (const SectionRef
&Section
: Obj
.sections()) {
1513 if (auto NameOrErr
= Section
.getName())
1516 consumeError(NameOrErr
.takeError());
1518 ++SectionAmountMap
[Name
];
1519 SectionNames
.push_back({ Name
, true });
1521 // Skip BSS and Virtual sections, they aren't interesting.
1522 if (Section
.isBSS() || Section
.isVirtual())
1525 // Skip sections stripped by dsymutil.
1526 if (Section
.isStripped())
1530 Expected
<section_iterator
> SecOrErr
= Section
.getRelocatedSection();
1532 ErrorPolicy EP
= HandleError(createError(
1533 "failed to get relocated section: ", SecOrErr
.takeError()));
1534 if (EP
== ErrorPolicy::Halt
)
1539 // Try to obtain an already relocated version of this section.
1540 // Else use the unrelocated section from the object file. We'll have to
1541 // apply relocations ourselves later.
1542 section_iterator RelocatedSection
= *SecOrErr
;
1543 if (!L
|| !L
->getLoadedSectionContents(*RelocatedSection
, Data
)) {
1544 Expected
<StringRef
> E
= Section
.getContents();
1548 // maybeDecompress below will error.
1549 consumeError(E
.takeError());
1552 if (auto Err
= maybeDecompress(Section
, Name
, Data
)) {
1553 ErrorPolicy EP
= HandleError(createError(
1554 "failed to decompress '" + Name
+ "', ", std::move(Err
)));
1555 if (EP
== ErrorPolicy::Halt
)
1560 // Compressed sections names in GNU style starts from ".z",
1561 // at this point section is decompressed and we drop compression prefix.
1563 Name
.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1565 // Map platform specific debug section names to DWARF standard section
1567 Name
= Obj
.mapDebugSectionName(Name
);
1569 if (StringRef
*SectionData
= mapSectionToMember(Name
)) {
1570 *SectionData
= Data
;
1571 if (Name
== "debug_ranges") {
1572 // FIXME: Use the other dwo range section when we emit it.
1573 RangesDWOSection
.Data
= Data
;
1575 } else if (Name
== "debug_info") {
1576 // Find debug_info and debug_types data by section rather than name as
1577 // there are multiple, comdat grouped, of these sections.
1578 InfoSections
[Section
].Data
= Data
;
1579 } else if (Name
== "debug_info.dwo") {
1580 InfoDWOSections
[Section
].Data
= Data
;
1581 } else if (Name
== "debug_types") {
1582 TypesSections
[Section
].Data
= Data
;
1583 } else if (Name
== "debug_types.dwo") {
1584 TypesDWOSections
[Section
].Data
= Data
;
1587 if (RelocatedSection
== Obj
.section_end())
1590 StringRef RelSecName
;
1591 if (auto NameOrErr
= RelocatedSection
->getName())
1592 RelSecName
= *NameOrErr
;
1594 consumeError(NameOrErr
.takeError());
1596 // If the section we're relocating was relocated already by the JIT,
1597 // then we used the relocated version above, so we do not need to process
1598 // relocations for it now.
1599 StringRef RelSecData
;
1600 if (L
&& L
->getLoadedSectionContents(*RelocatedSection
, RelSecData
))
1603 // In Mach-o files, the relocations do not need to be applied if
1604 // there is no load offset to apply. The value read at the
1605 // relocation point already factors in the section address
1606 // (actually applying the relocations will produce wrong results
1607 // as the section address will be added twice).
1608 if (!L
&& isa
<MachOObjectFile
>(&Obj
))
1611 RelSecName
= RelSecName
.substr(
1612 RelSecName
.find_first_not_of("._z")); // Skip . and _ prefixes.
1614 // TODO: Add support for relocations in other sections as needed.
1615 // Record relocations for the debug_info and debug_line sections.
1616 DWARFSectionMap
*Sec
= mapNameToDWARFSection(RelSecName
);
1617 RelocAddrMap
*Map
= Sec
? &Sec
->Relocs
: nullptr;
1619 // Find debug_info and debug_types relocs by section rather than name
1620 // as there are multiple, comdat grouped, of these sections.
1621 if (RelSecName
== "debug_info")
1622 Map
= &static_cast<DWARFSectionMap
&>(InfoSections
[*RelocatedSection
])
1624 else if (RelSecName
== "debug_info.dwo")
1625 Map
= &static_cast<DWARFSectionMap
&>(
1626 InfoDWOSections
[*RelocatedSection
])
1628 else if (RelSecName
== "debug_types")
1630 &static_cast<DWARFSectionMap
&>(TypesSections
[*RelocatedSection
])
1632 else if (RelSecName
== "debug_types.dwo")
1633 Map
= &static_cast<DWARFSectionMap
&>(
1634 TypesDWOSections
[*RelocatedSection
])
1640 if (Section
.relocation_begin() == Section
.relocation_end())
1643 // Symbol to [address, section index] cache mapping.
1644 std::map
<SymbolRef
, SymInfo
> AddrCache
;
1645 bool (*Supports
)(uint64_t);
1646 RelocationResolver Resolver
;
1647 std::tie(Supports
, Resolver
) = getRelocationResolver(Obj
);
1648 for (const RelocationRef
&Reloc
: Section
.relocations()) {
1649 // FIXME: it's not clear how to correctly handle scattered
1651 if (isRelocScattered(Obj
, Reloc
))
1654 Expected
<SymInfo
> SymInfoOrErr
=
1655 getSymbolInfo(Obj
, Reloc
, L
, AddrCache
);
1656 if (!SymInfoOrErr
) {
1657 if (HandleError(SymInfoOrErr
.takeError()) == ErrorPolicy::Halt
)
1662 // Check if Resolver can handle this relocation type early so as not to
1663 // handle invalid cases in DWARFDataExtractor.
1665 // TODO Don't store Resolver in every RelocAddrEntry.
1666 if (Supports
&& Supports(Reloc
.getType())) {
1667 auto I
= Map
->try_emplace(
1669 RelocAddrEntry
{SymInfoOrErr
->SectionIndex
, Reloc
,
1670 SymInfoOrErr
->Address
,
1671 Optional
<object::RelocationRef
>(), 0, Resolver
});
1672 // If we didn't successfully insert that's because we already had a
1673 // relocation for that offset. Store it as a second relocation in the
1674 // same RelocAddrEntry instead.
1676 RelocAddrEntry
&entry
= I
.first
->getSecond();
1678 ErrorPolicy EP
= HandleError(createError(
1679 "At most two relocations per offset are supported"));
1680 if (EP
== ErrorPolicy::Halt
)
1683 entry
.Reloc2
= Reloc
;
1684 entry
.SymbolValue2
= SymInfoOrErr
->Address
;
1687 SmallString
<32> Type
;
1688 Reloc
.getTypeName(Type
);
1689 ErrorPolicy EP
= HandleError(
1690 createError("failed to compute relocation: " + Type
+ ", ",
1691 errorCodeToError(object_error::parse_failed
)));
1692 if (EP
== ErrorPolicy::Halt
)
1698 for (SectionName
&S
: SectionNames
)
1699 if (SectionAmountMap
[S
.Name
] > 1)
1700 S
.IsNameUnique
= false;
1703 Optional
<RelocAddrEntry
> find(const DWARFSection
&S
,
1704 uint64_t Pos
) const override
{
1705 auto &Sec
= static_cast<const DWARFSectionMap
&>(S
);
1706 RelocAddrMap::const_iterator AI
= Sec
.Relocs
.find(Pos
);
1707 if (AI
== Sec
.Relocs
.end())
1712 const object::ObjectFile
*getFile() const override
{ return Obj
; }
1714 ArrayRef
<SectionName
> getSectionNames() const override
{
1715 return SectionNames
;
1718 bool isLittleEndian() const override
{ return IsLittleEndian
; }
1719 StringRef
getAbbrevDWOSection() const override
{ return AbbrevDWOSection
; }
1720 const DWARFSection
&getLineDWOSection() const override
{
1721 return LineDWOSection
;
1723 const DWARFSection
&getLocDWOSection() const override
{
1724 return LocDWOSection
;
1726 StringRef
getStrDWOSection() const override
{ return StrDWOSection
; }
1727 const DWARFSection
&getStrOffsetsDWOSection() const override
{
1728 return StrOffsetsDWOSection
;
1730 const DWARFSection
&getRangesDWOSection() const override
{
1731 return RangesDWOSection
;
1733 const DWARFSection
&getRnglistsDWOSection() const override
{
1734 return RnglistsDWOSection
;
1736 const DWARFSection
&getAddrSection() const override
{ return AddrSection
; }
1737 StringRef
getCUIndexSection() const override
{ return CUIndexSection
; }
1738 StringRef
getGdbIndexSection() const override
{ return GdbIndexSection
; }
1739 StringRef
getTUIndexSection() const override
{ return TUIndexSection
; }
1742 const DWARFSection
&getStrOffsetsSection() const override
{
1743 return StrOffsetsSection
;
1745 StringRef
getLineStrSection() const override
{ return LineStrSection
; }
1747 // Sections for DWARF5 split dwarf proposal.
1748 void forEachInfoDWOSections(
1749 function_ref
<void(const DWARFSection
&)> F
) const override
{
1750 for (auto &P
: InfoDWOSections
)
1753 void forEachTypesDWOSections(
1754 function_ref
<void(const DWARFSection
&)> F
) const override
{
1755 for (auto &P
: TypesDWOSections
)
1759 StringRef
getAbbrevSection() const override
{ return AbbrevSection
; }
1760 const DWARFSection
&getLocSection() const override
{ return LocSection
; }
1761 const DWARFSection
&getLoclistsSection() const override
{ return LoclistsSection
; }
1762 StringRef
getArangesSection() const override
{ return ArangesSection
; }
1763 const DWARFSection
&getFrameSection() const override
{
1764 return FrameSection
;
1766 const DWARFSection
&getEHFrameSection() const override
{
1767 return EHFrameSection
;
1769 const DWARFSection
&getLineSection() const override
{ return LineSection
; }
1770 StringRef
getStrSection() const override
{ return StrSection
; }
1771 const DWARFSection
&getRangesSection() const override
{ return RangesSection
; }
1772 const DWARFSection
&getRnglistsSection() const override
{
1773 return RnglistsSection
;
1775 StringRef
getMacinfoSection() const override
{ return MacinfoSection
; }
1776 const DWARFSection
&getPubnamesSection() const override
{ return PubnamesSection
; }
1777 const DWARFSection
&getPubtypesSection() const override
{ return PubtypesSection
; }
1778 const DWARFSection
&getGnuPubnamesSection() const override
{
1779 return GnuPubnamesSection
;
1781 const DWARFSection
&getGnuPubtypesSection() const override
{
1782 return GnuPubtypesSection
;
1784 const DWARFSection
&getAppleNamesSection() const override
{
1785 return AppleNamesSection
;
1787 const DWARFSection
&getAppleTypesSection() const override
{
1788 return AppleTypesSection
;
1790 const DWARFSection
&getAppleNamespacesSection() const override
{
1791 return AppleNamespacesSection
;
1793 const DWARFSection
&getAppleObjCSection() const override
{
1794 return AppleObjCSection
;
1796 const DWARFSection
&getNamesSection() const override
{
1797 return NamesSection
;
1800 StringRef
getFileName() const override
{ return FileName
; }
1801 uint8_t getAddressSize() const override
{ return AddressSize
; }
1802 void forEachInfoSections(
1803 function_ref
<void(const DWARFSection
&)> F
) const override
{
1804 for (auto &P
: InfoSections
)
1807 void forEachTypesSections(
1808 function_ref
<void(const DWARFSection
&)> F
) const override
{
1809 for (auto &P
: TypesSections
)
1815 std::unique_ptr
<DWARFContext
>
1816 DWARFContext::create(const object::ObjectFile
&Obj
, const LoadedObjectInfo
*L
,
1817 function_ref
<ErrorPolicy(Error
)> HandleError
,
1818 std::string DWPName
) {
1819 auto DObj
= std::make_unique
<DWARFObjInMemory
>(Obj
, L
, HandleError
);
1820 return std::make_unique
<DWARFContext
>(std::move(DObj
), std::move(DWPName
));
1823 std::unique_ptr
<DWARFContext
>
1824 DWARFContext::create(const StringMap
<std::unique_ptr
<MemoryBuffer
>> &Sections
,
1825 uint8_t AddrSize
, bool isLittleEndian
) {
1827 std::make_unique
<DWARFObjInMemory
>(Sections
, AddrSize
, isLittleEndian
);
1828 return std::make_unique
<DWARFContext
>(std::move(DObj
), "");
1831 Error
DWARFContext::loadRegisterInfo(const object::ObjectFile
&Obj
) {
1832 // Detect the architecture from the object file. We usually don't need OS
1833 // info to lookup a target and create register info.
1835 TT
.setArch(Triple::ArchType(Obj
.getArch()));
1836 TT
.setVendor(Triple::UnknownVendor
);
1837 TT
.setOS(Triple::UnknownOS
);
1838 std::string TargetLookupError
;
1839 const Target
*TheTarget
=
1840 TargetRegistry::lookupTarget(TT
.str(), TargetLookupError
);
1841 if (!TargetLookupError
.empty())
1842 return createStringError(errc::invalid_argument
,
1843 TargetLookupError
.c_str());
1844 RegInfo
.reset(TheTarget
->createMCRegInfo(TT
.str()));
1845 return Error::success();
1848 uint8_t DWARFContext::getCUAddrSize() {
1849 // In theory, different compile units may have different address byte
1850 // sizes, but for simplicity we just use the address byte size of the
1851 // last compile unit. In practice the address size field is repeated across
1852 // various DWARF headers (at least in version 5) to make it easier to dump
1853 // them independently, not to enable varying the address size.
1855 for (const auto &CU
: compile_units()) {
1856 Addr
= CU
->getAddressByteSize();
1862 void DWARFContext::dumpWarning(Error Warning
) {
1863 handleAllErrors(std::move(Warning
), [](ErrorInfoBase
&Info
) {
1864 WithColor::warning() << Info
.message() << '\n';