Fix dlsym of TLS variables

This commit is contained in:
Mateusz Tabaka
2020-12-30 18:14:53 +01:00
parent 261951bcba
commit 6497d71d2f
3 changed files with 31 additions and 8 deletions
+2
View File
@@ -358,12 +358,14 @@ impl DSO {
base: mmap.as_ptr() as usize,
value: sym.st_value as usize,
size: sym.st_size as usize,
sym_type: sym::st_type(sym.st_info),
}
} else {
Symbol {
base: 0,
value: sym.st_value as usize,
size: sym.st_size as usize,
sym_type: sym::st_type(sym.st_info),
}
};
} else {
+25 -4
View File
@@ -6,14 +6,18 @@ use alloc::{
};
use core::{cell::RefCell, mem::transmute, ptr};
use goblin::{
elf::{program_header, reloc, Elf},
elf::{program_header, reloc, sym::STT_TLS, Elf},
error::{Error, Result},
};
use crate::{
c_str::CString,
fs::File,
header::{fcntl, sys_mman, unistd::F_OK},
header::{
dl_tls::{__tls_get_addr, dl_tls_index},
fcntl, sys_mman,
unistd::F_OK,
},
io::Read,
platform::types::c_void,
};
@@ -32,6 +36,7 @@ pub struct Symbol {
pub value: usize,
pub base: usize,
pub size: usize,
pub sym_type: u8,
}
impl Symbol {
@@ -91,8 +96,24 @@ impl Linker {
pub fn get_sym(&self, lib_id: usize, name: &str) -> Option<*mut c_void> {
match self.objects.get(&lib_id) {
Some(obj) => obj.get_sym(name).map(|s| s.as_ptr()),
_ => None,
Some(obj) => {
return obj.get_sym(name).map(|s| {
if s.sym_type != STT_TLS {
s.as_ptr()
} else {
unsafe {
let mut tls_index = dl_tls_index {
ti_module: obj.tls_module_id as u64,
ti_offset: s.value as u64,
};
__tls_get_addr(&mut tls_index)
}
}
});
}
_ => {
return None;
}
}
}
+4 -4
View File
@@ -40,7 +40,7 @@ pub struct Tcb {
/// Size of the masters list in bytes (multiple of mem::size_of::<Master>())
pub masters_len: usize,
/// Index of last copied Master
pub last_master_copied: usize,
pub num_copied_masters: usize,
/// Pointer to dynamic linker
pub linker_ptr: *const Mutex<Linker>,
/// pointer to rust memory allocator structure
@@ -63,7 +63,7 @@ impl Tcb {
tcb_len: tcb_page.len(),
masters_ptr: ptr::null_mut(),
masters_len: 0,
last_master_copied: 0,
num_copied_masters: 0,
linker_ptr: ptr::null(),
mspace: 0,
},
@@ -114,7 +114,7 @@ impl Tcb {
if let Some(masters) = self.masters() {
for (i, master) in masters
.iter()
.skip(self.last_master_copied)
.skip(self.num_copied_masters)
.filter(|m| m.len > 0)
.enumerate()
{
@@ -135,7 +135,7 @@ impl Tcb {
return Err(Error::Malformed(format!("failed to copy tls master {}", i)));
}
}
self.last_master_copied = masters.len();
self.num_copied_masters = masters.len();
}
}