}
fn load_backend_from_dylib(path: &Path) -> fn() -> Box<dyn CodegenBackend> {
- let lib = DynamicLibrary::open(Some(path)).unwrap_or_else(|err| {
+ let lib = DynamicLibrary::open(path).unwrap_or_else(|err| {
let err = format!("couldn't load codegen backend {:?}: {:?}", path, err);
early_error(ErrorOutputType::default(), &err);
});
// 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(Some(&path)) {
+ let lib = match DynamicLibrary::open(&path) {
Ok(lib) => lib,
Err(err) => self.sess.span_fatal(span, &err),
};
}
impl DynamicLibrary {
- /// Lazily open a dynamic library. When passed None it gives a
- /// handle to the calling process
- pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
- let maybe_library = dl::open(filename.map(|path| path.as_os_str()));
+ /// Lazily open a dynamic library.
+ pub fn open(filename: &Path) -> Result<DynamicLibrary, String> {
+ let maybe_library = dl::open(filename.as_os_str());
// The dynamic library must not be constructed if there is
// an error opening the library so the destructor does not
use std::ptr;
use std::str;
- pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
+ pub(super) fn open(filename: &OsStr) -> Result<*mut u8, String> {
check_for_errors_in(|| unsafe {
- match filename {
- Some(filename) => open_external(filename),
- None => open_internal(),
- }
+ let s = CString::new(filename.as_bytes()).unwrap();
+ libc::dlopen(s.as_ptr(), libc::RTLD_LAZY) as *mut u8
})
}
- unsafe fn open_external(filename: &OsStr) -> *mut u8 {
- let s = CString::new(filename.as_bytes()).unwrap();
- libc::dlopen(s.as_ptr(), libc::RTLD_LAZY) as *mut u8
- }
-
- unsafe fn open_internal() -> *mut u8 {
- libc::dlopen(ptr::null(), libc::RTLD_LAZY) as *mut u8
- }
-
fn check_for_errors_in<T, F>(f: F) -> Result<T, String>
where
F: FnOnce() -> T,
use winapi::shared::minwindef::HMODULE;
use winapi::um::errhandlingapi::SetThreadErrorMode;
- use winapi::um::libloaderapi::{FreeLibrary, GetModuleHandleExW, GetProcAddress, LoadLibraryW};
+ use winapi::um::libloaderapi::{FreeLibrary, GetProcAddress, LoadLibraryW};
use winapi::um::winbase::SEM_FAILCRITICALERRORS;
- pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
+ pub(super) fn open(filename: &OsStr) -> Result<*mut u8, String> {
// disable "dll load failed" error dialog.
let prev_error_mode = unsafe {
let new_error_mode = SEM_FAILCRITICALERRORS;
prev_error_mode
};
- let result = match filename {
- Some(filename) => {
- let filename_str: Vec<_> = filename.encode_wide().chain(Some(0)).collect();
- let result = unsafe { LoadLibraryW(filename_str.as_ptr()) } as *mut u8;
- ptr_result(result)
- }
- None => {
- let mut handle = ptr::null_mut();
- let succeeded = unsafe { GetModuleHandleExW(0, ptr::null(), &mut handle) };
- if succeeded == 0 {
- Err(io::Error::last_os_error().to_string())
- } else {
- Ok(handle as *mut u8)
- }
- }
- };
+ let filename_str: Vec<_> = filename.encode_wide().chain(Some(0)).collect();
+ let result = unsafe { LoadLibraryW(filename_str.as_ptr()) } as *mut u8;
+ let result = ptr_result(result);
unsafe {
SetThreadErrorMode(prev_error_mode, ptr::null_mut());
use super::*;
-use std::mem;
-
-#[test]
-fn test_loading_atoi() {
- if cfg!(windows) {
- return;
- }
-
- // The C library does not need to be loaded since it is already linked in
- let lib = match DynamicLibrary::open(None) {
- Err(error) => panic!("Could not load self as module: {}", error),
- Ok(lib) => lib,
- };
-
- let atoi: extern "C" fn(*const libc::c_char) -> libc::c_int = unsafe {
- match lib.symbol("atoi") {
- Err(error) => panic!("Could not load function atoi: {}", error),
- Ok(atoi) => mem::transmute::<*mut u8, _>(atoi),
- }
- };
-
- let argument = CString::new("1383428980").unwrap();
- let expected_result = 0x52757374;
- let result = atoi(argument.as_ptr());
- if result != expected_result {
- panic!("atoi({:?}) != {} but equaled {} instead", argument, expected_result, result)
- }
-}
#[test]
fn test_errors_do_not_crash() {
// Open /dev/null as a library to get an error, and make sure
// that only causes an error, and not a crash.
let path = Path::new("/dev/null");
- match DynamicLibrary::open(Some(&path)) {
+ match DynamicLibrary::open(&path) {
Err(_) => {}
Ok(_) => panic!("Successfully opened the empty library."),
}
// 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(Some(&path)) {
+ let lib = match DynamicLibrary::open(&path) {
Ok(lib) => lib,
// this is fatal: there are almost certainly macros we need
// inside this crate, so continue would spew "macro undefined"
pub fn main() {
unsafe {
let path = Path::new("libdylib.so");
- let a = DynamicLibrary::open(Some(&path)).unwrap();
+ let a = DynamicLibrary::open(&path).unwrap();
assert!(a.symbol::<isize>("fun1").is_ok());
assert!(a.symbol::<isize>("fun2").is_ok());
assert!(a.symbol::<isize>("fun3").is_ok());
+++ /dev/null
-// ignore-musl - dlsym doesn't see symbols without "-C link-arg=-Wl,--export-dynamic"
-
-#![feature(rustc_private)]
-
-extern crate rustc_metadata;
-
-use rustc_metadata::dynamic_lib::DynamicLibrary;
-
-#[no_mangle]
-pub fn foo() {
- bar();
-}
-
-pub fn foo2<T>() {
- fn bar2() {
- bar();
- }
- bar2();
-}
-
-#[no_mangle]
-fn bar() {}
-
-#[allow(dead_code)]
-#[no_mangle]
-fn baz() {}
-
-pub fn test() {
- let lib = DynamicLibrary::open(None).unwrap();
- unsafe {
- assert!(lib.symbol::<isize>("foo").is_ok());
- assert!(lib.symbol::<isize>("baz").is_ok());
- assert!(lib.symbol::<isize>("bar").is_ok());
- }
-}
+++ /dev/null
-// run-pass
-// aux-build:linkage-visibility.rs
-// ignore-android: FIXME(#10356)
-// ignore-windows: std::dynamic_lib does not work on Windows well
-// ignore-emscripten no dynamic linking
-
-extern crate linkage_visibility as foo;
-
-pub fn main() {
- foo::test();
- foo::foo2::<isize>();
- foo::foo();
-}