summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp2
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h13
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp14
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp7
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp12
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp25
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);
OpenPOWER on IntegriCloud