Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
35269 views
1
//===- DWARFContext.cpp ---------------------------------------------------===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
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"
55
#include <algorithm>
56
#include <cstdint>
57
#include <deque>
58
#include <map>
59
#include <string>
60
#include <utility>
61
#include <vector>
62
63
using namespace llvm;
64
using namespace dwarf;
65
using namespace object;
66
67
#define DEBUG_TYPE "dwarf"
68
69
using DWARFLineTable = DWARFDebugLine::LineTable;
70
using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
71
using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
72
73
74
void fixupIndexV4(DWARFContext &C, DWARFUnitIndex &Index) {
75
using EntryType = DWARFUnitIndex::Entry::SectionContribution;
76
using EntryMap = DenseMap<uint32_t, EntryType>;
77
EntryMap Map;
78
const auto &DObj = C.getDWARFObj();
79
if (DObj.getCUIndexSection().empty())
80
return;
81
82
uint64_t Offset = 0;
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()))
87
return;
88
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))));
97
Map.clear();
98
break;
99
}
100
101
auto Iter = Map.insert({TruncOffset,
102
{Header.getOffset(), Header.getNextUnitOffset() -
103
Header.getOffset()}});
104
if (!Iter.second) {
105
logAllUnhandledErrors(
106
createError("Collision occured between for truncated offset 0x" +
107
Twine::utohexstr(TruncOffset)),
108
errs());
109
Map.clear();
110
return;
111
}
112
113
Offset = Header.getNextUnitOffset();
114
TruncOffset = Offset;
115
}
116
});
117
118
if (Map.empty())
119
return;
120
121
for (DWARFUnitIndex::Entry &E : Index.getMutableRows()) {
122
if (!E.isValid())
123
continue;
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()) +
129
" in the Map"),
130
errs());
131
break;
132
}
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())),
138
errs());
139
}
140
}
141
142
void fixupIndexV5(DWARFContext &C, DWARFUnitIndex &Index) {
143
DenseMap<uint64_t, uint64_t> Map;
144
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()))
149
return;
150
DWARFDataExtractor Data(DObj, S, C.isLittleEndian(), 0);
151
uint64_t Offset = 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))));
159
break;
160
}
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();
165
}
166
});
167
if (Map.empty())
168
return;
169
for (DWARFUnitIndex::Entry &E : Index.getMutableRows()) {
170
if (!E.isValid())
171
continue;
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"),
178
errs());
179
break;
180
}
181
CUOff.setOffset(Iter->second);
182
}
183
}
184
185
void fixupIndex(DWARFContext &C, DWARFUnitIndex &Index) {
186
if (Index.getVersion() < 5)
187
fixupIndexV4(C, Index);
188
else
189
fixupIndexV5(C, Index);
190
}
191
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) {
196
if (Cache)
197
return *Cache;
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));
203
return *Cache;
204
}
205
206
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
212
? D.compile_units()
213
: D.dwo_compile_units(),
214
SectionType == MacroSection
215
? D.getStringExtractor()
216
: D.getStringDWOExtractor(),
217
Data)
218
: Macro->parseMacinfo(Data)) {
219
D.getRecoverableErrorHandler()(std::move(Err));
220
Macro = nullptr;
221
}
222
};
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);
228
break;
229
}
230
case MacinfoDwoSection: {
231
DWARFDataExtractor Data(DObj.getMacinfoDWOSection(), D.isLittleEndian(), 0);
232
ParseAndDump(Data, /*IsMacro=*/false);
233
break;
234
}
235
case MacroSection: {
236
DWARFDataExtractor Data(DObj, DObj.getMacroSection(), D.isLittleEndian(),
237
0);
238
ParseAndDump(Data, /*IsMacro=*/true);
239
break;
240
}
241
case MacroDwoSection: {
242
DWARFDataExtractor Data(DObj.getMacroDWOSection(), D.isLittleEndian(), 0);
243
ParseAndDump(Data, /*IsMacro=*/true);
244
break;
245
}
246
}
247
return Macro;
248
}
249
250
namespace {
251
class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
252
253
DWARFUnitVector NormalUnits;
254
std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> NormalTypeUnits;
255
std::unique_ptr<DWARFUnitIndex> CUIndex;
256
std::unique_ptr<DWARFGdbIndex> GdbIndex;
257
std::unique_ptr<DWARFUnitIndex> TUIndex;
258
std::unique_ptr<DWARFDebugAbbrev> Abbrev;
259
std::unique_ptr<DWARFDebugLoc> Loc;
260
std::unique_ptr<DWARFDebugAranges> Aranges;
261
std::unique_ptr<DWARFDebugLine> Line;
262
std::unique_ptr<DWARFDebugFrame> DebugFrame;
263
std::unique_ptr<DWARFDebugFrame> EHFrame;
264
std::unique_ptr<DWARFDebugMacro> Macro;
265
std::unique_ptr<DWARFDebugMacro> Macinfo;
266
std::unique_ptr<DWARFDebugNames> Names;
267
std::unique_ptr<AppleAcceleratorTable> AppleNames;
268
std::unique_ptr<AppleAcceleratorTable> AppleTypes;
269
std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
270
std::unique_ptr<AppleAcceleratorTable> AppleObjC;
271
DWARFUnitVector DWOUnits;
272
std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> DWOTypeUnits;
273
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
274
std::unique_ptr<DWARFDebugMacro> MacinfoDWO;
275
std::unique_ptr<DWARFDebugMacro> MacroDWO;
276
struct DWOFile {
277
object::OwningBinary<object::ObjectFile> File;
278
std::unique_ptr<DWARFContext> Context;
279
};
280
StringMap<std::weak_ptr<DWOFile>> DWOFiles;
281
std::weak_ptr<DWOFile> DWP;
282
bool CheckedForDWP = false;
283
std::string DWPName;
284
285
public:
286
ThreadUnsafeDWARFContextState(DWARFContext &DC, std::string &DWP) :
287
DWARFContext::DWARFContextState(DC),
288
DWPName(std::move(DWP)) {}
289
290
DWARFUnitVector &getNormalUnits() override {
291
if (NormalUnits.empty()) {
292
const DWARFObject &DObj = D.getDWARFObj();
293
DObj.forEachInfoSections([&](const DWARFSection &S) {
294
NormalUnits.addUnitsForSection(D, S, DW_SECT_INFO);
295
});
296
NormalUnits.finishedInfoUnits();
297
DObj.forEachTypesSections([&](const DWARFSection &S) {
298
NormalUnits.addUnitsForSection(D, S, DW_SECT_EXT_TYPES);
299
});
300
}
301
return NormalUnits;
302
}
303
304
DWARFUnitVector &getDWOUnits(bool Lazy) override {
305
if (DWOUnits.empty()) {
306
const DWARFObject &DObj = D.getDWARFObj();
307
308
DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
309
DWOUnits.addUnitsForDWOSection(D, S, DW_SECT_INFO, Lazy);
310
});
311
DWOUnits.finishedInfoUnits();
312
DObj.forEachTypesDWOSections([&](const DWARFSection &S) {
313
DWOUnits.addUnitsForDWOSection(D, S, DW_SECT_EXT_TYPES, Lazy);
314
});
315
}
316
return DWOUnits;
317
}
318
319
const DWARFDebugAbbrev *getDebugAbbrevDWO() override {
320
if (AbbrevDWO)
321
return AbbrevDWO.get();
322
const DWARFObject &DObj = D.getDWARFObj();
323
DataExtractor abbrData(DObj.getAbbrevDWOSection(), D.isLittleEndian(), 0);
324
AbbrevDWO = std::make_unique<DWARFDebugAbbrev>(abbrData);
325
return AbbrevDWO.get();
326
}
327
328
const DWARFUnitIndex &getCUIndex() override {
329
if (CUIndex)
330
return *CUIndex;
331
332
DataExtractor Data(D.getDWARFObj().getCUIndexSection(),
333
D.isLittleEndian(), 0);
334
CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
335
if (CUIndex->parse(Data))
336
fixupIndex(D, *CUIndex);
337
return *CUIndex;
338
}
339
const DWARFUnitIndex &getTUIndex() override {
340
if (TUIndex)
341
return *TUIndex;
342
343
DataExtractor Data(D.getDWARFObj().getTUIndexSection(),
344
D.isLittleEndian(), 0);
345
TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES);
346
bool isParseSuccessful = TUIndex->parse(Data);
347
// If we are parsing TU-index and for .debug_types section we don't need
348
// to do anything.
349
if (isParseSuccessful && TUIndex->getVersion() != 2)
350
fixupIndex(D, *TUIndex);
351
return *TUIndex;
352
}
353
354
DWARFGdbIndex &getGdbIndex() override {
355
if (GdbIndex)
356
return *GdbIndex;
357
358
DataExtractor Data(D.getDWARFObj().getGdbIndexSection(), true /*LE*/, 0);
359
GdbIndex = std::make_unique<DWARFGdbIndex>();
360
GdbIndex->parse(Data);
361
return *GdbIndex;
362
}
363
364
const DWARFDebugAbbrev *getDebugAbbrev() override {
365
if (Abbrev)
366
return Abbrev.get();
367
368
DataExtractor Data(D.getDWARFObj().getAbbrevSection(),
369
D.isLittleEndian(), 0);
370
Abbrev = std::make_unique<DWARFDebugAbbrev>(Data);
371
return Abbrev.get();
372
}
373
374
const DWARFDebugLoc *getDebugLoc() override {
375
if (Loc)
376
return Loc.get();
377
378
const DWARFObject &DObj = D.getDWARFObj();
379
// Assume all units have the same address byte size.
380
auto Data =
381
D.getNumCompileUnits()
382
? DWARFDataExtractor(DObj, DObj.getLocSection(), D.isLittleEndian(),
383
D.getUnitAtIndex(0)->getAddressByteSize())
384
: DWARFDataExtractor("", D.isLittleEndian(), 0);
385
Loc = std::make_unique<DWARFDebugLoc>(std::move(Data));
386
return Loc.get();
387
}
388
389
const DWARFDebugAranges *getDebugAranges() override {
390
if (Aranges)
391
return Aranges.get();
392
393
Aranges = std::make_unique<DWARFDebugAranges>();
394
Aranges->generate(&D);
395
return Aranges.get();
396
}
397
398
Expected<const DWARFDebugLine::LineTable *>
399
getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {
400
if (!Line)
401
Line = std::make_unique<DWARFDebugLine>();
402
403
auto UnitDIE = U->getUnitDIE();
404
if (!UnitDIE)
405
return nullptr;
406
407
auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
408
if (!Offset)
409
return nullptr; // No line table for this compile unit.
410
411
uint64_t stmtOffset = *Offset + U->getLineTableOffset();
412
// See if the line table is cached.
413
if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
414
return lt;
415
416
// Make sure the offset is good before we try to parse.
417
if (stmtOffset >= U->getLineSection().Data.size())
418
return nullptr;
419
420
// We have to parse it first.
421
DWARFDataExtractor Data(U->getContext().getDWARFObj(), U->getLineSection(),
422
U->isLittleEndian(), U->getAddressByteSize());
423
return Line->getOrParseLineTable(Data, stmtOffset, U->getContext(), U,
424
RecoverableErrorHandler);
425
426
}
427
428
void clearLineTableForUnit(DWARFUnit *U) override {
429
if (!Line)
430
return;
431
432
auto UnitDIE = U->getUnitDIE();
433
if (!UnitDIE)
434
return;
435
436
auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
437
if (!Offset)
438
return;
439
440
uint64_t stmtOffset = *Offset + U->getLineTableOffset();
441
Line->clearLineTable(stmtOffset);
442
}
443
444
Expected<const DWARFDebugFrame *> getDebugFrame() override {
445
if (DebugFrame)
446
return DebugFrame.get();
447
const DWARFObject &DObj = D.getDWARFObj();
448
const DWARFSection &DS = DObj.getFrameSection();
449
450
// There's a "bug" in the DWARFv3 standard with respect to the target address
451
// size within debug frame sections. While DWARF is supposed to be independent
452
// of its container, FDEs have fields with size being "target address size",
453
// which isn't specified in DWARF in general. It's only specified for CUs, but
454
// .eh_frame can appear without a .debug_info section. Follow the example of
455
// other tools (libdwarf) and extract this from the container (ObjectFile
456
// provides this information). This problem is fixed in DWARFv4
457
// See this dwarf-discuss discussion for more details:
458
// http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
459
DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),
460
DObj.getAddressSize());
461
auto DF =
462
std::make_unique<DWARFDebugFrame>(D.getArch(), /*IsEH=*/false,
463
DS.Address);
464
if (Error E = DF->parse(Data))
465
return std::move(E);
466
467
DebugFrame.swap(DF);
468
return DebugFrame.get();
469
}
470
471
Expected<const DWARFDebugFrame *> getEHFrame() override {
472
if (EHFrame)
473
return EHFrame.get();
474
const DWARFObject &DObj = D.getDWARFObj();
475
476
const DWARFSection &DS = DObj.getEHFrameSection();
477
DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),
478
DObj.getAddressSize());
479
auto DF =
480
std::make_unique<DWARFDebugFrame>(D.getArch(), /*IsEH=*/true,
481
DS.Address);
482
if (Error E = DF->parse(Data))
483
return std::move(E);
484
EHFrame.swap(DF);
485
return EHFrame.get();
486
}
487
488
const DWARFDebugMacro *getDebugMacinfo() override {
489
if (!Macinfo)
490
Macinfo = parseMacroOrMacinfo(MacinfoSection);
491
return Macinfo.get();
492
}
493
const DWARFDebugMacro *getDebugMacinfoDWO() override {
494
if (!MacinfoDWO)
495
MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
496
return MacinfoDWO.get();
497
}
498
const DWARFDebugMacro *getDebugMacro() override {
499
if (!Macro)
500
Macro = parseMacroOrMacinfo(MacroSection);
501
return Macro.get();
502
}
503
const DWARFDebugMacro *getDebugMacroDWO() override {
504
if (!MacroDWO)
505
MacroDWO = parseMacroOrMacinfo(MacroDwoSection);
506
return MacroDWO.get();
507
}
508
const DWARFDebugNames &getDebugNames() override {
509
const DWARFObject &DObj = D.getDWARFObj();
510
return getAccelTable(Names, DObj, DObj.getNamesSection(),
511
DObj.getStrSection(), D.isLittleEndian());
512
}
513
const AppleAcceleratorTable &getAppleNames() override {
514
const DWARFObject &DObj = D.getDWARFObj();
515
return getAccelTable(AppleNames, DObj, DObj.getAppleNamesSection(),
516
DObj.getStrSection(), D.isLittleEndian());
517
518
}
519
const AppleAcceleratorTable &getAppleTypes() override {
520
const DWARFObject &DObj = D.getDWARFObj();
521
return getAccelTable(AppleTypes, DObj, DObj.getAppleTypesSection(),
522
DObj.getStrSection(), D.isLittleEndian());
523
524
}
525
const AppleAcceleratorTable &getAppleNamespaces() override {
526
const DWARFObject &DObj = D.getDWARFObj();
527
return getAccelTable(AppleNamespaces, DObj,
528
DObj.getAppleNamespacesSection(),
529
DObj.getStrSection(), D.isLittleEndian());
530
531
}
532
const AppleAcceleratorTable &getAppleObjC() override {
533
const DWARFObject &DObj = D.getDWARFObj();
534
return getAccelTable(AppleObjC, DObj, DObj.getAppleObjCSection(),
535
DObj.getStrSection(), D.isLittleEndian());
536
}
537
538
std::shared_ptr<DWARFContext>
539
getDWOContext(StringRef AbsolutePath) override {
540
if (auto S = DWP.lock()) {
541
DWARFContext *Ctxt = S->Context.get();
542
return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
543
}
544
545
std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
546
547
if (auto S = Entry->lock()) {
548
DWARFContext *Ctxt = S->Context.get();
549
return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
550
}
551
552
const DWARFObject &DObj = D.getDWARFObj();
553
554
Expected<OwningBinary<ObjectFile>> Obj = [&] {
555
if (!CheckedForDWP) {
556
SmallString<128> DWPName;
557
auto Obj = object::ObjectFile::createObjectFile(
558
this->DWPName.empty()
559
? (DObj.getFileName() + ".dwp").toStringRef(DWPName)
560
: StringRef(this->DWPName));
561
if (Obj) {
562
Entry = &DWP;
563
return Obj;
564
} else {
565
CheckedForDWP = true;
566
// TODO: Should this error be handled (maybe in a high verbosity mode)
567
// before falling back to .dwo files?
568
consumeError(Obj.takeError());
569
}
570
}
571
572
return object::ObjectFile::createObjectFile(AbsolutePath);
573
}();
574
575
if (!Obj) {
576
// TODO: Actually report errors helpfully.
577
consumeError(Obj.takeError());
578
return nullptr;
579
}
580
581
auto S = std::make_shared<DWOFile>();
582
S->File = std::move(Obj.get());
583
// Allow multi-threaded access if there is a .dwp file as the CU index and
584
// TU index might be accessed from multiple threads.
585
bool ThreadSafe = isThreadSafe();
586
S->Context = DWARFContext::create(
587
*S->File.getBinary(), DWARFContext::ProcessDebugRelocations::Ignore,
588
nullptr, "", WithColor::defaultErrorHandler,
589
WithColor::defaultWarningHandler, ThreadSafe);
590
*Entry = S;
591
auto *Ctxt = S->Context.get();
592
return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
593
}
594
595
bool isThreadSafe() const override { return false; }
596
597
const DenseMap<uint64_t, DWARFTypeUnit *> &getNormalTypeUnitMap() {
598
if (!NormalTypeUnits) {
599
NormalTypeUnits.emplace();
600
for (const auto &U :D.normal_units()) {
601
if (DWARFTypeUnit *TU = dyn_cast<DWARFTypeUnit>(U.get()))
602
(*NormalTypeUnits)[TU->getTypeHash()] = TU;
603
}
604
}
605
return *NormalTypeUnits;
606
}
607
608
const DenseMap<uint64_t, DWARFTypeUnit *> &getDWOTypeUnitMap() {
609
if (!DWOTypeUnits) {
610
DWOTypeUnits.emplace();
611
for (const auto &U :D.dwo_units()) {
612
if (DWARFTypeUnit *TU = dyn_cast<DWARFTypeUnit>(U.get()))
613
(*DWOTypeUnits)[TU->getTypeHash()] = TU;
614
}
615
}
616
return *DWOTypeUnits;
617
}
618
619
const DenseMap<uint64_t, DWARFTypeUnit *> &
620
getTypeUnitMap(bool IsDWO) override {
621
if (IsDWO)
622
return getDWOTypeUnitMap();
623
else
624
return getNormalTypeUnitMap();
625
}
626
627
628
};
629
630
class ThreadSafeState : public ThreadUnsafeDWARFContextState {
631
std::recursive_mutex Mutex;
632
633
public:
634
ThreadSafeState(DWARFContext &DC, std::string &DWP) :
635
ThreadUnsafeDWARFContextState(DC, DWP) {}
636
637
DWARFUnitVector &getNormalUnits() override {
638
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
639
return ThreadUnsafeDWARFContextState::getNormalUnits();
640
}
641
DWARFUnitVector &getDWOUnits(bool Lazy) override {
642
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
643
// We need to not do lazy parsing when we need thread safety as
644
// DWARFUnitVector, in lazy mode, will slowly add things to itself and
645
// will cause problems in a multi-threaded environment.
646
return ThreadUnsafeDWARFContextState::getDWOUnits(false);
647
}
648
const DWARFUnitIndex &getCUIndex() override {
649
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
650
return ThreadUnsafeDWARFContextState::getCUIndex();
651
}
652
const DWARFDebugAbbrev *getDebugAbbrevDWO() override {
653
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
654
return ThreadUnsafeDWARFContextState::getDebugAbbrevDWO();
655
}
656
657
const DWARFUnitIndex &getTUIndex() override {
658
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
659
return ThreadUnsafeDWARFContextState::getTUIndex();
660
}
661
DWARFGdbIndex &getGdbIndex() override {
662
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
663
return ThreadUnsafeDWARFContextState::getGdbIndex();
664
}
665
const DWARFDebugAbbrev *getDebugAbbrev() override {
666
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
667
return ThreadUnsafeDWARFContextState::getDebugAbbrev();
668
}
669
const DWARFDebugLoc *getDebugLoc() override {
670
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
671
return ThreadUnsafeDWARFContextState::getDebugLoc();
672
}
673
const DWARFDebugAranges *getDebugAranges() override {
674
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
675
return ThreadUnsafeDWARFContextState::getDebugAranges();
676
}
677
Expected<const DWARFDebugLine::LineTable *>
678
getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {
679
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
680
return ThreadUnsafeDWARFContextState::getLineTableForUnit(U, RecoverableErrorHandler);
681
}
682
void clearLineTableForUnit(DWARFUnit *U) override {
683
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
684
return ThreadUnsafeDWARFContextState::clearLineTableForUnit(U);
685
}
686
Expected<const DWARFDebugFrame *> getDebugFrame() override {
687
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
688
return ThreadUnsafeDWARFContextState::getDebugFrame();
689
}
690
Expected<const DWARFDebugFrame *> getEHFrame() override {
691
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
692
return ThreadUnsafeDWARFContextState::getEHFrame();
693
}
694
const DWARFDebugMacro *getDebugMacinfo() override {
695
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
696
return ThreadUnsafeDWARFContextState::getDebugMacinfo();
697
}
698
const DWARFDebugMacro *getDebugMacinfoDWO() override {
699
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
700
return ThreadUnsafeDWARFContextState::getDebugMacinfoDWO();
701
}
702
const DWARFDebugMacro *getDebugMacro() override {
703
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
704
return ThreadUnsafeDWARFContextState::getDebugMacro();
705
}
706
const DWARFDebugMacro *getDebugMacroDWO() override {
707
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
708
return ThreadUnsafeDWARFContextState::getDebugMacroDWO();
709
}
710
const DWARFDebugNames &getDebugNames() override {
711
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
712
return ThreadUnsafeDWARFContextState::getDebugNames();
713
}
714
const AppleAcceleratorTable &getAppleNames() override {
715
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
716
return ThreadUnsafeDWARFContextState::getAppleNames();
717
}
718
const AppleAcceleratorTable &getAppleTypes() override {
719
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
720
return ThreadUnsafeDWARFContextState::getAppleTypes();
721
}
722
const AppleAcceleratorTable &getAppleNamespaces() override {
723
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
724
return ThreadUnsafeDWARFContextState::getAppleNamespaces();
725
}
726
const AppleAcceleratorTable &getAppleObjC() override {
727
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
728
return ThreadUnsafeDWARFContextState::getAppleObjC();
729
}
730
std::shared_ptr<DWARFContext>
731
getDWOContext(StringRef AbsolutePath) override {
732
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
733
return ThreadUnsafeDWARFContextState::getDWOContext(AbsolutePath);
734
}
735
736
bool isThreadSafe() const override { return true; }
737
738
const DenseMap<uint64_t, DWARFTypeUnit *> &
739
getTypeUnitMap(bool IsDWO) override {
740
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
741
return ThreadUnsafeDWARFContextState::getTypeUnitMap(IsDWO);
742
}
743
};
744
} // namespace
745
746
DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj,
747
std::string DWPName,
748
std::function<void(Error)> RecoverableErrorHandler,
749
std::function<void(Error)> WarningHandler,
750
bool ThreadSafe)
751
: DIContext(CK_DWARF),
752
RecoverableErrorHandler(RecoverableErrorHandler),
753
WarningHandler(WarningHandler), DObj(std::move(DObj)) {
754
if (ThreadSafe)
755
State = std::make_unique<ThreadSafeState>(*this, DWPName);
756
else
757
State = std::make_unique<ThreadUnsafeDWARFContextState>(*this, DWPName);
758
}
759
760
DWARFContext::~DWARFContext() = default;
761
762
/// Dump the UUID load command.
763
static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) {
764
auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
765
if (!MachO)
766
return;
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";
772
return;
773
}
774
OS << "UUID: ";
775
memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
776
OS.write_uuid(UUID);
777
Triple T = MachO->getArchTriple();
778
OS << " (" << T.getArchName() << ')';
779
OS << ' ' << MachO->getFileName() << '\n';
780
}
781
}
782
}
783
784
using ContributionCollection =
785
std::vector<std::optional<StrOffsetsContributionDescriptor>>;
786
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
797
// first.
798
llvm::sort(Contributions,
799
[](const std::optional<StrOffsetsContributionDescriptor> &L,
800
const std::optional<StrOffsetsContributionDescriptor> &R) {
801
if (L && R)
802
return L->Base < R->Base;
803
return R.has_value();
804
});
805
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.
809
Contributions.erase(
810
llvm::unique(
811
Contributions,
812
[](const std::optional<StrOffsetsContributionDescriptor> &L,
813
const std::optional<StrOffsetsContributionDescriptor> &R) {
814
if (L && R)
815
return L->Base == R->Base && L->Size == R->Size;
816
return false;
817
}),
818
Contributions.end());
819
return Contributions;
820
}
821
822
// Dump a DWARF string offsets section. This may be a DWARF v5 formatted
823
// string offsets section, where each compile or type unit contributes a
824
// number of entries (string offsets), with each contribution preceded by
825
// a header containing size and version number. Alternatively, it may be a
826
// monolithic series of string offsets, as generated by the pre-DWARF v5
827
// implementation of split DWARF; however, in that case we still need to
828
// collect contributions of units because the size of the offsets (4 or 8
829
// bytes) depends on the format of the referencing unit (DWARF32 or DWARF64).
830
static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
831
StringRef SectionName,
832
const DWARFObject &Obj,
833
const DWARFSection &StringOffsetsSection,
834
StringRef StringSection,
835
DWARFContext::unit_iterator_range Units,
836
bool LittleEndian) {
837
auto Contributions = collectContributionData(Units);
838
DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
839
DataExtractor StrData(StringSection, LittleEndian, 0);
840
uint64_t SectionSize = StringOffsetsSection.Data.size();
841
uint64_t Offset = 0;
842
for (auto &Contribution : Contributions) {
843
// Report an ill-formed contribution.
844
if (!Contribution) {
845
OS << "error: invalid contribution to string offsets table in section ."
846
<< SectionName << ".\n";
847
return;
848
}
849
850
dwarf::DwarfFormat Format = Contribution->getFormat();
851
int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
852
uint16_t Version = Contribution->getVersion();
853
uint64_t ContributionHeader = Contribution->Base;
854
// In DWARF v5 there is a contribution header that immediately precedes
855
// the string offsets base (the location we have previously retrieved from
856
// the CU DIE's DW_AT_str_offsets attribute). The header is located either
857
// 8 or 16 bytes before the base, depending on the contribution's format.
858
if (Version >= 5)
859
ContributionHeader -= Format == DWARF32 ? 8 : 16;
860
861
// Detect overlapping contributions.
862
if (Offset > ContributionHeader) {
863
DumpOpts.RecoverableErrorHandler(createStringError(
864
errc::invalid_argument,
865
"overlapping contributions to string offsets table in section .%s.",
866
SectionName.data()));
867
}
868
// Report a gap in the table.
869
if (Offset < ContributionHeader) {
870
OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
871
OS << (ContributionHeader - Offset) << "\n";
872
}
873
OS << format("0x%8.8" PRIx64 ": ", ContributionHeader);
874
// In DWARF v5 the contribution size in the descriptor does not equal
875
// the originally encoded length (it does not contain the length of the
876
// version field and the padding, a total of 4 bytes). Add them back in
877
// for reporting.
878
OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
879
<< ", Format = " << dwarf::FormatString(Format)
880
<< ", Version = " << Version << "\n";
881
882
Offset = Contribution->Base;
883
unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
884
while (Offset - Contribution->Base < Contribution->Size) {
885
OS << format("0x%8.8" PRIx64 ": ", Offset);
886
uint64_t StringOffset =
887
StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
888
OS << format("%0*" PRIx64 " ", OffsetDumpWidth, StringOffset);
889
const char *S = StrData.getCStr(&StringOffset);
890
if (S)
891
OS << format("\"%s\"", S);
892
OS << "\n";
893
}
894
}
895
// Report a gap at the end of the table.
896
if (Offset < SectionSize) {
897
OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
898
OS << (SectionSize - Offset) << "\n";
899
}
900
}
901
902
// Dump the .debug_addr section.
903
static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
904
DIDumpOptions DumpOpts, uint16_t Version,
905
uint8_t AddrSize) {
906
uint64_t Offset = 0;
907
while (AddrData.isValidOffset(Offset)) {
908
DWARFDebugAddrTable AddrTable;
909
uint64_t TableOffset = Offset;
910
if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
911
DumpOpts.WarningHandler)) {
912
DumpOpts.RecoverableErrorHandler(std::move(Err));
913
// Keep going after an error, if we can, assuming that the length field
914
// could be read. If it couldn't, stop reading the section.
915
if (auto TableLength = AddrTable.getFullLength()) {
916
Offset = TableOffset + *TableLength;
917
continue;
918
}
919
break;
920
}
921
AddrTable.dump(OS, DumpOpts);
922
}
923
}
924
925
// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
926
static void dumpRnglistsSection(
927
raw_ostream &OS, DWARFDataExtractor &rnglistData,
928
llvm::function_ref<std::optional<object::SectionedAddress>(uint32_t)>
929
LookupPooledAddress,
930
DIDumpOptions DumpOpts) {
931
uint64_t Offset = 0;
932
while (rnglistData.isValidOffset(Offset)) {
933
llvm::DWARFDebugRnglistTable Rnglists;
934
uint64_t TableOffset = Offset;
935
if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
936
DumpOpts.RecoverableErrorHandler(std::move(Err));
937
uint64_t Length = Rnglists.length();
938
// Keep going after an error, if we can, assuming that the length field
939
// could be read. If it couldn't, stop reading the section.
940
if (Length == 0)
941
break;
942
Offset = TableOffset + Length;
943
} else {
944
Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts);
945
}
946
}
947
}
948
949
950
static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
951
DWARFDataExtractor Data, const DWARFObject &Obj,
952
std::optional<uint64_t> DumpOffset) {
953
uint64_t Offset = 0;
954
955
while (Data.isValidOffset(Offset)) {
956
DWARFListTableHeader Header(".debug_loclists", "locations");
957
if (Error E = Header.extract(Data, &Offset)) {
958
DumpOpts.RecoverableErrorHandler(std::move(E));
959
return;
960
}
961
962
Header.dump(Data, OS, DumpOpts);
963
964
uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
965
Data.setAddressSize(Header.getAddrSize());
966
DWARFDebugLoclists Loc(Data, Header.getVersion());
967
if (DumpOffset) {
968
if (DumpOffset >= Offset && DumpOffset < EndOffset) {
969
Offset = *DumpOffset;
970
Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/std::nullopt, Obj,
971
nullptr, DumpOpts, /*Indent=*/0);
972
OS << "\n";
973
return;
974
}
975
} else {
976
Loc.dumpRange(Offset, EndOffset - Offset, OS, Obj, DumpOpts);
977
}
978
Offset = EndOffset;
979
}
980
}
981
982
static void dumpPubTableSection(raw_ostream &OS, DIDumpOptions DumpOpts,
983
DWARFDataExtractor Data, bool GnuStyle) {
984
DWARFDebugPubTable Table;
985
Table.extract(Data, GnuStyle, DumpOpts.RecoverableErrorHandler);
986
Table.dump(OS);
987
}
988
989
void DWARFContext::dump(
990
raw_ostream &OS, DIDumpOptions DumpOpts,
991
std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
992
uint64_t DumpType = DumpOpts.DumpType;
993
994
StringRef Extension = sys::path::extension(DObj->getFileName());
995
bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");
996
997
// Print UUID header.
998
const auto *ObjFile = DObj->getFile();
999
if (DumpType & DIDT_UUID)
1000
dumpUUID(OS, *ObjFile);
1001
1002
// Print a header for each explicitly-requested section.
1003
// Otherwise just print one for non-empty sections.
1004
// Only print empty .dwo section headers when dumping a .dwo file.
1005
bool Explicit = DumpType != DIDT_All && !IsDWO;
1006
bool ExplicitDWO = Explicit && IsDWO;
1007
auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
1008
StringRef Section) -> std::optional<uint64_t> * {
1009
unsigned Mask = 1U << ID;
1010
bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
1011
if (!Should)
1012
return nullptr;
1013
OS << "\n" << Name << " contents:\n";
1014
return &DumpOffsets[ID];
1015
};
1016
1017
// Dump individual sections.
1018
if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,
1019
DObj->getAbbrevSection()))
1020
getDebugAbbrev()->dump(OS);
1021
if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
1022
DObj->getAbbrevDWOSection()))
1023
getDebugAbbrevDWO()->dump(OS);
1024
1025
auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
1026
OS << '\n' << Name << " contents:\n";
1027
if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
1028
for (const auto &U : Units) {
1029
U->getDIEForOffset(*DumpOffset)
1030
.dump(OS, 0, DumpOpts.noImplicitRecursion());
1031
DWARFDie CUDie = U->getUnitDIE(false);
1032
DWARFDie CUNonSkeletonDie = U->getNonSkeletonUnitDIE(false);
1033
if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie) {
1034
CUNonSkeletonDie.getDwarfUnit()
1035
->getDIEForOffset(*DumpOffset)
1036
.dump(OS, 0, DumpOpts.noImplicitRecursion());
1037
}
1038
}
1039
else
1040
for (const auto &U : Units)
1041
U->dump(OS, DumpOpts);
1042
};
1043
if ((DumpType & DIDT_DebugInfo)) {
1044
if (Explicit || getNumCompileUnits())
1045
dumpDebugInfo(".debug_info", info_section_units());
1046
if (ExplicitDWO || getNumDWOCompileUnits())
1047
dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
1048
}
1049
1050
auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
1051
OS << '\n' << Name << " contents:\n";
1052
for (const auto &U : Units)
1053
if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
1054
U->getDIEForOffset(*DumpOffset)
1055
.dump(OS, 0, DumpOpts.noImplicitRecursion());
1056
else
1057
U->dump(OS, DumpOpts);
1058
};
1059
if ((DumpType & DIDT_DebugTypes)) {
1060
if (Explicit || getNumTypeUnits())
1061
dumpDebugType(".debug_types", types_section_units());
1062
if (ExplicitDWO || getNumDWOTypeUnits())
1063
dumpDebugType(".debug_types.dwo", dwo_types_section_units());
1064
}
1065
1066
DIDumpOptions LLDumpOpts = DumpOpts;
1067
if (LLDumpOpts.Verbose)
1068
LLDumpOpts.DisplayRawContents = true;
1069
1070
if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
1071
DObj->getLocSection().Data)) {
1072
getDebugLoc()->dump(OS, *DObj, LLDumpOpts, *Off);
1073
}
1074
if (const auto *Off =
1075
shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
1076
DObj->getLoclistsSection().Data)) {
1077
DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
1078
0);
1079
dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off);
1080
}
1081
if (const auto *Off =
1082
shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists,
1083
DObj->getLoclistsDWOSection().Data)) {
1084
DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(),
1085
isLittleEndian(), 0);
1086
dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off);
1087
}
1088
1089
if (const auto *Off =
1090
shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
1091
DObj->getLocDWOSection().Data)) {
1092
DWARFDataExtractor Data(*DObj, DObj->getLocDWOSection(), isLittleEndian(),
1093
4);
1094
DWARFDebugLoclists Loc(Data, /*Version=*/4);
1095
if (*Off) {
1096
uint64_t Offset = **Off;
1097
Loc.dumpLocationList(&Offset, OS,
1098
/*BaseAddr=*/std::nullopt, *DObj, nullptr,
1099
LLDumpOpts,
1100
/*Indent=*/0);
1101
OS << "\n";
1102
} else {
1103
Loc.dumpRange(0, Data.getData().size(), OS, *DObj, LLDumpOpts);
1104
}
1105
}
1106
1107
if (const std::optional<uint64_t> *Off =
1108
shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
1109
DObj->getFrameSection().Data)) {
1110
if (Expected<const DWARFDebugFrame *> DF = getDebugFrame())
1111
(*DF)->dump(OS, DumpOpts, *Off);
1112
else
1113
RecoverableErrorHandler(DF.takeError());
1114
}
1115
1116
if (const std::optional<uint64_t> *Off =
1117
shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
1118
DObj->getEHFrameSection().Data)) {
1119
if (Expected<const DWARFDebugFrame *> DF = getEHFrame())
1120
(*DF)->dump(OS, DumpOpts, *Off);
1121
else
1122
RecoverableErrorHandler(DF.takeError());
1123
}
1124
1125
if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro,
1126
DObj->getMacroSection().Data)) {
1127
if (auto Macro = getDebugMacro())
1128
Macro->dump(OS);
1129
}
1130
1131
if (shouldDump(Explicit, ".debug_macro.dwo", DIDT_ID_DebugMacro,
1132
DObj->getMacroDWOSection())) {
1133
if (auto MacroDWO = getDebugMacroDWO())
1134
MacroDWO->dump(OS);
1135
}
1136
1137
if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro,
1138
DObj->getMacinfoSection())) {
1139
if (auto Macinfo = getDebugMacinfo())
1140
Macinfo->dump(OS);
1141
}
1142
1143
if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro,
1144
DObj->getMacinfoDWOSection())) {
1145
if (auto MacinfoDWO = getDebugMacinfoDWO())
1146
MacinfoDWO->dump(OS);
1147
}
1148
1149
if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
1150
DObj->getArangesSection())) {
1151
uint64_t offset = 0;
1152
DWARFDataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(),
1153
0);
1154
DWARFDebugArangeSet set;
1155
while (arangesData.isValidOffset(offset)) {
1156
if (Error E =
1157
set.extract(arangesData, &offset, DumpOpts.WarningHandler)) {
1158
RecoverableErrorHandler(std::move(E));
1159
break;
1160
}
1161
set.dump(OS);
1162
}
1163
}
1164
1165
auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
1166
DIDumpOptions DumpOpts,
1167
std::optional<uint64_t> DumpOffset) {
1168
while (!Parser.done()) {
1169
if (DumpOffset && Parser.getOffset() != *DumpOffset) {
1170
Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler);
1171
continue;
1172
}
1173
OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())
1174
<< "]\n";
1175
Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS,
1176
DumpOpts.Verbose);
1177
}
1178
};
1179
1180
auto DumpStrSection = [&](StringRef Section) {
1181
DataExtractor StrData(Section, isLittleEndian(), 0);
1182
uint64_t Offset = 0;
1183
uint64_t StrOffset = 0;
1184
while (StrData.isValidOffset(Offset)) {
1185
Error Err = Error::success();
1186
const char *CStr = StrData.getCStr(&Offset, &Err);
1187
if (Err) {
1188
DumpOpts.WarningHandler(std::move(Err));
1189
return;
1190
}
1191
OS << format("0x%8.8" PRIx64 ": \"", StrOffset);
1192
OS.write_escaped(CStr);
1193
OS << "\"\n";
1194
StrOffset = Offset;
1195
}
1196
};
1197
1198
if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
1199
DObj->getLineSection().Data)) {
1200
DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
1201
0);
1202
DWARFDebugLine::SectionParser Parser(LineData, *this, normal_units());
1203
DumpLineSection(Parser, DumpOpts, *Off);
1204
}
1205
1206
if (const auto *Off =
1207
shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
1208
DObj->getLineDWOSection().Data)) {
1209
DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
1210
isLittleEndian(), 0);
1211
DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_units());
1212
DumpLineSection(Parser, DumpOpts, *Off);
1213
}
1214
1215
if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
1216
DObj->getCUIndexSection())) {
1217
getCUIndex().dump(OS);
1218
}
1219
1220
if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,
1221
DObj->getTUIndexSection())) {
1222
getTUIndex().dump(OS);
1223
}
1224
1225
if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
1226
DObj->getStrSection()))
1227
DumpStrSection(DObj->getStrSection());
1228
1229
if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
1230
DObj->getStrDWOSection()))
1231
DumpStrSection(DObj->getStrDWOSection());
1232
1233
if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
1234
DObj->getLineStrSection()))
1235
DumpStrSection(DObj->getLineStrSection());
1236
1237
if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
1238
DObj->getAddrSection().Data)) {
1239
DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
1240
isLittleEndian(), 0);
1241
dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
1242
}
1243
1244
if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
1245
DObj->getRangesSection().Data)) {
1246
uint8_t savedAddressByteSize = getCUAddrSize();
1247
DWARFDataExtractor rangesData(*DObj, DObj->getRangesSection(),
1248
isLittleEndian(), savedAddressByteSize);
1249
uint64_t offset = 0;
1250
DWARFDebugRangeList rangeList;
1251
while (rangesData.isValidOffset(offset)) {
1252
if (Error E = rangeList.extract(rangesData, &offset)) {
1253
DumpOpts.RecoverableErrorHandler(std::move(E));
1254
break;
1255
}
1256
rangeList.dump(OS);
1257
}
1258
}
1259
1260
auto LookupPooledAddress =
1261
[&](uint32_t Index) -> std::optional<SectionedAddress> {
1262
const auto &CUs = compile_units();
1263
auto I = CUs.begin();
1264
if (I == CUs.end())
1265
return std::nullopt;
1266
return (*I)->getAddrOffsetSectionItem(Index);
1267
};
1268
1269
if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
1270
DObj->getRnglistsSection().Data)) {
1271
DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
1272
isLittleEndian(), 0);
1273
dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
1274
}
1275
1276
if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
1277
DObj->getRnglistsDWOSection().Data)) {
1278
DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
1279
isLittleEndian(), 0);
1280
dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
1281
}
1282
1283
if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
1284
DObj->getPubnamesSection().Data)) {
1285
DWARFDataExtractor PubTableData(*DObj, DObj->getPubnamesSection(),
1286
isLittleEndian(), 0);
1287
dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
1288
}
1289
1290
if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
1291
DObj->getPubtypesSection().Data)) {
1292
DWARFDataExtractor PubTableData(*DObj, DObj->getPubtypesSection(),
1293
isLittleEndian(), 0);
1294
dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
1295
}
1296
1297
if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
1298
DObj->getGnuPubnamesSection().Data)) {
1299
DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubnamesSection(),
1300
isLittleEndian(), 0);
1301
dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
1302
}
1303
1304
if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
1305
DObj->getGnuPubtypesSection().Data)) {
1306
DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubtypesSection(),
1307
isLittleEndian(), 0);
1308
dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
1309
}
1310
1311
if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
1312
DObj->getStrOffsetsSection().Data))
1313
dumpStringOffsetsSection(
1314
OS, DumpOpts, "debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),
1315
DObj->getStrSection(), normal_units(), isLittleEndian());
1316
if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
1317
DObj->getStrOffsetsDWOSection().Data))
1318
dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets.dwo", *DObj,
1319
DObj->getStrOffsetsDWOSection(),
1320
DObj->getStrDWOSection(), dwo_units(),
1321
isLittleEndian());
1322
1323
if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
1324
DObj->getGdbIndexSection())) {
1325
getGdbIndex().dump(OS);
1326
}
1327
1328
if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
1329
DObj->getAppleNamesSection().Data))
1330
getAppleNames().dump(OS);
1331
1332
if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
1333
DObj->getAppleTypesSection().Data))
1334
getAppleTypes().dump(OS);
1335
1336
if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,
1337
DObj->getAppleNamespacesSection().Data))
1338
getAppleNamespaces().dump(OS);
1339
1340
if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,
1341
DObj->getAppleObjCSection().Data))
1342
getAppleObjC().dump(OS);
1343
if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
1344
DObj->getNamesSection().Data))
1345
getDebugNames().dump(OS);
1346
}
1347
1348
DWARFTypeUnit *DWARFContext::getTypeUnitForHash(uint16_t Version, uint64_t Hash,
1349
bool IsDWO) {
1350
DWARFUnitVector &DWOUnits = State->getDWOUnits();
1351
if (const auto &TUI = getTUIndex()) {
1352
if (const auto *R = TUI.getFromHash(Hash))
1353
return dyn_cast_or_null<DWARFTypeUnit>(
1354
DWOUnits.getUnitForIndexEntry(*R));
1355
return nullptr;
1356
}
1357
return State->getTypeUnitMap(IsDWO).lookup(Hash);
1358
}
1359
1360
DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
1361
DWARFUnitVector &DWOUnits = State->getDWOUnits(LazyParse);
1362
1363
if (const auto &CUI = getCUIndex()) {
1364
if (const auto *R = CUI.getFromHash(Hash))
1365
return dyn_cast_or_null<DWARFCompileUnit>(
1366
DWOUnits.getUnitForIndexEntry(*R));
1367
return nullptr;
1368
}
1369
1370
// If there's no index, just search through the CUs in the DWO - there's
1371
// probably only one unless this is something like LTO - though an in-process
1372
// built/cached lookup table could be used in that case to improve repeated
1373
// lookups of different CUs in the DWO.
1374
for (const auto &DWOCU : dwo_compile_units()) {
1375
// Might not have parsed DWO ID yet.
1376
if (!DWOCU->getDWOId()) {
1377
if (std::optional<uint64_t> DWOId =
1378
toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
1379
DWOCU->setDWOId(*DWOId);
1380
else
1381
// No DWO ID?
1382
continue;
1383
}
1384
if (DWOCU->getDWOId() == Hash)
1385
return dyn_cast<DWARFCompileUnit>(DWOCU.get());
1386
}
1387
return nullptr;
1388
}
1389
1390
DWARFDie DWARFContext::getDIEForOffset(uint64_t Offset) {
1391
if (auto *CU = State->getNormalUnits().getUnitForOffset(Offset))
1392
return CU->getDIEForOffset(Offset);
1393
return DWARFDie();
1394
}
1395
1396
bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) {
1397
bool Success = true;
1398
DWARFVerifier verifier(OS, *this, DumpOpts);
1399
1400
Success &= verifier.handleDebugAbbrev();
1401
if (DumpOpts.DumpType & DIDT_DebugCUIndex)
1402
Success &= verifier.handleDebugCUIndex();
1403
if (DumpOpts.DumpType & DIDT_DebugTUIndex)
1404
Success &= verifier.handleDebugTUIndex();
1405
if (DumpOpts.DumpType & DIDT_DebugInfo)
1406
Success &= verifier.handleDebugInfo();
1407
if (DumpOpts.DumpType & DIDT_DebugLine)
1408
Success &= verifier.handleDebugLine();
1409
if (DumpOpts.DumpType & DIDT_DebugStrOffsets)
1410
Success &= verifier.handleDebugStrOffsets();
1411
Success &= verifier.handleAccelTables();
1412
verifier.summarize();
1413
return Success;
1414
}
1415
1416
const DWARFUnitIndex &DWARFContext::getCUIndex() {
1417
return State->getCUIndex();
1418
}
1419
1420
const DWARFUnitIndex &DWARFContext::getTUIndex() {
1421
return State->getTUIndex();
1422
}
1423
1424
DWARFGdbIndex &DWARFContext::getGdbIndex() {
1425
return State->getGdbIndex();
1426
}
1427
1428
const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
1429
return State->getDebugAbbrev();
1430
}
1431
1432
const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
1433
return State->getDebugAbbrevDWO();
1434
}
1435
1436
const DWARFDebugLoc *DWARFContext::getDebugLoc() {
1437
return State->getDebugLoc();
1438
}
1439
1440
const DWARFDebugAranges *DWARFContext::getDebugAranges() {
1441
return State->getDebugAranges();
1442
}
1443
1444
Expected<const DWARFDebugFrame *> DWARFContext::getDebugFrame() {
1445
return State->getDebugFrame();
1446
}
1447
1448
Expected<const DWARFDebugFrame *> DWARFContext::getEHFrame() {
1449
return State->getEHFrame();
1450
}
1451
1452
const DWARFDebugMacro *DWARFContext::getDebugMacro() {
1453
return State->getDebugMacro();
1454
}
1455
1456
const DWARFDebugMacro *DWARFContext::getDebugMacroDWO() {
1457
return State->getDebugMacroDWO();
1458
}
1459
1460
const DWARFDebugMacro *DWARFContext::getDebugMacinfo() {
1461
return State->getDebugMacinfo();
1462
}
1463
1464
const DWARFDebugMacro *DWARFContext::getDebugMacinfoDWO() {
1465
return State->getDebugMacinfoDWO();
1466
}
1467
1468
1469
const DWARFDebugNames &DWARFContext::getDebugNames() {
1470
return State->getDebugNames();
1471
}
1472
1473
const AppleAcceleratorTable &DWARFContext::getAppleNames() {
1474
return State->getAppleNames();
1475
}
1476
1477
const AppleAcceleratorTable &DWARFContext::getAppleTypes() {
1478
return State->getAppleTypes();
1479
}
1480
1481
const AppleAcceleratorTable &DWARFContext::getAppleNamespaces() {
1482
return State->getAppleNamespaces();
1483
}
1484
1485
const AppleAcceleratorTable &DWARFContext::getAppleObjC() {
1486
return State->getAppleObjC();
1487
}
1488
1489
const DWARFDebugLine::LineTable *
1490
DWARFContext::getLineTableForUnit(DWARFUnit *U) {
1491
Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable =
1492
getLineTableForUnit(U, WarningHandler);
1493
if (!ExpectedLineTable) {
1494
WarningHandler(ExpectedLineTable.takeError());
1495
return nullptr;
1496
}
1497
return *ExpectedLineTable;
1498
}
1499
1500
Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
1501
DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) {
1502
return State->getLineTableForUnit(U, RecoverableErrorHandler);
1503
}
1504
1505
void DWARFContext::clearLineTableForUnit(DWARFUnit *U) {
1506
return State->clearLineTableForUnit(U);
1507
}
1508
1509
DWARFUnitVector &DWARFContext::getDWOUnits(bool Lazy) {
1510
return State->getDWOUnits(Lazy);
1511
}
1512
1513
DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint64_t Offset) {
1514
return dyn_cast_or_null<DWARFCompileUnit>(
1515
State->getNormalUnits().getUnitForOffset(Offset));
1516
}
1517
1518
DWARFCompileUnit *DWARFContext::getCompileUnitForCodeAddress(uint64_t Address) {
1519
uint64_t CUOffset = getDebugAranges()->findAddress(Address);
1520
return getCompileUnitForOffset(CUOffset);
1521
}
1522
1523
DWARFCompileUnit *DWARFContext::getCompileUnitForDataAddress(uint64_t Address) {
1524
uint64_t CUOffset = getDebugAranges()->findAddress(Address);
1525
if (DWARFCompileUnit *OffsetCU = getCompileUnitForOffset(CUOffset))
1526
return OffsetCU;
1527
1528
// Global variables are often missed by the above search, for one of two
1529
// reasons:
1530
// 1. .debug_aranges may not include global variables. On clang, it seems we
1531
// put the globals in the aranges, but this isn't true for gcc.
1532
// 2. Even if the global variable is in a .debug_arange, global variables
1533
// may not be captured in the [start, end) addresses described by the
1534
// parent compile unit.
1535
//
1536
// So, we walk the CU's and their child DI's manually, looking for the
1537
// specific global variable.
1538
for (std::unique_ptr<DWARFUnit> &CU : compile_units()) {
1539
if (CU->getVariableForAddress(Address)) {
1540
return static_cast<DWARFCompileUnit *>(CU.get());
1541
}
1542
}
1543
return nullptr;
1544
}
1545
1546
DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address,
1547
bool CheckDWO) {
1548
DIEsForAddress Result;
1549
1550
DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address);
1551
if (!CU)
1552
return Result;
1553
1554
if (CheckDWO) {
1555
// We were asked to check the DWO file and this debug information is more
1556
// complete that any information in the skeleton compile unit, so search the
1557
// DWO first to see if we have a match.
1558
DWARFDie CUDie = CU->getUnitDIE(false);
1559
DWARFDie CUDwoDie = CU->getNonSkeletonUnitDIE(false);
1560
if (CheckDWO && CUDwoDie && CUDie != CUDwoDie) {
1561
// We have a DWO file, lets search it.
1562
DWARFCompileUnit *CUDwo =
1563
dyn_cast_or_null<DWARFCompileUnit>(CUDwoDie.getDwarfUnit());
1564
if (CUDwo) {
1565
Result.FunctionDIE = CUDwo->getSubroutineForAddress(Address);
1566
if (Result.FunctionDIE)
1567
Result.CompileUnit = CUDwo;
1568
}
1569
}
1570
}
1571
1572
// Search the normal DWARF if we didn't find a match in the DWO file or if
1573
// we didn't check the DWO file above.
1574
if (!Result) {
1575
Result.CompileUnit = CU;
1576
Result.FunctionDIE = CU->getSubroutineForAddress(Address);
1577
}
1578
1579
std::vector<DWARFDie> Worklist;
1580
Worklist.push_back(Result.FunctionDIE);
1581
while (!Worklist.empty()) {
1582
DWARFDie DIE = Worklist.back();
1583
Worklist.pop_back();
1584
1585
if (!DIE.isValid())
1586
continue;
1587
1588
if (DIE.getTag() == DW_TAG_lexical_block &&
1589
DIE.addressRangeContainsAddress(Address)) {
1590
Result.BlockDIE = DIE;
1591
break;
1592
}
1593
1594
append_range(Worklist, DIE);
1595
}
1596
1597
return Result;
1598
}
1599
1600
/// TODO: change input parameter from "uint64_t Address"
1601
/// into "SectionedAddress Address"
1602
static bool getFunctionNameAndStartLineForAddress(
1603
DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind,
1604
DILineInfoSpecifier::FileLineInfoKind FileNameKind,
1605
std::string &FunctionName, std::string &StartFile, uint32_t &StartLine,
1606
std::optional<uint64_t> &StartAddress) {
1607
// The address may correspond to instruction in some inlined function,
1608
// so we have to build the chain of inlined functions and take the
1609
// name of the topmost function in it.
1610
SmallVector<DWARFDie, 4> InlinedChain;
1611
CU->getInlinedChainForAddress(Address, InlinedChain);
1612
if (InlinedChain.empty())
1613
return false;
1614
1615
const DWARFDie &DIE = InlinedChain[0];
1616
bool FoundResult = false;
1617
const char *Name = nullptr;
1618
if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
1619
FunctionName = Name;
1620
FoundResult = true;
1621
}
1622
std::string DeclFile = DIE.getDeclFile(FileNameKind);
1623
if (!DeclFile.empty()) {
1624
StartFile = DeclFile;
1625
FoundResult = true;
1626
}
1627
if (auto DeclLineResult = DIE.getDeclLine()) {
1628
StartLine = DeclLineResult;
1629
FoundResult = true;
1630
}
1631
if (auto LowPcAddr = toSectionedAddress(DIE.find(DW_AT_low_pc)))
1632
StartAddress = LowPcAddr->Address;
1633
return FoundResult;
1634
}
1635
1636
static std::optional<int64_t>
1637
getExpressionFrameOffset(ArrayRef<uint8_t> Expr,
1638
std::optional<unsigned> FrameBaseReg) {
1639
if (!Expr.empty() &&
1640
(Expr[0] == DW_OP_fbreg ||
1641
(FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {
1642
unsigned Count;
1643
int64_t Offset = decodeSLEB128(Expr.data() + 1, &Count, Expr.end());
1644
// A single DW_OP_fbreg or DW_OP_breg.
1645
if (Expr.size() == Count + 1)
1646
return Offset;
1647
// Same + DW_OP_deref (Fortran arrays look like this).
1648
if (Expr.size() == Count + 2 && Expr[Count + 1] == DW_OP_deref)
1649
return Offset;
1650
// Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value)
1651
}
1652
return std::nullopt;
1653
}
1654
1655
void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
1656
DWARFDie Die, std::vector<DILocal> &Result) {
1657
if (Die.getTag() == DW_TAG_variable ||
1658
Die.getTag() == DW_TAG_formal_parameter) {
1659
DILocal Local;
1660
if (const char *Name = Subprogram.getSubroutineName(DINameKind::ShortName))
1661
Local.FunctionName = Name;
1662
1663
std::optional<unsigned> FrameBaseReg;
1664
if (auto FrameBase = Subprogram.find(DW_AT_frame_base))
1665
if (std::optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock())
1666
if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&
1667
(*Expr)[0] <= DW_OP_reg31) {
1668
FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
1669
}
1670
1671
if (Expected<std::vector<DWARFLocationExpression>> Loc =
1672
Die.getLocations(DW_AT_location)) {
1673
for (const auto &Entry : *Loc) {
1674
if (std::optional<int64_t> FrameOffset =
1675
getExpressionFrameOffset(Entry.Expr, FrameBaseReg)) {
1676
Local.FrameOffset = *FrameOffset;
1677
break;
1678
}
1679
}
1680
} else {
1681
// FIXME: missing DW_AT_location is OK here, but other errors should be
1682
// reported to the user.
1683
consumeError(Loc.takeError());
1684
}
1685
1686
if (auto TagOffsetAttr = Die.find(DW_AT_LLVM_tag_offset))
1687
Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();
1688
1689
if (auto Origin =
1690
Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
1691
Die = Origin;
1692
if (auto NameAttr = Die.find(DW_AT_name))
1693
if (std::optional<const char *> Name = dwarf::toString(*NameAttr))
1694
Local.Name = *Name;
1695
if (auto Type = Die.getAttributeValueAsReferencedDie(DW_AT_type))
1696
Local.Size = Type.getTypeSize(getCUAddrSize());
1697
if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) {
1698
if (const auto *LT = CU->getContext().getLineTableForUnit(CU))
1699
LT->getFileNameByIndex(
1700
*DeclFileAttr->getAsUnsignedConstant(), CU->getCompilationDir(),
1701
DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
1702
Local.DeclFile);
1703
}
1704
if (auto DeclLineAttr = Die.find(DW_AT_decl_line))
1705
Local.DeclLine = *DeclLineAttr->getAsUnsignedConstant();
1706
1707
Result.push_back(Local);
1708
return;
1709
}
1710
1711
if (Die.getTag() == DW_TAG_inlined_subroutine)
1712
if (auto Origin =
1713
Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
1714
Subprogram = Origin;
1715
1716
for (auto Child : Die)
1717
addLocalsForDie(CU, Subprogram, Child, Result);
1718
}
1719
1720
std::vector<DILocal>
1721
DWARFContext::getLocalsForAddress(object::SectionedAddress Address) {
1722
std::vector<DILocal> Result;
1723
DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
1724
if (!CU)
1725
return Result;
1726
1727
DWARFDie Subprogram = CU->getSubroutineForAddress(Address.Address);
1728
if (Subprogram.isValid())
1729
addLocalsForDie(CU, Subprogram, Subprogram, Result);
1730
return Result;
1731
}
1732
1733
DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
1734
DILineInfoSpecifier Spec) {
1735
DILineInfo Result;
1736
DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
1737
if (!CU)
1738
return Result;
1739
1740
getFunctionNameAndStartLineForAddress(
1741
CU, Address.Address, Spec.FNKind, Spec.FLIKind, Result.FunctionName,
1742
Result.StartFileName, Result.StartLine, Result.StartAddress);
1743
if (Spec.FLIKind != FileLineInfoKind::None) {
1744
if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
1745
LineTable->getFileLineInfoForAddress(
1746
{Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
1747
Spec.FLIKind, Result);
1748
}
1749
}
1750
1751
return Result;
1752
}
1753
1754
DILineInfo
1755
DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
1756
DILineInfo Result;
1757
DWARFCompileUnit *CU = getCompileUnitForDataAddress(Address.Address);
1758
if (!CU)
1759
return Result;
1760
1761
if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) {
1762
Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath);
1763
Result.Line = Die.getDeclLine();
1764
}
1765
1766
return Result;
1767
}
1768
1769
DILineInfoTable DWARFContext::getLineInfoForAddressRange(
1770
object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) {
1771
DILineInfoTable Lines;
1772
DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
1773
if (!CU)
1774
return Lines;
1775
1776
uint32_t StartLine = 0;
1777
std::string StartFileName;
1778
std::string FunctionName(DILineInfo::BadString);
1779
std::optional<uint64_t> StartAddress;
1780
getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind,
1781
Spec.FLIKind, FunctionName,
1782
StartFileName, StartLine, StartAddress);
1783
1784
// If the Specifier says we don't need FileLineInfo, just
1785
// return the top-most function at the starting address.
1786
if (Spec.FLIKind == FileLineInfoKind::None) {
1787
DILineInfo Result;
1788
Result.FunctionName = FunctionName;
1789
Result.StartFileName = StartFileName;
1790
Result.StartLine = StartLine;
1791
Result.StartAddress = StartAddress;
1792
Lines.push_back(std::make_pair(Address.Address, Result));
1793
return Lines;
1794
}
1795
1796
const DWARFLineTable *LineTable = getLineTableForUnit(CU);
1797
1798
// Get the index of row we're looking for in the line table.
1799
std::vector<uint32_t> RowVector;
1800
if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex},
1801
Size, RowVector)) {
1802
return Lines;
1803
}
1804
1805
for (uint32_t RowIndex : RowVector) {
1806
// Take file number and line/column from the row.
1807
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
1808
DILineInfo Result;
1809
LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
1810
Spec.FLIKind, Result.FileName);
1811
Result.FunctionName = FunctionName;
1812
Result.Line = Row.Line;
1813
Result.Column = Row.Column;
1814
Result.StartFileName = StartFileName;
1815
Result.StartLine = StartLine;
1816
Result.StartAddress = StartAddress;
1817
Lines.push_back(std::make_pair(Row.Address.Address, Result));
1818
}
1819
1820
return Lines;
1821
}
1822
1823
DIInliningInfo
1824
DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address,
1825
DILineInfoSpecifier Spec) {
1826
DIInliningInfo InliningInfo;
1827
1828
DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
1829
if (!CU)
1830
return InliningInfo;
1831
1832
const DWARFLineTable *LineTable = nullptr;
1833
SmallVector<DWARFDie, 4> InlinedChain;
1834
CU->getInlinedChainForAddress(Address.Address, InlinedChain);
1835
if (InlinedChain.size() == 0) {
1836
// If there is no DIE for address (e.g. it is in unavailable .dwo file),
1837
// try to at least get file/line info from symbol table.
1838
if (Spec.FLIKind != FileLineInfoKind::None) {
1839
DILineInfo Frame;
1840
LineTable = getLineTableForUnit(CU);
1841
if (LineTable && LineTable->getFileLineInfoForAddress(
1842
{Address.Address, Address.SectionIndex},
1843
CU->getCompilationDir(), Spec.FLIKind, Frame))
1844
InliningInfo.addFrame(Frame);
1845
}
1846
return InliningInfo;
1847
}
1848
1849
uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
1850
for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
1851
DWARFDie &FunctionDIE = InlinedChain[i];
1852
DILineInfo Frame;
1853
// Get function name if necessary.
1854
if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
1855
Frame.FunctionName = Name;
1856
if (auto DeclLineResult = FunctionDIE.getDeclLine())
1857
Frame.StartLine = DeclLineResult;
1858
Frame.StartFileName = FunctionDIE.getDeclFile(Spec.FLIKind);
1859
if (auto LowPcAddr = toSectionedAddress(FunctionDIE.find(DW_AT_low_pc)))
1860
Frame.StartAddress = LowPcAddr->Address;
1861
if (Spec.FLIKind != FileLineInfoKind::None) {
1862
if (i == 0) {
1863
// For the topmost frame, initialize the line table of this
1864
// compile unit and fetch file/line info from it.
1865
LineTable = getLineTableForUnit(CU);
1866
// For the topmost routine, get file/line info from line table.
1867
if (LineTable)
1868
LineTable->getFileLineInfoForAddress(
1869
{Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
1870
Spec.FLIKind, Frame);
1871
} else {
1872
// Otherwise, use call file, call line and call column from
1873
// previous DIE in inlined chain.
1874
if (LineTable)
1875
LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
1876
Spec.FLIKind, Frame.FileName);
1877
Frame.Line = CallLine;
1878
Frame.Column = CallColumn;
1879
Frame.Discriminator = CallDiscriminator;
1880
}
1881
// Get call file/line/column of a current DIE.
1882
if (i + 1 < n) {
1883
FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
1884
CallDiscriminator);
1885
}
1886
}
1887
InliningInfo.addFrame(Frame);
1888
}
1889
return InliningInfo;
1890
}
1891
1892
std::shared_ptr<DWARFContext>
1893
DWARFContext::getDWOContext(StringRef AbsolutePath) {
1894
return State->getDWOContext(AbsolutePath);
1895
}
1896
1897
static Error createError(const Twine &Reason, llvm::Error E) {
1898
return make_error<StringError>(Reason + toString(std::move(E)),
1899
inconvertibleErrorCode());
1900
}
1901
1902
/// SymInfo contains information about symbol: it's address
1903
/// and section index which is -1LL for absolute symbols.
1904
struct SymInfo {
1905
uint64_t Address;
1906
uint64_t SectionIndex;
1907
};
1908
1909
/// Returns the address of symbol relocation used against and a section index.
1910
/// Used for futher relocations computation. Symbol's section load address is
1911
static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj,
1912
const RelocationRef &Reloc,
1913
const LoadedObjectInfo *L,
1914
std::map<SymbolRef, SymInfo> &Cache) {
1915
SymInfo Ret = {0, (uint64_t)-1LL};
1916
object::section_iterator RSec = Obj.section_end();
1917
object::symbol_iterator Sym = Reloc.getSymbol();
1918
1919
std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
1920
// First calculate the address of the symbol or section as it appears
1921
// in the object file
1922
if (Sym != Obj.symbol_end()) {
1923
bool New;
1924
std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
1925
if (!New)
1926
return CacheIt->second;
1927
1928
Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
1929
if (!SymAddrOrErr)
1930
return createError("failed to compute symbol address: ",
1931
SymAddrOrErr.takeError());
1932
1933
// Also remember what section this symbol is in for later
1934
auto SectOrErr = Sym->getSection();
1935
if (!SectOrErr)
1936
return createError("failed to get symbol section: ",
1937
SectOrErr.takeError());
1938
1939
RSec = *SectOrErr;
1940
Ret.Address = *SymAddrOrErr;
1941
} else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1942
RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
1943
Ret.Address = RSec->getAddress();
1944
}
1945
1946
if (RSec != Obj.section_end())
1947
Ret.SectionIndex = RSec->getIndex();
1948
1949
// If we are given load addresses for the sections, we need to adjust:
1950
// SymAddr = (Address of Symbol Or Section in File) -
1951
// (Address of Section in File) +
1952
// (Load Address of Section)
1953
// RSec is now either the section being targeted or the section
1954
// containing the symbol being targeted. In either case,
1955
// we need to perform the same computation.
1956
if (L && RSec != Obj.section_end())
1957
if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1958
Ret.Address += SectionLoadAddress - RSec->getAddress();
1959
1960
if (CacheIt != Cache.end())
1961
CacheIt->second = Ret;
1962
1963
return Ret;
1964
}
1965
1966
static bool isRelocScattered(const object::ObjectFile &Obj,
1967
const RelocationRef &Reloc) {
1968
const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
1969
if (!MachObj)
1970
return false;
1971
// MachO also has relocations that point to sections and
1972
// scattered relocations.
1973
auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
1974
return MachObj->isRelocationScattered(RelocInfo);
1975
}
1976
1977
namespace {
1978
struct DWARFSectionMap final : public DWARFSection {
1979
RelocAddrMap Relocs;
1980
};
1981
1982
class DWARFObjInMemory final : public DWARFObject {
1983
bool IsLittleEndian;
1984
uint8_t AddressSize;
1985
StringRef FileName;
1986
const object::ObjectFile *Obj = nullptr;
1987
std::vector<SectionName> SectionNames;
1988
1989
using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
1990
std::map<object::SectionRef, unsigned>>;
1991
1992
InfoSectionMap InfoSections;
1993
InfoSectionMap TypesSections;
1994
InfoSectionMap InfoDWOSections;
1995
InfoSectionMap TypesDWOSections;
1996
1997
DWARFSectionMap LocSection;
1998
DWARFSectionMap LoclistsSection;
1999
DWARFSectionMap LoclistsDWOSection;
2000
DWARFSectionMap LineSection;
2001
DWARFSectionMap RangesSection;
2002
DWARFSectionMap RnglistsSection;
2003
DWARFSectionMap StrOffsetsSection;
2004
DWARFSectionMap LineDWOSection;
2005
DWARFSectionMap FrameSection;
2006
DWARFSectionMap EHFrameSection;
2007
DWARFSectionMap LocDWOSection;
2008
DWARFSectionMap StrOffsetsDWOSection;
2009
DWARFSectionMap RangesDWOSection;
2010
DWARFSectionMap RnglistsDWOSection;
2011
DWARFSectionMap AddrSection;
2012
DWARFSectionMap AppleNamesSection;
2013
DWARFSectionMap AppleTypesSection;
2014
DWARFSectionMap AppleNamespacesSection;
2015
DWARFSectionMap AppleObjCSection;
2016
DWARFSectionMap NamesSection;
2017
DWARFSectionMap PubnamesSection;
2018
DWARFSectionMap PubtypesSection;
2019
DWARFSectionMap GnuPubnamesSection;
2020
DWARFSectionMap GnuPubtypesSection;
2021
DWARFSectionMap MacroSection;
2022
2023
DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
2024
return StringSwitch<DWARFSectionMap *>(Name)
2025
.Case("debug_loc", &LocSection)
2026
.Case("debug_loclists", &LoclistsSection)
2027
.Case("debug_loclists.dwo", &LoclistsDWOSection)
2028
.Case("debug_line", &LineSection)
2029
.Case("debug_frame", &FrameSection)
2030
.Case("eh_frame", &EHFrameSection)
2031
.Case("debug_str_offsets", &StrOffsetsSection)
2032
.Case("debug_ranges", &RangesSection)
2033
.Case("debug_rnglists", &RnglistsSection)
2034
.Case("debug_loc.dwo", &LocDWOSection)
2035
.Case("debug_line.dwo", &LineDWOSection)
2036
.Case("debug_names", &NamesSection)
2037
.Case("debug_rnglists.dwo", &RnglistsDWOSection)
2038
.Case("debug_str_offsets.dwo", &StrOffsetsDWOSection)
2039
.Case("debug_addr", &AddrSection)
2040
.Case("apple_names", &AppleNamesSection)
2041
.Case("debug_pubnames", &PubnamesSection)
2042
.Case("debug_pubtypes", &PubtypesSection)
2043
.Case("debug_gnu_pubnames", &GnuPubnamesSection)
2044
.Case("debug_gnu_pubtypes", &GnuPubtypesSection)
2045
.Case("apple_types", &AppleTypesSection)
2046
.Case("apple_namespaces", &AppleNamespacesSection)
2047
.Case("apple_namespac", &AppleNamespacesSection)
2048
.Case("apple_objc", &AppleObjCSection)
2049
.Case("debug_macro", &MacroSection)
2050
.Default(nullptr);
2051
}
2052
2053
StringRef AbbrevSection;
2054
StringRef ArangesSection;
2055
StringRef StrSection;
2056
StringRef MacinfoSection;
2057
StringRef MacinfoDWOSection;
2058
StringRef MacroDWOSection;
2059
StringRef AbbrevDWOSection;
2060
StringRef StrDWOSection;
2061
StringRef CUIndexSection;
2062
StringRef GdbIndexSection;
2063
StringRef TUIndexSection;
2064
StringRef LineStrSection;
2065
2066
// A deque holding section data whose iterators are not invalidated when
2067
// new decompressed sections are inserted at the end.
2068
std::deque<SmallString<0>> UncompressedSections;
2069
2070
StringRef *mapSectionToMember(StringRef Name) {
2071
if (DWARFSection *Sec = mapNameToDWARFSection(Name))
2072
return &Sec->Data;
2073
return StringSwitch<StringRef *>(Name)
2074
.Case("debug_abbrev", &AbbrevSection)
2075
.Case("debug_aranges", &ArangesSection)
2076
.Case("debug_str", &StrSection)
2077
.Case("debug_macinfo", &MacinfoSection)
2078
.Case("debug_macinfo.dwo", &MacinfoDWOSection)
2079
.Case("debug_macro.dwo", &MacroDWOSection)
2080
.Case("debug_abbrev.dwo", &AbbrevDWOSection)
2081
.Case("debug_str.dwo", &StrDWOSection)
2082
.Case("debug_cu_index", &CUIndexSection)
2083
.Case("debug_tu_index", &TUIndexSection)
2084
.Case("gdb_index", &GdbIndexSection)
2085
.Case("debug_line_str", &LineStrSection)
2086
// Any more debug info sections go here.
2087
.Default(nullptr);
2088
}
2089
2090
/// If Sec is compressed section, decompresses and updates its contents
2091
/// provided by Data. Otherwise leaves it unchanged.
2092
Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
2093
StringRef &Data) {
2094
if (!Sec.isCompressed())
2095
return Error::success();
2096
2097
Expected<Decompressor> Decompressor =
2098
Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
2099
if (!Decompressor)
2100
return Decompressor.takeError();
2101
2102
SmallString<0> Out;
2103
if (auto Err = Decompressor->resizeAndDecompress(Out))
2104
return Err;
2105
2106
UncompressedSections.push_back(std::move(Out));
2107
Data = UncompressedSections.back();
2108
2109
return Error::success();
2110
}
2111
2112
public:
2113
DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
2114
uint8_t AddrSize, bool IsLittleEndian)
2115
: IsLittleEndian(IsLittleEndian) {
2116
for (const auto &SecIt : Sections) {
2117
if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
2118
*SectionData = SecIt.second->getBuffer();
2119
else if (SecIt.first() == "debug_info")
2120
// Find debug_info and debug_types data by section rather than name as
2121
// there are multiple, comdat grouped, of these sections.
2122
InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
2123
else if (SecIt.first() == "debug_info.dwo")
2124
InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
2125
else if (SecIt.first() == "debug_types")
2126
TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
2127
else if (SecIt.first() == "debug_types.dwo")
2128
TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
2129
}
2130
}
2131
DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
2132
function_ref<void(Error)> HandleError,
2133
function_ref<void(Error)> HandleWarning,
2134
DWARFContext::ProcessDebugRelocations RelocAction)
2135
: IsLittleEndian(Obj.isLittleEndian()),
2136
AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
2137
Obj(&Obj) {
2138
2139
StringMap<unsigned> SectionAmountMap;
2140
for (const SectionRef &Section : Obj.sections()) {
2141
StringRef Name;
2142
if (auto NameOrErr = Section.getName())
2143
Name = *NameOrErr;
2144
else
2145
consumeError(NameOrErr.takeError());
2146
2147
++SectionAmountMap[Name];
2148
SectionNames.push_back({ Name, true });
2149
2150
// Skip BSS and Virtual sections, they aren't interesting.
2151
if (Section.isBSS() || Section.isVirtual())
2152
continue;
2153
2154
// Skip sections stripped by dsymutil.
2155
if (Section.isStripped())
2156
continue;
2157
2158
StringRef Data;
2159
Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
2160
if (!SecOrErr) {
2161
HandleError(createError("failed to get relocated section: ",
2162
SecOrErr.takeError()));
2163
continue;
2164
}
2165
2166
// Try to obtain an already relocated version of this section.
2167
// Else use the unrelocated section from the object file. We'll have to
2168
// apply relocations ourselves later.
2169
section_iterator RelocatedSection =
2170
Obj.isRelocatableObject() ? *SecOrErr : Obj.section_end();
2171
if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
2172
Expected<StringRef> E = Section.getContents();
2173
if (E)
2174
Data = *E;
2175
else
2176
// maybeDecompress below will error.
2177
consumeError(E.takeError());
2178
}
2179
2180
if (auto Err = maybeDecompress(Section, Name, Data)) {
2181
HandleError(createError("failed to decompress '" + Name + "', ",
2182
std::move(Err)));
2183
continue;
2184
}
2185
2186
// Map platform specific debug section names to DWARF standard section
2187
// names.
2188
Name = Name.substr(Name.find_first_not_of("._"));
2189
Name = Obj.mapDebugSectionName(Name);
2190
2191
if (StringRef *SectionData = mapSectionToMember(Name)) {
2192
*SectionData = Data;
2193
if (Name == "debug_ranges") {
2194
// FIXME: Use the other dwo range section when we emit it.
2195
RangesDWOSection.Data = Data;
2196
} else if (Name == "debug_frame" || Name == "eh_frame") {
2197
if (DWARFSection *S = mapNameToDWARFSection(Name))
2198
S->Address = Section.getAddress();
2199
}
2200
} else if (InfoSectionMap *Sections =
2201
StringSwitch<InfoSectionMap *>(Name)
2202
.Case("debug_info", &InfoSections)
2203
.Case("debug_info.dwo", &InfoDWOSections)
2204
.Case("debug_types", &TypesSections)
2205
.Case("debug_types.dwo", &TypesDWOSections)
2206
.Default(nullptr)) {
2207
// Find debug_info and debug_types data by section rather than name as
2208
// there are multiple, comdat grouped, of these sections.
2209
DWARFSectionMap &S = (*Sections)[Section];
2210
S.Data = Data;
2211
}
2212
2213
if (RelocatedSection == Obj.section_end() ||
2214
(RelocAction == DWARFContext::ProcessDebugRelocations::Ignore))
2215
continue;
2216
2217
StringRef RelSecName;
2218
if (auto NameOrErr = RelocatedSection->getName())
2219
RelSecName = *NameOrErr;
2220
else
2221
consumeError(NameOrErr.takeError());
2222
2223
// If the section we're relocating was relocated already by the JIT,
2224
// then we used the relocated version above, so we do not need to process
2225
// relocations for it now.
2226
StringRef RelSecData;
2227
if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
2228
continue;
2229
2230
// In Mach-o files, the relocations do not need to be applied if
2231
// there is no load offset to apply. The value read at the
2232
// relocation point already factors in the section address
2233
// (actually applying the relocations will produce wrong results
2234
// as the section address will be added twice).
2235
if (!L && isa<MachOObjectFile>(&Obj))
2236
continue;
2237
2238
if (!Section.relocations().empty() && Name.ends_with(".dwo") &&
2239
RelSecName.starts_with(".debug")) {
2240
HandleWarning(createError("unexpected relocations for dwo section '" +
2241
RelSecName + "'"));
2242
}
2243
2244
// TODO: Add support for relocations in other sections as needed.
2245
// Record relocations for the debug_info and debug_line sections.
2246
RelSecName = RelSecName.substr(RelSecName.find_first_not_of("._"));
2247
DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
2248
RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
2249
if (!Map) {
2250
// Find debug_info and debug_types relocs by section rather than name
2251
// as there are multiple, comdat grouped, of these sections.
2252
if (RelSecName == "debug_info")
2253
Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
2254
.Relocs;
2255
else if (RelSecName == "debug_types")
2256
Map =
2257
&static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
2258
.Relocs;
2259
else
2260
continue;
2261
}
2262
2263
if (Section.relocation_begin() == Section.relocation_end())
2264
continue;
2265
2266
// Symbol to [address, section index] cache mapping.
2267
std::map<SymbolRef, SymInfo> AddrCache;
2268
SupportsRelocation Supports;
2269
RelocationResolver Resolver;
2270
std::tie(Supports, Resolver) = getRelocationResolver(Obj);
2271
for (const RelocationRef &Reloc : Section.relocations()) {
2272
// FIXME: it's not clear how to correctly handle scattered
2273
// relocations.
2274
if (isRelocScattered(Obj, Reloc))
2275
continue;
2276
2277
Expected<SymInfo> SymInfoOrErr =
2278
getSymbolInfo(Obj, Reloc, L, AddrCache);
2279
if (!SymInfoOrErr) {
2280
HandleError(SymInfoOrErr.takeError());
2281
continue;
2282
}
2283
2284
// Check if Resolver can handle this relocation type early so as not to
2285
// handle invalid cases in DWARFDataExtractor.
2286
//
2287
// TODO Don't store Resolver in every RelocAddrEntry.
2288
if (Supports && Supports(Reloc.getType())) {
2289
auto I = Map->try_emplace(
2290
Reloc.getOffset(),
2291
RelocAddrEntry{
2292
SymInfoOrErr->SectionIndex, Reloc, SymInfoOrErr->Address,
2293
std::optional<object::RelocationRef>(), 0, Resolver});
2294
// If we didn't successfully insert that's because we already had a
2295
// relocation for that offset. Store it as a second relocation in the
2296
// same RelocAddrEntry instead.
2297
if (!I.second) {
2298
RelocAddrEntry &entry = I.first->getSecond();
2299
if (entry.Reloc2) {
2300
HandleError(createError(
2301
"At most two relocations per offset are supported"));
2302
}
2303
entry.Reloc2 = Reloc;
2304
entry.SymbolValue2 = SymInfoOrErr->Address;
2305
}
2306
} else {
2307
SmallString<32> Type;
2308
Reloc.getTypeName(Type);
2309
// FIXME: Support more relocations & change this to an error
2310
HandleWarning(
2311
createError("failed to compute relocation: " + Type + ", ",
2312
errorCodeToError(object_error::parse_failed)));
2313
}
2314
}
2315
}
2316
2317
for (SectionName &S : SectionNames)
2318
if (SectionAmountMap[S.Name] > 1)
2319
S.IsNameUnique = false;
2320
}
2321
2322
std::optional<RelocAddrEntry> find(const DWARFSection &S,
2323
uint64_t Pos) const override {
2324
auto &Sec = static_cast<const DWARFSectionMap &>(S);
2325
RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
2326
if (AI == Sec.Relocs.end())
2327
return std::nullopt;
2328
return AI->second;
2329
}
2330
2331
const object::ObjectFile *getFile() const override { return Obj; }
2332
2333
ArrayRef<SectionName> getSectionNames() const override {
2334
return SectionNames;
2335
}
2336
2337
bool isLittleEndian() const override { return IsLittleEndian; }
2338
StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
2339
const DWARFSection &getLineDWOSection() const override {
2340
return LineDWOSection;
2341
}
2342
const DWARFSection &getLocDWOSection() const override {
2343
return LocDWOSection;
2344
}
2345
StringRef getStrDWOSection() const override { return StrDWOSection; }
2346
const DWARFSection &getStrOffsetsDWOSection() const override {
2347
return StrOffsetsDWOSection;
2348
}
2349
const DWARFSection &getRangesDWOSection() const override {
2350
return RangesDWOSection;
2351
}
2352
const DWARFSection &getRnglistsDWOSection() const override {
2353
return RnglistsDWOSection;
2354
}
2355
const DWARFSection &getLoclistsDWOSection() const override {
2356
return LoclistsDWOSection;
2357
}
2358
const DWARFSection &getAddrSection() const override { return AddrSection; }
2359
StringRef getCUIndexSection() const override { return CUIndexSection; }
2360
StringRef getGdbIndexSection() const override { return GdbIndexSection; }
2361
StringRef getTUIndexSection() const override { return TUIndexSection; }
2362
2363
// DWARF v5
2364
const DWARFSection &getStrOffsetsSection() const override {
2365
return StrOffsetsSection;
2366
}
2367
StringRef getLineStrSection() const override { return LineStrSection; }
2368
2369
// Sections for DWARF5 split dwarf proposal.
2370
void forEachInfoDWOSections(
2371
function_ref<void(const DWARFSection &)> F) const override {
2372
for (auto &P : InfoDWOSections)
2373
F(P.second);
2374
}
2375
void forEachTypesDWOSections(
2376
function_ref<void(const DWARFSection &)> F) const override {
2377
for (auto &P : TypesDWOSections)
2378
F(P.second);
2379
}
2380
2381
StringRef getAbbrevSection() const override { return AbbrevSection; }
2382
const DWARFSection &getLocSection() const override { return LocSection; }
2383
const DWARFSection &getLoclistsSection() const override { return LoclistsSection; }
2384
StringRef getArangesSection() const override { return ArangesSection; }
2385
const DWARFSection &getFrameSection() const override {
2386
return FrameSection;
2387
}
2388
const DWARFSection &getEHFrameSection() const override {
2389
return EHFrameSection;
2390
}
2391
const DWARFSection &getLineSection() const override { return LineSection; }
2392
StringRef getStrSection() const override { return StrSection; }
2393
const DWARFSection &getRangesSection() const override { return RangesSection; }
2394
const DWARFSection &getRnglistsSection() const override {
2395
return RnglistsSection;
2396
}
2397
const DWARFSection &getMacroSection() const override { return MacroSection; }
2398
StringRef getMacroDWOSection() const override { return MacroDWOSection; }
2399
StringRef getMacinfoSection() const override { return MacinfoSection; }
2400
StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }
2401
const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }
2402
const DWARFSection &getPubtypesSection() const override { return PubtypesSection; }
2403
const DWARFSection &getGnuPubnamesSection() const override {
2404
return GnuPubnamesSection;
2405
}
2406
const DWARFSection &getGnuPubtypesSection() const override {
2407
return GnuPubtypesSection;
2408
}
2409
const DWARFSection &getAppleNamesSection() const override {
2410
return AppleNamesSection;
2411
}
2412
const DWARFSection &getAppleTypesSection() const override {
2413
return AppleTypesSection;
2414
}
2415
const DWARFSection &getAppleNamespacesSection() const override {
2416
return AppleNamespacesSection;
2417
}
2418
const DWARFSection &getAppleObjCSection() const override {
2419
return AppleObjCSection;
2420
}
2421
const DWARFSection &getNamesSection() const override {
2422
return NamesSection;
2423
}
2424
2425
StringRef getFileName() const override { return FileName; }
2426
uint8_t getAddressSize() const override { return AddressSize; }
2427
void forEachInfoSections(
2428
function_ref<void(const DWARFSection &)> F) const override {
2429
for (auto &P : InfoSections)
2430
F(P.second);
2431
}
2432
void forEachTypesSections(
2433
function_ref<void(const DWARFSection &)> F) const override {
2434
for (auto &P : TypesSections)
2435
F(P.second);
2436
}
2437
};
2438
} // namespace
2439
2440
std::unique_ptr<DWARFContext>
2441
DWARFContext::create(const object::ObjectFile &Obj,
2442
ProcessDebugRelocations RelocAction,
2443
const LoadedObjectInfo *L, std::string DWPName,
2444
std::function<void(Error)> RecoverableErrorHandler,
2445
std::function<void(Error)> WarningHandler,
2446
bool ThreadSafe) {
2447
auto DObj = std::make_unique<DWARFObjInMemory>(
2448
Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);
2449
return std::make_unique<DWARFContext>(std::move(DObj),
2450
std::move(DWPName),
2451
RecoverableErrorHandler,
2452
WarningHandler,
2453
ThreadSafe);
2454
}
2455
2456
std::unique_ptr<DWARFContext>
2457
DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
2458
uint8_t AddrSize, bool isLittleEndian,
2459
std::function<void(Error)> RecoverableErrorHandler,
2460
std::function<void(Error)> WarningHandler,
2461
bool ThreadSafe) {
2462
auto DObj =
2463
std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
2464
return std::make_unique<DWARFContext>(
2465
std::move(DObj), "", RecoverableErrorHandler, WarningHandler, ThreadSafe);
2466
}
2467
2468
uint8_t DWARFContext::getCUAddrSize() {
2469
// In theory, different compile units may have different address byte
2470
// sizes, but for simplicity we just use the address byte size of the
2471
// first compile unit. In practice the address size field is repeated across
2472
// various DWARF headers (at least in version 5) to make it easier to dump
2473
// them independently, not to enable varying the address size.
2474
auto CUs = compile_units();
2475
return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
2476
}
2477
2478