Skip to content

Commit 51c0452

Browse files
committed
feat(env): don't use external TLS info structure
1 parent 7f362d0 commit 51c0452

4 files changed

Lines changed: 40 additions & 39 deletions

File tree

src/env/executable.rs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
use core::alloc::Layout;
12
use core::ops::Range;
23
use core::{ptr, slice};
34

45
use elf::abi;
56
use elf::file::Elf64_Ehdr;
67
use elf::segment::Elf64_Phdr;
7-
use hermit_entry::boot_info::TlsInfo;
88

99
pub fn executable_ptr_range() -> Range<*mut ()> {
1010
executable_start()..executable_end()
@@ -60,22 +60,34 @@ fn executable_end() -> *mut () {
6060
(&raw mut _end).cast::<()>()
6161
}
6262

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

67-
let phdrs = unsafe { ehdr.phdrs() };
68-
let tls_phdr = phdrs.iter().find(|phdr| phdr.p_type == abi::PT_TLS)?;
69-
let executable_start = executable_ptr_range().start.expose_provenance() as u64;
78+
let start = usize::try_from(executable_start + tls_phdr.p_vaddr).unwrap();
79+
let filesz = usize::try_from(tls_phdr.p_filesz).unwrap();
80+
let memsz = usize::try_from(tls_phdr.p_memsz).unwrap();
81+
let align = usize::try_from(tls_phdr.p_align).unwrap();
7082

71-
let tls_info = TlsInfo {
72-
start: executable_start + tls_phdr.p_vaddr,
73-
filesz: tls_phdr.p_filesz,
74-
memsz: tls_phdr.p_memsz,
75-
align: tls_phdr.p_align,
76-
};
83+
let start = ptr::with_exposed_provenance(start);
84+
let image = unsafe { slice::from_raw_parts(start, filesz) };
7785

78-
Some(tls_info)
86+
let layout = Layout::from_size_align(memsz, align).unwrap();
87+
assert_eq!(layout.pad_to_align(), layout);
88+
89+
Some(Self { image, layout })
90+
}
7991
}
8092

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

src/env/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use hashbrown::hash_map::Iter;
1414
use hermit_entry::boot_info::{BootInfo, PlatformInfo, RawBootInfo};
1515
use hermit_sync::OnceCell;
1616

17-
pub(crate) use self::executable::{executable_ptr_range, tls_info};
17+
pub(crate) use self::executable::{TlsInfo, executable_ptr_range};
1818
use crate::arch::kernel;
1919
pub(crate) use crate::arch::kernel::get_ram_address;
2020

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ fn synch_all_cores() {
232232
/// Entry Point of Hermit for the Boot Processor
233233
#[cfg(target_os = "none")]
234234
fn boot_processor_main() -> ! {
235+
use crate::env::TlsInfo;
236+
235237
// Initialize the kernel and hardware.
236238
hermit_sync::Lazy::force(&console::CONSOLE);
237239
unsafe {
@@ -270,7 +272,7 @@ fn boot_processor_main() -> ! {
270272
}
271273
let bss_ptr = &raw mut __bss_start;
272274
info!("BSS starts at {bss_ptr:p}");
273-
info!("tls_info = {:#x?}", env::tls_info());
275+
info!("tls_info = {:#x?}", TlsInfo::from_env());
274276
arch::boot_processor_init();
275277

276278
#[cfg(not(target_arch = "riscv64"))]

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)