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
) {
293 DWARFDebugLoclists Loclists
;
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().drop_front(Offset
),
303 Data
.isLittleEndian(), Header
.getAddrSize());
305 Loclists
.parse(LocData
, Header
.getVersion());
306 Loclists
.dump(OS
, 0, MRI
, DumpOffset
);
309 void DWARFContext::dump(
310 raw_ostream
&OS
, DIDumpOptions DumpOpts
,
311 std::array
<Optional
<uint64_t>, DIDT_ID_Count
> DumpOffsets
) {
313 uint64_t DumpType
= DumpOpts
.DumpType
;
315 StringRef Extension
= sys::path::extension(DObj
->getFileName());
316 bool IsDWO
= (Extension
== ".dwo") || (Extension
== ".dwp");
318 // Print UUID header.
319 const auto *ObjFile
= DObj
->getFile();
320 if (DumpType
& DIDT_UUID
)
321 dumpUUID(OS
, *ObjFile
);
323 // Print a header for each explicitly-requested section.
324 // Otherwise just print one for non-empty sections.
325 // Only print empty .dwo section headers when dumping a .dwo file.
326 bool Explicit
= DumpType
!= DIDT_All
&& !IsDWO
;
327 bool ExplicitDWO
= Explicit
&& IsDWO
;
328 auto shouldDump
= [&](bool Explicit
, const char *Name
, unsigned ID
,
329 StringRef Section
) -> Optional
<uint64_t> * {
330 unsigned Mask
= 1U << ID
;
331 bool Should
= (DumpType
& Mask
) && (Explicit
|| !Section
.empty());
334 OS
<< "\n" << Name
<< " contents:\n";
335 return &DumpOffsets
[ID
];
338 // Dump individual sections.
339 if (shouldDump(Explicit
, ".debug_abbrev", DIDT_ID_DebugAbbrev
,
340 DObj
->getAbbrevSection()))
341 getDebugAbbrev()->dump(OS
);
342 if (shouldDump(ExplicitDWO
, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev
,
343 DObj
->getAbbrevDWOSection()))
344 getDebugAbbrevDWO()->dump(OS
);
346 auto dumpDebugInfo
= [&](const char *Name
, unit_iterator_range Units
) {
347 OS
<< '\n' << Name
<< " contents:\n";
348 if (auto DumpOffset
= DumpOffsets
[DIDT_ID_DebugInfo
])
349 for (const auto &U
: Units
)
350 U
->getDIEForOffset(DumpOffset
.getValue())
351 .dump(OS
, 0, DumpOpts
.noImplicitRecursion());
353 for (const auto &U
: Units
)
354 U
->dump(OS
, DumpOpts
);
356 if ((DumpType
& DIDT_DebugInfo
)) {
357 if (Explicit
|| getNumCompileUnits())
358 dumpDebugInfo(".debug_info", info_section_units());
359 if (ExplicitDWO
|| getNumDWOCompileUnits())
360 dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
363 auto dumpDebugType
= [&](const char *Name
, unit_iterator_range Units
) {
364 OS
<< '\n' << Name
<< " contents:\n";
365 for (const auto &U
: Units
)
366 if (auto DumpOffset
= DumpOffsets
[DIDT_ID_DebugTypes
])
367 U
->getDIEForOffset(*DumpOffset
)
368 .dump(OS
, 0, DumpOpts
.noImplicitRecursion());
370 U
->dump(OS
, DumpOpts
);
372 if ((DumpType
& DIDT_DebugTypes
)) {
373 if (Explicit
|| getNumTypeUnits())
374 dumpDebugType(".debug_types", types_section_units());
375 if (ExplicitDWO
|| getNumDWOTypeUnits())
376 dumpDebugType(".debug_types.dwo", dwo_types_section_units());
379 if (const auto *Off
= shouldDump(Explicit
, ".debug_loc", DIDT_ID_DebugLoc
,
380 DObj
->getLocSection().Data
)) {
381 getDebugLoc()->dump(OS
, getRegisterInfo(), *Off
);
383 if (const auto *Off
=
384 shouldDump(Explicit
, ".debug_loclists", DIDT_ID_DebugLoclists
,
385 DObj
->getLoclistsSection().Data
)) {
386 DWARFDataExtractor
Data(*DObj
, DObj
->getLoclistsSection(), isLittleEndian(),
388 dumpLoclistsSection(OS
, DumpOpts
, Data
, getRegisterInfo(), *Off
);
390 if (const auto *Off
=
391 shouldDump(ExplicitDWO
, ".debug_loc.dwo", DIDT_ID_DebugLoc
,
392 DObj
->getLocDWOSection().Data
)) {
393 getDebugLocDWO()->dump(OS
, 0, getRegisterInfo(), *Off
);
396 if (const auto *Off
= shouldDump(Explicit
, ".debug_frame", DIDT_ID_DebugFrame
,
397 DObj
->getFrameSection().Data
))
398 getDebugFrame()->dump(OS
, getRegisterInfo(), *Off
);
400 if (const auto *Off
= shouldDump(Explicit
, ".eh_frame", DIDT_ID_DebugFrame
,
401 DObj
->getEHFrameSection().Data
))
402 getEHFrame()->dump(OS
, getRegisterInfo(), *Off
);
404 if (DumpType
& DIDT_DebugMacro
) {
405 if (Explicit
|| !getDebugMacro()->empty()) {
406 OS
<< "\n.debug_macinfo contents:\n";
407 getDebugMacro()->dump(OS
);
411 if (shouldDump(Explicit
, ".debug_aranges", DIDT_ID_DebugAranges
,
412 DObj
->getArangesSection())) {
414 DataExtractor
arangesData(DObj
->getArangesSection(), isLittleEndian(), 0);
415 DWARFDebugArangeSet set
;
416 while (set
.extract(arangesData
, &offset
))
420 auto DumpLineSection
= [&](DWARFDebugLine::SectionParser Parser
,
421 DIDumpOptions DumpOpts
,
422 Optional
<uint64_t> DumpOffset
) {
423 while (!Parser
.done()) {
424 if (DumpOffset
&& Parser
.getOffset() != *DumpOffset
) {
425 Parser
.skip(dumpWarning
);
428 OS
<< "debug_line[" << format("0x%8.8" PRIx64
, Parser
.getOffset())
430 if (DumpOpts
.Verbose
) {
431 Parser
.parseNext(dumpWarning
, dumpWarning
, &OS
);
433 DWARFDebugLine::LineTable LineTable
=
434 Parser
.parseNext(dumpWarning
, dumpWarning
);
435 LineTable
.dump(OS
, DumpOpts
);
440 if (const auto *Off
= shouldDump(Explicit
, ".debug_line", DIDT_ID_DebugLine
,
441 DObj
->getLineSection().Data
)) {
442 DWARFDataExtractor
LineData(*DObj
, DObj
->getLineSection(), isLittleEndian(),
444 DWARFDebugLine::SectionParser
Parser(LineData
, *this, compile_units(),
446 DumpLineSection(Parser
, DumpOpts
, *Off
);
449 if (const auto *Off
=
450 shouldDump(ExplicitDWO
, ".debug_line.dwo", DIDT_ID_DebugLine
,
451 DObj
->getLineDWOSection().Data
)) {
452 DWARFDataExtractor
LineData(*DObj
, DObj
->getLineDWOSection(),
453 isLittleEndian(), 0);
454 DWARFDebugLine::SectionParser
Parser(LineData
, *this, dwo_compile_units(),
456 DumpLineSection(Parser
, DumpOpts
, *Off
);
459 if (shouldDump(Explicit
, ".debug_cu_index", DIDT_ID_DebugCUIndex
,
460 DObj
->getCUIndexSection())) {
461 getCUIndex().dump(OS
);
464 if (shouldDump(Explicit
, ".debug_tu_index", DIDT_ID_DebugTUIndex
,
465 DObj
->getTUIndexSection())) {
466 getTUIndex().dump(OS
);
469 if (shouldDump(Explicit
, ".debug_str", DIDT_ID_DebugStr
,
470 DObj
->getStrSection())) {
471 DataExtractor
strData(DObj
->getStrSection(), isLittleEndian(), 0);
473 uint64_t strOffset
= 0;
474 while (const char *s
= strData
.getCStr(&offset
)) {
475 OS
<< format("0x%8.8" PRIx64
": \"%s\"\n", strOffset
, s
);
479 if (shouldDump(ExplicitDWO
, ".debug_str.dwo", DIDT_ID_DebugStr
,
480 DObj
->getStrDWOSection())) {
481 DataExtractor
strDWOData(DObj
->getStrDWOSection(), isLittleEndian(), 0);
483 uint64_t strDWOOffset
= 0;
484 while (const char *s
= strDWOData
.getCStr(&offset
)) {
485 OS
<< format("0x%8.8" PRIx64
": \"%s\"\n", strDWOOffset
, s
);
486 strDWOOffset
= offset
;
489 if (shouldDump(Explicit
, ".debug_line_str", DIDT_ID_DebugLineStr
,
490 DObj
->getLineStrSection())) {
491 DataExtractor
strData(DObj
->getLineStrSection(), isLittleEndian(), 0);
493 uint64_t strOffset
= 0;
494 while (const char *s
= strData
.getCStr(&offset
)) {
495 OS
<< format("0x%8.8" PRIx64
": \"", strOffset
);
502 if (shouldDump(Explicit
, ".debug_addr", DIDT_ID_DebugAddr
,
503 DObj
->getAddrSection().Data
)) {
504 DWARFDataExtractor
AddrData(*DObj
, DObj
->getAddrSection(),
505 isLittleEndian(), 0);
506 dumpAddrSection(OS
, AddrData
, DumpOpts
, getMaxVersion(), getCUAddrSize());
509 if (shouldDump(Explicit
, ".debug_ranges", DIDT_ID_DebugRanges
,
510 DObj
->getRangesSection().Data
)) {
511 uint8_t savedAddressByteSize
= getCUAddrSize();
512 DWARFDataExtractor
rangesData(*DObj
, DObj
->getRangesSection(),
513 isLittleEndian(), savedAddressByteSize
);
515 DWARFDebugRangeList rangeList
;
516 while (rangesData
.isValidOffset(offset
)) {
517 if (Error E
= rangeList
.extract(rangesData
, &offset
)) {
518 WithColor::error() << toString(std::move(E
)) << '\n';
525 auto LookupPooledAddress
= [&](uint32_t Index
) -> Optional
<SectionedAddress
> {
526 const auto &CUs
= compile_units();
527 auto I
= CUs
.begin();
530 return (*I
)->getAddrOffsetSectionItem(Index
);
533 if (shouldDump(Explicit
, ".debug_rnglists", DIDT_ID_DebugRnglists
,
534 DObj
->getRnglistsSection().Data
)) {
535 DWARFDataExtractor
RnglistData(*DObj
, DObj
->getRnglistsSection(),
536 isLittleEndian(), 0);
537 dumpRnglistsSection(OS
, RnglistData
, LookupPooledAddress
, DumpOpts
);
540 if (shouldDump(ExplicitDWO
, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists
,
541 DObj
->getRnglistsDWOSection().Data
)) {
542 DWARFDataExtractor
RnglistData(*DObj
, DObj
->getRnglistsDWOSection(),
543 isLittleEndian(), 0);
544 dumpRnglistsSection(OS
, RnglistData
, LookupPooledAddress
, DumpOpts
);
547 if (shouldDump(Explicit
, ".debug_pubnames", DIDT_ID_DebugPubnames
,
548 DObj
->getPubnamesSection().Data
))
549 DWARFDebugPubTable(*DObj
, DObj
->getPubnamesSection(), isLittleEndian(), false)
552 if (shouldDump(Explicit
, ".debug_pubtypes", DIDT_ID_DebugPubtypes
,
553 DObj
->getPubtypesSection().Data
))
554 DWARFDebugPubTable(*DObj
, DObj
->getPubtypesSection(), isLittleEndian(), false)
557 if (shouldDump(Explicit
, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames
,
558 DObj
->getGnuPubnamesSection().Data
))
559 DWARFDebugPubTable(*DObj
, DObj
->getGnuPubnamesSection(), isLittleEndian(),
563 if (shouldDump(Explicit
, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes
,
564 DObj
->getGnuPubtypesSection().Data
))
565 DWARFDebugPubTable(*DObj
, DObj
->getGnuPubtypesSection(), isLittleEndian(),
569 if (shouldDump(Explicit
, ".debug_str_offsets", DIDT_ID_DebugStrOffsets
,
570 DObj
->getStrOffsetsSection().Data
))
571 dumpStringOffsetsSection(OS
, "debug_str_offsets", *DObj
,
572 DObj
->getStrOffsetsSection(),
573 DObj
->getStrSection(), normal_units(),
574 isLittleEndian(), getMaxVersion());
575 if (shouldDump(ExplicitDWO
, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets
,
576 DObj
->getStrOffsetsDWOSection().Data
))
577 dumpStringOffsetsSection(OS
, "debug_str_offsets.dwo", *DObj
,
578 DObj
->getStrOffsetsDWOSection(),
579 DObj
->getStrDWOSection(), dwo_units(),
580 isLittleEndian(), getMaxDWOVersion());
582 if (shouldDump(Explicit
, ".gdb_index", DIDT_ID_GdbIndex
,
583 DObj
->getGdbIndexSection())) {
584 getGdbIndex().dump(OS
);
587 if (shouldDump(Explicit
, ".apple_names", DIDT_ID_AppleNames
,
588 DObj
->getAppleNamesSection().Data
))
589 getAppleNames().dump(OS
);
591 if (shouldDump(Explicit
, ".apple_types", DIDT_ID_AppleTypes
,
592 DObj
->getAppleTypesSection().Data
))
593 getAppleTypes().dump(OS
);
595 if (shouldDump(Explicit
, ".apple_namespaces", DIDT_ID_AppleNamespaces
,
596 DObj
->getAppleNamespacesSection().Data
))
597 getAppleNamespaces().dump(OS
);
599 if (shouldDump(Explicit
, ".apple_objc", DIDT_ID_AppleObjC
,
600 DObj
->getAppleObjCSection().Data
))
601 getAppleObjC().dump(OS
);
602 if (shouldDump(Explicit
, ".debug_names", DIDT_ID_DebugNames
,
603 DObj
->getNamesSection().Data
))
604 getDebugNames().dump(OS
);
607 DWARFCompileUnit
*DWARFContext::getDWOCompileUnitForHash(uint64_t Hash
) {
608 parseDWOUnits(LazyParse
);
610 if (const auto &CUI
= getCUIndex()) {
611 if (const auto *R
= CUI
.getFromHash(Hash
))
612 return dyn_cast_or_null
<DWARFCompileUnit
>(
613 DWOUnits
.getUnitForIndexEntry(*R
));
617 // If there's no index, just search through the CUs in the DWO - there's
618 // probably only one unless this is something like LTO - though an in-process
619 // built/cached lookup table could be used in that case to improve repeated
620 // lookups of different CUs in the DWO.
621 for (const auto &DWOCU
: dwo_compile_units()) {
622 // Might not have parsed DWO ID yet.
623 if (!DWOCU
->getDWOId()) {
624 if (Optional
<uint64_t> DWOId
=
625 toUnsigned(DWOCU
->getUnitDIE().find(DW_AT_GNU_dwo_id
)))
626 DWOCU
->setDWOId(*DWOId
);
631 if (DWOCU
->getDWOId() == Hash
)
632 return dyn_cast
<DWARFCompileUnit
>(DWOCU
.get());
637 DWARFDie
DWARFContext::getDIEForOffset(uint64_t Offset
) {
639 if (auto *CU
= NormalUnits
.getUnitForOffset(Offset
))
640 return CU
->getDIEForOffset(Offset
);
644 bool DWARFContext::verify(raw_ostream
&OS
, DIDumpOptions DumpOpts
) {
646 DWARFVerifier
verifier(OS
, *this, DumpOpts
);
648 Success
&= verifier
.handleDebugAbbrev();
649 if (DumpOpts
.DumpType
& DIDT_DebugInfo
)
650 Success
&= verifier
.handleDebugInfo();
651 if (DumpOpts
.DumpType
& DIDT_DebugLine
)
652 Success
&= verifier
.handleDebugLine();
653 Success
&= verifier
.handleAccelTables();
657 const DWARFUnitIndex
&DWARFContext::getCUIndex() {
661 DataExtractor
CUIndexData(DObj
->getCUIndexSection(), isLittleEndian(), 0);
663 CUIndex
= std::make_unique
<DWARFUnitIndex
>(DW_SECT_INFO
);
664 CUIndex
->parse(CUIndexData
);
668 const DWARFUnitIndex
&DWARFContext::getTUIndex() {
672 DataExtractor
TUIndexData(DObj
->getTUIndexSection(), isLittleEndian(), 0);
674 TUIndex
= std::make_unique
<DWARFUnitIndex
>(DW_SECT_TYPES
);
675 TUIndex
->parse(TUIndexData
);
679 DWARFGdbIndex
&DWARFContext::getGdbIndex() {
683 DataExtractor
GdbIndexData(DObj
->getGdbIndexSection(), true /*LE*/, 0);
684 GdbIndex
= std::make_unique
<DWARFGdbIndex
>();
685 GdbIndex
->parse(GdbIndexData
);
689 const DWARFDebugAbbrev
*DWARFContext::getDebugAbbrev() {
693 DataExtractor
abbrData(DObj
->getAbbrevSection(), isLittleEndian(), 0);
695 Abbrev
.reset(new DWARFDebugAbbrev());
696 Abbrev
->extract(abbrData
);
700 const DWARFDebugAbbrev
*DWARFContext::getDebugAbbrevDWO() {
702 return AbbrevDWO
.get();
704 DataExtractor
abbrData(DObj
->getAbbrevDWOSection(), isLittleEndian(), 0);
705 AbbrevDWO
.reset(new DWARFDebugAbbrev());
706 AbbrevDWO
->extract(abbrData
);
707 return AbbrevDWO
.get();
710 const DWARFDebugLoc
*DWARFContext::getDebugLoc() {
714 Loc
.reset(new DWARFDebugLoc
);
715 // Assume all units have the same address byte size.
716 if (getNumCompileUnits()) {
717 DWARFDataExtractor
LocData(*DObj
, DObj
->getLocSection(), isLittleEndian(),
718 getUnitAtIndex(0)->getAddressByteSize());
724 const DWARFDebugLoclists
*DWARFContext::getDebugLocDWO() {
728 LocDWO
.reset(new DWARFDebugLoclists());
729 // Assume all compile units have the same address byte size.
730 // FIXME: We don't need AddressSize for split DWARF since relocatable
731 // addresses cannot appear there. At the moment DWARFExpression requires it.
732 DataExtractor
LocData(DObj
->getLocDWOSection().Data
, isLittleEndian(), 4);
733 // Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and
734 // that means we are parsing the new style .debug_loc (pre-standatized version
735 // of the .debug_loclists).
736 LocDWO
->parse(LocData
, 4 /* Version */);
740 const DWARFDebugAranges
*DWARFContext::getDebugAranges() {
742 return Aranges
.get();
744 Aranges
.reset(new DWARFDebugAranges());
745 Aranges
->generate(this);
746 return Aranges
.get();
749 const DWARFDebugFrame
*DWARFContext::getDebugFrame() {
751 return DebugFrame
.get();
753 // There's a "bug" in the DWARFv3 standard with respect to the target address
754 // size within debug frame sections. While DWARF is supposed to be independent
755 // of its container, FDEs have fields with size being "target address size",
756 // which isn't specified in DWARF in general. It's only specified for CUs, but
757 // .eh_frame can appear without a .debug_info section. Follow the example of
758 // other tools (libdwarf) and extract this from the container (ObjectFile
759 // provides this information). This problem is fixed in DWARFv4
760 // See this dwarf-discuss discussion for more details:
761 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
762 DWARFDataExtractor
debugFrameData(*DObj
, DObj
->getFrameSection(),
763 isLittleEndian(), DObj
->getAddressSize());
764 DebugFrame
.reset(new DWARFDebugFrame(getArch(), false /* IsEH */));
765 DebugFrame
->parse(debugFrameData
);
766 return DebugFrame
.get();
769 const DWARFDebugFrame
*DWARFContext::getEHFrame() {
771 return EHFrame
.get();
773 DWARFDataExtractor
debugFrameData(*DObj
, DObj
->getEHFrameSection(),
774 isLittleEndian(), DObj
->getAddressSize());
775 DebugFrame
.reset(new DWARFDebugFrame(getArch(), true /* IsEH */));
776 DebugFrame
->parse(debugFrameData
);
777 return DebugFrame
.get();
780 const DWARFDebugMacro
*DWARFContext::getDebugMacro() {
784 DataExtractor
MacinfoData(DObj
->getMacinfoSection(), isLittleEndian(), 0);
785 Macro
.reset(new DWARFDebugMacro());
786 Macro
->parse(MacinfoData
);
790 template <typename T
>
791 static T
&getAccelTable(std::unique_ptr
<T
> &Cache
, const DWARFObject
&Obj
,
792 const DWARFSection
&Section
, StringRef StringSection
,
793 bool IsLittleEndian
) {
796 DWARFDataExtractor
AccelSection(Obj
, Section
, IsLittleEndian
, 0);
797 DataExtractor
StrData(StringSection
, IsLittleEndian
, 0);
798 Cache
.reset(new T(AccelSection
, StrData
));
799 if (Error E
= Cache
->extract())
800 llvm::consumeError(std::move(E
));
804 const DWARFDebugNames
&DWARFContext::getDebugNames() {
805 return getAccelTable(Names
, *DObj
, DObj
->getNamesSection(),
806 DObj
->getStrSection(), isLittleEndian());
809 const AppleAcceleratorTable
&DWARFContext::getAppleNames() {
810 return getAccelTable(AppleNames
, *DObj
, DObj
->getAppleNamesSection(),
811 DObj
->getStrSection(), isLittleEndian());
814 const AppleAcceleratorTable
&DWARFContext::getAppleTypes() {
815 return getAccelTable(AppleTypes
, *DObj
, DObj
->getAppleTypesSection(),
816 DObj
->getStrSection(), isLittleEndian());
819 const AppleAcceleratorTable
&DWARFContext::getAppleNamespaces() {
820 return getAccelTable(AppleNamespaces
, *DObj
,
821 DObj
->getAppleNamespacesSection(),
822 DObj
->getStrSection(), isLittleEndian());
825 const AppleAcceleratorTable
&DWARFContext::getAppleObjC() {
826 return getAccelTable(AppleObjC
, *DObj
, DObj
->getAppleObjCSection(),
827 DObj
->getStrSection(), isLittleEndian());
830 const DWARFDebugLine::LineTable
*
831 DWARFContext::getLineTableForUnit(DWARFUnit
*U
) {
832 Expected
<const DWARFDebugLine::LineTable
*> ExpectedLineTable
=
833 getLineTableForUnit(U
, dumpWarning
);
834 if (!ExpectedLineTable
) {
835 dumpWarning(ExpectedLineTable
.takeError());
838 return *ExpectedLineTable
;
841 Expected
<const DWARFDebugLine::LineTable
*> DWARFContext::getLineTableForUnit(
842 DWARFUnit
*U
, std::function
<void(Error
)> RecoverableErrorCallback
) {
844 Line
.reset(new DWARFDebugLine
);
846 auto UnitDIE
= U
->getUnitDIE();
850 auto Offset
= toSectionOffset(UnitDIE
.find(DW_AT_stmt_list
));
852 return nullptr; // No line table for this compile unit.
854 uint64_t stmtOffset
= *Offset
+ U
->getLineTableOffset();
855 // See if the line table is cached.
856 if (const DWARFLineTable
*lt
= Line
->getLineTable(stmtOffset
))
859 // Make sure the offset is good before we try to parse.
860 if (stmtOffset
>= U
->getLineSection().Data
.size())
863 // We have to parse it first.
864 DWARFDataExtractor
lineData(*DObj
, U
->getLineSection(), isLittleEndian(),
865 U
->getAddressByteSize());
866 return Line
->getOrParseLineTable(lineData
, stmtOffset
, *this, U
,
867 RecoverableErrorCallback
);
870 void DWARFContext::parseNormalUnits() {
871 if (!NormalUnits
.empty())
873 DObj
->forEachInfoSections([&](const DWARFSection
&S
) {
874 NormalUnits
.addUnitsForSection(*this, S
, DW_SECT_INFO
);
876 NormalUnits
.finishedInfoUnits();
877 DObj
->forEachTypesSections([&](const DWARFSection
&S
) {
878 NormalUnits
.addUnitsForSection(*this, S
, DW_SECT_TYPES
);
882 void DWARFContext::parseDWOUnits(bool Lazy
) {
883 if (!DWOUnits
.empty())
885 DObj
->forEachInfoDWOSections([&](const DWARFSection
&S
) {
886 DWOUnits
.addUnitsForDWOSection(*this, S
, DW_SECT_INFO
, Lazy
);
888 DWOUnits
.finishedInfoUnits();
889 DObj
->forEachTypesDWOSections([&](const DWARFSection
&S
) {
890 DWOUnits
.addUnitsForDWOSection(*this, S
, DW_SECT_TYPES
, Lazy
);
894 DWARFCompileUnit
*DWARFContext::getCompileUnitForOffset(uint64_t Offset
) {
896 return dyn_cast_or_null
<DWARFCompileUnit
>(
897 NormalUnits
.getUnitForOffset(Offset
));
900 DWARFCompileUnit
*DWARFContext::getCompileUnitForAddress(uint64_t Address
) {
901 // First, get the offset of the compile unit.
902 uint64_t CUOffset
= getDebugAranges()->findAddress(Address
);
903 // Retrieve the compile unit.
904 return getCompileUnitForOffset(CUOffset
);
907 DWARFContext::DIEsForAddress
DWARFContext::getDIEsForAddress(uint64_t Address
) {
908 DIEsForAddress Result
;
910 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
);
914 Result
.CompileUnit
= CU
;
915 Result
.FunctionDIE
= CU
->getSubroutineForAddress(Address
);
917 std::vector
<DWARFDie
> Worklist
;
918 Worklist
.push_back(Result
.FunctionDIE
);
919 while (!Worklist
.empty()) {
920 DWARFDie DIE
= Worklist
.back();
926 if (DIE
.getTag() == DW_TAG_lexical_block
&&
927 DIE
.addressRangeContainsAddress(Address
)) {
928 Result
.BlockDIE
= DIE
;
932 for (auto Child
: DIE
)
933 Worklist
.push_back(Child
);
939 /// TODO: change input parameter from "uint64_t Address"
940 /// into "SectionedAddress Address"
941 static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit
*CU
,
943 FunctionNameKind Kind
,
944 std::string
&FunctionName
,
945 uint32_t &StartLine
) {
946 // The address may correspond to instruction in some inlined function,
947 // so we have to build the chain of inlined functions and take the
948 // name of the topmost function in it.
949 SmallVector
<DWARFDie
, 4> InlinedChain
;
950 CU
->getInlinedChainForAddress(Address
, InlinedChain
);
951 if (InlinedChain
.empty())
954 const DWARFDie
&DIE
= InlinedChain
[0];
955 bool FoundResult
= false;
956 const char *Name
= nullptr;
957 if (Kind
!= FunctionNameKind::None
&& (Name
= DIE
.getSubroutineName(Kind
))) {
961 if (auto DeclLineResult
= DIE
.getDeclLine()) {
962 StartLine
= DeclLineResult
;
969 static Optional
<uint64_t> getTypeSize(DWARFDie Type
, uint64_t PointerSize
) {
970 if (auto SizeAttr
= Type
.find(DW_AT_byte_size
))
971 if (Optional
<uint64_t> Size
= SizeAttr
->getAsUnsignedConstant())
974 switch (Type
.getTag()) {
975 case DW_TAG_pointer_type
:
976 case DW_TAG_reference_type
:
977 case DW_TAG_rvalue_reference_type
:
979 case DW_TAG_ptr_to_member_type
: {
980 if (DWARFDie BaseType
= Type
.getAttributeValueAsReferencedDie(DW_AT_type
))
981 if (BaseType
.getTag() == DW_TAG_subroutine_type
)
982 return 2 * PointerSize
;
985 case DW_TAG_const_type
:
986 case DW_TAG_volatile_type
:
987 case DW_TAG_restrict_type
:
988 case DW_TAG_typedef
: {
989 if (DWARFDie BaseType
= Type
.getAttributeValueAsReferencedDie(DW_AT_type
))
990 return getTypeSize(BaseType
, PointerSize
);
993 case DW_TAG_array_type
: {
994 DWARFDie BaseType
= Type
.getAttributeValueAsReferencedDie(DW_AT_type
);
996 return Optional
<uint64_t>();
997 Optional
<uint64_t> BaseSize
= getTypeSize(BaseType
, PointerSize
);
999 return Optional
<uint64_t>();
1000 uint64_t Size
= *BaseSize
;
1001 for (DWARFDie Child
: Type
) {
1002 if (Child
.getTag() != DW_TAG_subrange_type
)
1005 if (auto ElemCountAttr
= Child
.find(DW_AT_count
))
1006 if (Optional
<uint64_t> ElemCount
=
1007 ElemCountAttr
->getAsUnsignedConstant())
1009 if (auto UpperBoundAttr
= Child
.find(DW_AT_upper_bound
))
1010 if (Optional
<int64_t> UpperBound
=
1011 UpperBoundAttr
->getAsSignedConstant()) {
1012 int64_t LowerBound
= 0;
1013 if (auto LowerBoundAttr
= Child
.find(DW_AT_lower_bound
))
1014 LowerBound
= LowerBoundAttr
->getAsSignedConstant().getValueOr(0);
1015 Size
*= *UpperBound
- LowerBound
+ 1;
1023 return Optional
<uint64_t>();
1026 void DWARFContext::addLocalsForDie(DWARFCompileUnit
*CU
, DWARFDie Subprogram
,
1027 DWARFDie Die
, std::vector
<DILocal
> &Result
) {
1028 if (Die
.getTag() == DW_TAG_variable
||
1029 Die
.getTag() == DW_TAG_formal_parameter
) {
1031 if (auto NameAttr
= Subprogram
.find(DW_AT_name
))
1032 if (Optional
<const char *> Name
= NameAttr
->getAsCString())
1033 Local
.FunctionName
= *Name
;
1034 if (auto LocationAttr
= Die
.find(DW_AT_location
))
1035 if (Optional
<ArrayRef
<uint8_t>> Location
= LocationAttr
->getAsBlock())
1036 if (!Location
->empty() && (*Location
)[0] == DW_OP_fbreg
)
1038 decodeSLEB128(Location
->data() + 1, nullptr, Location
->end());
1039 if (auto TagOffsetAttr
= Die
.find(DW_AT_LLVM_tag_offset
))
1040 Local
.TagOffset
= TagOffsetAttr
->getAsUnsignedConstant();
1043 Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
1045 if (auto NameAttr
= Die
.find(DW_AT_name
))
1046 if (Optional
<const char *> Name
= NameAttr
->getAsCString())
1048 if (auto Type
= Die
.getAttributeValueAsReferencedDie(DW_AT_type
))
1049 Local
.Size
= getTypeSize(Type
, getCUAddrSize());
1050 if (auto DeclFileAttr
= Die
.find(DW_AT_decl_file
)) {
1051 if (const auto *LT
= CU
->getContext().getLineTableForUnit(CU
))
1052 LT
->getFileNameByIndex(
1053 DeclFileAttr
->getAsUnsignedConstant().getValue(),
1054 CU
->getCompilationDir(),
1055 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
,
1058 if (auto DeclLineAttr
= Die
.find(DW_AT_decl_line
))
1059 Local
.DeclLine
= DeclLineAttr
->getAsUnsignedConstant().getValue();
1061 Result
.push_back(Local
);
1065 if (Die
.getTag() == DW_TAG_inlined_subroutine
)
1067 Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
1068 Subprogram
= Origin
;
1070 for (auto Child
: Die
)
1071 addLocalsForDie(CU
, Subprogram
, Child
, Result
);
1074 std::vector
<DILocal
>
1075 DWARFContext::getLocalsForAddress(object::SectionedAddress Address
) {
1076 std::vector
<DILocal
> Result
;
1077 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1081 DWARFDie Subprogram
= CU
->getSubroutineForAddress(Address
.Address
);
1082 if (Subprogram
.isValid())
1083 addLocalsForDie(CU
, Subprogram
, Subprogram
, Result
);
1087 DILineInfo
DWARFContext::getLineInfoForAddress(object::SectionedAddress Address
,
1088 DILineInfoSpecifier Spec
) {
1091 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1095 getFunctionNameAndStartLineForAddress(CU
, Address
.Address
, Spec
.FNKind
,
1096 Result
.FunctionName
, Result
.StartLine
);
1097 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1098 if (const DWARFLineTable
*LineTable
= getLineTableForUnit(CU
)) {
1099 LineTable
->getFileLineInfoForAddress(
1100 {Address
.Address
, Address
.SectionIndex
}, CU
->getCompilationDir(),
1101 Spec
.FLIKind
, Result
);
1107 DILineInfoTable
DWARFContext::getLineInfoForAddressRange(
1108 object::SectionedAddress Address
, uint64_t Size
, DILineInfoSpecifier Spec
) {
1109 DILineInfoTable Lines
;
1110 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1114 uint32_t StartLine
= 0;
1115 std::string
FunctionName(DILineInfo::BadString
);
1116 getFunctionNameAndStartLineForAddress(CU
, Address
.Address
, Spec
.FNKind
,
1117 FunctionName
, StartLine
);
1119 // If the Specifier says we don't need FileLineInfo, just
1120 // return the top-most function at the starting address.
1121 if (Spec
.FLIKind
== FileLineInfoKind::None
) {
1123 Result
.FunctionName
= FunctionName
;
1124 Result
.StartLine
= StartLine
;
1125 Lines
.push_back(std::make_pair(Address
.Address
, Result
));
1129 const DWARFLineTable
*LineTable
= getLineTableForUnit(CU
);
1131 // Get the index of row we're looking for in the line table.
1132 std::vector
<uint32_t> RowVector
;
1133 if (!LineTable
->lookupAddressRange({Address
.Address
, Address
.SectionIndex
},
1138 for (uint32_t RowIndex
: RowVector
) {
1139 // Take file number and line/column from the row.
1140 const DWARFDebugLine::Row
&Row
= LineTable
->Rows
[RowIndex
];
1142 LineTable
->getFileNameByIndex(Row
.File
, CU
->getCompilationDir(),
1143 Spec
.FLIKind
, Result
.FileName
);
1144 Result
.FunctionName
= FunctionName
;
1145 Result
.Line
= Row
.Line
;
1146 Result
.Column
= Row
.Column
;
1147 Result
.StartLine
= StartLine
;
1148 Lines
.push_back(std::make_pair(Row
.Address
.Address
, Result
));
1155 DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address
,
1156 DILineInfoSpecifier Spec
) {
1157 DIInliningInfo InliningInfo
;
1159 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1161 return InliningInfo
;
1163 const DWARFLineTable
*LineTable
= nullptr;
1164 SmallVector
<DWARFDie
, 4> InlinedChain
;
1165 CU
->getInlinedChainForAddress(Address
.Address
, InlinedChain
);
1166 if (InlinedChain
.size() == 0) {
1167 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
1168 // try to at least get file/line info from symbol table.
1169 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1171 LineTable
= getLineTableForUnit(CU
);
1172 if (LineTable
&& LineTable
->getFileLineInfoForAddress(
1173 {Address
.Address
, Address
.SectionIndex
},
1174 CU
->getCompilationDir(), Spec
.FLIKind
, Frame
))
1175 InliningInfo
.addFrame(Frame
);
1177 return InliningInfo
;
1180 uint32_t CallFile
= 0, CallLine
= 0, CallColumn
= 0, CallDiscriminator
= 0;
1181 for (uint32_t i
= 0, n
= InlinedChain
.size(); i
!= n
; i
++) {
1182 DWARFDie
&FunctionDIE
= InlinedChain
[i
];
1184 // Get function name if necessary.
1185 if (const char *Name
= FunctionDIE
.getSubroutineName(Spec
.FNKind
))
1186 Frame
.FunctionName
= Name
;
1187 if (auto DeclLineResult
= FunctionDIE
.getDeclLine())
1188 Frame
.StartLine
= DeclLineResult
;
1189 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1191 // For the topmost frame, initialize the line table of this
1192 // compile unit and fetch file/line info from it.
1193 LineTable
= getLineTableForUnit(CU
);
1194 // For the topmost routine, get file/line info from line table.
1196 LineTable
->getFileLineInfoForAddress(
1197 {Address
.Address
, Address
.SectionIndex
}, CU
->getCompilationDir(),
1198 Spec
.FLIKind
, Frame
);
1200 // Otherwise, use call file, call line and call column from
1201 // previous DIE in inlined chain.
1203 LineTable
->getFileNameByIndex(CallFile
, CU
->getCompilationDir(),
1204 Spec
.FLIKind
, Frame
.FileName
);
1205 Frame
.Line
= CallLine
;
1206 Frame
.Column
= CallColumn
;
1207 Frame
.Discriminator
= CallDiscriminator
;
1209 // Get call file/line/column of a current DIE.
1211 FunctionDIE
.getCallerFrame(CallFile
, CallLine
, CallColumn
,
1215 InliningInfo
.addFrame(Frame
);
1217 return InliningInfo
;
1220 std::shared_ptr
<DWARFContext
>
1221 DWARFContext::getDWOContext(StringRef AbsolutePath
) {
1222 if (auto S
= DWP
.lock()) {
1223 DWARFContext
*Ctxt
= S
->Context
.get();
1224 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1227 std::weak_ptr
<DWOFile
> *Entry
= &DWOFiles
[AbsolutePath
];
1229 if (auto S
= Entry
->lock()) {
1230 DWARFContext
*Ctxt
= S
->Context
.get();
1231 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1234 Expected
<OwningBinary
<ObjectFile
>> Obj
= [&] {
1235 if (!CheckedForDWP
) {
1236 SmallString
<128> DWPName
;
1237 auto Obj
= object::ObjectFile::createObjectFile(
1238 this->DWPName
.empty()
1239 ? (DObj
->getFileName() + ".dwp").toStringRef(DWPName
)
1240 : StringRef(this->DWPName
));
1245 CheckedForDWP
= true;
1246 // TODO: Should this error be handled (maybe in a high verbosity mode)
1247 // before falling back to .dwo files?
1248 consumeError(Obj
.takeError());
1252 return object::ObjectFile::createObjectFile(AbsolutePath
);
1256 // TODO: Actually report errors helpfully.
1257 consumeError(Obj
.takeError());
1261 auto S
= std::make_shared
<DWOFile
>();
1262 S
->File
= std::move(Obj
.get());
1263 S
->Context
= DWARFContext::create(*S
->File
.getBinary());
1265 auto *Ctxt
= S
->Context
.get();
1266 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1269 static Error
createError(const Twine
&Reason
, llvm::Error E
) {
1270 return make_error
<StringError
>(Reason
+ toString(std::move(E
)),
1271 inconvertibleErrorCode());
1274 /// SymInfo contains information about symbol: it's address
1275 /// and section index which is -1LL for absolute symbols.
1278 uint64_t SectionIndex
;
1281 /// Returns the address of symbol relocation used against and a section index.
1282 /// Used for futher relocations computation. Symbol's section load address is
1283 static Expected
<SymInfo
> getSymbolInfo(const object::ObjectFile
&Obj
,
1284 const RelocationRef
&Reloc
,
1285 const LoadedObjectInfo
*L
,
1286 std::map
<SymbolRef
, SymInfo
> &Cache
) {
1287 SymInfo Ret
= {0, (uint64_t)-1LL};
1288 object::section_iterator RSec
= Obj
.section_end();
1289 object::symbol_iterator Sym
= Reloc
.getSymbol();
1291 std::map
<SymbolRef
, SymInfo
>::iterator CacheIt
= Cache
.end();
1292 // First calculate the address of the symbol or section as it appears
1293 // in the object file
1294 if (Sym
!= Obj
.symbol_end()) {
1296 std::tie(CacheIt
, New
) = Cache
.insert({*Sym
, {0, 0}});
1298 return CacheIt
->second
;
1300 Expected
<uint64_t> SymAddrOrErr
= Sym
->getAddress();
1302 return createError("failed to compute symbol address: ",
1303 SymAddrOrErr
.takeError());
1305 // Also remember what section this symbol is in for later
1306 auto SectOrErr
= Sym
->getSection();
1308 return createError("failed to get symbol section: ",
1309 SectOrErr
.takeError());
1312 Ret
.Address
= *SymAddrOrErr
;
1313 } else if (auto *MObj
= dyn_cast
<MachOObjectFile
>(&Obj
)) {
1314 RSec
= MObj
->getRelocationSection(Reloc
.getRawDataRefImpl());
1315 Ret
.Address
= RSec
->getAddress();
1318 if (RSec
!= Obj
.section_end())
1319 Ret
.SectionIndex
= RSec
->getIndex();
1321 // If we are given load addresses for the sections, we need to adjust:
1322 // SymAddr = (Address of Symbol Or Section in File) -
1323 // (Address of Section in File) +
1324 // (Load Address of Section)
1325 // RSec is now either the section being targeted or the section
1326 // containing the symbol being targeted. In either case,
1327 // we need to perform the same computation.
1328 if (L
&& RSec
!= Obj
.section_end())
1329 if (uint64_t SectionLoadAddress
= L
->getSectionLoadAddress(*RSec
))
1330 Ret
.Address
+= SectionLoadAddress
- RSec
->getAddress();
1332 if (CacheIt
!= Cache
.end())
1333 CacheIt
->second
= Ret
;
1338 static bool isRelocScattered(const object::ObjectFile
&Obj
,
1339 const RelocationRef
&Reloc
) {
1340 const MachOObjectFile
*MachObj
= dyn_cast
<MachOObjectFile
>(&Obj
);
1343 // MachO also has relocations that point to sections and
1344 // scattered relocations.
1345 auto RelocInfo
= MachObj
->getRelocation(Reloc
.getRawDataRefImpl());
1346 return MachObj
->isRelocationScattered(RelocInfo
);
1349 ErrorPolicy
DWARFContext::defaultErrorHandler(Error E
) {
1350 WithColor::error() << toString(std::move(E
)) << '\n';
1351 return ErrorPolicy::Continue
;
1355 struct DWARFSectionMap final
: public DWARFSection
{
1356 RelocAddrMap Relocs
;
1359 class DWARFObjInMemory final
: public DWARFObject
{
1360 bool IsLittleEndian
;
1361 uint8_t AddressSize
;
1363 const object::ObjectFile
*Obj
= nullptr;
1364 std::vector
<SectionName
> SectionNames
;
1366 using InfoSectionMap
= MapVector
<object::SectionRef
, DWARFSectionMap
,
1367 std::map
<object::SectionRef
, unsigned>>;
1369 InfoSectionMap InfoSections
;
1370 InfoSectionMap TypesSections
;
1371 InfoSectionMap InfoDWOSections
;
1372 InfoSectionMap TypesDWOSections
;
1374 DWARFSectionMap LocSection
;
1375 DWARFSectionMap LoclistsSection
;
1376 DWARFSectionMap LineSection
;
1377 DWARFSectionMap RangesSection
;
1378 DWARFSectionMap RnglistsSection
;
1379 DWARFSectionMap StrOffsetsSection
;
1380 DWARFSectionMap LineDWOSection
;
1381 DWARFSectionMap FrameSection
;
1382 DWARFSectionMap EHFrameSection
;
1383 DWARFSectionMap LocDWOSection
;
1384 DWARFSectionMap StrOffsetsDWOSection
;
1385 DWARFSectionMap RangesDWOSection
;
1386 DWARFSectionMap RnglistsDWOSection
;
1387 DWARFSectionMap AddrSection
;
1388 DWARFSectionMap AppleNamesSection
;
1389 DWARFSectionMap AppleTypesSection
;
1390 DWARFSectionMap AppleNamespacesSection
;
1391 DWARFSectionMap AppleObjCSection
;
1392 DWARFSectionMap NamesSection
;
1393 DWARFSectionMap PubnamesSection
;
1394 DWARFSectionMap PubtypesSection
;
1395 DWARFSectionMap GnuPubnamesSection
;
1396 DWARFSectionMap GnuPubtypesSection
;
1398 DWARFSectionMap
*mapNameToDWARFSection(StringRef Name
) {
1399 return StringSwitch
<DWARFSectionMap
*>(Name
)
1400 .Case("debug_loc", &LocSection
)
1401 .Case("debug_loclists", &LoclistsSection
)
1402 .Case("debug_line", &LineSection
)
1403 .Case("debug_frame", &FrameSection
)
1404 .Case("eh_frame", &EHFrameSection
)
1405 .Case("debug_str_offsets", &StrOffsetsSection
)
1406 .Case("debug_ranges", &RangesSection
)
1407 .Case("debug_rnglists", &RnglistsSection
)
1408 .Case("debug_loc.dwo", &LocDWOSection
)
1409 .Case("debug_line.dwo", &LineDWOSection
)
1410 .Case("debug_names", &NamesSection
)
1411 .Case("debug_rnglists.dwo", &RnglistsDWOSection
)
1412 .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection
)
1413 .Case("debug_addr", &AddrSection
)
1414 .Case("apple_names", &AppleNamesSection
)
1415 .Case("debug_pubnames", &PubnamesSection
)
1416 .Case("debug_pubtypes", &PubtypesSection
)
1417 .Case("debug_gnu_pubnames", &GnuPubnamesSection
)
1418 .Case("debug_gnu_pubtypes", &GnuPubtypesSection
)
1419 .Case("apple_types", &AppleTypesSection
)
1420 .Case("apple_namespaces", &AppleNamespacesSection
)
1421 .Case("apple_namespac", &AppleNamespacesSection
)
1422 .Case("apple_objc", &AppleObjCSection
)
1426 StringRef AbbrevSection
;
1427 StringRef ArangesSection
;
1428 StringRef StrSection
;
1429 StringRef MacinfoSection
;
1430 StringRef AbbrevDWOSection
;
1431 StringRef StrDWOSection
;
1432 StringRef CUIndexSection
;
1433 StringRef GdbIndexSection
;
1434 StringRef TUIndexSection
;
1435 StringRef LineStrSection
;
1437 // A deque holding section data whose iterators are not invalidated when
1438 // new decompressed sections are inserted at the end.
1439 std::deque
<SmallString
<0>> UncompressedSections
;
1441 StringRef
*mapSectionToMember(StringRef Name
) {
1442 if (DWARFSection
*Sec
= mapNameToDWARFSection(Name
))
1444 return StringSwitch
<StringRef
*>(Name
)
1445 .Case("debug_abbrev", &AbbrevSection
)
1446 .Case("debug_aranges", &ArangesSection
)
1447 .Case("debug_str", &StrSection
)
1448 .Case("debug_macinfo", &MacinfoSection
)
1449 .Case("debug_abbrev.dwo", &AbbrevDWOSection
)
1450 .Case("debug_str.dwo", &StrDWOSection
)
1451 .Case("debug_cu_index", &CUIndexSection
)
1452 .Case("debug_tu_index", &TUIndexSection
)
1453 .Case("gdb_index", &GdbIndexSection
)
1454 .Case("debug_line_str", &LineStrSection
)
1455 // Any more debug info sections go here.
1459 /// If Sec is compressed section, decompresses and updates its contents
1460 /// provided by Data. Otherwise leaves it unchanged.
1461 Error
maybeDecompress(const object::SectionRef
&Sec
, StringRef Name
,
1463 if (!Decompressor::isCompressed(Sec
))
1464 return Error::success();
1466 Expected
<Decompressor
> Decompressor
=
1467 Decompressor::create(Name
, Data
, IsLittleEndian
, AddressSize
== 8);
1469 return Decompressor
.takeError();
1472 if (auto Err
= Decompressor
->resizeAndDecompress(Out
))
1475 UncompressedSections
.push_back(std::move(Out
));
1476 Data
= UncompressedSections
.back();
1478 return Error::success();
1482 DWARFObjInMemory(const StringMap
<std::unique_ptr
<MemoryBuffer
>> &Sections
,
1483 uint8_t AddrSize
, bool IsLittleEndian
)
1484 : IsLittleEndian(IsLittleEndian
) {
1485 for (const auto &SecIt
: Sections
) {
1486 if (StringRef
*SectionData
= mapSectionToMember(SecIt
.first()))
1487 *SectionData
= SecIt
.second
->getBuffer();
1488 else if (SecIt
.first() == "debug_info")
1489 // Find debug_info and debug_types data by section rather than name as
1490 // there are multiple, comdat grouped, of these sections.
1491 InfoSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1492 else if (SecIt
.first() == "debug_info.dwo")
1493 InfoDWOSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1494 else if (SecIt
.first() == "debug_types")
1495 TypesSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1496 else if (SecIt
.first() == "debug_types.dwo")
1497 TypesDWOSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1500 DWARFObjInMemory(const object::ObjectFile
&Obj
, const LoadedObjectInfo
*L
,
1501 function_ref
<ErrorPolicy(Error
)> HandleError
)
1502 : IsLittleEndian(Obj
.isLittleEndian()),
1503 AddressSize(Obj
.getBytesInAddress()), FileName(Obj
.getFileName()),
1506 StringMap
<unsigned> SectionAmountMap
;
1507 for (const SectionRef
&Section
: Obj
.sections()) {
1509 if (auto NameOrErr
= Section
.getName())
1512 consumeError(NameOrErr
.takeError());
1514 ++SectionAmountMap
[Name
];
1515 SectionNames
.push_back({ Name
, true });
1517 // Skip BSS and Virtual sections, they aren't interesting.
1518 if (Section
.isBSS() || Section
.isVirtual())
1521 // Skip sections stripped by dsymutil.
1522 if (Section
.isStripped())
1526 section_iterator RelocatedSection
= Section
.getRelocatedSection();
1527 // Try to obtain an already relocated version of this section.
1528 // Else use the unrelocated section from the object file. We'll have to
1529 // apply relocations ourselves later.
1530 if (!L
|| !L
->getLoadedSectionContents(*RelocatedSection
, Data
)) {
1531 Expected
<StringRef
> E
= Section
.getContents();
1535 // maybeDecompress below will error.
1536 consumeError(E
.takeError());
1539 if (auto Err
= maybeDecompress(Section
, Name
, Data
)) {
1540 ErrorPolicy EP
= HandleError(createError(
1541 "failed to decompress '" + Name
+ "', ", std::move(Err
)));
1542 if (EP
== ErrorPolicy::Halt
)
1547 // Compressed sections names in GNU style starts from ".z",
1548 // at this point section is decompressed and we drop compression prefix.
1550 Name
.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1552 // Map platform specific debug section names to DWARF standard section
1554 Name
= Obj
.mapDebugSectionName(Name
);
1556 if (StringRef
*SectionData
= mapSectionToMember(Name
)) {
1557 *SectionData
= Data
;
1558 if (Name
== "debug_ranges") {
1559 // FIXME: Use the other dwo range section when we emit it.
1560 RangesDWOSection
.Data
= Data
;
1562 } else if (Name
== "debug_info") {
1563 // Find debug_info and debug_types data by section rather than name as
1564 // there are multiple, comdat grouped, of these sections.
1565 InfoSections
[Section
].Data
= Data
;
1566 } else if (Name
== "debug_info.dwo") {
1567 InfoDWOSections
[Section
].Data
= Data
;
1568 } else if (Name
== "debug_types") {
1569 TypesSections
[Section
].Data
= Data
;
1570 } else if (Name
== "debug_types.dwo") {
1571 TypesDWOSections
[Section
].Data
= Data
;
1574 if (RelocatedSection
== Obj
.section_end())
1577 StringRef RelSecName
;
1578 if (auto NameOrErr
= RelocatedSection
->getName())
1579 RelSecName
= *NameOrErr
;
1581 consumeError(NameOrErr
.takeError());
1583 // If the section we're relocating was relocated already by the JIT,
1584 // then we used the relocated version above, so we do not need to process
1585 // relocations for it now.
1586 StringRef RelSecData
;
1587 if (L
&& L
->getLoadedSectionContents(*RelocatedSection
, RelSecData
))
1590 // In Mach-o files, the relocations do not need to be applied if
1591 // there is no load offset to apply. The value read at the
1592 // relocation point already factors in the section address
1593 // (actually applying the relocations will produce wrong results
1594 // as the section address will be added twice).
1595 if (!L
&& isa
<MachOObjectFile
>(&Obj
))
1598 RelSecName
= RelSecName
.substr(
1599 RelSecName
.find_first_not_of("._z")); // Skip . and _ prefixes.
1601 // TODO: Add support for relocations in other sections as needed.
1602 // Record relocations for the debug_info and debug_line sections.
1603 DWARFSectionMap
*Sec
= mapNameToDWARFSection(RelSecName
);
1604 RelocAddrMap
*Map
= Sec
? &Sec
->Relocs
: nullptr;
1606 // Find debug_info and debug_types relocs by section rather than name
1607 // as there are multiple, comdat grouped, of these sections.
1608 if (RelSecName
== "debug_info")
1609 Map
= &static_cast<DWARFSectionMap
&>(InfoSections
[*RelocatedSection
])
1611 else if (RelSecName
== "debug_info.dwo")
1612 Map
= &static_cast<DWARFSectionMap
&>(
1613 InfoDWOSections
[*RelocatedSection
])
1615 else if (RelSecName
== "debug_types")
1617 &static_cast<DWARFSectionMap
&>(TypesSections
[*RelocatedSection
])
1619 else if (RelSecName
== "debug_types.dwo")
1620 Map
= &static_cast<DWARFSectionMap
&>(
1621 TypesDWOSections
[*RelocatedSection
])
1627 if (Section
.relocation_begin() == Section
.relocation_end())
1630 // Symbol to [address, section index] cache mapping.
1631 std::map
<SymbolRef
, SymInfo
> AddrCache
;
1632 bool (*Supports
)(uint64_t);
1633 RelocationResolver Resolver
;
1634 std::tie(Supports
, Resolver
) = getRelocationResolver(Obj
);
1635 for (const RelocationRef
&Reloc
: Section
.relocations()) {
1636 // FIXME: it's not clear how to correctly handle scattered
1638 if (isRelocScattered(Obj
, Reloc
))
1641 Expected
<SymInfo
> SymInfoOrErr
=
1642 getSymbolInfo(Obj
, Reloc
, L
, AddrCache
);
1643 if (!SymInfoOrErr
) {
1644 if (HandleError(SymInfoOrErr
.takeError()) == ErrorPolicy::Halt
)
1649 // Check if Resolver can handle this relocation type early so as not to
1650 // handle invalid cases in DWARFDataExtractor.
1652 // TODO Don't store Resolver in every RelocAddrEntry.
1653 if (Supports
&& Supports(Reloc
.getType())) {
1654 auto I
= Map
->try_emplace(
1656 RelocAddrEntry
{SymInfoOrErr
->SectionIndex
, Reloc
,
1657 SymInfoOrErr
->Address
,
1658 Optional
<object::RelocationRef
>(), 0, Resolver
});
1659 // If we didn't successfully insert that's because we already had a
1660 // relocation for that offset. Store it as a second relocation in the
1661 // same RelocAddrEntry instead.
1663 RelocAddrEntry
&entry
= I
.first
->getSecond();
1665 ErrorPolicy EP
= HandleError(createError(
1666 "At most two relocations per offset are supported"));
1667 if (EP
== ErrorPolicy::Halt
)
1670 entry
.Reloc2
= Reloc
;
1671 entry
.SymbolValue2
= SymInfoOrErr
->Address
;
1674 SmallString
<32> Type
;
1675 Reloc
.getTypeName(Type
);
1676 ErrorPolicy EP
= HandleError(
1677 createError("failed to compute relocation: " + Type
+ ", ",
1678 errorCodeToError(object_error::parse_failed
)));
1679 if (EP
== ErrorPolicy::Halt
)
1685 for (SectionName
&S
: SectionNames
)
1686 if (SectionAmountMap
[S
.Name
] > 1)
1687 S
.IsNameUnique
= false;
1690 Optional
<RelocAddrEntry
> find(const DWARFSection
&S
,
1691 uint64_t Pos
) const override
{
1692 auto &Sec
= static_cast<const DWARFSectionMap
&>(S
);
1693 RelocAddrMap::const_iterator AI
= Sec
.Relocs
.find(Pos
);
1694 if (AI
== Sec
.Relocs
.end())
1699 const object::ObjectFile
*getFile() const override
{ return Obj
; }
1701 ArrayRef
<SectionName
> getSectionNames() const override
{
1702 return SectionNames
;
1705 bool isLittleEndian() const override
{ return IsLittleEndian
; }
1706 StringRef
getAbbrevDWOSection() const override
{ return AbbrevDWOSection
; }
1707 const DWARFSection
&getLineDWOSection() const override
{
1708 return LineDWOSection
;
1710 const DWARFSection
&getLocDWOSection() const override
{
1711 return LocDWOSection
;
1713 StringRef
getStrDWOSection() const override
{ return StrDWOSection
; }
1714 const DWARFSection
&getStrOffsetsDWOSection() const override
{
1715 return StrOffsetsDWOSection
;
1717 const DWARFSection
&getRangesDWOSection() const override
{
1718 return RangesDWOSection
;
1720 const DWARFSection
&getRnglistsDWOSection() const override
{
1721 return RnglistsDWOSection
;
1723 const DWARFSection
&getAddrSection() const override
{ return AddrSection
; }
1724 StringRef
getCUIndexSection() const override
{ return CUIndexSection
; }
1725 StringRef
getGdbIndexSection() const override
{ return GdbIndexSection
; }
1726 StringRef
getTUIndexSection() const override
{ return TUIndexSection
; }
1729 const DWARFSection
&getStrOffsetsSection() const override
{
1730 return StrOffsetsSection
;
1732 StringRef
getLineStrSection() const override
{ return LineStrSection
; }
1734 // Sections for DWARF5 split dwarf proposal.
1735 void forEachInfoDWOSections(
1736 function_ref
<void(const DWARFSection
&)> F
) const override
{
1737 for (auto &P
: InfoDWOSections
)
1740 void forEachTypesDWOSections(
1741 function_ref
<void(const DWARFSection
&)> F
) const override
{
1742 for (auto &P
: TypesDWOSections
)
1746 StringRef
getAbbrevSection() const override
{ return AbbrevSection
; }
1747 const DWARFSection
&getLocSection() const override
{ return LocSection
; }
1748 const DWARFSection
&getLoclistsSection() const override
{ return LoclistsSection
; }
1749 StringRef
getArangesSection() const override
{ return ArangesSection
; }
1750 const DWARFSection
&getFrameSection() const override
{
1751 return FrameSection
;
1753 const DWARFSection
&getEHFrameSection() const override
{
1754 return EHFrameSection
;
1756 const DWARFSection
&getLineSection() const override
{ return LineSection
; }
1757 StringRef
getStrSection() const override
{ return StrSection
; }
1758 const DWARFSection
&getRangesSection() const override
{ return RangesSection
; }
1759 const DWARFSection
&getRnglistsSection() const override
{
1760 return RnglistsSection
;
1762 StringRef
getMacinfoSection() const override
{ return MacinfoSection
; }
1763 const DWARFSection
&getPubnamesSection() const override
{ return PubnamesSection
; }
1764 const DWARFSection
&getPubtypesSection() const override
{ return PubtypesSection
; }
1765 const DWARFSection
&getGnuPubnamesSection() const override
{
1766 return GnuPubnamesSection
;
1768 const DWARFSection
&getGnuPubtypesSection() const override
{
1769 return GnuPubtypesSection
;
1771 const DWARFSection
&getAppleNamesSection() const override
{
1772 return AppleNamesSection
;
1774 const DWARFSection
&getAppleTypesSection() const override
{
1775 return AppleTypesSection
;
1777 const DWARFSection
&getAppleNamespacesSection() const override
{
1778 return AppleNamespacesSection
;
1780 const DWARFSection
&getAppleObjCSection() const override
{
1781 return AppleObjCSection
;
1783 const DWARFSection
&getNamesSection() const override
{
1784 return NamesSection
;
1787 StringRef
getFileName() const override
{ return FileName
; }
1788 uint8_t getAddressSize() const override
{ return AddressSize
; }
1789 void forEachInfoSections(
1790 function_ref
<void(const DWARFSection
&)> F
) const override
{
1791 for (auto &P
: InfoSections
)
1794 void forEachTypesSections(
1795 function_ref
<void(const DWARFSection
&)> F
) const override
{
1796 for (auto &P
: TypesSections
)
1802 std::unique_ptr
<DWARFContext
>
1803 DWARFContext::create(const object::ObjectFile
&Obj
, const LoadedObjectInfo
*L
,
1804 function_ref
<ErrorPolicy(Error
)> HandleError
,
1805 std::string DWPName
) {
1806 auto DObj
= std::make_unique
<DWARFObjInMemory
>(Obj
, L
, HandleError
);
1807 return std::make_unique
<DWARFContext
>(std::move(DObj
), std::move(DWPName
));
1810 std::unique_ptr
<DWARFContext
>
1811 DWARFContext::create(const StringMap
<std::unique_ptr
<MemoryBuffer
>> &Sections
,
1812 uint8_t AddrSize
, bool isLittleEndian
) {
1814 std::make_unique
<DWARFObjInMemory
>(Sections
, AddrSize
, isLittleEndian
);
1815 return std::make_unique
<DWARFContext
>(std::move(DObj
), "");
1818 Error
DWARFContext::loadRegisterInfo(const object::ObjectFile
&Obj
) {
1819 // Detect the architecture from the object file. We usually don't need OS
1820 // info to lookup a target and create register info.
1822 TT
.setArch(Triple::ArchType(Obj
.getArch()));
1823 TT
.setVendor(Triple::UnknownVendor
);
1824 TT
.setOS(Triple::UnknownOS
);
1825 std::string TargetLookupError
;
1826 const Target
*TheTarget
=
1827 TargetRegistry::lookupTarget(TT
.str(), TargetLookupError
);
1828 if (!TargetLookupError
.empty())
1829 return createStringError(errc::invalid_argument
,
1830 TargetLookupError
.c_str());
1831 RegInfo
.reset(TheTarget
->createMCRegInfo(TT
.str()));
1832 return Error::success();
1835 uint8_t DWARFContext::getCUAddrSize() {
1836 // In theory, different compile units may have different address byte
1837 // sizes, but for simplicity we just use the address byte size of the
1838 // last compile unit. In practice the address size field is repeated across
1839 // various DWARF headers (at least in version 5) to make it easier to dump
1840 // them independently, not to enable varying the address size.
1842 for (const auto &CU
: compile_units()) {
1843 Addr
= CU
->getAddressByteSize();
1849 void DWARFContext::dumpWarning(Error Warning
) {
1850 handleAllErrors(std::move(Warning
), [](ErrorInfoBase
&Info
) {
1851 WithColor::warning() << Info
.message() << '\n';