unsafe_op_in_unsafe_fn: ld_so, generic/redox-rt
There are a few functions where I allowed the lint. The lower level and
FFI nature of relibc means that there are areas with a lot of unsafe.
Some functions are basically long blocks of unsafe or contain lots of
small blocks of unsafe. unsafe_op_in_unsafe_fn doesn't add clarity to
these functions. Instead, it reduces readability by adding an indent or
small "unsafe { .. }" clutter.
This commit is contained in:
@@ -22,6 +22,7 @@ pub struct GenericTcb<Os> {
|
||||
}
|
||||
impl<Os> GenericTcb<Os> {
|
||||
/// Architecture specific code to read a usize from the TCB - aarch64
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[inline(always)]
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub unsafe fn arch_read(offset: usize) -> usize {
|
||||
@@ -36,6 +37,7 @@ impl<Os> GenericTcb<Os> {
|
||||
}
|
||||
|
||||
/// Architecture specific code to read a usize from the TCB - x86
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[inline(always)]
|
||||
#[cfg(target_arch = "x86")]
|
||||
pub unsafe fn arch_read(offset: usize) -> usize {
|
||||
@@ -51,6 +53,7 @@ impl<Os> GenericTcb<Os> {
|
||||
}
|
||||
|
||||
/// Architecture specific code to read a usize from the TCB - x86_64
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[inline(always)]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub unsafe fn arch_read(offset: usize) -> usize {
|
||||
@@ -66,6 +69,7 @@ impl<Os> GenericTcb<Os> {
|
||||
}
|
||||
|
||||
/// Architecture specific code to read a usize from the TCB - riscv64
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[inline(always)]
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
unsafe fn arch_read(offset: usize) -> usize {
|
||||
@@ -81,8 +85,8 @@ impl<Os> GenericTcb<Os> {
|
||||
}
|
||||
|
||||
pub unsafe fn current_ptr() -> Option<*mut Self> {
|
||||
let tcb_ptr = Self::arch_read(offset_of!(Self, tcb_ptr)) as *mut Self;
|
||||
let tcb_len = Self::arch_read(offset_of!(Self, tcb_len));
|
||||
let tcb_ptr = unsafe { Self::arch_read(offset_of!(Self, tcb_ptr)) as *mut Self };
|
||||
let tcb_len = unsafe { Self::arch_read(offset_of!(Self, tcb_len)) };
|
||||
if tcb_ptr.is_null() || tcb_len < mem::size_of::<Self>() {
|
||||
None
|
||||
} else {
|
||||
@@ -90,7 +94,7 @@ impl<Os> GenericTcb<Os> {
|
||||
}
|
||||
}
|
||||
pub unsafe fn current() -> Option<&'static mut Self> {
|
||||
Some(&mut *Self::current_ptr()?)
|
||||
unsafe { Some(&mut *Self::current_ptr()?) }
|
||||
}
|
||||
}
|
||||
pub fn panic_notls(_msg: impl core::fmt::Display) -> ! {
|
||||
|
||||
@@ -100,6 +100,7 @@ unsafe extern "sysv64" fn fork_impl(args: &ForkArgs, initial_rsp: *mut usize) ->
|
||||
Error::mux(fork_inner(initial_rsp, args))
|
||||
}
|
||||
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
unsafe extern "sysv64" fn child_hook(
|
||||
cur_filetable_fd: usize,
|
||||
new_proc_fd: usize,
|
||||
@@ -483,8 +484,8 @@ pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) -> PosixStackt
|
||||
// since rsp has not been overwritten with the previous context's stack, just yet. At this
|
||||
// point, we know [rsp+0] contains the saved RSP, and [rsp-8] contains the saved RIP.
|
||||
let stack_ptr = stack.regs.rsp as *const usize;
|
||||
stack.regs.rsp = stack_ptr.read();
|
||||
stack.regs.rip = stack_ptr.sub(1).read();
|
||||
stack.regs.rsp = unsafe { stack_ptr.read() };
|
||||
stack.regs.rip = unsafe { stack_ptr.sub(1).read() };
|
||||
} else if stack.regs.rip == __relibc_internal_sigentry_crit_second as usize
|
||||
|| stack.regs.rip == __relibc_internal_sigentry_crit_third as usize
|
||||
{
|
||||
@@ -499,6 +500,7 @@ pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) -> PosixStackt
|
||||
pub(crate) static SUPPORTS_AVX: AtomicU8 = AtomicU8::new(0);
|
||||
|
||||
// __relibc will be prepended to the name, so no_mangle is fine
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe fn manually_enter_trampoline() {
|
||||
let c = &Tcb::current().unwrap().os_specific.control;
|
||||
|
||||
+30
-21
@@ -75,6 +75,7 @@ impl RtTcb {
|
||||
pub type Tcb = GenericTcb<RtTcb>;
|
||||
|
||||
/// OS and architecture specific code to activate TLS - Redox aarch64
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub unsafe fn tcb_activate(_tcb: &RtTcb, tls_end: usize, tls_len: usize) {
|
||||
// Uses ABI page
|
||||
@@ -87,6 +88,7 @@ pub unsafe fn tcb_activate(_tcb: &RtTcb, tls_end: usize, tls_len: usize) {
|
||||
}
|
||||
|
||||
/// OS and architecture specific code to activate TLS - Redox x86
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[cfg(target_arch = "x86")]
|
||||
pub unsafe fn tcb_activate(tcb: &RtTcb, tls_end: usize, _tls_len: usize) {
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
@@ -104,6 +106,7 @@ pub unsafe fn tcb_activate(tcb: &RtTcb, tls_end: usize, _tls_len: usize) {
|
||||
}
|
||||
|
||||
/// OS and architecture specific code to activate TLS - Redox x86_64
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub unsafe fn tcb_activate(tcb: &RtTcb, tls_end_and_tcb_start: usize, _tls_len: usize) {
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
@@ -121,6 +124,7 @@ pub unsafe fn tcb_activate(tcb: &RtTcb, tls_end_and_tcb_start: usize, _tls_len:
|
||||
}
|
||||
|
||||
/// OS and architecture specific code to activate TLS - Redox riscv64
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub unsafe fn tcb_activate(_tcb: &RtTcb, tls_end: usize, tls_len: usize) {
|
||||
// tp points to static tls block
|
||||
@@ -135,6 +139,7 @@ pub unsafe fn tcb_activate(_tcb: &RtTcb, tls_end: usize, tls_len: usize) {
|
||||
}
|
||||
|
||||
/// Initialize redox-rt in situations where relibc is not used
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[cfg(not(feature = "proc"))]
|
||||
pub unsafe fn initialize_freestanding(this_thr_fd: FdGuard) -> &'static FdGuard {
|
||||
// TODO: This code is a hack! Integrate the ld_so TCB code into generic-rt, and then use that
|
||||
@@ -197,20 +202,22 @@ pub unsafe fn initialize(#[cfg(feature = "proc")] proc_fd: FdGuard) {
|
||||
|
||||
#[cfg(feature = "proc")]
|
||||
{
|
||||
crate::arch::PROC_FD.get().write(*proc_fd);
|
||||
unsafe { crate::arch::PROC_FD.get().write(*proc_fd) };
|
||||
}
|
||||
|
||||
STATIC_PROC_INFO.get().write(StaticProcInfo {
|
||||
pid: metadata.pid,
|
||||
unsafe {
|
||||
STATIC_PROC_INFO.get().write(StaticProcInfo {
|
||||
pid: metadata.pid,
|
||||
|
||||
#[cfg(feature = "proc")]
|
||||
proc_fd: MaybeUninit::new(proc_fd),
|
||||
#[cfg(feature = "proc")]
|
||||
proc_fd: MaybeUninit::new(proc_fd),
|
||||
|
||||
#[cfg(not(feature = "proc"))]
|
||||
proc_fd: MaybeUninit::uninit(),
|
||||
#[cfg(not(feature = "proc"))]
|
||||
proc_fd: MaybeUninit::uninit(),
|
||||
|
||||
has_proc_fd: cfg!(feature = "proc"),
|
||||
});
|
||||
has_proc_fd: cfg!(feature = "proc"),
|
||||
})
|
||||
};
|
||||
|
||||
#[cfg(feature = "proc")]
|
||||
{
|
||||
@@ -282,21 +289,23 @@ unsafe fn child_hook_common(args: ChildHookCommonArgs) {
|
||||
let metadata = ProcMeta::default();
|
||||
|
||||
if let Some(proc_fd) = &args.new_proc_fd {
|
||||
crate::arch::PROC_FD.get().write(**proc_fd);
|
||||
unsafe { crate::arch::PROC_FD.get().write(**proc_fd) };
|
||||
}
|
||||
|
||||
let old_proc_fd = STATIC_PROC_INFO
|
||||
.get()
|
||||
.replace(StaticProcInfo {
|
||||
pid: metadata.pid,
|
||||
has_proc_fd: args.new_proc_fd.is_some(),
|
||||
proc_fd: args
|
||||
.new_proc_fd
|
||||
.map_or_else(MaybeUninit::uninit, MaybeUninit::new),
|
||||
})
|
||||
.proc_fd;
|
||||
let old_proc_fd = unsafe {
|
||||
STATIC_PROC_INFO
|
||||
.get()
|
||||
.replace(StaticProcInfo {
|
||||
pid: metadata.pid,
|
||||
has_proc_fd: args.new_proc_fd.is_some(),
|
||||
proc_fd: args
|
||||
.new_proc_fd
|
||||
.map_or_else(MaybeUninit::uninit, MaybeUninit::new),
|
||||
})
|
||||
.proc_fd
|
||||
};
|
||||
drop(old_proc_fd);
|
||||
|
||||
let old_thr_fd = RtTcb::current().thr_fd.get().replace(Some(args.new_thr_fd));
|
||||
let old_thr_fd = unsafe { RtTcb::current().thr_fd.get().replace(Some(args.new_thr_fd)) };
|
||||
drop(old_thr_fd);
|
||||
}
|
||||
|
||||
+10
-8
@@ -649,7 +649,7 @@ impl MmapGuard {
|
||||
flags: PROT_READ | PROT_WRITE,
|
||||
},
|
||||
)?;
|
||||
let slice = &mut *this.as_mut_ptr_slice();
|
||||
let slice = unsafe { &mut *this.as_mut_ptr_slice() };
|
||||
|
||||
Ok((this, slice))
|
||||
}
|
||||
@@ -975,13 +975,15 @@ pub unsafe fn make_init() -> [&'static FdGuard; 2] {
|
||||
syscall::dup(*proc_fd, b"thread-0").expect("failed to get managed thread for init"),
|
||||
);
|
||||
|
||||
let managed_thr_fd = (*RtTcb::current().thr_fd.get()).insert(managed_thr_fd);
|
||||
let managed_thr_fd = unsafe { (*RtTcb::current().thr_fd.get()).insert(managed_thr_fd) };
|
||||
|
||||
STATIC_PROC_INFO.get().write(crate::StaticProcInfo {
|
||||
pid: 1,
|
||||
proc_fd: MaybeUninit::new(proc_fd),
|
||||
has_proc_fd: true,
|
||||
});
|
||||
unsafe {
|
||||
STATIC_PROC_INFO.get().write(crate::StaticProcInfo {
|
||||
pid: 1,
|
||||
proc_fd: MaybeUninit::new(proc_fd),
|
||||
has_proc_fd: true,
|
||||
})
|
||||
};
|
||||
*DYNAMIC_PROC_INFO.lock() = crate::DynamicProcInfo {
|
||||
pgid: 1,
|
||||
ruid: 0,
|
||||
@@ -992,7 +994,7 @@ pub unsafe fn make_init() -> [&'static FdGuard; 2] {
|
||||
sgid: 0,
|
||||
};
|
||||
[
|
||||
(*STATIC_PROC_INFO.get()).proc_fd.assume_init_ref(),
|
||||
unsafe { (*STATIC_PROC_INFO.get()).proc_fd.assume_init_ref() },
|
||||
managed_thr_fd,
|
||||
]
|
||||
}
|
||||
|
||||
+22
-17
@@ -106,13 +106,16 @@ pub struct SiginfoAbi {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn inner(stack: &mut SigStack) {
|
||||
let os = &Tcb::current().unwrap().os_specific;
|
||||
let os = unsafe { &Tcb::current().unwrap().os_specific };
|
||||
|
||||
let stack_ptr = NonNull::from(&mut *stack);
|
||||
stack.link = core::mem::replace(&mut (*os.arch.get()).last_sigstack, Some(stack_ptr))
|
||||
.map_or_else(core::ptr::null_mut, |x| x.as_ptr());
|
||||
stack.link = core::mem::replace(
|
||||
unsafe { &mut (*os.arch.get()).last_sigstack },
|
||||
Some(stack_ptr),
|
||||
)
|
||||
.map_or_else(core::ptr::null_mut, |x| x.as_ptr());
|
||||
|
||||
let signals_were_disabled = (*os.arch.get()).disable_signals_depth > 0;
|
||||
let signals_were_disabled = unsafe { (*os.arch.get()).disable_signals_depth > 0 };
|
||||
|
||||
let targeted_thread_not_process = stack.sig_num >= 64;
|
||||
stack.sig_num %= 64;
|
||||
@@ -121,12 +124,12 @@ unsafe fn inner(stack: &mut SigStack) {
|
||||
stack.sig_num += 1;
|
||||
|
||||
let (sender_pid, sender_uid) = {
|
||||
let area = &mut *os.arch.get();
|
||||
let area = unsafe { &mut *os.arch.get() };
|
||||
|
||||
// Undefined if the signal was not realtime
|
||||
stack.sival = area.tmp_rt_inf.arg;
|
||||
|
||||
stack.old_stack = arch_pre(stack, area);
|
||||
stack.old_stack = unsafe { arch_pre(stack, area) };
|
||||
|
||||
if (stack.sig_num - 1) / 32 == 1 && !targeted_thread_not_process {
|
||||
stack.sig_code = area.tmp_rt_inf.code as u32;
|
||||
@@ -210,7 +213,7 @@ unsafe fn inner(stack: &mut SigStack) {
|
||||
|
||||
// Call handler, either sa_handler or sa_siginfo depending on flag.
|
||||
if sigaction.flags.contains(SigactionFlags::SIGINFO)
|
||||
&& let Some(sigaction) = handler.sigaction
|
||||
&& let Some(sigaction) = unsafe { handler.sigaction }
|
||||
{
|
||||
let info = SiginfoAbi {
|
||||
si_signo: stack.sig_num as c_int,
|
||||
@@ -222,12 +225,14 @@ unsafe fn inner(stack: &mut SigStack) {
|
||||
si_uid: sender_uid as i32,
|
||||
si_value: stack.sival,
|
||||
};
|
||||
sigaction(
|
||||
stack.sig_num as c_int,
|
||||
core::ptr::addr_of!(info).cast(),
|
||||
stack as *mut SigStack as *mut (),
|
||||
);
|
||||
} else if let Some(handler) = handler.handler {
|
||||
unsafe {
|
||||
sigaction(
|
||||
stack.sig_num as c_int,
|
||||
core::ptr::addr_of!(info).cast(),
|
||||
stack as *mut SigStack as *mut (),
|
||||
)
|
||||
};
|
||||
} else if let Some(handler) = unsafe { handler.handler } {
|
||||
handler(stack.sig_num as c_int);
|
||||
}
|
||||
|
||||
@@ -248,10 +253,10 @@ unsafe fn inner(stack: &mut SigStack) {
|
||||
// TODO: If resetting the sigmask caused signals to be unblocked, then should they be delivered
|
||||
// here? And would it be possible to tail-call-optimize that?
|
||||
|
||||
(*os.arch.get()).last_sig_was_restart = shall_restart;
|
||||
unsafe { (*os.arch.get()).last_sig_was_restart = shall_restart };
|
||||
|
||||
// TODO: Support setting uc_link to jump back to a different context?
|
||||
(*os.arch.get()).last_sigstack = NonNull::new(stack.link);
|
||||
unsafe { (*os.arch.get()).last_sigstack = NonNull::new(stack.link) };
|
||||
|
||||
// TODO: Support restoring uc_stack?
|
||||
|
||||
@@ -266,7 +271,7 @@ unsafe fn inner(stack: &mut SigStack) {
|
||||
}
|
||||
#[cfg(not(target_arch = "x86"))]
|
||||
pub(crate) unsafe extern "C" fn inner_c(stack: usize) {
|
||||
inner(&mut *(stack as *mut SigStack))
|
||||
unsafe { inner(&mut *(stack as *mut SigStack)) }
|
||||
}
|
||||
#[cfg(target_arch = "x86")]
|
||||
pub(crate) unsafe extern "fastcall" fn inner_fastcall(stack: usize) {
|
||||
@@ -698,7 +703,7 @@ pub unsafe fn sigaltstack(
|
||||
old_out: Option<&mut Sigaltstack>,
|
||||
) -> Result<()> {
|
||||
let _g = tmp_disable_signals();
|
||||
let tcb = &mut *Tcb::current().unwrap().os_specific.arch.get();
|
||||
let tcb = unsafe { &mut *Tcb::current().unwrap().os_specific.arch.get() };
|
||||
|
||||
let old = get_sigaltstack(tcb, crate::arch::current_sp());
|
||||
|
||||
|
||||
+20
-16
@@ -101,27 +101,31 @@ pub fn posix_getppid() -> u32 {
|
||||
#[inline]
|
||||
pub unsafe fn sys_futex_wait(addr: *mut u32, val: u32, deadline: Option<&TimeSpec>) -> Result<()> {
|
||||
wrapper(true, false, || {
|
||||
syscall::syscall5(
|
||||
syscall::SYS_FUTEX,
|
||||
addr as usize,
|
||||
syscall::FUTEX_WAIT,
|
||||
val as usize,
|
||||
deadline.map_or(0, |d| d as *const _ as usize),
|
||||
0,
|
||||
)
|
||||
unsafe {
|
||||
syscall::syscall5(
|
||||
syscall::SYS_FUTEX,
|
||||
addr as usize,
|
||||
syscall::FUTEX_WAIT,
|
||||
val as usize,
|
||||
deadline.map_or(0, |d| d as *const _ as usize),
|
||||
0,
|
||||
)
|
||||
}
|
||||
.map(|_| ())
|
||||
})
|
||||
}
|
||||
#[inline]
|
||||
pub unsafe fn sys_futex_wake(addr: *mut u32, num: u32) -> Result<u32> {
|
||||
syscall::syscall5(
|
||||
syscall::SYS_FUTEX,
|
||||
addr as usize,
|
||||
syscall::FUTEX_WAKE,
|
||||
num as usize,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
unsafe {
|
||||
syscall::syscall5(
|
||||
syscall::SYS_FUTEX,
|
||||
addr as usize,
|
||||
syscall::FUTEX_WAKE,
|
||||
num as usize,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
}
|
||||
.map(|awoken| awoken as u32)
|
||||
}
|
||||
pub fn sys_call(
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{RtTcb, arch::*, proc::*, signal::tmp_disable_signals, static_proc_in
|
||||
pub unsafe fn rlct_clone_impl(stack: *mut usize) -> Result<FdGuard> {
|
||||
let proc_info = static_proc_info();
|
||||
assert!(proc_info.has_proc_fd);
|
||||
let cur_proc_fd = proc_info.proc_fd.assume_init_ref();
|
||||
let cur_proc_fd = unsafe { proc_info.proc_fd.assume_init_ref() };
|
||||
|
||||
let cur_thr_fd = RtTcb::current().thread_fd();
|
||||
let new_thr_fd = FdGuard::new(syscall::dup(**cur_proc_fd, b"new-thread")?);
|
||||
@@ -56,7 +56,7 @@ pub unsafe fn exit_this_thread(stack_base: *mut (), stack_size: usize) -> ! {
|
||||
// TODO: modify interface so it writes directly to the thread fd?
|
||||
let status_fd = syscall::dup(**tcb.thread_fd(), b"status").unwrap();
|
||||
|
||||
let _ = syscall::funmap(tcb as *const RtTcb as usize, syscall::PAGE_SIZE);
|
||||
let _ = unsafe { syscall::funmap(tcb as *const RtTcb as usize, syscall::PAGE_SIZE) };
|
||||
|
||||
let mut buf = [0; size_of::<usize>() * 3];
|
||||
plain::slice_from_mut_bytes(&mut buf)
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ pub unsafe extern "C" fn relibc_crt0(sp: usize) -> ! {
|
||||
) -> c_int,
|
||||
) -> !;
|
||||
}
|
||||
relibc_start_v1(sp, main)
|
||||
unsafe { relibc_start_v1(sp, main) }
|
||||
}
|
||||
|
||||
#[linkage = "weak"]
|
||||
|
||||
+1
-1
@@ -767,7 +767,7 @@ impl DSO {
|
||||
unsafe fn get_array<'a, T>(ptr: Option<*const T>, len: Option<usize>) -> &'a [T] {
|
||||
if let Some(ptr) = ptr {
|
||||
let len = len.expect("dynamic entry was present without it's corresponding size");
|
||||
core::slice::from_raw_parts(ptr, len)
|
||||
unsafe { core::slice::from_raw_parts(ptr, len) }
|
||||
} else {
|
||||
assert!(len.is_none());
|
||||
&[]
|
||||
|
||||
+3
-2
@@ -3,6 +3,7 @@
|
||||
// FIXME(andypython): remove this when #![allow(warnings, unused_variables)] is
|
||||
// dropped from src/lib.rs.
|
||||
#![warn(warnings, unused_variables)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use core::{mem, ptr};
|
||||
use object::{
|
||||
@@ -200,9 +201,9 @@ pub unsafe fn init(
|
||||
}
|
||||
|
||||
pub unsafe fn fini() {
|
||||
if let Some(tcb) = Tcb::current() {
|
||||
if let Some(tcb) = unsafe { Tcb::current() } {
|
||||
if !tcb.linker_ptr.is_null() {
|
||||
let linker = (*tcb.linker_ptr).lock();
|
||||
let linker = unsafe { (*tcb.linker_ptr).lock() };
|
||||
linker.fini();
|
||||
}
|
||||
}
|
||||
|
||||
+17
-11
@@ -1,5 +1,7 @@
|
||||
// Start code adapted from https://gitlab.redox-os.org/redox-os/relibc/blob/master/src/start.rs
|
||||
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use alloc::{
|
||||
borrow::ToOwned,
|
||||
boxed::Box,
|
||||
@@ -7,12 +9,14 @@ use alloc::{
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
};
|
||||
use generic_rt::ExpectTlsFree;
|
||||
|
||||
use crate::{
|
||||
ALLOCATOR,
|
||||
c_str::CStr,
|
||||
header::unistd,
|
||||
header::{
|
||||
sys_auxv::{AT_ENTRY, AT_PHDR},
|
||||
unistd,
|
||||
},
|
||||
platform::{get_auxv, get_auxvs, types::c_char},
|
||||
start::Stack,
|
||||
sync::mutex::Mutex,
|
||||
@@ -25,7 +29,8 @@ use super::{
|
||||
linker::{Config, Linker},
|
||||
tcb::Tcb,
|
||||
};
|
||||
use crate::header::sys_auxv::{AT_ENTRY, AT_PHDR};
|
||||
|
||||
use generic_rt::ExpectTlsFree;
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub const SIZEOF_EHDR: usize = 52;
|
||||
@@ -36,16 +41,16 @@ pub const SIZEOF_EHDR: usize = 64;
|
||||
unsafe fn get_argv(mut ptr: *const usize) -> (Vec<String>, *const usize) {
|
||||
//traverse the stack and collect argument vector
|
||||
let mut argv = Vec::new();
|
||||
while *ptr != 0 {
|
||||
let arg = *ptr;
|
||||
match CStr::from_ptr(arg as *const c_char).to_str() {
|
||||
while unsafe { *ptr != 0 } {
|
||||
let arg = unsafe { *ptr };
|
||||
match unsafe { CStr::from_ptr(arg as *const c_char).to_str() } {
|
||||
Ok(arg_str) => argv.push(arg_str.to_owned()),
|
||||
_ => {
|
||||
eprintln!("ld.so: failed to parse argv[{}]", argv.len());
|
||||
unistd::_exit(1);
|
||||
}
|
||||
}
|
||||
ptr = ptr.add(1);
|
||||
ptr = unsafe { ptr.add(1) };
|
||||
}
|
||||
|
||||
(argv, ptr)
|
||||
@@ -54,9 +59,9 @@ unsafe fn get_argv(mut ptr: *const usize) -> (Vec<String>, *const usize) {
|
||||
unsafe fn get_env(mut ptr: *const usize) -> (BTreeMap<String, String>, *const usize) {
|
||||
//traverse the stack and collect argument environment variables
|
||||
let mut envs = BTreeMap::new();
|
||||
while *ptr != 0 {
|
||||
let env = *ptr;
|
||||
if let Ok(arg_str) = CStr::from_ptr(env as *const c_char).to_str() {
|
||||
while unsafe { *ptr != 0 } {
|
||||
let env = unsafe { *ptr };
|
||||
if let Ok(arg_str) = unsafe { CStr::from_ptr(env as *const c_char).to_str() } {
|
||||
let mut parts = arg_str.splitn(2, '=');
|
||||
if let Some(key) = parts.next() {
|
||||
if let Some(value) = parts.next() {
|
||||
@@ -64,12 +69,13 @@ unsafe fn get_env(mut ptr: *const usize) -> (BTreeMap<String, String>, *const us
|
||||
}
|
||||
}
|
||||
}
|
||||
ptr = ptr.add(1);
|
||||
ptr = unsafe { ptr.add(1) };
|
||||
}
|
||||
|
||||
(envs, ptr)
|
||||
}
|
||||
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
unsafe fn adjust_stack(sp: &'static mut Stack) {
|
||||
let mut argv = sp.argv() as *mut usize;
|
||||
|
||||
|
||||
+29
-17
@@ -1,3 +1,5 @@
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::{
|
||||
cell::UnsafeCell,
|
||||
@@ -32,7 +34,7 @@ pub struct Master {
|
||||
impl Master {
|
||||
/// The initial data for this TLS region
|
||||
pub unsafe fn data(&self) -> &'static [u8] {
|
||||
slice::from_raw_parts(self.ptr, self.len)
|
||||
unsafe { slice::from_raw_parts(self.ptr, self.len) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +79,7 @@ impl Tcb {
|
||||
/// Create a new TCB
|
||||
///
|
||||
/// `size` is the size of the TLS in bytes.
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
pub unsafe fn new(size: usize) -> Result<&'static mut Self, DlError> {
|
||||
let page_size = Sys::getpagesize();
|
||||
let (_abi_page, tls, tcb_page) = Self::os_new(size.next_multiple_of(page_size))?;
|
||||
@@ -117,7 +120,7 @@ impl Tcb {
|
||||
|
||||
/// Get the current TCB
|
||||
pub unsafe fn current() -> Option<&'static mut Self> {
|
||||
Some(&mut *GenericTcb::<OsSpecific>::current_ptr()?.cast())
|
||||
unsafe { Some(&mut *GenericTcb::<OsSpecific>::current_ptr()?.cast()) }
|
||||
}
|
||||
|
||||
/// A slice for all of the TLS data
|
||||
@@ -125,8 +128,10 @@ impl Tcb {
|
||||
if self.tls_end.is_null() || self.tls_len == 0 {
|
||||
None
|
||||
} else {
|
||||
let tls_start = self.tls_end.sub(self.tls_len);
|
||||
Some(slice::from_raw_parts_mut(tls_start, self.tls_len))
|
||||
unsafe {
|
||||
let tls_start = self.tls_end.sub(self.tls_len);
|
||||
Some(slice::from_raw_parts_mut(tls_start, self.tls_len))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +152,7 @@ impl Tcb {
|
||||
/// Copy data from masters
|
||||
pub unsafe fn copy_masters(&mut self) -> Result<(), DlError> {
|
||||
//TODO: Complain if masters or tls exist without the other
|
||||
if let Some(tls) = self.tls() {
|
||||
if let Some(tls) = unsafe { self.tls() } {
|
||||
if let Some(masters) = self.masters() {
|
||||
for master in masters
|
||||
.iter()
|
||||
@@ -161,7 +166,7 @@ impl Tcb {
|
||||
master.offset..master.offset + master.len
|
||||
};
|
||||
if let Some(tls_data) = tls.get_mut(range) {
|
||||
let data = master.data();
|
||||
let data = unsafe { master.data() };
|
||||
trace!(
|
||||
"tls master: {:p}, {:#x}: {:p}, {:#x}",
|
||||
data.as_ptr(),
|
||||
@@ -201,13 +206,15 @@ impl Tcb {
|
||||
|
||||
/// Activate TLS
|
||||
pub unsafe fn activate(&mut self, #[cfg(target_os = "redox")] thr_fd: redox_rt::proc::FdGuard) {
|
||||
Self::os_arch_activate(
|
||||
&self.os_specific,
|
||||
self.tls_end as usize,
|
||||
self.tls_len,
|
||||
#[cfg(target_os = "redox")]
|
||||
thr_fd,
|
||||
);
|
||||
unsafe {
|
||||
Self::os_arch_activate(
|
||||
&self.os_specific,
|
||||
self.tls_end as usize,
|
||||
self.tls_len,
|
||||
#[cfg(target_os = "redox")]
|
||||
thr_fd,
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
pub fn setup_dtv(&mut self, n: usize) {
|
||||
@@ -255,6 +262,7 @@ impl Tcb {
|
||||
}
|
||||
|
||||
/// Mapping with correct flags for TCB and TLS
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
unsafe fn map(size: usize) -> Result<&'static mut [u8], DlError> {
|
||||
let ptr = Sys::mmap(
|
||||
ptr::null_mut(),
|
||||
@@ -317,7 +325,7 @@ impl Tcb {
|
||||
size: usize,
|
||||
) -> Result<(&'static mut [u8], &'static mut [u8], &'static mut [u8]), DlError> {
|
||||
let page_size = Sys::getpagesize();
|
||||
let abi_tls_tcb = Self::map(page_size + size + page_size)?;
|
||||
let abi_tls_tcb = unsafe { Self::map(page_size + size + page_size)? };
|
||||
let (abi, tls_tcb) = abi_tls_tcb.split_at_mut(page_size);
|
||||
let (tls, tcb) = tls_tcb.split_at_mut(size);
|
||||
Ok((abi, tls, tcb))
|
||||
@@ -327,7 +335,9 @@ impl Tcb {
|
||||
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
|
||||
unsafe fn os_arch_activate(_os: &(), tls_end: usize, _tls_len: usize) {
|
||||
const ARCH_SET_FS: usize = 0x1002;
|
||||
syscall!(ARCH_PRCTL, ARCH_SET_FS, tls_end);
|
||||
unsafe {
|
||||
syscall!(ARCH_PRCTL, ARCH_SET_FS, tls_end);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
@@ -337,8 +347,10 @@ impl Tcb {
|
||||
tls_len: usize,
|
||||
thr_fd: redox_rt::proc::FdGuard,
|
||||
) {
|
||||
os.thr_fd.get().write(Some(thr_fd));
|
||||
redox_rt::tcb_activate(os, tls_end, tls_len)
|
||||
unsafe {
|
||||
os.thr_fd.get().write(Some(thr_fd));
|
||||
redox_rt::tcb_activate(os, tls_end, tls_len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user