sel4_runtime_common/
tls.rs
1use sel4_elf_header::PT_TLS;
8use sel4_panicking_env::abort;
9
10#[allow(unused_imports)]
11use sel4_initialize_tls::{SetThreadPointerFn, UncheckedTlsImage, DEFAULT_SET_THREAD_POINTER_FN};
12
13use crate::locate_phdrs;
14
15#[allow(clippy::missing_safety_doc)]
16pub(crate) unsafe fn with_tls(f: impl FnOnce() -> !) -> ! {
17 let phdr = locate_phdrs()
18 .iter()
19 .find(|phdr| phdr.p_type == PT_TLS)
20 .unwrap_or_else(|| abort!("no PT_TLS segment"));
21 let unchecked = UncheckedTlsImage {
22 vaddr: phdr.p_vaddr,
23 filesz: phdr.p_filesz,
24 memsz: phdr.p_memsz,
25 align: phdr.p_align,
26 };
27 unchecked
28 .check()
29 .unwrap_or_else(|_| abort!("invalid TLS image: {unchecked:#x?}"))
30 .with_initialize_on_stack(CHOSEN_SET_THREAD_POINTER_FN, f)
31}
32
33sel4::sel4_cfg_if! {
34 if #[sel4_cfg(all(ARCH_X86_64, SET_TLS_BASE_SELF))] {
35 const CHOSEN_SET_THREAD_POINTER_FN: SetThreadPointerFn = set_thread_pointer_via_syscall;
36
37 unsafe extern "C" fn set_thread_pointer_via_syscall(val: usize) {
38 sel4::set_tls_base(val);
39 }
40 } else {
41 const CHOSEN_SET_THREAD_POINTER_FN: SetThreadPointerFn = DEFAULT_SET_THREAD_POINTER_FN;
42 }
43}
44
45#[cfg(target_arch = "arm")]
46#[no_mangle]
47extern "C" fn __aeabi_read_tp() -> usize {
48 let mut val: usize;
49 unsafe {
50 core::arch::asm!("mrc p15, 0, {val}, c13, c0, 2", val = out(reg) val); }
52 val
53}