diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h | 7 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 48 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 9 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/Inputs/split-dwarf-dwp.o | bin | 0 -> 2744 bytes | |||
| -rw-r--r-- | llvm/test/DebugInfo/Inputs/split-dwarf-dwp.o.dwp | bin | 0 -> 1256 bytes | |||
| -rw-r--r-- | llvm/test/DebugInfo/llvm-symbolizer.test | 8 |
6 files changed, 59 insertions, 13 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h index 25ddcf38a65..42883967a9e 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -76,6 +76,8 @@ class DWARFContext : public DIContext { std::unique_ptr<DWARFContext> Context; }; StringMap<std::weak_ptr<DWOFile>> DWOFiles; + std::weak_ptr<DWOFile> DWP; + bool CheckedForDWP = false; /// Read compile units from the debug_info section (if necessary) /// and store them in CUs. @@ -171,6 +173,8 @@ public: return DWOCUs[index].get(); } + DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash); + /// Get a DIE given an exact offset. DWARFDie getDIEForOffset(uint32_t Offset); @@ -212,6 +216,7 @@ public: DIInliningInfo getInliningInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; + virtual StringRef getFileName() const = 0; virtual bool isLittleEndian() const = 0; virtual uint8_t getAddressSize() const = 0; virtual const DWARFSection &getInfoSection() = 0; @@ -271,6 +276,7 @@ private: class DWARFContextInMemory : public DWARFContext { virtual void anchor(); + StringRef FileName; bool IsLittleEndian; uint8_t AddressSize; DWARFSection InfoSection; @@ -324,6 +330,7 @@ public: uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost); + StringRef getFileName() const override { return FileName; } bool isLittleEndian() const override { return IsLittleEndian; } uint8_t getAddressSize() const override { return AddressSize; } const DWARFSection &getInfoSection() override { return InfoSection; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 41a4620372e..896837c8547 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -287,6 +287,15 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH, getStringSection(), isLittleEndian()); } +DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) { + // FIXME: Improve this for the case where this DWO file is really a DWP file + // with an index - use the index for lookup instead of a linear search. + for (const auto &DWOCU : dwo_compile_units()) + if (DWOCU->getDWOId() == Hash) + return DWOCU.get(); + return nullptr; +} + DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) { parseCompileUnits(); if (auto *CU = CUs.getUnitForOffset(Offset)) @@ -899,22 +908,47 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address, std::shared_ptr<DWARFContext> DWARFContext::getDWOContext(StringRef AbsolutePath) { - auto &Entry = DWOFiles[AbsolutePath]; - if (auto S = Entry.lock()) { + if (auto S = DWP.lock()) { DWARFContext *Ctxt = S->Context.get(); return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); } - auto S = std::make_shared<DWOFile>(); - auto Obj = object::ObjectFile::createObjectFile(AbsolutePath); + std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath]; + + if (auto S = Entry->lock()) { + DWARFContext *Ctxt = S->Context.get(); + return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); + } + + SmallString<128> DWPName; + Expected<OwningBinary<ObjectFile>> Obj = [&] { + if (!CheckedForDWP) { + (getFileName() + ".dwp").toVector(DWPName); + auto Obj = object::ObjectFile::createObjectFile(DWPName); + if (Obj) { + Entry = &DWP; + return Obj; + } else { + CheckedForDWP = true; + // TODO: Should this error be handled (maybe in a high verbosity mode) + // before falling back to .dwo files? + consumeError(Obj.takeError()); + } + } + + return object::ObjectFile::createObjectFile(AbsolutePath); + }(); + if (!Obj) { // TODO: Actually report errors helpfully. consumeError(Obj.takeError()); return nullptr; } + + auto S = std::make_shared<DWOFile>(); S->File = std::move(Obj.get()); S->Context = llvm::make_unique<DWARFContextInMemory>(*S->File.getBinary()); - Entry = S; + *Entry = S; auto *Ctxt = S->Context.get(); return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); } @@ -1011,8 +1045,8 @@ Error DWARFContextInMemory::maybeDecompress(const SectionRef &Sec, } DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, - const LoadedObjectInfo *L) - : IsLittleEndian(Obj.isLittleEndian()), + const LoadedObjectInfo *L) + : FileName(Obj.getFileName()), IsLittleEndian(Obj.isLittleEndian()), AddressSize(Obj.getBytesInAddress()) { for (const SectionRef &Section : Obj.sections()) { StringRef name; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index 0a3ba480776..c5add6a478b 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -274,13 +274,10 @@ bool DWARFUnit::parseDWO() { if (!DWOContext) return false; - for (const auto &DWOCU : DWOContext->dwo_compile_units()) - if (DWOCU->getDWOId() == DWOId) { - DWO = std::shared_ptr<DWARFUnit>(std::move(DWOContext), DWOCU.get()); - break; - } - if (!DWO) + DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId); + if (!DWOCU) return false; + DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU); // Share .debug_addr and .debug_ranges section with compile unit in .dwo DWO->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase); auto DWORangesBase = UnitDie.getRangesBaseAttribute(); diff --git a/llvm/test/DebugInfo/Inputs/split-dwarf-dwp.o b/llvm/test/DebugInfo/Inputs/split-dwarf-dwp.o Binary files differnew file mode 100644 index 00000000000..614c62040de --- /dev/null +++ b/llvm/test/DebugInfo/Inputs/split-dwarf-dwp.o diff --git a/llvm/test/DebugInfo/Inputs/split-dwarf-dwp.o.dwp b/llvm/test/DebugInfo/Inputs/split-dwarf-dwp.o.dwp Binary files differnew file mode 100644 index 00000000000..16a0af8c062 --- /dev/null +++ b/llvm/test/DebugInfo/Inputs/split-dwarf-dwp.o.dwp diff --git a/llvm/test/DebugInfo/llvm-symbolizer.test b/llvm/test/DebugInfo/llvm-symbolizer.test index f0db8f4b921..2c64804659f 100644 --- a/llvm/test/DebugInfo/llvm-symbolizer.test +++ b/llvm/test/DebugInfo/llvm-symbolizer.test @@ -27,6 +27,9 @@ RUN: cp %p/Inputs/split-dwarf-multiple-cu.dwo %T RUN: echo "%p/Inputs/split-dwarf-multiple-cu.o 0x4" >> %t.input RUN: cp %p/Inputs/split-dwarf-addr-object-relocation.dwo %T RUN: echo "%p/Inputs/split-dwarf-addr-object-relocation.o 0x14" >> %t.input +RUN: cp %p/Inputs/split-dwarf-dwp.o %T +RUN: cp %p/Inputs/split-dwarf-dwp.o.dwp %T +RUN: echo "%T/split-dwarf-dwp.o 0x4" >> %t.input RUN: llvm-symbolizer --functions=linkage --inlining --demangle=false \ RUN: --default-arch=i386 < %t.input | FileCheck --check-prefix=CHECK --check-prefix=SPLIT --check-prefix=DWO %s @@ -147,6 +150,11 @@ CHECK-NEXT: split-dwarf-addr-object-relocation.cpp:3:3 CHECK-NEXT: f3 CHECK-NEXT: split-dwarf-addr-object-relocation.cpp:6:0 +CHECK: f2 +CHECK-NEXT: split-dwarf-dwp.cpp:3:3 +CHECK-NEXT: f3 +CHECK-NEXT: split-dwarf-dwp.cpp:6:0 + RUN: echo "unexisting-file 0x1234" > %t.input2 RUN: llvm-symbolizer < %t.input2 2>&1 | FileCheck %s --check-prefix=MISSING-FILE |

