forked from OSchip/llvm-project
[llvm-jitlink] Support promotion of ODR weak symbols in -harness mode.
This prevents weak symbols from being immediately dead-stripped when not directly referenced from the test harneess, enabling use of weak symbols from the code under test.
This commit is contained in:
parent
e281376e99
commit
e12a028ed3
|
@ -17,9 +17,16 @@ _public_func_to_interpose:
|
|||
_private_func_to_interpose:
|
||||
retq
|
||||
|
||||
.globl _used_weak
|
||||
.weak_definition _used_weak
|
||||
.p2align 4, 0x90
|
||||
_used_weak:
|
||||
retq
|
||||
|
||||
.globl _public_func_to_test
|
||||
.p2align 4, 0x90
|
||||
_public_func_to_test:
|
||||
callq _used_weak
|
||||
jmp _public_func_to_interpose
|
||||
|
||||
.p2align 4, 0x90
|
||||
|
|
|
@ -188,10 +188,28 @@ static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
|
|||
if (!Sym->hasName())
|
||||
continue;
|
||||
|
||||
if (S.HarnessExternals.count(Sym->getName())) {
|
||||
if (Sym->getLinkage() == Linkage::Weak) {
|
||||
if (!S.CanonicalWeakDefs.count(Sym->getName()) ||
|
||||
S.CanonicalWeakDefs[Sym->getName()] != G.getName()) {
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Externalizing weak symbol " << Sym->getName() << "\n";
|
||||
});
|
||||
DefinitionsToRemove.push_back(Sym);
|
||||
} else {
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Making weak symbol " << Sym->getName() << " strong\n";
|
||||
});
|
||||
if (S.HarnessExternals.count(Sym->getName()))
|
||||
Sym->setScope(Scope::Default);
|
||||
else
|
||||
Sym->setScope(Scope::Hidden);
|
||||
Sym->setLinkage(Linkage::Strong);
|
||||
}
|
||||
} else if (S.HarnessExternals.count(Sym->getName())) {
|
||||
LLVM_DEBUG(dbgs() << " Promoting " << Sym->getName() << "\n");
|
||||
Sym->setScope(Scope::Default);
|
||||
Sym->setLive(true);
|
||||
continue;
|
||||
} else if (S.HarnessDefinitions.count(Sym->getName())) {
|
||||
LLVM_DEBUG(dbgs() << " Externalizing " << Sym->getName() << "\n");
|
||||
DefinitionsToRemove.push_back(Sym);
|
||||
|
@ -504,10 +522,6 @@ Error LLVMJITLinkObjectLinkingLayer::add(JITDylib &JD,
|
|||
if (!Name)
|
||||
return Name.takeError();
|
||||
|
||||
// Skip symbols that aren't in the HarnessExternals set.
|
||||
if (!S.HarnessExternals.count(*Name))
|
||||
continue;
|
||||
|
||||
// Skip symbols that have type SF_File.
|
||||
if (auto SymType = Sym.getType()) {
|
||||
if (*SymType == object::SymbolRef::ST_File)
|
||||
|
@ -515,13 +529,28 @@ Error LLVMJITLinkObjectLinkingLayer::add(JITDylib &JD,
|
|||
} else
|
||||
return SymType.takeError();
|
||||
|
||||
auto InternedName = S.ES.intern(*Name);
|
||||
auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
|
||||
if (!SymFlags)
|
||||
return SymFlags.takeError();
|
||||
|
||||
*SymFlags |= JITSymbolFlags::Exported;
|
||||
if (SymFlags->isWeak()) {
|
||||
// If this is a weak symbol that's not defined in the harness then we
|
||||
// need to either mark it as strong (if this is the first definition
|
||||
// that we've seen) or discard it.
|
||||
if (S.HarnessDefinitions.count(*Name) || S.CanonicalWeakDefs.count(*Name))
|
||||
continue;
|
||||
S.CanonicalWeakDefs[*Name] = O->getBufferIdentifier();
|
||||
*SymFlags &= ~JITSymbolFlags::Weak;
|
||||
if (!S.HarnessExternals.count(*Name))
|
||||
*SymFlags &= ~JITSymbolFlags::Exported;
|
||||
} else if (S.HarnessExternals.count(*Name)) {
|
||||
*SymFlags |= JITSymbolFlags::Exported;
|
||||
} else {
|
||||
// Skip symbols that aren't in the HarnessExternals set.
|
||||
continue;
|
||||
}
|
||||
|
||||
auto InternedName = S.ES.intern(*Name);
|
||||
SymbolFlags[InternedName] = std::move(*SymFlags);
|
||||
}
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ struct Session {
|
|||
StringSet<> HarnessFiles;
|
||||
StringSet<> HarnessExternals;
|
||||
StringSet<> HarnessDefinitions;
|
||||
DenseMap<StringRef, StringRef> CanonicalWeakDefs;
|
||||
|
||||
private:
|
||||
Session(Triple TT, Error &Err);
|
||||
|
|
Loading…
Reference in New Issue