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 14 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