diff --git a/src/context/memory.rs b/src/context/memory.rs index 68fe756daa170c87a5e024c4a4e0e32a21ef403b..67798c6108023b327e2c877581747431d8540f15 100644 --- a/src/context/memory.rs +++ b/src/context/memory.rs @@ -323,5 +323,17 @@ impl Drop for Memory { pub struct Tls { pub master: VirtualAddress, pub file_size: usize, - pub mem: Memory + pub mem: Memory, + pub offset: usize, +} + +impl Tls { + /// Load TLS data from master + pub unsafe fn load(&mut self) { + intrinsics::copy( + self.master.get() as *const u8, + (self.mem.start_address().get() + self.offset) as *mut u8, + self.file_size + ); + } } diff --git a/src/syscall/process.rs b/src/syscall/process.rs index c9125c3e1db9a39a620207623743cf4f7e363c49..4c6249110f4851fe61a3766fe8c236e8d2329b4c 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -225,13 +225,12 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { tls.mem.size(), entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE, true - ) + ), + offset: tls.offset, }; unsafe { - intrinsics::copy(tls.master.get() as *const u8, - new_tls.mem.start_address().get() as *mut u8, - tls.file_size); + new_tls.load(); } new_tls.mem.remap(tls.mem.flags()); @@ -668,15 +667,18 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> { entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE, true ); - - unsafe { *(::USER_TCB_OFFSET as *mut usize) = ::USER_TLS_OFFSET + segment.p_memsz as usize; } + let rounded_size = ((segment.p_memsz + 4095)/4096) * 4096; + let rounded_offset = rounded_size - segment.p_memsz; + let tcb_offset = ::USER_TLS_OFFSET + rounded_size as usize; + unsafe { *(::USER_TCB_OFFSET as *mut usize) = tcb_offset; } context.image.push(memory.to_shared()); tls_option = Some(( VirtualAddress::new(segment.p_vaddr as usize), segment.p_filesz as usize, - segment.p_memsz as usize + rounded_size as usize, + rounded_offset as usize, )); } } @@ -706,8 +708,8 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> { )); // Map TLS - if let Some((master, file_size, size)) = tls_option { - let tls = context::memory::Tls { + if let Some((master, file_size, size, offset)) = tls_option { + let mut tls = context::memory::Tls { master: master, file_size: file_size, mem: context::memory::Memory::new( @@ -715,14 +717,12 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> { size, entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE, true - ) + ), + offset: offset, }; unsafe { - // Copy file data - intrinsics::copy(master.get() as *const u8, - tls.mem.start_address().get() as *mut u8, - file_size); + tls.load(); } context.tls = Some(tls);