Skip to content

Commit 2932d6c

Browse files
committed
feat(env): don't use external TLS info structure
1 parent 4b307dd commit 2932d6c

3 files changed

Lines changed: 38 additions & 38 deletions

File tree

src/env/executable.rs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,31 +56,44 @@ fn executable_end() -> *mut () {
5656

5757
#[cfg(not(feature = "common-os"))]
5858
pub mod tls {
59+
use core::alloc::Layout;
5960
use core::{ptr, slice};
6061

6162
use elf::abi;
6263
use elf::file::Elf64_Ehdr;
6364
use elf::segment::Elf64_Phdr;
64-
use hermit_entry::boot_info::TlsInfo;
6565

6666
use crate::env;
6767

68-
pub fn tls_info() -> Option<TlsInfo> {
69-
let ehdr = ehdr();
70-
ehdr.sanity_check_ident();
68+
#[derive(Debug)]
69+
pub struct TlsInfo<'a> {
70+
pub image: &'a [u8],
71+
pub layout: Layout,
72+
}
73+
74+
impl TlsInfo<'_> {
75+
pub fn from_env() -> Option<Self> {
76+
let ehdr = ehdr();
77+
ehdr.sanity_check_ident();
78+
79+
let phdrs = unsafe { ehdr.phdrs() };
80+
let tls_phdr = phdrs.iter().find(|phdr| phdr.p_type == abi::PT_TLS)?;
81+
let executable_start = env::executable_ptr_range().start.expose_provenance() as u64;
7182

72-
let phdrs = unsafe { ehdr.phdrs() };
73-
let tls_phdr = phdrs.iter().find(|phdr| phdr.p_type == abi::PT_TLS)?;
74-
let executable_start = env::executable_ptr_range().start.expose_provenance() as u64;
83+
let start = usize::try_from(executable_start + tls_phdr.p_vaddr).unwrap();
84+
let filesz = usize::try_from(tls_phdr.p_filesz).unwrap();
85+
let memsz = usize::try_from(tls_phdr.p_memsz).unwrap();
86+
let align = usize::try_from(tls_phdr.p_align).unwrap();
7587

76-
let tls_info = TlsInfo {
77-
start: executable_start + tls_phdr.p_vaddr,
78-
filesz: tls_phdr.p_filesz,
79-
memsz: tls_phdr.p_memsz,
80-
align: tls_phdr.p_align,
81-
};
88+
let start = ptr::with_exposed_provenance(start);
89+
let image = unsafe { slice::from_raw_parts(start, filesz) };
8290

83-
Some(tls_info)
91+
let layout = Layout::from_size_align(memsz, align)
92+
.unwrap()
93+
.pad_to_align();
94+
95+
Some(Self { image, layout })
96+
}
8497
}
8598

8699
fn ehdr() -> &'static Elf64_Ehdr {

src/env/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use hermit_sync::OnceCell;
1616

1717
pub(crate) use self::executable::executable_ptr_range;
1818
#[cfg(not(feature = "common-os"))]
19-
pub(crate) use self::executable::tls::tls_info;
19+
pub(crate) use self::executable::tls::TlsInfo;
2020
use crate::arch::kernel;
2121
pub(crate) use crate::arch::kernel::get_ram_address;
2222

src/scheduler/task/tls.rs

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@
2020
2121
use core::alloc::Layout;
2222
use core::mem::{self, MaybeUninit};
23-
use core::{ptr, slice};
24-
25-
use hermit_entry::boot_info::TlsInfo;
23+
use core::ptr;
2624

2725
use self::allocation::Allocation;
26+
use crate::env::TlsInfo;
2827

2928
/// Thread-local storage data structures.
3029
pub struct Tls {
@@ -51,22 +50,8 @@ struct Tcb {
5150
}
5251

5352
impl Tls {
54-
unsafe fn new(tls_info: TlsInfo) -> Self {
55-
let start = usize::try_from(tls_info.start).unwrap();
56-
let filesz = usize::try_from(tls_info.filesz).unwrap();
57-
let memsz = usize::try_from(tls_info.memsz).unwrap();
58-
let align = usize::try_from(tls_info.align).unwrap();
59-
60-
// Get TLS initialization image
61-
let tls_init_image = {
62-
let start = ptr::with_exposed_provenance(start);
63-
unsafe { slice::from_raw_parts(start, filesz) }
64-
};
65-
53+
unsafe fn new(tls_info: TlsInfo<'_>) -> Self {
6654
let tcb_layout = Layout::new::<Tcb>().pad_to_align();
67-
let data_layout = Layout::from_size_align(memsz, align)
68-
.unwrap()
69-
.pad_to_align();
7055

7156
let (layout, tls_offset, tcb_offset) =
7257
if cfg!(any(target_arch = "aarch64", target_arch = "riscv64")) {
@@ -79,7 +64,7 @@ impl Tls {
7964
assert_eq!(mem::offset_of!(Tcb, dtv), 0);
8065

8166
// In variant I, the TLS data comes after the TCB.
82-
let (tls_layout, data_offset) = tcb_layout.extend(data_layout).unwrap();
67+
let (tls_layout, data_offset) = tcb_layout.extend(tls_info.layout).unwrap();
8368
(tls_layout.pad_to_align(), data_offset, 0)
8469
} else if cfg!(target_arch = "x86_64") {
8570
// x86-64 uses TLS data structures variant II.
@@ -92,7 +77,7 @@ impl Tls {
9277
assert_eq!(mem::offset_of!(Tcb, thread_ptr), 0);
9378

9479
// In Variant II, the TCB comes after the TLS data.
95-
let (tls_layout, tcb_offset) = data_layout.extend(tcb_layout).unwrap();
80+
let (tls_layout, tcb_offset) = tls_info.layout.extend(tcb_layout).unwrap();
9681
(tls_layout.pad_to_align(), 0, tcb_offset)
9782
} else {
9883
unimplemented!()
@@ -101,10 +86,12 @@ impl Tls {
10186
let mut block = Allocation::new(layout).unwrap();
10287

10388
// Initialize the beginning of the TLS block with the TLS initialization image.
104-
block.as_mut_slice()[tls_offset..][..tls_init_image.len()].copy_from_slice(tls_init_image);
89+
let image =
90+
unsafe { &*(ptr::from_ref(tls_info.image) as *const [core::mem::MaybeUninit<u8>]) };
91+
block.as_mut_slice()[tls_offset..][..tls_info.image.len()].copy_from_slice(image);
10592

10693
// Fill the rest of the TLS block with zeros.
107-
block.as_mut_slice()[tls_offset..][tls_init_image.len()..data_layout.size()]
94+
block.as_mut_slice()[tls_offset..][tls_info.image.len()..tls_info.layout.size()]
10895
.fill(MaybeUninit::new(0));
10996

11097
let thread_ptr = if cfg!(target_arch = "riscv64") {
@@ -138,7 +125,7 @@ impl Tls {
138125
}
139126

140127
pub fn from_env() -> Option<Self> {
141-
let tls_info = crate::env::tls_info()?;
128+
let tls_info = TlsInfo::from_env()?;
142129
let this = unsafe { Self::new(tls_info) };
143130
Some(this)
144131
}

0 commit comments

Comments
 (0)