4
4
5
5
// Map from symbol name (in a certain library) to its GV in sysimg and the
6
6
// DL handle address in the current session.
7
- typedef StringMap<std::pair< GlobalVariable*, void *> > SymMapGV;
7
+ typedef StringMap<GlobalVariable*> SymMapGV;
8
8
static StringMap<std::pair<GlobalVariable*,SymMapGV>> libMapGV;
9
9
#ifdef _OS_WINDOWS_
10
10
static SymMapGV symMapExe;
@@ -43,85 +43,58 @@ lazyModule(Func &&func)
43
43
44
44
// Find or create the GVs for the library and symbol lookup.
45
45
// Return `runtime_lib` (whether the library name is a string)
46
- // Optionally return the symbol address in the current session
47
- // when `symaddr != nullptr`.
48
46
// The `lib` and `sym` GV returned may not be in the current module.
49
47
template <typename MT>
50
48
static bool runtime_sym_gvs (const char *f_lib, const char *f_name, MT &&M,
51
- GlobalVariable *&lib, GlobalVariable *&sym,
52
- void **symaddr=nullptr )
49
+ GlobalVariable *&lib, GlobalVariable *&sym)
53
50
{
54
- void *libsym = NULL ;
55
51
bool runtime_lib = false ;
56
52
GlobalVariable *libptrgv;
57
53
SymMapGV *symMap;
58
54
#ifdef _OS_WINDOWS_
59
55
if ((intptr_t )f_lib == 1 ) {
60
56
libptrgv = jlexe_var;
61
- libsym = jl_exe_handle;
62
57
symMap = &symMapExe;
63
58
}
64
59
else if ((intptr_t )f_lib == 2 ) {
65
60
libptrgv = jldll_var;
66
- libsym = jl_dl_handle;
67
61
symMap = &symMapDl;
68
62
}
69
63
else
70
64
#endif
71
65
if (f_lib == NULL ) {
72
66
libptrgv = jlRTLD_DEFAULT_var;
73
- libsym = jl_RTLD_DEFAULT_handle;
74
67
symMap = &symMapDefault;
75
68
}
76
69
else {
77
70
std::string name = " ccalllib_" ;
78
71
name += f_lib;
79
72
runtime_lib = true ;
80
- auto iter = libMapGV. find ( f_lib) ;
81
- if (iter == libMapGV. end () ) {
73
+ auto &libgv = libMapGV[ f_lib] ;
74
+ if (libgv. first == NULL ) {
82
75
libptrgv = new GlobalVariable (*M, T_pint8, false ,
83
76
GlobalVariable::ExternalLinkage,
84
- NULL , name);
85
- auto &libgv = libMapGV[f_lib];
86
- libgv = std::make_pair (global_proto (libptrgv), SymMapGV ());
87
- symMap = &libgv.second ;
88
- libsym = jl_get_library (f_lib);
89
- assert (libsym != NULL );
90
- *jl_emit_and_add_to_shadow (libptrgv) = libsym;
77
+ Constant::getNullValue (T_pint8), name);
78
+ libgv.first = global_proto (libptrgv);
91
79
}
92
80
else {
93
- libptrgv = iter->second .first ;
94
- symMap = &iter->second .second ;
81
+ libptrgv = libgv.first ;
95
82
}
83
+ symMap = &libgv.second ;
96
84
}
97
- if (libsym == NULL ) {
98
- libsym = *(void **)jl_get_globalvar (libptrgv);
99
- }
100
- assert (libsym != NULL );
101
85
102
- GlobalVariable *llvmgv;
103
- auto sym_iter = symMap->find (f_name);
104
- if (sym_iter == symMap->end ()) {
86
+ GlobalVariable *&llvmgv = (*symMap)[f_name];
87
+ if (llvmgv == NULL ) {
105
88
// MCJIT forces this to have external linkage eventually, so we would clobber
106
89
// the symbol of the actual function.
107
90
std::string name = " ccall_" ;
108
91
name += f_name;
109
92
name += " _" ;
110
93
name += std::to_string (globalUnique++);
111
94
llvmgv = new GlobalVariable (*M, T_pvoidfunc, false ,
112
- GlobalVariable::ExternalLinkage, NULL , name);
95
+ GlobalVariable::ExternalLinkage,
96
+ Constant::getNullValue (T_pvoidfunc), name);
113
97
llvmgv = global_proto (llvmgv);
114
- void *addr;
115
- jl_dlsym (libsym, f_name, &addr, 0 );
116
- (*symMap)[f_name] = std::make_pair (llvmgv, addr);
117
- if (symaddr)
118
- *symaddr = addr;
119
- *jl_emit_and_add_to_shadow (llvmgv) = addr;
120
- }
121
- else {
122
- if (symaddr)
123
- *symaddr = sym_iter->second .second ;
124
- llvmgv = sym_iter->second .first ;
125
98
}
126
99
127
100
lib = libptrgv;
@@ -218,7 +191,7 @@ static GlobalVariable *emit_plt_thunk(
218
191
const AttributeList &attrs,
219
192
CallingConv::ID cc, const char *f_lib, const char *f_name,
220
193
GlobalVariable *libptrgv, GlobalVariable *llvmgv,
221
- void *symaddr, bool runtime_lib)
194
+ bool runtime_lib)
222
195
{
223
196
PointerType *funcptype = PointerType::get (functype, 0 );
224
197
libptrgv = prepare_global_in (M, libptrgv);
@@ -237,8 +210,7 @@ static GlobalVariable *emit_plt_thunk(
237
210
auto gname = funcName.str ();
238
211
GlobalVariable *got = new GlobalVariable (*M, T_pvoidfunc, false ,
239
212
GlobalVariable::ExternalLinkage,
240
- nullptr , gname);
241
- *jl_emit_and_add_to_shadow (got) = symaddr;
213
+ ConstantExpr::getBitCast (plt, T_pvoidfunc), gname);
242
214
BasicBlock *b0 = BasicBlock::Create (jl_LLVMContext, " top" , plt);
243
215
IRBuilder<> irbuilder (b0);
244
216
Value *ptr = runtime_sym_lookup (irbuilder, funcptype, f_lib, f_name, plt, libptrgv,
@@ -274,6 +246,7 @@ static GlobalVariable *emit_plt_thunk(
274
246
}
275
247
}
276
248
irbuilder.ClearInsertionPoint ();
249
+
277
250
got = global_proto (got); // exchange got for the permanent global before jl_finalize_module destroys it
278
251
jl_finalize_module (M, true );
279
252
@@ -297,21 +270,19 @@ static Value *emit_plt(
297
270
assert (!functype->isVarArg ());
298
271
GlobalVariable *libptrgv;
299
272
GlobalVariable *llvmgv;
300
- void *symaddr;
301
273
auto LM = lazyModule ([&] {
302
274
Module *m = new Module (f_name, jl_LLVMContext);
303
275
jl_setup_module (m);
304
276
return m;
305
277
});
306
- bool runtime_lib = runtime_sym_gvs (f_lib, f_name, LM,
307
- libptrgv, llvmgv, &symaddr);
278
+ bool runtime_lib = runtime_sym_gvs (f_lib, f_name, LM, libptrgv, llvmgv);
308
279
PointerType *funcptype = PointerType::get (functype, 0 );
309
280
310
281
auto &pltMap = allPltMap[attrs];
311
282
auto key = std::make_tuple (llvmgv, functype, cc);
312
283
GlobalVariable *&shadowgot = pltMap[key];
313
284
if (!shadowgot) {
314
- shadowgot = emit_plt_thunk (LM.get (), functype, attrs, cc, f_lib, f_name, libptrgv, llvmgv, symaddr, runtime_lib);
285
+ shadowgot = emit_plt_thunk (LM.get (), functype, attrs, cc, f_lib, f_name, libptrgv, llvmgv, runtime_lib);
315
286
}
316
287
else {
317
288
// `runtime_sym_gvs` shouldn't have created anything in a new module
0 commit comments