llvm.org GIT mirror llvm / fbda701
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278065 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 3 years ago
6 changed file(s) with 92 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
115115 LinkingResolver(OrcMCJITReplacement &M) : M(M) {}
116116
117117 JITSymbol findSymbol(const std::string &Name) override {
118 return M.findMangledSymbol(Name);
118 return M.ClientResolver->findSymbol(Name);
119119 }
120120
121121 JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
122 return M.ClientResolver->findSymbol(Name);
122 if (auto Sym = M.findMangledSymbol(Name))
123 return Sym;
124 return M.ClientResolver->findSymbolInLogicalDylib(Name);
123125 }
124126
125127 private:
224224
225225 // Compute JIT symbol flags.
226226 JITSymbolFlags JITSymFlags = JITSymbolFlags::fromObjectSymbol(*I);
227
228 // If this is a weak definition, check to see if there's a strong one.
229 // If there is, skip this symbol (we won't be providing it: the strong
230 // definition will). If there's no strong definition, make this definition
231 // strong.
232 if (JITSymFlags.isWeak()) {
233 // First check whether there's already a definition in this instance.
234 // FIXME: Override existing weak definitions with strong ones.
235 if (GlobalSymbolTable.count(Name))
236 continue;
237 // Then check the symbol resolver to see if there's a definition
238 // elsewhere in this logical dylib.
239 if (auto Sym = Resolver.findSymbolInLogicalDylib(Name))
240 if (Sym.getFlags().isStrongDefinition())
241 continue;
242 // else
243 JITSymFlags &= ~JITSymbolFlags::Weak;
244 }
227245
228246 if (Flags & SymbolRef::SF_Absolute &&
229247 SymType != object::SymbolRef::ST_File) {
0 define linkonce_odr i32 @baz() #0 {
1 entry:
2 ret i32 0
3 }
4
5 define i8* @bar() {
6 entry:
7 ret i8* bitcast (i32 ()* @baz to i8*)
8 }
0 ; RUN: lli -jit-kind=mcjit -extra-module %p/Inputs/weak-function-2.ll %s
1 ;
2 ; Check that functions in two different modules agree on the address of weak
3 ; function 'baz'
4
5 define linkonce_odr i32 @baz() {
6 entry:
7 ret i32 0
8 }
9
10 define i8* @foo() {
11 entry:
12 ret i8* bitcast (i32 ()* @baz to i8*)
13 }
14
15 declare i8* @bar()
16
17 define i32 @main(i32 %argc, i8** %argv) {
18 entry:
19 %call = tail call i8* @foo()
20 %call1 = tail call i8* @bar()
21 %cmp = icmp ne i8* %call, %call1
22 %conv = zext i1 %cmp to i32
23 ret i32 %conv
24 }
25
0 define linkonce_odr i32 @baz() #0 {
1 entry:
2 ret i32 0
3 }
4
5 define i8* @bar() {
6 entry:
7 ret i8* bitcast (i32 ()* @baz to i8*)
8 }
0 ; RUN: lli -jit-kind=orc-mcjit -extra-module %p/Inputs/weak-function-2.ll %s
1 ;
2 ; Check that functions in two different modules agree on the address of weak
3 ; function 'baz'
4
5 define linkonce_odr i32 @baz() {
6 entry:
7 ret i32 0
8 }
9
10 define i8* @foo() {
11 entry:
12 ret i8* bitcast (i32 ()* @baz to i8*)
13 }
14
15 declare i8* @bar()
16
17 define i32 @main(i32 %argc, i8** %argv) {
18 entry:
19 %call = tail call i8* @foo()
20 %call1 = tail call i8* @bar()
21 %cmp = icmp ne i8* %call, %call1
22 %conv = zext i1 %cmp to i32
23 ret i32 %conv
24 }
25