Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace dynamic library module with libloading #90716

Merged
merged 1 commit into from
Dec 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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