• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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