Split part of TCB into generic-rt

This commit is contained in:
4lDO2
2024-06-20 22:38:36 +02:00
parent 736a445af6
commit 58d1153536
9 changed files with 135 additions and 79 deletions
Generated
+6
View File
@@ -143,6 +143,10 @@ dependencies = [
"version_check",
]
[[package]]
name = "generic-rt"
version = "0.1.0"
[[package]]
name = "goblin"
version = "0.7.1"
@@ -362,6 +366,7 @@ name = "redox-rt"
version = "0.1.0"
dependencies = [
"bitflags",
"generic-rt",
"goblin",
"plain",
"redox_syscall",
@@ -395,6 +400,7 @@ dependencies = [
"cbitset",
"cc",
"dlmalloc",
"generic-rt",
"goblin",
"libc",
"md-5",
+2
View File
@@ -15,6 +15,7 @@ members = [
"src/crtn",
"redox-rt",
"ld_so",
"generic-rt",
]
exclude = ["tests", "dlmalloc-rs"]
@@ -42,6 +43,7 @@ bcrypt-pbkdf = { version = "0.10", default-features = false, features = ["alloc"
scrypt = { version = "0.11", default-features = false, features = ["simple"]}
pbkdf2 = { version = "0.12", features = ["sha2"]}
sha2 = { version = "0.10", default-features = false }
generic-rt = { path = "generic-rt" }
[dependencies.goblin]
version = "0.7"
+6
View File
@@ -0,0 +1,6 @@
[package]
name = "generic-rt"
version = "0.1.0"
edition = "2021"
[dependencies]
+73
View File
@@ -0,0 +1,73 @@
#![no_std]
use core::arch::asm;
use core::mem::{self, offset_of};
#[derive(Debug)]
#[repr(C)]
pub struct GenericTcb<Os> {
/// Pointer to the end of static TLS. Must be the first member
pub tls_end: *mut u8,
/// Size of the memory allocated for the static TLS in bytes (multiple of page size)
pub tls_len: usize,
/// Pointer to this structure
pub tcb_ptr: *mut Self,
/// Size of the memory allocated for this structure in bytes (should be same as page size)
pub tcb_len: usize,
pub os_specific: Os,
}
impl<Os> GenericTcb<Os> {
/// Architecture specific code to read a usize from the TCB - aarch64
#[inline(always)]
#[cfg(target_arch = "aarch64")]
pub unsafe fn arch_read(offset: usize) -> usize {
let abi_ptr: usize;
asm!(
"mrs {}, tpidr_el0",
out(reg) abi_ptr,
);
let tcb_ptr = *(abi_ptr as *const usize);
*((tcb_ptr + offset) as *const usize)
}
/// Architecture specific code to read a usize from the TCB - x86
#[inline(always)]
#[cfg(target_arch = "x86")]
pub unsafe fn arch_read(offset: usize) -> usize {
let value;
asm!(
"
mov {}, gs:[{}]
",
out(reg) value,
in(reg) offset,
);
value
}
/// Architecture specific code to read a usize from the TCB - x86_64
#[inline(always)]
#[cfg(target_arch = "x86_64")]
pub unsafe fn arch_read(offset: usize) -> usize {
let value;
asm!(
"
mov {}, fs:[{}]
",
out(reg) value,
in(reg) offset,
);
value
}
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));
if tcb_ptr.is_null() || tcb_len < mem::size_of::<Self>() {
None
} else {
Some(tcb_ptr)
}
}
}
+2
View File
@@ -13,3 +13,5 @@ bitflags = "2"
goblin = { version = "0.7", default-features = false, features = ["elf32", "elf64", "endian_fd"] }
plain = "0.2"
redox_syscall = "0.5.1"
generic-rt = { path = "../generic-rt" }
+1 -2
View File
@@ -11,12 +11,11 @@ use crate::signal::inner_c;
pub(crate) const STACK_TOP: usize = 1 << 47;
pub(crate) const STACK_SIZE: usize = 1024 * 1024;
// NOTE: MUST MATCH TCB STRUCT
#[derive(Debug, Default)]
pub struct SigArea {
altstack_top: usize,
altstack_bottom: usize,
tmp: usize,
_rsvd: usize,
}
/// Deactive TLS, used before exec() on Redox to not trick target executable into thinking TLS
+14 -3
View File
@@ -143,9 +143,15 @@ pub fn sigaction(signal: u8, new: Option<&Sigaction>, old: Option<&mut Sigaction
// TODO: handle tmp_disable_signals
}
// TODO: Handle pending signals before these flags are set.
(SIGTSTP, Sigaction::Default) => PROC_CONTROL_STRUCT.word[0].fetch_or(SIGW0_TSTP_IS_STOP_BIT, Ordering::SeqCst),
(SIGTTIN, Sigaction::Default) => PROC_CONTROL_STRUCT.word[0].fetch_or(SIGW0_TTIN_IS_STOP_BIT, Ordering::SeqCst),
(SIGTTOU, Sigaction::Default) => PROC_CONTROL_STRUCT.word[0].fetch_or(SIGW0_TTOU_IS_STOP_BIT, Ordering::SeqCst),
(SIGTSTP, Sigaction::Default) => {
PROC_CONTROL_STRUCT.word[0].fetch_or(SIGW0_TSTP_IS_STOP_BIT, Ordering::SeqCst);
}
(SIGTTIN, Sigaction::Default) => {
PROC_CONTROL_STRUCT.word[0].fetch_or(SIGW0_TTIN_IS_STOP_BIT, Ordering::SeqCst);
}
(SIGTTOU, Sigaction::Default) => {
PROC_CONTROL_STRUCT.word[0].fetch_or(SIGW0_TTOU_IS_STOP_BIT, Ordering::SeqCst);
}
(_, Sigaction::Default) => (),
(_, Sigaction::Handled { .. }) => (),
@@ -275,3 +281,8 @@ pub fn setup_sighandler(control: &Sigcontrol) {
syscall::write(fd, &data).expect("failed to write to thisproc:current/sighandler");
let _ = syscall::close(fd);
}
#[derive(Debug, Default)]
pub struct RtSigarea {
pub control: Sigcontrol,
pub arch: crate::arch::SigArea,
}
+30 -73
View File
@@ -1,6 +1,7 @@
use alloc::vec::Vec;
use generic_rt::GenericTcb;
use syscall::Sigcontrol;
use core::{arch::asm, cell::UnsafeCell, mem::{self, offset_of}, ptr, slice, sync::atomic::AtomicBool};
use core::{arch::asm, cell::UnsafeCell, mem, ops::{Deref, DerefMut}, ptr, slice, sync::atomic::AtomicBool};
use goblin::error::{Error, Result};
use super::ExpectTlsFree;
@@ -30,18 +31,17 @@ impl Master {
}
}
#[cfg(target_os = "linux")]
type OsSpecific = ();
#[cfg(target_os = "redox")]
type OsSpecific = redox_rt::signal::RtSigarea;
#[derive(Debug)]
#[repr(C)]
// FIXME: Only return &Tcb, and use interior mutability, since it contains the Pthread struct
pub struct Tcb {
/// Pointer to the end of static TLS. Must be the first member
pub tls_end: *mut u8,
/// Size of the memory allocated for the static TLS in bytes (multiple of page size)
pub tls_len: usize,
/// Pointer to this structure
pub tcb_ptr: *mut Tcb,
/// Size of the memory allocated for this structure in bytes (should be same as page size)
pub tcb_len: usize,
pub generic: GenericTcb<OsSpecific>,
/// Pointer to a list of initial TLS data
pub masters_ptr: *mut Master,
/// Size of the masters list in bytes (multiple of mem::size_of::<Master>())
@@ -54,13 +54,6 @@ pub struct Tcb {
pub mspace: *const Mutex<Dlmalloc>,
/// Underlying pthread_t struct, pthread_self() returns &self.pthread
pub pthread: Pthread,
#[cfg(target_os = "redox")]
pub sigcontrol: RtSigarea,
}
#[derive(Debug, Default)]
pub struct RtSigarea {
pub control: Sigcontrol,
pub internal: [usize; 4],
}
impl Tcb {
@@ -74,10 +67,13 @@ impl Tcb {
ptr::write(
tcb_ptr,
Self {
tls_end: tls.as_mut_ptr().add(tls.len()),
tls_len: tls.len(),
tcb_ptr,
tcb_len: tcb_page.len(),
generic: GenericTcb {
tls_end: tls.as_mut_ptr().add(tls.len()),
tls_len: tls.len(),
tcb_ptr: tcb_ptr.cast(),
tcb_len: tcb_page.len(),
os_specific: OsSpecific::default(),
},
masters_ptr: ptr::null_mut(),
masters_len: 0,
num_copied_masters: 0,
@@ -92,8 +88,6 @@ impl Tcb {
stack_size: 0,
os_tid: UnsafeCell::new(OsTid::default()),
},
#[cfg(target_os = "redox")]
sigcontrol: Default::default(),
},
);
@@ -102,13 +96,7 @@ impl Tcb {
/// Get the current TCB
pub unsafe fn current() -> Option<&'static 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));
if tcb_ptr.is_null() || tcb_len < mem::size_of::<Self>() {
None
} else {
Some(&mut *tcb_ptr)
}
Some(&mut *GenericTcb::<OsSpecific>::current_ptr()?.cast())
}
/// A slice for all of the TLS data
@@ -228,50 +216,6 @@ impl Tcb {
Ok((abi, tls, tcb))
}
/// Architecture specific code to read a usize from the TCB - aarch64
#[inline(always)]
#[cfg(target_arch = "aarch64")]
unsafe fn arch_read(offset: usize) -> usize {
let abi_ptr: usize;
asm!(
"mrs {}, tpidr_el0",
out(reg) abi_ptr,
);
let tcb_ptr = *(abi_ptr as *const usize);
*((tcb_ptr + offset) as *const usize)
}
/// Architecture specific code to read a usize from the TCB - x86
#[inline(always)]
#[cfg(target_arch = "x86")]
unsafe fn arch_read(offset: usize) -> usize {
let value;
asm!(
"
mov {}, gs:[{}]
",
out(reg) value,
in(reg) offset,
);
value
}
/// Architecture specific code to read a usize from the TCB - x86_64
#[inline(always)]
#[cfg(target_arch = "x86_64")]
unsafe fn arch_read(offset: usize) -> usize {
let value;
asm!(
"
mov {}, fs:[{}]
",
out(reg) value,
in(reg) offset,
);
value
}
/// OS and architecture specific code to activate TLS - Linux x86_64
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
unsafe fn os_arch_activate(tls_end: usize, _tls_len: usize) {
@@ -331,3 +275,16 @@ impl Tcb {
let _ = syscall::close(file);
}
}
impl Deref for Tcb {
type Target = GenericTcb<OsSpecific>;
fn deref(&self) -> &Self::Target {
&self.generic
}
}
impl DerefMut for Tcb {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.generic
}
}
+1 -1
View File
@@ -158,7 +158,7 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
tcb.linker_ptr = Box::into_raw(Box::new(Mutex::new(linker)));
}
#[cfg(target_os = "redox")]
redox_rt::signal::setup_sighandler(&tcb.sigcontrol.control);
redox_rt::signal::setup_sighandler(&tcb.os_specific.control);
}
// Set up argc and argv