1 #![allow(unsafe_code)]
2
3 use super::super::c;
4 use super::super::elf::*;
5 use super::super::param::auxv::exe_phdrs_slice;
6 use core::ptr::null;
7
8 /// For use with [`set_thread_area`].
9 ///
10 /// [`set_thread_area`]: crate::runtime::set_thread_area
11 #[cfg(target_arch = "x86")]
12 pub type UserDesc = linux_raw_sys::general::user_desc;
13
startup_tls_info() -> StartupTlsInfo14 pub(crate) fn startup_tls_info() -> StartupTlsInfo {
15 let mut base = null();
16 let mut tls_phdr = null();
17 let mut stack_size = 0;
18
19 let phdrs = exe_phdrs_slice();
20
21 // Safety: We assume the phdr array pointer and length the kernel provided
22 // to the process describe a valid phdr array.
23 unsafe {
24 for phdr in phdrs {
25 match phdr.p_type {
26 PT_PHDR => base = phdrs.as_ptr().cast::<u8>().offset(-(phdr.p_vaddr as isize)),
27 PT_TLS => tls_phdr = phdr,
28 PT_GNU_STACK => stack_size = phdr.p_memsz,
29 _ => {}
30 }
31 }
32
33 StartupTlsInfo {
34 addr: base.cast::<u8>().add((*tls_phdr).p_vaddr).cast(),
35 mem_size: (*tls_phdr).p_memsz,
36 file_size: (*tls_phdr).p_filesz,
37 align: (*tls_phdr).p_align,
38 stack_size,
39 }
40 }
41 }
42
43 /// The values returned from [`startup_tls_info`].
44 ///
45 /// [`startup_tls_info`]: crate::runtime::startup_tls_info
46 pub struct StartupTlsInfo {
47 /// The base address of the TLS segment.
48 pub addr: *const c::c_void,
49 /// The size of the memory region.
50 pub mem_size: usize,
51 /// The size beyond which all memory is zero-initialized.
52 pub file_size: usize,
53 /// The required alignment for the TLS segment.
54 pub align: usize,
55 /// The requested minimum size for stacks.
56 pub stack_size: usize,
57 }
58