Skip to content

Commit 82f8aef

Browse files
committed
[JITLink][MachO] Handle muliple symbols at same offset when splitting C-strings.
The C-string section splitting support added in f9649d1 triggered an assert ("Duplicate canonical symbol at address") when multiple symbols were defined at the the same offset within a C-string block (this triggered on arm64, where we always add a block start symbol). The bug was caused by a failure to update the record of the last canonical symbol address. The fix was to maintain this record correctly, and move the auto-generation of the block-start symbol above the handling for symbols defined in the object itself so that all symbols (auto-generated and defined) are processed in address order.
1 parent e978f6b commit 82f8aef

File tree

1 file changed

+21
-19
lines changed

1 file changed

+21
-19
lines changed

llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -655,37 +655,39 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
655655
<< " for \"" << StringRef(B.getContent().data()) << "\"\n";
656656
});
657657

658-
// Process any symbols that point into this block.
659-
JITTargetAddress LastCanonicalAddr = BlockEnd;
660-
Symbol *BlockStartSymbol = nullptr;
658+
// If there's no symbol at the start of this block then create one.
659+
if (NSyms.empty() || NSyms.back()->Value != B.getAddress()) {
660+
auto &S = G->addAnonymousSymbol(B, 0, BlockSize, false, false);
661+
setCanonicalSymbol(S);
662+
LLVM_DEBUG({
663+
dbgs() << " Adding anonymous symbol for c-string block "
664+
<< formatv("{0:x16} -- {1:x16}", S.getAddress(),
665+
S.getAddress() + BlockSize)
666+
<< "\n";
667+
});
668+
}
669+
670+
// Process any remaining symbols that point into this block.
671+
JITTargetAddress LastCanonicalAddr = B.getAddress() + BlockEnd;
661672
while (!NSyms.empty() &&
662673
NSyms.back()->Value < (B.getAddress() + BlockSize)) {
663674
auto &NSym = *NSyms.back();
664675
size_t SymSize = (B.getAddress() + BlockSize) - NSyms.back()->Value;
665676
bool SymLive =
666677
(NSym.Desc & MachO::N_NO_DEAD_STRIP) || SectionIsNoDeadStrip;
667678

668-
auto &S =
669-
createStandardGraphSymbol(NSym, B, SymSize, SectionIsText, SymLive,
670-
NSym.Value != LastCanonicalAddr);
679+
bool IsCanonical = false;
680+
if (LastCanonicalAddr != NSym.Value) {
681+
IsCanonical = true;
682+
LastCanonicalAddr = NSym.Value;
683+
}
671684

672-
if (S.getAddress() == B.getAddress() && !BlockStartSymbol)
673-
BlockStartSymbol = &S;
685+
createStandardGraphSymbol(NSym, B, SymSize, SectionIsText, SymLive,
686+
IsCanonical);
674687

675688
NSyms.pop_back();
676689
}
677690

678-
if (!BlockStartSymbol) {
679-
auto &S = G->addAnonymousSymbol(B, 0, BlockSize, false, false);
680-
setCanonicalSymbol(S);
681-
LLVM_DEBUG({
682-
dbgs() << " Adding anonymous symbol for "
683-
<< formatv("{0:x16} -- {1:x16}", S.getAddress(),
684-
S.getAddress() + BlockSize)
685-
<< "\n";
686-
});
687-
}
688-
689691
BlockStart += BlockSize;
690692
}
691693

0 commit comments

Comments
 (0)