[JITLink][MachO] Handle muliple symbols at same offset when splitting C-strings.

The C-string section splitting support added in f9649d123d 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.
This commit is contained in:
Lang Hames 2021-06-09 18:56:30 +10:00
parent e978f6bc97
commit 82f8aef3de
1 changed files with 21 additions and 19 deletions

View File

@ -655,9 +655,20 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
<< " for \"" << StringRef(B.getContent().data()) << "\"\n";
});
// Process any symbols that point into this block.
JITTargetAddress LastCanonicalAddr = BlockEnd;
Symbol *BlockStartSymbol = nullptr;
// If there's no symbol at the start of this block then create one.
if (NSyms.empty() || NSyms.back()->Value != B.getAddress()) {
auto &S = G->addAnonymousSymbol(B, 0, BlockSize, false, false);
setCanonicalSymbol(S);
LLVM_DEBUG({
dbgs() << " Adding anonymous symbol for c-string block "
<< formatv("{0:x16} -- {1:x16}", S.getAddress(),
S.getAddress() + BlockSize)
<< "\n";
});
}
// Process any remaining symbols that point into this block.
JITTargetAddress LastCanonicalAddr = B.getAddress() + BlockEnd;
while (!NSyms.empty() &&
NSyms.back()->Value < (B.getAddress() + BlockSize)) {
auto &NSym = *NSyms.back();
@ -665,27 +676,18 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
bool SymLive =
(NSym.Desc & MachO::N_NO_DEAD_STRIP) || SectionIsNoDeadStrip;
auto &S =
createStandardGraphSymbol(NSym, B, SymSize, SectionIsText, SymLive,
NSym.Value != LastCanonicalAddr);
bool IsCanonical = false;
if (LastCanonicalAddr != NSym.Value) {
IsCanonical = true;
LastCanonicalAddr = NSym.Value;
}
if (S.getAddress() == B.getAddress() && !BlockStartSymbol)
BlockStartSymbol = &S;
createStandardGraphSymbol(NSym, B, SymSize, SectionIsText, SymLive,
IsCanonical);
NSyms.pop_back();
}
if (!BlockStartSymbol) {
auto &S = G->addAnonymousSymbol(B, 0, BlockSize, false, false);
setCanonicalSymbol(S);
LLVM_DEBUG({
dbgs() << " Adding anonymous symbol for "
<< formatv("{0:x16} -- {1:x16}", S.getAddress(),
S.getAddress() + BlockSize)
<< "\n";
});
}
BlockStart += BlockSize;
}