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/MapVector.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/BinaryFormat/Dwarf.h"
17 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
18 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
19 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
20 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
21 #include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
22 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
23 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
24 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
25 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
26 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
27 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
28 #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
29 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
30 #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
31 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
32 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
33 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
34 #include "llvm/DebugInfo/DWARF/DWARFListTable.h"
35 #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
36 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
37 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
38 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
39 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
40 #include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
41 #include "llvm/MC/TargetRegistry.h"
42 #include "llvm/Object/Decompressor.h"
43 #include "llvm/Object/MachO.h"
44 #include "llvm/Object/ObjectFile.h"
45 #include "llvm/Object/RelocationResolver.h"
46 #include "llvm/Support/Casting.h"
47 #include "llvm/Support/DataExtractor.h"
48 #include "llvm/Support/Error.h"
49 #include "llvm/Support/Format.h"
50 #include "llvm/Support/LEB128.h"
51 #include "llvm/Support/FormatVariadic.h"
52 #include "llvm/Support/MemoryBuffer.h"
53 #include "llvm/Support/Path.h"
54 #include "llvm/Support/raw_ostream.h"
64 using namespace dwarf
;
65 using namespace object
;
67 #define DEBUG_TYPE "dwarf"
69 using DWARFLineTable
= DWARFDebugLine::LineTable
;
70 using FileLineInfoKind
= DILineInfoSpecifier::FileLineInfoKind
;
71 using FunctionNameKind
= DILineInfoSpecifier::FunctionNameKind
;
73 DWARFContext::DWARFContext(std::unique_ptr
<const DWARFObject
> DObj
,
75 std::function
<void(Error
)> RecoverableErrorHandler
,
76 std::function
<void(Error
)> WarningHandler
)
77 : DIContext(CK_DWARF
), DWPName(std::move(DWPName
)),
78 RecoverableErrorHandler(RecoverableErrorHandler
),
79 WarningHandler(WarningHandler
), DObj(std::move(DObj
)) {}
81 DWARFContext::~DWARFContext() = default;
83 /// Dump the UUID load command.
84 static void dumpUUID(raw_ostream
&OS
, const ObjectFile
&Obj
) {
85 auto *MachO
= dyn_cast
<MachOObjectFile
>(&Obj
);
88 for (auto LC
: MachO
->load_commands()) {
89 raw_ostream::uuid_t UUID
;
90 if (LC
.C
.cmd
== MachO::LC_UUID
) {
91 if (LC
.C
.cmdsize
< sizeof(UUID
) + sizeof(LC
.C
)) {
92 OS
<< "error: UUID load command is too short.\n";
96 memcpy(&UUID
, LC
.Ptr
+sizeof(LC
.C
), sizeof(UUID
));
98 Triple T
= MachO
->getArchTriple();
99 OS
<< " (" << T
.getArchName() << ')';
100 OS
<< ' ' << MachO
->getFileName() << '\n';
105 using ContributionCollection
=
106 std::vector
<std::optional
<StrOffsetsContributionDescriptor
>>;
108 // Collect all the contributions to the string offsets table from all units,
109 // sort them by their starting offsets and remove duplicates.
110 static ContributionCollection
111 collectContributionData(DWARFContext::unit_iterator_range Units
) {
112 ContributionCollection Contributions
;
113 for (const auto &U
: Units
)
114 if (const auto &C
= U
->getStringOffsetsTableContribution())
115 Contributions
.push_back(C
);
116 // Sort the contributions so that any invalid ones are placed at
117 // the start of the contributions vector. This way they are reported
119 llvm::sort(Contributions
,
120 [](const std::optional
<StrOffsetsContributionDescriptor
> &L
,
121 const std::optional
<StrOffsetsContributionDescriptor
> &R
) {
123 return L
->Base
< R
->Base
;
124 return R
.has_value();
127 // Uniquify contributions, as it is possible that units (specifically
128 // type units in dwo or dwp files) share contributions. We don't want
129 // to report them more than once.
131 std::unique(Contributions
.begin(), Contributions
.end(),
132 [](const std::optional
<StrOffsetsContributionDescriptor
> &L
,
133 const std::optional
<StrOffsetsContributionDescriptor
> &R
) {
135 return L
->Base
== R
->Base
&& L
->Size
== R
->Size
;
138 Contributions
.end());
139 return Contributions
;
142 // Dump a DWARF string offsets section. This may be a DWARF v5 formatted
143 // string offsets section, where each compile or type unit contributes a
144 // number of entries (string offsets), with each contribution preceded by
145 // a header containing size and version number. Alternatively, it may be a
146 // monolithic series of string offsets, as generated by the pre-DWARF v5
147 // implementation of split DWARF; however, in that case we still need to
148 // collect contributions of units because the size of the offsets (4 or 8
149 // bytes) depends on the format of the referencing unit (DWARF32 or DWARF64).
150 static void dumpStringOffsetsSection(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
151 StringRef SectionName
,
152 const DWARFObject
&Obj
,
153 const DWARFSection
&StringOffsetsSection
,
154 StringRef StringSection
,
155 DWARFContext::unit_iterator_range Units
,
157 auto Contributions
= collectContributionData(Units
);
158 DWARFDataExtractor
StrOffsetExt(Obj
, StringOffsetsSection
, LittleEndian
, 0);
159 DataExtractor
StrData(StringSection
, LittleEndian
, 0);
160 uint64_t SectionSize
= StringOffsetsSection
.Data
.size();
162 for (auto &Contribution
: Contributions
) {
163 // Report an ill-formed contribution.
165 OS
<< "error: invalid contribution to string offsets table in section ."
166 << SectionName
<< ".\n";
170 dwarf::DwarfFormat Format
= Contribution
->getFormat();
171 int OffsetDumpWidth
= 2 * dwarf::getDwarfOffsetByteSize(Format
);
172 uint16_t Version
= Contribution
->getVersion();
173 uint64_t ContributionHeader
= Contribution
->Base
;
174 // In DWARF v5 there is a contribution header that immediately precedes
175 // the string offsets base (the location we have previously retrieved from
176 // the CU DIE's DW_AT_str_offsets attribute). The header is located either
177 // 8 or 16 bytes before the base, depending on the contribution's format.
179 ContributionHeader
-= Format
== DWARF32
? 8 : 16;
181 // Detect overlapping contributions.
182 if (Offset
> ContributionHeader
) {
183 DumpOpts
.RecoverableErrorHandler(createStringError(
184 errc::invalid_argument
,
185 "overlapping contributions to string offsets table in section .%s.",
186 SectionName
.data()));
188 // Report a gap in the table.
189 if (Offset
< ContributionHeader
) {
190 OS
<< format("0x%8.8" PRIx64
": Gap, length = ", Offset
);
191 OS
<< (ContributionHeader
- Offset
) << "\n";
193 OS
<< format("0x%8.8" PRIx64
": ", ContributionHeader
);
194 // In DWARF v5 the contribution size in the descriptor does not equal
195 // the originally encoded length (it does not contain the length of the
196 // version field and the padding, a total of 4 bytes). Add them back in
198 OS
<< "Contribution size = " << (Contribution
->Size
+ (Version
< 5 ? 0 : 4))
199 << ", Format = " << dwarf::FormatString(Format
)
200 << ", Version = " << Version
<< "\n";
202 Offset
= Contribution
->Base
;
203 unsigned EntrySize
= Contribution
->getDwarfOffsetByteSize();
204 while (Offset
- Contribution
->Base
< Contribution
->Size
) {
205 OS
<< format("0x%8.8" PRIx64
": ", Offset
);
206 uint64_t StringOffset
=
207 StrOffsetExt
.getRelocatedValue(EntrySize
, &Offset
);
208 OS
<< format("%0*" PRIx64
" ", OffsetDumpWidth
, StringOffset
);
209 const char *S
= StrData
.getCStr(&StringOffset
);
211 OS
<< format("\"%s\"", S
);
215 // Report a gap at the end of the table.
216 if (Offset
< SectionSize
) {
217 OS
<< format("0x%8.8" PRIx64
": Gap, length = ", Offset
);
218 OS
<< (SectionSize
- Offset
) << "\n";
222 // Dump the .debug_addr section.
223 static void dumpAddrSection(raw_ostream
&OS
, DWARFDataExtractor
&AddrData
,
224 DIDumpOptions DumpOpts
, uint16_t Version
,
227 while (AddrData
.isValidOffset(Offset
)) {
228 DWARFDebugAddrTable AddrTable
;
229 uint64_t TableOffset
= Offset
;
230 if (Error Err
= AddrTable
.extract(AddrData
, &Offset
, Version
, AddrSize
,
231 DumpOpts
.WarningHandler
)) {
232 DumpOpts
.RecoverableErrorHandler(std::move(Err
));
233 // Keep going after an error, if we can, assuming that the length field
234 // could be read. If it couldn't, stop reading the section.
235 if (auto TableLength
= AddrTable
.getFullLength()) {
236 Offset
= TableOffset
+ *TableLength
;
241 AddrTable
.dump(OS
, DumpOpts
);
245 // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
246 static void dumpRnglistsSection(
247 raw_ostream
&OS
, DWARFDataExtractor
&rnglistData
,
248 llvm::function_ref
<std::optional
<object::SectionedAddress
>(uint32_t)>
250 DIDumpOptions DumpOpts
) {
252 while (rnglistData
.isValidOffset(Offset
)) {
253 llvm::DWARFDebugRnglistTable Rnglists
;
254 uint64_t TableOffset
= Offset
;
255 if (Error Err
= Rnglists
.extract(rnglistData
, &Offset
)) {
256 DumpOpts
.RecoverableErrorHandler(std::move(Err
));
257 uint64_t Length
= Rnglists
.length();
258 // Keep going after an error, if we can, assuming that the length field
259 // could be read. If it couldn't, stop reading the section.
262 Offset
= TableOffset
+ Length
;
264 Rnglists
.dump(rnglistData
, OS
, LookupPooledAddress
, DumpOpts
);
269 std::unique_ptr
<DWARFDebugMacro
>
270 DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType
) {
271 auto Macro
= std::make_unique
<DWARFDebugMacro
>();
272 auto ParseAndDump
= [&](DWARFDataExtractor
&Data
, bool IsMacro
) {
273 if (Error Err
= IsMacro
? Macro
->parseMacro(SectionType
== MacroSection
275 : dwo_compile_units(),
276 SectionType
== MacroSection
277 ? getStringExtractor()
278 : getStringDWOExtractor(),
280 : Macro
->parseMacinfo(Data
)) {
281 RecoverableErrorHandler(std::move(Err
));
285 switch (SectionType
) {
286 case MacinfoSection
: {
287 DWARFDataExtractor
Data(DObj
->getMacinfoSection(), isLittleEndian(), 0);
288 ParseAndDump(Data
, /*IsMacro=*/false);
291 case MacinfoDwoSection
: {
292 DWARFDataExtractor
Data(DObj
->getMacinfoDWOSection(), isLittleEndian(), 0);
293 ParseAndDump(Data
, /*IsMacro=*/false);
297 DWARFDataExtractor
Data(*DObj
, DObj
->getMacroSection(), isLittleEndian(),
299 ParseAndDump(Data
, /*IsMacro=*/true);
302 case MacroDwoSection
: {
303 DWARFDataExtractor
Data(DObj
->getMacroDWOSection(), isLittleEndian(), 0);
304 ParseAndDump(Data
, /*IsMacro=*/true);
311 static void dumpLoclistsSection(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
312 DWARFDataExtractor Data
, const DWARFObject
&Obj
,
313 std::optional
<uint64_t> DumpOffset
) {
316 while (Data
.isValidOffset(Offset
)) {
317 DWARFListTableHeader
Header(".debug_loclists", "locations");
318 if (Error E
= Header
.extract(Data
, &Offset
)) {
319 DumpOpts
.RecoverableErrorHandler(std::move(E
));
323 Header
.dump(Data
, OS
, DumpOpts
);
325 uint64_t EndOffset
= Header
.length() + Header
.getHeaderOffset();
326 Data
.setAddressSize(Header
.getAddrSize());
327 DWARFDebugLoclists
Loc(Data
, Header
.getVersion());
329 if (DumpOffset
>= Offset
&& DumpOffset
< EndOffset
) {
330 Offset
= *DumpOffset
;
331 Loc
.dumpLocationList(&Offset
, OS
, /*BaseAddr=*/std::nullopt
, Obj
,
332 nullptr, DumpOpts
, /*Indent=*/0);
337 Loc
.dumpRange(Offset
, EndOffset
- Offset
, OS
, Obj
, DumpOpts
);
343 static void dumpPubTableSection(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
344 DWARFDataExtractor Data
, bool GnuStyle
) {
345 DWARFDebugPubTable Table
;
346 Table
.extract(Data
, GnuStyle
, DumpOpts
.RecoverableErrorHandler
);
350 void DWARFContext::dump(
351 raw_ostream
&OS
, DIDumpOptions DumpOpts
,
352 std::array
<std::optional
<uint64_t>, DIDT_ID_Count
> DumpOffsets
) {
353 uint64_t DumpType
= DumpOpts
.DumpType
;
355 StringRef Extension
= sys::path::extension(DObj
->getFileName());
356 bool IsDWO
= (Extension
== ".dwo") || (Extension
== ".dwp");
358 // Print UUID header.
359 const auto *ObjFile
= DObj
->getFile();
360 if (DumpType
& DIDT_UUID
)
361 dumpUUID(OS
, *ObjFile
);
363 // Print a header for each explicitly-requested section.
364 // Otherwise just print one for non-empty sections.
365 // Only print empty .dwo section headers when dumping a .dwo file.
366 bool Explicit
= DumpType
!= DIDT_All
&& !IsDWO
;
367 bool ExplicitDWO
= Explicit
&& IsDWO
;
368 auto shouldDump
= [&](bool Explicit
, const char *Name
, unsigned ID
,
369 StringRef Section
) -> std::optional
<uint64_t> * {
370 unsigned Mask
= 1U << ID
;
371 bool Should
= (DumpType
& Mask
) && (Explicit
|| !Section
.empty());
374 OS
<< "\n" << Name
<< " contents:\n";
375 return &DumpOffsets
[ID
];
378 // Dump individual sections.
379 if (shouldDump(Explicit
, ".debug_abbrev", DIDT_ID_DebugAbbrev
,
380 DObj
->getAbbrevSection()))
381 getDebugAbbrev()->dump(OS
);
382 if (shouldDump(ExplicitDWO
, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev
,
383 DObj
->getAbbrevDWOSection()))
384 getDebugAbbrevDWO()->dump(OS
);
386 auto dumpDebugInfo
= [&](const char *Name
, unit_iterator_range Units
) {
387 OS
<< '\n' << Name
<< " contents:\n";
388 if (auto DumpOffset
= DumpOffsets
[DIDT_ID_DebugInfo
])
389 for (const auto &U
: Units
)
390 U
->getDIEForOffset(*DumpOffset
)
391 .dump(OS
, 0, DumpOpts
.noImplicitRecursion());
393 for (const auto &U
: Units
)
394 U
->dump(OS
, DumpOpts
);
396 if ((DumpType
& DIDT_DebugInfo
)) {
397 if (Explicit
|| getNumCompileUnits())
398 dumpDebugInfo(".debug_info", info_section_units());
399 if (ExplicitDWO
|| getNumDWOCompileUnits())
400 dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
403 auto dumpDebugType
= [&](const char *Name
, unit_iterator_range Units
) {
404 OS
<< '\n' << Name
<< " contents:\n";
405 for (const auto &U
: Units
)
406 if (auto DumpOffset
= DumpOffsets
[DIDT_ID_DebugTypes
])
407 U
->getDIEForOffset(*DumpOffset
)
408 .dump(OS
, 0, DumpOpts
.noImplicitRecursion());
410 U
->dump(OS
, DumpOpts
);
412 if ((DumpType
& DIDT_DebugTypes
)) {
413 if (Explicit
|| getNumTypeUnits())
414 dumpDebugType(".debug_types", types_section_units());
415 if (ExplicitDWO
|| getNumDWOTypeUnits())
416 dumpDebugType(".debug_types.dwo", dwo_types_section_units());
419 DIDumpOptions LLDumpOpts
= DumpOpts
;
420 if (LLDumpOpts
.Verbose
)
421 LLDumpOpts
.DisplayRawContents
= true;
423 if (const auto *Off
= shouldDump(Explicit
, ".debug_loc", DIDT_ID_DebugLoc
,
424 DObj
->getLocSection().Data
)) {
425 getDebugLoc()->dump(OS
, *DObj
, LLDumpOpts
, *Off
);
427 if (const auto *Off
=
428 shouldDump(Explicit
, ".debug_loclists", DIDT_ID_DebugLoclists
,
429 DObj
->getLoclistsSection().Data
)) {
430 DWARFDataExtractor
Data(*DObj
, DObj
->getLoclistsSection(), isLittleEndian(),
432 dumpLoclistsSection(OS
, LLDumpOpts
, Data
, *DObj
, *Off
);
434 if (const auto *Off
=
435 shouldDump(ExplicitDWO
, ".debug_loclists.dwo", DIDT_ID_DebugLoclists
,
436 DObj
->getLoclistsDWOSection().Data
)) {
437 DWARFDataExtractor
Data(*DObj
, DObj
->getLoclistsDWOSection(),
438 isLittleEndian(), 0);
439 dumpLoclistsSection(OS
, LLDumpOpts
, Data
, *DObj
, *Off
);
442 if (const auto *Off
=
443 shouldDump(ExplicitDWO
, ".debug_loc.dwo", DIDT_ID_DebugLoc
,
444 DObj
->getLocDWOSection().Data
)) {
445 DWARFDataExtractor
Data(*DObj
, DObj
->getLocDWOSection(), isLittleEndian(),
447 DWARFDebugLoclists
Loc(Data
, /*Version=*/4);
449 uint64_t Offset
= **Off
;
450 Loc
.dumpLocationList(&Offset
, OS
,
451 /*BaseAddr=*/std::nullopt
, *DObj
, nullptr,
456 Loc
.dumpRange(0, Data
.getData().size(), OS
, *DObj
, LLDumpOpts
);
460 if (const std::optional
<uint64_t> *Off
=
461 shouldDump(Explicit
, ".debug_frame", DIDT_ID_DebugFrame
,
462 DObj
->getFrameSection().Data
)) {
463 if (Expected
<const DWARFDebugFrame
*> DF
= getDebugFrame())
464 (*DF
)->dump(OS
, DumpOpts
, *Off
);
466 RecoverableErrorHandler(DF
.takeError());
469 if (const std::optional
<uint64_t> *Off
=
470 shouldDump(Explicit
, ".eh_frame", DIDT_ID_DebugFrame
,
471 DObj
->getEHFrameSection().Data
)) {
472 if (Expected
<const DWARFDebugFrame
*> DF
= getEHFrame())
473 (*DF
)->dump(OS
, DumpOpts
, *Off
);
475 RecoverableErrorHandler(DF
.takeError());
478 if (shouldDump(Explicit
, ".debug_macro", DIDT_ID_DebugMacro
,
479 DObj
->getMacroSection().Data
)) {
480 if (auto Macro
= getDebugMacro())
484 if (shouldDump(Explicit
, ".debug_macro.dwo", DIDT_ID_DebugMacro
,
485 DObj
->getMacroDWOSection())) {
486 if (auto MacroDWO
= getDebugMacroDWO())
490 if (shouldDump(Explicit
, ".debug_macinfo", DIDT_ID_DebugMacro
,
491 DObj
->getMacinfoSection())) {
492 if (auto Macinfo
= getDebugMacinfo())
496 if (shouldDump(Explicit
, ".debug_macinfo.dwo", DIDT_ID_DebugMacro
,
497 DObj
->getMacinfoDWOSection())) {
498 if (auto MacinfoDWO
= getDebugMacinfoDWO())
499 MacinfoDWO
->dump(OS
);
502 if (shouldDump(Explicit
, ".debug_aranges", DIDT_ID_DebugAranges
,
503 DObj
->getArangesSection())) {
505 DWARFDataExtractor
arangesData(DObj
->getArangesSection(), isLittleEndian(),
507 DWARFDebugArangeSet set
;
508 while (arangesData
.isValidOffset(offset
)) {
510 set
.extract(arangesData
, &offset
, DumpOpts
.WarningHandler
)) {
511 RecoverableErrorHandler(std::move(E
));
518 auto DumpLineSection
= [&](DWARFDebugLine::SectionParser Parser
,
519 DIDumpOptions DumpOpts
,
520 std::optional
<uint64_t> DumpOffset
) {
521 while (!Parser
.done()) {
522 if (DumpOffset
&& Parser
.getOffset() != *DumpOffset
) {
523 Parser
.skip(DumpOpts
.WarningHandler
, DumpOpts
.WarningHandler
);
526 OS
<< "debug_line[" << format("0x%8.8" PRIx64
, Parser
.getOffset())
528 Parser
.parseNext(DumpOpts
.WarningHandler
, DumpOpts
.WarningHandler
, &OS
,
533 auto DumpStrSection
= [&](StringRef Section
) {
534 DataExtractor
StrData(Section
, isLittleEndian(), 0);
536 uint64_t StrOffset
= 0;
537 while (StrData
.isValidOffset(Offset
)) {
538 Error Err
= Error::success();
539 const char *CStr
= StrData
.getCStr(&Offset
, &Err
);
541 DumpOpts
.WarningHandler(std::move(Err
));
544 OS
<< format("0x%8.8" PRIx64
": \"", StrOffset
);
545 OS
.write_escaped(CStr
);
551 if (const auto *Off
= shouldDump(Explicit
, ".debug_line", DIDT_ID_DebugLine
,
552 DObj
->getLineSection().Data
)) {
553 DWARFDataExtractor
LineData(*DObj
, DObj
->getLineSection(), isLittleEndian(),
555 DWARFDebugLine::SectionParser
Parser(LineData
, *this, normal_units());
556 DumpLineSection(Parser
, DumpOpts
, *Off
);
559 if (const auto *Off
=
560 shouldDump(ExplicitDWO
, ".debug_line.dwo", DIDT_ID_DebugLine
,
561 DObj
->getLineDWOSection().Data
)) {
562 DWARFDataExtractor
LineData(*DObj
, DObj
->getLineDWOSection(),
563 isLittleEndian(), 0);
564 DWARFDebugLine::SectionParser
Parser(LineData
, *this, dwo_units());
565 DumpLineSection(Parser
, DumpOpts
, *Off
);
568 if (shouldDump(Explicit
, ".debug_cu_index", DIDT_ID_DebugCUIndex
,
569 DObj
->getCUIndexSection())) {
570 getCUIndex().dump(OS
);
573 if (shouldDump(Explicit
, ".debug_tu_index", DIDT_ID_DebugTUIndex
,
574 DObj
->getTUIndexSection())) {
575 getTUIndex().dump(OS
);
578 if (shouldDump(Explicit
, ".debug_str", DIDT_ID_DebugStr
,
579 DObj
->getStrSection()))
580 DumpStrSection(DObj
->getStrSection());
582 if (shouldDump(ExplicitDWO
, ".debug_str.dwo", DIDT_ID_DebugStr
,
583 DObj
->getStrDWOSection()))
584 DumpStrSection(DObj
->getStrDWOSection());
586 if (shouldDump(Explicit
, ".debug_line_str", DIDT_ID_DebugLineStr
,
587 DObj
->getLineStrSection()))
588 DumpStrSection(DObj
->getLineStrSection());
590 if (shouldDump(Explicit
, ".debug_addr", DIDT_ID_DebugAddr
,
591 DObj
->getAddrSection().Data
)) {
592 DWARFDataExtractor
AddrData(*DObj
, DObj
->getAddrSection(),
593 isLittleEndian(), 0);
594 dumpAddrSection(OS
, AddrData
, DumpOpts
, getMaxVersion(), getCUAddrSize());
597 if (shouldDump(Explicit
, ".debug_ranges", DIDT_ID_DebugRanges
,
598 DObj
->getRangesSection().Data
)) {
599 uint8_t savedAddressByteSize
= getCUAddrSize();
600 DWARFDataExtractor
rangesData(*DObj
, DObj
->getRangesSection(),
601 isLittleEndian(), savedAddressByteSize
);
603 DWARFDebugRangeList rangeList
;
604 while (rangesData
.isValidOffset(offset
)) {
605 if (Error E
= rangeList
.extract(rangesData
, &offset
)) {
606 DumpOpts
.RecoverableErrorHandler(std::move(E
));
613 auto LookupPooledAddress
=
614 [&](uint32_t Index
) -> std::optional
<SectionedAddress
> {
615 const auto &CUs
= compile_units();
616 auto I
= CUs
.begin();
619 return (*I
)->getAddrOffsetSectionItem(Index
);
622 if (shouldDump(Explicit
, ".debug_rnglists", DIDT_ID_DebugRnglists
,
623 DObj
->getRnglistsSection().Data
)) {
624 DWARFDataExtractor
RnglistData(*DObj
, DObj
->getRnglistsSection(),
625 isLittleEndian(), 0);
626 dumpRnglistsSection(OS
, RnglistData
, LookupPooledAddress
, DumpOpts
);
629 if (shouldDump(ExplicitDWO
, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists
,
630 DObj
->getRnglistsDWOSection().Data
)) {
631 DWARFDataExtractor
RnglistData(*DObj
, DObj
->getRnglistsDWOSection(),
632 isLittleEndian(), 0);
633 dumpRnglistsSection(OS
, RnglistData
, LookupPooledAddress
, DumpOpts
);
636 if (shouldDump(Explicit
, ".debug_pubnames", DIDT_ID_DebugPubnames
,
637 DObj
->getPubnamesSection().Data
)) {
638 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getPubnamesSection(),
639 isLittleEndian(), 0);
640 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/false);
643 if (shouldDump(Explicit
, ".debug_pubtypes", DIDT_ID_DebugPubtypes
,
644 DObj
->getPubtypesSection().Data
)) {
645 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getPubtypesSection(),
646 isLittleEndian(), 0);
647 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/false);
650 if (shouldDump(Explicit
, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames
,
651 DObj
->getGnuPubnamesSection().Data
)) {
652 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getGnuPubnamesSection(),
653 isLittleEndian(), 0);
654 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/true);
657 if (shouldDump(Explicit
, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes
,
658 DObj
->getGnuPubtypesSection().Data
)) {
659 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getGnuPubtypesSection(),
660 isLittleEndian(), 0);
661 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/true);
664 if (shouldDump(Explicit
, ".debug_str_offsets", DIDT_ID_DebugStrOffsets
,
665 DObj
->getStrOffsetsSection().Data
))
666 dumpStringOffsetsSection(
667 OS
, DumpOpts
, "debug_str_offsets", *DObj
, DObj
->getStrOffsetsSection(),
668 DObj
->getStrSection(), normal_units(), isLittleEndian());
669 if (shouldDump(ExplicitDWO
, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets
,
670 DObj
->getStrOffsetsDWOSection().Data
))
671 dumpStringOffsetsSection(OS
, DumpOpts
, "debug_str_offsets.dwo", *DObj
,
672 DObj
->getStrOffsetsDWOSection(),
673 DObj
->getStrDWOSection(), dwo_units(),
676 if (shouldDump(Explicit
, ".gdb_index", DIDT_ID_GdbIndex
,
677 DObj
->getGdbIndexSection())) {
678 getGdbIndex().dump(OS
);
681 if (shouldDump(Explicit
, ".apple_names", DIDT_ID_AppleNames
,
682 DObj
->getAppleNamesSection().Data
))
683 getAppleNames().dump(OS
);
685 if (shouldDump(Explicit
, ".apple_types", DIDT_ID_AppleTypes
,
686 DObj
->getAppleTypesSection().Data
))
687 getAppleTypes().dump(OS
);
689 if (shouldDump(Explicit
, ".apple_namespaces", DIDT_ID_AppleNamespaces
,
690 DObj
->getAppleNamespacesSection().Data
))
691 getAppleNamespaces().dump(OS
);
693 if (shouldDump(Explicit
, ".apple_objc", DIDT_ID_AppleObjC
,
694 DObj
->getAppleObjCSection().Data
))
695 getAppleObjC().dump(OS
);
696 if (shouldDump(Explicit
, ".debug_names", DIDT_ID_DebugNames
,
697 DObj
->getNamesSection().Data
))
698 getDebugNames().dump(OS
);
701 DWARFTypeUnit
*DWARFContext::getTypeUnitForHash(uint16_t Version
, uint64_t Hash
,
703 parseDWOUnits(LazyParse
);
705 if (const auto &TUI
= getTUIndex()) {
706 if (const auto *R
= TUI
.getFromHash(Hash
))
707 return dyn_cast_or_null
<DWARFTypeUnit
>(
708 DWOUnits
.getUnitForIndexEntry(*R
));
712 struct UnitContainers
{
713 const DWARFUnitVector
&Units
;
714 std::optional
<DenseMap
<uint64_t, DWARFTypeUnit
*>> &Map
;
716 UnitContainers Units
= IsDWO
? UnitContainers
{DWOUnits
, DWOTypeUnits
}
717 : UnitContainers
{NormalUnits
, NormalTypeUnits
};
720 for (const auto &U
: IsDWO
? dwo_units() : normal_units()) {
721 if (DWARFTypeUnit
*TU
= dyn_cast
<DWARFTypeUnit
>(U
.get()))
722 (*Units
.Map
)[TU
->getTypeHash()] = TU
;
726 return (*Units
.Map
)[Hash
];
729 DWARFCompileUnit
*DWARFContext::getDWOCompileUnitForHash(uint64_t Hash
) {
730 parseDWOUnits(LazyParse
);
732 if (const auto &CUI
= getCUIndex()) {
733 if (const auto *R
= CUI
.getFromHash(Hash
))
734 return dyn_cast_or_null
<DWARFCompileUnit
>(
735 DWOUnits
.getUnitForIndexEntry(*R
));
739 // If there's no index, just search through the CUs in the DWO - there's
740 // probably only one unless this is something like LTO - though an in-process
741 // built/cached lookup table could be used in that case to improve repeated
742 // lookups of different CUs in the DWO.
743 for (const auto &DWOCU
: dwo_compile_units()) {
744 // Might not have parsed DWO ID yet.
745 if (!DWOCU
->getDWOId()) {
746 if (std::optional
<uint64_t> DWOId
=
747 toUnsigned(DWOCU
->getUnitDIE().find(DW_AT_GNU_dwo_id
)))
748 DWOCU
->setDWOId(*DWOId
);
753 if (DWOCU
->getDWOId() == Hash
)
754 return dyn_cast
<DWARFCompileUnit
>(DWOCU
.get());
759 DWARFDie
DWARFContext::getDIEForOffset(uint64_t Offset
) {
761 if (auto *CU
= NormalUnits
.getUnitForOffset(Offset
))
762 return CU
->getDIEForOffset(Offset
);
766 bool DWARFContext::verify(raw_ostream
&OS
, DIDumpOptions DumpOpts
) {
768 DWARFVerifier
verifier(OS
, *this, DumpOpts
);
770 Success
&= verifier
.handleDebugAbbrev();
771 if (DumpOpts
.DumpType
& DIDT_DebugCUIndex
)
772 Success
&= verifier
.handleDebugCUIndex();
773 if (DumpOpts
.DumpType
& DIDT_DebugTUIndex
)
774 Success
&= verifier
.handleDebugTUIndex();
775 if (DumpOpts
.DumpType
& DIDT_DebugInfo
)
776 Success
&= verifier
.handleDebugInfo();
777 if (DumpOpts
.DumpType
& DIDT_DebugLine
)
778 Success
&= verifier
.handleDebugLine();
779 Success
&= verifier
.handleAccelTables();
783 void fixupIndexV4(const DWARFObject
&DObj
, DWARFContext
&C
,
784 DWARFUnitIndex
&Index
) {
785 using EntryType
= DWARFUnitIndex::Entry::SectionContribution
;
786 using EntryMap
= DenseMap
<uint32_t, EntryType
>;
788 if (DObj
.getCUIndexSection().empty())
792 uint32_t TruncOffset
= 0;
793 DObj
.forEachInfoDWOSections([&](const DWARFSection
&S
) {
794 if (!(C
.getParseCUTUIndexManually() ||
795 S
.Data
.size() >= std::numeric_limits
<uint32_t>::max()))
798 DWARFDataExtractor
Data(DObj
, S
, C
.isLittleEndian(), 0);
799 while (Data
.isValidOffset(Offset
)) {
800 DWARFUnitHeader Header
;
801 if (!Header
.extract(C
, Data
, &Offset
, DWARFSectionKind::DW_SECT_INFO
)) {
802 logAllUnhandledErrors(
803 createError("Failed to parse CU header in DWP file"), errs());
808 auto Iter
= Map
.insert({TruncOffset
,
809 {Header
.getOffset(), Header
.getNextUnitOffset() -
810 Header
.getOffset()}});
812 logAllUnhandledErrors(
813 createError("Collision occured between for truncated offset 0x" +
814 Twine::utohexstr(TruncOffset
)),
820 Offset
= Header
.getNextUnitOffset();
821 TruncOffset
= Offset
;
828 for (DWARFUnitIndex::Entry
&E
: Index
.getMutableRows()) {
831 DWARFUnitIndex::Entry::SectionContribution
&CUOff
= E
.getContribution();
832 auto Iter
= Map
.find(CUOff
.getOffset());
833 if (Iter
== Map
.end()) {
834 logAllUnhandledErrors(createError("Could not find CU offset 0x" +
835 Twine::utohexstr(CUOff
.getOffset()) +
840 CUOff
.setOffset(Iter
->second
.getOffset());
841 if (CUOff
.getOffset() != Iter
->second
.getOffset())
842 logAllUnhandledErrors(createError("Length of CU in CU index doesn't "
843 "match calculated length at offset 0x" +
844 Twine::utohexstr(CUOff
.getOffset())),
849 void fixupIndexV5(const DWARFObject
&DObj
, DWARFContext
&C
,
850 DWARFUnitIndex
&Index
) {
851 DenseMap
<uint64_t, uint64_t> Map
;
853 DObj
.forEachInfoDWOSections([&](const DWARFSection
&S
) {
854 if (!(C
.getParseCUTUIndexManually() ||
855 S
.Data
.size() >= std::numeric_limits
<uint32_t>::max()))
857 DWARFDataExtractor
Data(DObj
, S
, C
.isLittleEndian(), 0);
859 while (Data
.isValidOffset(Offset
)) {
860 DWARFUnitHeader Header
;
861 if (!Header
.extract(C
, Data
, &Offset
, DWARFSectionKind::DW_SECT_INFO
)) {
862 logAllUnhandledErrors(
863 createError("Failed to parse unit header in DWP file"), errs());
866 bool CU
= Header
.getUnitType() == DW_UT_split_compile
;
867 uint64_t Sig
= CU
? *Header
.getDWOId() : Header
.getTypeHash();
868 Map
[Sig
] = Header
.getOffset();
869 Offset
= Header
.getNextUnitOffset();
874 for (DWARFUnitIndex::Entry
&E
: Index
.getMutableRows()) {
877 DWARFUnitIndex::Entry::SectionContribution
&CUOff
= E
.getContribution();
878 auto Iter
= Map
.find(E
.getSignature());
879 if (Iter
== Map
.end()) {
880 logAllUnhandledErrors(
881 createError("Could not find unit with signature 0x" +
882 Twine::utohexstr(E
.getSignature()) + " in the Map"),
886 CUOff
.setOffset(Iter
->second
);
890 void fixupIndex(const DWARFObject
&DObj
, DWARFContext
&C
,
891 DWARFUnitIndex
&Index
) {
892 if (Index
.getVersion() < 5)
893 fixupIndexV4(DObj
, C
, Index
);
895 fixupIndexV5(DObj
, C
, Index
);
898 const DWARFUnitIndex
&DWARFContext::getCUIndex() {
902 DataExtractor
CUIndexData(DObj
->getCUIndexSection(), isLittleEndian(), 0);
903 CUIndex
= std::make_unique
<DWARFUnitIndex
>(DW_SECT_INFO
);
904 bool IsParseSuccessful
= CUIndex
->parse(CUIndexData
);
905 if (IsParseSuccessful
)
906 fixupIndex(*DObj
, *this, *CUIndex
);
910 const DWARFUnitIndex
&DWARFContext::getTUIndex() {
914 DataExtractor
TUIndexData(DObj
->getTUIndexSection(), isLittleEndian(), 0);
915 TUIndex
= std::make_unique
<DWARFUnitIndex
>(DW_SECT_EXT_TYPES
);
916 bool isParseSuccessful
= TUIndex
->parse(TUIndexData
);
917 // If we are parsing TU-index and for .debug_types section we don't need
919 if (isParseSuccessful
&& TUIndex
->getVersion() != 2)
920 fixupIndex(*DObj
, *this, *TUIndex
);
924 DWARFGdbIndex
&DWARFContext::getGdbIndex() {
928 DataExtractor
GdbIndexData(DObj
->getGdbIndexSection(), true /*LE*/, 0);
929 GdbIndex
= std::make_unique
<DWARFGdbIndex
>();
930 GdbIndex
->parse(GdbIndexData
);
934 const DWARFDebugAbbrev
*DWARFContext::getDebugAbbrev() {
938 DataExtractor
abbrData(DObj
->getAbbrevSection(), isLittleEndian(), 0);
940 Abbrev
.reset(new DWARFDebugAbbrev());
941 Abbrev
->extract(abbrData
);
945 const DWARFDebugAbbrev
*DWARFContext::getDebugAbbrevDWO() {
947 return AbbrevDWO
.get();
949 DataExtractor
abbrData(DObj
->getAbbrevDWOSection(), isLittleEndian(), 0);
950 AbbrevDWO
.reset(new DWARFDebugAbbrev());
951 AbbrevDWO
->extract(abbrData
);
952 return AbbrevDWO
.get();
955 const DWARFDebugLoc
*DWARFContext::getDebugLoc() {
959 // Assume all units have the same address byte size.
962 ? DWARFDataExtractor(*DObj
, DObj
->getLocSection(), isLittleEndian(),
963 getUnitAtIndex(0)->getAddressByteSize())
964 : DWARFDataExtractor("", isLittleEndian(), 0);
965 Loc
.reset(new DWARFDebugLoc(std::move(LocData
)));
969 const DWARFDebugAranges
*DWARFContext::getDebugAranges() {
971 return Aranges
.get();
973 Aranges
.reset(new DWARFDebugAranges());
974 Aranges
->generate(this);
975 return Aranges
.get();
978 Expected
<const DWARFDebugFrame
*> DWARFContext::getDebugFrame() {
980 return DebugFrame
.get();
982 const DWARFSection
&DS
= DObj
->getFrameSection();
984 // There's a "bug" in the DWARFv3 standard with respect to the target address
985 // size within debug frame sections. While DWARF is supposed to be independent
986 // of its container, FDEs have fields with size being "target address size",
987 // which isn't specified in DWARF in general. It's only specified for CUs, but
988 // .eh_frame can appear without a .debug_info section. Follow the example of
989 // other tools (libdwarf) and extract this from the container (ObjectFile
990 // provides this information). This problem is fixed in DWARFv4
991 // See this dwarf-discuss discussion for more details:
992 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
993 DWARFDataExtractor
DebugFrameData(*DObj
, DS
, isLittleEndian(),
994 DObj
->getAddressSize());
996 std::make_unique
<DWARFDebugFrame
>(getArch(), /*IsEH=*/false, DS
.Address
);
997 if (Error E
= DF
->parse(DebugFrameData
))
1000 DebugFrame
.swap(DF
);
1001 return DebugFrame
.get();
1004 Expected
<const DWARFDebugFrame
*> DWARFContext::getEHFrame() {
1006 return EHFrame
.get();
1008 const DWARFSection
&DS
= DObj
->getEHFrameSection();
1009 DWARFDataExtractor
DebugFrameData(*DObj
, DS
, isLittleEndian(),
1010 DObj
->getAddressSize());
1013 std::make_unique
<DWARFDebugFrame
>(getArch(), /*IsEH=*/true, DS
.Address
);
1014 if (Error E
= DF
->parse(DebugFrameData
))
1015 return std::move(E
);
1016 DebugFrame
.swap(DF
);
1017 return DebugFrame
.get();
1020 const DWARFDebugMacro
*DWARFContext::getDebugMacro() {
1022 Macro
= parseMacroOrMacinfo(MacroSection
);
1026 const DWARFDebugMacro
*DWARFContext::getDebugMacroDWO() {
1028 MacroDWO
= parseMacroOrMacinfo(MacroDwoSection
);
1029 return MacroDWO
.get();
1032 const DWARFDebugMacro
*DWARFContext::getDebugMacinfo() {
1034 Macinfo
= parseMacroOrMacinfo(MacinfoSection
);
1035 return Macinfo
.get();
1038 const DWARFDebugMacro
*DWARFContext::getDebugMacinfoDWO() {
1040 MacinfoDWO
= parseMacroOrMacinfo(MacinfoDwoSection
);
1041 return MacinfoDWO
.get();
1044 template <typename T
>
1045 static T
&getAccelTable(std::unique_ptr
<T
> &Cache
, const DWARFObject
&Obj
,
1046 const DWARFSection
&Section
, StringRef StringSection
,
1047 bool IsLittleEndian
) {
1050 DWARFDataExtractor
AccelSection(Obj
, Section
, IsLittleEndian
, 0);
1051 DataExtractor
StrData(StringSection
, IsLittleEndian
, 0);
1052 Cache
.reset(new T(AccelSection
, StrData
));
1053 if (Error E
= Cache
->extract())
1054 llvm::consumeError(std::move(E
));
1058 const DWARFDebugNames
&DWARFContext::getDebugNames() {
1059 return getAccelTable(Names
, *DObj
, DObj
->getNamesSection(),
1060 DObj
->getStrSection(), isLittleEndian());
1063 const AppleAcceleratorTable
&DWARFContext::getAppleNames() {
1064 return getAccelTable(AppleNames
, *DObj
, DObj
->getAppleNamesSection(),
1065 DObj
->getStrSection(), isLittleEndian());
1068 const AppleAcceleratorTable
&DWARFContext::getAppleTypes() {
1069 return getAccelTable(AppleTypes
, *DObj
, DObj
->getAppleTypesSection(),
1070 DObj
->getStrSection(), isLittleEndian());
1073 const AppleAcceleratorTable
&DWARFContext::getAppleNamespaces() {
1074 return getAccelTable(AppleNamespaces
, *DObj
,
1075 DObj
->getAppleNamespacesSection(),
1076 DObj
->getStrSection(), isLittleEndian());
1079 const AppleAcceleratorTable
&DWARFContext::getAppleObjC() {
1080 return getAccelTable(AppleObjC
, *DObj
, DObj
->getAppleObjCSection(),
1081 DObj
->getStrSection(), isLittleEndian());
1084 const DWARFDebugLine::LineTable
*
1085 DWARFContext::getLineTableForUnit(DWARFUnit
*U
) {
1086 Expected
<const DWARFDebugLine::LineTable
*> ExpectedLineTable
=
1087 getLineTableForUnit(U
, WarningHandler
);
1088 if (!ExpectedLineTable
) {
1089 WarningHandler(ExpectedLineTable
.takeError());
1092 return *ExpectedLineTable
;
1095 Expected
<const DWARFDebugLine::LineTable
*> DWARFContext::getLineTableForUnit(
1096 DWARFUnit
*U
, function_ref
<void(Error
)> RecoverableErrorHandler
) {
1098 Line
.reset(new DWARFDebugLine
);
1100 auto UnitDIE
= U
->getUnitDIE();
1104 auto Offset
= toSectionOffset(UnitDIE
.find(DW_AT_stmt_list
));
1106 return nullptr; // No line table for this compile unit.
1108 uint64_t stmtOffset
= *Offset
+ U
->getLineTableOffset();
1109 // See if the line table is cached.
1110 if (const DWARFLineTable
*lt
= Line
->getLineTable(stmtOffset
))
1113 // Make sure the offset is good before we try to parse.
1114 if (stmtOffset
>= U
->getLineSection().Data
.size())
1117 // We have to parse it first.
1118 DWARFDataExtractor
lineData(*DObj
, U
->getLineSection(), isLittleEndian(),
1119 U
->getAddressByteSize());
1120 return Line
->getOrParseLineTable(lineData
, stmtOffset
, *this, U
,
1121 RecoverableErrorHandler
);
1124 void DWARFContext::clearLineTableForUnit(DWARFUnit
*U
) {
1128 auto UnitDIE
= U
->getUnitDIE();
1132 auto Offset
= toSectionOffset(UnitDIE
.find(DW_AT_stmt_list
));
1136 uint64_t stmtOffset
= *Offset
+ U
->getLineTableOffset();
1137 Line
->clearLineTable(stmtOffset
);
1140 void DWARFContext::parseNormalUnits() {
1141 if (!NormalUnits
.empty())
1143 DObj
->forEachInfoSections([&](const DWARFSection
&S
) {
1144 NormalUnits
.addUnitsForSection(*this, S
, DW_SECT_INFO
);
1146 NormalUnits
.finishedInfoUnits();
1147 DObj
->forEachTypesSections([&](const DWARFSection
&S
) {
1148 NormalUnits
.addUnitsForSection(*this, S
, DW_SECT_EXT_TYPES
);
1152 void DWARFContext::parseDWOUnits(bool Lazy
) {
1153 if (!DWOUnits
.empty())
1155 DObj
->forEachInfoDWOSections([&](const DWARFSection
&S
) {
1156 DWOUnits
.addUnitsForDWOSection(*this, S
, DW_SECT_INFO
, Lazy
);
1158 DWOUnits
.finishedInfoUnits();
1159 DObj
->forEachTypesDWOSections([&](const DWARFSection
&S
) {
1160 DWOUnits
.addUnitsForDWOSection(*this, S
, DW_SECT_EXT_TYPES
, Lazy
);
1164 DWARFCompileUnit
*DWARFContext::getCompileUnitForOffset(uint64_t Offset
) {
1166 return dyn_cast_or_null
<DWARFCompileUnit
>(
1167 NormalUnits
.getUnitForOffset(Offset
));
1170 DWARFCompileUnit
*DWARFContext::getCompileUnitForCodeAddress(uint64_t Address
) {
1171 uint64_t CUOffset
= getDebugAranges()->findAddress(Address
);
1172 return getCompileUnitForOffset(CUOffset
);
1175 DWARFCompileUnit
*DWARFContext::getCompileUnitForDataAddress(uint64_t Address
) {
1176 uint64_t CUOffset
= getDebugAranges()->findAddress(Address
);
1177 if (DWARFCompileUnit
*OffsetCU
= getCompileUnitForOffset(CUOffset
))
1180 // Global variables are often missed by the above search, for one of two
1182 // 1. .debug_aranges may not include global variables. On clang, it seems we
1183 // put the globals in the aranges, but this isn't true for gcc.
1184 // 2. Even if the global variable is in a .debug_arange, global variables
1185 // may not be captured in the [start, end) addresses described by the
1186 // parent compile unit.
1188 // So, we walk the CU's and their child DI's manually, looking for the
1189 // specific global variable.
1190 for (std::unique_ptr
<DWARFUnit
> &CU
: compile_units()) {
1191 if (DWARFDie Die
= CU
->getVariableForAddress(Address
)) {
1192 return static_cast<DWARFCompileUnit
*>(CU
.get());
1198 DWARFContext::DIEsForAddress
DWARFContext::getDIEsForAddress(uint64_t Address
) {
1199 DIEsForAddress Result
;
1201 DWARFCompileUnit
*CU
= getCompileUnitForCodeAddress(Address
);
1205 Result
.CompileUnit
= CU
;
1206 Result
.FunctionDIE
= CU
->getSubroutineForAddress(Address
);
1208 std::vector
<DWARFDie
> Worklist
;
1209 Worklist
.push_back(Result
.FunctionDIE
);
1210 while (!Worklist
.empty()) {
1211 DWARFDie DIE
= Worklist
.back();
1212 Worklist
.pop_back();
1217 if (DIE
.getTag() == DW_TAG_lexical_block
&&
1218 DIE
.addressRangeContainsAddress(Address
)) {
1219 Result
.BlockDIE
= DIE
;
1223 append_range(Worklist
, DIE
);
1229 /// TODO: change input parameter from "uint64_t Address"
1230 /// into "SectionedAddress Address"
1231 static bool getFunctionNameAndStartLineForAddress(
1232 DWARFCompileUnit
*CU
, uint64_t Address
, FunctionNameKind Kind
,
1233 DILineInfoSpecifier::FileLineInfoKind FileNameKind
,
1234 std::string
&FunctionName
, std::string
&StartFile
, uint32_t &StartLine
,
1235 std::optional
<uint64_t> &StartAddress
) {
1236 // The address may correspond to instruction in some inlined function,
1237 // so we have to build the chain of inlined functions and take the
1238 // name of the topmost function in it.
1239 SmallVector
<DWARFDie
, 4> InlinedChain
;
1240 CU
->getInlinedChainForAddress(Address
, InlinedChain
);
1241 if (InlinedChain
.empty())
1244 const DWARFDie
&DIE
= InlinedChain
[0];
1245 bool FoundResult
= false;
1246 const char *Name
= nullptr;
1247 if (Kind
!= FunctionNameKind::None
&& (Name
= DIE
.getSubroutineName(Kind
))) {
1248 FunctionName
= Name
;
1251 std::string DeclFile
= DIE
.getDeclFile(FileNameKind
);
1252 if (!DeclFile
.empty()) {
1253 StartFile
= DeclFile
;
1256 if (auto DeclLineResult
= DIE
.getDeclLine()) {
1257 StartLine
= DeclLineResult
;
1260 if (auto LowPcAddr
= toSectionedAddress(DIE
.find(DW_AT_low_pc
)))
1261 StartAddress
= LowPcAddr
->Address
;
1265 static std::optional
<int64_t>
1266 getExpressionFrameOffset(ArrayRef
<uint8_t> Expr
,
1267 std::optional
<unsigned> FrameBaseReg
) {
1268 if (!Expr
.empty() &&
1269 (Expr
[0] == DW_OP_fbreg
||
1270 (FrameBaseReg
&& Expr
[0] == DW_OP_breg0
+ *FrameBaseReg
))) {
1272 int64_t Offset
= decodeSLEB128(Expr
.data() + 1, &Count
, Expr
.end());
1273 // A single DW_OP_fbreg or DW_OP_breg.
1274 if (Expr
.size() == Count
+ 1)
1276 // Same + DW_OP_deref (Fortran arrays look like this).
1277 if (Expr
.size() == Count
+ 2 && Expr
[Count
+ 1] == DW_OP_deref
)
1279 // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value)
1281 return std::nullopt
;
1284 void DWARFContext::addLocalsForDie(DWARFCompileUnit
*CU
, DWARFDie Subprogram
,
1285 DWARFDie Die
, std::vector
<DILocal
> &Result
) {
1286 if (Die
.getTag() == DW_TAG_variable
||
1287 Die
.getTag() == DW_TAG_formal_parameter
) {
1289 if (const char *Name
= Subprogram
.getSubroutineName(DINameKind::ShortName
))
1290 Local
.FunctionName
= Name
;
1292 std::optional
<unsigned> FrameBaseReg
;
1293 if (auto FrameBase
= Subprogram
.find(DW_AT_frame_base
))
1294 if (std::optional
<ArrayRef
<uint8_t>> Expr
= FrameBase
->getAsBlock())
1295 if (!Expr
->empty() && (*Expr
)[0] >= DW_OP_reg0
&&
1296 (*Expr
)[0] <= DW_OP_reg31
) {
1297 FrameBaseReg
= (*Expr
)[0] - DW_OP_reg0
;
1300 if (Expected
<std::vector
<DWARFLocationExpression
>> Loc
=
1301 Die
.getLocations(DW_AT_location
)) {
1302 for (const auto &Entry
: *Loc
) {
1303 if (std::optional
<int64_t> FrameOffset
=
1304 getExpressionFrameOffset(Entry
.Expr
, FrameBaseReg
)) {
1305 Local
.FrameOffset
= *FrameOffset
;
1310 // FIXME: missing DW_AT_location is OK here, but other errors should be
1311 // reported to the user.
1312 consumeError(Loc
.takeError());
1315 if (auto TagOffsetAttr
= Die
.find(DW_AT_LLVM_tag_offset
))
1316 Local
.TagOffset
= TagOffsetAttr
->getAsUnsignedConstant();
1319 Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
1321 if (auto NameAttr
= Die
.find(DW_AT_name
))
1322 if (std::optional
<const char *> Name
= dwarf::toString(*NameAttr
))
1324 if (auto Type
= Die
.getAttributeValueAsReferencedDie(DW_AT_type
))
1325 Local
.Size
= Type
.getTypeSize(getCUAddrSize());
1326 if (auto DeclFileAttr
= Die
.find(DW_AT_decl_file
)) {
1327 if (const auto *LT
= CU
->getContext().getLineTableForUnit(CU
))
1328 LT
->getFileNameByIndex(
1329 *DeclFileAttr
->getAsUnsignedConstant(), CU
->getCompilationDir(),
1330 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
,
1333 if (auto DeclLineAttr
= Die
.find(DW_AT_decl_line
))
1334 Local
.DeclLine
= *DeclLineAttr
->getAsUnsignedConstant();
1336 Result
.push_back(Local
);
1340 if (Die
.getTag() == DW_TAG_inlined_subroutine
)
1342 Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
1343 Subprogram
= Origin
;
1345 for (auto Child
: Die
)
1346 addLocalsForDie(CU
, Subprogram
, Child
, Result
);
1349 std::vector
<DILocal
>
1350 DWARFContext::getLocalsForAddress(object::SectionedAddress Address
) {
1351 std::vector
<DILocal
> Result
;
1352 DWARFCompileUnit
*CU
= getCompileUnitForCodeAddress(Address
.Address
);
1356 DWARFDie Subprogram
= CU
->getSubroutineForAddress(Address
.Address
);
1357 if (Subprogram
.isValid())
1358 addLocalsForDie(CU
, Subprogram
, Subprogram
, Result
);
1362 DILineInfo
DWARFContext::getLineInfoForAddress(object::SectionedAddress Address
,
1363 DILineInfoSpecifier Spec
) {
1365 DWARFCompileUnit
*CU
= getCompileUnitForCodeAddress(Address
.Address
);
1369 getFunctionNameAndStartLineForAddress(
1370 CU
, Address
.Address
, Spec
.FNKind
, Spec
.FLIKind
, Result
.FunctionName
,
1371 Result
.StartFileName
, Result
.StartLine
, Result
.StartAddress
);
1372 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1373 if (const DWARFLineTable
*LineTable
= getLineTableForUnit(CU
)) {
1374 LineTable
->getFileLineInfoForAddress(
1375 {Address
.Address
, Address
.SectionIndex
}, CU
->getCompilationDir(),
1376 Spec
.FLIKind
, Result
);
1384 DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address
) {
1386 DWARFCompileUnit
*CU
= getCompileUnitForDataAddress(Address
.Address
);
1390 if (DWARFDie Die
= CU
->getVariableForAddress(Address
.Address
)) {
1391 Result
.FileName
= Die
.getDeclFile(FileLineInfoKind::AbsoluteFilePath
);
1392 Result
.Line
= Die
.getDeclLine();
1398 DILineInfoTable
DWARFContext::getLineInfoForAddressRange(
1399 object::SectionedAddress Address
, uint64_t Size
, DILineInfoSpecifier Spec
) {
1400 DILineInfoTable Lines
;
1401 DWARFCompileUnit
*CU
= getCompileUnitForCodeAddress(Address
.Address
);
1405 uint32_t StartLine
= 0;
1406 std::string StartFileName
;
1407 std::string
FunctionName(DILineInfo::BadString
);
1408 std::optional
<uint64_t> StartAddress
;
1409 getFunctionNameAndStartLineForAddress(CU
, Address
.Address
, Spec
.FNKind
,
1410 Spec
.FLIKind
, FunctionName
,
1411 StartFileName
, StartLine
, StartAddress
);
1413 // If the Specifier says we don't need FileLineInfo, just
1414 // return the top-most function at the starting address.
1415 if (Spec
.FLIKind
== FileLineInfoKind::None
) {
1417 Result
.FunctionName
= FunctionName
;
1418 Result
.StartFileName
= StartFileName
;
1419 Result
.StartLine
= StartLine
;
1420 Result
.StartAddress
= StartAddress
;
1421 Lines
.push_back(std::make_pair(Address
.Address
, Result
));
1425 const DWARFLineTable
*LineTable
= getLineTableForUnit(CU
);
1427 // Get the index of row we're looking for in the line table.
1428 std::vector
<uint32_t> RowVector
;
1429 if (!LineTable
->lookupAddressRange({Address
.Address
, Address
.SectionIndex
},
1434 for (uint32_t RowIndex
: RowVector
) {
1435 // Take file number and line/column from the row.
1436 const DWARFDebugLine::Row
&Row
= LineTable
->Rows
[RowIndex
];
1438 LineTable
->getFileNameByIndex(Row
.File
, CU
->getCompilationDir(),
1439 Spec
.FLIKind
, Result
.FileName
);
1440 Result
.FunctionName
= FunctionName
;
1441 Result
.Line
= Row
.Line
;
1442 Result
.Column
= Row
.Column
;
1443 Result
.StartFileName
= StartFileName
;
1444 Result
.StartLine
= StartLine
;
1445 Result
.StartAddress
= StartAddress
;
1446 Lines
.push_back(std::make_pair(Row
.Address
.Address
, Result
));
1453 DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address
,
1454 DILineInfoSpecifier Spec
) {
1455 DIInliningInfo InliningInfo
;
1457 DWARFCompileUnit
*CU
= getCompileUnitForCodeAddress(Address
.Address
);
1459 return InliningInfo
;
1461 const DWARFLineTable
*LineTable
= nullptr;
1462 SmallVector
<DWARFDie
, 4> InlinedChain
;
1463 CU
->getInlinedChainForAddress(Address
.Address
, InlinedChain
);
1464 if (InlinedChain
.size() == 0) {
1465 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
1466 // try to at least get file/line info from symbol table.
1467 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1469 LineTable
= getLineTableForUnit(CU
);
1470 if (LineTable
&& LineTable
->getFileLineInfoForAddress(
1471 {Address
.Address
, Address
.SectionIndex
},
1472 CU
->getCompilationDir(), Spec
.FLIKind
, Frame
))
1473 InliningInfo
.addFrame(Frame
);
1475 return InliningInfo
;
1478 uint32_t CallFile
= 0, CallLine
= 0, CallColumn
= 0, CallDiscriminator
= 0;
1479 for (uint32_t i
= 0, n
= InlinedChain
.size(); i
!= n
; i
++) {
1480 DWARFDie
&FunctionDIE
= InlinedChain
[i
];
1482 // Get function name if necessary.
1483 if (const char *Name
= FunctionDIE
.getSubroutineName(Spec
.FNKind
))
1484 Frame
.FunctionName
= Name
;
1485 if (auto DeclLineResult
= FunctionDIE
.getDeclLine())
1486 Frame
.StartLine
= DeclLineResult
;
1487 Frame
.StartFileName
= FunctionDIE
.getDeclFile(Spec
.FLIKind
);
1488 if (auto LowPcAddr
= toSectionedAddress(FunctionDIE
.find(DW_AT_low_pc
)))
1489 Frame
.StartAddress
= LowPcAddr
->Address
;
1490 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1492 // For the topmost frame, initialize the line table of this
1493 // compile unit and fetch file/line info from it.
1494 LineTable
= getLineTableForUnit(CU
);
1495 // For the topmost routine, get file/line info from line table.
1497 LineTable
->getFileLineInfoForAddress(
1498 {Address
.Address
, Address
.SectionIndex
}, CU
->getCompilationDir(),
1499 Spec
.FLIKind
, Frame
);
1501 // Otherwise, use call file, call line and call column from
1502 // previous DIE in inlined chain.
1504 LineTable
->getFileNameByIndex(CallFile
, CU
->getCompilationDir(),
1505 Spec
.FLIKind
, Frame
.FileName
);
1506 Frame
.Line
= CallLine
;
1507 Frame
.Column
= CallColumn
;
1508 Frame
.Discriminator
= CallDiscriminator
;
1510 // Get call file/line/column of a current DIE.
1512 FunctionDIE
.getCallerFrame(CallFile
, CallLine
, CallColumn
,
1516 InliningInfo
.addFrame(Frame
);
1518 return InliningInfo
;
1521 std::shared_ptr
<DWARFContext
>
1522 DWARFContext::getDWOContext(StringRef AbsolutePath
) {
1523 if (auto S
= DWP
.lock()) {
1524 DWARFContext
*Ctxt
= S
->Context
.get();
1525 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1528 std::weak_ptr
<DWOFile
> *Entry
= &DWOFiles
[AbsolutePath
];
1530 if (auto S
= Entry
->lock()) {
1531 DWARFContext
*Ctxt
= S
->Context
.get();
1532 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1535 Expected
<OwningBinary
<ObjectFile
>> Obj
= [&] {
1536 if (!CheckedForDWP
) {
1537 SmallString
<128> DWPName
;
1538 auto Obj
= object::ObjectFile::createObjectFile(
1539 this->DWPName
.empty()
1540 ? (DObj
->getFileName() + ".dwp").toStringRef(DWPName
)
1541 : StringRef(this->DWPName
));
1546 CheckedForDWP
= true;
1547 // TODO: Should this error be handled (maybe in a high verbosity mode)
1548 // before falling back to .dwo files?
1549 consumeError(Obj
.takeError());
1553 return object::ObjectFile::createObjectFile(AbsolutePath
);
1557 // TODO: Actually report errors helpfully.
1558 consumeError(Obj
.takeError());
1562 auto S
= std::make_shared
<DWOFile
>();
1563 S
->File
= std::move(Obj
.get());
1564 S
->Context
= DWARFContext::create(*S
->File
.getBinary(),
1565 ProcessDebugRelocations::Ignore
);
1567 auto *Ctxt
= S
->Context
.get();
1568 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1571 static Error
createError(const Twine
&Reason
, llvm::Error E
) {
1572 return make_error
<StringError
>(Reason
+ toString(std::move(E
)),
1573 inconvertibleErrorCode());
1576 /// SymInfo contains information about symbol: it's address
1577 /// and section index which is -1LL for absolute symbols.
1580 uint64_t SectionIndex
;
1583 /// Returns the address of symbol relocation used against and a section index.
1584 /// Used for futher relocations computation. Symbol's section load address is
1585 static Expected
<SymInfo
> getSymbolInfo(const object::ObjectFile
&Obj
,
1586 const RelocationRef
&Reloc
,
1587 const LoadedObjectInfo
*L
,
1588 std::map
<SymbolRef
, SymInfo
> &Cache
) {
1589 SymInfo Ret
= {0, (uint64_t)-1LL};
1590 object::section_iterator RSec
= Obj
.section_end();
1591 object::symbol_iterator Sym
= Reloc
.getSymbol();
1593 std::map
<SymbolRef
, SymInfo
>::iterator CacheIt
= Cache
.end();
1594 // First calculate the address of the symbol or section as it appears
1595 // in the object file
1596 if (Sym
!= Obj
.symbol_end()) {
1598 std::tie(CacheIt
, New
) = Cache
.insert({*Sym
, {0, 0}});
1600 return CacheIt
->second
;
1602 Expected
<uint64_t> SymAddrOrErr
= Sym
->getAddress();
1604 return createError("failed to compute symbol address: ",
1605 SymAddrOrErr
.takeError());
1607 // Also remember what section this symbol is in for later
1608 auto SectOrErr
= Sym
->getSection();
1610 return createError("failed to get symbol section: ",
1611 SectOrErr
.takeError());
1614 Ret
.Address
= *SymAddrOrErr
;
1615 } else if (auto *MObj
= dyn_cast
<MachOObjectFile
>(&Obj
)) {
1616 RSec
= MObj
->getRelocationSection(Reloc
.getRawDataRefImpl());
1617 Ret
.Address
= RSec
->getAddress();
1620 if (RSec
!= Obj
.section_end())
1621 Ret
.SectionIndex
= RSec
->getIndex();
1623 // If we are given load addresses for the sections, we need to adjust:
1624 // SymAddr = (Address of Symbol Or Section in File) -
1625 // (Address of Section in File) +
1626 // (Load Address of Section)
1627 // RSec is now either the section being targeted or the section
1628 // containing the symbol being targeted. In either case,
1629 // we need to perform the same computation.
1630 if (L
&& RSec
!= Obj
.section_end())
1631 if (uint64_t SectionLoadAddress
= L
->getSectionLoadAddress(*RSec
))
1632 Ret
.Address
+= SectionLoadAddress
- RSec
->getAddress();
1634 if (CacheIt
!= Cache
.end())
1635 CacheIt
->second
= Ret
;
1640 static bool isRelocScattered(const object::ObjectFile
&Obj
,
1641 const RelocationRef
&Reloc
) {
1642 const MachOObjectFile
*MachObj
= dyn_cast
<MachOObjectFile
>(&Obj
);
1645 // MachO also has relocations that point to sections and
1646 // scattered relocations.
1647 auto RelocInfo
= MachObj
->getRelocation(Reloc
.getRawDataRefImpl());
1648 return MachObj
->isRelocationScattered(RelocInfo
);
1652 struct DWARFSectionMap final
: public DWARFSection
{
1653 RelocAddrMap Relocs
;
1656 class DWARFObjInMemory final
: public DWARFObject
{
1657 bool IsLittleEndian
;
1658 uint8_t AddressSize
;
1660 const object::ObjectFile
*Obj
= nullptr;
1661 std::vector
<SectionName
> SectionNames
;
1663 using InfoSectionMap
= MapVector
<object::SectionRef
, DWARFSectionMap
,
1664 std::map
<object::SectionRef
, unsigned>>;
1666 InfoSectionMap InfoSections
;
1667 InfoSectionMap TypesSections
;
1668 InfoSectionMap InfoDWOSections
;
1669 InfoSectionMap TypesDWOSections
;
1671 DWARFSectionMap LocSection
;
1672 DWARFSectionMap LoclistsSection
;
1673 DWARFSectionMap LoclistsDWOSection
;
1674 DWARFSectionMap LineSection
;
1675 DWARFSectionMap RangesSection
;
1676 DWARFSectionMap RnglistsSection
;
1677 DWARFSectionMap StrOffsetsSection
;
1678 DWARFSectionMap LineDWOSection
;
1679 DWARFSectionMap FrameSection
;
1680 DWARFSectionMap EHFrameSection
;
1681 DWARFSectionMap LocDWOSection
;
1682 DWARFSectionMap StrOffsetsDWOSection
;
1683 DWARFSectionMap RangesDWOSection
;
1684 DWARFSectionMap RnglistsDWOSection
;
1685 DWARFSectionMap AddrSection
;
1686 DWARFSectionMap AppleNamesSection
;
1687 DWARFSectionMap AppleTypesSection
;
1688 DWARFSectionMap AppleNamespacesSection
;
1689 DWARFSectionMap AppleObjCSection
;
1690 DWARFSectionMap NamesSection
;
1691 DWARFSectionMap PubnamesSection
;
1692 DWARFSectionMap PubtypesSection
;
1693 DWARFSectionMap GnuPubnamesSection
;
1694 DWARFSectionMap GnuPubtypesSection
;
1695 DWARFSectionMap MacroSection
;
1697 DWARFSectionMap
*mapNameToDWARFSection(StringRef Name
) {
1698 return StringSwitch
<DWARFSectionMap
*>(Name
)
1699 .Case("debug_loc", &LocSection
)
1700 .Case("debug_loclists", &LoclistsSection
)
1701 .Case("debug_loclists.dwo", &LoclistsDWOSection
)
1702 .Case("debug_line", &LineSection
)
1703 .Case("debug_frame", &FrameSection
)
1704 .Case("eh_frame", &EHFrameSection
)
1705 .Case("debug_str_offsets", &StrOffsetsSection
)
1706 .Case("debug_ranges", &RangesSection
)
1707 .Case("debug_rnglists", &RnglistsSection
)
1708 .Case("debug_loc.dwo", &LocDWOSection
)
1709 .Case("debug_line.dwo", &LineDWOSection
)
1710 .Case("debug_names", &NamesSection
)
1711 .Case("debug_rnglists.dwo", &RnglistsDWOSection
)
1712 .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection
)
1713 .Case("debug_addr", &AddrSection
)
1714 .Case("apple_names", &AppleNamesSection
)
1715 .Case("debug_pubnames", &PubnamesSection
)
1716 .Case("debug_pubtypes", &PubtypesSection
)
1717 .Case("debug_gnu_pubnames", &GnuPubnamesSection
)
1718 .Case("debug_gnu_pubtypes", &GnuPubtypesSection
)
1719 .Case("apple_types", &AppleTypesSection
)
1720 .Case("apple_namespaces", &AppleNamespacesSection
)
1721 .Case("apple_namespac", &AppleNamespacesSection
)
1722 .Case("apple_objc", &AppleObjCSection
)
1723 .Case("debug_macro", &MacroSection
)
1727 StringRef AbbrevSection
;
1728 StringRef ArangesSection
;
1729 StringRef StrSection
;
1730 StringRef MacinfoSection
;
1731 StringRef MacinfoDWOSection
;
1732 StringRef MacroDWOSection
;
1733 StringRef AbbrevDWOSection
;
1734 StringRef StrDWOSection
;
1735 StringRef CUIndexSection
;
1736 StringRef GdbIndexSection
;
1737 StringRef TUIndexSection
;
1738 StringRef LineStrSection
;
1740 // A deque holding section data whose iterators are not invalidated when
1741 // new decompressed sections are inserted at the end.
1742 std::deque
<SmallString
<0>> UncompressedSections
;
1744 StringRef
*mapSectionToMember(StringRef Name
) {
1745 if (DWARFSection
*Sec
= mapNameToDWARFSection(Name
))
1747 return StringSwitch
<StringRef
*>(Name
)
1748 .Case("debug_abbrev", &AbbrevSection
)
1749 .Case("debug_aranges", &ArangesSection
)
1750 .Case("debug_str", &StrSection
)
1751 .Case("debug_macinfo", &MacinfoSection
)
1752 .Case("debug_macinfo.dwo", &MacinfoDWOSection
)
1753 .Case("debug_macro.dwo", &MacroDWOSection
)
1754 .Case("debug_abbrev.dwo", &AbbrevDWOSection
)
1755 .Case("debug_str.dwo", &StrDWOSection
)
1756 .Case("debug_cu_index", &CUIndexSection
)
1757 .Case("debug_tu_index", &TUIndexSection
)
1758 .Case("gdb_index", &GdbIndexSection
)
1759 .Case("debug_line_str", &LineStrSection
)
1760 // Any more debug info sections go here.
1764 /// If Sec is compressed section, decompresses and updates its contents
1765 /// provided by Data. Otherwise leaves it unchanged.
1766 Error
maybeDecompress(const object::SectionRef
&Sec
, StringRef Name
,
1768 if (!Sec
.isCompressed())
1769 return Error::success();
1771 Expected
<Decompressor
> Decompressor
=
1772 Decompressor::create(Name
, Data
, IsLittleEndian
, AddressSize
== 8);
1774 return Decompressor
.takeError();
1777 if (auto Err
= Decompressor
->resizeAndDecompress(Out
))
1780 UncompressedSections
.push_back(std::move(Out
));
1781 Data
= UncompressedSections
.back();
1783 return Error::success();
1787 DWARFObjInMemory(const StringMap
<std::unique_ptr
<MemoryBuffer
>> &Sections
,
1788 uint8_t AddrSize
, bool IsLittleEndian
)
1789 : IsLittleEndian(IsLittleEndian
) {
1790 for (const auto &SecIt
: Sections
) {
1791 if (StringRef
*SectionData
= mapSectionToMember(SecIt
.first()))
1792 *SectionData
= SecIt
.second
->getBuffer();
1793 else if (SecIt
.first() == "debug_info")
1794 // Find debug_info and debug_types data by section rather than name as
1795 // there are multiple, comdat grouped, of these sections.
1796 InfoSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1797 else if (SecIt
.first() == "debug_info.dwo")
1798 InfoDWOSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1799 else if (SecIt
.first() == "debug_types")
1800 TypesSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1801 else if (SecIt
.first() == "debug_types.dwo")
1802 TypesDWOSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1805 DWARFObjInMemory(const object::ObjectFile
&Obj
, const LoadedObjectInfo
*L
,
1806 function_ref
<void(Error
)> HandleError
,
1807 function_ref
<void(Error
)> HandleWarning
,
1808 DWARFContext::ProcessDebugRelocations RelocAction
)
1809 : IsLittleEndian(Obj
.isLittleEndian()),
1810 AddressSize(Obj
.getBytesInAddress()), FileName(Obj
.getFileName()),
1813 StringMap
<unsigned> SectionAmountMap
;
1814 for (const SectionRef
&Section
: Obj
.sections()) {
1816 if (auto NameOrErr
= Section
.getName())
1819 consumeError(NameOrErr
.takeError());
1821 ++SectionAmountMap
[Name
];
1822 SectionNames
.push_back({ Name
, true });
1824 // Skip BSS and Virtual sections, they aren't interesting.
1825 if (Section
.isBSS() || Section
.isVirtual())
1828 // Skip sections stripped by dsymutil.
1829 if (Section
.isStripped())
1833 Expected
<section_iterator
> SecOrErr
= Section
.getRelocatedSection();
1835 HandleError(createError("failed to get relocated section: ",
1836 SecOrErr
.takeError()));
1840 // Try to obtain an already relocated version of this section.
1841 // Else use the unrelocated section from the object file. We'll have to
1842 // apply relocations ourselves later.
1843 section_iterator RelocatedSection
=
1844 Obj
.isRelocatableObject() ? *SecOrErr
: Obj
.section_end();
1845 if (!L
|| !L
->getLoadedSectionContents(*RelocatedSection
, Data
)) {
1846 Expected
<StringRef
> E
= Section
.getContents();
1850 // maybeDecompress below will error.
1851 consumeError(E
.takeError());
1854 if (auto Err
= maybeDecompress(Section
, Name
, Data
)) {
1855 HandleError(createError("failed to decompress '" + Name
+ "', ",
1860 // Compressed sections names in GNU style starts from ".z",
1861 // at this point section is decompressed and we drop compression prefix.
1863 Name
.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1865 // Map platform specific debug section names to DWARF standard section
1867 Name
= Obj
.mapDebugSectionName(Name
);
1869 if (StringRef
*SectionData
= mapSectionToMember(Name
)) {
1870 *SectionData
= Data
;
1871 if (Name
== "debug_ranges") {
1872 // FIXME: Use the other dwo range section when we emit it.
1873 RangesDWOSection
.Data
= Data
;
1874 } else if (Name
== "debug_frame" || Name
== "eh_frame") {
1875 if (DWARFSection
*S
= mapNameToDWARFSection(Name
))
1876 S
->Address
= Section
.getAddress();
1878 } else if (InfoSectionMap
*Sections
=
1879 StringSwitch
<InfoSectionMap
*>(Name
)
1880 .Case("debug_info", &InfoSections
)
1881 .Case("debug_info.dwo", &InfoDWOSections
)
1882 .Case("debug_types", &TypesSections
)
1883 .Case("debug_types.dwo", &TypesDWOSections
)
1884 .Default(nullptr)) {
1885 // Find debug_info and debug_types data by section rather than name as
1886 // there are multiple, comdat grouped, of these sections.
1887 DWARFSectionMap
&S
= (*Sections
)[Section
];
1891 if (RelocatedSection
!= Obj
.section_end() && Name
.contains(".dwo"))
1893 createError("Unexpected relocations for dwo section " + Name
));
1895 if (RelocatedSection
== Obj
.section_end() ||
1896 (RelocAction
== DWARFContext::ProcessDebugRelocations::Ignore
))
1899 StringRef RelSecName
;
1900 if (auto NameOrErr
= RelocatedSection
->getName())
1901 RelSecName
= *NameOrErr
;
1903 consumeError(NameOrErr
.takeError());
1905 // If the section we're relocating was relocated already by the JIT,
1906 // then we used the relocated version above, so we do not need to process
1907 // relocations for it now.
1908 StringRef RelSecData
;
1909 if (L
&& L
->getLoadedSectionContents(*RelocatedSection
, RelSecData
))
1912 // In Mach-o files, the relocations do not need to be applied if
1913 // there is no load offset to apply. The value read at the
1914 // relocation point already factors in the section address
1915 // (actually applying the relocations will produce wrong results
1916 // as the section address will be added twice).
1917 if (!L
&& isa
<MachOObjectFile
>(&Obj
))
1920 RelSecName
= RelSecName
.substr(
1921 RelSecName
.find_first_not_of("._z")); // Skip . and _ prefixes.
1923 // TODO: Add support for relocations in other sections as needed.
1924 // Record relocations for the debug_info and debug_line sections.
1925 DWARFSectionMap
*Sec
= mapNameToDWARFSection(RelSecName
);
1926 RelocAddrMap
*Map
= Sec
? &Sec
->Relocs
: nullptr;
1928 // Find debug_info and debug_types relocs by section rather than name
1929 // as there are multiple, comdat grouped, of these sections.
1930 if (RelSecName
== "debug_info")
1931 Map
= &static_cast<DWARFSectionMap
&>(InfoSections
[*RelocatedSection
])
1933 else if (RelSecName
== "debug_types")
1935 &static_cast<DWARFSectionMap
&>(TypesSections
[*RelocatedSection
])
1941 if (Section
.relocation_begin() == Section
.relocation_end())
1944 // Symbol to [address, section index] cache mapping.
1945 std::map
<SymbolRef
, SymInfo
> AddrCache
;
1946 SupportsRelocation Supports
;
1947 RelocationResolver Resolver
;
1948 std::tie(Supports
, Resolver
) = getRelocationResolver(Obj
);
1949 for (const RelocationRef
&Reloc
: Section
.relocations()) {
1950 // FIXME: it's not clear how to correctly handle scattered
1952 if (isRelocScattered(Obj
, Reloc
))
1955 Expected
<SymInfo
> SymInfoOrErr
=
1956 getSymbolInfo(Obj
, Reloc
, L
, AddrCache
);
1957 if (!SymInfoOrErr
) {
1958 HandleError(SymInfoOrErr
.takeError());
1962 // Check if Resolver can handle this relocation type early so as not to
1963 // handle invalid cases in DWARFDataExtractor.
1965 // TODO Don't store Resolver in every RelocAddrEntry.
1966 if (Supports
&& Supports(Reloc
.getType())) {
1967 auto I
= Map
->try_emplace(
1970 SymInfoOrErr
->SectionIndex
, Reloc
, SymInfoOrErr
->Address
,
1971 std::optional
<object::RelocationRef
>(), 0, Resolver
});
1972 // If we didn't successfully insert that's because we already had a
1973 // relocation for that offset. Store it as a second relocation in the
1974 // same RelocAddrEntry instead.
1976 RelocAddrEntry
&entry
= I
.first
->getSecond();
1978 HandleError(createError(
1979 "At most two relocations per offset are supported"));
1981 entry
.Reloc2
= Reloc
;
1982 entry
.SymbolValue2
= SymInfoOrErr
->Address
;
1985 SmallString
<32> Type
;
1986 Reloc
.getTypeName(Type
);
1987 // FIXME: Support more relocations & change this to an error
1989 createError("failed to compute relocation: " + Type
+ ", ",
1990 errorCodeToError(object_error::parse_failed
)));
1995 for (SectionName
&S
: SectionNames
)
1996 if (SectionAmountMap
[S
.Name
] > 1)
1997 S
.IsNameUnique
= false;
2000 std::optional
<RelocAddrEntry
> find(const DWARFSection
&S
,
2001 uint64_t Pos
) const override
{
2002 auto &Sec
= static_cast<const DWARFSectionMap
&>(S
);
2003 RelocAddrMap::const_iterator AI
= Sec
.Relocs
.find(Pos
);
2004 if (AI
== Sec
.Relocs
.end())
2005 return std::nullopt
;
2009 const object::ObjectFile
*getFile() const override
{ return Obj
; }
2011 ArrayRef
<SectionName
> getSectionNames() const override
{
2012 return SectionNames
;
2015 bool isLittleEndian() const override
{ return IsLittleEndian
; }
2016 StringRef
getAbbrevDWOSection() const override
{ return AbbrevDWOSection
; }
2017 const DWARFSection
&getLineDWOSection() const override
{
2018 return LineDWOSection
;
2020 const DWARFSection
&getLocDWOSection() const override
{
2021 return LocDWOSection
;
2023 StringRef
getStrDWOSection() const override
{ return StrDWOSection
; }
2024 const DWARFSection
&getStrOffsetsDWOSection() const override
{
2025 return StrOffsetsDWOSection
;
2027 const DWARFSection
&getRangesDWOSection() const override
{
2028 return RangesDWOSection
;
2030 const DWARFSection
&getRnglistsDWOSection() const override
{
2031 return RnglistsDWOSection
;
2033 const DWARFSection
&getLoclistsDWOSection() const override
{
2034 return LoclistsDWOSection
;
2036 const DWARFSection
&getAddrSection() const override
{ return AddrSection
; }
2037 StringRef
getCUIndexSection() const override
{ return CUIndexSection
; }
2038 StringRef
getGdbIndexSection() const override
{ return GdbIndexSection
; }
2039 StringRef
getTUIndexSection() const override
{ return TUIndexSection
; }
2042 const DWARFSection
&getStrOffsetsSection() const override
{
2043 return StrOffsetsSection
;
2045 StringRef
getLineStrSection() const override
{ return LineStrSection
; }
2047 // Sections for DWARF5 split dwarf proposal.
2048 void forEachInfoDWOSections(
2049 function_ref
<void(const DWARFSection
&)> F
) const override
{
2050 for (auto &P
: InfoDWOSections
)
2053 void forEachTypesDWOSections(
2054 function_ref
<void(const DWARFSection
&)> F
) const override
{
2055 for (auto &P
: TypesDWOSections
)
2059 StringRef
getAbbrevSection() const override
{ return AbbrevSection
; }
2060 const DWARFSection
&getLocSection() const override
{ return LocSection
; }
2061 const DWARFSection
&getLoclistsSection() const override
{ return LoclistsSection
; }
2062 StringRef
getArangesSection() const override
{ return ArangesSection
; }
2063 const DWARFSection
&getFrameSection() const override
{
2064 return FrameSection
;
2066 const DWARFSection
&getEHFrameSection() const override
{
2067 return EHFrameSection
;
2069 const DWARFSection
&getLineSection() const override
{ return LineSection
; }
2070 StringRef
getStrSection() const override
{ return StrSection
; }
2071 const DWARFSection
&getRangesSection() const override
{ return RangesSection
; }
2072 const DWARFSection
&getRnglistsSection() const override
{
2073 return RnglistsSection
;
2075 const DWARFSection
&getMacroSection() const override
{ return MacroSection
; }
2076 StringRef
getMacroDWOSection() const override
{ return MacroDWOSection
; }
2077 StringRef
getMacinfoSection() const override
{ return MacinfoSection
; }
2078 StringRef
getMacinfoDWOSection() const override
{ return MacinfoDWOSection
; }
2079 const DWARFSection
&getPubnamesSection() const override
{ return PubnamesSection
; }
2080 const DWARFSection
&getPubtypesSection() const override
{ return PubtypesSection
; }
2081 const DWARFSection
&getGnuPubnamesSection() const override
{
2082 return GnuPubnamesSection
;
2084 const DWARFSection
&getGnuPubtypesSection() const override
{
2085 return GnuPubtypesSection
;
2087 const DWARFSection
&getAppleNamesSection() const override
{
2088 return AppleNamesSection
;
2090 const DWARFSection
&getAppleTypesSection() const override
{
2091 return AppleTypesSection
;
2093 const DWARFSection
&getAppleNamespacesSection() const override
{
2094 return AppleNamespacesSection
;
2096 const DWARFSection
&getAppleObjCSection() const override
{
2097 return AppleObjCSection
;
2099 const DWARFSection
&getNamesSection() const override
{
2100 return NamesSection
;
2103 StringRef
getFileName() const override
{ return FileName
; }
2104 uint8_t getAddressSize() const override
{ return AddressSize
; }
2105 void forEachInfoSections(
2106 function_ref
<void(const DWARFSection
&)> F
) const override
{
2107 for (auto &P
: InfoSections
)
2110 void forEachTypesSections(
2111 function_ref
<void(const DWARFSection
&)> F
) const override
{
2112 for (auto &P
: TypesSections
)
2118 std::unique_ptr
<DWARFContext
>
2119 DWARFContext::create(const object::ObjectFile
&Obj
,
2120 ProcessDebugRelocations RelocAction
,
2121 const LoadedObjectInfo
*L
, std::string DWPName
,
2122 std::function
<void(Error
)> RecoverableErrorHandler
,
2123 std::function
<void(Error
)> WarningHandler
) {
2124 auto DObj
= std::make_unique
<DWARFObjInMemory
>(
2125 Obj
, L
, RecoverableErrorHandler
, WarningHandler
, RelocAction
);
2126 return std::make_unique
<DWARFContext
>(std::move(DObj
), std::move(DWPName
),
2127 RecoverableErrorHandler
,
2131 std::unique_ptr
<DWARFContext
>
2132 DWARFContext::create(const StringMap
<std::unique_ptr
<MemoryBuffer
>> &Sections
,
2133 uint8_t AddrSize
, bool isLittleEndian
,
2134 std::function
<void(Error
)> RecoverableErrorHandler
,
2135 std::function
<void(Error
)> WarningHandler
) {
2137 std::make_unique
<DWARFObjInMemory
>(Sections
, AddrSize
, isLittleEndian
);
2138 return std::make_unique
<DWARFContext
>(
2139 std::move(DObj
), "", RecoverableErrorHandler
, WarningHandler
);
2142 uint8_t DWARFContext::getCUAddrSize() {
2143 // In theory, different compile units may have different address byte
2144 // sizes, but for simplicity we just use the address byte size of the
2145 // first compile unit. In practice the address size field is repeated across
2146 // various DWARF headers (at least in version 5) to make it easier to dump
2147 // them independently, not to enable varying the address size.
2148 auto CUs
= compile_units();
2149 return CUs
.empty() ? 0 : (*CUs
.begin())->getAddressByteSize();