1 //! dlfcn implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/dlfcn.h.html 2 3 use core::{ 4 ptr, str, 5 sync::atomic::{AtomicUsize, Ordering}, 6 }; 7 use crate::unix::c_str::*; 8 use crate::ld_so::tcb::Tcb; 9 10 static ERROR_NOT_SUPPORTED: &'static CStr = c_str!("dlfcn not supported"); 11 12 #[thread_local] 13 static ERROR: AtomicUsize = AtomicUsize::new(0); 14 15 #[no_mangle] 16 pub unsafe extern "C" fn dladdr(addr: *mut ::c_void, info: *mut ::Dl_info) -> ::c_int { 17 //TODO 18 (*info).dli_fname = ptr::null(); 19 (*info).dli_fbase = ptr::null_mut(); 20 (*info).dli_sname = ptr::null(); 21 (*info).dli_saddr = ptr::null_mut(); 22 0 23 } 24 25 #[no_mangle] 26 pub unsafe extern "C" fn dlopen(cfilename: *const ::c_char, flags: ::c_int) -> *mut ::c_void { 27 //TODO support all sort of flags 28 29 let filename = if cfilename.is_null() { 30 None 31 } else { 32 Some(str::from_utf8_unchecked( 33 CStr::from_ptr(cfilename).to_bytes(), 34 )) 35 }; 36 37 let tcb = match Tcb::current() { 38 Some(tcb) => tcb, 39 None => { 40 ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); 41 return ptr::null_mut(); 42 } 43 }; 44 if tcb.linker_ptr.is_null() { 45 ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); 46 return ptr::null_mut(); 47 } 48 let mut linker = (&*tcb.linker_ptr).lock(); 49 50 let cbs_c = linker.cbs.clone(); 51 let cbs = cbs_c.borrow(); 52 53 let id = match (cbs.load_library)(&mut linker, filename) { 54 Err(err) => { 55 ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); 56 return ptr::null_mut(); 57 } 58 Ok(id) => id, 59 }; 60 61 id as *mut ::c_void 62 } 63 64 #[no_mangle] 65 pub unsafe extern "C" fn dlsym(handle: *mut ::c_void, symbol: *const ::c_char) -> *mut ::c_void { 66 if symbol.is_null() { 67 ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); 68 return ptr::null_mut(); 69 } 70 71 let symbol_str = str::from_utf8_unchecked(CStr::from_ptr(symbol).to_bytes()); 72 73 let tcb = match Tcb::current() { 74 Some(tcb) => tcb, 75 None => { 76 ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); 77 return ptr::null_mut(); 78 } 79 }; 80 81 if tcb.linker_ptr.is_null() { 82 ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); 83 return ptr::null_mut(); 84 } 85 86 let linker = (&*tcb.linker_ptr).lock(); 87 let cbs_c = linker.cbs.clone(); 88 let cbs = cbs_c.borrow(); 89 match (cbs.get_sym)(&linker, handle as usize, symbol_str) { 90 Some(sym) => sym, 91 _ => { 92 ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); 93 ptr::null_mut() 94 } 95 } 96 } 97 98 #[no_mangle] 99 pub unsafe extern "C" fn dlclose(handle: *mut ::c_void) -> ::c_int { 100 let tcb = match Tcb::current() { 101 Some(tcb) => tcb, 102 None => { 103 ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); 104 return -1; 105 } 106 }; 107 108 if tcb.linker_ptr.is_null() { 109 ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); 110 return -1; 111 }; 112 let mut linker = (&*tcb.linker_ptr).lock(); 113 let cbs_c = linker.cbs.clone(); 114 let cbs = cbs_c.borrow(); 115 (cbs.unload)(&mut linker, handle as usize); 116 0 117 } 118 119 #[no_mangle] 120 pub extern "C" fn dlerror() -> *mut ::c_char { 121 ERROR.swap(0, Ordering::SeqCst) as *mut ::c_char 122 } 123