llvm.org GIT mirror llvm / ee809ac
Use delegation instead of inheritance. This changes DwarfContext to delegate to DwarfObject instead of having pure virtual methods. With this DwarfContextInMemory is replaced with an implementation of DwarfObject that is local to a .cpp file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308543 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 2 years ago
20 changed file(s) with 713 addition(s) and 603 deletion(s). Raw diff Collapse all Expand all
2525 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
2626 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
2727 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
28 #include "llvm/DebugInfo/DWARF/DWARFObject.h"
2829 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
2930 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
3031 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
4445 class MemoryBuffer;
4546 class raw_ostream;
4647
48 /// Used as a return value for a error callback passed to DWARF context.
49 /// Callback should return Halt if client application wants to stop
50 /// object parsing, or should return Continue otherwise.
51 enum class ErrorPolicy { Halt, Continue };
52
4753 /// DWARFContext
4854 /// This data structure is the top level entity that deals with dwarf debug
49 /// information parsing. The actual data is supplied through pure virtual
50 /// methods that a concrete implementation provides.
55 /// information parsing. The actual data is supplied through DWARFObj.
5156 class DWARFContext : public DIContext {
5257 DWARFUnitSection CUs;
5358 std::deque> TUs;
9499 /// and store them in DWOTUs.
95100 void parseDWOTypeUnits();
96101
102 protected:
103 std::unique_ptr DObj;
104
97105 public:
98 DWARFContext() : DIContext(CK_DWARF) {}
106 DWARFContext(std::unique_ptr DObj)
107 : DIContext(CK_DWARF), DObj(std::move(DObj)) {}
99108 DWARFContext(DWARFContext &) = delete;
100109 DWARFContext &operator=(DWARFContext &) = delete;
110
111 const DWARFObject &getDWARFObj() const { return *DObj; }
101112
102113 static bool classof(const DIContext *DICtx) {
103114 return DICtx->getKind() == CK_DWARF;
221232 DIInliningInfo getInliningInfoForAddress(uint64_t Address,
222233 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
223234
224 virtual StringRef getFileName() const = 0;
225 virtual bool isLittleEndian() const = 0;
226 virtual uint8_t getAddressSize() const = 0;
227 virtual const DWARFSection &getInfoSection() = 0;
228 virtual void forEachTypesSections(function_ref F) = 0;
229 virtual StringRef getAbbrevSection() = 0;
230 virtual const DWARFSection &getLocSection() = 0;
231 virtual StringRef getARangeSection() = 0;
232 virtual StringRef getDebugFrameSection() = 0;
233 virtual StringRef getEHFrameSection() = 0;
234 virtual const DWARFSection &getLineSection() = 0;
235 virtual StringRef getStringSection() = 0;
236 virtual const DWARFSection& getRangeSection() = 0;
237 virtual StringRef getMacinfoSection() = 0;
238 virtual StringRef getPubNamesSection() = 0;
239 virtual StringRef getPubTypesSection() = 0;
240 virtual StringRef getGnuPubNamesSection() = 0;
241 virtual StringRef getGnuPubTypesSection() = 0;
242
243 /// DWARF v5
244 /// @{
245 virtual const DWARFSection &getStringOffsetSection() = 0;
246 /// @}
247
248 // Sections for DWARF5 split dwarf proposal.
249 virtual const DWARFSection &getInfoDWOSection() = 0;
250 virtual void
251 forEachTypesDWOSections(function_ref F) = 0;
252 virtual StringRef getAbbrevDWOSection() = 0;
253 virtual const DWARFSection &getLineDWOSection() = 0;
254 virtual const DWARFSection &getLocDWOSection() = 0;
255 virtual StringRef getStringDWOSection() = 0;
256 virtual const DWARFSection &getStringOffsetDWOSection() = 0;
257 virtual const DWARFSection &getRangeDWOSection() = 0;
258 virtual const DWARFSection &getAddrSection() = 0;
259 virtual const DWARFSection& getAppleNamesSection() = 0;
260 virtual const DWARFSection& getAppleTypesSection() = 0;
261 virtual const DWARFSection& getAppleNamespacesSection() = 0;
262 virtual const DWARFSection& getAppleObjCSection() = 0;
263 virtual StringRef getCUIndexSection() = 0;
264 virtual StringRef getGdbIndexSection() = 0;
265 virtual StringRef getTUIndexSection() = 0;
266
235 bool isLittleEndian() const { return DObj->isLittleEndian(); }
267236 static bool isSupportedVersion(unsigned version) {
268237 return version == 2 || version == 3 || version == 4 || version == 5;
269238 }
270239
271240 std::shared_ptr getDWOContext(StringRef AbsolutePath);
241
242 /// Function used to handle default error reporting policy. Prints a error
243 /// message and returns Continue, so DWARF context ignores the error.
244 static ErrorPolicy defaultErrorHandler(Error E);
245 static std::unique_ptr
246 create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
247 function_ref HandleError = defaultErrorHandler);
248
249 static std::unique_ptr
250 create(const StringMap> &Sections,
251 uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost);
272252
273253 private:
274254 /// Return the compile unit that includes an offset (relative to .debug_info).
279259 DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
280260 };
281261
282 /// Used as a return value for a error callback passed to DWARF context.
283 /// Callback should return Halt if client application wants to stop
284 /// object parsing, or should return Continue otherwise.
285 enum class ErrorPolicy { Halt, Continue };
286
287 /// DWARFContextInMemory is the simplest possible implementation of a
288 /// DWARFContext. It assumes all content is available in memory and stores
289 /// pointers to it.
290 class DWARFContextInMemory : public DWARFContext {
291 virtual void anchor();
292
293 using TypeSectionMap = MapVector
294 std::map>;
295
296 StringRef FileName;
297 bool IsLittleEndian;
298 uint8_t AddressSize;
299 DWARFSection InfoSection;
300 TypeSectionMap TypesSections;
301 StringRef AbbrevSection;
302 DWARFSection LocSection;
303 StringRef ARangeSection;
304 StringRef DebugFrameSection;
305 StringRef EHFrameSection;
306 DWARFSection LineSection;
307 StringRef StringSection;
308 DWARFSection RangeSection;
309 StringRef MacinfoSection;
310 StringRef PubNamesSection;
311 StringRef PubTypesSection;
312 StringRef GnuPubNamesSection;
313 StringRef GnuPubTypesSection;
314
315 /// DWARF v5
316 /// @{
317 DWARFSection StringOffsetSection;
318 /// @}
319
320 // Sections for DWARF5 split dwarf proposal.
321 DWARFSection InfoDWOSection;
322 TypeSectionMap TypesDWOSections;
323 StringRef AbbrevDWOSection;
324 DWARFSection LineDWOSection;
325 DWARFSection LocDWOSection;
326 StringRef StringDWOSection;
327 DWARFSection StringOffsetDWOSection;
328 DWARFSection RangeDWOSection;
329 DWARFSection AddrSection;
330 DWARFSection AppleNamesSection;
331 DWARFSection AppleTypesSection;
332 DWARFSection AppleNamespacesSection;
333 DWARFSection AppleObjCSection;
334 StringRef CUIndexSection;
335 StringRef GdbIndexSection;
336 StringRef TUIndexSection;
337
338 SmallVector, 4> UncompressedSections;
339
340 DWARFSection *mapNameToDWARFSection(StringRef Name);
341 StringRef *mapSectionToMember(StringRef Name);
342
343 /// If Sec is compressed section, decompresses and updates its contents
344 /// provided by Data. Otherwise leaves it unchanged.
345 Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
346 StringRef &Data);
347
348 /// Function used to handle default error reporting policy. Prints a error
349 /// message and returns Continue, so DWARF context ignores the error.
350 static ErrorPolicy defaultErrorHandler(Error E);
351
352 public:
353 DWARFContextInMemory(
354 const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
355 function_ref HandleError = defaultErrorHandler);
356
357 DWARFContextInMemory(const StringMap> &Sections,
358 uint8_t AddrSize,
359 bool isLittleEndian = sys::IsLittleEndianHost);
360
361 StringRef getFileName() const override { return FileName; }
362 bool isLittleEndian() const override { return IsLittleEndian; }
363 uint8_t getAddressSize() const override { return AddressSize; }
364 const DWARFSection &getInfoSection() override { return InfoSection; }
365 void forEachTypesSections(function_ref F) override {
366 for (auto &P : TypesSections)
367 F(P.second);
368 }
369 StringRef getAbbrevSection() override { return AbbrevSection; }
370 const DWARFSection &getLocSection() override { return LocSection; }
371 StringRef getARangeSection() override { return ARangeSection; }
372 StringRef getDebugFrameSection() override { return DebugFrameSection; }
373 StringRef getEHFrameSection() override { return EHFrameSection; }
374 const DWARFSection &getLineSection() override { return LineSection; }
375 StringRef getStringSection() override { return StringSection; }
376 const DWARFSection &getRangeSection() override { return RangeSection; }
377 StringRef getMacinfoSection() override { return MacinfoSection; }
378 StringRef getPubNamesSection() override { return PubNamesSection; }
379 StringRef getPubTypesSection() override { return PubTypesSection; }
380 StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; }
381 StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; }
382 const DWARFSection& getAppleNamesSection() override { return AppleNamesSection; }
383 const DWARFSection& getAppleTypesSection() override { return AppleTypesSection; }
384 const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; }
385 const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; }
386
387 // DWARF v5
388 const DWARFSection &getStringOffsetSection() override {
389 return StringOffsetSection;
390 }
391
392 // Sections for DWARF5 split dwarf proposal.
393 const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
394
395 void forEachTypesDWOSections(function_ref F) override {
396 for (auto &P : TypesDWOSections)
397 F(P.second);
398 }
399
400 StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; }
401 const DWARFSection &getLineDWOSection() override { return LineDWOSection; }
402 const DWARFSection &getLocDWOSection() override { return LocDWOSection; }
403 StringRef getStringDWOSection() override { return StringDWOSection; }
404
405 const DWARFSection &getStringOffsetDWOSection() override {
406 return StringOffsetDWOSection;
407 }
408
409 const DWARFSection &getRangeDWOSection() override { return RangeDWOSection; }
410
411 const DWARFSection &getAddrSection() override { return AddrSection; }
412
413 StringRef getCUIndexSection() override { return CUIndexSection; }
414 StringRef getGdbIndexSection() override { return GdbIndexSection; }
415 StringRef getTUIndexSection() override { return TUIndexSection; }
416 };
417
418262 } // end namespace llvm
419263
420264 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
1313 #include "llvm/Support/DataExtractor.h"
1414
1515 namespace llvm {
16 class DWARFObject;
1617
1718 /// A DataExtractor (typically for an in-memory copy of an object-file section)
1819 /// plus a relocation map for that section, if there is one.
1920 class DWARFDataExtractor : public DataExtractor {
20 const RelocAddrMap *RelocMap = nullptr;
21 const DWARFObject *Obj = nullptr;
22 const DWARFSection *Section = nullptr;
23
2124 public:
2225 /// Constructor for the normal case of extracting data from a DWARF section.
2326 /// The DWARFSection's lifetime must be at least as long as the extractor's.
24 DWARFDataExtractor(const DWARFSection &Section, bool IsLittleEndian,
25 uint8_t AddressSize)
26 : DataExtractor(Section.Data, IsLittleEndian, AddressSize),
27 RelocMap(&Section.Relocs) {}
27 DWARFDataExtractor(const DWARFObject &Obj, const DWARFSection &Section,
28 bool IsLittleEndian, uint8_t AddressSize)
29 : DataExtractor(Section.Data, IsLittleEndian, AddressSize), Obj(&Obj),
30 Section(&Section) {}
2831
2932 /// Constructor for cases when there are no relocations.
3033 DWARFDataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
0 //===- DWARFObject.h --------------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===-----------------------------------------------------------------------===/
8
9 #ifndef LLVM_DEBUGINFO_DWARF_DWARFOBJECT_H
10 #define LLVM_DEBUGINFO_DWARF_DWARFOBJECT_H
11
12 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
13
14 namespace llvm {
15 // This is responsible for low level access to the object file. It
16 // knows how to find the required sections and compute relocated
17 // values.
18 // The default implementations of the get
methods return dummy values.
19 // This is to allow clients that only need some of those to implement just the
20 // ones they need. We can't use unreachable for as many cases because the parser
21 // implementation is eager and will call some of these methods even if the
22 // result is not used.
23 class DWARFObject {
24 DWARFSection Dummy;
25
26 public:
27 virtual ~DWARFObject() = default;
28 virtual StringRef getFileName() const { llvm_unreachable("unimplemented"); }
29 virtual bool isLittleEndian() const = 0;
30 virtual uint8_t getAddressSize() const { llvm_unreachable("unimplemented"); }
31 virtual const DWARFSection &getInfoSection() const { return Dummy; }
32 virtual void
33 forEachTypesSections(function_ref F) const {}
34 virtual StringRef getAbbrevSection() const { return ""; }
35 virtual const DWARFSection &getLocSection() const { return Dummy; }
36 virtual StringRef getARangeSection() const { return ""; }
37 virtual StringRef getDebugFrameSection() const { return ""; }
38 virtual StringRef getEHFrameSection() const { return ""; }
39 virtual const DWARFSection &getLineSection() const { return Dummy; }
40 virtual StringRef getStringSection() const { return ""; }
41 virtual const DWARFSection &getRangeSection() const { return Dummy; }
42 virtual StringRef getMacinfoSection() const { return ""; }
43 virtual StringRef getPubNamesSection() const { return ""; }
44 virtual StringRef getPubTypesSection() const { return ""; }
45 virtual StringRef getGnuPubNamesSection() const { return ""; }
46 virtual StringRef getGnuPubTypesSection() const { return ""; }
47 virtual const DWARFSection &getStringOffsetSection() const { return Dummy; }
48 virtual const DWARFSection &getInfoDWOSection() const { return Dummy; }
49 virtual void
50 forEachTypesDWOSections(function_ref F) const {}
51 virtual StringRef getAbbrevDWOSection() const { return ""; }
52 virtual const DWARFSection &getLineDWOSection() const { return Dummy; }
53 virtual const DWARFSection &getLocDWOSection() const { return Dummy; }
54 virtual StringRef getStringDWOSection() const { return ""; }
55 virtual const DWARFSection &getStringOffsetDWOSection() const {
56 return Dummy;
57 }
58 virtual const DWARFSection &getRangeDWOSection() const { return Dummy; }
59 virtual const DWARFSection &getAddrSection() const { return Dummy; }
60 virtual const DWARFSection &getAppleNamesSection() const { return Dummy; }
61 virtual const DWARFSection &getAppleTypesSection() const { return Dummy; }
62 virtual const DWARFSection &getAppleNamespacesSection() const {
63 return Dummy;
64 }
65 virtual const DWARFSection &getAppleObjCSection() const { return Dummy; }
66 virtual StringRef getCUIndexSection() const { return ""; }
67 virtual StringRef getGdbIndexSection() const { return ""; }
68 virtual StringRef getTUIndexSection() const { return ""; }
69 virtual Optional find(const DWARFSection &Sec,
70 uint64_t Pos) const = 0;
71 };
72
73 } // namespace llvm
74 #endif
1616
1717 struct DWARFSection {
1818 StringRef Data;
19 };
20
21 struct DWARFSectionMap final : public DWARFSection {
1922 RelocAddrMap Relocs;
2023 };
2124
196196 bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
197197 bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
198198
199 DWARFDataExtractor getDebugInfoExtractor() const {
200 return DWARFDataExtractor(InfoSection, isLittleEndian,
201 getAddressByteSize());
202 }
199 DWARFDataExtractor getDebugInfoExtractor() const;
203200
204201 DataExtractor getStringExtractor() const {
205202 return DataExtractor(StringSection, false, 0);
206203 }
207204
208 const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
209 const RelocAddrMap &getStringOffsetsRelocMap() const {
210 return StringOffsetSection.Relocs;
211 }
212205
213206 bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
214207
5959 using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
6060
6161 static void dumpAccelSection(raw_ostream &OS, StringRef Name,
62 const DWARFSection& Section, StringRef StringSection,
63 bool LittleEndian) {
64 DWARFDataExtractor AccelSection(Section, LittleEndian, 0);
62 const DWARFObject &Obj,
63 const DWARFSection &Section,
64 StringRef StringSection, bool LittleEndian) {
65 DWARFDataExtractor AccelSection(Obj, Section, LittleEndian, 0);
6566 DataExtractor StrData(StringSection, LittleEndian, 0);
6667 OS << "\n." << Name << " contents:\n";
6768 DWARFAcceleratorTable Accel(AccelSection, StrData);
7273
7374 static void
7475 dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName,
76 const DWARFObject &Obj,
7577 const DWARFSection &StringOffsetsSection,
7678 StringRef StringSection, bool LittleEndian) {
77 DWARFDataExtractor StrOffsetExt(StringOffsetsSection, LittleEndian, 0);
79 DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
7880 uint32_t Offset = 0;
7981 uint64_t SectionSize = StringOffsetsSection.Data.size();
8082
152154 // monolithic series of string offsets, as generated by the pre-DWARF v5
153155 // implementation of split DWARF.
154156 static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
157 const DWARFObject &Obj,
155158 const DWARFSection &StringOffsetsSection,
156159 StringRef StringSection, bool LittleEndian,
157160 unsigned MaxVersion) {
162165 // we assume that the section is formatted like a DWARF v5 string offsets
163166 // section.
164167 if (MaxVersion >= 5)
165 dumpDWARFv5StringOffsetsSection(OS, SectionName, StringOffsetsSection,
168 dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection,
166169 StringSection, LittleEndian);
167170 else {
168171 DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
258261 uint32_t offset = 0;
259262 if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
260263 OS << "\n.debug_aranges contents:\n";
261 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
264 DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0);
262265 DWARFDebugArangeSet set;
263266 while (set.extract(arangesData, &offset))
264267 set.dump(OS);
273276 if (!CUDIE)
274277 continue;
275278 if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) {
276 DWARFDataExtractor lineData(getLineSection(), isLittleEndian(),
277 savedAddressByteSize);
279 DWARFDataExtractor lineData(*DObj, DObj->getLineSection(),
280 isLittleEndian(), savedAddressByteSize);
278281 DWARFDebugLine::LineTable LineTable;
279282 uint32_t Offset = *StmtOffset;
280283 LineTable.parse(lineData, &Offset);
296299 if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
297300 OS << "\n.debug_line.dwo contents:\n";
298301 unsigned stmtOffset = 0;
299 DWARFDataExtractor lineData(getLineDWOSection(), isLittleEndian(),
300 savedAddressByteSize);
302 DWARFDataExtractor lineData(*DObj, DObj->getLineDWOSection(),
303 isLittleEndian(), savedAddressByteSize);
301304 DWARFDebugLine::LineTable LineTable;
302305 while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
303306 LineTable.dump(OS);
307310
308311 if (DumpType == DIDT_All || DumpType == DIDT_Str) {
309312 OS << "\n.debug_str contents:\n";
310 DataExtractor strData(getStringSection(), isLittleEndian(), 0);
313 DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0);
311314 offset = 0;
312315 uint32_t strOffset = 0;
313316 while (const char *s = strData.getCStr(&offset)) {
317320 }
318321
319322 if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
320 !getStringDWOSection().empty()) {
323 !DObj->getStringDWOSection().empty()) {
321324 OS << "\n.debug_str.dwo contents:\n";
322 DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
325 DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0);
323326 offset = 0;
324327 uint32_t strDWOOffset = 0;
325328 while (const char *s = strDWOData.getCStr(&offset)) {
334337 // sizes, but for simplicity we just use the address byte size of the last
335338 // compile unit (there is no easy and fast way to associate address range
336339 // list and the compile unit it describes).
337 DWARFDataExtractor rangesData(getRangeSection(), isLittleEndian(),
338 savedAddressByteSize);
340 DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
341 isLittleEndian(), savedAddressByteSize);
339342 offset = 0;
340343 DWARFDebugRangeList rangeList;
341344 while (rangeList.extract(rangesData, &offset))
343346 }
344347
345348 if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
346 DWARFDebugPubTable(getPubNamesSection(), isLittleEndian(), false)
349 DWARFDebugPubTable(DObj->getPubNamesSection(), isLittleEndian(), false)
347350 .dump("debug_pubnames", OS);
348351
349352 if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
350 DWARFDebugPubTable(getPubTypesSection(), isLittleEndian(), false)
353 DWARFDebugPubTable(DObj->getPubTypesSection(), isLittleEndian(), false)
351354 .dump("debug_pubtypes", OS);
352355
353356 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
354 DWARFDebugPubTable(getGnuPubNamesSection(), isLittleEndian(),
357 DWARFDebugPubTable(DObj->getGnuPubNamesSection(), isLittleEndian(),
355358 true /* GnuStyle */)
356359 .dump("debug_gnu_pubnames", OS);
357360
358361 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
359 DWARFDebugPubTable(getGnuPubTypesSection(), isLittleEndian(),
362 DWARFDebugPubTable(DObj->getGnuPubTypesSection(), isLittleEndian(),
360363 true /* GnuStyle */)
361364 .dump("debug_gnu_pubtypes", OS);
362365
363366 if (DumpType == DIDT_All || DumpType == DIDT_StrOffsets)
364 dumpStringOffsetsSection(OS, "debug_str_offsets", getStringOffsetSection(),
365 getStringSection(), isLittleEndian(),
366 getMaxVersion());
367 dumpStringOffsetsSection(
368 OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(),
369 DObj->getStringSection(), isLittleEndian(), getMaxVersion());
367370
368371 if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) {
369 dumpStringOffsetsSection(OS, "debug_str_offsets.dwo",
370 getStringOffsetDWOSection(), getStringDWOSection(),
371 isLittleEndian(), getMaxVersion());
372 dumpStringOffsetsSection(
373 OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(),
374 DObj->getStringDWOSection(), isLittleEndian(), getMaxVersion());
372375 }
373376
374377 if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) &&
375 !getGdbIndexSection().empty()) {
378 !DObj->getGdbIndexSection().empty()) {
376379 OS << "\n.gnu_index contents:\n";
377380 getGdbIndex().dump(OS);
378381 }
379382
380383 if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
381 dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
382 getStringSection(), isLittleEndian());
384 dumpAccelSection(OS, "apple_names", *DObj, DObj->getAppleNamesSection(),
385 DObj->getStringSection(), isLittleEndian());
383386
384387 if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
385 dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
386 getStringSection(), isLittleEndian());
388 dumpAccelSection(OS, "apple_types", *DObj, DObj->getAppleTypesSection(),
389 DObj->getStringSection(), isLittleEndian());
387390
388391 if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
389 dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
390 getStringSection(), isLittleEndian());
392 dumpAccelSection(OS, "apple_namespaces", *DObj,
393 DObj->getAppleNamespacesSection(),
394 DObj->getStringSection(), isLittleEndian());
391395
392396 if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
393 dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
394 getStringSection(), isLittleEndian());
397 dumpAccelSection(OS, "apple_objc", *DObj, DObj->getAppleObjCSection(),
398 DObj->getStringSection(), isLittleEndian());
395399 }
396400
397401 DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
432436 if (CUIndex)
433437 return *CUIndex;
434438
435 DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0);
439 DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
436440
437441 CUIndex = llvm::make_unique(DW_SECT_INFO);
438442 CUIndex->parse(CUIndexData);
443447 if (TUIndex)
444448 return *TUIndex;
445449
446 DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0);
450 DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
447451
448452 TUIndex = llvm::make_unique(DW_SECT_TYPES);
449453 TUIndex->parse(TUIndexData);
454458 if (GdbIndex)
455459 return *GdbIndex;
456460
457 DataExtractor GdbIndexData(getGdbIndexSection(), true /*LE*/, 0);
461 DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
458462 GdbIndex = llvm::make_unique();
459463 GdbIndex->parse(GdbIndexData);
460464 return *GdbIndex;
464468 if (Abbrev)
465469 return Abbrev.get();
466470
467 DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
471 DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0);
468472
469473 Abbrev.reset(new DWARFDebugAbbrev());
470474 Abbrev->extract(abbrData);
475479 if (AbbrevDWO)
476480 return AbbrevDWO.get();
477481
478 DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
482 DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0);
479483 AbbrevDWO.reset(new DWARFDebugAbbrev());
480484 AbbrevDWO->extract(abbrData);
481485 return AbbrevDWO.get();
488492 Loc.reset(new DWARFDebugLoc);
489493 // assume all compile units have the same address byte size
490494 if (getNumCompileUnits()) {
491 DWARFDataExtractor LocData(getLocSection(), isLittleEndian(),
495 DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
492496 getCompileUnitAtIndex(0)->getAddressByteSize());
493497 Loc->parse(LocData);
494498 }
499503 if (LocDWO)
500504 return LocDWO.get();
501505
502 DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
506 DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 0);
503507 LocDWO.reset(new DWARFDebugLocDWO());
504508 LocDWO->parse(LocData);
505509 return LocDWO.get();
527531 // provides this information). This problem is fixed in DWARFv4
528532 // See this dwarf-discuss discussion for more details:
529533 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
530 DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
531 getAddressSize());
534 DataExtractor debugFrameData(DObj->getDebugFrameSection(), isLittleEndian(),
535 DObj->getAddressSize());
532536 DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
533537 DebugFrame->parse(debugFrameData);
534538 return DebugFrame.get();
538542 if (EHFrame)
539543 return EHFrame.get();
540544
541 DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(),
542 getAddressSize());
545 DataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
546 DObj->getAddressSize());
543547 DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
544548 DebugFrame->parse(debugFrameData);
545549 return DebugFrame.get();
549553 if (Macro)
550554 return Macro.get();
551555
552 DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0);
556 DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0);
553557 Macro.reset(new DWARFDebugMacro());
554558 Macro->parse(MacinfoData);
555559 return Macro.get();
578582 return nullptr;
579583
580584 // We have to parse it first.
581 DWARFDataExtractor lineData(U->getLineSection(), isLittleEndian(),
585 DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
582586 U->getAddressByteSize());
583587 return Line->getOrParseLineTable(lineData, stmtOffset);
584588 }
585589
586590 void DWARFContext::parseCompileUnits() {
587 CUs.parse(*this, getInfoSection());
591 CUs.parse(*this, DObj->getInfoSection());
588592 }
589593
590594 void DWARFContext::parseTypeUnits() {
591595 if (!TUs.empty())
592596 return;
593 forEachTypesSections([&](const DWARFSection &S) {
597 DObj->forEachTypesSections([&](const DWARFSection &S) {
594598 TUs.emplace_back();
595599 TUs.back().parse(*this, S);
596600 });
597601 }
598602
599603 void DWARFContext::parseDWOCompileUnits() {
600 DWOCUs.parseDWO(*this, getInfoDWOSection());
604 DWOCUs.parseDWO(*this, DObj->getInfoDWOSection());
601605 }
602606
603607 void DWARFContext::parseDWOTypeUnits() {
604608 if (!DWOTUs.empty())
605609 return;
606 forEachTypesDWOSections([&](const DWARFSection &S) {
610 DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
607611 DWOTUs.emplace_back();
608612 DWOTUs.back().parseDWO(*this, S);
609613 });
778782 return InliningInfo;
779783 }
780784
785 /// DWARFContextInMemory is the simplest possible implementation of a
786 /// DWARFContext. It assumes all content is available in memory and stores
787 /// pointers to it.
788 class DWARFContextInMemory : public DWARFContext {
789 public:
790 DWARFContextInMemory(
791 const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
792 function_ref HandleError = defaultErrorHandler);
793
794 DWARFContextInMemory(const StringMap> &Sections,
795 uint8_t AddrSize,
796 bool isLittleEndian = sys::IsLittleEndianHost);
797 };
798
781799 std::shared_ptr
782800 DWARFContext::getDWOContext(StringRef AbsolutePath) {
783801 if (auto S = DWP.lock()) {
795813 SmallString<128> DWPName;
796814 Expected> Obj = [&] {
797815 if (!CheckedForDWP) {
798 (getFileName() + ".dwp").toVector(DWPName);
816 (DObj->getFileName() + ".dwp").toVector(DWPName);
799817 auto Obj = object::ObjectFile::createObjectFile(DWPName);
800818 if (Obj) {
801819 Entry = &DWP;
819837
820838 auto S = std::make_shared();
821839 S->File = std::move(Obj.get());
822 S->Context = llvm::make_unique(*S->File.getBinary());
840 S->Context = DWARFContext::create(*S->File.getBinary());
823841 *Entry = S;
824842 auto *Ctxt = S->Context.get();
825843 return std::shared_ptr(std::move(S), Ctxt);
905923 return MachObj->isRelocationScattered(RelocInfo);
906924 }
907925
908 Error DWARFContextInMemory::maybeDecompress(const SectionRef &Sec,
909 StringRef Name, StringRef &Data) {
910 if (!Decompressor::isCompressed(Sec))
911 return Error::success();
912
913 Expected Decompressor =
914 Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
915 if (!Decompressor)
916 return Decompressor.takeError();
917
918 SmallString<32> Out;
919 if (auto Err = Decompressor->resizeAndDecompress(Out))
920 return Err;
921
922 UncompressedSections.emplace_back(std::move(Out));
923 Data = UncompressedSections.back();
924
925 return Error::success();
926 }
927
928 ErrorPolicy DWARFContextInMemory::defaultErrorHandler(Error E) {
926 ErrorPolicy DWARFContext::defaultErrorHandler(Error E) {
929927 errs() << "error: " + toString(std::move(E)) << '\n';
930928 return ErrorPolicy::Continue;
931929 }
932930
933 DWARFContextInMemory::DWARFContextInMemory(
934 const object::ObjectFile &Obj, const LoadedObjectInfo *L,
935 function_ref HandleError)
936 : FileName(Obj.getFileName()), IsLittleEndian(Obj.isLittleEndian()),
937 AddressSize(Obj.getBytesInAddress()) {
938 for (const SectionRef &Section : Obj.sections()) {
939 StringRef Name;
940 Section.getName(Name);
941 // Skip BSS and Virtual sections, they aren't interesting.
942 if (Section.isBSS() || Section.isVirtual())
943 continue;
944
945 StringRef Data;
946 section_iterator RelocatedSection = Section.getRelocatedSection();
947 // Try to obtain an already relocated version of this section.
948 // Else use the unrelocated section from the object file. We'll have to
949 // apply relocations ourselves later.
950 if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data))
951 Section.getContents(Data);
952
953 if (auto Err = maybeDecompress(Section, Name, Data)) {
954 ErrorPolicy EP = HandleError(
955 createError("failed to decompress '" + Name + "', ", std::move(Err)));
956 if (EP == ErrorPolicy::Halt)
957 return;
958 continue;
959 }
960
961 // Compressed sections names in GNU style starts from ".z",
962 // at this point section is decompressed and we drop compression prefix.
963 Name = Name.substr(
964 Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
965
966 // Map platform specific debug section names to DWARF standard section
967 // names.
968 Name = Obj.mapDebugSectionName(Name);
969
970 if (StringRef *SectionData = mapSectionToMember(Name)) {
971 *SectionData = Data;
972 if (Name == "debug_ranges") {
973 // FIXME: Use the other dwo range section when we emit it.
974 RangeDWOSection.Data = Data;
975 }
976 } else if (Name == "debug_types") {
977 // Find debug_types data by section rather than name as there are
978 // multiple, comdat grouped, debug_types sections.
979 TypesSections[Section].Data = Data;
980 } else if (Name == "debug_types.dwo") {
981 TypesDWOSections[Section].Data = Data;
982 }
983
984 if (RelocatedSection == Obj.section_end())
985 continue;
986
987 StringRef RelSecName;
988 StringRef RelSecData;
989 RelocatedSection->getName(RelSecName);
990
991 // If the section we're relocating was relocated already by the JIT,
992 // then we used the relocated version above, so we do not need to process
993 // relocations for it now.
994 if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
995 continue;
996
997 // In Mach-o files, the relocations do not need to be applied if
998 // there is no load offset to apply. The value read at the
999 // relocation point already factors in the section address
1000 // (actually applying the relocations will produce wrong results
1001 // as the section address will be added twice).
1002 if (!L && isa(&Obj))
1003 continue;
1004
1005 RelSecName = RelSecName.substr(
1006 RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
1007
1008 // TODO: Add support for relocations in other sections as needed.
1009 // Record relocations for the debug_info and debug_line sections.
1010 DWARFSection *Sec = mapNameToDWARFSection(RelSecName);
1011 RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
1012 if (!Map) {
1013 // Find debug_types relocs by section rather than name as there are
1014 // multiple, comdat grouped, debug_types sections.
1015 if (RelSecName == "debug_types")
1016 Map = &TypesSections[*RelocatedSection].Relocs;
1017 else if (RelSecName == "debug_types.dwo")
1018 Map = &TypesDWOSections[*RelocatedSection].Relocs;
1019 else
931 class DWARFObjInMemory final : public DWARFObject {
932 bool IsLittleEndian;
933 uint8_t AddressSize;
934 StringRef FileName;
935
936 using TypeSectionMap = MapVector
937 std::map>;
938
939 TypeSectionMap TypesSections;
940 TypeSectionMap TypesDWOSections;
941
942 DWARFSectionMap InfoSection;
943 DWARFSectionMap LocSection;
944 DWARFSectionMap LineSection;
945 DWARFSectionMap RangeSection;
946 DWARFSectionMap StringOffsetSection;
947 DWARFSectionMap InfoDWOSection;
948 DWARFSectionMap LineDWOSection;
949 DWARFSectionMap LocDWOSection;
950 DWARFSectionMap StringOffsetDWOSection;
951 DWARFSectionMap RangeDWOSection;
952 DWARFSectionMap AddrSection;
953 DWARFSectionMap AppleNamesSection;
954 DWARFSectionMap AppleTypesSection;
955 DWARFSectionMap AppleNamespacesSection;
956 DWARFSectionMap AppleObjCSection;
957
958 DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
959 return StringSwitch(Name)
960 .Case("debug_info", &InfoSection)
961 .Case("debug_loc", &LocSection)
962 .Case("debug_line", &LineSection)
963 .Case("debug_str_offsets", &StringOffsetSection)
964 .Case("debug_ranges", &RangeSection)
965 .Case("debug_info.dwo", &InfoDWOSection)
966 .Case("debug_loc.dwo", &LocDWOSection)
967 .Case("debug_line.dwo", &LineDWOSection)
968 .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
969 .Case("debug_addr", &AddrSection)
970 .Case("apple_names", &AppleNamesSection)
971 .Case("apple_types", &AppleTypesSection)
972 .Case("apple_namespaces", &AppleNamespacesSection)
973 .Case("apple_namespac", &AppleNamespacesSection)
974 .Case("apple_objc", &AppleObjCSection)
975 .Default(nullptr);
976 }
977
978 StringRef AbbrevSection;
979 StringRef ARangeSection;
980 StringRef DebugFrameSection;
981 StringRef EHFrameSection;
982 StringRef StringSection;
983 StringRef MacinfoSection;
984 StringRef PubNamesSection;
985 StringRef PubTypesSection;
986 StringRef GnuPubNamesSection;
987 StringRef AbbrevDWOSection;
988 StringRef StringDWOSection;
989 StringRef GnuPubTypesSection;
990 StringRef CUIndexSection;
991 StringRef GdbIndexSection;
992 StringRef TUIndexSection;
993
994 SmallVector, 4> UncompressedSections;
995
996 StringRef *mapSectionToMember(StringRef Name) {
997 if (DWARFSection *Sec = mapNameToDWARFSection(Name))
998 return &Sec->Data;
999 return StringSwitch(Name)
1000 .Case("debug_abbrev", &AbbrevSection)
1001 .Case("debug_aranges", &ARangeSection)
1002 .Case("debug_frame", &DebugFrameSection)
1003 .Case("eh_frame", &EHFrameSection)
1004 .Case("debug_str", &StringSection)
1005 .Case("debug_macinfo", &MacinfoSection)
1006 .Case("debug_pubnames", &PubNamesSection)
1007 .Case("debug_pubtypes", &PubTypesSection)
1008 .Case("debug_gnu_pubnames", &GnuPubNamesSection)
1009 .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
1010 .Case("debug_abbrev.dwo", &AbbrevDWOSection)
1011 .Case("debug_str.dwo", &StringDWOSection)
1012 .Case("debug_cu_index", &CUIndexSection)
1013 .Case("debug_tu_index", &TUIndexSection)
1014 .Case("gdb_index", &GdbIndexSection)
1015 // Any more debug info sections go here.
1016 .Default(nullptr);
1017 }
1018
1019 /// If Sec is compressed section, decompresses and updates its contents
1020 /// provided by Data. Otherwise leaves it unchanged.
1021 Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
1022 StringRef &Data) {
1023 if (!Decompressor::isCompressed(Sec))
1024 return Error::success();
1025
1026 Expected Decompressor =
1027 Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
1028 if (!Decompressor)
1029 return Decompressor.takeError();
1030
1031 SmallString<32> Out;
1032 if (auto Err = Decompressor->resizeAndDecompress(Out))
1033 return Err;
1034
1035 UncompressedSections.emplace_back(std::move(Out));
1036 Data = UncompressedSections.back();
1037
1038 return Error::success();
1039 }
1040
1041 public:
1042 DWARFObjInMemory(const StringMap> &Sections,
1043 uint8_t AddrSize, bool IsLittleEndian)
1044 : IsLittleEndian(IsLittleEndian) {
1045 for (const auto &SecIt : Sections) {
1046 if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
1047 *SectionData = SecIt.second->getBuffer();
1048 }
1049 }
1050 DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
1051 function_ref HandleError)
1052 : IsLittleEndian(Obj.isLittleEndian()),
1053 AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()) {
1054
1055 for (const SectionRef &Section : Obj.sections()) {
1056 StringRef Name;
1057 Section.getName(Name);
1058 // Skip BSS and Virtual sections, they aren't interesting.
1059 if (Section.isBSS() || Section.isVirtual())
10201060 continue;
1021 }
1022
1023 if (Section.relocation_begin() == Section.relocation_end())
1024 continue;
1025
1026 // Symbol to [address, section index] cache mapping.
1027 std::map AddrCache;
1028 for (const RelocationRef &Reloc : Section.relocations()) {
1029 // FIXME: it's not clear how to correctly handle scattered
1030 // relocations.
1031 if (isRelocScattered(Obj, Reloc))
1032 continue;
1033
1034 Expected SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache);
1035 if (!SymInfoOrErr) {
1036 if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
1037 return;
1038 continue;
1039 }
1040
1041 object::RelocVisitor V(Obj);
1042 uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
1043 if (V.error()) {
1044 SmallString<32> Type;
1045 Reloc.getTypeName(Type);
1046 ErrorPolicy EP = HandleError(
1047 createError("failed to compute relocation: " + Type + ", ",
1048 errorCodeToError(object_error::parse_failed)));
1061
1062 StringRef Data;
1063 section_iterator RelocatedSection = Section.getRelocatedSection();
1064 // Try to obtain an already relocated version of this section.
1065 // Else use the unrelocated section from the object file. We'll have to
1066 // apply relocations ourselves later.
1067 if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data))
1068 Section.getContents(Data);
1069
1070 if (auto Err = maybeDecompress(Section, Name, Data)) {
1071 ErrorPolicy EP = HandleError(createError(
1072 "failed to decompress '" + Name + "', ", std::move(Err)));
10491073 if (EP == ErrorPolicy::Halt)
10501074 return;
10511075 continue;
10521076 }
1053 RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
1054 Map->insert({Reloc.getOffset(), Rel});
1055 }
1056 }
1057 }
1058
1059 DWARFContextInMemory::DWARFContextInMemory(
1060 const StringMap> &Sections, uint8_t AddrSize,
1061 bool isLittleEndian)
1062 : IsLittleEndian(isLittleEndian), AddressSize(AddrSize) {
1063 for (const auto &SecIt : Sections) {
1064 if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
1065 *SectionData = SecIt.second->getBuffer();
1066 }
1067 }
1068
1069 DWARFSection *DWARFContextInMemory::mapNameToDWARFSection(StringRef Name) {
1070 return StringSwitch(Name)
1071 .Case("debug_info", &InfoSection)
1072 .Case("debug_loc", &LocSection)
1073 .Case("debug_line", &LineSection)
1074 .Case("debug_str_offsets", &StringOffsetSection)
1075 .Case("debug_ranges", &RangeSection)
1076 .Case("debug_info.dwo", &InfoDWOSection)
1077 .Case("debug_loc.dwo", &LocDWOSection)
1078 .Case("debug_line.dwo", &LineDWOSection)
1079 .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
1080 .Case("debug_addr", &AddrSection)
1081 .Case("apple_names", &AppleNamesSection)
1082 .Case("apple_types", &AppleTypesSection)
1083 .Case("apple_namespaces", &AppleNamespacesSection)
1084 .Case("apple_namespac", &AppleNamespacesSection)
1085 .Case("apple_objc", &AppleObjCSection)
1086 .Default(nullptr);
1087 }
1088
1089 StringRef *DWARFContextInMemory::mapSectionToMember(StringRef Name) {
1090 if (DWARFSection *Sec = mapNameToDWARFSection(Name))
1091 return &Sec->Data;
1092 return StringSwitch(Name)
1093 .Case("debug_abbrev", &AbbrevSection)
1094 .Case("debug_aranges", &ARangeSection)
1095 .Case("debug_frame", &DebugFrameSection)
1096 .Case("eh_frame", &EHFrameSection)
1097 .Case("debug_str", &StringSection)
1098 .Case("debug_macinfo", &MacinfoSection)
1099 .Case("debug_pubnames", &PubNamesSection)
1100 .Case("debug_pubtypes", &PubTypesSection)
1101 .Case("debug_gnu_pubnames", &GnuPubNamesSection)
1102 .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
1103 .Case("debug_abbrev.dwo", &AbbrevDWOSection)
1104 .Case("debug_str.dwo", &StringDWOSection)
1105 .Case("debug_cu_index", &CUIndexSection)
1106 .Case("debug_tu_index", &TUIndexSection)
1107 .Case("gdb_index", &GdbIndexSection)
1108 // Any more debug info sections go here.
1109 .Default(nullptr);
1110 }
1111
1112 void DWARFContextInMemory::anchor() {}
1077
1078 // Compressed sections names in GNU style starts from ".z",
1079 // at this point section is decompressed and we drop compression prefix.
1080 Name = Name.substr(
1081 Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1082
1083 // Map platform specific debug section names to DWARF standard section
1084 // names.
1085 Name = Obj.mapDebugSectionName(Name);
1086
1087 if (StringRef *SectionData = mapSectionToMember(Name)) {
1088 *SectionData = Data;
1089 if (Name == "debug_ranges") {
1090 // FIXME: Use the other dwo range section when we emit it.
1091 RangeDWOSection.Data = Data;
1092 }
1093 } else if (Name == "debug_types") {
1094 // Find debug_types data by section rather than name as there are
1095 // multiple, comdat grouped, debug_types sections.
1096 TypesSections[Section].Data = Data;
1097 } else if (Name == "debug_types.dwo") {
1098 TypesDWOSections[Section].Data = Data;
1099 }
1100
1101 if (RelocatedSection == Obj.section_end())
1102 continue;
1103
1104 StringRef RelSecName;
1105 StringRef RelSecData;
1106 RelocatedSection->getName(RelSecName);
1107
1108 // If the section we're relocating was relocated already by the JIT,
1109 // then we used the relocated version above, so we do not need to process
1110 // relocations for it now.
1111 if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
1112 continue;
1113
1114 // In Mach-o files, the relocations do not need to be applied if
1115 // there is no load offset to apply. The value read at the
1116 // relocation point already factors in the section address
1117 // (actually applying the relocations will produce wrong results
1118 // as the section address will be added twice).
1119 if (!L && isa(&Obj))
1120 continue;
1121
1122 RelSecName = RelSecName.substr(
1123 RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
1124
1125 // TODO: Add support for relocations in other sections as needed.
1126 // Record relocations for the debug_info and debug_line sections.
1127 DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
1128 RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
1129 if (!Map) {
1130 // Find debug_types relocs by section rather than name as there are
1131 // multiple, comdat grouped, debug_types sections.
1132 if (RelSecName == "debug_types")
1133 Map =
1134 &static_cast(TypesSections[*RelocatedSection])
1135 .Relocs;
1136 else if (RelSecName == "debug_types.dwo")
1137 Map = &static_cast(
1138 TypesDWOSections[*RelocatedSection])
1139 .Relocs;
1140 else
1141 continue;
1142 }
1143
1144 if (Section.relocation_begin() == Section.relocation_end())
1145 continue;
1146
1147 // Symbol to [address, section index] cache mapping.
1148 std::map AddrCache;
1149 for (const RelocationRef &Reloc : Section.relocations()) {
1150 // FIXME: it's not clear how to correctly handle scattered
1151 // relocations.
1152 if (isRelocScattered(Obj, Reloc))
1153 continue;
1154
1155 Expected SymInfoOrErr =
1156 getSymbolInfo(Obj, Reloc, L, AddrCache);
1157 if (!SymInfoOrErr) {
1158 if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
1159 return;
1160 continue;
1161 }
1162
1163 object::RelocVisitor V(Obj);
1164 uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
1165 if (V.error()) {
1166 SmallString<32> Type;
1167 Reloc.getTypeName(Type);
1168 ErrorPolicy EP = HandleError(
1169 createError("failed to compute relocation: " + Type + ", ",
1170 errorCodeToError(object_error::parse_failed)));
1171 if (EP == ErrorPolicy::Halt)
1172 return;
1173 continue;
1174 }
1175 RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
1176 Map->insert({Reloc.getOffset(), Rel});
1177 }
1178 }
1179 }
1180
1181 Optional find(const DWARFSection &S,
1182 uint64_t Pos) const override {
1183 auto &Sec = static_cast(S);
1184 RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
1185 if (AI == Sec.Relocs.end())
1186 return None;
1187 return AI->second;
1188 }
1189
1190 bool isLittleEndian() const override { return IsLittleEndian; }
1191 StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
1192 const DWARFSection &getLineDWOSection() const override {
1193 return LineDWOSection;
1194 }
1195 const DWARFSection &getLocDWOSection() const override {
1196 return LocDWOSection;
1197 }
1198 StringRef getStringDWOSection() const override { return StringDWOSection; }
1199 const DWARFSection &getStringOffsetDWOSection() const override {
1200 return StringOffsetDWOSection;
1201 }
1202 const DWARFSection &getRangeDWOSection() const override {
1203 return RangeDWOSection;
1204 }
1205 const DWARFSection &getAddrSection() const override { return AddrSection; }
1206 StringRef getCUIndexSection() const override { return CUIndexSection; }
1207 StringRef getGdbIndexSection() const override { return GdbIndexSection; }
1208 StringRef getTUIndexSection() const override { return TUIndexSection; }
1209
1210 // DWARF v5
1211 const DWARFSection &getStringOffsetSection() const override {
1212 return StringOffsetSection;
1213 }
1214
1215 // Sections for DWARF5 split dwarf proposal.
1216 const DWARFSection &getInfoDWOSection() const override {
1217 return InfoDWOSection;
1218 }
1219 void forEachTypesDWOSections(
1220 function_ref F) const override {
1221 for (auto &P : TypesDWOSections)
1222 F(P.second);
1223 }
1224
1225 StringRef getAbbrevSection() const override { return AbbrevSection; }
1226 const DWARFSection &getLocSection() const override { return LocSection; }
1227 StringRef getARangeSection() const override { return ARangeSection; }
1228 StringRef getDebugFrameSection() const override { return DebugFrameSection; }
1229 StringRef getEHFrameSection() const override { return EHFrameSection; }
1230 const DWARFSection &getLineSection() const override { return LineSection; }
1231 StringRef getStringSection() const override { return StringSection; }
1232 const DWARFSection &getRangeSection() const override { return RangeSection; }
1233 StringRef getMacinfoSection() const override { return MacinfoSection; }
1234 StringRef getPubNamesSection() const override { return PubNamesSection; }
1235 StringRef getPubTypesSection() const override { return PubTypesSection; }
1236 StringRef getGnuPubNamesSection() const override {
1237 return GnuPubNamesSection;
1238 }
1239 StringRef getGnuPubTypesSection() const override {
1240 return GnuPubTypesSection;
1241 }
1242 const DWARFSection &getAppleNamesSection() const override {
1243 return AppleNamesSection;
1244 }
1245 const DWARFSection &getAppleTypesSection() const override {
1246 return AppleTypesSection;
1247 }
1248 const DWARFSection &getAppleNamespacesSection() const override {
1249 return AppleNamespacesSection;
1250 }
1251 const DWARFSection &getAppleObjCSection() const override {
1252 return AppleObjCSection;
1253 }
1254
1255 StringRef getFileName() const override { return FileName; }
1256 uint8_t getAddressSize() const override { return AddressSize; }
1257 const DWARFSection &getInfoSection() const override { return InfoSection; }
1258 void forEachTypesSections(
1259 function_ref F) const override {
1260 for (auto &P : TypesSections)
1261 F(P.second);
1262 }
1263 };
1264
1265 std::unique_ptr
1266 DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
1267 function_ref HandleError) {
1268 auto DObj = make_unique(Obj, L, HandleError);
1269 return make_unique(std::move(DObj));
1270 }
1271
1272 std::unique_ptr
1273 DWARFContext::create(const StringMap> &Sections,
1274 uint8_t AddrSize, bool isLittleEndian) {
1275 auto DObj = make_unique(Sections, AddrSize, isLittleEndian);
1276 return make_unique(std::move(DObj));
1277 }
77 //===----------------------------------------------------------------------===//
88
99 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
10 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
1011
1112 using namespace llvm;
1213
1314 uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
1415 uint64_t *SecNdx) const {
15 if (!RelocMap)
16 if (!Section)
1617 return getUnsigned(Off, Size);
17 RelocAddrMap::const_iterator AI = RelocMap->find(*Off);
18 if (AI == RelocMap->end())
18 Optional Rel = Obj->find(*Section, *Off);
19 if (!Rel)
1920 return getUnsigned(Off, Size);
2021 if (SecNdx)
21 *SecNdx = AI->second.SectionIndex;
22 return getUnsigned(Off, Size) + AI->second.Value;
22 *SecNdx = Rel->SectionIndex;
23 return getUnsigned(Off, Size) + Rel->Value;
2324 }
4242 return;
4343
4444 // Extract aranges from .debug_aranges section.
45 DataExtractor ArangesData(CTX->getARangeSection(), CTX->isLittleEndian(), 0);
45 DataExtractor ArangesData(CTX->getDWARFObj().getARangeSection(),
46 CTX->isLittleEndian(), 0);
4647 extract(ArangesData);
4748
4849 // Generate aranges from DIEs: even if .debug_aranges section is present,
2929 using namespace dwarf;
3030
3131 void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
32 parseImpl(C, Section, C.getDebugAbbrev(), &C.getRangeSection(),
33 C.getStringSection(), C.getStringOffsetSection(),
34 &C.getAddrSection(), C.getLineSection(), C.isLittleEndian(), false);
32 const DWARFObject &D = C.getDWARFObj();
33 parseImpl(C, Section, C.getDebugAbbrev(), &D.getRangeSection(),
34 D.getStringSection(), D.getStringOffsetSection(),
35 &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false);
3536 }
3637
3738 void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
3839 const DWARFSection &DWOSection,
3940 DWARFUnitIndex *Index) {
40 parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &C.getRangeDWOSection(),
41 C.getStringDWOSection(), C.getStringOffsetDWOSection(),
42 &C.getAddrSection(), C.getLineDWOSection(), C.isLittleEndian(),
41 const DWARFObject &D = C.getDWARFObj();
42 parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
43 D.getStringDWOSection(), D.getStringOffsetDWOSection(),
44 &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(),
4345 true);
4446 }
4547
5860
5961 DWARFUnit::~DWARFUnit() = default;
6062
63 DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const {
64 return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian,
65 getAddressByteSize());
66 }
67
6168 bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index,
6269 uint64_t &Result) const {
6370 uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
6471 if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
6572 return false;
66 DWARFDataExtractor DA(*AddrOffsetSection, isLittleEndian,
67 getAddressByteSize());
73 DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
74 isLittleEndian, getAddressByteSize());
6875 Result = DA.getRelocatedAddress(&Offset);
6976 return true;
7077 }
7582 uint32_t Offset = StringOffsetSectionBase + Index * ItemSize;
7683 if (StringOffsetSection.Data.size() < Offset + ItemSize)
7784 return false;
78 DWARFDataExtractor DA(StringOffsetSection, isLittleEndian, 0);
85 DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
86 isLittleEndian, 0);
7987 Result = DA.getRelocatedValue(ItemSize, &Offset);
8088 return true;
8189 }
140148 DWARFDebugRangeList &RangeList) const {
141149 // Require that compile unit is extracted.
142150 assert(!DieArray.empty());
143 DWARFDataExtractor RangesData(*RangeSection, isLittleEndian,
144 getAddressByteSize());
151 DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
152 isLittleEndian, getAddressByteSize());
145153 uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
146154 return RangeList.extract(RangesData, &ActualRangeListOffset);
147155 }
104104 bool DWARFVerifier::handleDebugInfo() {
105105 OS << "Verifying .debug_info Unit Header Chain...\n";
106106
107 DWARFDataExtractor DebugInfoData(DCtx.getInfoSection(), DCtx.isLittleEndian(),
108 0);
107 const DWARFObject &DObj = DCtx.getDWARFObj();
108 DWARFDataExtractor DebugInfoData(DObj, DObj.getInfoSection(),
109 DCtx.isLittleEndian(), 0);
109110 uint32_t NumDebugInfoErrors = 0;
110111 uint32_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
111112 uint8_t UnitType = 0;
126127 case dwarf::DW_UT_split_type: {
127128 DWARFUnitSection TUSection{};
128129 Unit.reset(new DWARFTypeUnit(
129 DCtx, DCtx.getInfoSection(), DCtx.getDebugAbbrev(),
130 &DCtx.getRangeSection(), DCtx.getStringSection(),
131 DCtx.getStringOffsetSection(), &DCtx.getAppleObjCSection(),
132 DCtx.getLineSection(), DCtx.isLittleEndian(), false, TUSection,
130 DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
131 &DObj.getRangeSection(), DObj.getStringSection(),
132 DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
133 DObj.getLineSection(), DCtx.isLittleEndian(), false, TUSection,
133134 nullptr));
134135 break;
135136 }
142143 case 0: {
143144 DWARFUnitSection CUSection{};
144145 Unit.reset(new DWARFCompileUnit(
145 DCtx, DCtx.getInfoSection(), DCtx.getDebugAbbrev(),
146 &DCtx.getRangeSection(), DCtx.getStringSection(),
147 DCtx.getStringOffsetSection(), &DCtx.getAppleObjCSection(),
148 DCtx.getLineSection(), DCtx.isLittleEndian(), false, CUSection,
146 DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
147 &DObj.getRangeSection(), DObj.getStringSection(),
148 DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
149 DObj.getLineSection(), DCtx.isLittleEndian(), false, CUSection,
149150 nullptr));
150151 break;
151152 }
168169
169170 unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
170171 DWARFAttribute &AttrValue) {
172 const DWARFObject &DObj = DCtx.getDWARFObj();
171173 unsigned NumErrors = 0;
172174 const auto Attr = AttrValue.Attr;
173175 switch (Attr) {
174176 case DW_AT_ranges:
175177 // Make sure the offset in the DW_AT_ranges attribute is valid.
176178 if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
177 if (*SectionOffset >= DCtx.getRangeSection().Data.size()) {
179 if (*SectionOffset >= DObj.getRangeSection().Data.size()) {
178180 ++NumErrors;
179181 OS << "error: DW_AT_ranges offset is beyond .debug_ranges "
180182 "bounds:\n";
191193 case DW_AT_stmt_list:
192194 // Make sure the offset in the DW_AT_stmt_list attribute is valid.
193195 if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
194 if (*SectionOffset >= DCtx.getLineSection().Data.size()) {
196 if (*SectionOffset >= DObj.getLineSection().Data.size()) {
195197 ++NumErrors;
196198 OS << "error: DW_AT_stmt_list offset is beyond .debug_line "
197199 "bounds: "
215217
216218 unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
217219 DWARFAttribute &AttrValue) {
220 const DWARFObject &DObj = DCtx.getDWARFObj();
218221 unsigned NumErrors = 0;
219222 const auto Form = AttrValue.Value.getForm();
220223 switch (Form) {
252255 Optional RefVal = AttrValue.Value.getAsReference();
253256 assert(RefVal);
254257 if (RefVal) {
255 if (*RefVal >= DCtx.getInfoSection().Data.size()) {
258 if (*RefVal >= DObj.getInfoSection().Data.size()) {
256259 ++NumErrors;
257260 OS << "error: DW_FORM_ref_addr offset beyond .debug_info "
258261 "bounds:\n";
269272 case DW_FORM_strp: {
270273 auto SecOffset = AttrValue.Value.getAsSectionOffset();
271274 assert(SecOffset); // DW_FORM_strp is a section offset.
272 if (SecOffset && *SecOffset >= DCtx.getStringSection().size()) {
275 if (SecOffset && *SecOffset >= DObj.getStringSection().size()) {
273276 ++NumErrors;
274277 OS << "error: DW_FORM_strp offset beyond .debug_str bounds:\n";
275278 Die.dump(OS, 0);
317320 continue;
318321 const uint32_t LineTableOffset = *StmtSectionOffset;
319322 auto LineTable = DCtx.getLineTableForUnit(CU.get());
320 if (LineTableOffset < DCtx.getLineSection().Data.size()) {
323 if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
321324 if (!LineTable) {
322325 ++NumDebugLineErrors;
323326 OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset)
407410
408411 bool DWARFVerifier::handleAppleNames() {
409412 NumAppleNamesErrors = 0;
410
411 DWARFDataExtractor AppleNamesSection(DCtx.getAppleNamesSection(),
413 const DWARFObject &D = DCtx.getDWARFObj();
414 DWARFDataExtractor AppleNamesSection(D, D.getAppleNamesSection(),
412415 DCtx.isLittleEndian(), 0);
413 DataExtractor StrData(DCtx.getStringSection(), DCtx.isLittleEndian(), 0);
416 DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0);
414417 DWARFAcceleratorTable AppleNames(AppleNamesSection, StrData);
415418
416419 if (!AppleNames.extract()) {
408408 }
409409 }
410410 if (!Context)
411 Context.reset(new DWARFContextInMemory(*Objects.second));
411 Context = DWARFContext::create(*Objects.second);
412412 assert(Context);
413413 auto InfoOrErr =
414414 SymbolizableObjectFile::create(Objects.first, std::move(Context));
844844 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
845845
846846 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
847 const DWARFSection &InputSec = Dwarf.getLocSection();
847 const DWARFSection &InputSec = Dwarf.getDWARFObj().getLocSection();
848848 DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
849849 DWARFUnit &OrigUnit = Unit.getOrigUnit();
850850 auto OrigUnitDie = OrigUnit.getUnitDIE(false);
13001300 /// Construct the output DIE tree by cloning the DIEs we
13011301 /// chose to keep above. If there are no valid relocs, then there's
13021302 /// nothing to clone/emit.
1303 void cloneAllCompileUnits(DWARFContextInMemory &DwarfContext);
1303 void cloneAllCompileUnits(DWARFContext &DwarfContext);
13041304
13051305 private:
13061306 typedef DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec;
28722872 DWARFDebugRangeList RangeList;
28732873 const auto &FunctionRanges = Unit.getFunctionRanges();
28742874 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
2875 DWARFDataExtractor RangeExtractor(OrigDwarf.getRangeSection(),
2875 DWARFDataExtractor RangeExtractor(OrigDwarf.getDWARFObj(),
2876 OrigDwarf.getDWARFObj().getRangeSection(),
28762877 OrigDwarf.isLittleEndian(), AddressSize);
28772878 auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;
28782879 DWARFUnit &OrigUnit = Unit.getOrigUnit();
29832984 // Parse the original line info for the unit.
29842985 DWARFDebugLine::LineTable LineTable;
29852986 uint32_t StmtOffset = *StmtList;
2986 DWARFDataExtractor LineExtractor(OrigDwarf.getLineSection(),
2987 OrigDwarf.isLittleEndian(),
2988 Unit.getOrigUnit().getAddressByteSize());
2987 DWARFDataExtractor LineExtractor(
2988 OrigDwarf.getDWARFObj(), OrigDwarf.getDWARFObj().getLineSection(),
2989 OrigDwarf.isLittleEndian(), Unit.getOrigUnit().getAddressByteSize());
29892990 LineTable.parse(LineExtractor, &StmtOffset);
29902991
29912992 // This vector is the output line table.
30853086 LineTable.Prologue.OpcodeBase > 13)
30863087 reportWarning("line table parameters mismatch. Cannot emit.");
30873088 else {
3088 StringRef LineData = OrigDwarf.getLineSection().Data;
3089 StringRef LineData = OrigDwarf.getDWARFObj().getLineSection().Data;
30893090 MCDwarfLineTableParams Params;
30903091 Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
30913092 Params.DWARF2LineBase = LineTable.Prologue.LineBase;
31113112 void DwarfLinker::patchFrameInfoForObject(const DebugMapObject &DMO,
31123113 DWARFContext &OrigDwarf,
31133114 unsigned AddrSize) {
3114 StringRef FrameData = OrigDwarf.getDebugFrameSection();
3115 StringRef FrameData = OrigDwarf.getDWARFObj().getDebugFrameSection();
31153116 if (FrameData.empty())
31163117 return;
31173118
33223323 std::unique_ptr Unit;
33233324
33243325 // Setup access to the debug info.
3325 DWARFContextInMemory DwarfContext(*ErrOrObj);
3326 auto DwarfContext = DWARFContext::create(*ErrOrObj);
33263327 RelocationManager RelocMgr(*this);
3327 for (const auto &CU : DwarfContext.compile_units()) {
3328 for (const auto &CU : DwarfContext->compile_units()) {
33283329 auto CUDie = CU->getUnitDIE(false);
33293330 // Recursively get all modules imported by this one.
33303331 if (!registerModuleReference(CUDie, *CU, ModuleMap, Indent)) {
33643365 std::vector> CompileUnits;
33653366 CompileUnits.push_back(std::move(Unit));
33663367 DIECloner(*this, RelocMgr, DIEAlloc, CompileUnits, Options)
3367 .cloneAllCompileUnits(DwarfContext);
3368 }
3369
3370 void DwarfLinker::DIECloner::cloneAllCompileUnits(
3371 DWARFContextInMemory &DwarfContext) {
3368 .cloneAllCompileUnits(*DwarfContext);
3369 }
3370
3371 void DwarfLinker::DIECloner::cloneAllCompileUnits(DWARFContext &DwarfContext) {
33723372 if (!Linker.Streamer)
33733373 return;
33743374
34373437 }
34383438
34393439 // Setup access to the debug info.
3440 DWARFContextInMemory DwarfContext(*ErrOrObj);
3441 startDebugObject(DwarfContext, *Obj);
3440 auto DwarfContext = DWARFContext::create(*ErrOrObj);
3441 startDebugObject(*DwarfContext, *Obj);
34423442
34433443 // In a first phase, just read in the debug info and load all clang modules.
3444 for (const auto &CU : DwarfContext.compile_units()) {
3444 for (const auto &CU : DwarfContext->compile_units()) {
34453445 auto CUDie = CU->getUnitDIE(false);
34463446 if (Options.Verbose) {
34473447 outs() << "Input compilation unit:";
34753475 RelocMgr.resetValidRelocs();
34763476 if (RelocMgr.hasValidRelocs())
34773477 DIECloner(*this, RelocMgr, DIEAlloc, Units, Options)
3478 .cloneAllCompileUnits(DwarfContext);
3478 .cloneAllCompileUnits(*DwarfContext);
34793479 if (!Options.NoOutput && !Units.empty())
3480 patchFrameInfoForObject(*Obj, DwarfContext,
3480 patchFrameInfoForObject(*Obj, *DwarfContext,
34813481 Units[0]->getOrigUnit().getAddressByteSize());
34823482
34833483 // Clean-up before starting working on the next object.
9393 }
9494
9595 static void DumpObjectFile(ObjectFile &Obj, Twine Filename) {
96 std::unique_ptr DICtx(new DWARFContextInMemory(Obj));
96 std::unique_ptr DICtx = DWARFContext::create(Obj);
9797
9898 outs() << Filename.str() << ":\tfile format " << Obj.getFileFormatName()
9999 << "\n\n";
130130 }
131131
132132 static bool VerifyObjectFile(ObjectFile &Obj, Twine Filename) {
133 std::unique_ptr DICtx(new DWARFContextInMemory(Obj));
134
133 std::unique_ptr DICtx = DWARFContext::create(Obj);
134
135135 // Verify the DWARF and exit with non-zero exit status if verification
136136 // fails.
137137 raw_ostream &stream = Quiet ? nulls() : outs();
12741274 printWeakBindTable(MachOOF);
12751275
12761276 if (DwarfDumpType != DIDT_Null) {
1277 std::unique_ptr DICtx(new DWARFContextInMemory(*MachOOF));
1277 std::unique_ptr DICtx = DWARFContext::create(*MachOOF);
12781278 // Dump the complete DWARF structure.
12791279 DIDumpOptions DumpOpts;
12801280 DumpOpts.DumpType = DwarfDumpType;
65936593 }
65946594
65956595 // Setup the DIContext
6596 diContext.reset(new DWARFContextInMemory(*DbgObj));
6596 diContext = DWARFContext::create(*DbgObj);
65976597 }
65986598
65996599 if (FilterSections.size() == 0)
6161 #include
6262 #include
6363 #include
64 #include
6465 #include
65 #include
6666
6767 using namespace llvm;
6868 using namespace object;
20802080 if (PrintFaultMaps)
20812081 printFaultMaps(o);
20822082 if (DwarfDumpType != DIDT_Null) {
2083 std::unique_ptr DICtx(new DWARFContextInMemory(*o));
2083 std::unique_ptr DICtx = DWARFContext::create(*o);
20842084 // Dump the complete DWARF structure.
20852085 DIDumpOptions DumpOpts;
20862086 DumpOpts.DumpType = DwarfDumpType;
323323 }
324324 }
325325
326 std::unique_ptr Context(
327 new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get()));
326 std::unique_ptr Context =
327 DWARFContext::create(*SymbolObj, LoadedObjInfo.get());
328328
329329 std::vector> SymAddr =
330330 object::computeSymbolSizes(*SymbolObj);
2323 InitialLength.TotalLength64 = Data.getU64(&Offset);
2424 }
2525
26 void dumpDebugAbbrev(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
26 void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) {
2727 auto AbbrevSetPtr = DCtx.getDebugAbbrev();
2828 if (AbbrevSetPtr) {
2929 for (auto AbbrvDeclSet : *AbbrevSetPtr) {
4747 }
4848 }
4949
50 void dumpDebugStrings(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
51 StringRef RemainingTable = DCtx.getStringSection();
50 void dumpDebugStrings(DWARFContext &DCtx, DWARFYAML::Data &Y) {
51 StringRef RemainingTable = DCtx.getDWARFObj().getStringSection();
5252 while (RemainingTable.size() > 0) {
5353 auto SymbolPair = RemainingTable.split('\0');
5454 RemainingTable = SymbolPair.second;
5656 }
5757 }
5858
59 void dumpDebugARanges(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
60 DataExtractor ArangesData(DCtx.getARangeSection(), DCtx.isLittleEndian(), 0);
59 void dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
60 DataExtractor ArangesData(DCtx.getDWARFObj().getARangeSection(),
61 DCtx.isLittleEndian(), 0);
6162 uint32_t Offset = 0;
6263 DWARFDebugArangeSet Set;
6364
7879 }
7980 }
8081
81 void dumpPubSection(DWARFContextInMemory &DCtx, DWARFYAML::PubSection &Y,
82 void dumpPubSection(DWARFContext &DCtx, DWARFYAML::PubSection &Y,
8283 StringRef Section) {
8384 DataExtractor PubSectionData(Section, DCtx.isLittleEndian(), 0);
8485 uint32_t Offset = 0;
9697 }
9798 }
9899
99 void dumpDebugPubSections(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
100 void dumpDebugPubSections(DWARFContext &DCtx, DWARFYAML::Data &Y) {
101 const DWARFObject &D = DCtx.getDWARFObj();
100102 Y.PubNames.IsGNUStyle = false;
101 dumpPubSection(DCtx, Y.PubNames, DCtx.getPubNamesSection());
103 dumpPubSection(DCtx, Y.PubNames, D.getPubNamesSection());
102104
103105 Y.PubTypes.IsGNUStyle = false;
104 dumpPubSection(DCtx, Y.PubTypes, DCtx.getPubTypesSection());
106 dumpPubSection(DCtx, Y.PubTypes, D.getPubTypesSection());
105107
106108 Y.GNUPubNames.IsGNUStyle = true;
107 dumpPubSection(DCtx, Y.GNUPubNames, DCtx.getGnuPubNamesSection());
109 dumpPubSection(DCtx, Y.GNUPubNames, D.getGnuPubNamesSection());
108110
109111 Y.GNUPubTypes.IsGNUStyle = true;
110 dumpPubSection(DCtx, Y.GNUPubTypes, DCtx.getGnuPubTypesSection());
111 }
112
113 void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
112 dumpPubSection(DCtx, Y.GNUPubTypes, D.getGnuPubTypesSection());
113 }
114
115 void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) {
114116 for (const auto &CU : DCtx.compile_units()) {
115117 DWARFYAML::Unit NewUnit;
116118 NewUnit.Length.setLength(CU->getLength());
234236 return true;
235237 }
236238
237 void dumpDebugLines(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
239 void dumpDebugLines(DWARFContext &DCtx, DWARFYAML::Data &Y) {
238240 for (const auto &CU : DCtx.compile_units()) {
239241 auto CUDIE = CU->getUnitDIE();
240242 if (!CUDIE)
242244 if (auto StmtOffset =
243245 dwarf::toSectionOffset(CUDIE.find(dwarf::DW_AT_stmt_list))) {
244246 DWARFYAML::LineTable DebugLines;
245 DataExtractor LineData(DCtx.getLineSection().Data, DCtx.isLittleEndian(),
246 CU->getAddressByteSize());
247 DataExtractor LineData(DCtx.getDWARFObj().getLineSection().Data,
248 DCtx.isLittleEndian(), CU->getAddressByteSize());
247249 uint32_t Offset = *StmtOffset;
248250 dumpInitialLength(LineData, Offset, DebugLines.Length);
249251 uint64_t LineTableLength = DebugLines.Length.getLength();
343345 }
344346 }
345347
346 std::error_code dwarf2yaml(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
348 std::error_code dwarf2yaml(DWARFContext &DCtx, DWARFYAML::Data &Y) {
347349 dumpDebugAbbrev(DCtx, Y);
348350 dumpDebugStrings(DCtx, Y);
349351 dumpDebugARanges(DCtx, Y);
3434 ArrayRef OpcodeBuffer, bool Lazy = false);
3535 void dumpExportTrie(std::unique_ptr &Y);
3636 void dumpSymbols(std::unique_ptr &Y);
37 void dumpDebugAbbrev(DWARFContextInMemory &DCtx,
37 void dumpDebugAbbrev(DWARFContext &DCtx,
3838 std::unique_ptr &Y);
39 void dumpDebugStrings(DWARFContextInMemory &DCtx,
39 void dumpDebugStrings(DWARFContext &DCtx,
4040 std::unique_ptr &Y);
4141
4242 public:
186186 dumpLoadCommands(Y);
187187 dumpLinkEdit(Y);
188188
189 DWARFContextInMemory DICtx(Obj);
190 if (auto Err = dwarf2yaml(DICtx, Y->DWARF))
189 std::unique_ptr DICtx = DWARFContext::create(Obj);
190 if (auto Err = dwarf2yaml(*DICtx, Y->DWARF))
191191 return errorCodeToError(Err);
192192 return std::move(Y);
193193 }
2828
2929 // Forward decls for dwarf2yaml
3030 namespace llvm {
31 class DWARFContextInMemory;
31 class DWARFContext;
3232 namespace DWARFYAML {
3333 struct Data;
3434 }
3535 }
3636
37 std::error_code dwarf2yaml(llvm::DWARFContextInMemory &DCtx,
38 llvm::DWARFYAML::Data &Y);
37 std::error_code dwarf2yaml(llvm::DWARFContext &DCtx, llvm::DWARFYAML::Data &Y);
3938
4039 #endif
1313 #include "llvm/ADT/StringRef.h"
1414 #include "llvm/ADT/Triple.h"
1515 #include "llvm/BinaryFormat/Dwarf.h"
16 #include "llvm/CodeGen/AsmPrinter.h"
1617 #include "llvm/Config/llvm-config.h"
17 #include "llvm/CodeGen/AsmPrinter.h"
1818 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
1919 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
2020 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
2727 #include "llvm/ObjectYAML/DWARFYAML.h"
2828 #include "llvm/Support/Error.h"
2929 #include "llvm/Support/MemoryBuffer.h"
30 #include "llvm/Support/TargetRegistry.h"
3031 #include "llvm/Support/TargetSelect.h"
31 #include "llvm/Support/TargetRegistry.h"
3232 #include "llvm/Testing/Support/Error.h"
3333 #include "gtest/gtest.h"
3434 #include
227227 MemoryBufferRef FileBuffer(FileBytes, "dwarf");
228228 auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
229229 EXPECT_TRUE((bool)Obj);
230 DWARFContextInMemory DwarfContext(*Obj.get());
231 uint32_t NumCUs = DwarfContext.getNumCompileUnits();
230 std::unique_ptr DwarfContext = DWARFContext::create(**Obj);
231 uint32_t NumCUs = DwarfContext->getNumCompileUnits();
232232 EXPECT_EQ(NumCUs, 1u);
233 DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
233 DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
234234 auto DieDG = U->getUnitDIE(false);
235235 EXPECT_TRUE(DieDG.isValid());
236236
457457 MemoryBufferRef FileBuffer(FileBytes, "dwarf");
458458 auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
459459 EXPECT_TRUE((bool)Obj);
460 DWARFContextInMemory DwarfContext(*Obj.get());
460 std::unique_ptr DwarfContext = DWARFContext::create(**Obj);
461461
462462 // Verify the number of compile units is correct.
463 uint32_t NumCUs = DwarfContext.getNumCompileUnits();
463 uint32_t NumCUs = DwarfContext->getNumCompileUnits();
464464 EXPECT_EQ(NumCUs, 1u);
465 DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
465 DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
466466
467467 // Get the compile unit DIE is valid.
468468 auto DieDG = U->getUnitDIE(false);
628628 MemoryBufferRef FileBuffer(FileBytes, "dwarf");
629629 auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
630630 EXPECT_TRUE((bool)Obj);
631 DWARFContextInMemory DwarfContext(*Obj.get());
631 std::unique_ptr DwarfContext = DWARFContext::create(**Obj);
632632
633633 // Verify the number of compile units is correct.
634 uint32_t NumCUs = DwarfContext.getNumCompileUnits();
634 uint32_t NumCUs = DwarfContext->getNumCompileUnits();
635635 EXPECT_EQ(NumCUs, 2u);
636 DWARFCompileUnit *U1 = DwarfContext.getCompileUnitAtIndex(0);
637 DWARFCompileUnit *U2 = DwarfContext.getCompileUnitAtIndex(1);
636 DWARFCompileUnit *U1 = DwarfContext->getCompileUnitAtIndex(0);
637 DWARFCompileUnit *U2 = DwarfContext->getCompileUnitAtIndex(1);
638638
639639 // Get the compile unit DIE is valid.
640640 auto Unit1DieDG = U1->getUnitDIE(false);
836836 MemoryBufferRef FileBuffer(FileBytes, "dwarf");
837837 auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
838838 EXPECT_TRUE((bool)Obj);
839 DWARFContextInMemory DwarfContext(*Obj.get());
839 std::unique_ptr DwarfContext = DWARFContext::create(**Obj);
840840
841841 // Verify the number of compile units is correct.
842 uint32_t NumCUs = DwarfContext.getNumCompileUnits();
842 uint32_t NumCUs = DwarfContext->getNumCompileUnits();
843843 EXPECT_EQ(NumCUs, 1u);
844 DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
844 DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
845845
846846 // Get the compile unit DIE is valid.
847847 auto DieDG = U->getUnitDIE(false);
10111011 MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
10121012 auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
10131013 EXPECT_TRUE((bool)Obj);
1014 DWARFContextInMemory DwarfContext(*Obj.get());
1014 std::unique_ptr DwarfContext = DWARFContext::create(**Obj);
10151015
10161016 // Verify the number of compile units is correct.
1017 uint32_t NumCUs = DwarfContext.getNumCompileUnits();
1017 uint32_t NumCUs = DwarfContext->getNumCompileUnits();
10181018 EXPECT_EQ(NumCUs, 1u);
1019 DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
1019 DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
10201020
10211021 // Get the compile unit DIE is valid.
10221022 auto CUDie = U->getUnitDIE(false);
11261126 MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
11271127 auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
11281128 EXPECT_TRUE((bool)Obj);
1129 DWARFContextInMemory DwarfContext(*Obj.get());
1129 std::unique_ptr DwarfContext = DWARFContext::create(**Obj);
11301130
11311131 // Verify the number of compile units is correct.
1132 uint32_t NumCUs = DwarfContext.getNumCompileUnits();
1132 uint32_t NumCUs = DwarfContext->getNumCompileUnits();
11331133 EXPECT_EQ(NumCUs, 1u);
1134 DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
1134 DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
11351135
11361136 // Get the compile unit DIE is valid.
11371137 auto CUDie = U->getUnitDIE(false);
11871187
11881188 auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
11891189 ASSERT_TRUE((bool)ErrOrSections);
1190 DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
1190 std::unique_ptr DwarfContext =
1191 DWARFContext::create(*ErrOrSections, 8);
11911192
11921193 // Verify the number of compile units is correct.
1193 uint32_t NumCUs = DwarfContext.getNumCompileUnits();
1194 uint32_t NumCUs = DwarfContext->getNumCompileUnits();
11941195 EXPECT_EQ(NumCUs, 1u);
1195 DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
1196 DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
11961197
11971198 // Get the compile unit DIE is valid.
11981199 auto CUDie = U->getUnitDIE(false);
12341235 MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
12351236 auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
12361237 EXPECT_TRUE((bool)Obj);
1237 DWARFContextInMemory DwarfContext(*Obj.get());
1238 std::unique_ptr DwarfContext = DWARFContext::create(**Obj);
12381239
12391240 // Verify the number of compile units is correct.
1240 uint32_t NumCUs = DwarfContext.getNumCompileUnits();
1241 uint32_t NumCUs = DwarfContext->getNumCompileUnits();
12411242 EXPECT_EQ(NumCUs, 1u);
1242 DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
1243 DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
12431244
12441245 // Get the compile unit DIE is valid.
12451246 auto CUDie = U->getUnitDIE(false);
12981299 MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
12991300 auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
13001301 EXPECT_TRUE((bool)Obj);
1301 DWARFContextInMemory DwarfContext(*Obj.get());
1302 std::unique_ptr DwarfContext = DWARFContext::create(**Obj);
13021303
13031304 // Verify the number of compile units is correct.
1304 uint32_t NumCUs = DwarfContext.getNumCompileUnits();
1305 uint32_t NumCUs = DwarfContext->getNumCompileUnits();
13051306 EXPECT_EQ(NumCUs, 1u);
1306 DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
1307 DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
13071308
13081309 // Get the compile unit DIE is valid.
13091310 auto CUDie = U->getUnitDIE(false);
15041505 MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
15051506 auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
15061507 EXPECT_TRUE((bool)Obj);
1507 DWARFContextInMemory DwarfContext(*Obj.get());
1508 std::unique_ptr DwarfContext = DWARFContext::create(**Obj);
15081509
15091510 // Verify the number of compile units is correct.
1510 uint32_t NumCUs = DwarfContext.getNumCompileUnits();
1511 uint32_t NumCUs = DwarfContext->getNumCompileUnits();
15111512 EXPECT_EQ(NumCUs, 1u);
1512 DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
1513 DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
15131514
15141515 // Get the compile unit DIE is valid.
15151516 auto CUDie = U->getUnitDIE(false);
15671568 MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
15681569 auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
15691570 EXPECT_TRUE((bool)Obj);
1570 DWARFContextInMemory DwarfContext(*Obj.get());
1571 DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
1571 std::unique_ptr DwarfContext = DWARFContext::create(**Obj);
1572 DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
15721573 EXPECT_TRUE((bool)U);
15731574
15741575 const auto *Abbrevs = U->getAbbreviations();
17071708 )";
17081709 auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
17091710 ASSERT_TRUE((bool)ErrOrSections);
1710 DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
1711 VerifyError(DwarfContext, "error: DW_FORM_ref4 CU offset 0x00001234 is "
1712 "invalid (must be less than CU size of "
1713 "0x0000001a):");
1711 std::unique_ptr DwarfContext =
1712 DWARFContext::create(*ErrOrSections, 8);
1713 VerifyError(*DwarfContext, "error: DW_FORM_ref4 CU offset 0x00001234 is "
1714 "invalid (must be less than CU size of "
1715 "0x0000001a):");
17141716 }
17151717
17161718 TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRefAddr) {
17551757 )";
17561758 auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
17571759 ASSERT_TRUE((bool)ErrOrSections);
1758 DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
1759 VerifyError(DwarfContext,
1760 std::unique_ptr DwarfContext =
1761 DWARFContext::create(*ErrOrSections, 8);
1762 VerifyError(*DwarfContext,
17601763 "error: DW_FORM_ref_addr offset beyond .debug_info bounds:");
17611764 }
17621765
17911794 )";
17921795 auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
17931796 ASSERT_TRUE((bool)ErrOrSections);
1794 DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
1795 VerifyError(DwarfContext,
1797 std::unique_ptr DwarfContext =
1798 DWARFContext::create(*ErrOrSections, 8);
1799 VerifyError(*DwarfContext,
17961800 "error: DW_AT_ranges offset is beyond .debug_ranges bounds:");
17971801 }
17981802
18271831 )";
18281832 auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
18291833 ASSERT_TRUE((bool)ErrOrSections);
1830 DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
1834 std::unique_ptr DwarfContext =
1835 DWARFContext::create(*ErrOrSections, 8);
18311836 VerifyError(
1832 DwarfContext,
1837 *DwarfContext,
18331838 "error: DW_AT_stmt_list offset is beyond .debug_line bounds: 0x00001000");
18341839 }
18351840
18591864 )";
18601865 auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
18611866 ASSERT_TRUE((bool)ErrOrSections);
1862 DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
1863 VerifyError(DwarfContext,
1867 std::unique_ptr DwarfContext =
1868 DWARFContext::create(*ErrOrSections, 8);
1869 VerifyError(*DwarfContext,
18641870 "error: DW_FORM_strp offset beyond .debug_str bounds:");
18651871 }
18661872
19061912 )";
19071913 auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
19081914 ASSERT_TRUE((bool)ErrOrSections);
1909 DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
1915 std::unique_ptr DwarfContext =
1916 DWARFContext::create(*ErrOrSections, 8);
19101917 VerifyError(
1911 DwarfContext,
1918 *DwarfContext,
19121919 "error: invalid DIE reference 0x00000011. Offset is in between DIEs:");
19131920 }
19141921
19761983 )";
19771984 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
19781985 ASSERT_TRUE((bool)ErrOrSections);
1979 DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
1980 VerifyError(DwarfContext, "error: .debug_line[0x00000000] row[1] decreases "
1981 "in address from previous row:");
1986 std::unique_ptr DwarfContext =
1987 DWARFContext::create(*ErrOrSections, 8);
1988 VerifyError(*DwarfContext, "error: .debug_line[0x00000000] row[1] decreases "
1989 "in address from previous row:");
19821990 }
19831991
19841992 TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineFileIndex) {
20472055 )";
20482056 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
20492057 ASSERT_TRUE((bool)ErrOrSections);
2050 DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
2051 VerifyError(DwarfContext, "error: .debug_line[0x00000000][1] has invalid "
2052 "file index 5 (valid values are [1,1]):");
2058 std::unique_ptr DwarfContext =
2059 DWARFContext::create(*ErrOrSections, 8);
2060 VerifyError(*DwarfContext, "error: .debug_line[0x00000000][1] has invalid "
2061 "file index 5 (valid values are [1,1]):");
20532062 }
20542063
20552064 TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) {
21272136 )";
21282137 auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
21292138 ASSERT_TRUE((bool)ErrOrSections);
2130 DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
2131 VerifyError(DwarfContext, "error: two compile unit DIEs, 0x0000000b and "
2132 "0x0000001f, have the same DW_AT_stmt_list section "
2133 "offset:");
2139 std::unique_ptr DwarfContext =
2140 DWARFContext::create(*ErrOrSections, 8);
2141 VerifyError(*DwarfContext,
2142 "error: two compile unit DIEs, 0x0000000b and "
2143 "0x0000001f, have the same DW_AT_stmt_list section "
2144 "offset:");
21342145 }
21352146
21362147 TEST(DWARFDebugInfo, TestErrorReportingPolicy) {
21602171 // DWARFContextInMemory
21612172 // to parse whole file and find both two errors we know about.
21622173 int Errors = 0;
2163 DWARFContextInMemory Ctx1(*Obj.get(), nullptr, [&](Error E) {
2164 ++Errors;
2165 consumeError(std::move(E));
2166 return ErrorPolicy::Continue;
2167 });
2174 std::unique_ptr Ctx1 =
2175 DWARFContext::create(**Obj, nullptr, [&](Error E) {
2176 ++Errors;
2177 consumeError(std::move(E));
2178 return ErrorPolicy::Continue;
2179 });
21682180 EXPECT_TRUE(Errors == 2);
21692181
21702182 // Case 2: error handler stops parsing of object after first error.
21712183 Errors = 0;
2172 DWARFContextInMemory Ctx2(*Obj.get(), nullptr, [&](Error E) {
2173 ++Errors;
2174 consumeError(std::move(E));
2175 return ErrorPolicy::Halt;
2176 });
2184 std::unique_ptr Ctx2 =
2185 DWARFContext::create(**Obj, nullptr, [&](Error E) {
2186 ++Errors;
2187 consumeError(std::move(E));
2188 return ErrorPolicy::Halt;
2189 });
21772190 EXPECT_TRUE(Errors == 1);
21782191 }
21792192