feat(dlfcn): return DSO as the handle
Fine because: > The value of this handle should not be interpreted in any way by the > caller. From: https://pubs.opengroup.org/onlinepubs/009696599/functions/dlopen.html * Add tests for unload * Implement NOLOAD so we can test that the loaded object has been destroyed. * Minor cleanup. Signed-off-by: Anhad Singh <andypython@protonmail.com>
This commit is contained in:
@@ -29,14 +29,14 @@ pub unsafe extern "C" fn __tls_get_addr(ti: *mut dl_tls_index) -> *mut c_void {
|
||||
tcb.dtv_mut().unwrap().len()
|
||||
);
|
||||
|
||||
if tcb.dtv_mut().unwrap_or_default().len() < masters.len() {
|
||||
if tcb.dtv_mut().len() < masters.len() {
|
||||
// Reallocate DTV.
|
||||
tcb.setup_dtv(masters.len());
|
||||
}
|
||||
|
||||
let dtv_index = ti.ti_module as usize - 1;
|
||||
|
||||
if tcb.dtv_mut().unwrap()[dtv_index].is_null() {
|
||||
if tcb.dtv_mut()[dtv_index].is_null() {
|
||||
// Allocate TLS for module.
|
||||
let master = &masters[dtv_index];
|
||||
|
||||
@@ -50,10 +50,10 @@ pub unsafe extern "C" fn __tls_get_addr(ti: *mut dl_tls_index) -> *mut c_void {
|
||||
unsafe { core::ptr::copy_nonoverlapping(master.ptr, module_tls, master.len) };
|
||||
|
||||
// Set the DTV entry.
|
||||
tcb.dtv_mut().unwrap()[dtv_index] = module_tls;
|
||||
tcb.dtv_mut()[dtv_index] = module_tls;
|
||||
}
|
||||
|
||||
let mut ptr = tcb.dtv_mut().unwrap()[dtv_index];
|
||||
let mut ptr = tcb.dtv_mut()[dtv_index];
|
||||
|
||||
if ptr.is_null() {
|
||||
panic!(
|
||||
|
||||
+28
-11
@@ -3,14 +3,17 @@
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use core::{
|
||||
ptr, str,
|
||||
ptr::{self, NonNull},
|
||||
str,
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
c_str::CStr,
|
||||
ld_so::{
|
||||
linker::{ObjectScope, Resolve},
|
||||
linker::{ObjectHandle, ObjectScope, Resolve},
|
||||
tcb::Tcb,
|
||||
},
|
||||
platform::types::*,
|
||||
@@ -18,7 +21,10 @@ use crate::{
|
||||
|
||||
pub const RTLD_LAZY: c_int = 1 << 0;
|
||||
pub const RTLD_NOW: c_int = 1 << 1;
|
||||
// FIXME(andypython):
|
||||
// #ifdef _GNU_SOURCE
|
||||
pub const RTLD_NOLOAD: c_int = 1 << 2;
|
||||
// #endif
|
||||
pub const RTLD_GLOBAL: c_int = 1 << 8;
|
||||
pub const RTLD_LOCAL: c_int = 0x0000;
|
||||
|
||||
@@ -62,6 +68,8 @@ pub unsafe extern "C" fn dlopen(cfilename: *const c_char, flags: c_int) -> *mut
|
||||
ObjectScope::Local
|
||||
};
|
||||
|
||||
let noload = flags & RTLD_NOLOAD == RTLD_NOLOAD;
|
||||
|
||||
let filename = if cfilename.is_null() {
|
||||
None
|
||||
} else {
|
||||
@@ -88,19 +96,19 @@ pub unsafe extern "C" fn dlopen(cfilename: *const c_char, flags: c_int) -> *mut
|
||||
let cbs_c = linker.cbs.clone();
|
||||
let cbs = cbs_c.borrow();
|
||||
|
||||
let id = match (cbs.load_library)(&mut linker, filename, resolve, scope) {
|
||||
Err(err) => {
|
||||
match (cbs.load_library)(&mut linker, filename, resolve, scope, noload) {
|
||||
Ok(handle) => handle.as_ptr().cast_mut(),
|
||||
Err(error) => {
|
||||
ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
|
||||
return ptr::null_mut();
|
||||
ptr::null_mut()
|
||||
}
|
||||
Ok(id) => id,
|
||||
};
|
||||
|
||||
id as *mut c_void
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void {
|
||||
let handle = ObjectHandle::from_ptr(handle);
|
||||
|
||||
if symbol.is_null() {
|
||||
ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
|
||||
return ptr::null_mut();
|
||||
@@ -108,6 +116,9 @@ pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *m
|
||||
|
||||
let symbol_str = unsafe { str::from_utf8_unchecked(CStr::from_ptr(symbol).to_bytes()) };
|
||||
|
||||
// FIXME(andypython): just call obj.scope.get_sym() directly or search the
|
||||
// global scope. The rest is unnecessary as Linker::get_sym() does not
|
||||
// depend on the Linker state.
|
||||
let tcb = match unsafe { Tcb::current() } {
|
||||
Some(tcb) => tcb,
|
||||
None => {
|
||||
@@ -124,7 +135,7 @@ pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *m
|
||||
let linker = unsafe { (&*tcb.linker_ptr).lock() };
|
||||
let cbs_c = linker.cbs.clone();
|
||||
let cbs = cbs_c.borrow();
|
||||
match (cbs.get_sym)(&linker, handle as usize, symbol_str) {
|
||||
match (cbs.get_sym)(&linker, handle, symbol_str) {
|
||||
Some(sym) => sym,
|
||||
_ => {
|
||||
ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
|
||||
@@ -147,10 +158,16 @@ pub unsafe extern "C" fn dlclose(handle: *mut c_void) -> c_int {
|
||||
ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
|
||||
return -1;
|
||||
};
|
||||
|
||||
let Some(handle) = ObjectHandle::from_ptr(handle) else {
|
||||
ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
|
||||
return -1;
|
||||
};
|
||||
|
||||
let mut linker = unsafe { (&*tcb.linker_ptr).lock() };
|
||||
let cbs_c = linker.cbs.clone();
|
||||
let cbs = cbs_c.borrow();
|
||||
(cbs.unload)(&mut linker, handle as usize);
|
||||
(cbs.unload)(&mut linker, handle);
|
||||
0
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user