Merge branch 'master' into 'master'
tcb: fix non x86 See merge request redox-os/relibc!650
This commit is contained in:
+4
-4
@@ -662,8 +662,7 @@ impl Linker {
|
||||
// We are now loading the main program or its dependencies. The TLS for all initially
|
||||
// loaded objects reside in the static TLS block. Depending on the architecture, the
|
||||
// static TLS block is either placed before the TP or after the TP.
|
||||
let tcb_ptr = tcb as *mut Tcb;
|
||||
|
||||
//
|
||||
// Setup the DTVs.
|
||||
tcb.setup_dtv(tcb_masters.len());
|
||||
|
||||
@@ -677,7 +676,7 @@ impl Linker {
|
||||
|
||||
if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
|
||||
// Below the TP
|
||||
tcb.dtv_mut()[dtv_idx] = tcb_ptr.cast::<u8>().sub(obj.tls_offset);
|
||||
tcb.dtv_mut()[dtv_idx] = tcb.tls_end.sub(obj.tls_offset);
|
||||
} else {
|
||||
// FIMXE(andypython): Make it above the TP
|
||||
//
|
||||
@@ -685,7 +684,8 @@ impl Linker {
|
||||
// tcb_ptr.add(1).cast::<u8>().add(obj.tls_offset);
|
||||
//
|
||||
// FIXME(andypython): https://gitlab.redox-os.org/redox-os/relibc/-/merge_requests/570#note_35788
|
||||
tcb.dtv_mut()[dtv_idx] = tcb.tls_end.sub(tcb.tls_len).add(obj.tls_offset);
|
||||
let tls_start = tcb.tls_end.sub(tcb.tls_len);
|
||||
tcb.dtv_mut()[dtv_idx] = tls_start.add(obj.tls_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+70
-17
@@ -126,22 +126,22 @@ impl Tcb {
|
||||
if self.tls_end.is_null() || self.tls_len == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(slice::from_raw_parts_mut(
|
||||
self.tls_end.offset(-(self.tls_len as isize)),
|
||||
self.tls_len,
|
||||
))
|
||||
let tls_start = self.tls_end.sub(self.tls_len);
|
||||
Some(slice::from_raw_parts_mut(tls_start, self.tls_len))
|
||||
}
|
||||
}
|
||||
|
||||
/// The initial images for TLS
|
||||
pub unsafe fn masters(&self) -> Option<&'static mut [Master]> {
|
||||
pub fn masters(&self) -> Option<&'static mut [Master]> {
|
||||
if self.masters_ptr.is_null() || self.masters_len == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(slice::from_raw_parts_mut(
|
||||
self.masters_ptr,
|
||||
self.masters_len / mem::size_of::<Master>(),
|
||||
))
|
||||
Some(unsafe {
|
||||
slice::from_raw_parts_mut(
|
||||
self.masters_ptr,
|
||||
self.masters_len / mem::size_of::<Master>(),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,19 +150,16 @@ impl Tcb {
|
||||
//TODO: Complain if masters or tls exist without the other
|
||||
if let Some(tls) = self.tls() {
|
||||
if let Some(masters) = self.masters() {
|
||||
for (i, master) in masters
|
||||
for master in masters
|
||||
.iter()
|
||||
.skip(self.num_copied_masters)
|
||||
.filter(|m| m.len > 0)
|
||||
.enumerate()
|
||||
.filter(|master| master.len != 0)
|
||||
{
|
||||
let range = if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
|
||||
// x86 TLS layout is backwards
|
||||
// x86{_64} TLS layout is backwards
|
||||
self.tls_len - master.offset..self.tls_len - master.offset + master.len
|
||||
} else {
|
||||
//TODO: fix aarch64 TLS layout when there is more than one master
|
||||
assert_eq!(i, 0, "aarch64 TLS layout only supports one master");
|
||||
0..master.len
|
||||
master.offset..master.offset + master.len
|
||||
};
|
||||
if let Some(tls_data) = tls.get_mut(range) {
|
||||
let data = master.data();
|
||||
@@ -211,7 +208,22 @@ impl Tcb {
|
||||
|
||||
pub fn setup_dtv(&mut self, n: usize) {
|
||||
if self.dtv_ptr.is_null() {
|
||||
let dtv = vec![ptr::null_mut(); n];
|
||||
let mut dtv = vec![ptr::null_mut(); n];
|
||||
|
||||
if let Some(masters) = self.masters() {
|
||||
for (i, master) in masters.iter().enumerate() {
|
||||
let tls = unsafe { self.tls().unwrap() };
|
||||
let offset = if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
|
||||
// x86{_64} TLS layout is backwards
|
||||
self.tls_len - master.offset
|
||||
} else {
|
||||
master.offset
|
||||
};
|
||||
|
||||
dtv[i] = unsafe { tls.as_mut_ptr().add(offset) };
|
||||
}
|
||||
}
|
||||
|
||||
let (ptr, len, _) = dtv.into_raw_parts();
|
||||
|
||||
self.dtv_ptr = ptr;
|
||||
@@ -255,6 +267,47 @@ impl Tcb {
|
||||
}
|
||||
|
||||
/// OS specific code to create a new TLS and TCB - Linux and Redox
|
||||
///
|
||||
/// Memory layout:
|
||||
///
|
||||
/// ```text
|
||||
/// 0 page_size size (size + page_size * 2)
|
||||
/// |----------|---------------------------|----------|
|
||||
/// +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
/// | ABI Page | TLS | TCB Page |
|
||||
/// +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
/// ^ $tp (aarch64) ^ $tp (x86_64)
|
||||
/// ```
|
||||
///
|
||||
/// `$tp` refers to the architecture specific thread pointer.
|
||||
///
|
||||
/// **Note**: On x86{_64}, the TLS layout is backwards (i.e. the first byte of the TLS is at
|
||||
/// the end of the TLS region).
|
||||
///
|
||||
/// ABI page layout for aarch64:
|
||||
/// ```text
|
||||
/// 0 4096
|
||||
/// +---------------------+
|
||||
/// | ABI Page |
|
||||
/// +---------------------+
|
||||
/// ^
|
||||
/// |
|
||||
/// +-------> (page_size - 16): pointer to the start of the TCB page
|
||||
/// ```
|
||||
///
|
||||
/// ABI page layout for riscv64:
|
||||
///
|
||||
/// ```text
|
||||
/// 0 4096
|
||||
/// +---------------------+
|
||||
/// | ABI Page |
|
||||
/// +---------------------+
|
||||
/// ^
|
||||
/// |
|
||||
/// +-------> (page_size - 8): pointer to the start of the TCB page
|
||||
/// ```
|
||||
///
|
||||
/// For x86_64, the ABI page is not used.
|
||||
#[cfg(any(target_os = "linux", target_os = "redox"))]
|
||||
unsafe fn os_new(
|
||||
size: usize,
|
||||
|
||||
Reference in New Issue
Block a user