@@ -87,47 +87,52 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
87
87
}
88
88
89
89
/// Get the pointer to the function of the specified name in the shared object file,
90
- /// if it exists. The function must be in the shared object file specified: we do *not*
91
- /// return pointers to functions in dependencies of the library.
90
+ /// if it exists. The function must be in one of the shared object files specified:
91
+ /// we do *not* return pointers to functions in dependencies of libraries.
92
92
fn get_func_ptr_explicitly_from_lib ( & mut self , link_name : Symbol ) -> Option < CodePtr > {
93
93
let this = self . eval_context_mut ( ) ;
94
- // Try getting the function from the shared library.
95
- let ( lib, lib_path) = this. machine . native_lib . as_ref ( ) . unwrap ( ) ;
96
- let func: libloading:: Symbol < ' _ , unsafe extern "C" fn ( ) > =
97
- unsafe { lib. get ( link_name. as_str ( ) . as_bytes ( ) ) . ok ( ) ? } ;
98
- #[ expect( clippy:: as_conversions) ] // fn-ptr to raw-ptr cast needs `as`.
99
- let fn_ptr = * func. deref ( ) as * mut std:: ffi:: c_void ;
94
+ // Try getting the function from one of the shared libraries.
95
+ for ( lib, lib_path) in & this. machine . native_lib {
96
+ let Ok ( func) : Result < libloading:: Symbol < ' _ , unsafe extern "C" fn ( ) > , _ > =
97
+ ( unsafe { lib. get ( link_name. as_str ( ) . as_bytes ( ) ) } )
98
+ else {
99
+ continue ;
100
+ } ;
101
+ #[ expect( clippy:: as_conversions) ] // fn-ptr to raw-ptr cast needs `as`.
102
+ let fn_ptr = * func. deref ( ) as * mut std:: ffi:: c_void ;
100
103
101
- // FIXME: this is a hack!
102
- // The `libloading` crate will automatically load system libraries like `libc`.
103
- // On linux `libloading` is based on `dlsym`: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#202
104
- // and `dlsym`(https://linux.die.net/man/3/dlsym) looks through the dependency tree of the
105
- // library if it can't find the symbol in the library itself.
106
- // So, in order to check if the function was actually found in the specified
107
- // `machine.external_so_lib` we need to check its `dli_fname` and compare it to
108
- // the specified SO file path.
109
- // This code is a reimplementation of the mechanism for getting `dli_fname` in `libloading`,
110
- // from: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#411
111
- // using the `libc` crate where this interface is public.
112
- let mut info = std:: mem:: MaybeUninit :: < libc:: Dl_info > :: zeroed ( ) ;
113
- unsafe {
114
- if libc:: dladdr ( fn_ptr, info. as_mut_ptr ( ) ) != 0 {
115
- let info = info. assume_init ( ) ;
116
- #[ cfg( target_os = "cygwin" ) ]
117
- let fname_ptr = info. dli_fname . as_ptr ( ) ;
118
- #[ cfg( not( target_os = "cygwin" ) ) ]
119
- let fname_ptr = info. dli_fname ;
120
- assert ! ( !fname_ptr. is_null( ) ) ;
121
- if std:: ffi:: CStr :: from_ptr ( fname_ptr) . to_str ( ) . unwrap ( )
122
- != lib_path. to_str ( ) . unwrap ( )
123
- {
124
- return None ;
104
+ // FIXME: this is a hack!
105
+ // The `libloading` crate will automatically load system libraries like `libc`.
106
+ // On linux `libloading` is based on `dlsym`: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#202
107
+ // and `dlsym`(https://linux.die.net/man/3/dlsym) looks through the dependency tree of the
108
+ // library if it can't find the symbol in the library itself.
109
+ // So, in order to check if the function was actually found in the specified
110
+ // `machine.external_so_lib` we need to check its `dli_fname` and compare it to
111
+ // the specified SO file path.
112
+ // This code is a reimplementation of the mechanism for getting `dli_fname` in `libloading`,
113
+ // from: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#411
114
+ // using the `libc` crate where this interface is public.
115
+ let mut info = std:: mem:: MaybeUninit :: < libc:: Dl_info > :: zeroed ( ) ;
116
+ unsafe {
117
+ if libc:: dladdr ( fn_ptr, info. as_mut_ptr ( ) ) != 0 {
118
+ let info = info. assume_init ( ) ;
119
+ #[ cfg( target_os = "cygwin" ) ]
120
+ let fname_ptr = info. dli_fname . as_ptr ( ) ;
121
+ #[ cfg( not( target_os = "cygwin" ) ) ]
122
+ let fname_ptr = info. dli_fname ;
123
+ assert ! ( !fname_ptr. is_null( ) ) ;
124
+ if std:: ffi:: CStr :: from_ptr ( fname_ptr) . to_str ( ) . unwrap ( )
125
+ != lib_path. to_str ( ) . unwrap ( )
126
+ {
127
+ return None ;
128
+ }
125
129
}
126
130
}
127
- }
128
131
129
- // Return a pointer to the function.
130
- Some ( CodePtr ( fn_ptr) )
132
+ // Return a pointer to the function.
133
+ return Some ( CodePtr ( fn_ptr) ) ;
134
+ }
135
+ None
131
136
}
132
137
}
133
138
0 commit comments