Fix missing symbols for ARM dynamic linking
This commit is contained in:
committed by
Jeremy Soller
parent
b8bae33fde
commit
d6eaa0dbf9
@@ -110,13 +110,13 @@ SECTIONS
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
/* .init_array :
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
} */
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
@@ -248,9 +248,8 @@ SECTIONS
|
||||
* ld.so will be moved out of relibc. So, till that time, we have to discard any sections
|
||||
* that may reference use thread local storage.
|
||||
*
|
||||
* .init_array also depends on TLS and is discarded as we don't need it.
|
||||
* .init_array need to be not discarded unlike x86_64 linker variant
|
||||
*/
|
||||
*(.gnu.linkonce.tb.*) *(.tcommon)
|
||||
*(.init_array)
|
||||
}
|
||||
}
|
||||
|
||||
+88
-13
@@ -1,29 +1,104 @@
|
||||
use crate::{platform::types::*, raw_cell::RawCell};
|
||||
|
||||
// TODO: Implement cxa_finalize and uncomment this
|
||||
use crate::platform::types::*;
|
||||
use alloc::vec::Vec;
|
||||
use core::{cell::RefCell, ptr};
|
||||
use spin::Mutex;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct CxaAtExitFunc {
|
||||
//func: extern "C" fn(*mut c_void),
|
||||
//arg: *mut c_void,
|
||||
//dso: *mut c_void,
|
||||
func: extern "C" fn(*mut c_void),
|
||||
arg: usize,
|
||||
dso: usize,
|
||||
}
|
||||
|
||||
static CXA_ATEXIT_FUNCS: RawCell<[Option<CxaAtExitFunc>; 32]> = RawCell::new([None; 32]);
|
||||
#[derive(Clone, Copy)]
|
||||
struct CxaThreadAtExitFunc {
|
||||
func: extern "C" fn(*mut c_void),
|
||||
obj: *mut c_void,
|
||||
dso: *mut c_void,
|
||||
}
|
||||
|
||||
static CXA_ATEXIT_FUNCS: Mutex<Vec<Option<CxaAtExitFunc>>> = Mutex::new(Vec::new());
|
||||
#[thread_local]
|
||||
static DTORS: RefCell<Vec<CxaThreadAtExitFunc>> = RefCell::new(Vec::new());
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __cxa_atexit(
|
||||
func_opt: Option<extern "C" fn(*mut c_void)>,
|
||||
func: Option<extern "C" fn(*mut c_void)>,
|
||||
arg: *mut c_void,
|
||||
dso: *mut c_void,
|
||||
) -> c_int {
|
||||
for i in 0..CXA_ATEXIT_FUNCS.unsafe_ref().len() {
|
||||
if CXA_ATEXIT_FUNCS.unsafe_ref()[i].is_none() {
|
||||
CXA_ATEXIT_FUNCS.unsafe_mut()[i] =
|
||||
func_opt.map(|func| CxaAtExitFunc {} /*{ func, arg, dso }*/);
|
||||
let Some(func) = func else {
|
||||
return 0;
|
||||
};
|
||||
|
||||
let entry = CxaAtExitFunc {
|
||||
func,
|
||||
arg: arg as usize,
|
||||
dso: dso as usize,
|
||||
};
|
||||
|
||||
let mut funcs = CXA_ATEXIT_FUNCS.lock();
|
||||
|
||||
for slot in funcs.iter_mut() {
|
||||
if slot.is_none() {
|
||||
*slot = Some(entry);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
-1
|
||||
// No empty slots
|
||||
funcs.push(Some(entry));
|
||||
0
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __cxa_finalize(dso: *mut c_void) {
|
||||
let mut funcs = CXA_ATEXIT_FUNCS.lock();
|
||||
|
||||
let dso_usize = dso as usize;
|
||||
|
||||
for slot in funcs.iter_mut().rev() {
|
||||
if let Some(entry) = slot.as_ref() {
|
||||
if dso.is_null() || entry.dso == dso_usize {
|
||||
if let Some(entry_to_run) = slot.take() {
|
||||
(entry_to_run.func)(entry_to_run.arg as *mut c_void);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clean up remaining list
|
||||
if dso.is_null() {
|
||||
funcs.clear();
|
||||
} else {
|
||||
funcs.retain(|opt| opt.is_some());
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __cxa_thread_atexit_impl(
|
||||
func: extern "C" fn(*mut c_void),
|
||||
obj: *mut c_void,
|
||||
dso: *mut c_void,
|
||||
) {
|
||||
let entry = CxaThreadAtExitFunc { func, obj, dso };
|
||||
DTORS.borrow_mut().push(entry);
|
||||
}
|
||||
|
||||
// called internally
|
||||
pub unsafe fn __cxa_thread_finalize() {
|
||||
let mut dtors = DTORS.borrow_mut();
|
||||
while let Some(entry) = dtors.pop() {
|
||||
(entry.func)(entry.obj);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn _ITM_deregisterTMCloneTable(_ptr: *mut c_void) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn _ITM_registerTMCloneTable(_ptr: *mut c_void, _len: usize) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
@@ -302,6 +302,8 @@ pub unsafe extern "C" fn __relibc_internal_pthread_cleanup_pop(execute: c_int) {
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn run_destructor_stack() {
|
||||
unsafe { crate::cxa::__cxa_thread_finalize() };
|
||||
|
||||
let mut ptr = CLEANUP_LL_HEAD.get();
|
||||
|
||||
while !ptr.is_null() {
|
||||
|
||||
Reference in New Issue
Block a user