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:
Josh Megnauth
2025-10-04 19:18:22 -04:00
parent 7ed934a01d
commit e39b27664f
12 changed files with 146 additions and 101 deletions
+7 -3
View File
@@ -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) -> ! {
+4 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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(
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
}
}
}