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/raw_ostream.h"
58 using namespace dwarf
;
59 using namespace object
;
61 #define DEBUG_TYPE "dwarf"
63 using DWARFLineTable
= DWARFDebugLine::LineTable
;
64 using FileLineInfoKind
= DILineInfoSpecifier::FileLineInfoKind
;
65 using FunctionNameKind
= DILineInfoSpecifier::FunctionNameKind
;
67 DWARFContext::DWARFContext(std::unique_ptr
<const DWARFObject
> DObj
,
69 std::function
<void(Error
)> RecoverableErrorHandler
,
70 std::function
<void(Error
)> WarningHandler
)
71 : DIContext(CK_DWARF
), DWPName(std::move(DWPName
)),
72 RecoverableErrorHandler(RecoverableErrorHandler
),
73 WarningHandler(WarningHandler
), DObj(std::move(DObj
)) {}
75 DWARFContext::~DWARFContext() = default;
77 /// Dump the UUID load command.
78 static void dumpUUID(raw_ostream
&OS
, const ObjectFile
&Obj
) {
79 auto *MachO
= dyn_cast
<MachOObjectFile
>(&Obj
);
82 for (auto LC
: MachO
->load_commands()) {
83 raw_ostream::uuid_t UUID
;
84 if (LC
.C
.cmd
== MachO::LC_UUID
) {
85 if (LC
.C
.cmdsize
< sizeof(UUID
) + sizeof(LC
.C
)) {
86 OS
<< "error: UUID load command is too short.\n";
90 memcpy(&UUID
, LC
.Ptr
+sizeof(LC
.C
), sizeof(UUID
));
92 Triple T
= MachO
->getArchTriple();
93 OS
<< " (" << T
.getArchName() << ')';
94 OS
<< ' ' << MachO
->getFileName() << '\n';
99 using ContributionCollection
=
100 std::vector
<Optional
<StrOffsetsContributionDescriptor
>>;
102 // Collect all the contributions to the string offsets table from all units,
103 // sort them by their starting offsets and remove duplicates.
104 static ContributionCollection
105 collectContributionData(DWARFContext::unit_iterator_range Units
) {
106 ContributionCollection Contributions
;
107 for (const auto &U
: Units
)
108 if (const auto &C
= U
->getStringOffsetsTableContribution())
109 Contributions
.push_back(C
);
110 // Sort the contributions so that any invalid ones are placed at
111 // the start of the contributions vector. This way they are reported
113 llvm::sort(Contributions
,
114 [](const Optional
<StrOffsetsContributionDescriptor
> &L
,
115 const Optional
<StrOffsetsContributionDescriptor
> &R
) {
117 return L
->Base
< R
->Base
;
121 // Uniquify contributions, as it is possible that units (specifically
122 // type units in dwo or dwp files) share contributions. We don't want
123 // to report them more than once.
125 std::unique(Contributions
.begin(), Contributions
.end(),
126 [](const Optional
<StrOffsetsContributionDescriptor
> &L
,
127 const Optional
<StrOffsetsContributionDescriptor
> &R
) {
129 return L
->Base
== R
->Base
&& L
->Size
== R
->Size
;
132 Contributions
.end());
133 return Contributions
;
136 // Dump a DWARF string offsets section. This may be a DWARF v5 formatted
137 // string offsets section, where each compile or type unit contributes a
138 // number of entries (string offsets), with each contribution preceded by
139 // a header containing size and version number. Alternatively, it may be a
140 // monolithic series of string offsets, as generated by the pre-DWARF v5
141 // implementation of split DWARF; however, in that case we still need to
142 // collect contributions of units because the size of the offsets (4 or 8
143 // bytes) depends on the format of the referencing unit (DWARF32 or DWARF64).
144 static void dumpStringOffsetsSection(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
145 StringRef SectionName
,
146 const DWARFObject
&Obj
,
147 const DWARFSection
&StringOffsetsSection
,
148 StringRef StringSection
,
149 DWARFContext::unit_iterator_range Units
,
151 auto Contributions
= collectContributionData(Units
);
152 DWARFDataExtractor
StrOffsetExt(Obj
, StringOffsetsSection
, LittleEndian
, 0);
153 DataExtractor
StrData(StringSection
, LittleEndian
, 0);
154 uint64_t SectionSize
= StringOffsetsSection
.Data
.size();
156 for (auto &Contribution
: Contributions
) {
157 // Report an ill-formed contribution.
159 OS
<< "error: invalid contribution to string offsets table in section ."
160 << SectionName
<< ".\n";
164 dwarf::DwarfFormat Format
= Contribution
->getFormat();
165 int OffsetDumpWidth
= 2 * dwarf::getDwarfOffsetByteSize(Format
);
166 uint16_t Version
= Contribution
->getVersion();
167 uint64_t ContributionHeader
= Contribution
->Base
;
168 // In DWARF v5 there is a contribution header that immediately precedes
169 // the string offsets base (the location we have previously retrieved from
170 // the CU DIE's DW_AT_str_offsets attribute). The header is located either
171 // 8 or 16 bytes before the base, depending on the contribution's format.
173 ContributionHeader
-= Format
== DWARF32
? 8 : 16;
175 // Detect overlapping contributions.
176 if (Offset
> ContributionHeader
) {
177 DumpOpts
.RecoverableErrorHandler(createStringError(
178 errc::invalid_argument
,
179 "overlapping contributions to string offsets table in section .%s.",
180 SectionName
.data()));
182 // Report a gap in the table.
183 if (Offset
< ContributionHeader
) {
184 OS
<< format("0x%8.8" PRIx64
": Gap, length = ", Offset
);
185 OS
<< (ContributionHeader
- Offset
) << "\n";
187 OS
<< format("0x%8.8" PRIx64
": ", ContributionHeader
);
188 // In DWARF v5 the contribution size in the descriptor does not equal
189 // the originally encoded length (it does not contain the length of the
190 // version field and the padding, a total of 4 bytes). Add them back in
192 OS
<< "Contribution size = " << (Contribution
->Size
+ (Version
< 5 ? 0 : 4))
193 << ", Format = " << dwarf::FormatString(Format
)
194 << ", Version = " << Version
<< "\n";
196 Offset
= Contribution
->Base
;
197 unsigned EntrySize
= Contribution
->getDwarfOffsetByteSize();
198 while (Offset
- Contribution
->Base
< Contribution
->Size
) {
199 OS
<< format("0x%8.8" PRIx64
": ", Offset
);
200 uint64_t StringOffset
=
201 StrOffsetExt
.getRelocatedValue(EntrySize
, &Offset
);
202 OS
<< format("%0*" PRIx64
" ", OffsetDumpWidth
, StringOffset
);
203 const char *S
= StrData
.getCStr(&StringOffset
);
205 OS
<< format("\"%s\"", S
);
209 // Report a gap at the end of the table.
210 if (Offset
< SectionSize
) {
211 OS
<< format("0x%8.8" PRIx64
": Gap, length = ", Offset
);
212 OS
<< (SectionSize
- Offset
) << "\n";
216 // Dump the .debug_addr section.
217 static void dumpAddrSection(raw_ostream
&OS
, DWARFDataExtractor
&AddrData
,
218 DIDumpOptions DumpOpts
, uint16_t Version
,
221 while (AddrData
.isValidOffset(Offset
)) {
222 DWARFDebugAddrTable AddrTable
;
223 uint64_t TableOffset
= Offset
;
224 if (Error Err
= AddrTable
.extract(AddrData
, &Offset
, Version
, AddrSize
,
225 DumpOpts
.WarningHandler
)) {
226 DumpOpts
.RecoverableErrorHandler(std::move(Err
));
227 // Keep going after an error, if we can, assuming that the length field
228 // could be read. If it couldn't, stop reading the section.
229 if (auto TableLength
= AddrTable
.getFullLength()) {
230 Offset
= TableOffset
+ *TableLength
;
235 AddrTable
.dump(OS
, DumpOpts
);
239 // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
240 static void dumpRnglistsSection(
241 raw_ostream
&OS
, DWARFDataExtractor
&rnglistData
,
242 llvm::function_ref
<Optional
<object::SectionedAddress
>(uint32_t)>
244 DIDumpOptions DumpOpts
) {
246 while (rnglistData
.isValidOffset(Offset
)) {
247 llvm::DWARFDebugRnglistTable Rnglists
;
248 uint64_t TableOffset
= Offset
;
249 if (Error Err
= Rnglists
.extract(rnglistData
, &Offset
)) {
250 DumpOpts
.RecoverableErrorHandler(std::move(Err
));
251 uint64_t Length
= Rnglists
.length();
252 // Keep going after an error, if we can, assuming that the length field
253 // could be read. If it couldn't, stop reading the section.
256 Offset
= TableOffset
+ Length
;
258 Rnglists
.dump(rnglistData
, OS
, LookupPooledAddress
, DumpOpts
);
263 std::unique_ptr
<DWARFDebugMacro
>
264 DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType
) {
265 auto Macro
= std::make_unique
<DWARFDebugMacro
>();
266 auto ParseAndDump
= [&](DWARFDataExtractor
&Data
, bool IsMacro
) {
267 if (Error Err
= IsMacro
? Macro
->parseMacro(SectionType
== MacroSection
269 : dwo_compile_units(),
270 SectionType
== MacroSection
271 ? getStringExtractor()
272 : getStringDWOExtractor(),
274 : Macro
->parseMacinfo(Data
)) {
275 RecoverableErrorHandler(std::move(Err
));
279 switch (SectionType
) {
280 case MacinfoSection
: {
281 DWARFDataExtractor
Data(DObj
->getMacinfoSection(), isLittleEndian(), 0);
282 ParseAndDump(Data
, /*IsMacro=*/false);
285 case MacinfoDwoSection
: {
286 DWARFDataExtractor
Data(DObj
->getMacinfoDWOSection(), isLittleEndian(), 0);
287 ParseAndDump(Data
, /*IsMacro=*/false);
291 DWARFDataExtractor
Data(*DObj
, DObj
->getMacroSection(), isLittleEndian(),
293 ParseAndDump(Data
, /*IsMacro=*/true);
296 case MacroDwoSection
: {
297 DWARFDataExtractor
Data(DObj
->getMacroDWOSection(), isLittleEndian(), 0);
298 ParseAndDump(Data
, /*IsMacro=*/true);
305 static void dumpLoclistsSection(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
306 DWARFDataExtractor Data
,
307 const MCRegisterInfo
*MRI
,
308 const DWARFObject
&Obj
,
309 Optional
<uint64_t> DumpOffset
) {
312 while (Data
.isValidOffset(Offset
)) {
313 DWARFListTableHeader
Header(".debug_loclists", "locations");
314 if (Error E
= Header
.extract(Data
, &Offset
)) {
315 DumpOpts
.RecoverableErrorHandler(std::move(E
));
319 Header
.dump(Data
, OS
, DumpOpts
);
321 uint64_t EndOffset
= Header
.length() + Header
.getHeaderOffset();
322 Data
.setAddressSize(Header
.getAddrSize());
323 DWARFDebugLoclists
Loc(Data
, Header
.getVersion());
325 if (DumpOffset
>= Offset
&& DumpOffset
< EndOffset
) {
326 Offset
= *DumpOffset
;
327 Loc
.dumpLocationList(&Offset
, OS
, /*BaseAddr=*/None
, MRI
, Obj
, nullptr,
328 DumpOpts
, /*Indent=*/0);
333 Loc
.dumpRange(Offset
, EndOffset
- Offset
, OS
, MRI
, Obj
, DumpOpts
);
339 static void dumpPubTableSection(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
340 DWARFDataExtractor Data
, bool GnuStyle
) {
341 DWARFDebugPubTable Table
;
342 Table
.extract(Data
, GnuStyle
, DumpOpts
.RecoverableErrorHandler
);
346 void DWARFContext::dump(
347 raw_ostream
&OS
, DIDumpOptions DumpOpts
,
348 std::array
<Optional
<uint64_t>, DIDT_ID_Count
> DumpOffsets
) {
349 uint64_t DumpType
= DumpOpts
.DumpType
;
351 StringRef Extension
= sys::path::extension(DObj
->getFileName());
352 bool IsDWO
= (Extension
== ".dwo") || (Extension
== ".dwp");
354 // Print UUID header.
355 const auto *ObjFile
= DObj
->getFile();
356 if (DumpType
& DIDT_UUID
)
357 dumpUUID(OS
, *ObjFile
);
359 // Print a header for each explicitly-requested section.
360 // Otherwise just print one for non-empty sections.
361 // Only print empty .dwo section headers when dumping a .dwo file.
362 bool Explicit
= DumpType
!= DIDT_All
&& !IsDWO
;
363 bool ExplicitDWO
= Explicit
&& IsDWO
;
364 auto shouldDump
= [&](bool Explicit
, const char *Name
, unsigned ID
,
365 StringRef Section
) -> Optional
<uint64_t> * {
366 unsigned Mask
= 1U << ID
;
367 bool Should
= (DumpType
& Mask
) && (Explicit
|| !Section
.empty());
370 OS
<< "\n" << Name
<< " contents:\n";
371 return &DumpOffsets
[ID
];
374 // Dump individual sections.
375 if (shouldDump(Explicit
, ".debug_abbrev", DIDT_ID_DebugAbbrev
,
376 DObj
->getAbbrevSection()))
377 getDebugAbbrev()->dump(OS
);
378 if (shouldDump(ExplicitDWO
, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev
,
379 DObj
->getAbbrevDWOSection()))
380 getDebugAbbrevDWO()->dump(OS
);
382 auto dumpDebugInfo
= [&](const char *Name
, unit_iterator_range Units
) {
383 OS
<< '\n' << Name
<< " contents:\n";
384 if (auto DumpOffset
= DumpOffsets
[DIDT_ID_DebugInfo
])
385 for (const auto &U
: Units
)
386 U
->getDIEForOffset(DumpOffset
.getValue())
387 .dump(OS
, 0, DumpOpts
.noImplicitRecursion());
389 for (const auto &U
: Units
)
390 U
->dump(OS
, DumpOpts
);
392 if ((DumpType
& DIDT_DebugInfo
)) {
393 if (Explicit
|| getNumCompileUnits())
394 dumpDebugInfo(".debug_info", info_section_units());
395 if (ExplicitDWO
|| getNumDWOCompileUnits())
396 dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
399 auto dumpDebugType
= [&](const char *Name
, unit_iterator_range Units
) {
400 OS
<< '\n' << Name
<< " contents:\n";
401 for (const auto &U
: Units
)
402 if (auto DumpOffset
= DumpOffsets
[DIDT_ID_DebugTypes
])
403 U
->getDIEForOffset(*DumpOffset
)
404 .dump(OS
, 0, DumpOpts
.noImplicitRecursion());
406 U
->dump(OS
, DumpOpts
);
408 if ((DumpType
& DIDT_DebugTypes
)) {
409 if (Explicit
|| getNumTypeUnits())
410 dumpDebugType(".debug_types", types_section_units());
411 if (ExplicitDWO
|| getNumDWOTypeUnits())
412 dumpDebugType(".debug_types.dwo", dwo_types_section_units());
415 DIDumpOptions LLDumpOpts
= DumpOpts
;
416 if (LLDumpOpts
.Verbose
)
417 LLDumpOpts
.DisplayRawContents
= true;
419 if (const auto *Off
= shouldDump(Explicit
, ".debug_loc", DIDT_ID_DebugLoc
,
420 DObj
->getLocSection().Data
)) {
421 getDebugLoc()->dump(OS
, getRegisterInfo(), *DObj
, LLDumpOpts
, *Off
);
423 if (const auto *Off
=
424 shouldDump(Explicit
, ".debug_loclists", DIDT_ID_DebugLoclists
,
425 DObj
->getLoclistsSection().Data
)) {
426 DWARFDataExtractor
Data(*DObj
, DObj
->getLoclistsSection(), isLittleEndian(),
428 dumpLoclistsSection(OS
, LLDumpOpts
, Data
, getRegisterInfo(), *DObj
, *Off
);
430 if (const auto *Off
=
431 shouldDump(ExplicitDWO
, ".debug_loclists.dwo", DIDT_ID_DebugLoclists
,
432 DObj
->getLoclistsDWOSection().Data
)) {
433 DWARFDataExtractor
Data(*DObj
, DObj
->getLoclistsDWOSection(),
434 isLittleEndian(), 0);
435 dumpLoclistsSection(OS
, LLDumpOpts
, Data
, getRegisterInfo(), *DObj
, *Off
);
438 if (const auto *Off
=
439 shouldDump(ExplicitDWO
, ".debug_loc.dwo", DIDT_ID_DebugLoc
,
440 DObj
->getLocDWOSection().Data
)) {
441 DWARFDataExtractor
Data(*DObj
, DObj
->getLocDWOSection(), isLittleEndian(),
443 DWARFDebugLoclists
Loc(Data
, /*Version=*/4);
445 uint64_t Offset
= **Off
;
446 Loc
.dumpLocationList(&Offset
, OS
,
447 /*BaseAddr=*/None
, getRegisterInfo(), *DObj
, nullptr,
448 LLDumpOpts
, /*Indent=*/0);
451 Loc
.dumpRange(0, Data
.getData().size(), OS
, getRegisterInfo(), *DObj
,
456 if (const Optional
<uint64_t> *Off
=
457 shouldDump(Explicit
, ".debug_frame", DIDT_ID_DebugFrame
,
458 DObj
->getFrameSection().Data
)) {
459 if (Expected
<const DWARFDebugFrame
*> DF
= getDebugFrame())
460 (*DF
)->dump(OS
, DumpOpts
, getRegisterInfo(), *Off
);
462 RecoverableErrorHandler(DF
.takeError());
465 if (const Optional
<uint64_t> *Off
=
466 shouldDump(Explicit
, ".eh_frame", DIDT_ID_DebugFrame
,
467 DObj
->getEHFrameSection().Data
)) {
468 if (Expected
<const DWARFDebugFrame
*> DF
= getEHFrame())
469 (*DF
)->dump(OS
, DumpOpts
, getRegisterInfo(), *Off
);
471 RecoverableErrorHandler(DF
.takeError());
474 if (shouldDump(Explicit
, ".debug_macro", DIDT_ID_DebugMacro
,
475 DObj
->getMacroSection().Data
)) {
476 if (auto Macro
= getDebugMacro())
480 if (shouldDump(Explicit
, ".debug_macro.dwo", DIDT_ID_DebugMacro
,
481 DObj
->getMacroDWOSection())) {
482 if (auto MacroDWO
= getDebugMacroDWO())
486 if (shouldDump(Explicit
, ".debug_macinfo", DIDT_ID_DebugMacro
,
487 DObj
->getMacinfoSection())) {
488 if (auto Macinfo
= getDebugMacinfo())
492 if (shouldDump(Explicit
, ".debug_macinfo.dwo", DIDT_ID_DebugMacro
,
493 DObj
->getMacinfoDWOSection())) {
494 if (auto MacinfoDWO
= getDebugMacinfoDWO())
495 MacinfoDWO
->dump(OS
);
498 if (shouldDump(Explicit
, ".debug_aranges", DIDT_ID_DebugAranges
,
499 DObj
->getArangesSection())) {
501 DWARFDataExtractor
arangesData(DObj
->getArangesSection(), isLittleEndian(),
503 DWARFDebugArangeSet set
;
504 while (arangesData
.isValidOffset(offset
)) {
506 set
.extract(arangesData
, &offset
, DumpOpts
.WarningHandler
)) {
507 RecoverableErrorHandler(std::move(E
));
514 auto DumpLineSection
= [&](DWARFDebugLine::SectionParser Parser
,
515 DIDumpOptions DumpOpts
,
516 Optional
<uint64_t> DumpOffset
) {
517 while (!Parser
.done()) {
518 if (DumpOffset
&& Parser
.getOffset() != *DumpOffset
) {
519 Parser
.skip(DumpOpts
.WarningHandler
, DumpOpts
.WarningHandler
);
522 OS
<< "debug_line[" << format("0x%8.8" PRIx64
, Parser
.getOffset())
524 Parser
.parseNext(DumpOpts
.WarningHandler
, DumpOpts
.WarningHandler
, &OS
,
529 auto DumpStrSection
= [&](StringRef Section
) {
530 DataExtractor
StrData(Section
, isLittleEndian(), 0);
532 uint64_t StrOffset
= 0;
533 while (StrData
.isValidOffset(Offset
)) {
534 Error Err
= Error::success();
535 const char *CStr
= StrData
.getCStr(&Offset
, &Err
);
537 DumpOpts
.WarningHandler(std::move(Err
));
540 OS
<< format("0x%8.8" PRIx64
": \"", StrOffset
);
541 OS
.write_escaped(CStr
);
547 if (const auto *Off
= shouldDump(Explicit
, ".debug_line", DIDT_ID_DebugLine
,
548 DObj
->getLineSection().Data
)) {
549 DWARFDataExtractor
LineData(*DObj
, DObj
->getLineSection(), isLittleEndian(),
551 DWARFDebugLine::SectionParser
Parser(LineData
, *this, normal_units());
552 DumpLineSection(Parser
, DumpOpts
, *Off
);
555 if (const auto *Off
=
556 shouldDump(ExplicitDWO
, ".debug_line.dwo", DIDT_ID_DebugLine
,
557 DObj
->getLineDWOSection().Data
)) {
558 DWARFDataExtractor
LineData(*DObj
, DObj
->getLineDWOSection(),
559 isLittleEndian(), 0);
560 DWARFDebugLine::SectionParser
Parser(LineData
, *this, dwo_units());
561 DumpLineSection(Parser
, DumpOpts
, *Off
);
564 if (shouldDump(Explicit
, ".debug_cu_index", DIDT_ID_DebugCUIndex
,
565 DObj
->getCUIndexSection())) {
566 getCUIndex().dump(OS
);
569 if (shouldDump(Explicit
, ".debug_tu_index", DIDT_ID_DebugTUIndex
,
570 DObj
->getTUIndexSection())) {
571 getTUIndex().dump(OS
);
574 if (shouldDump(Explicit
, ".debug_str", DIDT_ID_DebugStr
,
575 DObj
->getStrSection()))
576 DumpStrSection(DObj
->getStrSection());
578 if (shouldDump(ExplicitDWO
, ".debug_str.dwo", DIDT_ID_DebugStr
,
579 DObj
->getStrDWOSection()))
580 DumpStrSection(DObj
->getStrDWOSection());
582 if (shouldDump(Explicit
, ".debug_line_str", DIDT_ID_DebugLineStr
,
583 DObj
->getLineStrSection()))
584 DumpStrSection(DObj
->getLineStrSection());
586 if (shouldDump(Explicit
, ".debug_addr", DIDT_ID_DebugAddr
,
587 DObj
->getAddrSection().Data
)) {
588 DWARFDataExtractor
AddrData(*DObj
, DObj
->getAddrSection(),
589 isLittleEndian(), 0);
590 dumpAddrSection(OS
, AddrData
, DumpOpts
, getMaxVersion(), getCUAddrSize());
593 if (shouldDump(Explicit
, ".debug_ranges", DIDT_ID_DebugRanges
,
594 DObj
->getRangesSection().Data
)) {
595 uint8_t savedAddressByteSize
= getCUAddrSize();
596 DWARFDataExtractor
rangesData(*DObj
, DObj
->getRangesSection(),
597 isLittleEndian(), savedAddressByteSize
);
599 DWARFDebugRangeList rangeList
;
600 while (rangesData
.isValidOffset(offset
)) {
601 if (Error E
= rangeList
.extract(rangesData
, &offset
)) {
602 DumpOpts
.RecoverableErrorHandler(std::move(E
));
609 auto LookupPooledAddress
= [&](uint32_t Index
) -> Optional
<SectionedAddress
> {
610 const auto &CUs
= compile_units();
611 auto I
= CUs
.begin();
614 return (*I
)->getAddrOffsetSectionItem(Index
);
617 if (shouldDump(Explicit
, ".debug_rnglists", DIDT_ID_DebugRnglists
,
618 DObj
->getRnglistsSection().Data
)) {
619 DWARFDataExtractor
RnglistData(*DObj
, DObj
->getRnglistsSection(),
620 isLittleEndian(), 0);
621 dumpRnglistsSection(OS
, RnglistData
, LookupPooledAddress
, DumpOpts
);
624 if (shouldDump(ExplicitDWO
, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists
,
625 DObj
->getRnglistsDWOSection().Data
)) {
626 DWARFDataExtractor
RnglistData(*DObj
, DObj
->getRnglistsDWOSection(),
627 isLittleEndian(), 0);
628 dumpRnglistsSection(OS
, RnglistData
, LookupPooledAddress
, DumpOpts
);
631 if (shouldDump(Explicit
, ".debug_pubnames", DIDT_ID_DebugPubnames
,
632 DObj
->getPubnamesSection().Data
)) {
633 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getPubnamesSection(),
634 isLittleEndian(), 0);
635 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/false);
638 if (shouldDump(Explicit
, ".debug_pubtypes", DIDT_ID_DebugPubtypes
,
639 DObj
->getPubtypesSection().Data
)) {
640 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getPubtypesSection(),
641 isLittleEndian(), 0);
642 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/false);
645 if (shouldDump(Explicit
, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames
,
646 DObj
->getGnuPubnamesSection().Data
)) {
647 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getGnuPubnamesSection(),
648 isLittleEndian(), 0);
649 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/true);
652 if (shouldDump(Explicit
, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes
,
653 DObj
->getGnuPubtypesSection().Data
)) {
654 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getGnuPubtypesSection(),
655 isLittleEndian(), 0);
656 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/true);
659 if (shouldDump(Explicit
, ".debug_str_offsets", DIDT_ID_DebugStrOffsets
,
660 DObj
->getStrOffsetsSection().Data
))
661 dumpStringOffsetsSection(
662 OS
, DumpOpts
, "debug_str_offsets", *DObj
, DObj
->getStrOffsetsSection(),
663 DObj
->getStrSection(), normal_units(), isLittleEndian());
664 if (shouldDump(ExplicitDWO
, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets
,
665 DObj
->getStrOffsetsDWOSection().Data
))
666 dumpStringOffsetsSection(OS
, DumpOpts
, "debug_str_offsets.dwo", *DObj
,
667 DObj
->getStrOffsetsDWOSection(),
668 DObj
->getStrDWOSection(), dwo_units(),
671 if (shouldDump(Explicit
, ".gdb_index", DIDT_ID_GdbIndex
,
672 DObj
->getGdbIndexSection())) {
673 getGdbIndex().dump(OS
);
676 if (shouldDump(Explicit
, ".apple_names", DIDT_ID_AppleNames
,
677 DObj
->getAppleNamesSection().Data
))
678 getAppleNames().dump(OS
);
680 if (shouldDump(Explicit
, ".apple_types", DIDT_ID_AppleTypes
,
681 DObj
->getAppleTypesSection().Data
))
682 getAppleTypes().dump(OS
);
684 if (shouldDump(Explicit
, ".apple_namespaces", DIDT_ID_AppleNamespaces
,
685 DObj
->getAppleNamespacesSection().Data
))
686 getAppleNamespaces().dump(OS
);
688 if (shouldDump(Explicit
, ".apple_objc", DIDT_ID_AppleObjC
,
689 DObj
->getAppleObjCSection().Data
))
690 getAppleObjC().dump(OS
);
691 if (shouldDump(Explicit
, ".debug_names", DIDT_ID_DebugNames
,
692 DObj
->getNamesSection().Data
))
693 getDebugNames().dump(OS
);
696 DWARFCompileUnit
*DWARFContext::getDWOCompileUnitForHash(uint64_t Hash
) {
697 parseDWOUnits(LazyParse
);
699 if (const auto &CUI
= getCUIndex()) {
700 if (const auto *R
= CUI
.getFromHash(Hash
))
701 return dyn_cast_or_null
<DWARFCompileUnit
>(
702 DWOUnits
.getUnitForIndexEntry(*R
));
706 // If there's no index, just search through the CUs in the DWO - there's
707 // probably only one unless this is something like LTO - though an in-process
708 // built/cached lookup table could be used in that case to improve repeated
709 // lookups of different CUs in the DWO.
710 for (const auto &DWOCU
: dwo_compile_units()) {
711 // Might not have parsed DWO ID yet.
712 if (!DWOCU
->getDWOId()) {
713 if (Optional
<uint64_t> DWOId
=
714 toUnsigned(DWOCU
->getUnitDIE().find(DW_AT_GNU_dwo_id
)))
715 DWOCU
->setDWOId(*DWOId
);
720 if (DWOCU
->getDWOId() == Hash
)
721 return dyn_cast
<DWARFCompileUnit
>(DWOCU
.get());
726 DWARFDie
DWARFContext::getDIEForOffset(uint64_t Offset
) {
728 if (auto *CU
= NormalUnits
.getUnitForOffset(Offset
))
729 return CU
->getDIEForOffset(Offset
);
733 bool DWARFContext::verify(raw_ostream
&OS
, DIDumpOptions DumpOpts
) {
735 DWARFVerifier
verifier(OS
, *this, DumpOpts
);
737 Success
&= verifier
.handleDebugAbbrev();
738 if (DumpOpts
.DumpType
& DIDT_DebugInfo
)
739 Success
&= verifier
.handleDebugInfo();
740 if (DumpOpts
.DumpType
& DIDT_DebugLine
)
741 Success
&= verifier
.handleDebugLine();
742 Success
&= verifier
.handleAccelTables();
746 const DWARFUnitIndex
&DWARFContext::getCUIndex() {
750 DataExtractor
CUIndexData(DObj
->getCUIndexSection(), isLittleEndian(), 0);
752 CUIndex
= std::make_unique
<DWARFUnitIndex
>(DW_SECT_INFO
);
753 CUIndex
->parse(CUIndexData
);
757 const DWARFUnitIndex
&DWARFContext::getTUIndex() {
761 DataExtractor
TUIndexData(DObj
->getTUIndexSection(), isLittleEndian(), 0);
763 TUIndex
= std::make_unique
<DWARFUnitIndex
>(DW_SECT_EXT_TYPES
);
764 TUIndex
->parse(TUIndexData
);
768 DWARFGdbIndex
&DWARFContext::getGdbIndex() {
772 DataExtractor
GdbIndexData(DObj
->getGdbIndexSection(), true /*LE*/, 0);
773 GdbIndex
= std::make_unique
<DWARFGdbIndex
>();
774 GdbIndex
->parse(GdbIndexData
);
778 const DWARFDebugAbbrev
*DWARFContext::getDebugAbbrev() {
782 DataExtractor
abbrData(DObj
->getAbbrevSection(), isLittleEndian(), 0);
784 Abbrev
.reset(new DWARFDebugAbbrev());
785 Abbrev
->extract(abbrData
);
789 const DWARFDebugAbbrev
*DWARFContext::getDebugAbbrevDWO() {
791 return AbbrevDWO
.get();
793 DataExtractor
abbrData(DObj
->getAbbrevDWOSection(), isLittleEndian(), 0);
794 AbbrevDWO
.reset(new DWARFDebugAbbrev());
795 AbbrevDWO
->extract(abbrData
);
796 return AbbrevDWO
.get();
799 const DWARFDebugLoc
*DWARFContext::getDebugLoc() {
803 // Assume all units have the same address byte size.
806 ? DWARFDataExtractor(*DObj
, DObj
->getLocSection(), isLittleEndian(),
807 getUnitAtIndex(0)->getAddressByteSize())
808 : DWARFDataExtractor("", isLittleEndian(), 0);
809 Loc
.reset(new DWARFDebugLoc(std::move(LocData
)));
813 const DWARFDebugAranges
*DWARFContext::getDebugAranges() {
815 return Aranges
.get();
817 Aranges
.reset(new DWARFDebugAranges());
818 Aranges
->generate(this);
819 return Aranges
.get();
822 Expected
<const DWARFDebugFrame
*> DWARFContext::getDebugFrame() {
824 return DebugFrame
.get();
826 const DWARFSection
&DS
= DObj
->getFrameSection();
828 // There's a "bug" in the DWARFv3 standard with respect to the target address
829 // size within debug frame sections. While DWARF is supposed to be independent
830 // of its container, FDEs have fields with size being "target address size",
831 // which isn't specified in DWARF in general. It's only specified for CUs, but
832 // .eh_frame can appear without a .debug_info section. Follow the example of
833 // other tools (libdwarf) and extract this from the container (ObjectFile
834 // provides this information). This problem is fixed in DWARFv4
835 // See this dwarf-discuss discussion for more details:
836 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
837 DWARFDataExtractor
DebugFrameData(*DObj
, DS
, isLittleEndian(),
838 DObj
->getAddressSize());
840 std::make_unique
<DWARFDebugFrame
>(getArch(), /*IsEH=*/false, DS
.Address
);
841 if (Error E
= DF
->parse(DebugFrameData
))
845 return DebugFrame
.get();
848 Expected
<const DWARFDebugFrame
*> DWARFContext::getEHFrame() {
850 return EHFrame
.get();
852 const DWARFSection
&DS
= DObj
->getEHFrameSection();
853 DWARFDataExtractor
DebugFrameData(*DObj
, DS
, isLittleEndian(),
854 DObj
->getAddressSize());
857 std::make_unique
<DWARFDebugFrame
>(getArch(), /*IsEH=*/true, DS
.Address
);
858 if (Error E
= DF
->parse(DebugFrameData
))
861 return DebugFrame
.get();
864 const DWARFDebugMacro
*DWARFContext::getDebugMacro() {
866 Macro
= parseMacroOrMacinfo(MacroSection
);
870 const DWARFDebugMacro
*DWARFContext::getDebugMacroDWO() {
872 MacroDWO
= parseMacroOrMacinfo(MacroDwoSection
);
873 return MacroDWO
.get();
876 const DWARFDebugMacro
*DWARFContext::getDebugMacinfo() {
878 Macinfo
= parseMacroOrMacinfo(MacinfoSection
);
879 return Macinfo
.get();
882 const DWARFDebugMacro
*DWARFContext::getDebugMacinfoDWO() {
884 MacinfoDWO
= parseMacroOrMacinfo(MacinfoDwoSection
);
885 return MacinfoDWO
.get();
888 template <typename T
>
889 static T
&getAccelTable(std::unique_ptr
<T
> &Cache
, const DWARFObject
&Obj
,
890 const DWARFSection
&Section
, StringRef StringSection
,
891 bool IsLittleEndian
) {
894 DWARFDataExtractor
AccelSection(Obj
, Section
, IsLittleEndian
, 0);
895 DataExtractor
StrData(StringSection
, IsLittleEndian
, 0);
896 Cache
.reset(new T(AccelSection
, StrData
));
897 if (Error E
= Cache
->extract())
898 llvm::consumeError(std::move(E
));
902 const DWARFDebugNames
&DWARFContext::getDebugNames() {
903 return getAccelTable(Names
, *DObj
, DObj
->getNamesSection(),
904 DObj
->getStrSection(), isLittleEndian());
907 const AppleAcceleratorTable
&DWARFContext::getAppleNames() {
908 return getAccelTable(AppleNames
, *DObj
, DObj
->getAppleNamesSection(),
909 DObj
->getStrSection(), isLittleEndian());
912 const AppleAcceleratorTable
&DWARFContext::getAppleTypes() {
913 return getAccelTable(AppleTypes
, *DObj
, DObj
->getAppleTypesSection(),
914 DObj
->getStrSection(), isLittleEndian());
917 const AppleAcceleratorTable
&DWARFContext::getAppleNamespaces() {
918 return getAccelTable(AppleNamespaces
, *DObj
,
919 DObj
->getAppleNamespacesSection(),
920 DObj
->getStrSection(), isLittleEndian());
923 const AppleAcceleratorTable
&DWARFContext::getAppleObjC() {
924 return getAccelTable(AppleObjC
, *DObj
, DObj
->getAppleObjCSection(),
925 DObj
->getStrSection(), isLittleEndian());
928 const DWARFDebugLine::LineTable
*
929 DWARFContext::getLineTableForUnit(DWARFUnit
*U
) {
930 Expected
<const DWARFDebugLine::LineTable
*> ExpectedLineTable
=
931 getLineTableForUnit(U
, WarningHandler
);
932 if (!ExpectedLineTable
) {
933 WarningHandler(ExpectedLineTable
.takeError());
936 return *ExpectedLineTable
;
939 Expected
<const DWARFDebugLine::LineTable
*> DWARFContext::getLineTableForUnit(
940 DWARFUnit
*U
, function_ref
<void(Error
)> RecoverableErrorHandler
) {
942 Line
.reset(new DWARFDebugLine
);
944 auto UnitDIE
= U
->getUnitDIE();
948 auto Offset
= toSectionOffset(UnitDIE
.find(DW_AT_stmt_list
));
950 return nullptr; // No line table for this compile unit.
952 uint64_t stmtOffset
= *Offset
+ U
->getLineTableOffset();
953 // See if the line table is cached.
954 if (const DWARFLineTable
*lt
= Line
->getLineTable(stmtOffset
))
957 // Make sure the offset is good before we try to parse.
958 if (stmtOffset
>= U
->getLineSection().Data
.size())
961 // We have to parse it first.
962 DWARFDataExtractor
lineData(*DObj
, U
->getLineSection(), isLittleEndian(),
963 U
->getAddressByteSize());
964 return Line
->getOrParseLineTable(lineData
, stmtOffset
, *this, U
,
965 RecoverableErrorHandler
);
968 void DWARFContext::parseNormalUnits() {
969 if (!NormalUnits
.empty())
971 DObj
->forEachInfoSections([&](const DWARFSection
&S
) {
972 NormalUnits
.addUnitsForSection(*this, S
, DW_SECT_INFO
);
974 NormalUnits
.finishedInfoUnits();
975 DObj
->forEachTypesSections([&](const DWARFSection
&S
) {
976 NormalUnits
.addUnitsForSection(*this, S
, DW_SECT_EXT_TYPES
);
980 void DWARFContext::parseDWOUnits(bool Lazy
) {
981 if (!DWOUnits
.empty())
983 DObj
->forEachInfoDWOSections([&](const DWARFSection
&S
) {
984 DWOUnits
.addUnitsForDWOSection(*this, S
, DW_SECT_INFO
, Lazy
);
986 DWOUnits
.finishedInfoUnits();
987 DObj
->forEachTypesDWOSections([&](const DWARFSection
&S
) {
988 DWOUnits
.addUnitsForDWOSection(*this, S
, DW_SECT_EXT_TYPES
, Lazy
);
992 DWARFCompileUnit
*DWARFContext::getCompileUnitForOffset(uint64_t Offset
) {
994 return dyn_cast_or_null
<DWARFCompileUnit
>(
995 NormalUnits
.getUnitForOffset(Offset
));
998 DWARFCompileUnit
*DWARFContext::getCompileUnitForAddress(uint64_t Address
) {
999 // First, get the offset of the compile unit.
1000 uint64_t CUOffset
= getDebugAranges()->findAddress(Address
);
1001 // Retrieve the compile unit.
1002 return getCompileUnitForOffset(CUOffset
);
1005 DWARFContext::DIEsForAddress
DWARFContext::getDIEsForAddress(uint64_t Address
) {
1006 DIEsForAddress Result
;
1008 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
);
1012 Result
.CompileUnit
= CU
;
1013 Result
.FunctionDIE
= CU
->getSubroutineForAddress(Address
);
1015 std::vector
<DWARFDie
> Worklist
;
1016 Worklist
.push_back(Result
.FunctionDIE
);
1017 while (!Worklist
.empty()) {
1018 DWARFDie DIE
= Worklist
.back();
1019 Worklist
.pop_back();
1024 if (DIE
.getTag() == DW_TAG_lexical_block
&&
1025 DIE
.addressRangeContainsAddress(Address
)) {
1026 Result
.BlockDIE
= DIE
;
1030 append_range(Worklist
, DIE
);
1036 /// TODO: change input parameter from "uint64_t Address"
1037 /// into "SectionedAddress Address"
1038 static bool getFunctionNameAndStartLineForAddress(
1039 DWARFCompileUnit
*CU
, uint64_t Address
, FunctionNameKind Kind
,
1040 DILineInfoSpecifier::FileLineInfoKind FileNameKind
,
1041 std::string
&FunctionName
, std::string
&StartFile
, uint32_t &StartLine
,
1042 Optional
<uint64_t> &StartAddress
) {
1043 // The address may correspond to instruction in some inlined function,
1044 // so we have to build the chain of inlined functions and take the
1045 // name of the topmost function in it.
1046 SmallVector
<DWARFDie
, 4> InlinedChain
;
1047 CU
->getInlinedChainForAddress(Address
, InlinedChain
);
1048 if (InlinedChain
.empty())
1051 const DWARFDie
&DIE
= InlinedChain
[0];
1052 bool FoundResult
= false;
1053 const char *Name
= nullptr;
1054 if (Kind
!= FunctionNameKind::None
&& (Name
= DIE
.getSubroutineName(Kind
))) {
1055 FunctionName
= Name
;
1058 std::string DeclFile
= DIE
.getDeclFile(FileNameKind
);
1059 if (!DeclFile
.empty()) {
1060 StartFile
= DeclFile
;
1063 if (auto DeclLineResult
= DIE
.getDeclLine()) {
1064 StartLine
= DeclLineResult
;
1067 if (auto LowPcAddr
= toSectionedAddress(DIE
.find(DW_AT_low_pc
)))
1068 StartAddress
= LowPcAddr
->Address
;
1072 static Optional
<uint64_t> getTypeSize(DWARFDie Type
, uint64_t PointerSize
) {
1073 if (auto SizeAttr
= Type
.find(DW_AT_byte_size
))
1074 if (Optional
<uint64_t> Size
= SizeAttr
->getAsUnsignedConstant())
1077 switch (Type
.getTag()) {
1078 case DW_TAG_pointer_type
:
1079 case DW_TAG_reference_type
:
1080 case DW_TAG_rvalue_reference_type
:
1082 case DW_TAG_ptr_to_member_type
: {
1083 if (DWARFDie BaseType
= Type
.getAttributeValueAsReferencedDie(DW_AT_type
))
1084 if (BaseType
.getTag() == DW_TAG_subroutine_type
)
1085 return 2 * PointerSize
;
1088 case DW_TAG_const_type
:
1089 case DW_TAG_volatile_type
:
1090 case DW_TAG_restrict_type
:
1091 case DW_TAG_typedef
: {
1092 if (DWARFDie BaseType
= Type
.getAttributeValueAsReferencedDie(DW_AT_type
))
1093 return getTypeSize(BaseType
, PointerSize
);
1096 case DW_TAG_array_type
: {
1097 DWARFDie BaseType
= Type
.getAttributeValueAsReferencedDie(DW_AT_type
);
1099 return Optional
<uint64_t>();
1100 Optional
<uint64_t> BaseSize
= getTypeSize(BaseType
, PointerSize
);
1102 return Optional
<uint64_t>();
1103 uint64_t Size
= *BaseSize
;
1104 for (DWARFDie Child
: Type
) {
1105 if (Child
.getTag() != DW_TAG_subrange_type
)
1108 if (auto ElemCountAttr
= Child
.find(DW_AT_count
))
1109 if (Optional
<uint64_t> ElemCount
=
1110 ElemCountAttr
->getAsUnsignedConstant())
1112 if (auto UpperBoundAttr
= Child
.find(DW_AT_upper_bound
))
1113 if (Optional
<int64_t> UpperBound
=
1114 UpperBoundAttr
->getAsSignedConstant()) {
1115 int64_t LowerBound
= 0;
1116 if (auto LowerBoundAttr
= Child
.find(DW_AT_lower_bound
))
1117 LowerBound
= LowerBoundAttr
->getAsSignedConstant().getValueOr(0);
1118 Size
*= *UpperBound
- LowerBound
+ 1;
1126 return Optional
<uint64_t>();
1129 static Optional
<int64_t>
1130 getExpressionFrameOffset(ArrayRef
<uint8_t> Expr
,
1131 Optional
<unsigned> FrameBaseReg
) {
1132 if (!Expr
.empty() &&
1133 (Expr
[0] == DW_OP_fbreg
||
1134 (FrameBaseReg
&& Expr
[0] == DW_OP_breg0
+ *FrameBaseReg
))) {
1136 int64_t Offset
= decodeSLEB128(Expr
.data() + 1, &Count
, Expr
.end());
1137 // A single DW_OP_fbreg or DW_OP_breg.
1138 if (Expr
.size() == Count
+ 1)
1140 // Same + DW_OP_deref (Fortran arrays look like this).
1141 if (Expr
.size() == Count
+ 2 && Expr
[Count
+ 1] == DW_OP_deref
)
1143 // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value)
1148 void DWARFContext::addLocalsForDie(DWARFCompileUnit
*CU
, DWARFDie Subprogram
,
1149 DWARFDie Die
, std::vector
<DILocal
> &Result
) {
1150 if (Die
.getTag() == DW_TAG_variable
||
1151 Die
.getTag() == DW_TAG_formal_parameter
) {
1153 if (const char *Name
= Subprogram
.getSubroutineName(DINameKind::ShortName
))
1154 Local
.FunctionName
= Name
;
1156 Optional
<unsigned> FrameBaseReg
;
1157 if (auto FrameBase
= Subprogram
.find(DW_AT_frame_base
))
1158 if (Optional
<ArrayRef
<uint8_t>> Expr
= FrameBase
->getAsBlock())
1159 if (!Expr
->empty() && (*Expr
)[0] >= DW_OP_reg0
&&
1160 (*Expr
)[0] <= DW_OP_reg31
) {
1161 FrameBaseReg
= (*Expr
)[0] - DW_OP_reg0
;
1164 if (Expected
<std::vector
<DWARFLocationExpression
>> Loc
=
1165 Die
.getLocations(DW_AT_location
)) {
1166 for (const auto &Entry
: *Loc
) {
1167 if (Optional
<int64_t> FrameOffset
=
1168 getExpressionFrameOffset(Entry
.Expr
, FrameBaseReg
)) {
1169 Local
.FrameOffset
= *FrameOffset
;
1174 // FIXME: missing DW_AT_location is OK here, but other errors should be
1175 // reported to the user.
1176 consumeError(Loc
.takeError());
1179 if (auto TagOffsetAttr
= Die
.find(DW_AT_LLVM_tag_offset
))
1180 Local
.TagOffset
= TagOffsetAttr
->getAsUnsignedConstant();
1183 Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
1185 if (auto NameAttr
= Die
.find(DW_AT_name
))
1186 if (Optional
<const char *> Name
= NameAttr
->getAsCString())
1188 if (auto Type
= Die
.getAttributeValueAsReferencedDie(DW_AT_type
))
1189 Local
.Size
= getTypeSize(Type
, getCUAddrSize());
1190 if (auto DeclFileAttr
= Die
.find(DW_AT_decl_file
)) {
1191 if (const auto *LT
= CU
->getContext().getLineTableForUnit(CU
))
1192 LT
->getFileNameByIndex(
1193 DeclFileAttr
->getAsUnsignedConstant().getValue(),
1194 CU
->getCompilationDir(),
1195 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
,
1198 if (auto DeclLineAttr
= Die
.find(DW_AT_decl_line
))
1199 Local
.DeclLine
= DeclLineAttr
->getAsUnsignedConstant().getValue();
1201 Result
.push_back(Local
);
1205 if (Die
.getTag() == DW_TAG_inlined_subroutine
)
1207 Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
1208 Subprogram
= Origin
;
1210 for (auto Child
: Die
)
1211 addLocalsForDie(CU
, Subprogram
, Child
, Result
);
1214 std::vector
<DILocal
>
1215 DWARFContext::getLocalsForAddress(object::SectionedAddress Address
) {
1216 std::vector
<DILocal
> Result
;
1217 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1221 DWARFDie Subprogram
= CU
->getSubroutineForAddress(Address
.Address
);
1222 if (Subprogram
.isValid())
1223 addLocalsForDie(CU
, Subprogram
, Subprogram
, Result
);
1227 DILineInfo
DWARFContext::getLineInfoForAddress(object::SectionedAddress Address
,
1228 DILineInfoSpecifier Spec
) {
1231 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1235 getFunctionNameAndStartLineForAddress(
1236 CU
, Address
.Address
, Spec
.FNKind
, Spec
.FLIKind
, Result
.FunctionName
,
1237 Result
.StartFileName
, Result
.StartLine
, Result
.StartAddress
);
1238 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1239 if (const DWARFLineTable
*LineTable
= getLineTableForUnit(CU
)) {
1240 LineTable
->getFileLineInfoForAddress(
1241 {Address
.Address
, Address
.SectionIndex
}, CU
->getCompilationDir(),
1242 Spec
.FLIKind
, Result
);
1248 DILineInfoTable
DWARFContext::getLineInfoForAddressRange(
1249 object::SectionedAddress Address
, uint64_t Size
, DILineInfoSpecifier Spec
) {
1250 DILineInfoTable Lines
;
1251 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1255 uint32_t StartLine
= 0;
1256 std::string StartFileName
;
1257 std::string
FunctionName(DILineInfo::BadString
);
1258 Optional
<uint64_t> StartAddress
;
1259 getFunctionNameAndStartLineForAddress(CU
, Address
.Address
, Spec
.FNKind
,
1260 Spec
.FLIKind
, FunctionName
,
1261 StartFileName
, StartLine
, StartAddress
);
1263 // If the Specifier says we don't need FileLineInfo, just
1264 // return the top-most function at the starting address.
1265 if (Spec
.FLIKind
== FileLineInfoKind::None
) {
1267 Result
.FunctionName
= FunctionName
;
1268 Result
.StartFileName
= StartFileName
;
1269 Result
.StartLine
= StartLine
;
1270 Result
.StartAddress
= StartAddress
;
1271 Lines
.push_back(std::make_pair(Address
.Address
, Result
));
1275 const DWARFLineTable
*LineTable
= getLineTableForUnit(CU
);
1277 // Get the index of row we're looking for in the line table.
1278 std::vector
<uint32_t> RowVector
;
1279 if (!LineTable
->lookupAddressRange({Address
.Address
, Address
.SectionIndex
},
1284 for (uint32_t RowIndex
: RowVector
) {
1285 // Take file number and line/column from the row.
1286 const DWARFDebugLine::Row
&Row
= LineTable
->Rows
[RowIndex
];
1288 LineTable
->getFileNameByIndex(Row
.File
, CU
->getCompilationDir(),
1289 Spec
.FLIKind
, Result
.FileName
);
1290 Result
.FunctionName
= FunctionName
;
1291 Result
.Line
= Row
.Line
;
1292 Result
.Column
= Row
.Column
;
1293 Result
.StartFileName
= StartFileName
;
1294 Result
.StartLine
= StartLine
;
1295 Result
.StartAddress
= StartAddress
;
1296 Lines
.push_back(std::make_pair(Row
.Address
.Address
, Result
));
1303 DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address
,
1304 DILineInfoSpecifier Spec
) {
1305 DIInliningInfo InliningInfo
;
1307 DWARFCompileUnit
*CU
= getCompileUnitForAddress(Address
.Address
);
1309 return InliningInfo
;
1311 const DWARFLineTable
*LineTable
= nullptr;
1312 SmallVector
<DWARFDie
, 4> InlinedChain
;
1313 CU
->getInlinedChainForAddress(Address
.Address
, InlinedChain
);
1314 if (InlinedChain
.size() == 0) {
1315 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
1316 // try to at least get file/line info from symbol table.
1317 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1319 LineTable
= getLineTableForUnit(CU
);
1320 if (LineTable
&& LineTable
->getFileLineInfoForAddress(
1321 {Address
.Address
, Address
.SectionIndex
},
1322 CU
->getCompilationDir(), Spec
.FLIKind
, Frame
))
1323 InliningInfo
.addFrame(Frame
);
1325 return InliningInfo
;
1328 uint32_t CallFile
= 0, CallLine
= 0, CallColumn
= 0, CallDiscriminator
= 0;
1329 for (uint32_t i
= 0, n
= InlinedChain
.size(); i
!= n
; i
++) {
1330 DWARFDie
&FunctionDIE
= InlinedChain
[i
];
1332 // Get function name if necessary.
1333 if (const char *Name
= FunctionDIE
.getSubroutineName(Spec
.FNKind
))
1334 Frame
.FunctionName
= Name
;
1335 if (auto DeclLineResult
= FunctionDIE
.getDeclLine())
1336 Frame
.StartLine
= DeclLineResult
;
1337 Frame
.StartFileName
= FunctionDIE
.getDeclFile(Spec
.FLIKind
);
1338 if (auto LowPcAddr
= toSectionedAddress(FunctionDIE
.find(DW_AT_low_pc
)))
1339 Frame
.StartAddress
= LowPcAddr
->Address
;
1340 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1342 // For the topmost frame, initialize the line table of this
1343 // compile unit and fetch file/line info from it.
1344 LineTable
= getLineTableForUnit(CU
);
1345 // For the topmost routine, get file/line info from line table.
1347 LineTable
->getFileLineInfoForAddress(
1348 {Address
.Address
, Address
.SectionIndex
}, CU
->getCompilationDir(),
1349 Spec
.FLIKind
, Frame
);
1351 // Otherwise, use call file, call line and call column from
1352 // previous DIE in inlined chain.
1354 LineTable
->getFileNameByIndex(CallFile
, CU
->getCompilationDir(),
1355 Spec
.FLIKind
, Frame
.FileName
);
1356 Frame
.Line
= CallLine
;
1357 Frame
.Column
= CallColumn
;
1358 Frame
.Discriminator
= CallDiscriminator
;
1360 // Get call file/line/column of a current DIE.
1362 FunctionDIE
.getCallerFrame(CallFile
, CallLine
, CallColumn
,
1366 InliningInfo
.addFrame(Frame
);
1368 return InliningInfo
;
1371 std::shared_ptr
<DWARFContext
>
1372 DWARFContext::getDWOContext(StringRef AbsolutePath
) {
1373 if (auto S
= DWP
.lock()) {
1374 DWARFContext
*Ctxt
= S
->Context
.get();
1375 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1378 std::weak_ptr
<DWOFile
> *Entry
= &DWOFiles
[AbsolutePath
];
1380 if (auto S
= Entry
->lock()) {
1381 DWARFContext
*Ctxt
= S
->Context
.get();
1382 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1385 Expected
<OwningBinary
<ObjectFile
>> Obj
= [&] {
1386 if (!CheckedForDWP
) {
1387 SmallString
<128> DWPName
;
1388 auto Obj
= object::ObjectFile::createObjectFile(
1389 this->DWPName
.empty()
1390 ? (DObj
->getFileName() + ".dwp").toStringRef(DWPName
)
1391 : StringRef(this->DWPName
));
1396 CheckedForDWP
= true;
1397 // TODO: Should this error be handled (maybe in a high verbosity mode)
1398 // before falling back to .dwo files?
1399 consumeError(Obj
.takeError());
1403 return object::ObjectFile::createObjectFile(AbsolutePath
);
1407 // TODO: Actually report errors helpfully.
1408 consumeError(Obj
.takeError());
1412 auto S
= std::make_shared
<DWOFile
>();
1413 S
->File
= std::move(Obj
.get());
1414 S
->Context
= DWARFContext::create(*S
->File
.getBinary(),
1415 ProcessDebugRelocations::Ignore
);
1417 auto *Ctxt
= S
->Context
.get();
1418 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
1421 static Error
createError(const Twine
&Reason
, llvm::Error E
) {
1422 return make_error
<StringError
>(Reason
+ toString(std::move(E
)),
1423 inconvertibleErrorCode());
1426 /// SymInfo contains information about symbol: it's address
1427 /// and section index which is -1LL for absolute symbols.
1430 uint64_t SectionIndex
;
1433 /// Returns the address of symbol relocation used against and a section index.
1434 /// Used for futher relocations computation. Symbol's section load address is
1435 static Expected
<SymInfo
> getSymbolInfo(const object::ObjectFile
&Obj
,
1436 const RelocationRef
&Reloc
,
1437 const LoadedObjectInfo
*L
,
1438 std::map
<SymbolRef
, SymInfo
> &Cache
) {
1439 SymInfo Ret
= {0, (uint64_t)-1LL};
1440 object::section_iterator RSec
= Obj
.section_end();
1441 object::symbol_iterator Sym
= Reloc
.getSymbol();
1443 std::map
<SymbolRef
, SymInfo
>::iterator CacheIt
= Cache
.end();
1444 // First calculate the address of the symbol or section as it appears
1445 // in the object file
1446 if (Sym
!= Obj
.symbol_end()) {
1448 std::tie(CacheIt
, New
) = Cache
.insert({*Sym
, {0, 0}});
1450 return CacheIt
->second
;
1452 Expected
<uint64_t> SymAddrOrErr
= Sym
->getAddress();
1454 return createError("failed to compute symbol address: ",
1455 SymAddrOrErr
.takeError());
1457 // Also remember what section this symbol is in for later
1458 auto SectOrErr
= Sym
->getSection();
1460 return createError("failed to get symbol section: ",
1461 SectOrErr
.takeError());
1464 Ret
.Address
= *SymAddrOrErr
;
1465 } else if (auto *MObj
= dyn_cast
<MachOObjectFile
>(&Obj
)) {
1466 RSec
= MObj
->getRelocationSection(Reloc
.getRawDataRefImpl());
1467 Ret
.Address
= RSec
->getAddress();
1470 if (RSec
!= Obj
.section_end())
1471 Ret
.SectionIndex
= RSec
->getIndex();
1473 // If we are given load addresses for the sections, we need to adjust:
1474 // SymAddr = (Address of Symbol Or Section in File) -
1475 // (Address of Section in File) +
1476 // (Load Address of Section)
1477 // RSec is now either the section being targeted or the section
1478 // containing the symbol being targeted. In either case,
1479 // we need to perform the same computation.
1480 if (L
&& RSec
!= Obj
.section_end())
1481 if (uint64_t SectionLoadAddress
= L
->getSectionLoadAddress(*RSec
))
1482 Ret
.Address
+= SectionLoadAddress
- RSec
->getAddress();
1484 if (CacheIt
!= Cache
.end())
1485 CacheIt
->second
= Ret
;
1490 static bool isRelocScattered(const object::ObjectFile
&Obj
,
1491 const RelocationRef
&Reloc
) {
1492 const MachOObjectFile
*MachObj
= dyn_cast
<MachOObjectFile
>(&Obj
);
1495 // MachO also has relocations that point to sections and
1496 // scattered relocations.
1497 auto RelocInfo
= MachObj
->getRelocation(Reloc
.getRawDataRefImpl());
1498 return MachObj
->isRelocationScattered(RelocInfo
);
1502 struct DWARFSectionMap final
: public DWARFSection
{
1503 RelocAddrMap Relocs
;
1506 class DWARFObjInMemory final
: public DWARFObject
{
1507 bool IsLittleEndian
;
1508 uint8_t AddressSize
;
1510 const object::ObjectFile
*Obj
= nullptr;
1511 std::vector
<SectionName
> SectionNames
;
1513 using InfoSectionMap
= MapVector
<object::SectionRef
, DWARFSectionMap
,
1514 std::map
<object::SectionRef
, unsigned>>;
1516 InfoSectionMap InfoSections
;
1517 InfoSectionMap TypesSections
;
1518 InfoSectionMap InfoDWOSections
;
1519 InfoSectionMap TypesDWOSections
;
1521 DWARFSectionMap LocSection
;
1522 DWARFSectionMap LoclistsSection
;
1523 DWARFSectionMap LoclistsDWOSection
;
1524 DWARFSectionMap LineSection
;
1525 DWARFSectionMap RangesSection
;
1526 DWARFSectionMap RnglistsSection
;
1527 DWARFSectionMap StrOffsetsSection
;
1528 DWARFSectionMap LineDWOSection
;
1529 DWARFSectionMap FrameSection
;
1530 DWARFSectionMap EHFrameSection
;
1531 DWARFSectionMap LocDWOSection
;
1532 DWARFSectionMap StrOffsetsDWOSection
;
1533 DWARFSectionMap RangesDWOSection
;
1534 DWARFSectionMap RnglistsDWOSection
;
1535 DWARFSectionMap AddrSection
;
1536 DWARFSectionMap AppleNamesSection
;
1537 DWARFSectionMap AppleTypesSection
;
1538 DWARFSectionMap AppleNamespacesSection
;
1539 DWARFSectionMap AppleObjCSection
;
1540 DWARFSectionMap NamesSection
;
1541 DWARFSectionMap PubnamesSection
;
1542 DWARFSectionMap PubtypesSection
;
1543 DWARFSectionMap GnuPubnamesSection
;
1544 DWARFSectionMap GnuPubtypesSection
;
1545 DWARFSectionMap MacroSection
;
1547 DWARFSectionMap
*mapNameToDWARFSection(StringRef Name
) {
1548 return StringSwitch
<DWARFSectionMap
*>(Name
)
1549 .Case("debug_loc", &LocSection
)
1550 .Case("debug_loclists", &LoclistsSection
)
1551 .Case("debug_loclists.dwo", &LoclistsDWOSection
)
1552 .Case("debug_line", &LineSection
)
1553 .Case("debug_frame", &FrameSection
)
1554 .Case("eh_frame", &EHFrameSection
)
1555 .Case("debug_str_offsets", &StrOffsetsSection
)
1556 .Case("debug_ranges", &RangesSection
)
1557 .Case("debug_rnglists", &RnglistsSection
)
1558 .Case("debug_loc.dwo", &LocDWOSection
)
1559 .Case("debug_line.dwo", &LineDWOSection
)
1560 .Case("debug_names", &NamesSection
)
1561 .Case("debug_rnglists.dwo", &RnglistsDWOSection
)
1562 .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection
)
1563 .Case("debug_addr", &AddrSection
)
1564 .Case("apple_names", &AppleNamesSection
)
1565 .Case("debug_pubnames", &PubnamesSection
)
1566 .Case("debug_pubtypes", &PubtypesSection
)
1567 .Case("debug_gnu_pubnames", &GnuPubnamesSection
)
1568 .Case("debug_gnu_pubtypes", &GnuPubtypesSection
)
1569 .Case("apple_types", &AppleTypesSection
)
1570 .Case("apple_namespaces", &AppleNamespacesSection
)
1571 .Case("apple_namespac", &AppleNamespacesSection
)
1572 .Case("apple_objc", &AppleObjCSection
)
1573 .Case("debug_macro", &MacroSection
)
1577 StringRef AbbrevSection
;
1578 StringRef ArangesSection
;
1579 StringRef StrSection
;
1580 StringRef MacinfoSection
;
1581 StringRef MacinfoDWOSection
;
1582 StringRef MacroDWOSection
;
1583 StringRef AbbrevDWOSection
;
1584 StringRef StrDWOSection
;
1585 StringRef CUIndexSection
;
1586 StringRef GdbIndexSection
;
1587 StringRef TUIndexSection
;
1588 StringRef LineStrSection
;
1590 // A deque holding section data whose iterators are not invalidated when
1591 // new decompressed sections are inserted at the end.
1592 std::deque
<SmallString
<0>> UncompressedSections
;
1594 StringRef
*mapSectionToMember(StringRef Name
) {
1595 if (DWARFSection
*Sec
= mapNameToDWARFSection(Name
))
1597 return StringSwitch
<StringRef
*>(Name
)
1598 .Case("debug_abbrev", &AbbrevSection
)
1599 .Case("debug_aranges", &ArangesSection
)
1600 .Case("debug_str", &StrSection
)
1601 .Case("debug_macinfo", &MacinfoSection
)
1602 .Case("debug_macinfo.dwo", &MacinfoDWOSection
)
1603 .Case("debug_macro.dwo", &MacroDWOSection
)
1604 .Case("debug_abbrev.dwo", &AbbrevDWOSection
)
1605 .Case("debug_str.dwo", &StrDWOSection
)
1606 .Case("debug_cu_index", &CUIndexSection
)
1607 .Case("debug_tu_index", &TUIndexSection
)
1608 .Case("gdb_index", &GdbIndexSection
)
1609 .Case("debug_line_str", &LineStrSection
)
1610 // Any more debug info sections go here.
1614 /// If Sec is compressed section, decompresses and updates its contents
1615 /// provided by Data. Otherwise leaves it unchanged.
1616 Error
maybeDecompress(const object::SectionRef
&Sec
, StringRef Name
,
1618 if (!Decompressor::isCompressed(Sec
))
1619 return Error::success();
1621 Expected
<Decompressor
> Decompressor
=
1622 Decompressor::create(Name
, Data
, IsLittleEndian
, AddressSize
== 8);
1624 return Decompressor
.takeError();
1627 if (auto Err
= Decompressor
->resizeAndDecompress(Out
))
1630 UncompressedSections
.push_back(std::move(Out
));
1631 Data
= UncompressedSections
.back();
1633 return Error::success();
1637 DWARFObjInMemory(const StringMap
<std::unique_ptr
<MemoryBuffer
>> &Sections
,
1638 uint8_t AddrSize
, bool IsLittleEndian
)
1639 : IsLittleEndian(IsLittleEndian
) {
1640 for (const auto &SecIt
: Sections
) {
1641 if (StringRef
*SectionData
= mapSectionToMember(SecIt
.first()))
1642 *SectionData
= SecIt
.second
->getBuffer();
1643 else if (SecIt
.first() == "debug_info")
1644 // Find debug_info and debug_types data by section rather than name as
1645 // there are multiple, comdat grouped, of these sections.
1646 InfoSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1647 else if (SecIt
.first() == "debug_info.dwo")
1648 InfoDWOSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1649 else if (SecIt
.first() == "debug_types")
1650 TypesSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1651 else if (SecIt
.first() == "debug_types.dwo")
1652 TypesDWOSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
1655 DWARFObjInMemory(const object::ObjectFile
&Obj
, const LoadedObjectInfo
*L
,
1656 function_ref
<void(Error
)> HandleError
,
1657 function_ref
<void(Error
)> HandleWarning
,
1658 DWARFContext::ProcessDebugRelocations RelocAction
)
1659 : IsLittleEndian(Obj
.isLittleEndian()),
1660 AddressSize(Obj
.getBytesInAddress()), FileName(Obj
.getFileName()),
1663 StringMap
<unsigned> SectionAmountMap
;
1664 for (const SectionRef
&Section
: Obj
.sections()) {
1666 if (auto NameOrErr
= Section
.getName())
1669 consumeError(NameOrErr
.takeError());
1671 ++SectionAmountMap
[Name
];
1672 SectionNames
.push_back({ Name
, true });
1674 // Skip BSS and Virtual sections, they aren't interesting.
1675 if (Section
.isBSS() || Section
.isVirtual())
1678 // Skip sections stripped by dsymutil.
1679 if (Section
.isStripped())
1683 Expected
<section_iterator
> SecOrErr
= Section
.getRelocatedSection();
1685 HandleError(createError("failed to get relocated section: ",
1686 SecOrErr
.takeError()));
1690 // Try to obtain an already relocated version of this section.
1691 // Else use the unrelocated section from the object file. We'll have to
1692 // apply relocations ourselves later.
1693 section_iterator RelocatedSection
=
1694 Obj
.isRelocatableObject() ? *SecOrErr
: Obj
.section_end();
1695 if (!L
|| !L
->getLoadedSectionContents(*RelocatedSection
, Data
)) {
1696 Expected
<StringRef
> E
= Section
.getContents();
1700 // maybeDecompress below will error.
1701 consumeError(E
.takeError());
1704 if (auto Err
= maybeDecompress(Section
, Name
, Data
)) {
1705 HandleError(createError("failed to decompress '" + Name
+ "', ",
1710 // Compressed sections names in GNU style starts from ".z",
1711 // at this point section is decompressed and we drop compression prefix.
1713 Name
.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1715 // Map platform specific debug section names to DWARF standard section
1717 Name
= Obj
.mapDebugSectionName(Name
);
1719 if (StringRef
*SectionData
= mapSectionToMember(Name
)) {
1720 *SectionData
= Data
;
1721 if (Name
== "debug_ranges") {
1722 // FIXME: Use the other dwo range section when we emit it.
1723 RangesDWOSection
.Data
= Data
;
1724 } else if (Name
== "debug_frame" || Name
== "eh_frame") {
1725 if (DWARFSection
*S
= mapNameToDWARFSection(Name
))
1726 S
->Address
= Section
.getAddress();
1728 } else if (InfoSectionMap
*Sections
=
1729 StringSwitch
<InfoSectionMap
*>(Name
)
1730 .Case("debug_info", &InfoSections
)
1731 .Case("debug_info.dwo", &InfoDWOSections
)
1732 .Case("debug_types", &TypesSections
)
1733 .Case("debug_types.dwo", &TypesDWOSections
)
1734 .Default(nullptr)) {
1735 // Find debug_info and debug_types data by section rather than name as
1736 // there are multiple, comdat grouped, of these sections.
1737 DWARFSectionMap
&S
= (*Sections
)[Section
];
1741 if (RelocatedSection
!= Obj
.section_end() && Name
.contains(".dwo"))
1743 createError("Unexpected relocations for dwo section " + Name
));
1745 if (RelocatedSection
== Obj
.section_end() ||
1746 (RelocAction
== DWARFContext::ProcessDebugRelocations::Ignore
))
1749 StringRef RelSecName
;
1750 if (auto NameOrErr
= RelocatedSection
->getName())
1751 RelSecName
= *NameOrErr
;
1753 consumeError(NameOrErr
.takeError());
1755 // If the section we're relocating was relocated already by the JIT,
1756 // then we used the relocated version above, so we do not need to process
1757 // relocations for it now.
1758 StringRef RelSecData
;
1759 if (L
&& L
->getLoadedSectionContents(*RelocatedSection
, RelSecData
))
1762 // In Mach-o files, the relocations do not need to be applied if
1763 // there is no load offset to apply. The value read at the
1764 // relocation point already factors in the section address
1765 // (actually applying the relocations will produce wrong results
1766 // as the section address will be added twice).
1767 if (!L
&& isa
<MachOObjectFile
>(&Obj
))
1770 RelSecName
= RelSecName
.substr(
1771 RelSecName
.find_first_not_of("._z")); // Skip . and _ prefixes.
1773 // TODO: Add support for relocations in other sections as needed.
1774 // Record relocations for the debug_info and debug_line sections.
1775 DWARFSectionMap
*Sec
= mapNameToDWARFSection(RelSecName
);
1776 RelocAddrMap
*Map
= Sec
? &Sec
->Relocs
: nullptr;
1778 // Find debug_info and debug_types relocs by section rather than name
1779 // as there are multiple, comdat grouped, of these sections.
1780 if (RelSecName
== "debug_info")
1781 Map
= &static_cast<DWARFSectionMap
&>(InfoSections
[*RelocatedSection
])
1783 else if (RelSecName
== "debug_types")
1785 &static_cast<DWARFSectionMap
&>(TypesSections
[*RelocatedSection
])
1791 if (Section
.relocation_begin() == Section
.relocation_end())
1794 // Symbol to [address, section index] cache mapping.
1795 std::map
<SymbolRef
, SymInfo
> AddrCache
;
1796 SupportsRelocation Supports
;
1797 RelocationResolver Resolver
;
1798 std::tie(Supports
, Resolver
) = getRelocationResolver(Obj
);
1799 for (const RelocationRef
&Reloc
: Section
.relocations()) {
1800 // FIXME: it's not clear how to correctly handle scattered
1802 if (isRelocScattered(Obj
, Reloc
))
1805 Expected
<SymInfo
> SymInfoOrErr
=
1806 getSymbolInfo(Obj
, Reloc
, L
, AddrCache
);
1807 if (!SymInfoOrErr
) {
1808 HandleError(SymInfoOrErr
.takeError());
1812 // Check if Resolver can handle this relocation type early so as not to
1813 // handle invalid cases in DWARFDataExtractor.
1815 // TODO Don't store Resolver in every RelocAddrEntry.
1816 if (Supports
&& Supports(Reloc
.getType())) {
1817 auto I
= Map
->try_emplace(
1819 RelocAddrEntry
{SymInfoOrErr
->SectionIndex
, Reloc
,
1820 SymInfoOrErr
->Address
,
1821 Optional
<object::RelocationRef
>(), 0, Resolver
});
1822 // If we didn't successfully insert that's because we already had a
1823 // relocation for that offset. Store it as a second relocation in the
1824 // same RelocAddrEntry instead.
1826 RelocAddrEntry
&entry
= I
.first
->getSecond();
1828 HandleError(createError(
1829 "At most two relocations per offset are supported"));
1831 entry
.Reloc2
= Reloc
;
1832 entry
.SymbolValue2
= SymInfoOrErr
->Address
;
1835 SmallString
<32> Type
;
1836 Reloc
.getTypeName(Type
);
1837 // FIXME: Support more relocations & change this to an error
1839 createError("failed to compute relocation: " + Type
+ ", ",
1840 errorCodeToError(object_error::parse_failed
)));
1845 for (SectionName
&S
: SectionNames
)
1846 if (SectionAmountMap
[S
.Name
] > 1)
1847 S
.IsNameUnique
= false;
1850 Optional
<RelocAddrEntry
> find(const DWARFSection
&S
,
1851 uint64_t Pos
) const override
{
1852 auto &Sec
= static_cast<const DWARFSectionMap
&>(S
);
1853 RelocAddrMap::const_iterator AI
= Sec
.Relocs
.find(Pos
);
1854 if (AI
== Sec
.Relocs
.end())
1859 const object::ObjectFile
*getFile() const override
{ return Obj
; }
1861 ArrayRef
<SectionName
> getSectionNames() const override
{
1862 return SectionNames
;
1865 bool isLittleEndian() const override
{ return IsLittleEndian
; }
1866 StringRef
getAbbrevDWOSection() const override
{ return AbbrevDWOSection
; }
1867 const DWARFSection
&getLineDWOSection() const override
{
1868 return LineDWOSection
;
1870 const DWARFSection
&getLocDWOSection() const override
{
1871 return LocDWOSection
;
1873 StringRef
getStrDWOSection() const override
{ return StrDWOSection
; }
1874 const DWARFSection
&getStrOffsetsDWOSection() const override
{
1875 return StrOffsetsDWOSection
;
1877 const DWARFSection
&getRangesDWOSection() const override
{
1878 return RangesDWOSection
;
1880 const DWARFSection
&getRnglistsDWOSection() const override
{
1881 return RnglistsDWOSection
;
1883 const DWARFSection
&getLoclistsDWOSection() const override
{
1884 return LoclistsDWOSection
;
1886 const DWARFSection
&getAddrSection() const override
{ return AddrSection
; }
1887 StringRef
getCUIndexSection() const override
{ return CUIndexSection
; }
1888 StringRef
getGdbIndexSection() const override
{ return GdbIndexSection
; }
1889 StringRef
getTUIndexSection() const override
{ return TUIndexSection
; }
1892 const DWARFSection
&getStrOffsetsSection() const override
{
1893 return StrOffsetsSection
;
1895 StringRef
getLineStrSection() const override
{ return LineStrSection
; }
1897 // Sections for DWARF5 split dwarf proposal.
1898 void forEachInfoDWOSections(
1899 function_ref
<void(const DWARFSection
&)> F
) const override
{
1900 for (auto &P
: InfoDWOSections
)
1903 void forEachTypesDWOSections(
1904 function_ref
<void(const DWARFSection
&)> F
) const override
{
1905 for (auto &P
: TypesDWOSections
)
1909 StringRef
getAbbrevSection() const override
{ return AbbrevSection
; }
1910 const DWARFSection
&getLocSection() const override
{ return LocSection
; }
1911 const DWARFSection
&getLoclistsSection() const override
{ return LoclistsSection
; }
1912 StringRef
getArangesSection() const override
{ return ArangesSection
; }
1913 const DWARFSection
&getFrameSection() const override
{
1914 return FrameSection
;
1916 const DWARFSection
&getEHFrameSection() const override
{
1917 return EHFrameSection
;
1919 const DWARFSection
&getLineSection() const override
{ return LineSection
; }
1920 StringRef
getStrSection() const override
{ return StrSection
; }
1921 const DWARFSection
&getRangesSection() const override
{ return RangesSection
; }
1922 const DWARFSection
&getRnglistsSection() const override
{
1923 return RnglistsSection
;
1925 const DWARFSection
&getMacroSection() const override
{ return MacroSection
; }
1926 StringRef
getMacroDWOSection() const override
{ return MacroDWOSection
; }
1927 StringRef
getMacinfoSection() const override
{ return MacinfoSection
; }
1928 StringRef
getMacinfoDWOSection() const override
{ return MacinfoDWOSection
; }
1929 const DWARFSection
&getPubnamesSection() const override
{ return PubnamesSection
; }
1930 const DWARFSection
&getPubtypesSection() const override
{ return PubtypesSection
; }
1931 const DWARFSection
&getGnuPubnamesSection() const override
{
1932 return GnuPubnamesSection
;
1934 const DWARFSection
&getGnuPubtypesSection() const override
{
1935 return GnuPubtypesSection
;
1937 const DWARFSection
&getAppleNamesSection() const override
{
1938 return AppleNamesSection
;
1940 const DWARFSection
&getAppleTypesSection() const override
{
1941 return AppleTypesSection
;
1943 const DWARFSection
&getAppleNamespacesSection() const override
{
1944 return AppleNamespacesSection
;
1946 const DWARFSection
&getAppleObjCSection() const override
{
1947 return AppleObjCSection
;
1949 const DWARFSection
&getNamesSection() const override
{
1950 return NamesSection
;
1953 StringRef
getFileName() const override
{ return FileName
; }
1954 uint8_t getAddressSize() const override
{ return AddressSize
; }
1955 void forEachInfoSections(
1956 function_ref
<void(const DWARFSection
&)> F
) const override
{
1957 for (auto &P
: InfoSections
)
1960 void forEachTypesSections(
1961 function_ref
<void(const DWARFSection
&)> F
) const override
{
1962 for (auto &P
: TypesSections
)
1968 std::unique_ptr
<DWARFContext
>
1969 DWARFContext::create(const object::ObjectFile
&Obj
,
1970 ProcessDebugRelocations RelocAction
,
1971 const LoadedObjectInfo
*L
, std::string DWPName
,
1972 std::function
<void(Error
)> RecoverableErrorHandler
,
1973 std::function
<void(Error
)> WarningHandler
) {
1974 auto DObj
= std::make_unique
<DWARFObjInMemory
>(
1975 Obj
, L
, RecoverableErrorHandler
, WarningHandler
, RelocAction
);
1976 return std::make_unique
<DWARFContext
>(std::move(DObj
), std::move(DWPName
),
1977 RecoverableErrorHandler
,
1981 std::unique_ptr
<DWARFContext
>
1982 DWARFContext::create(const StringMap
<std::unique_ptr
<MemoryBuffer
>> &Sections
,
1983 uint8_t AddrSize
, bool isLittleEndian
,
1984 std::function
<void(Error
)> RecoverableErrorHandler
,
1985 std::function
<void(Error
)> WarningHandler
) {
1987 std::make_unique
<DWARFObjInMemory
>(Sections
, AddrSize
, isLittleEndian
);
1988 return std::make_unique
<DWARFContext
>(
1989 std::move(DObj
), "", RecoverableErrorHandler
, WarningHandler
);
1992 Error
DWARFContext::loadRegisterInfo(const object::ObjectFile
&Obj
) {
1993 // Detect the architecture from the object file. We usually don't need OS
1994 // info to lookup a target and create register info.
1996 TT
.setArch(Triple::ArchType(Obj
.getArch()));
1997 TT
.setVendor(Triple::UnknownVendor
);
1998 TT
.setOS(Triple::UnknownOS
);
1999 std::string TargetLookupError
;
2000 const Target
*TheTarget
=
2001 TargetRegistry::lookupTarget(TT
.str(), TargetLookupError
);
2002 if (!TargetLookupError
.empty())
2003 return createStringError(errc::invalid_argument
,
2004 TargetLookupError
.c_str());
2005 RegInfo
.reset(TheTarget
->createMCRegInfo(TT
.str()));
2006 return Error::success();
2009 uint8_t DWARFContext::getCUAddrSize() {
2010 // In theory, different compile units may have different address byte
2011 // sizes, but for simplicity we just use the address byte size of the
2012 // first compile unit. In practice the address size field is repeated across
2013 // various DWARF headers (at least in version 5) to make it easier to dump
2014 // them independently, not to enable varying the address size.
2015 auto CUs
= compile_units();
2016 return CUs
.empty() ? 0 : (*CUs
.begin())->getAddressByteSize();