Split part of TCB into generic-rt
This commit is contained in:
Generated
+6
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "generic-rt"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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" }
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user