@@ -150,36 +150,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
150
150
}
151
151
}
152
152
153
- /// Call specified external C function, with supplied arguments.
154
- /// Need to convert all the arguments from their hir representations to
155
- /// a form compatible with C (through `libffi` call).
156
- /// Then, convert return from the C call into a corresponding form that
157
- /// can be stored in Miri internal memory.
158
- fn call_and_add_external_c_fct_to_context (
159
- & mut self ,
160
- link_name : Symbol ,
161
- dest : & PlaceTy < ' tcx , Tag > ,
162
- args : & [ OpTy < ' tcx , Tag > ] ,
163
- ) -> InterpResult < ' tcx , bool > {
153
+ /// Get the pointer to the function of the specified name in the shared object file,
154
+ /// if it exists. The function must be in the shared object file specified: we do *not*
155
+ /// return pointers to functions in dependencies of the library.
156
+ fn get_func_ptr_explicitly_from_lib ( & mut self , link_name : Symbol ) -> Option < CodePtr > {
164
157
let this = self . eval_context_mut ( ) ;
158
+ // Try getting the function from the shared library.
165
159
let ( lib, lib_path) = this. machine . external_so_lib . as_ref ( ) . unwrap ( ) ;
166
-
167
- // Load the C function from the library.
168
- // Because this is getting the C function from the shared object file
169
- // it is not necessarily a sound operation, but there is no way around
170
- // this and we've checked as much as we can.
171
160
let func: libloading:: Symbol < ' _ , unsafe extern "C" fn ( ) > = unsafe {
172
161
match lib. get ( link_name. as_str ( ) . as_bytes ( ) ) {
173
162
Ok ( x) => x,
174
163
Err ( _) => {
175
- // Shared object file does not export this function -- try the shims next.
176
- return Ok ( false ) ;
164
+ return None ;
177
165
}
178
166
}
179
167
} ;
180
168
181
169
// FIXME: this is a hack!
182
170
// The `libloading` crate will automatically load system libraries like `libc`.
171
+ // On linux `libloading` is based on `dlsym`: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#202
172
+ // and `dlsym`(https://linux.die.net/man/3/dlsym) looks through the dependency tree of the
173
+ // library if it can't find the symbol in the library itself.
183
174
// So, in order to check if the function was actually found in the specified
184
175
// `machine.external_so_lib` we need to check its `dli_fname` and compare it to
185
176
// the specified SO file path.
@@ -192,10 +183,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
192
183
if std:: ffi:: CStr :: from_ptr ( info. assume_init ( ) . dli_fname ) . to_str ( ) . unwrap ( )
193
184
!= lib_path. to_str ( ) . unwrap ( )
194
185
{
195
- return Ok ( false ) ;
186
+ return None ;
196
187
}
197
188
}
198
189
}
190
+ // Return a pointer to the function.
191
+ Some ( CodePtr ( * func. deref ( ) as * mut _ ) )
192
+ }
193
+
194
+ /// Call specified external C function, with supplied arguments.
195
+ /// Need to convert all the arguments from their hir representations to
196
+ /// a form compatible with C (through `libffi` call).
197
+ /// Then, convert return from the C call into a corresponding form that
198
+ /// can be stored in Miri internal memory.
199
+ fn call_and_add_external_c_fct_to_context (
200
+ & mut self ,
201
+ link_name : Symbol ,
202
+ dest : & PlaceTy < ' tcx , Tag > ,
203
+ args : & [ OpTy < ' tcx , Tag > ] ,
204
+ ) -> InterpResult < ' tcx , bool > {
205
+ // Get the pointer to the function in the shared object file if it exists.
206
+ let code_ptr = match self . get_func_ptr_explicitly_from_lib ( link_name) {
207
+ Some ( ptr) => ptr,
208
+ None => {
209
+ // Shared object file does not export this function -- try the shims next.
210
+ return Ok ( false ) ;
211
+ }
212
+ } ;
213
+
214
+ let this = self . eval_context_mut ( ) ;
199
215
200
216
// Get the function arguments, and convert them to `libffi`-compatible form.
201
217
let mut libffi_args = Vec :: < CArg > :: with_capacity ( args. len ( ) ) ;
@@ -214,9 +230,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
214
230
. collect :: < Vec < libffi:: high:: Arg < ' _ > > > ( ) ;
215
231
216
232
// Code pointer to C function.
217
- let ptr = CodePtr ( * func. deref ( ) as * mut _ ) ;
218
- // Call the functio and store output, depending on return type in the function signature.
219
- self . call_external_c_and_store_return ( link_name, dest, ptr , libffi_args) ?;
233
+ // let ptr = CodePtr(*func.deref() as *mut _);
234
+ // Call the function and store output, depending on return type in the function signature.
235
+ self . call_external_c_and_store_return ( link_name, dest, code_ptr , libffi_args) ?;
220
236
Ok ( true )
221
237
}
222
238
}
0 commit comments