Skip to content

Commit a7de42f

Browse files
committed
Use pull instead of push based model for getting dylib symbols in the jit
This avoids having to parse the dylibs to get all symbols and matches the way the dynamic linker resolves symbols. Furthermore it fixes the jit on Windows.
1 parent 53f4bb9 commit a7de42f

File tree

2 files changed

+18
-36
lines changed

2 files changed

+18
-36
lines changed

build_system/tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,7 @@ impl TestRunner {
465465
out_dir.push("out");
466466

467467
let is_native = host_triple == target_triple;
468-
let jit_supported =
469-
target_triple.contains("x86_64") && is_native && !host_triple.contains("windows");
468+
let jit_supported = target_triple.contains("x86_64") && is_native;
470469

471470
let mut rust_flags = env::var("RUSTFLAGS").ok().unwrap_or("".to_string());
472471
let mut run_wrapper = Vec::new();

src/driver/jit.rs

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,12 @@ fn create_jit_module(
6767
hotswap: bool,
6868
) -> (JITModule, CodegenCx) {
6969
let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string());
70-
let imported_symbols = load_imported_symbols_for_jit(tcx.sess, crate_info);
7170

7271
let isa = crate::build_isa(tcx.sess, backend_config);
7372
let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
7473
jit_builder.hotswap(hotswap);
7574
crate::compiler_builtins::register_functions_for_jit(&mut jit_builder);
76-
jit_builder.symbols(imported_symbols);
75+
jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info));
7776
jit_builder.symbol("__clif_jit_fn", clif_jit_fn as *const u8);
7877
let mut jit_module = JITModule::new(jit_builder);
7978

@@ -286,10 +285,10 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) ->
286285
})
287286
}
288287

289-
fn load_imported_symbols_for_jit(
288+
fn dep_symbol_lookup_fn(
290289
sess: &Session,
291290
crate_info: CrateInfo,
292-
) -> Vec<(String, *const u8)> {
291+
) -> Box<dyn Fn(&str) -> Option<*const u8>> {
293292
use rustc_middle::middle::dependency_format::Linkage;
294293

295294
let mut dylib_paths = Vec::new();
@@ -316,39 +315,23 @@ fn load_imported_symbols_for_jit(
316315
}
317316
}
318317

319-
let mut imported_symbols = Vec::new();
320-
for path in dylib_paths {
321-
use object::{Object, ObjectSymbol};
322-
let lib = libloading::Library::new(&path).unwrap();
323-
let obj = std::fs::read(path).unwrap();
324-
let obj = object::File::parse(&*obj).unwrap();
325-
imported_symbols.extend(obj.dynamic_symbols().filter_map(|symbol| {
326-
let name = symbol.name().unwrap().to_string();
327-
if name.is_empty() || !symbol.is_global() || symbol.is_undefined() {
328-
return None;
329-
}
330-
if name.starts_with("rust_metadata_") {
331-
// The metadata is part of a section that is not loaded by the dynamic linker in
332-
// case of cg_llvm.
333-
return None;
334-
}
335-
let dlsym_name = if cfg!(target_os = "macos") {
336-
// On macOS `dlsym` expects the name without leading `_`.
337-
assert!(name.starts_with('_'), "{:?}", name);
338-
&name[1..]
339-
} else {
340-
&name
341-
};
342-
let symbol: libloading::Symbol<'_, *const u8> =
343-
unsafe { lib.get(dlsym_name.as_bytes()) }.unwrap();
344-
Some((name, *symbol))
345-
}));
346-
std::mem::forget(lib)
347-
}
318+
let imported_dylibs = Box::leak(
319+
dylib_paths
320+
.into_iter()
321+
.map(|path| libloading::Library::new(&path).unwrap())
322+
.collect::<Box<[_]>>(),
323+
);
348324

349325
sess.abort_if_errors();
350326

351-
imported_symbols
327+
Box::new(move |sym_name| {
328+
for dylib in &*imported_dylibs {
329+
if let Ok(sym) = unsafe { dylib.get::<*const u8>(sym_name.as_bytes()) } {
330+
return Some(*sym);
331+
}
332+
}
333+
None
334+
})
352335
}
353336

354337
fn codegen_shim<'tcx>(

0 commit comments

Comments
 (0)