Skip to content

Commit 3eeb90e

Browse files
lhamesmemfrob
authored andcommitted
[ORC] Attempt to auto-claim responsibility for weak defs in ObjectLinkingLayer.
Compilers may insert new definitions during compilation, E.g. EH personality function pointers, or named constant pool entries. This commit causes ObjectLinkingLayer to attempt to claim responsibility for all weak definitions in objects as they're linked. This is always safe (first claimant for each symbol is granted responsibility, subsequent claims are rejected without error) and prevents compiler-injected symbols from being dead-stripped (which they will be if they remain unclaimed by anyone). This change was motivated by errors seen by an out-of-tree client while testing eh-frame support in JITLink ELF/x86-64: IR containing exceptions didn't define DW.ref.__gxx_personality_v0 (since it's added by CodeGen), and this caused DW.ref.__gxx_personality_v0 to be dead-stripped leading to linker failures. No test case yet: We won't have a way to test in-tree until we enable JITLink for lli on Linux.
1 parent 604a5bb commit 3eeb90e

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,9 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
214214
Error modifyPassConfig(const Triple &TT, PassConfiguration &Config) override {
215215
// Add passes to mark duplicate defs as should-discard, and to walk the
216216
// link graph to build the symbol dependence graph.
217-
Config.PrePrunePasses.push_back(
218-
[this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); });
217+
Config.PrePrunePasses.push_back([this](LinkGraph &G) {
218+
return claimOrExternalizeWeakAndCommonSymbols(G);
219+
});
219220

220221
Layer.modifyPassConfig(*MR, TT, Config);
221222

@@ -233,19 +234,38 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
233234
using LocalSymbolNamedDependenciesMap =
234235
DenseMap<const Symbol *, LocalSymbolNamedDependencies>;
235236

236-
Error externalizeWeakAndCommonSymbols(LinkGraph &G) {
237+
Error claimOrExternalizeWeakAndCommonSymbols(LinkGraph &G) {
237238
auto &ES = Layer.getExecutionSession();
238-
for (auto *Sym : G.defined_symbols())
239+
240+
SymbolFlagsMap NewSymbolsToClaim;
241+
std::vector<std::pair<SymbolStringPtr, Symbol *>> NameToSym;
242+
243+
auto ProcessSymbol = [&](Symbol *Sym) {
239244
if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
240-
if (!MR->getSymbols().count(ES.intern(Sym->getName())))
241-
G.makeExternal(*Sym);
245+
auto Name = ES.intern(Sym->getName());
246+
if (!MR->getSymbols().count(ES.intern(Sym->getName()))) {
247+
JITSymbolFlags SF = JITSymbolFlags::Weak;
248+
if (Sym->getScope() == Scope::Default)
249+
SF |= JITSymbolFlags::Exported;
250+
NewSymbolsToClaim[Name] = SF;
251+
NameToSym.push_back(std::make_pair(std::move(Name), Sym));
252+
}
242253
}
254+
};
243255

256+
for (auto *Sym : G.defined_symbols())
257+
ProcessSymbol(Sym);
244258
for (auto *Sym : G.absolute_symbols())
245-
if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
246-
if (!MR->getSymbols().count(ES.intern(Sym->getName())))
247-
G.makeExternal(*Sym);
248-
}
259+
ProcessSymbol(Sym);
260+
261+
// Attempt to claim all weak defs that we're not already responsible for.
262+
// This cannot fail -- any clashes will just result in rejection of our
263+
// claim, at which point we'll externalize that symbol.
264+
cantFail(MR->defineMaterializing(std::move(NewSymbolsToClaim)));
265+
266+
for (auto &KV : NameToSym)
267+
if (!MR->getSymbols().count(KV.first))
268+
G.makeExternal(*KV.second);
249269

250270
return Error::success();
251271
}

0 commit comments

Comments
 (0)