diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 13 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 25 |
6 files changed, 54 insertions, 19 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index a4d699496b4..04c206ffea2 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -855,6 +855,8 @@ void DwarfCompileUnit::emitHeader(bool UseOffsets) { : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton : dwarf::DW_UT_compile; DwarfUnit::emitCommonHeader(UseOffsets, UT); + if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile) + Asm->emitInt64(getDWOId()); } bool DwarfCompileUnit::hasDwarfPubSections() const { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 60821c2cc99..5aea16acdc1 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -83,6 +83,9 @@ class DwarfCompileUnit final : public DwarfUnit { DenseMap<const MDNode *, DIE *> AbstractSPDies; DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> AbstractVariables; + /// DWO ID for correlating skeleton and split units. + uint64_t DWOId = 0; + /// Construct a DIE for the given DbgVariable without initializing the /// DbgVariable's DIE reference. DIE *constructVariableDIEImpl(const DbgVariable &DV, bool Abstract); @@ -219,6 +222,13 @@ public: /// Set the skeleton unit associated with this unit. void setSkeleton(DwarfCompileUnit &Skel) { Skeleton = &Skel; } + unsigned getHeaderSize() const override { + // DWARF v5 added the DWO ID to the header for split/skeleton units. + unsigned DWOIdSize = + DD->getDwarfVersion() >= 5 && DD->useSplitDwarf() ? sizeof(uint64_t) + : 0; + return DwarfUnit::getHeaderSize() + DWOIdSize; + } unsigned getLength() { return sizeof(uint32_t) + // Length field getHeaderSize() + getUnitDie().getSize(); @@ -290,6 +300,9 @@ public: void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; } const MCSymbol *getBaseAddress() const { return BaseAddress; } + uint64_t getDWOId() const { return DWOId; } + void setDWOId(uint64_t DwoId) { DWOId = DwoId; } + bool hasDwarfPubSections() const; }; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 4f61fca4343..258a6d36067 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -747,11 +747,15 @@ void DwarfDebug::finalizeModuleInfo() { // Emit a unique identifier for this CU. uint64_t ID = DIEHash(Asm).computeCUSignature(DWOName, TheCU.getUnitDie()); - TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id, - dwarf::DW_FORM_data8, ID); - SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, - dwarf::DW_FORM_data8, ID); - + if (getDwarfVersion() >= 5) { + TheCU.setDWOId(ID); + SkCU->setDWOId(ID); + } else { + TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); + SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); + } // We don't keep track of which addresses are used in which CU so this // is a bit pessimistic under LTO. if (!AddrPool.isEmpty()) { diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp index 43b235621d1..00a23b3898f 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp @@ -22,9 +22,10 @@ void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { if (getVersion() >= 5) OS << " unit_type = " << dwarf::UnitTypeString(getUnitType()); OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset()) - << " addr_size = " << format("0x%02x", getAddressByteSize()) - << " (next unit at " << format("0x%08x", getNextUnitOffset()) - << ")\n"; + << " addr_size = " << format("0x%02x", getAddressByteSize()); + if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile) + OS << " DWO_id = " << format("0x%016" PRIx64, *getDWOId()); + OS << " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n"; if (DWARFDie CUDie = getUnitDIE(false)) CUDie.dump(OS, 0, DumpOpts); diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 982dd7cf479..a4053a30536 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -561,9 +561,19 @@ DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) { // probably only one unless this is something like LTO - though an in-process // built/cached lookup table could be used in that case to improve repeated // lookups of different CUs in the DWO. - for (const auto &DWOCU : dwo_compile_units()) + for (const auto &DWOCU : dwo_compile_units()) { + // Might not have parsed DWO ID yet. + if (!DWOCU->getDWOId()) { + if (Optional<uint64_t> DWOId = + toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id))) + DWOCU->setDWOId(*DWOId); + else + // No DWO ID? + continue; + } if (DWOCU->getDWOId() == Hash) return DWOCU.get(); + } return nullptr; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index 78d267d64fc..260c5dc94c4 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -130,15 +130,22 @@ bool DWARFUnitHeader::extract(DWARFContext &Context, return false; AbbrOffset = AbbrEntry->Offset; } - bool TypeOffsetOK = true; if (isTypeUnit()) { TypeHash = debug_info.getU64(offset_ptr); TypeOffset = debug_info.getU32(offset_ptr); - // Type offset is unit-relative; should be after the header and before - // the end of the current unit. - TypeOffsetOK = TypeOffset >= *offset_ptr - Offset && - TypeOffset < getLength() + SizeOfLength; - } + } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton) + DWOId = debug_info.getU64(offset_ptr); + + // Header fields all parsed, capture the size of this unit header. + assert(*offset_ptr - Offset <= 255 && "unexpected header size"); + Size = uint8_t(*offset_ptr - Offset); + + // Type offset is unit-relative; should be after the header and before + // the end of the current unit. + bool TypeOffsetOK = + !isTypeUnit() + ? true + : TypeOffset >= Size && TypeOffset < getLength() + SizeOfLength; bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1); bool VersionOK = DWARFContext::isSupportedVersion(getVersion()); bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8; @@ -197,10 +204,6 @@ const char *DWARFUnit::getCompilationDir() { return dwarf::toString(getUnitDIE().find(DW_AT_comp_dir), nullptr); } -Optional<uint64_t> DWARFUnit::getDWOId() { - return toUnsigned(getUnitDIE().find(DW_AT_GNU_dwo_id)); -} - void DWARFUnit::extractDIEsToVector( bool AppendCUDie, bool AppendNonCUDies, std::vector<DWARFDebugInfoEntry> &Dies) const { @@ -269,6 +272,8 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) { // If CU DIE was just parsed, copy several attribute values from it. if (!HasCUDie) { DWARFDie UnitDie = getUnitDIE(); + if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id))) + Header.setDWOId(*DWOId); if (!isDWO) { assert(AddrOffsetSectionBase == 0); assert(RangeSectionBase == 0); |