Skip to content

Commit

Permalink
replace dynamic library module with libloading
Browse files Browse the repository at this point in the history
  • Loading branch information
euclio committed Dec 6, 2021
1 parent 0fb1c37 commit 923f939
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 313 deletions.
16 changes: 14 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1921,6 +1921,16 @@ dependencies = [
"pkg-config",
]

[[package]]
name = "libloading"
version = "0.7.1"
source = "registry+/~https://github.com/rust-lang/crates.io-index"
checksum = "c0cf036d15402bea3c5d4de17b3fce76b3e4a56ebc1f577be0e7a72f7c607cf0"
dependencies = [
"cfg-if 1.0.0",
"winapi",
]

[[package]]
name = "libm"
version = "0.1.4"
Expand Down Expand Up @@ -3708,6 +3718,7 @@ dependencies = [
"bitflags",
"cstr",
"libc",
"libloading",
"measureme 10.0.0",
"rustc-demangle",
"rustc_arena",
Expand Down Expand Up @@ -3992,6 +4003,7 @@ name = "rustc_interface"
version = "0.0.0"
dependencies = [
"libc",
"libloading",
"rustc-rayon",
"rustc-rayon-core",
"rustc_ast",
Expand Down Expand Up @@ -4104,7 +4116,7 @@ dependencies = [
name = "rustc_metadata"
version = "0.0.0"
dependencies = [
"libc",
"libloading",
"odht",
"rustc_ast",
"rustc_attr",
Expand All @@ -4124,7 +4136,6 @@ dependencies = [
"smallvec",
"snap",
"tracing",
"winapi",
]

[[package]]
Expand Down Expand Up @@ -4297,6 +4308,7 @@ dependencies = [
name = "rustc_plugin_impl"
version = "0.0.0"
dependencies = [
"libloading",
"rustc_ast",
"rustc_errors",
"rustc_hir",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ doctest = false
bitflags = "1.0"
cstr = "0.2"
libc = "0.2"
libloading = "0.7.1"
measureme = "10.0.0"
snap = "1"
tracing = "0.1"
Expand Down
17 changes: 8 additions & 9 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::back::write::create_informational_target_machine;
use crate::{llvm, llvm_util};
use libc::c_int;
use libloading::Library;
use rustc_codegen_ssa::target_features::supported_target_features;
use rustc_data_structures::fx::FxHashSet;
use rustc_metadata::dynamic_lib::DynamicLibrary;
use rustc_middle::bug;
use rustc_session::config::PrintRequest;
use rustc_session::Session;
Expand All @@ -13,7 +13,6 @@ use std::ffi::{CStr, CString};
use tracing::debug;

use std::mem;
use std::path::Path;
use std::ptr;
use std::slice;
use std::str;
Expand Down Expand Up @@ -120,14 +119,14 @@ unsafe fn configure_llvm(sess: &Session) {

llvm::LLVMInitializePasses();

// Register LLVM plugins by loading them into the compiler process.
for plugin in &sess.opts.debugging_opts.llvm_plugins {
let path = Path::new(plugin);
let res = DynamicLibrary::open(path);
match res {
Ok(_) => debug!("LLVM plugin loaded succesfully {} ({})", path.display(), plugin),
Err(e) => bug!("couldn't load plugin: {}", e),
}
mem::forget(res);
let lib = Library::new(plugin).unwrap_or_else(|e| bug!("couldn't load plugin: {}", e));
debug!("LLVM plugin loaded successfully {:?} ({})", lib, plugin);

// Intentionally leak the dynamic library. We can't ever unload it
// since the library can make things that will live arbitrarily long.
mem::forget(lib);
}

rustc_llvm::initialize_available_targets();
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ doctest = false

[dependencies]
libc = "0.2"
libloading = "0.7.1"
tracing = "0.1"
rustc-rayon-core = "0.3.1"
rayon = { version = "0.3.1", package = "rustc-rayon" }
Expand Down
46 changes: 21 additions & 25 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use libloading::Library;
use rustc_ast::mut_visit::{visit_clobber, MutVisitor, *};
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, AttrVec, BlockCheckMode};
Expand All @@ -7,7 +8,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::jobserver;
use rustc_data_structures::sync::Lrc;
use rustc_errors::registry::Registry;
use rustc_metadata::dynamic_lib::DynamicLibrary;
#[cfg(parallel_compiler)]
use rustc_middle::ty::tls;
use rustc_parse::validate_attr;
Expand Down Expand Up @@ -39,6 +39,9 @@ use std::sync::{Arc, Mutex};
use std::thread;
use tracing::info;

/// Function pointer type that constructs a new CodegenBackend.
pub type MakeBackendFn = fn() -> Box<dyn CodegenBackend>;

/// Adds `target_feature = "..."` cfgs for a variety of platform
/// specific features (SSE, NEON etc.).
///
Expand Down Expand Up @@ -211,28 +214,24 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
})
}

fn load_backend_from_dylib(path: &Path) -> fn() -> Box<dyn CodegenBackend> {
let lib = DynamicLibrary::open(path).unwrap_or_else(|err| {
let err = format!("couldn't load codegen backend {:?}: {:?}", path, err);
fn load_backend_from_dylib(path: &Path) -> MakeBackendFn {
let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| {
let err = format!("couldn't load codegen backend {:?}: {}", path, err);
early_error(ErrorOutputType::default(), &err);
});
unsafe {
match lib.symbol("__rustc_codegen_backend") {
Ok(f) => {
mem::forget(lib);
mem::transmute::<*mut u8, _>(f)
}
Err(e) => {
let err = format!(
"couldn't load codegen backend as it \
doesn't export the `__rustc_codegen_backend` \
symbol: {:?}",
e
);
early_error(ErrorOutputType::default(), &err);
}
}
}

let backend_sym = unsafe { lib.get::<MakeBackendFn>(b"__rustc_codegen_backend") }
.unwrap_or_else(|e| {
let err = format!("couldn't load codegen backend: {}", e);
early_error(ErrorOutputType::default(), &err);
});

// Intentionally leak the dynamic library. We can't ever unload it
// since the library can make things that will live arbitrarily long.
let backend_sym = unsafe { backend_sym.into_raw() };
mem::forget(lib);

*backend_sym
}

/// Get the codegen backend based on the name and specified sysroot.
Expand Down Expand Up @@ -380,10 +379,7 @@ fn sysroot_candidates() -> Vec<PathBuf> {
}
}

pub fn get_codegen_sysroot(
maybe_sysroot: &Option<PathBuf>,
backend_name: &str,
) -> fn() -> Box<dyn CodegenBackend> {
pub fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> MakeBackendFn {
// For now we only allow this function to be called once as it'll dlopen a
// few things, which seems to work best if we only do that once. In
// general this assertion never trips due to the once guard in `get_codegen_backend`,
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2021"
doctest = false

[dependencies]
libc = "0.2"
libloading = "0.7.1"
odht = { version = "0.3.1", features = ["nightly"] }
snap = "1"
tracing = "0.1"
Expand All @@ -27,6 +27,3 @@ rustc_ast = { path = "../rustc_ast" }
rustc_expand = { path = "../rustc_expand" }
rustc_span = { path = "../rustc_span" }
rustc_session = { path = "../rustc_session" }

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["errhandlingapi", "libloaderapi"] }
21 changes: 7 additions & 14 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Validates all used crates and extern libraries and loads their metadata
use crate::dynamic_lib::DynamicLibrary;
use crate::locator::{CrateError, CrateLocator, CratePaths};
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};

Expand Down Expand Up @@ -676,25 +675,19 @@ impl<'a> CrateLoader<'a> {
) -> Result<&'static [ProcMacro], CrateError> {
// Make sure the path contains a / or the linker will search for it.
let path = env::current_dir().unwrap().join(path);
let lib = match DynamicLibrary::open(&path) {
Ok(lib) => lib,
Err(s) => return Err(CrateError::DlOpen(s)),
};
let lib = unsafe { libloading::Library::new(path) }
.map_err(|err| CrateError::DlOpen(err.to_string()))?;

let sym = self.sess.generate_proc_macro_decls_symbol(stable_crate_id);
let decls = unsafe {
let sym = match lib.symbol(&sym) {
Ok(f) => f,
Err(s) => return Err(CrateError::DlSym(s)),
};
*(sym as *const &[ProcMacro])
};
let sym_name = self.sess.generate_proc_macro_decls_symbol(stable_crate_id);
let sym = unsafe { lib.get::<*const &[ProcMacro]>(sym_name.as_bytes()) }
.map_err(|err| CrateError::DlSym(err.to_string()))?;

// Intentionally leak the dynamic library. We can't ever unload it
// since the library can make things that will live arbitrarily long.
let sym = unsafe { sym.into_raw() };
std::mem::forget(lib);

Ok(decls)
Ok(unsafe { **sym })
}

fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
Expand Down
Loading

0 comments on commit 923f939

Please sign in to comment.