From: Lang Hames Date: Mon, 8 Aug 2016 22:53:37 +0000 (+0000) Subject: [RuntimeDyld][Orc][MCJIT] Add partial weak-symbol support to RuntimeDyld. X-Git-Tag: llvmorg-4.0.0-rc1~13016 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=33c0b6bfcaf7579ec552bf4688da33b41f12847a;p=platform%2Fupstream%2Fllvm.git [RuntimeDyld][Orc][MCJIT] Add partial weak-symbol support to RuntimeDyld. This patch causes RuntimeDyld to check for existing definitions when it encounters weak symbols. If a definition already exists then the new weak definition is discarded. All symbol lookups within a "logical dylib" should now agree on the address of any given weak symbol. This allows the JIT to better match the behavior of the static linker for C++ code. This support is only partial, as it does not allow strong definitions that occur after the first weak definition (in JIT symbol lookup order) to override the previous weak definitions. Support for this will be added in a future patch. llvm-svn: 278065 --- diff --git a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h index 805852b..db9c519 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @@ -116,11 +116,13 @@ class OrcMCJITReplacement : public ExecutionEngine { LinkingResolver(OrcMCJITReplacement &M) : M(M) {} JITSymbol findSymbol(const std::string &Name) override { - return M.findMangledSymbol(Name); + return M.ClientResolver->findSymbol(Name); } JITSymbol findSymbolInLogicalDylib(const std::string &Name) override { - return M.ClientResolver->findSymbol(Name); + if (auto Sym = M.findMangledSymbol(Name)) + return Sym; + return M.ClientResolver->findSymbolInLogicalDylib(Name); } private: diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 1770525..0c69b1a 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -226,6 +226,24 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { // Compute JIT symbol flags. JITSymbolFlags JITSymFlags = JITSymbolFlags::fromObjectSymbol(*I); + // If this is a weak definition, check to see if there's a strong one. + // If there is, skip this symbol (we won't be providing it: the strong + // definition will). If there's no strong definition, make this definition + // strong. + if (JITSymFlags.isWeak()) { + // First check whether there's already a definition in this instance. + // FIXME: Override existing weak definitions with strong ones. + if (GlobalSymbolTable.count(Name)) + continue; + // Then check the symbol resolver to see if there's a definition + // elsewhere in this logical dylib. + if (auto Sym = Resolver.findSymbolInLogicalDylib(Name)) + if (Sym.getFlags().isStrongDefinition()) + continue; + // else + JITSymFlags &= ~JITSymbolFlags::Weak; + } + if (Flags & SymbolRef::SF_Absolute && SymType != object::SymbolRef::ST_File) { uint64_t Addr = 0; diff --git a/llvm/test/ExecutionEngine/MCJIT/Inputs/weak-function-2.ll b/llvm/test/ExecutionEngine/MCJIT/Inputs/weak-function-2.ll new file mode 100644 index 0000000..a7ff83d --- /dev/null +++ b/llvm/test/ExecutionEngine/MCJIT/Inputs/weak-function-2.ll @@ -0,0 +1,9 @@ +define linkonce_odr i32 @baz() #0 { +entry: + ret i32 0 +} + +define i8* @bar() { +entry: + ret i8* bitcast (i32 ()* @baz to i8*) +} diff --git a/llvm/test/ExecutionEngine/MCJIT/weak-function.ll b/llvm/test/ExecutionEngine/MCJIT/weak-function.ll new file mode 100644 index 0000000..562d6ad --- /dev/null +++ b/llvm/test/ExecutionEngine/MCJIT/weak-function.ll @@ -0,0 +1,26 @@ +; RUN: lli -jit-kind=mcjit -extra-module %p/Inputs/weak-function-2.ll %s +; +; Check that functions in two different modules agree on the address of weak +; function 'baz' + +define linkonce_odr i32 @baz() { +entry: + ret i32 0 +} + +define i8* @foo() { +entry: + ret i8* bitcast (i32 ()* @baz to i8*) +} + +declare i8* @bar() + +define i32 @main(i32 %argc, i8** %argv) { +entry: + %call = tail call i8* @foo() + %call1 = tail call i8* @bar() + %cmp = icmp ne i8* %call, %call1 + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/Inputs/weak-function-2.ll b/llvm/test/ExecutionEngine/OrcMCJIT/Inputs/weak-function-2.ll new file mode 100644 index 0000000..a7ff83d --- /dev/null +++ b/llvm/test/ExecutionEngine/OrcMCJIT/Inputs/weak-function-2.ll @@ -0,0 +1,9 @@ +define linkonce_odr i32 @baz() #0 { +entry: + ret i32 0 +} + +define i8* @bar() { +entry: + ret i8* bitcast (i32 ()* @baz to i8*) +} diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/weak-function.ll b/llvm/test/ExecutionEngine/OrcMCJIT/weak-function.ll new file mode 100644 index 0000000..db255cd --- /dev/null +++ b/llvm/test/ExecutionEngine/OrcMCJIT/weak-function.ll @@ -0,0 +1,26 @@ +; RUN: lli -jit-kind=orc-mcjit -extra-module %p/Inputs/weak-function-2.ll %s +; +; Check that functions in two different modules agree on the address of weak +; function 'baz' + +define linkonce_odr i32 @baz() { +entry: + ret i32 0 +} + +define i8* @foo() { +entry: + ret i8* bitcast (i32 ()* @baz to i8*) +} + +declare i8* @bar() + +define i32 @main(i32 %argc, i8** %argv) { +entry: + %call = tail call i8* @foo() + %call1 = tail call i8* @bar() + %cmp = icmp ne i8* %call, %call1 + %conv = zext i1 %cmp to i32 + ret i32 %conv +} +