Remove support for self-opening

This was only used for linkage test cases, which is already covered by
the run-make-fulldeps/symbol-visibility test -- which fairly extensively makes
sure we're correctly exporting the right symbols at the right visibility (for
various Rust crate types).
This commit is contained in:
Mark Rousskov 2020-04-24 18:31:42 -04:00
parent 0b958790b3
commit 97983af76a
8 changed files with 16 additions and 117 deletions

View File

@ -205,7 +205,7 @@ pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(
}
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);
});

View File

@ -585,7 +585,7 @@ impl<'a> CrateLoader<'a> {
// 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),
};

View File

@ -16,10 +16,9 @@ impl Drop for DynamicLibrary {
}
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
@ -57,24 +56,13 @@ mod dl {
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,
@ -124,10 +112,10 @@ mod dl {
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;
@ -139,22 +127,9 @@ mod dl {
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());

View File

@ -1,32 +1,4 @@
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() {
@ -39,7 +11,7 @@ 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."),
}

View File

@ -76,7 +76,7 @@ fn dylink_registrar(
// 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"

View File

@ -8,7 +8,7 @@ use std::path::Path;
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());

View File

@ -1,35 +0,0 @@
// 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());
}
}

View File

@ -1,13 +0,0 @@
// 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();
}