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
;
74 void fixupIndexV4(DWARFContext
&C
, DWARFUnitIndex
&Index
) {
75 using EntryType
= DWARFUnitIndex::Entry::SectionContribution
;
76 using EntryMap
= DenseMap
<uint32_t, EntryType
>;
78 const auto &DObj
= C
.getDWARFObj();
79 if (DObj
.getCUIndexSection().empty())
83 uint32_t TruncOffset
= 0;
84 DObj
.forEachInfoDWOSections([&](const DWARFSection
&S
) {
85 if (!(C
.getParseCUTUIndexManually() ||
86 S
.Data
.size() >= std::numeric_limits
<uint32_t>::max()))
89 DWARFDataExtractor
Data(DObj
, S
, C
.isLittleEndian(), 0);
90 while (Data
.isValidOffset(Offset
)) {
91 DWARFUnitHeader Header
;
92 if (Error ExtractionErr
= Header
.extract(
93 C
, Data
, &Offset
, DWARFSectionKind::DW_SECT_INFO
)) {
94 C
.getWarningHandler()(
95 createError("Failed to parse CU header in DWP file: " +
96 toString(std::move(ExtractionErr
))));
101 auto Iter
= Map
.insert({TruncOffset
,
102 {Header
.getOffset(), Header
.getNextUnitOffset() -
103 Header
.getOffset()}});
105 logAllUnhandledErrors(
106 createError("Collision occured between for truncated offset 0x" +
107 Twine::utohexstr(TruncOffset
)),
113 Offset
= Header
.getNextUnitOffset();
114 TruncOffset
= Offset
;
121 for (DWARFUnitIndex::Entry
&E
: Index
.getMutableRows()) {
124 DWARFUnitIndex::Entry::SectionContribution
&CUOff
= E
.getContribution();
125 auto Iter
= Map
.find(CUOff
.getOffset());
126 if (Iter
== Map
.end()) {
127 logAllUnhandledErrors(createError("Could not find CU offset 0x" +
128 Twine::utohexstr(CUOff
.getOffset()) +
133 CUOff
.setOffset(Iter
->second
.getOffset());
134 if (CUOff
.getOffset() != Iter
->second
.getOffset())
135 logAllUnhandledErrors(createError("Length of CU in CU index doesn't "
136 "match calculated length at offset 0x" +
137 Twine::utohexstr(CUOff
.getOffset())),
142 void fixupIndexV5(DWARFContext
&C
, DWARFUnitIndex
&Index
) {
143 DenseMap
<uint64_t, uint64_t> Map
;
145 const auto &DObj
= C
.getDWARFObj();
146 DObj
.forEachInfoDWOSections([&](const DWARFSection
&S
) {
147 if (!(C
.getParseCUTUIndexManually() ||
148 S
.Data
.size() >= std::numeric_limits
<uint32_t>::max()))
150 DWARFDataExtractor
Data(DObj
, S
, C
.isLittleEndian(), 0);
152 while (Data
.isValidOffset(Offset
)) {
153 DWARFUnitHeader Header
;
154 if (Error ExtractionErr
= Header
.extract(
155 C
, Data
, &Offset
, DWARFSectionKind::DW_SECT_INFO
)) {
156 C
.getWarningHandler()(
157 createError("Failed to parse CU header in DWP file: " +
158 toString(std::move(ExtractionErr
))));
161 bool CU
= Header
.getUnitType() == DW_UT_split_compile
;
162 uint64_t Sig
= CU
? *Header
.getDWOId() : Header
.getTypeHash();
163 Map
[Sig
] = Header
.getOffset();
164 Offset
= Header
.getNextUnitOffset();
169 for (DWARFUnitIndex::Entry
&E
: Index
.getMutableRows()) {
172 DWARFUnitIndex::Entry::SectionContribution
&CUOff
= E
.getContribution();
173 auto Iter
= Map
.find(E
.getSignature());
174 if (Iter
== Map
.end()) {
175 logAllUnhandledErrors(
176 createError("Could not find unit with signature 0x" +
177 Twine::utohexstr(E
.getSignature()) + " in the Map"),
181 CUOff
.setOffset(Iter
->second
);
185 void fixupIndex(DWARFContext
&C
, DWARFUnitIndex
&Index
) {
186 if (Index
.getVersion() < 5)
187 fixupIndexV4(C
, Index
);
189 fixupIndexV5(C
, Index
);
192 template <typename T
>
193 static T
&getAccelTable(std::unique_ptr
<T
> &Cache
, const DWARFObject
&Obj
,
194 const DWARFSection
&Section
, StringRef StringSection
,
195 bool IsLittleEndian
) {
198 DWARFDataExtractor
AccelSection(Obj
, Section
, IsLittleEndian
, 0);
199 DataExtractor
StrData(StringSection
, IsLittleEndian
, 0);
200 Cache
= std::make_unique
<T
>(AccelSection
, StrData
);
201 if (Error E
= Cache
->extract())
202 llvm::consumeError(std::move(E
));
207 std::unique_ptr
<DWARFDebugMacro
>
208 DWARFContext::DWARFContextState::parseMacroOrMacinfo(MacroSecType SectionType
) {
209 auto Macro
= std::make_unique
<DWARFDebugMacro
>();
210 auto ParseAndDump
= [&](DWARFDataExtractor
&Data
, bool IsMacro
) {
211 if (Error Err
= IsMacro
? Macro
->parseMacro(SectionType
== MacroSection
213 : D
.dwo_compile_units(),
214 SectionType
== MacroSection
215 ? D
.getStringExtractor()
216 : D
.getStringDWOExtractor(),
218 : Macro
->parseMacinfo(Data
)) {
219 D
.getRecoverableErrorHandler()(std::move(Err
));
223 const DWARFObject
&DObj
= D
.getDWARFObj();
224 switch (SectionType
) {
225 case MacinfoSection
: {
226 DWARFDataExtractor
Data(DObj
.getMacinfoSection(), D
.isLittleEndian(), 0);
227 ParseAndDump(Data
, /*IsMacro=*/false);
230 case MacinfoDwoSection
: {
231 DWARFDataExtractor
Data(DObj
.getMacinfoDWOSection(), D
.isLittleEndian(), 0);
232 ParseAndDump(Data
, /*IsMacro=*/false);
236 DWARFDataExtractor
Data(DObj
, DObj
.getMacroSection(), D
.isLittleEndian(),
238 ParseAndDump(Data
, /*IsMacro=*/true);
241 case MacroDwoSection
: {
242 DWARFDataExtractor
Data(DObj
.getMacroDWOSection(), D
.isLittleEndian(), 0);
243 ParseAndDump(Data
, /*IsMacro=*/true);
250 class ThreadUnsafeDWARFContextState
: public DWARFContext::DWARFContextState
{
252 DWARFUnitVector NormalUnits
;
253 std::optional
<DenseMap
<uint64_t, DWARFTypeUnit
*>> NormalTypeUnits
;
254 std::unique_ptr
<DWARFUnitIndex
> CUIndex
;
255 std::unique_ptr
<DWARFGdbIndex
> GdbIndex
;
256 std::unique_ptr
<DWARFUnitIndex
> TUIndex
;
257 std::unique_ptr
<DWARFDebugAbbrev
> Abbrev
;
258 std::unique_ptr
<DWARFDebugLoc
> Loc
;
259 std::unique_ptr
<DWARFDebugAranges
> Aranges
;
260 std::unique_ptr
<DWARFDebugLine
> Line
;
261 std::unique_ptr
<DWARFDebugFrame
> DebugFrame
;
262 std::unique_ptr
<DWARFDebugFrame
> EHFrame
;
263 std::unique_ptr
<DWARFDebugMacro
> Macro
;
264 std::unique_ptr
<DWARFDebugMacro
> Macinfo
;
265 std::unique_ptr
<DWARFDebugNames
> Names
;
266 std::unique_ptr
<AppleAcceleratorTable
> AppleNames
;
267 std::unique_ptr
<AppleAcceleratorTable
> AppleTypes
;
268 std::unique_ptr
<AppleAcceleratorTable
> AppleNamespaces
;
269 std::unique_ptr
<AppleAcceleratorTable
> AppleObjC
;
270 DWARFUnitVector DWOUnits
;
271 std::optional
<DenseMap
<uint64_t, DWARFTypeUnit
*>> DWOTypeUnits
;
272 std::unique_ptr
<DWARFDebugAbbrev
> AbbrevDWO
;
273 std::unique_ptr
<DWARFDebugMacro
> MacinfoDWO
;
274 std::unique_ptr
<DWARFDebugMacro
> MacroDWO
;
276 object::OwningBinary
<object::ObjectFile
> File
;
277 std::unique_ptr
<DWARFContext
> Context
;
279 StringMap
<std::weak_ptr
<DWOFile
>> DWOFiles
;
280 std::weak_ptr
<DWOFile
> DWP
;
281 bool CheckedForDWP
= false;
285 ThreadUnsafeDWARFContextState(DWARFContext
&DC
, std::string
&DWP
) :
286 DWARFContext::DWARFContextState(DC
),
287 DWPName(std::move(DWP
)) {}
289 DWARFUnitVector
&getNormalUnits() override
{
290 if (NormalUnits
.empty()) {
291 const DWARFObject
&DObj
= D
.getDWARFObj();
292 DObj
.forEachInfoSections([&](const DWARFSection
&S
) {
293 NormalUnits
.addUnitsForSection(D
, S
, DW_SECT_INFO
);
295 NormalUnits
.finishedInfoUnits();
296 DObj
.forEachTypesSections([&](const DWARFSection
&S
) {
297 NormalUnits
.addUnitsForSection(D
, S
, DW_SECT_EXT_TYPES
);
303 DWARFUnitVector
&getDWOUnits(bool Lazy
) override
{
304 if (DWOUnits
.empty()) {
305 const DWARFObject
&DObj
= D
.getDWARFObj();
307 DObj
.forEachInfoDWOSections([&](const DWARFSection
&S
) {
308 DWOUnits
.addUnitsForDWOSection(D
, S
, DW_SECT_INFO
, Lazy
);
310 DWOUnits
.finishedInfoUnits();
311 DObj
.forEachTypesDWOSections([&](const DWARFSection
&S
) {
312 DWOUnits
.addUnitsForDWOSection(D
, S
, DW_SECT_EXT_TYPES
, Lazy
);
318 const DWARFDebugAbbrev
*getDebugAbbrevDWO() override
{
320 return AbbrevDWO
.get();
321 const DWARFObject
&DObj
= D
.getDWARFObj();
322 DataExtractor
abbrData(DObj
.getAbbrevDWOSection(), D
.isLittleEndian(), 0);
323 AbbrevDWO
= std::make_unique
<DWARFDebugAbbrev
>(abbrData
);
324 return AbbrevDWO
.get();
327 const DWARFUnitIndex
&getCUIndex() override
{
331 DataExtractor
Data(D
.getDWARFObj().getCUIndexSection(),
332 D
.isLittleEndian(), 0);
333 CUIndex
= std::make_unique
<DWARFUnitIndex
>(DW_SECT_INFO
);
334 if (CUIndex
->parse(Data
))
335 fixupIndex(D
, *CUIndex
);
338 const DWARFUnitIndex
&getTUIndex() override
{
342 DataExtractor
Data(D
.getDWARFObj().getTUIndexSection(),
343 D
.isLittleEndian(), 0);
344 TUIndex
= std::make_unique
<DWARFUnitIndex
>(DW_SECT_EXT_TYPES
);
345 bool isParseSuccessful
= TUIndex
->parse(Data
);
346 // If we are parsing TU-index and for .debug_types section we don't need
348 if (isParseSuccessful
&& TUIndex
->getVersion() != 2)
349 fixupIndex(D
, *TUIndex
);
353 DWARFGdbIndex
&getGdbIndex() override
{
357 DataExtractor
Data(D
.getDWARFObj().getGdbIndexSection(), true /*LE*/, 0);
358 GdbIndex
= std::make_unique
<DWARFGdbIndex
>();
359 GdbIndex
->parse(Data
);
363 const DWARFDebugAbbrev
*getDebugAbbrev() override
{
367 DataExtractor
Data(D
.getDWARFObj().getAbbrevSection(),
368 D
.isLittleEndian(), 0);
369 Abbrev
= std::make_unique
<DWARFDebugAbbrev
>(Data
);
373 const DWARFDebugLoc
*getDebugLoc() override
{
377 const DWARFObject
&DObj
= D
.getDWARFObj();
378 // Assume all units have the same address byte size.
380 D
.getNumCompileUnits()
381 ? DWARFDataExtractor(DObj
, DObj
.getLocSection(), D
.isLittleEndian(),
382 D
.getUnitAtIndex(0)->getAddressByteSize())
383 : DWARFDataExtractor("", D
.isLittleEndian(), 0);
384 Loc
= std::make_unique
<DWARFDebugLoc
>(std::move(Data
));
388 const DWARFDebugAranges
*getDebugAranges() override
{
390 return Aranges
.get();
392 Aranges
= std::make_unique
<DWARFDebugAranges
>();
393 Aranges
->generate(&D
);
394 return Aranges
.get();
397 Expected
<const DWARFDebugLine::LineTable
*>
398 getLineTableForUnit(DWARFUnit
*U
, function_ref
<void(Error
)> RecoverableErrorHandler
) override
{
400 Line
= std::make_unique
<DWARFDebugLine
>();
402 auto UnitDIE
= U
->getUnitDIE();
406 auto Offset
= toSectionOffset(UnitDIE
.find(DW_AT_stmt_list
));
408 return nullptr; // No line table for this compile unit.
410 uint64_t stmtOffset
= *Offset
+ U
->getLineTableOffset();
411 // See if the line table is cached.
412 if (const DWARFLineTable
*lt
= Line
->getLineTable(stmtOffset
))
415 // Make sure the offset is good before we try to parse.
416 if (stmtOffset
>= U
->getLineSection().Data
.size())
419 // We have to parse it first.
420 DWARFDataExtractor
Data(U
->getContext().getDWARFObj(), U
->getLineSection(),
421 U
->isLittleEndian(), U
->getAddressByteSize());
422 return Line
->getOrParseLineTable(Data
, stmtOffset
, U
->getContext(), U
,
423 RecoverableErrorHandler
);
427 void clearLineTableForUnit(DWARFUnit
*U
) override
{
431 auto UnitDIE
= U
->getUnitDIE();
435 auto Offset
= toSectionOffset(UnitDIE
.find(DW_AT_stmt_list
));
439 uint64_t stmtOffset
= *Offset
+ U
->getLineTableOffset();
440 Line
->clearLineTable(stmtOffset
);
443 Expected
<const DWARFDebugFrame
*> getDebugFrame() override
{
445 return DebugFrame
.get();
446 const DWARFObject
&DObj
= D
.getDWARFObj();
447 const DWARFSection
&DS
= DObj
.getFrameSection();
449 // There's a "bug" in the DWARFv3 standard with respect to the target address
450 // size within debug frame sections. While DWARF is supposed to be independent
451 // of its container, FDEs have fields with size being "target address size",
452 // which isn't specified in DWARF in general. It's only specified for CUs, but
453 // .eh_frame can appear without a .debug_info section. Follow the example of
454 // other tools (libdwarf) and extract this from the container (ObjectFile
455 // provides this information). This problem is fixed in DWARFv4
456 // See this dwarf-discuss discussion for more details:
457 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
458 DWARFDataExtractor
Data(DObj
, DS
, D
.isLittleEndian(),
459 DObj
.getAddressSize());
461 std::make_unique
<DWARFDebugFrame
>(D
.getArch(), /*IsEH=*/false,
463 if (Error E
= DF
->parse(Data
))
467 return DebugFrame
.get();
470 Expected
<const DWARFDebugFrame
*> getEHFrame() override
{
472 return EHFrame
.get();
473 const DWARFObject
&DObj
= D
.getDWARFObj();
475 const DWARFSection
&DS
= DObj
.getEHFrameSection();
476 DWARFDataExtractor
Data(DObj
, DS
, D
.isLittleEndian(),
477 DObj
.getAddressSize());
479 std::make_unique
<DWARFDebugFrame
>(D
.getArch(), /*IsEH=*/true,
481 if (Error E
= DF
->parse(Data
))
484 return EHFrame
.get();
487 const DWARFDebugMacro
*getDebugMacinfo() override
{
489 Macinfo
= parseMacroOrMacinfo(MacinfoSection
);
490 return Macinfo
.get();
492 const DWARFDebugMacro
*getDebugMacinfoDWO() override
{
494 MacinfoDWO
= parseMacroOrMacinfo(MacinfoDwoSection
);
495 return MacinfoDWO
.get();
497 const DWARFDebugMacro
*getDebugMacro() override
{
499 Macro
= parseMacroOrMacinfo(MacroSection
);
502 const DWARFDebugMacro
*getDebugMacroDWO() override
{
504 MacroDWO
= parseMacroOrMacinfo(MacroDwoSection
);
505 return MacroDWO
.get();
507 const DWARFDebugNames
&getDebugNames() override
{
508 const DWARFObject
&DObj
= D
.getDWARFObj();
509 return getAccelTable(Names
, DObj
, DObj
.getNamesSection(),
510 DObj
.getStrSection(), D
.isLittleEndian());
512 const AppleAcceleratorTable
&getAppleNames() override
{
513 const DWARFObject
&DObj
= D
.getDWARFObj();
514 return getAccelTable(AppleNames
, DObj
, DObj
.getAppleNamesSection(),
515 DObj
.getStrSection(), D
.isLittleEndian());
518 const AppleAcceleratorTable
&getAppleTypes() override
{
519 const DWARFObject
&DObj
= D
.getDWARFObj();
520 return getAccelTable(AppleTypes
, DObj
, DObj
.getAppleTypesSection(),
521 DObj
.getStrSection(), D
.isLittleEndian());
524 const AppleAcceleratorTable
&getAppleNamespaces() override
{
525 const DWARFObject
&DObj
= D
.getDWARFObj();
526 return getAccelTable(AppleNamespaces
, DObj
,
527 DObj
.getAppleNamespacesSection(),
528 DObj
.getStrSection(), D
.isLittleEndian());
531 const AppleAcceleratorTable
&getAppleObjC() override
{
532 const DWARFObject
&DObj
= D
.getDWARFObj();
533 return getAccelTable(AppleObjC
, DObj
, DObj
.getAppleObjCSection(),
534 DObj
.getStrSection(), D
.isLittleEndian());
537 std::shared_ptr
<DWARFContext
>
538 getDWOContext(StringRef AbsolutePath
) override
{
539 if (auto S
= DWP
.lock()) {
540 DWARFContext
*Ctxt
= S
->Context
.get();
541 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
544 std::weak_ptr
<DWOFile
> *Entry
= &DWOFiles
[AbsolutePath
];
546 if (auto S
= Entry
->lock()) {
547 DWARFContext
*Ctxt
= S
->Context
.get();
548 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
551 const DWARFObject
&DObj
= D
.getDWARFObj();
553 Expected
<OwningBinary
<ObjectFile
>> Obj
= [&] {
554 if (!CheckedForDWP
) {
555 SmallString
<128> DWPName
;
556 auto Obj
= object::ObjectFile::createObjectFile(
557 this->DWPName
.empty()
558 ? (DObj
.getFileName() + ".dwp").toStringRef(DWPName
)
559 : StringRef(this->DWPName
));
564 CheckedForDWP
= true;
565 // TODO: Should this error be handled (maybe in a high verbosity mode)
566 // before falling back to .dwo files?
567 consumeError(Obj
.takeError());
571 return object::ObjectFile::createObjectFile(AbsolutePath
);
575 // TODO: Actually report errors helpfully.
576 consumeError(Obj
.takeError());
580 auto S
= std::make_shared
<DWOFile
>();
581 S
->File
= std::move(Obj
.get());
582 // Allow multi-threaded access if there is a .dwp file as the CU index and
583 // TU index might be accessed from multiple threads.
584 bool ThreadSafe
= isThreadSafe();
585 S
->Context
= DWARFContext::create(
586 *S
->File
.getBinary(), DWARFContext::ProcessDebugRelocations::Ignore
,
587 nullptr, "", WithColor::defaultErrorHandler
,
588 WithColor::defaultWarningHandler
, ThreadSafe
);
590 auto *Ctxt
= S
->Context
.get();
591 return std::shared_ptr
<DWARFContext
>(std::move(S
), Ctxt
);
594 bool isThreadSafe() const override
{ return false; }
596 const DenseMap
<uint64_t, DWARFTypeUnit
*> &getNormalTypeUnitMap() {
597 if (!NormalTypeUnits
) {
598 NormalTypeUnits
.emplace();
599 for (const auto &U
:D
.normal_units()) {
600 if (DWARFTypeUnit
*TU
= dyn_cast
<DWARFTypeUnit
>(U
.get()))
601 (*NormalTypeUnits
)[TU
->getTypeHash()] = TU
;
604 return *NormalTypeUnits
;
607 const DenseMap
<uint64_t, DWARFTypeUnit
*> &getDWOTypeUnitMap() {
609 DWOTypeUnits
.emplace();
610 for (const auto &U
:D
.dwo_units()) {
611 if (DWARFTypeUnit
*TU
= dyn_cast
<DWARFTypeUnit
>(U
.get()))
612 (*DWOTypeUnits
)[TU
->getTypeHash()] = TU
;
615 return *DWOTypeUnits
;
618 const DenseMap
<uint64_t, DWARFTypeUnit
*> &
619 getTypeUnitMap(bool IsDWO
) override
{
621 return getDWOTypeUnitMap();
623 return getNormalTypeUnitMap();
629 class ThreadSafeState
: public ThreadUnsafeDWARFContextState
{
630 std::recursive_mutex Mutex
;
633 ThreadSafeState(DWARFContext
&DC
, std::string
&DWP
) :
634 ThreadUnsafeDWARFContextState(DC
, DWP
) {}
636 DWARFUnitVector
&getNormalUnits() override
{
637 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
638 return ThreadUnsafeDWARFContextState::getNormalUnits();
640 DWARFUnitVector
&getDWOUnits(bool Lazy
) override
{
641 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
642 // We need to not do lazy parsing when we need thread safety as
643 // DWARFUnitVector, in lazy mode, will slowly add things to itself and
644 // will cause problems in a multi-threaded environment.
645 return ThreadUnsafeDWARFContextState::getDWOUnits(false);
647 const DWARFUnitIndex
&getCUIndex() override
{
648 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
649 return ThreadUnsafeDWARFContextState::getCUIndex();
651 const DWARFDebugAbbrev
*getDebugAbbrevDWO() override
{
652 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
653 return ThreadUnsafeDWARFContextState::getDebugAbbrevDWO();
656 const DWARFUnitIndex
&getTUIndex() override
{
657 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
658 return ThreadUnsafeDWARFContextState::getTUIndex();
660 DWARFGdbIndex
&getGdbIndex() override
{
661 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
662 return ThreadUnsafeDWARFContextState::getGdbIndex();
664 const DWARFDebugAbbrev
*getDebugAbbrev() override
{
665 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
666 return ThreadUnsafeDWARFContextState::getDebugAbbrev();
668 const DWARFDebugLoc
*getDebugLoc() override
{
669 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
670 return ThreadUnsafeDWARFContextState::getDebugLoc();
672 const DWARFDebugAranges
*getDebugAranges() override
{
673 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
674 return ThreadUnsafeDWARFContextState::getDebugAranges();
676 Expected
<const DWARFDebugLine::LineTable
*>
677 getLineTableForUnit(DWARFUnit
*U
, function_ref
<void(Error
)> RecoverableErrorHandler
) override
{
678 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
679 return ThreadUnsafeDWARFContextState::getLineTableForUnit(U
, RecoverableErrorHandler
);
681 void clearLineTableForUnit(DWARFUnit
*U
) override
{
682 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
683 return ThreadUnsafeDWARFContextState::clearLineTableForUnit(U
);
685 Expected
<const DWARFDebugFrame
*> getDebugFrame() override
{
686 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
687 return ThreadUnsafeDWARFContextState::getDebugFrame();
689 Expected
<const DWARFDebugFrame
*> getEHFrame() override
{
690 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
691 return ThreadUnsafeDWARFContextState::getEHFrame();
693 const DWARFDebugMacro
*getDebugMacinfo() override
{
694 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
695 return ThreadUnsafeDWARFContextState::getDebugMacinfo();
697 const DWARFDebugMacro
*getDebugMacinfoDWO() override
{
698 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
699 return ThreadUnsafeDWARFContextState::getDebugMacinfoDWO();
701 const DWARFDebugMacro
*getDebugMacro() override
{
702 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
703 return ThreadUnsafeDWARFContextState::getDebugMacro();
705 const DWARFDebugMacro
*getDebugMacroDWO() override
{
706 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
707 return ThreadUnsafeDWARFContextState::getDebugMacroDWO();
709 const DWARFDebugNames
&getDebugNames() override
{
710 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
711 return ThreadUnsafeDWARFContextState::getDebugNames();
713 const AppleAcceleratorTable
&getAppleNames() override
{
714 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
715 return ThreadUnsafeDWARFContextState::getAppleNames();
717 const AppleAcceleratorTable
&getAppleTypes() override
{
718 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
719 return ThreadUnsafeDWARFContextState::getAppleTypes();
721 const AppleAcceleratorTable
&getAppleNamespaces() override
{
722 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
723 return ThreadUnsafeDWARFContextState::getAppleNamespaces();
725 const AppleAcceleratorTable
&getAppleObjC() override
{
726 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
727 return ThreadUnsafeDWARFContextState::getAppleObjC();
729 std::shared_ptr
<DWARFContext
>
730 getDWOContext(StringRef AbsolutePath
) override
{
731 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
732 return ThreadUnsafeDWARFContextState::getDWOContext(AbsolutePath
);
735 bool isThreadSafe() const override
{ return true; }
737 const DenseMap
<uint64_t, DWARFTypeUnit
*> &
738 getTypeUnitMap(bool IsDWO
) override
{
739 std::unique_lock
<std::recursive_mutex
> LockGuard(Mutex
);
740 return ThreadUnsafeDWARFContextState::getTypeUnitMap(IsDWO
);
746 DWARFContext::DWARFContext(std::unique_ptr
<const DWARFObject
> DObj
,
748 std::function
<void(Error
)> RecoverableErrorHandler
,
749 std::function
<void(Error
)> WarningHandler
,
751 : DIContext(CK_DWARF
),
752 RecoverableErrorHandler(RecoverableErrorHandler
),
753 WarningHandler(WarningHandler
), DObj(std::move(DObj
)) {
755 State
= std::make_unique
<ThreadSafeState
>(*this, DWPName
);
757 State
= std::make_unique
<ThreadUnsafeDWARFContextState
>(*this, DWPName
);
760 DWARFContext::~DWARFContext() = default;
762 /// Dump the UUID load command.
763 static void dumpUUID(raw_ostream
&OS
, const ObjectFile
&Obj
) {
764 auto *MachO
= dyn_cast
<MachOObjectFile
>(&Obj
);
767 for (auto LC
: MachO
->load_commands()) {
768 raw_ostream::uuid_t UUID
;
769 if (LC
.C
.cmd
== MachO::LC_UUID
) {
770 if (LC
.C
.cmdsize
< sizeof(UUID
) + sizeof(LC
.C
)) {
771 OS
<< "error: UUID load command is too short.\n";
775 memcpy(&UUID
, LC
.Ptr
+sizeof(LC
.C
), sizeof(UUID
));
777 Triple T
= MachO
->getArchTriple();
778 OS
<< " (" << T
.getArchName() << ')';
779 OS
<< ' ' << MachO
->getFileName() << '\n';
784 using ContributionCollection
=
785 std::vector
<std::optional
<StrOffsetsContributionDescriptor
>>;
787 // Collect all the contributions to the string offsets table from all units,
788 // sort them by their starting offsets and remove duplicates.
789 static ContributionCollection
790 collectContributionData(DWARFContext::unit_iterator_range Units
) {
791 ContributionCollection Contributions
;
792 for (const auto &U
: Units
)
793 if (const auto &C
= U
->getStringOffsetsTableContribution())
794 Contributions
.push_back(C
);
795 // Sort the contributions so that any invalid ones are placed at
796 // the start of the contributions vector. This way they are reported
798 llvm::sort(Contributions
,
799 [](const std::optional
<StrOffsetsContributionDescriptor
> &L
,
800 const std::optional
<StrOffsetsContributionDescriptor
> &R
) {
802 return L
->Base
< R
->Base
;
803 return R
.has_value();
806 // Uniquify contributions, as it is possible that units (specifically
807 // type units in dwo or dwp files) share contributions. We don't want
808 // to report them more than once.
810 std::unique(Contributions
.begin(), Contributions
.end(),
811 [](const std::optional
<StrOffsetsContributionDescriptor
> &L
,
812 const std::optional
<StrOffsetsContributionDescriptor
> &R
) {
814 return L
->Base
== R
->Base
&& L
->Size
== R
->Size
;
817 Contributions
.end());
818 return Contributions
;
821 // Dump a DWARF string offsets section. This may be a DWARF v5 formatted
822 // string offsets section, where each compile or type unit contributes a
823 // number of entries (string offsets), with each contribution preceded by
824 // a header containing size and version number. Alternatively, it may be a
825 // monolithic series of string offsets, as generated by the pre-DWARF v5
826 // implementation of split DWARF; however, in that case we still need to
827 // collect contributions of units because the size of the offsets (4 or 8
828 // bytes) depends on the format of the referencing unit (DWARF32 or DWARF64).
829 static void dumpStringOffsetsSection(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
830 StringRef SectionName
,
831 const DWARFObject
&Obj
,
832 const DWARFSection
&StringOffsetsSection
,
833 StringRef StringSection
,
834 DWARFContext::unit_iterator_range Units
,
836 auto Contributions
= collectContributionData(Units
);
837 DWARFDataExtractor
StrOffsetExt(Obj
, StringOffsetsSection
, LittleEndian
, 0);
838 DataExtractor
StrData(StringSection
, LittleEndian
, 0);
839 uint64_t SectionSize
= StringOffsetsSection
.Data
.size();
841 for (auto &Contribution
: Contributions
) {
842 // Report an ill-formed contribution.
844 OS
<< "error: invalid contribution to string offsets table in section ."
845 << SectionName
<< ".\n";
849 dwarf::DwarfFormat Format
= Contribution
->getFormat();
850 int OffsetDumpWidth
= 2 * dwarf::getDwarfOffsetByteSize(Format
);
851 uint16_t Version
= Contribution
->getVersion();
852 uint64_t ContributionHeader
= Contribution
->Base
;
853 // In DWARF v5 there is a contribution header that immediately precedes
854 // the string offsets base (the location we have previously retrieved from
855 // the CU DIE's DW_AT_str_offsets attribute). The header is located either
856 // 8 or 16 bytes before the base, depending on the contribution's format.
858 ContributionHeader
-= Format
== DWARF32
? 8 : 16;
860 // Detect overlapping contributions.
861 if (Offset
> ContributionHeader
) {
862 DumpOpts
.RecoverableErrorHandler(createStringError(
863 errc::invalid_argument
,
864 "overlapping contributions to string offsets table in section .%s.",
865 SectionName
.data()));
867 // Report a gap in the table.
868 if (Offset
< ContributionHeader
) {
869 OS
<< format("0x%8.8" PRIx64
": Gap, length = ", Offset
);
870 OS
<< (ContributionHeader
- Offset
) << "\n";
872 OS
<< format("0x%8.8" PRIx64
": ", ContributionHeader
);
873 // In DWARF v5 the contribution size in the descriptor does not equal
874 // the originally encoded length (it does not contain the length of the
875 // version field and the padding, a total of 4 bytes). Add them back in
877 OS
<< "Contribution size = " << (Contribution
->Size
+ (Version
< 5 ? 0 : 4))
878 << ", Format = " << dwarf::FormatString(Format
)
879 << ", Version = " << Version
<< "\n";
881 Offset
= Contribution
->Base
;
882 unsigned EntrySize
= Contribution
->getDwarfOffsetByteSize();
883 while (Offset
- Contribution
->Base
< Contribution
->Size
) {
884 OS
<< format("0x%8.8" PRIx64
": ", Offset
);
885 uint64_t StringOffset
=
886 StrOffsetExt
.getRelocatedValue(EntrySize
, &Offset
);
887 OS
<< format("%0*" PRIx64
" ", OffsetDumpWidth
, StringOffset
);
888 const char *S
= StrData
.getCStr(&StringOffset
);
890 OS
<< format("\"%s\"", S
);
894 // Report a gap at the end of the table.
895 if (Offset
< SectionSize
) {
896 OS
<< format("0x%8.8" PRIx64
": Gap, length = ", Offset
);
897 OS
<< (SectionSize
- Offset
) << "\n";
901 // Dump the .debug_addr section.
902 static void dumpAddrSection(raw_ostream
&OS
, DWARFDataExtractor
&AddrData
,
903 DIDumpOptions DumpOpts
, uint16_t Version
,
906 while (AddrData
.isValidOffset(Offset
)) {
907 DWARFDebugAddrTable AddrTable
;
908 uint64_t TableOffset
= Offset
;
909 if (Error Err
= AddrTable
.extract(AddrData
, &Offset
, Version
, AddrSize
,
910 DumpOpts
.WarningHandler
)) {
911 DumpOpts
.RecoverableErrorHandler(std::move(Err
));
912 // Keep going after an error, if we can, assuming that the length field
913 // could be read. If it couldn't, stop reading the section.
914 if (auto TableLength
= AddrTable
.getFullLength()) {
915 Offset
= TableOffset
+ *TableLength
;
920 AddrTable
.dump(OS
, DumpOpts
);
924 // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
925 static void dumpRnglistsSection(
926 raw_ostream
&OS
, DWARFDataExtractor
&rnglistData
,
927 llvm::function_ref
<std::optional
<object::SectionedAddress
>(uint32_t)>
929 DIDumpOptions DumpOpts
) {
931 while (rnglistData
.isValidOffset(Offset
)) {
932 llvm::DWARFDebugRnglistTable Rnglists
;
933 uint64_t TableOffset
= Offset
;
934 if (Error Err
= Rnglists
.extract(rnglistData
, &Offset
)) {
935 DumpOpts
.RecoverableErrorHandler(std::move(Err
));
936 uint64_t Length
= Rnglists
.length();
937 // Keep going after an error, if we can, assuming that the length field
938 // could be read. If it couldn't, stop reading the section.
941 Offset
= TableOffset
+ Length
;
943 Rnglists
.dump(rnglistData
, OS
, LookupPooledAddress
, DumpOpts
);
949 static void dumpLoclistsSection(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
950 DWARFDataExtractor Data
, const DWARFObject
&Obj
,
951 std::optional
<uint64_t> DumpOffset
) {
954 while (Data
.isValidOffset(Offset
)) {
955 DWARFListTableHeader
Header(".debug_loclists", "locations");
956 if (Error E
= Header
.extract(Data
, &Offset
)) {
957 DumpOpts
.RecoverableErrorHandler(std::move(E
));
961 Header
.dump(Data
, OS
, DumpOpts
);
963 uint64_t EndOffset
= Header
.length() + Header
.getHeaderOffset();
964 Data
.setAddressSize(Header
.getAddrSize());
965 DWARFDebugLoclists
Loc(Data
, Header
.getVersion());
967 if (DumpOffset
>= Offset
&& DumpOffset
< EndOffset
) {
968 Offset
= *DumpOffset
;
969 Loc
.dumpLocationList(&Offset
, OS
, /*BaseAddr=*/std::nullopt
, Obj
,
970 nullptr, DumpOpts
, /*Indent=*/0);
975 Loc
.dumpRange(Offset
, EndOffset
- Offset
, OS
, Obj
, DumpOpts
);
981 static void dumpPubTableSection(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
982 DWARFDataExtractor Data
, bool GnuStyle
) {
983 DWARFDebugPubTable Table
;
984 Table
.extract(Data
, GnuStyle
, DumpOpts
.RecoverableErrorHandler
);
988 void DWARFContext::dump(
989 raw_ostream
&OS
, DIDumpOptions DumpOpts
,
990 std::array
<std::optional
<uint64_t>, DIDT_ID_Count
> DumpOffsets
) {
991 uint64_t DumpType
= DumpOpts
.DumpType
;
993 StringRef Extension
= sys::path::extension(DObj
->getFileName());
994 bool IsDWO
= (Extension
== ".dwo") || (Extension
== ".dwp");
996 // Print UUID header.
997 const auto *ObjFile
= DObj
->getFile();
998 if (DumpType
& DIDT_UUID
)
999 dumpUUID(OS
, *ObjFile
);
1001 // Print a header for each explicitly-requested section.
1002 // Otherwise just print one for non-empty sections.
1003 // Only print empty .dwo section headers when dumping a .dwo file.
1004 bool Explicit
= DumpType
!= DIDT_All
&& !IsDWO
;
1005 bool ExplicitDWO
= Explicit
&& IsDWO
;
1006 auto shouldDump
= [&](bool Explicit
, const char *Name
, unsigned ID
,
1007 StringRef Section
) -> std::optional
<uint64_t> * {
1008 unsigned Mask
= 1U << ID
;
1009 bool Should
= (DumpType
& Mask
) && (Explicit
|| !Section
.empty());
1012 OS
<< "\n" << Name
<< " contents:\n";
1013 return &DumpOffsets
[ID
];
1016 // Dump individual sections.
1017 if (shouldDump(Explicit
, ".debug_abbrev", DIDT_ID_DebugAbbrev
,
1018 DObj
->getAbbrevSection()))
1019 getDebugAbbrev()->dump(OS
);
1020 if (shouldDump(ExplicitDWO
, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev
,
1021 DObj
->getAbbrevDWOSection()))
1022 getDebugAbbrevDWO()->dump(OS
);
1024 auto dumpDebugInfo
= [&](const char *Name
, unit_iterator_range Units
) {
1025 OS
<< '\n' << Name
<< " contents:\n";
1026 if (auto DumpOffset
= DumpOffsets
[DIDT_ID_DebugInfo
])
1027 for (const auto &U
: Units
) {
1028 U
->getDIEForOffset(*DumpOffset
)
1029 .dump(OS
, 0, DumpOpts
.noImplicitRecursion());
1030 DWARFDie CUDie
= U
->getUnitDIE(false);
1031 DWARFDie CUNonSkeletonDie
= U
->getNonSkeletonUnitDIE(false);
1032 if (CUNonSkeletonDie
&& CUDie
!= CUNonSkeletonDie
) {
1033 CUNonSkeletonDie
.getDwarfUnit()
1034 ->getDIEForOffset(*DumpOffset
)
1035 .dump(OS
, 0, DumpOpts
.noImplicitRecursion());
1039 for (const auto &U
: Units
)
1040 U
->dump(OS
, DumpOpts
);
1042 if ((DumpType
& DIDT_DebugInfo
)) {
1043 if (Explicit
|| getNumCompileUnits())
1044 dumpDebugInfo(".debug_info", info_section_units());
1045 if (ExplicitDWO
|| getNumDWOCompileUnits())
1046 dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
1049 auto dumpDebugType
= [&](const char *Name
, unit_iterator_range Units
) {
1050 OS
<< '\n' << Name
<< " contents:\n";
1051 for (const auto &U
: Units
)
1052 if (auto DumpOffset
= DumpOffsets
[DIDT_ID_DebugTypes
])
1053 U
->getDIEForOffset(*DumpOffset
)
1054 .dump(OS
, 0, DumpOpts
.noImplicitRecursion());
1056 U
->dump(OS
, DumpOpts
);
1058 if ((DumpType
& DIDT_DebugTypes
)) {
1059 if (Explicit
|| getNumTypeUnits())
1060 dumpDebugType(".debug_types", types_section_units());
1061 if (ExplicitDWO
|| getNumDWOTypeUnits())
1062 dumpDebugType(".debug_types.dwo", dwo_types_section_units());
1065 DIDumpOptions LLDumpOpts
= DumpOpts
;
1066 if (LLDumpOpts
.Verbose
)
1067 LLDumpOpts
.DisplayRawContents
= true;
1069 if (const auto *Off
= shouldDump(Explicit
, ".debug_loc", DIDT_ID_DebugLoc
,
1070 DObj
->getLocSection().Data
)) {
1071 getDebugLoc()->dump(OS
, *DObj
, LLDumpOpts
, *Off
);
1073 if (const auto *Off
=
1074 shouldDump(Explicit
, ".debug_loclists", DIDT_ID_DebugLoclists
,
1075 DObj
->getLoclistsSection().Data
)) {
1076 DWARFDataExtractor
Data(*DObj
, DObj
->getLoclistsSection(), isLittleEndian(),
1078 dumpLoclistsSection(OS
, LLDumpOpts
, Data
, *DObj
, *Off
);
1080 if (const auto *Off
=
1081 shouldDump(ExplicitDWO
, ".debug_loclists.dwo", DIDT_ID_DebugLoclists
,
1082 DObj
->getLoclistsDWOSection().Data
)) {
1083 DWARFDataExtractor
Data(*DObj
, DObj
->getLoclistsDWOSection(),
1084 isLittleEndian(), 0);
1085 dumpLoclistsSection(OS
, LLDumpOpts
, Data
, *DObj
, *Off
);
1088 if (const auto *Off
=
1089 shouldDump(ExplicitDWO
, ".debug_loc.dwo", DIDT_ID_DebugLoc
,
1090 DObj
->getLocDWOSection().Data
)) {
1091 DWARFDataExtractor
Data(*DObj
, DObj
->getLocDWOSection(), isLittleEndian(),
1093 DWARFDebugLoclists
Loc(Data
, /*Version=*/4);
1095 uint64_t Offset
= **Off
;
1096 Loc
.dumpLocationList(&Offset
, OS
,
1097 /*BaseAddr=*/std::nullopt
, *DObj
, nullptr,
1102 Loc
.dumpRange(0, Data
.getData().size(), OS
, *DObj
, LLDumpOpts
);
1106 if (const std::optional
<uint64_t> *Off
=
1107 shouldDump(Explicit
, ".debug_frame", DIDT_ID_DebugFrame
,
1108 DObj
->getFrameSection().Data
)) {
1109 if (Expected
<const DWARFDebugFrame
*> DF
= getDebugFrame())
1110 (*DF
)->dump(OS
, DumpOpts
, *Off
);
1112 RecoverableErrorHandler(DF
.takeError());
1115 if (const std::optional
<uint64_t> *Off
=
1116 shouldDump(Explicit
, ".eh_frame", DIDT_ID_DebugFrame
,
1117 DObj
->getEHFrameSection().Data
)) {
1118 if (Expected
<const DWARFDebugFrame
*> DF
= getEHFrame())
1119 (*DF
)->dump(OS
, DumpOpts
, *Off
);
1121 RecoverableErrorHandler(DF
.takeError());
1124 if (shouldDump(Explicit
, ".debug_macro", DIDT_ID_DebugMacro
,
1125 DObj
->getMacroSection().Data
)) {
1126 if (auto Macro
= getDebugMacro())
1130 if (shouldDump(Explicit
, ".debug_macro.dwo", DIDT_ID_DebugMacro
,
1131 DObj
->getMacroDWOSection())) {
1132 if (auto MacroDWO
= getDebugMacroDWO())
1136 if (shouldDump(Explicit
, ".debug_macinfo", DIDT_ID_DebugMacro
,
1137 DObj
->getMacinfoSection())) {
1138 if (auto Macinfo
= getDebugMacinfo())
1142 if (shouldDump(Explicit
, ".debug_macinfo.dwo", DIDT_ID_DebugMacro
,
1143 DObj
->getMacinfoDWOSection())) {
1144 if (auto MacinfoDWO
= getDebugMacinfoDWO())
1145 MacinfoDWO
->dump(OS
);
1148 if (shouldDump(Explicit
, ".debug_aranges", DIDT_ID_DebugAranges
,
1149 DObj
->getArangesSection())) {
1150 uint64_t offset
= 0;
1151 DWARFDataExtractor
arangesData(DObj
->getArangesSection(), isLittleEndian(),
1153 DWARFDebugArangeSet set
;
1154 while (arangesData
.isValidOffset(offset
)) {
1156 set
.extract(arangesData
, &offset
, DumpOpts
.WarningHandler
)) {
1157 RecoverableErrorHandler(std::move(E
));
1164 auto DumpLineSection
= [&](DWARFDebugLine::SectionParser Parser
,
1165 DIDumpOptions DumpOpts
,
1166 std::optional
<uint64_t> DumpOffset
) {
1167 while (!Parser
.done()) {
1168 if (DumpOffset
&& Parser
.getOffset() != *DumpOffset
) {
1169 Parser
.skip(DumpOpts
.WarningHandler
, DumpOpts
.WarningHandler
);
1172 OS
<< "debug_line[" << format("0x%8.8" PRIx64
, Parser
.getOffset())
1174 Parser
.parseNext(DumpOpts
.WarningHandler
, DumpOpts
.WarningHandler
, &OS
,
1179 auto DumpStrSection
= [&](StringRef Section
) {
1180 DataExtractor
StrData(Section
, isLittleEndian(), 0);
1181 uint64_t Offset
= 0;
1182 uint64_t StrOffset
= 0;
1183 while (StrData
.isValidOffset(Offset
)) {
1184 Error Err
= Error::success();
1185 const char *CStr
= StrData
.getCStr(&Offset
, &Err
);
1187 DumpOpts
.WarningHandler(std::move(Err
));
1190 OS
<< format("0x%8.8" PRIx64
": \"", StrOffset
);
1191 OS
.write_escaped(CStr
);
1197 if (const auto *Off
= shouldDump(Explicit
, ".debug_line", DIDT_ID_DebugLine
,
1198 DObj
->getLineSection().Data
)) {
1199 DWARFDataExtractor
LineData(*DObj
, DObj
->getLineSection(), isLittleEndian(),
1201 DWARFDebugLine::SectionParser
Parser(LineData
, *this, normal_units());
1202 DumpLineSection(Parser
, DumpOpts
, *Off
);
1205 if (const auto *Off
=
1206 shouldDump(ExplicitDWO
, ".debug_line.dwo", DIDT_ID_DebugLine
,
1207 DObj
->getLineDWOSection().Data
)) {
1208 DWARFDataExtractor
LineData(*DObj
, DObj
->getLineDWOSection(),
1209 isLittleEndian(), 0);
1210 DWARFDebugLine::SectionParser
Parser(LineData
, *this, dwo_units());
1211 DumpLineSection(Parser
, DumpOpts
, *Off
);
1214 if (shouldDump(Explicit
, ".debug_cu_index", DIDT_ID_DebugCUIndex
,
1215 DObj
->getCUIndexSection())) {
1216 getCUIndex().dump(OS
);
1219 if (shouldDump(Explicit
, ".debug_tu_index", DIDT_ID_DebugTUIndex
,
1220 DObj
->getTUIndexSection())) {
1221 getTUIndex().dump(OS
);
1224 if (shouldDump(Explicit
, ".debug_str", DIDT_ID_DebugStr
,
1225 DObj
->getStrSection()))
1226 DumpStrSection(DObj
->getStrSection());
1228 if (shouldDump(ExplicitDWO
, ".debug_str.dwo", DIDT_ID_DebugStr
,
1229 DObj
->getStrDWOSection()))
1230 DumpStrSection(DObj
->getStrDWOSection());
1232 if (shouldDump(Explicit
, ".debug_line_str", DIDT_ID_DebugLineStr
,
1233 DObj
->getLineStrSection()))
1234 DumpStrSection(DObj
->getLineStrSection());
1236 if (shouldDump(Explicit
, ".debug_addr", DIDT_ID_DebugAddr
,
1237 DObj
->getAddrSection().Data
)) {
1238 DWARFDataExtractor
AddrData(*DObj
, DObj
->getAddrSection(),
1239 isLittleEndian(), 0);
1240 dumpAddrSection(OS
, AddrData
, DumpOpts
, getMaxVersion(), getCUAddrSize());
1243 if (shouldDump(Explicit
, ".debug_ranges", DIDT_ID_DebugRanges
,
1244 DObj
->getRangesSection().Data
)) {
1245 uint8_t savedAddressByteSize
= getCUAddrSize();
1246 DWARFDataExtractor
rangesData(*DObj
, DObj
->getRangesSection(),
1247 isLittleEndian(), savedAddressByteSize
);
1248 uint64_t offset
= 0;
1249 DWARFDebugRangeList rangeList
;
1250 while (rangesData
.isValidOffset(offset
)) {
1251 if (Error E
= rangeList
.extract(rangesData
, &offset
)) {
1252 DumpOpts
.RecoverableErrorHandler(std::move(E
));
1259 auto LookupPooledAddress
=
1260 [&](uint32_t Index
) -> std::optional
<SectionedAddress
> {
1261 const auto &CUs
= compile_units();
1262 auto I
= CUs
.begin();
1264 return std::nullopt
;
1265 return (*I
)->getAddrOffsetSectionItem(Index
);
1268 if (shouldDump(Explicit
, ".debug_rnglists", DIDT_ID_DebugRnglists
,
1269 DObj
->getRnglistsSection().Data
)) {
1270 DWARFDataExtractor
RnglistData(*DObj
, DObj
->getRnglistsSection(),
1271 isLittleEndian(), 0);
1272 dumpRnglistsSection(OS
, RnglistData
, LookupPooledAddress
, DumpOpts
);
1275 if (shouldDump(ExplicitDWO
, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists
,
1276 DObj
->getRnglistsDWOSection().Data
)) {
1277 DWARFDataExtractor
RnglistData(*DObj
, DObj
->getRnglistsDWOSection(),
1278 isLittleEndian(), 0);
1279 dumpRnglistsSection(OS
, RnglistData
, LookupPooledAddress
, DumpOpts
);
1282 if (shouldDump(Explicit
, ".debug_pubnames", DIDT_ID_DebugPubnames
,
1283 DObj
->getPubnamesSection().Data
)) {
1284 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getPubnamesSection(),
1285 isLittleEndian(), 0);
1286 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/false);
1289 if (shouldDump(Explicit
, ".debug_pubtypes", DIDT_ID_DebugPubtypes
,
1290 DObj
->getPubtypesSection().Data
)) {
1291 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getPubtypesSection(),
1292 isLittleEndian(), 0);
1293 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/false);
1296 if (shouldDump(Explicit
, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames
,
1297 DObj
->getGnuPubnamesSection().Data
)) {
1298 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getGnuPubnamesSection(),
1299 isLittleEndian(), 0);
1300 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/true);
1303 if (shouldDump(Explicit
, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes
,
1304 DObj
->getGnuPubtypesSection().Data
)) {
1305 DWARFDataExtractor
PubTableData(*DObj
, DObj
->getGnuPubtypesSection(),
1306 isLittleEndian(), 0);
1307 dumpPubTableSection(OS
, DumpOpts
, PubTableData
, /*GnuStyle=*/true);
1310 if (shouldDump(Explicit
, ".debug_str_offsets", DIDT_ID_DebugStrOffsets
,
1311 DObj
->getStrOffsetsSection().Data
))
1312 dumpStringOffsetsSection(
1313 OS
, DumpOpts
, "debug_str_offsets", *DObj
, DObj
->getStrOffsetsSection(),
1314 DObj
->getStrSection(), normal_units(), isLittleEndian());
1315 if (shouldDump(ExplicitDWO
, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets
,
1316 DObj
->getStrOffsetsDWOSection().Data
))
1317 dumpStringOffsetsSection(OS
, DumpOpts
, "debug_str_offsets.dwo", *DObj
,
1318 DObj
->getStrOffsetsDWOSection(),
1319 DObj
->getStrDWOSection(), dwo_units(),
1322 if (shouldDump(Explicit
, ".gdb_index", DIDT_ID_GdbIndex
,
1323 DObj
->getGdbIndexSection())) {
1324 getGdbIndex().dump(OS
);
1327 if (shouldDump(Explicit
, ".apple_names", DIDT_ID_AppleNames
,
1328 DObj
->getAppleNamesSection().Data
))
1329 getAppleNames().dump(OS
);
1331 if (shouldDump(Explicit
, ".apple_types", DIDT_ID_AppleTypes
,
1332 DObj
->getAppleTypesSection().Data
))
1333 getAppleTypes().dump(OS
);
1335 if (shouldDump(Explicit
, ".apple_namespaces", DIDT_ID_AppleNamespaces
,
1336 DObj
->getAppleNamespacesSection().Data
))
1337 getAppleNamespaces().dump(OS
);
1339 if (shouldDump(Explicit
, ".apple_objc", DIDT_ID_AppleObjC
,
1340 DObj
->getAppleObjCSection().Data
))
1341 getAppleObjC().dump(OS
);
1342 if (shouldDump(Explicit
, ".debug_names", DIDT_ID_DebugNames
,
1343 DObj
->getNamesSection().Data
))
1344 getDebugNames().dump(OS
);
1347 DWARFTypeUnit
*DWARFContext::getTypeUnitForHash(uint16_t Version
, uint64_t Hash
,
1349 DWARFUnitVector
&DWOUnits
= State
->getDWOUnits();
1350 if (const auto &TUI
= getTUIndex()) {
1351 if (const auto *R
= TUI
.getFromHash(Hash
))
1352 return dyn_cast_or_null
<DWARFTypeUnit
>(
1353 DWOUnits
.getUnitForIndexEntry(*R
));
1356 return State
->getTypeUnitMap(IsDWO
).lookup(Hash
);
1359 DWARFCompileUnit
*DWARFContext::getDWOCompileUnitForHash(uint64_t Hash
) {
1360 DWARFUnitVector
&DWOUnits
= State
->getDWOUnits(LazyParse
);
1362 if (const auto &CUI
= getCUIndex()) {
1363 if (const auto *R
= CUI
.getFromHash(Hash
))
1364 return dyn_cast_or_null
<DWARFCompileUnit
>(
1365 DWOUnits
.getUnitForIndexEntry(*R
));
1369 // If there's no index, just search through the CUs in the DWO - there's
1370 // probably only one unless this is something like LTO - though an in-process
1371 // built/cached lookup table could be used in that case to improve repeated
1372 // lookups of different CUs in the DWO.
1373 for (const auto &DWOCU
: dwo_compile_units()) {
1374 // Might not have parsed DWO ID yet.
1375 if (!DWOCU
->getDWOId()) {
1376 if (std::optional
<uint64_t> DWOId
=
1377 toUnsigned(DWOCU
->getUnitDIE().find(DW_AT_GNU_dwo_id
)))
1378 DWOCU
->setDWOId(*DWOId
);
1383 if (DWOCU
->getDWOId() == Hash
)
1384 return dyn_cast
<DWARFCompileUnit
>(DWOCU
.get());
1389 DWARFDie
DWARFContext::getDIEForOffset(uint64_t Offset
) {
1390 if (auto *CU
= State
->getNormalUnits().getUnitForOffset(Offset
))
1391 return CU
->getDIEForOffset(Offset
);
1395 bool DWARFContext::verify(raw_ostream
&OS
, DIDumpOptions DumpOpts
) {
1396 bool Success
= true;
1397 DWARFVerifier
verifier(OS
, *this, DumpOpts
);
1399 Success
&= verifier
.handleDebugAbbrev();
1400 if (DumpOpts
.DumpType
& DIDT_DebugCUIndex
)
1401 Success
&= verifier
.handleDebugCUIndex();
1402 if (DumpOpts
.DumpType
& DIDT_DebugTUIndex
)
1403 Success
&= verifier
.handleDebugTUIndex();
1404 if (DumpOpts
.DumpType
& DIDT_DebugInfo
)
1405 Success
&= verifier
.handleDebugInfo();
1406 if (DumpOpts
.DumpType
& DIDT_DebugLine
)
1407 Success
&= verifier
.handleDebugLine();
1408 if (DumpOpts
.DumpType
& DIDT_DebugStrOffsets
)
1409 Success
&= verifier
.handleDebugStrOffsets();
1410 Success
&= verifier
.handleAccelTables();
1414 const DWARFUnitIndex
&DWARFContext::getCUIndex() {
1415 return State
->getCUIndex();
1418 const DWARFUnitIndex
&DWARFContext::getTUIndex() {
1419 return State
->getTUIndex();
1422 DWARFGdbIndex
&DWARFContext::getGdbIndex() {
1423 return State
->getGdbIndex();
1426 const DWARFDebugAbbrev
*DWARFContext::getDebugAbbrev() {
1427 return State
->getDebugAbbrev();
1430 const DWARFDebugAbbrev
*DWARFContext::getDebugAbbrevDWO() {
1431 return State
->getDebugAbbrevDWO();
1434 const DWARFDebugLoc
*DWARFContext::getDebugLoc() {
1435 return State
->getDebugLoc();
1438 const DWARFDebugAranges
*DWARFContext::getDebugAranges() {
1439 return State
->getDebugAranges();
1442 Expected
<const DWARFDebugFrame
*> DWARFContext::getDebugFrame() {
1443 return State
->getDebugFrame();
1446 Expected
<const DWARFDebugFrame
*> DWARFContext::getEHFrame() {
1447 return State
->getEHFrame();
1450 const DWARFDebugMacro
*DWARFContext::getDebugMacro() {
1451 return State
->getDebugMacro();
1454 const DWARFDebugMacro
*DWARFContext::getDebugMacroDWO() {
1455 return State
->getDebugMacroDWO();
1458 const DWARFDebugMacro
*DWARFContext::getDebugMacinfo() {
1459 return State
->getDebugMacinfo();
1462 const DWARFDebugMacro
*DWARFContext::getDebugMacinfoDWO() {
1463 return State
->getDebugMacinfoDWO();
1467 const DWARFDebugNames
&DWARFContext::getDebugNames() {
1468 return State
->getDebugNames();
1471 const AppleAcceleratorTable
&DWARFContext::getAppleNames() {
1472 return State
->getAppleNames();
1475 const AppleAcceleratorTable
&DWARFContext::getAppleTypes() {
1476 return State
->getAppleTypes();
1479 const AppleAcceleratorTable
&DWARFContext::getAppleNamespaces() {
1480 return State
->getAppleNamespaces();
1483 const AppleAcceleratorTable
&DWARFContext::getAppleObjC() {
1484 return State
->getAppleObjC();
1487 const DWARFDebugLine::LineTable
*
1488 DWARFContext::getLineTableForUnit(DWARFUnit
*U
) {
1489 Expected
<const DWARFDebugLine::LineTable
*> ExpectedLineTable
=
1490 getLineTableForUnit(U
, WarningHandler
);
1491 if (!ExpectedLineTable
) {
1492 WarningHandler(ExpectedLineTable
.takeError());
1495 return *ExpectedLineTable
;
1498 Expected
<const DWARFDebugLine::LineTable
*> DWARFContext::getLineTableForUnit(
1499 DWARFUnit
*U
, function_ref
<void(Error
)> RecoverableErrorHandler
) {
1500 return State
->getLineTableForUnit(U
, RecoverableErrorHandler
);
1503 void DWARFContext::clearLineTableForUnit(DWARFUnit
*U
) {
1504 return State
->clearLineTableForUnit(U
);
1507 DWARFUnitVector
&DWARFContext::getDWOUnits(bool Lazy
) {
1508 return State
->getDWOUnits(Lazy
);
1511 DWARFCompileUnit
*DWARFContext::getCompileUnitForOffset(uint64_t Offset
) {
1512 return dyn_cast_or_null
<DWARFCompileUnit
>(
1513 State
->getNormalUnits().getUnitForOffset(Offset
));
1516 DWARFCompileUnit
*DWARFContext::getCompileUnitForCodeAddress(uint64_t Address
) {
1517 uint64_t CUOffset
= getDebugAranges()->findAddress(Address
);
1518 return getCompileUnitForOffset(CUOffset
);
1521 DWARFCompileUnit
*DWARFContext::getCompileUnitForDataAddress(uint64_t Address
) {
1522 uint64_t CUOffset
= getDebugAranges()->findAddress(Address
);
1523 if (DWARFCompileUnit
*OffsetCU
= getCompileUnitForOffset(CUOffset
))
1526 // Global variables are often missed by the above search, for one of two
1528 // 1. .debug_aranges may not include global variables. On clang, it seems we
1529 // put the globals in the aranges, but this isn't true for gcc.
1530 // 2. Even if the global variable is in a .debug_arange, global variables
1531 // may not be captured in the [start, end) addresses described by the
1532 // parent compile unit.
1534 // So, we walk the CU's and their child DI's manually, looking for the
1535 // specific global variable.
1536 for (std::unique_ptr
<DWARFUnit
> &CU
: compile_units()) {
1537 if (CU
->getVariableForAddress(Address
)) {
1538 return static_cast<DWARFCompileUnit
*>(CU
.get());
1544 DWARFContext::DIEsForAddress
DWARFContext::getDIEsForAddress(uint64_t Address
,
1546 DIEsForAddress Result
;
1548 DWARFCompileUnit
*CU
= getCompileUnitForCodeAddress(Address
);
1553 // We were asked to check the DWO file and this debug information is more
1554 // complete that any information in the skeleton compile unit, so search the
1555 // DWO first to see if we have a match.
1556 DWARFDie CUDie
= CU
->getUnitDIE(false);
1557 DWARFDie CUDwoDie
= CU
->getNonSkeletonUnitDIE(false);
1558 if (CheckDWO
&& CUDwoDie
&& CUDie
!= CUDwoDie
) {
1559 // We have a DWO file, lets search it.
1560 DWARFCompileUnit
*CUDwo
=
1561 dyn_cast_or_null
<DWARFCompileUnit
>(CUDwoDie
.getDwarfUnit());
1563 Result
.FunctionDIE
= CUDwo
->getSubroutineForAddress(Address
);
1564 if (Result
.FunctionDIE
)
1565 Result
.CompileUnit
= CUDwo
;
1570 // Search the normal DWARF if we didn't find a match in the DWO file or if
1571 // we didn't check the DWO file above.
1573 Result
.CompileUnit
= CU
;
1574 Result
.FunctionDIE
= CU
->getSubroutineForAddress(Address
);
1577 std::vector
<DWARFDie
> Worklist
;
1578 Worklist
.push_back(Result
.FunctionDIE
);
1579 while (!Worklist
.empty()) {
1580 DWARFDie DIE
= Worklist
.back();
1581 Worklist
.pop_back();
1586 if (DIE
.getTag() == DW_TAG_lexical_block
&&
1587 DIE
.addressRangeContainsAddress(Address
)) {
1588 Result
.BlockDIE
= DIE
;
1592 append_range(Worklist
, DIE
);
1598 /// TODO: change input parameter from "uint64_t Address"
1599 /// into "SectionedAddress Address"
1600 static bool getFunctionNameAndStartLineForAddress(
1601 DWARFCompileUnit
*CU
, uint64_t Address
, FunctionNameKind Kind
,
1602 DILineInfoSpecifier::FileLineInfoKind FileNameKind
,
1603 std::string
&FunctionName
, std::string
&StartFile
, uint32_t &StartLine
,
1604 std::optional
<uint64_t> &StartAddress
) {
1605 // The address may correspond to instruction in some inlined function,
1606 // so we have to build the chain of inlined functions and take the
1607 // name of the topmost function in it.
1608 SmallVector
<DWARFDie
, 4> InlinedChain
;
1609 CU
->getInlinedChainForAddress(Address
, InlinedChain
);
1610 if (InlinedChain
.empty())
1613 const DWARFDie
&DIE
= InlinedChain
[0];
1614 bool FoundResult
= false;
1615 const char *Name
= nullptr;
1616 if (Kind
!= FunctionNameKind::None
&& (Name
= DIE
.getSubroutineName(Kind
))) {
1617 FunctionName
= Name
;
1620 std::string DeclFile
= DIE
.getDeclFile(FileNameKind
);
1621 if (!DeclFile
.empty()) {
1622 StartFile
= DeclFile
;
1625 if (auto DeclLineResult
= DIE
.getDeclLine()) {
1626 StartLine
= DeclLineResult
;
1629 if (auto LowPcAddr
= toSectionedAddress(DIE
.find(DW_AT_low_pc
)))
1630 StartAddress
= LowPcAddr
->Address
;
1634 static std::optional
<int64_t>
1635 getExpressionFrameOffset(ArrayRef
<uint8_t> Expr
,
1636 std::optional
<unsigned> FrameBaseReg
) {
1637 if (!Expr
.empty() &&
1638 (Expr
[0] == DW_OP_fbreg
||
1639 (FrameBaseReg
&& Expr
[0] == DW_OP_breg0
+ *FrameBaseReg
))) {
1641 int64_t Offset
= decodeSLEB128(Expr
.data() + 1, &Count
, Expr
.end());
1642 // A single DW_OP_fbreg or DW_OP_breg.
1643 if (Expr
.size() == Count
+ 1)
1645 // Same + DW_OP_deref (Fortran arrays look like this).
1646 if (Expr
.size() == Count
+ 2 && Expr
[Count
+ 1] == DW_OP_deref
)
1648 // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value)
1650 return std::nullopt
;
1653 void DWARFContext::addLocalsForDie(DWARFCompileUnit
*CU
, DWARFDie Subprogram
,
1654 DWARFDie Die
, std::vector
<DILocal
> &Result
) {
1655 if (Die
.getTag() == DW_TAG_variable
||
1656 Die
.getTag() == DW_TAG_formal_parameter
) {
1658 if (const char *Name
= Subprogram
.getSubroutineName(DINameKind::ShortName
))
1659 Local
.FunctionName
= Name
;
1661 std::optional
<unsigned> FrameBaseReg
;
1662 if (auto FrameBase
= Subprogram
.find(DW_AT_frame_base
))
1663 if (std::optional
<ArrayRef
<uint8_t>> Expr
= FrameBase
->getAsBlock())
1664 if (!Expr
->empty() && (*Expr
)[0] >= DW_OP_reg0
&&
1665 (*Expr
)[0] <= DW_OP_reg31
) {
1666 FrameBaseReg
= (*Expr
)[0] - DW_OP_reg0
;
1669 if (Expected
<std::vector
<DWARFLocationExpression
>> Loc
=
1670 Die
.getLocations(DW_AT_location
)) {
1671 for (const auto &Entry
: *Loc
) {
1672 if (std::optional
<int64_t> FrameOffset
=
1673 getExpressionFrameOffset(Entry
.Expr
, FrameBaseReg
)) {
1674 Local
.FrameOffset
= *FrameOffset
;
1679 // FIXME: missing DW_AT_location is OK here, but other errors should be
1680 // reported to the user.
1681 consumeError(Loc
.takeError());
1684 if (auto TagOffsetAttr
= Die
.find(DW_AT_LLVM_tag_offset
))
1685 Local
.TagOffset
= TagOffsetAttr
->getAsUnsignedConstant();
1688 Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
1690 if (auto NameAttr
= Die
.find(DW_AT_name
))
1691 if (std::optional
<const char *> Name
= dwarf::toString(*NameAttr
))
1693 if (auto Type
= Die
.getAttributeValueAsReferencedDie(DW_AT_type
))
1694 Local
.Size
= Type
.getTypeSize(getCUAddrSize());
1695 if (auto DeclFileAttr
= Die
.find(DW_AT_decl_file
)) {
1696 if (const auto *LT
= CU
->getContext().getLineTableForUnit(CU
))
1697 LT
->getFileNameByIndex(
1698 *DeclFileAttr
->getAsUnsignedConstant(), CU
->getCompilationDir(),
1699 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
,
1702 if (auto DeclLineAttr
= Die
.find(DW_AT_decl_line
))
1703 Local
.DeclLine
= *DeclLineAttr
->getAsUnsignedConstant();
1705 Result
.push_back(Local
);
1709 if (Die
.getTag() == DW_TAG_inlined_subroutine
)
1711 Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
1712 Subprogram
= Origin
;
1714 for (auto Child
: Die
)
1715 addLocalsForDie(CU
, Subprogram
, Child
, Result
);
1718 std::vector
<DILocal
>
1719 DWARFContext::getLocalsForAddress(object::SectionedAddress Address
) {
1720 std::vector
<DILocal
> Result
;
1721 DWARFCompileUnit
*CU
= getCompileUnitForCodeAddress(Address
.Address
);
1725 DWARFDie Subprogram
= CU
->getSubroutineForAddress(Address
.Address
);
1726 if (Subprogram
.isValid())
1727 addLocalsForDie(CU
, Subprogram
, Subprogram
, Result
);
1731 DILineInfo
DWARFContext::getLineInfoForAddress(object::SectionedAddress Address
,
1732 DILineInfoSpecifier Spec
) {
1734 DWARFCompileUnit
*CU
= getCompileUnitForCodeAddress(Address
.Address
);
1738 getFunctionNameAndStartLineForAddress(
1739 CU
, Address
.Address
, Spec
.FNKind
, Spec
.FLIKind
, Result
.FunctionName
,
1740 Result
.StartFileName
, Result
.StartLine
, Result
.StartAddress
);
1741 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1742 if (const DWARFLineTable
*LineTable
= getLineTableForUnit(CU
)) {
1743 LineTable
->getFileLineInfoForAddress(
1744 {Address
.Address
, Address
.SectionIndex
}, CU
->getCompilationDir(),
1745 Spec
.FLIKind
, Result
);
1753 DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address
) {
1755 DWARFCompileUnit
*CU
= getCompileUnitForDataAddress(Address
.Address
);
1759 if (DWARFDie Die
= CU
->getVariableForAddress(Address
.Address
)) {
1760 Result
.FileName
= Die
.getDeclFile(FileLineInfoKind::AbsoluteFilePath
);
1761 Result
.Line
= Die
.getDeclLine();
1767 DILineInfoTable
DWARFContext::getLineInfoForAddressRange(
1768 object::SectionedAddress Address
, uint64_t Size
, DILineInfoSpecifier Spec
) {
1769 DILineInfoTable Lines
;
1770 DWARFCompileUnit
*CU
= getCompileUnitForCodeAddress(Address
.Address
);
1774 uint32_t StartLine
= 0;
1775 std::string StartFileName
;
1776 std::string
FunctionName(DILineInfo::BadString
);
1777 std::optional
<uint64_t> StartAddress
;
1778 getFunctionNameAndStartLineForAddress(CU
, Address
.Address
, Spec
.FNKind
,
1779 Spec
.FLIKind
, FunctionName
,
1780 StartFileName
, StartLine
, StartAddress
);
1782 // If the Specifier says we don't need FileLineInfo, just
1783 // return the top-most function at the starting address.
1784 if (Spec
.FLIKind
== FileLineInfoKind::None
) {
1786 Result
.FunctionName
= FunctionName
;
1787 Result
.StartFileName
= StartFileName
;
1788 Result
.StartLine
= StartLine
;
1789 Result
.StartAddress
= StartAddress
;
1790 Lines
.push_back(std::make_pair(Address
.Address
, Result
));
1794 const DWARFLineTable
*LineTable
= getLineTableForUnit(CU
);
1796 // Get the index of row we're looking for in the line table.
1797 std::vector
<uint32_t> RowVector
;
1798 if (!LineTable
->lookupAddressRange({Address
.Address
, Address
.SectionIndex
},
1803 for (uint32_t RowIndex
: RowVector
) {
1804 // Take file number and line/column from the row.
1805 const DWARFDebugLine::Row
&Row
= LineTable
->Rows
[RowIndex
];
1807 LineTable
->getFileNameByIndex(Row
.File
, CU
->getCompilationDir(),
1808 Spec
.FLIKind
, Result
.FileName
);
1809 Result
.FunctionName
= FunctionName
;
1810 Result
.Line
= Row
.Line
;
1811 Result
.Column
= Row
.Column
;
1812 Result
.StartFileName
= StartFileName
;
1813 Result
.StartLine
= StartLine
;
1814 Result
.StartAddress
= StartAddress
;
1815 Lines
.push_back(std::make_pair(Row
.Address
.Address
, Result
));
1822 DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address
,
1823 DILineInfoSpecifier Spec
) {
1824 DIInliningInfo InliningInfo
;
1826 DWARFCompileUnit
*CU
= getCompileUnitForCodeAddress(Address
.Address
);
1828 return InliningInfo
;
1830 const DWARFLineTable
*LineTable
= nullptr;
1831 SmallVector
<DWARFDie
, 4> InlinedChain
;
1832 CU
->getInlinedChainForAddress(Address
.Address
, InlinedChain
);
1833 if (InlinedChain
.size() == 0) {
1834 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
1835 // try to at least get file/line info from symbol table.
1836 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1838 LineTable
= getLineTableForUnit(CU
);
1839 if (LineTable
&& LineTable
->getFileLineInfoForAddress(
1840 {Address
.Address
, Address
.SectionIndex
},
1841 CU
->getCompilationDir(), Spec
.FLIKind
, Frame
))
1842 InliningInfo
.addFrame(Frame
);
1844 return InliningInfo
;
1847 uint32_t CallFile
= 0, CallLine
= 0, CallColumn
= 0, CallDiscriminator
= 0;
1848 for (uint32_t i
= 0, n
= InlinedChain
.size(); i
!= n
; i
++) {
1849 DWARFDie
&FunctionDIE
= InlinedChain
[i
];
1851 // Get function name if necessary.
1852 if (const char *Name
= FunctionDIE
.getSubroutineName(Spec
.FNKind
))
1853 Frame
.FunctionName
= Name
;
1854 if (auto DeclLineResult
= FunctionDIE
.getDeclLine())
1855 Frame
.StartLine
= DeclLineResult
;
1856 Frame
.StartFileName
= FunctionDIE
.getDeclFile(Spec
.FLIKind
);
1857 if (auto LowPcAddr
= toSectionedAddress(FunctionDIE
.find(DW_AT_low_pc
)))
1858 Frame
.StartAddress
= LowPcAddr
->Address
;
1859 if (Spec
.FLIKind
!= FileLineInfoKind::None
) {
1861 // For the topmost frame, initialize the line table of this
1862 // compile unit and fetch file/line info from it.
1863 LineTable
= getLineTableForUnit(CU
);
1864 // For the topmost routine, get file/line info from line table.
1866 LineTable
->getFileLineInfoForAddress(
1867 {Address
.Address
, Address
.SectionIndex
}, CU
->getCompilationDir(),
1868 Spec
.FLIKind
, Frame
);
1870 // Otherwise, use call file, call line and call column from
1871 // previous DIE in inlined chain.
1873 LineTable
->getFileNameByIndex(CallFile
, CU
->getCompilationDir(),
1874 Spec
.FLIKind
, Frame
.FileName
);
1875 Frame
.Line
= CallLine
;
1876 Frame
.Column
= CallColumn
;
1877 Frame
.Discriminator
= CallDiscriminator
;
1879 // Get call file/line/column of a current DIE.
1881 FunctionDIE
.getCallerFrame(CallFile
, CallLine
, CallColumn
,
1885 InliningInfo
.addFrame(Frame
);
1887 return InliningInfo
;
1890 std::shared_ptr
<DWARFContext
>
1891 DWARFContext::getDWOContext(StringRef AbsolutePath
) {
1892 return State
->getDWOContext(AbsolutePath
);
1895 static Error
createError(const Twine
&Reason
, llvm::Error E
) {
1896 return make_error
<StringError
>(Reason
+ toString(std::move(E
)),
1897 inconvertibleErrorCode());
1900 /// SymInfo contains information about symbol: it's address
1901 /// and section index which is -1LL for absolute symbols.
1904 uint64_t SectionIndex
;
1907 /// Returns the address of symbol relocation used against and a section index.
1908 /// Used for futher relocations computation. Symbol's section load address is
1909 static Expected
<SymInfo
> getSymbolInfo(const object::ObjectFile
&Obj
,
1910 const RelocationRef
&Reloc
,
1911 const LoadedObjectInfo
*L
,
1912 std::map
<SymbolRef
, SymInfo
> &Cache
) {
1913 SymInfo Ret
= {0, (uint64_t)-1LL};
1914 object::section_iterator RSec
= Obj
.section_end();
1915 object::symbol_iterator Sym
= Reloc
.getSymbol();
1917 std::map
<SymbolRef
, SymInfo
>::iterator CacheIt
= Cache
.end();
1918 // First calculate the address of the symbol or section as it appears
1919 // in the object file
1920 if (Sym
!= Obj
.symbol_end()) {
1922 std::tie(CacheIt
, New
) = Cache
.insert({*Sym
, {0, 0}});
1924 return CacheIt
->second
;
1926 Expected
<uint64_t> SymAddrOrErr
= Sym
->getAddress();
1928 return createError("failed to compute symbol address: ",
1929 SymAddrOrErr
.takeError());
1931 // Also remember what section this symbol is in for later
1932 auto SectOrErr
= Sym
->getSection();
1934 return createError("failed to get symbol section: ",
1935 SectOrErr
.takeError());
1938 Ret
.Address
= *SymAddrOrErr
;
1939 } else if (auto *MObj
= dyn_cast
<MachOObjectFile
>(&Obj
)) {
1940 RSec
= MObj
->getRelocationSection(Reloc
.getRawDataRefImpl());
1941 Ret
.Address
= RSec
->getAddress();
1944 if (RSec
!= Obj
.section_end())
1945 Ret
.SectionIndex
= RSec
->getIndex();
1947 // If we are given load addresses for the sections, we need to adjust:
1948 // SymAddr = (Address of Symbol Or Section in File) -
1949 // (Address of Section in File) +
1950 // (Load Address of Section)
1951 // RSec is now either the section being targeted or the section
1952 // containing the symbol being targeted. In either case,
1953 // we need to perform the same computation.
1954 if (L
&& RSec
!= Obj
.section_end())
1955 if (uint64_t SectionLoadAddress
= L
->getSectionLoadAddress(*RSec
))
1956 Ret
.Address
+= SectionLoadAddress
- RSec
->getAddress();
1958 if (CacheIt
!= Cache
.end())
1959 CacheIt
->second
= Ret
;
1964 static bool isRelocScattered(const object::ObjectFile
&Obj
,
1965 const RelocationRef
&Reloc
) {
1966 const MachOObjectFile
*MachObj
= dyn_cast
<MachOObjectFile
>(&Obj
);
1969 // MachO also has relocations that point to sections and
1970 // scattered relocations.
1971 auto RelocInfo
= MachObj
->getRelocation(Reloc
.getRawDataRefImpl());
1972 return MachObj
->isRelocationScattered(RelocInfo
);
1976 struct DWARFSectionMap final
: public DWARFSection
{
1977 RelocAddrMap Relocs
;
1980 class DWARFObjInMemory final
: public DWARFObject
{
1981 bool IsLittleEndian
;
1982 uint8_t AddressSize
;
1984 const object::ObjectFile
*Obj
= nullptr;
1985 std::vector
<SectionName
> SectionNames
;
1987 using InfoSectionMap
= MapVector
<object::SectionRef
, DWARFSectionMap
,
1988 std::map
<object::SectionRef
, unsigned>>;
1990 InfoSectionMap InfoSections
;
1991 InfoSectionMap TypesSections
;
1992 InfoSectionMap InfoDWOSections
;
1993 InfoSectionMap TypesDWOSections
;
1995 DWARFSectionMap LocSection
;
1996 DWARFSectionMap LoclistsSection
;
1997 DWARFSectionMap LoclistsDWOSection
;
1998 DWARFSectionMap LineSection
;
1999 DWARFSectionMap RangesSection
;
2000 DWARFSectionMap RnglistsSection
;
2001 DWARFSectionMap StrOffsetsSection
;
2002 DWARFSectionMap LineDWOSection
;
2003 DWARFSectionMap FrameSection
;
2004 DWARFSectionMap EHFrameSection
;
2005 DWARFSectionMap LocDWOSection
;
2006 DWARFSectionMap StrOffsetsDWOSection
;
2007 DWARFSectionMap RangesDWOSection
;
2008 DWARFSectionMap RnglistsDWOSection
;
2009 DWARFSectionMap AddrSection
;
2010 DWARFSectionMap AppleNamesSection
;
2011 DWARFSectionMap AppleTypesSection
;
2012 DWARFSectionMap AppleNamespacesSection
;
2013 DWARFSectionMap AppleObjCSection
;
2014 DWARFSectionMap NamesSection
;
2015 DWARFSectionMap PubnamesSection
;
2016 DWARFSectionMap PubtypesSection
;
2017 DWARFSectionMap GnuPubnamesSection
;
2018 DWARFSectionMap GnuPubtypesSection
;
2019 DWARFSectionMap MacroSection
;
2021 DWARFSectionMap
*mapNameToDWARFSection(StringRef Name
) {
2022 return StringSwitch
<DWARFSectionMap
*>(Name
)
2023 .Case("debug_loc", &LocSection
)
2024 .Case("debug_loclists", &LoclistsSection
)
2025 .Case("debug_loclists.dwo", &LoclistsDWOSection
)
2026 .Case("debug_line", &LineSection
)
2027 .Case("debug_frame", &FrameSection
)
2028 .Case("eh_frame", &EHFrameSection
)
2029 .Case("debug_str_offsets", &StrOffsetsSection
)
2030 .Case("debug_ranges", &RangesSection
)
2031 .Case("debug_rnglists", &RnglistsSection
)
2032 .Case("debug_loc.dwo", &LocDWOSection
)
2033 .Case("debug_line.dwo", &LineDWOSection
)
2034 .Case("debug_names", &NamesSection
)
2035 .Case("debug_rnglists.dwo", &RnglistsDWOSection
)
2036 .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection
)
2037 .Case("debug_addr", &AddrSection
)
2038 .Case("apple_names", &AppleNamesSection
)
2039 .Case("debug_pubnames", &PubnamesSection
)
2040 .Case("debug_pubtypes", &PubtypesSection
)
2041 .Case("debug_gnu_pubnames", &GnuPubnamesSection
)
2042 .Case("debug_gnu_pubtypes", &GnuPubtypesSection
)
2043 .Case("apple_types", &AppleTypesSection
)
2044 .Case("apple_namespaces", &AppleNamespacesSection
)
2045 .Case("apple_namespac", &AppleNamespacesSection
)
2046 .Case("apple_objc", &AppleObjCSection
)
2047 .Case("debug_macro", &MacroSection
)
2051 StringRef AbbrevSection
;
2052 StringRef ArangesSection
;
2053 StringRef StrSection
;
2054 StringRef MacinfoSection
;
2055 StringRef MacinfoDWOSection
;
2056 StringRef MacroDWOSection
;
2057 StringRef AbbrevDWOSection
;
2058 StringRef StrDWOSection
;
2059 StringRef CUIndexSection
;
2060 StringRef GdbIndexSection
;
2061 StringRef TUIndexSection
;
2062 StringRef LineStrSection
;
2064 // A deque holding section data whose iterators are not invalidated when
2065 // new decompressed sections are inserted at the end.
2066 std::deque
<SmallString
<0>> UncompressedSections
;
2068 StringRef
*mapSectionToMember(StringRef Name
) {
2069 if (DWARFSection
*Sec
= mapNameToDWARFSection(Name
))
2071 return StringSwitch
<StringRef
*>(Name
)
2072 .Case("debug_abbrev", &AbbrevSection
)
2073 .Case("debug_aranges", &ArangesSection
)
2074 .Case("debug_str", &StrSection
)
2075 .Case("debug_macinfo", &MacinfoSection
)
2076 .Case("debug_macinfo.dwo", &MacinfoDWOSection
)
2077 .Case("debug_macro.dwo", &MacroDWOSection
)
2078 .Case("debug_abbrev.dwo", &AbbrevDWOSection
)
2079 .Case("debug_str.dwo", &StrDWOSection
)
2080 .Case("debug_cu_index", &CUIndexSection
)
2081 .Case("debug_tu_index", &TUIndexSection
)
2082 .Case("gdb_index", &GdbIndexSection
)
2083 .Case("debug_line_str", &LineStrSection
)
2084 // Any more debug info sections go here.
2088 /// If Sec is compressed section, decompresses and updates its contents
2089 /// provided by Data. Otherwise leaves it unchanged.
2090 Error
maybeDecompress(const object::SectionRef
&Sec
, StringRef Name
,
2092 if (!Sec
.isCompressed())
2093 return Error::success();
2095 Expected
<Decompressor
> Decompressor
=
2096 Decompressor::create(Name
, Data
, IsLittleEndian
, AddressSize
== 8);
2098 return Decompressor
.takeError();
2101 if (auto Err
= Decompressor
->resizeAndDecompress(Out
))
2104 UncompressedSections
.push_back(std::move(Out
));
2105 Data
= UncompressedSections
.back();
2107 return Error::success();
2111 DWARFObjInMemory(const StringMap
<std::unique_ptr
<MemoryBuffer
>> &Sections
,
2112 uint8_t AddrSize
, bool IsLittleEndian
)
2113 : IsLittleEndian(IsLittleEndian
) {
2114 for (const auto &SecIt
: Sections
) {
2115 if (StringRef
*SectionData
= mapSectionToMember(SecIt
.first()))
2116 *SectionData
= SecIt
.second
->getBuffer();
2117 else if (SecIt
.first() == "debug_info")
2118 // Find debug_info and debug_types data by section rather than name as
2119 // there are multiple, comdat grouped, of these sections.
2120 InfoSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
2121 else if (SecIt
.first() == "debug_info.dwo")
2122 InfoDWOSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
2123 else if (SecIt
.first() == "debug_types")
2124 TypesSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
2125 else if (SecIt
.first() == "debug_types.dwo")
2126 TypesDWOSections
[SectionRef()].Data
= SecIt
.second
->getBuffer();
2129 DWARFObjInMemory(const object::ObjectFile
&Obj
, const LoadedObjectInfo
*L
,
2130 function_ref
<void(Error
)> HandleError
,
2131 function_ref
<void(Error
)> HandleWarning
,
2132 DWARFContext::ProcessDebugRelocations RelocAction
)
2133 : IsLittleEndian(Obj
.isLittleEndian()),
2134 AddressSize(Obj
.getBytesInAddress()), FileName(Obj
.getFileName()),
2137 StringMap
<unsigned> SectionAmountMap
;
2138 for (const SectionRef
&Section
: Obj
.sections()) {
2140 if (auto NameOrErr
= Section
.getName())
2143 consumeError(NameOrErr
.takeError());
2145 ++SectionAmountMap
[Name
];
2146 SectionNames
.push_back({ Name
, true });
2148 // Skip BSS and Virtual sections, they aren't interesting.
2149 if (Section
.isBSS() || Section
.isVirtual())
2152 // Skip sections stripped by dsymutil.
2153 if (Section
.isStripped())
2157 Expected
<section_iterator
> SecOrErr
= Section
.getRelocatedSection();
2159 HandleError(createError("failed to get relocated section: ",
2160 SecOrErr
.takeError()));
2164 // Try to obtain an already relocated version of this section.
2165 // Else use the unrelocated section from the object file. We'll have to
2166 // apply relocations ourselves later.
2167 section_iterator RelocatedSection
=
2168 Obj
.isRelocatableObject() ? *SecOrErr
: Obj
.section_end();
2169 if (!L
|| !L
->getLoadedSectionContents(*RelocatedSection
, Data
)) {
2170 Expected
<StringRef
> E
= Section
.getContents();
2174 // maybeDecompress below will error.
2175 consumeError(E
.takeError());
2178 if (auto Err
= maybeDecompress(Section
, Name
, Data
)) {
2179 HandleError(createError("failed to decompress '" + Name
+ "', ",
2184 // Map platform specific debug section names to DWARF standard section
2186 Name
= Name
.substr(Name
.find_first_not_of("._"));
2187 Name
= Obj
.mapDebugSectionName(Name
);
2189 if (StringRef
*SectionData
= mapSectionToMember(Name
)) {
2190 *SectionData
= Data
;
2191 if (Name
== "debug_ranges") {
2192 // FIXME: Use the other dwo range section when we emit it.
2193 RangesDWOSection
.Data
= Data
;
2194 } else if (Name
== "debug_frame" || Name
== "eh_frame") {
2195 if (DWARFSection
*S
= mapNameToDWARFSection(Name
))
2196 S
->Address
= Section
.getAddress();
2198 } else if (InfoSectionMap
*Sections
=
2199 StringSwitch
<InfoSectionMap
*>(Name
)
2200 .Case("debug_info", &InfoSections
)
2201 .Case("debug_info.dwo", &InfoDWOSections
)
2202 .Case("debug_types", &TypesSections
)
2203 .Case("debug_types.dwo", &TypesDWOSections
)
2204 .Default(nullptr)) {
2205 // Find debug_info and debug_types data by section rather than name as
2206 // there are multiple, comdat grouped, of these sections.
2207 DWARFSectionMap
&S
= (*Sections
)[Section
];
2211 if (RelocatedSection
== Obj
.section_end() ||
2212 (RelocAction
== DWARFContext::ProcessDebugRelocations::Ignore
))
2215 StringRef RelSecName
;
2216 if (auto NameOrErr
= RelocatedSection
->getName())
2217 RelSecName
= *NameOrErr
;
2219 consumeError(NameOrErr
.takeError());
2221 // If the section we're relocating was relocated already by the JIT,
2222 // then we used the relocated version above, so we do not need to process
2223 // relocations for it now.
2224 StringRef RelSecData
;
2225 if (L
&& L
->getLoadedSectionContents(*RelocatedSection
, RelSecData
))
2228 // In Mach-o files, the relocations do not need to be applied if
2229 // there is no load offset to apply. The value read at the
2230 // relocation point already factors in the section address
2231 // (actually applying the relocations will produce wrong results
2232 // as the section address will be added twice).
2233 if (!L
&& isa
<MachOObjectFile
>(&Obj
))
2236 if (!Section
.relocations().empty() && Name
.ends_with(".dwo") &&
2237 RelSecName
.starts_with(".debug")) {
2238 HandleWarning(createError("unexpected relocations for dwo section '" +
2242 // TODO: Add support for relocations in other sections as needed.
2243 // Record relocations for the debug_info and debug_line sections.
2244 RelSecName
= RelSecName
.substr(RelSecName
.find_first_not_of("._"));
2245 DWARFSectionMap
*Sec
= mapNameToDWARFSection(RelSecName
);
2246 RelocAddrMap
*Map
= Sec
? &Sec
->Relocs
: nullptr;
2248 // Find debug_info and debug_types relocs by section rather than name
2249 // as there are multiple, comdat grouped, of these sections.
2250 if (RelSecName
== "debug_info")
2251 Map
= &static_cast<DWARFSectionMap
&>(InfoSections
[*RelocatedSection
])
2253 else if (RelSecName
== "debug_types")
2255 &static_cast<DWARFSectionMap
&>(TypesSections
[*RelocatedSection
])
2261 if (Section
.relocation_begin() == Section
.relocation_end())
2264 // Symbol to [address, section index] cache mapping.
2265 std::map
<SymbolRef
, SymInfo
> AddrCache
;
2266 SupportsRelocation Supports
;
2267 RelocationResolver Resolver
;
2268 std::tie(Supports
, Resolver
) = getRelocationResolver(Obj
);
2269 for (const RelocationRef
&Reloc
: Section
.relocations()) {
2270 // FIXME: it's not clear how to correctly handle scattered
2272 if (isRelocScattered(Obj
, Reloc
))
2275 Expected
<SymInfo
> SymInfoOrErr
=
2276 getSymbolInfo(Obj
, Reloc
, L
, AddrCache
);
2277 if (!SymInfoOrErr
) {
2278 HandleError(SymInfoOrErr
.takeError());
2282 // Check if Resolver can handle this relocation type early so as not to
2283 // handle invalid cases in DWARFDataExtractor.
2285 // TODO Don't store Resolver in every RelocAddrEntry.
2286 if (Supports
&& Supports(Reloc
.getType())) {
2287 auto I
= Map
->try_emplace(
2290 SymInfoOrErr
->SectionIndex
, Reloc
, SymInfoOrErr
->Address
,
2291 std::optional
<object::RelocationRef
>(), 0, Resolver
});
2292 // If we didn't successfully insert that's because we already had a
2293 // relocation for that offset. Store it as a second relocation in the
2294 // same RelocAddrEntry instead.
2296 RelocAddrEntry
&entry
= I
.first
->getSecond();
2298 HandleError(createError(
2299 "At most two relocations per offset are supported"));
2301 entry
.Reloc2
= Reloc
;
2302 entry
.SymbolValue2
= SymInfoOrErr
->Address
;
2305 SmallString
<32> Type
;
2306 Reloc
.getTypeName(Type
);
2307 // FIXME: Support more relocations & change this to an error
2309 createError("failed to compute relocation: " + Type
+ ", ",
2310 errorCodeToError(object_error::parse_failed
)));
2315 for (SectionName
&S
: SectionNames
)
2316 if (SectionAmountMap
[S
.Name
] > 1)
2317 S
.IsNameUnique
= false;
2320 std::optional
<RelocAddrEntry
> find(const DWARFSection
&S
,
2321 uint64_t Pos
) const override
{
2322 auto &Sec
= static_cast<const DWARFSectionMap
&>(S
);
2323 RelocAddrMap::const_iterator AI
= Sec
.Relocs
.find(Pos
);
2324 if (AI
== Sec
.Relocs
.end())
2325 return std::nullopt
;
2329 const object::ObjectFile
*getFile() const override
{ return Obj
; }
2331 ArrayRef
<SectionName
> getSectionNames() const override
{
2332 return SectionNames
;
2335 bool isLittleEndian() const override
{ return IsLittleEndian
; }
2336 StringRef
getAbbrevDWOSection() const override
{ return AbbrevDWOSection
; }
2337 const DWARFSection
&getLineDWOSection() const override
{
2338 return LineDWOSection
;
2340 const DWARFSection
&getLocDWOSection() const override
{
2341 return LocDWOSection
;
2343 StringRef
getStrDWOSection() const override
{ return StrDWOSection
; }
2344 const DWARFSection
&getStrOffsetsDWOSection() const override
{
2345 return StrOffsetsDWOSection
;
2347 const DWARFSection
&getRangesDWOSection() const override
{
2348 return RangesDWOSection
;
2350 const DWARFSection
&getRnglistsDWOSection() const override
{
2351 return RnglistsDWOSection
;
2353 const DWARFSection
&getLoclistsDWOSection() const override
{
2354 return LoclistsDWOSection
;
2356 const DWARFSection
&getAddrSection() const override
{ return AddrSection
; }
2357 StringRef
getCUIndexSection() const override
{ return CUIndexSection
; }
2358 StringRef
getGdbIndexSection() const override
{ return GdbIndexSection
; }
2359 StringRef
getTUIndexSection() const override
{ return TUIndexSection
; }
2362 const DWARFSection
&getStrOffsetsSection() const override
{
2363 return StrOffsetsSection
;
2365 StringRef
getLineStrSection() const override
{ return LineStrSection
; }
2367 // Sections for DWARF5 split dwarf proposal.
2368 void forEachInfoDWOSections(
2369 function_ref
<void(const DWARFSection
&)> F
) const override
{
2370 for (auto &P
: InfoDWOSections
)
2373 void forEachTypesDWOSections(
2374 function_ref
<void(const DWARFSection
&)> F
) const override
{
2375 for (auto &P
: TypesDWOSections
)
2379 StringRef
getAbbrevSection() const override
{ return AbbrevSection
; }
2380 const DWARFSection
&getLocSection() const override
{ return LocSection
; }
2381 const DWARFSection
&getLoclistsSection() const override
{ return LoclistsSection
; }
2382 StringRef
getArangesSection() const override
{ return ArangesSection
; }
2383 const DWARFSection
&getFrameSection() const override
{
2384 return FrameSection
;
2386 const DWARFSection
&getEHFrameSection() const override
{
2387 return EHFrameSection
;
2389 const DWARFSection
&getLineSection() const override
{ return LineSection
; }
2390 StringRef
getStrSection() const override
{ return StrSection
; }
2391 const DWARFSection
&getRangesSection() const override
{ return RangesSection
; }
2392 const DWARFSection
&getRnglistsSection() const override
{
2393 return RnglistsSection
;
2395 const DWARFSection
&getMacroSection() const override
{ return MacroSection
; }
2396 StringRef
getMacroDWOSection() const override
{ return MacroDWOSection
; }
2397 StringRef
getMacinfoSection() const override
{ return MacinfoSection
; }
2398 StringRef
getMacinfoDWOSection() const override
{ return MacinfoDWOSection
; }
2399 const DWARFSection
&getPubnamesSection() const override
{ return PubnamesSection
; }
2400 const DWARFSection
&getPubtypesSection() const override
{ return PubtypesSection
; }
2401 const DWARFSection
&getGnuPubnamesSection() const override
{
2402 return GnuPubnamesSection
;
2404 const DWARFSection
&getGnuPubtypesSection() const override
{
2405 return GnuPubtypesSection
;
2407 const DWARFSection
&getAppleNamesSection() const override
{
2408 return AppleNamesSection
;
2410 const DWARFSection
&getAppleTypesSection() const override
{
2411 return AppleTypesSection
;
2413 const DWARFSection
&getAppleNamespacesSection() const override
{
2414 return AppleNamespacesSection
;
2416 const DWARFSection
&getAppleObjCSection() const override
{
2417 return AppleObjCSection
;
2419 const DWARFSection
&getNamesSection() const override
{
2420 return NamesSection
;
2423 StringRef
getFileName() const override
{ return FileName
; }
2424 uint8_t getAddressSize() const override
{ return AddressSize
; }
2425 void forEachInfoSections(
2426 function_ref
<void(const DWARFSection
&)> F
) const override
{
2427 for (auto &P
: InfoSections
)
2430 void forEachTypesSections(
2431 function_ref
<void(const DWARFSection
&)> F
) const override
{
2432 for (auto &P
: TypesSections
)
2438 std::unique_ptr
<DWARFContext
>
2439 DWARFContext::create(const object::ObjectFile
&Obj
,
2440 ProcessDebugRelocations RelocAction
,
2441 const LoadedObjectInfo
*L
, std::string DWPName
,
2442 std::function
<void(Error
)> RecoverableErrorHandler
,
2443 std::function
<void(Error
)> WarningHandler
,
2445 auto DObj
= std::make_unique
<DWARFObjInMemory
>(
2446 Obj
, L
, RecoverableErrorHandler
, WarningHandler
, RelocAction
);
2447 return std::make_unique
<DWARFContext
>(std::move(DObj
),
2449 RecoverableErrorHandler
,
2454 std::unique_ptr
<DWARFContext
>
2455 DWARFContext::create(const StringMap
<std::unique_ptr
<MemoryBuffer
>> &Sections
,
2456 uint8_t AddrSize
, bool isLittleEndian
,
2457 std::function
<void(Error
)> RecoverableErrorHandler
,
2458 std::function
<void(Error
)> WarningHandler
,
2461 std::make_unique
<DWARFObjInMemory
>(Sections
, AddrSize
, isLittleEndian
);
2462 return std::make_unique
<DWARFContext
>(
2463 std::move(DObj
), "", RecoverableErrorHandler
, WarningHandler
, ThreadSafe
);
2466 uint8_t DWARFContext::getCUAddrSize() {
2467 // In theory, different compile units may have different address byte
2468 // sizes, but for simplicity we just use the address byte size of the
2469 // first compile unit. In practice the address size field is repeated across
2470 // various DWARF headers (at least in version 5) to make it easier to dump
2471 // them independently, not to enable varying the address size.
2472 auto CUs
= compile_units();
2473 return CUs
.empty() ? 0 : (*CUs
.begin())->getAddressByteSize();