aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorJonas Devlieghere <jonas@devlieghere.com>2022-12-20 11:28:57 -0800
committerJonas Devlieghere <jonas@devlieghere.com>2022-12-20 12:53:17 -0800
commitc9cbe6937b1fe797f805648216257ae88bde4ad7 (patch)
tree765ff7b660943d8be55078c0f7bc74f4d29a80af /llvm/lib
parent66ba7c32add07204dd0b8a7e0c14b44f0d3b850d (diff)
downloadllvm-c9cbe6937b1fe797f805648216257ae88bde4ad7.zip
llvm-c9cbe6937b1fe797f805648216257ae88bde4ad7.tar.gz
llvm-c9cbe6937b1fe797f805648216257ae88bde4ad7.tar.bz2
[dsymutil] Track uncloned references in the DIEInfo.
To improve deduplication across CUs within a single object file, 2b747241a6a0 changed the way we track ODR canonical candidates. The result is that some assumptions no longer hold. Because of the aforementioned change, the following condition assert(Ref > InputDIE.getOffset()); in DWARFLinker::DIECloner::cloneDieReferenceAttribute is no longer an invariant. An example of a situation where this assertion no longer holds is when we have decided to replace a backward reference in the current CU with a forward reference in a subsequent CU. The ODR canonical DIE hasn't been emitted yet, but the references DIE has an offset smaller than the current DIE. The assertion is only true if the referenced DIE was the ODR canonical DIE, which is no longer guaranteed to be part of the same CU. Big thanks to Alexey for putting a test together. Differential revision: https://reviews.llvm.org/D138176
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DWARFLinker/DWARFLinker.cpp6
-rw-r--r--llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp4
2 files changed, 6 insertions, 4 deletions
diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp
index ee70690..6096ffc 100644
--- a/llvm/lib/DWARFLinker/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp
@@ -935,9 +935,9 @@ unsigned DWARFLinker::DIECloner::cloneDieReferenceAttribute(
}
if (!RefInfo.Clone) {
- assert(Ref > InputDIE.getOffset());
// We haven't cloned this DIE yet. Just create an empty one and
// store it. It'll get really cloned when we process it.
+ RefInfo.UnclonedReference = true;
RefInfo.Clone = DIE::get(DIEAlloc, dwarf::Tag(RefDie.getTag()));
}
NewRefDie = RefInfo.Clone;
@@ -950,8 +950,8 @@ unsigned DWARFLinker::DIECloner::cloneDieReferenceAttribute(
// FIXME: we should be able to design DIEEntry reliance on
// DwarfDebug away.
uint64_t Attr;
- if (Ref < InputDIE.getOffset()) {
- // We must have already cloned that DIE.
+ if (Ref < InputDIE.getOffset() && !RefInfo.UnclonedReference) {
+ // We have already cloned that DIE.
uint32_t NewRefOffset =
RefUnit->getStartOffset() + NewRefDie->getOffset();
Attr = NewRefOffset;
diff --git a/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
index 77d914a..d8bac50 100644
--- a/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
+++ b/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
@@ -94,8 +94,10 @@ void CompileUnit::fixupForwardReferences() {
assert(Ctxt->getCanonicalDIEOffset() &&
"Canonical die offset is not set");
Attr.set(Ctxt->getCanonicalDIEOffset());
- } else
+ } else {
+ assert(RefDie->getOffset() && "Referenced die offset is not set");
Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());
+ }
}
}