@@ -120,7 +120,7 @@ static Value *runtime_sym_lookup(
120
120
IRBuilder<> &irbuilder,
121
121
jl_codectx_t *ctx,
122
122
PointerType *funcptype, const char *f_lib, jl_value_t *lib_expr,
123
- const char *f_name, Function *f,
123
+ const char *f_name, const char *f_version, Function *f,
124
124
GlobalVariable *libptrgv,
125
125
GlobalVariable *llvmgv, bool runtime_lib)
126
126
{
@@ -129,7 +129,7 @@ static Value *runtime_sym_lookup(
129
129
// global HMODULE *libptrgv
130
130
// global void **llvmgv
131
131
// if (*llvmgv == NULL) {
132
- // *llvmgv = jl_load_and_lookup(f_lib, f_name, libptrgv);
132
+ // *llvmgv = jl_load_and_lookup(f_lib, f_name, f_version, libptrgv);
133
133
// }
134
134
// return (*llvmgv)
135
135
auto T_pvoidfunc = JuliaType::get_pvoidfunc_ty (irbuilder.getContext ());
@@ -158,8 +158,9 @@ static Value *runtime_sym_lookup(
158
158
Value *nameval = stringConstPtr (emission_context, irbuilder, f_name);
159
159
if (lib_expr) {
160
160
jl_cgval_t libval = emit_expr (*ctx, lib_expr);
161
- llvmf = irbuilder.CreateCall (prepare_call_in (jl_builderModule (irbuilder), jllazydlsym_func),
162
- { boxed (*ctx, libval), nameval });
161
+ Value *versionval = nullableStringConstPtr (emission_context, irbuilder, f_version);
162
+ llvmf = irbuilder.CreateCall (prepare_call_in (jl_builderModule (irbuilder), jllazydlvsym_func),
163
+ { boxed (*ctx, libval), nameval, versionval });
163
164
}
164
165
else {
165
166
Value *libname;
@@ -170,8 +171,9 @@ static Value *runtime_sym_lookup(
170
171
// f_lib is actually one of the special sentinel values
171
172
libname = ConstantExpr::getIntToPtr (ConstantInt::get (getSizeTy (irbuilder.getContext ()), (uintptr_t )f_lib), getInt8PtrTy (irbuilder.getContext ()));
172
173
}
173
- llvmf = irbuilder.CreateCall (prepare_call_in (jl_builderModule (irbuilder), jldlsym_func),
174
- { libname, nameval, libptrgv });
174
+ Value *versionval = nullableStringConstPtr (emission_context, irbuilder, f_version);
175
+ llvmf = irbuilder.CreateCall (prepare_call_in (jl_builderModule (irbuilder), jldlvsym_func),
176
+ { libname, nameval, versionval, libptrgv });
175
177
}
176
178
StoreInst *store = irbuilder.CreateAlignedStore (llvmf, llvmgv, Align (sizeof (void *)));
177
179
store->setAtomic (AtomicOrdering::Release);
@@ -188,18 +190,18 @@ static Value *runtime_sym_lookup(
188
190
static Value *runtime_sym_lookup (
189
191
jl_codectx_t &ctx,
190
192
PointerType *funcptype, const char *f_lib, jl_value_t *lib_expr,
191
- const char *f_name, Function *f,
193
+ const char *f_name, const char *f_version, Function *f,
192
194
GlobalVariable *libptrgv,
193
195
GlobalVariable *llvmgv, bool runtime_lib)
194
196
{
195
197
return runtime_sym_lookup (ctx.emission_context , ctx.builder , &ctx, funcptype, f_lib, lib_expr,
196
- f_name, f, libptrgv, llvmgv, runtime_lib);
198
+ f_name, f_version, f, libptrgv, llvmgv, runtime_lib);
197
199
}
198
200
199
201
static Value *runtime_sym_lookup (
200
202
jl_codectx_t &ctx,
201
203
PointerType *funcptype, const char *f_lib, jl_value_t *lib_expr,
202
- const char *f_name, Function *f)
204
+ const char *f_name, const char *f_version, Function *f)
203
205
{
204
206
auto T_pvoidfunc = JuliaType::get_pvoidfunc_ty (ctx.builder .getContext ());
205
207
GlobalVariable *libptrgv;
@@ -223,15 +225,16 @@ static Value *runtime_sym_lookup(
223
225
libptrgv = prepare_global_in (jl_Module, libptrgv);
224
226
}
225
227
llvmgv = prepare_global_in (jl_Module, llvmgv);
226
- return runtime_sym_lookup (ctx, funcptype, f_lib, lib_expr, f_name, f, libptrgv, llvmgv, runtime_lib);
228
+ return runtime_sym_lookup (ctx, funcptype, f_lib, lib_expr, f_name, f_version, f, libptrgv, llvmgv, runtime_lib);
227
229
}
228
230
229
231
// Emit a "PLT" entry that will be lazily initialized
230
232
// when being called the first time.
231
233
static GlobalVariable *emit_plt_thunk (
232
234
jl_codectx_t &ctx,
233
235
FunctionType *functype, const AttributeList &attrs,
234
- CallingConv::ID cc, const char *f_lib, const char *f_name,
236
+ CallingConv::ID cc,
237
+ const char *f_lib, const char *f_name, const char *f_version,
235
238
GlobalVariable *libptrgv, GlobalVariable *llvmgv,
236
239
bool runtime_lib)
237
240
{
@@ -256,8 +259,8 @@ static GlobalVariable *emit_plt_thunk(
256
259
fname);
257
260
BasicBlock *b0 = BasicBlock::Create (M->getContext (), " top" , plt);
258
261
IRBuilder<> irbuilder (b0);
259
- Value *ptr = runtime_sym_lookup (ctx.emission_context , irbuilder, NULL , funcptype, f_lib, NULL , f_name, plt, libptrgv,
260
- llvmgv, runtime_lib);
262
+ Value *ptr = runtime_sym_lookup (ctx.emission_context , irbuilder, NULL , funcptype,
263
+ f_lib, NULL , f_name, f_version, plt, libptrgv, llvmgv, runtime_lib);
261
264
StoreInst *store = irbuilder.CreateAlignedStore (irbuilder.CreateBitCast (ptr, T_pvoidfunc), got, Align (sizeof (void *)));
262
265
store->setAtomic (AtomicOrdering::Release);
263
266
SmallVector<Value*, 16 > args;
@@ -303,7 +306,8 @@ static Value *emit_plt(
303
306
jl_codectx_t &ctx,
304
307
FunctionType *functype,
305
308
const AttributeList &attrs,
306
- CallingConv::ID cc, const char *f_lib, const char *f_name)
309
+ CallingConv::ID cc,
310
+ const char *f_lib, const char *f_name, const char *f_version)
307
311
{
308
312
++PLT;
309
313
assert (ctx.emission_context .imaging );
@@ -320,7 +324,7 @@ static Value *emit_plt(
320
324
GlobalVariable *&sharedgot = pltMap[key];
321
325
if (!sharedgot) {
322
326
sharedgot = emit_plt_thunk (ctx,
323
- functype, attrs, cc, f_lib, f_name, libptrgv, llvmgv, runtime_lib);
327
+ functype, attrs, cc, f_lib, f_name, f_version, libptrgv, llvmgv, runtime_lib);
324
328
}
325
329
GlobalVariable *got = prepare_global_in (jl_Module, sharedgot);
326
330
LoadInst *got_val = ctx.builder .CreateAlignedLoad (got->getValueType (), got, Align (sizeof (void *)));
@@ -565,6 +569,7 @@ typedef struct {
565
569
void (*fptr)(void ); // if the argument is a constant pointer
566
570
const char *f_name; // if the symbol name is known
567
571
const char *f_lib; // if a library name is specified
572
+ const char *f_version;
568
573
jl_value_t *lib_expr; // expression to compute library path lazily
569
574
jl_value_t *gcroot;
570
575
} native_sym_arg_t ;
@@ -576,6 +581,8 @@ static void interpret_symbol_arg(jl_codectx_t &ctx, native_sym_arg_t &out, jl_va
576
581
void (*&fptr)(void ) = out.fptr ;
577
582
const char *&f_name = out.f_name ;
578
583
const char *&f_lib = out.f_lib ;
584
+ const char *&f_version = out.f_version ;
585
+ f_version = NULL ;
579
586
580
587
jl_value_t *ptr = static_eval (ctx, arg);
581
588
if (ptr == NULL ) {
@@ -709,20 +716,24 @@ static jl_cgval_t emit_cglobal(jl_codectx_t &ctx, jl_value_t **args, size_t narg
709
716
}
710
717
else {
711
718
if (sym.lib_expr ) {
712
- res = runtime_sym_lookup (ctx, cast<PointerType>(getInt8PtrTy (ctx.builder .getContext ())), NULL , sym.lib_expr , sym.f_name , ctx.f );
719
+ res = runtime_sym_lookup (ctx, cast<PointerType>(getInt8PtrTy (ctx.builder .getContext ())), NULL ,
720
+ sym.lib_expr , sym.f_name , sym.f_version , ctx.f );
713
721
}
714
722
else if (ctx.emission_context .imaging ) {
715
- res = runtime_sym_lookup (ctx, cast<PointerType>(getInt8PtrTy (ctx.builder .getContext ())), sym.f_lib , NULL , sym.f_name , ctx.f );
723
+ res = runtime_sym_lookup (ctx, cast<PointerType>(getInt8PtrTy (ctx.builder .getContext ())),
724
+ sym.f_lib , NULL , sym.f_name , sym.f_version , ctx.f );
716
725
res = ctx.builder .CreatePtrToInt (res, lrt);
717
726
}
718
727
else {
719
728
void *symaddr;
720
729
721
730
void * libsym = jl_get_library_ (sym.f_lib , 0 );
722
- if (!libsym || !jl_dlsym (libsym, sym.f_name , &symaddr, 0 )) {
731
+ int symbol_found = jl_dlvsym (libsym, sym.f_name , sym.f_version , &symaddr, 0 );
732
+ if (!libsym || !symbol_found) {
723
733
// Error mode, either the library or the symbol couldn't be find during compiletime.
724
734
// Fallback to a runtime symbol lookup.
725
- res = runtime_sym_lookup (ctx, cast<PointerType>(getInt8PtrTy (ctx.builder .getContext ())), sym.f_lib , NULL , sym.f_name , ctx.f );
735
+ res = runtime_sym_lookup (ctx, cast<PointerType>(getInt8PtrTy (ctx.builder .getContext ())),
736
+ sym.f_lib , NULL , sym.f_name , sym.f_version , ctx.f );
726
737
res = ctx.builder .CreatePtrToInt (res, lrt);
727
738
} else {
728
739
// since we aren't saving this code, there's no sense in
@@ -2043,25 +2054,26 @@ jl_cgval_t function_sig_t::emit_a_ccall(
2043
2054
PointerType *funcptype = PointerType::get (functype, 0 );
2044
2055
if (symarg.lib_expr ) {
2045
2056
++DeferredCCallLookups;
2046
- llvmf = runtime_sym_lookup (ctx, funcptype, NULL , symarg.lib_expr , symarg.f_name , ctx.f );
2057
+ llvmf = runtime_sym_lookup (ctx, funcptype, NULL , symarg.lib_expr , symarg.f_name , symarg. f_version , ctx.f );
2047
2058
}
2048
2059
else if (ctx.emission_context .imaging ) {
2049
2060
++DeferredCCallLookups;
2050
2061
// vararg requires musttail,
2051
2062
// but musttail is incompatible with noreturn.
2052
2063
if (functype->isVarArg ())
2053
- llvmf = runtime_sym_lookup (ctx, funcptype, symarg.f_lib , NULL , symarg.f_name , ctx.f );
2064
+ llvmf = runtime_sym_lookup (ctx, funcptype, symarg.f_lib , NULL , symarg.f_name , symarg. f_version , ctx.f );
2054
2065
else
2055
- llvmf = emit_plt (ctx, functype, attributes, cc, symarg.f_lib , symarg.f_name );
2066
+ llvmf = emit_plt (ctx, functype, attributes, cc, symarg.f_lib , symarg.f_name , symarg. f_version );
2056
2067
}
2057
2068
else {
2058
2069
void *symaddr;
2059
2070
void *libsym = jl_get_library_ (symarg.f_lib , 0 );
2060
- if (!libsym || !jl_dlsym (libsym, symarg.f_name , &symaddr, 0 )) {
2071
+ int symbol_found = jl_dlvsym (libsym, symarg.f_name , symarg.f_version , &symaddr, 0 );
2072
+ if (!libsym || !symbol_found) {
2061
2073
++DeferredCCallLookups;
2062
2074
// either the library or the symbol could not be found, place a runtime
2063
2075
// lookup here instead.
2064
- llvmf = runtime_sym_lookup (ctx, funcptype, symarg.f_lib , NULL , symarg.f_name , ctx.f );
2076
+ llvmf = runtime_sym_lookup (ctx, funcptype, symarg.f_lib , NULL , symarg.f_name , symarg. f_version , ctx.f );
2065
2077
} else {
2066
2078
++LiteralCCalls;
2067
2079
// since we aren't saving this code, there's no sense in
0 commit comments