@@ -120,7 +120,7 @@ static Value *runtime_sym_lookup(
120120 IRBuilder<> &irbuilder,
121121 jl_codectx_t *ctx,
122122 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,
124124 GlobalVariable *libptrgv,
125125 GlobalVariable *llvmgv, bool runtime_lib)
126126{
@@ -158,8 +158,14 @@ static Value *runtime_sym_lookup(
158158 Value *nameval = stringConstPtr (emission_context, irbuilder, f_name);
159159 if (lib_expr) {
160160 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+ if (f_version != NULL ) {
162+ Value *versionval = stringConstPtr (emission_context, irbuilder, f_version);
163+ llvmf = irbuilder.CreateCall (prepare_call_in (jl_builderModule (irbuilder), jllazydlvsym_func),
164+ { boxed (*ctx, libval), nameval, versionval });
165+ } else {
166+ llvmf = irbuilder.CreateCall (prepare_call_in (jl_builderModule (irbuilder), jllazydlsym_func),
167+ { boxed (*ctx, libval), nameval });
168+ }
163169 }
164170 else {
165171 Value *libname;
@@ -170,8 +176,14 @@ static Value *runtime_sym_lookup(
170176 // f_lib is actually one of the special sentinel values
171177 libname = ConstantExpr::getIntToPtr (ConstantInt::get (getSizeTy (irbuilder.getContext ()), (uintptr_t )f_lib), getInt8PtrTy (irbuilder.getContext ()));
172178 }
173- llvmf = irbuilder.CreateCall (prepare_call_in (jl_builderModule (irbuilder), jldlsym_func),
174- { libname, nameval, libptrgv });
179+ if (f_version != NULL ) {
180+ Value *versionval = stringConstPtr (emission_context, irbuilder, f_version);
181+ llvmf = irbuilder.CreateCall (prepare_call_in (jl_builderModule (irbuilder), jldlvsym_func),
182+ { libname, nameval, versionval, libptrgv });
183+ } else {
184+ llvmf = irbuilder.CreateCall (prepare_call_in (jl_builderModule (irbuilder), jldlsym_func),
185+ { libname, nameval, libptrgv });
186+ }
175187 }
176188 StoreInst *store = irbuilder.CreateAlignedStore (llvmf, llvmgv, Align (sizeof (void *)));
177189 store->setAtomic (AtomicOrdering::Release);
@@ -188,18 +200,18 @@ static Value *runtime_sym_lookup(
188200static Value *runtime_sym_lookup (
189201 jl_codectx_t &ctx,
190202 PointerType *funcptype, const char *f_lib, jl_value_t *lib_expr,
191- const char *f_name, Function *f,
203+ const char *f_name, const char *f_version, Function *f,
192204 GlobalVariable *libptrgv,
193205 GlobalVariable *llvmgv, bool runtime_lib)
194206{
195207 return runtime_sym_lookup (ctx.emission_context , ctx.builder , &ctx, funcptype, f_lib, lib_expr,
196- f_name, f, libptrgv, llvmgv, runtime_lib);
208+ f_name, f_version, f, libptrgv, llvmgv, runtime_lib);
197209}
198210
199211static Value *runtime_sym_lookup (
200212 jl_codectx_t &ctx,
201213 PointerType *funcptype, const char *f_lib, jl_value_t *lib_expr,
202- const char *f_name, Function *f)
214+ const char *f_name, const char *f_version, Function *f)
203215{
204216 auto T_pvoidfunc = JuliaType::get_pvoidfunc_ty (ctx.builder .getContext ());
205217 GlobalVariable *libptrgv;
@@ -223,15 +235,16 @@ static Value *runtime_sym_lookup(
223235 libptrgv = prepare_global_in (jl_Module, libptrgv);
224236 }
225237 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);
238+ return runtime_sym_lookup (ctx, funcptype, f_lib, lib_expr, f_name, f_version, f, libptrgv, llvmgv, runtime_lib);
227239}
228240
229241// Emit a "PLT" entry that will be lazily initialized
230242// when being called the first time.
231243static GlobalVariable *emit_plt_thunk (
232244 jl_codectx_t &ctx,
233245 FunctionType *functype, const AttributeList &attrs,
234- CallingConv::ID cc, const char *f_lib, const char *f_name,
246+ CallingConv::ID cc,
247+ const char *f_lib, const char *f_name, const char *f_version,
235248 GlobalVariable *libptrgv, GlobalVariable *llvmgv,
236249 bool runtime_lib)
237250{
@@ -256,8 +269,8 @@ static GlobalVariable *emit_plt_thunk(
256269 fname);
257270 BasicBlock *b0 = BasicBlock::Create (M->getContext (), " top" , plt);
258271 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);
272+ Value *ptr = runtime_sym_lookup (ctx.emission_context , irbuilder, NULL , funcptype,
273+ f_lib, NULL , f_name, f_version, plt, libptrgv, llvmgv, runtime_lib);
261274 StoreInst *store = irbuilder.CreateAlignedStore (irbuilder.CreateBitCast (ptr, T_pvoidfunc), got, Align (sizeof (void *)));
262275 store->setAtomic (AtomicOrdering::Release);
263276 SmallVector<Value*, 16 > args;
@@ -303,7 +316,8 @@ static Value *emit_plt(
303316 jl_codectx_t &ctx,
304317 FunctionType *functype,
305318 const AttributeList &attrs,
306- CallingConv::ID cc, const char *f_lib, const char *f_name)
319+ CallingConv::ID cc,
320+ const char *f_lib, const char *f_name, const char *f_version)
307321{
308322 ++PLT;
309323 assert (ctx.emission_context .imaging );
@@ -320,7 +334,7 @@ static Value *emit_plt(
320334 GlobalVariable *&sharedgot = pltMap[key];
321335 if (!sharedgot) {
322336 sharedgot = emit_plt_thunk (ctx,
323- functype, attrs, cc, f_lib, f_name, libptrgv, llvmgv, runtime_lib);
337+ functype, attrs, cc, f_lib, f_name, f_version, libptrgv, llvmgv, runtime_lib);
324338 }
325339 GlobalVariable *got = prepare_global_in (jl_Module, sharedgot);
326340 LoadInst *got_val = ctx.builder .CreateAlignedLoad (got->getValueType (), got, Align (sizeof (void *)));
@@ -565,6 +579,7 @@ typedef struct {
565579 void (*fptr)(void ); // if the argument is a constant pointer
566580 const char *f_name; // if the symbol name is known
567581 const char *f_lib; // if a library name is specified
582+ const char *f_version;
568583 jl_value_t *lib_expr; // expression to compute library path lazily
569584 jl_value_t *gcroot;
570585} native_sym_arg_t ;
@@ -576,6 +591,8 @@ static void interpret_symbol_arg(jl_codectx_t &ctx, native_sym_arg_t &out, jl_va
576591 void (*&fptr)(void ) = out.fptr ;
577592 const char *&f_name = out.f_name ;
578593 const char *&f_lib = out.f_lib ;
594+ const char *&f_version = out.f_version ;
595+ f_version = NULL ;
579596
580597 jl_value_t *ptr = static_eval (ctx, arg);
581598 if (ptr == NULL ) {
@@ -709,20 +726,29 @@ static jl_cgval_t emit_cglobal(jl_codectx_t &ctx, jl_value_t **args, size_t narg
709726 }
710727 else {
711728 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 );
729+ res = runtime_sym_lookup (ctx, cast<PointerType>(getInt8PtrTy (ctx.builder .getContext ())), NULL ,
730+ sym.lib_expr , sym.f_name , sym.f_version , ctx.f );
713731 }
714732 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 );
733+ res = runtime_sym_lookup (ctx, cast<PointerType>(getInt8PtrTy (ctx.builder .getContext ())),
734+ sym.f_lib , NULL , sym.f_name , sym.f_version , ctx.f );
716735 res = ctx.builder .CreatePtrToInt (res, lrt);
717736 }
718737 else {
719738 void *symaddr;
720739
721740 void * libsym = jl_get_library_ (sym.f_lib , 0 );
722- if (!libsym || !jl_dlsym (libsym, sym.f_name , &symaddr, 0 )) {
741+ int symbol_found = 0 ;
742+ if (sym.f_version != NULL ) {
743+ symbol_found = jl_dlvsym (libsym, sym.f_name , sym.f_version , &symaddr, 0 );
744+ } else {
745+ symbol_found = jl_dlsym (libsym, sym.f_name , &symaddr, 0 );
746+ }
747+ if (!libsym || !symbol_found) {
723748 // Error mode, either the library or the symbol couldn't be find during compiletime.
724749 // 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 );
750+ res = runtime_sym_lookup (ctx, cast<PointerType>(getInt8PtrTy (ctx.builder .getContext ())),
751+ sym.f_lib , NULL , sym.f_name , sym.f_version , ctx.f );
726752 res = ctx.builder .CreatePtrToInt (res, lrt);
727753 } else {
728754 // since we aren't saving this code, there's no sense in
@@ -2043,25 +2069,31 @@ jl_cgval_t function_sig_t::emit_a_ccall(
20432069 PointerType *funcptype = PointerType::get (functype, 0 );
20442070 if (symarg.lib_expr ) {
20452071 ++DeferredCCallLookups;
2046- llvmf = runtime_sym_lookup (ctx, funcptype, NULL , symarg.lib_expr , symarg.f_name , ctx.f );
2072+ llvmf = runtime_sym_lookup (ctx, funcptype, NULL , symarg.lib_expr , symarg.f_name , symarg. f_version , ctx.f );
20472073 }
20482074 else if (ctx.emission_context .imaging ) {
20492075 ++DeferredCCallLookups;
20502076 // vararg requires musttail,
20512077 // but musttail is incompatible with noreturn.
20522078 if (functype->isVarArg ())
2053- llvmf = runtime_sym_lookup (ctx, funcptype, symarg.f_lib , NULL , symarg.f_name , ctx.f );
2079+ llvmf = runtime_sym_lookup (ctx, funcptype, symarg.f_lib , NULL , symarg.f_name , symarg. f_version , ctx.f );
20542080 else
2055- llvmf = emit_plt (ctx, functype, attributes, cc, symarg.f_lib , symarg.f_name );
2081+ llvmf = emit_plt (ctx, functype, attributes, cc, symarg.f_lib , symarg.f_name , symarg. f_version );
20562082 }
20572083 else {
20582084 void *symaddr;
20592085 void *libsym = jl_get_library_ (symarg.f_lib , 0 );
2060- if (!libsym || !jl_dlsym (libsym, symarg.f_name , &symaddr, 0 )) {
2086+ int symbol_found = 0 ;
2087+ if (symarg.f_version != NULL ) {
2088+ symbol_found = jl_dlvsym (libsym, symarg.f_name , symarg.f_version , &symaddr, 0 );
2089+ } else {
2090+ symbol_found = jl_dlsym (libsym, symarg.f_name , &symaddr, 0 );
2091+ }
2092+ if (!libsym || !symbol_found) {
20612093 ++DeferredCCallLookups;
20622094 // either the library or the symbol could not be found, place a runtime
20632095 // lookup here instead.
2064- llvmf = runtime_sym_lookup (ctx, funcptype, symarg.f_lib , NULL , symarg.f_name , ctx.f );
2096+ llvmf = runtime_sym_lookup (ctx, funcptype, symarg.f_lib , NULL , symarg.f_name , symarg. f_version , ctx.f );
20652097 } else {
20662098 ++LiteralCCalls;
20672099 // since we aren't saving this code, there's no sense in
0 commit comments