use crate::elf::{ElfLayout, ElfPhdr, ElfProgramType};
#[derive(Clone, Copy, Default)]
pub struct TlsInfo {
pub vaddr: usize,
pub filesz: usize,
pub memsz: usize,
pub align: usize,
pub image: &'static [u8],
}
impl core::fmt::Debug for TlsInfo {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("TlsInfo")
.field("vaddr", &format_args!("0x{:x}", self.vaddr))
.field("filesz", &self.filesz)
.field("memsz", &self.memsz)
.field("align", &self.align)
.field("image_len", &self.image.len())
.finish()
}
}
impl TlsInfo {
pub fn new<L: ElfLayout>(phdr: &ElfPhdr<L>, image: &'static [u8]) -> Self {
assert_eq!(phdr.program_type(), ElfProgramType::TLS);
Self {
vaddr: phdr.p_vaddr(),
filesz: phdr.p_filesz(),
memsz: phdr.p_memsz(),
align: phdr.p_align(),
image,
}
}
}
#[repr(transparent)]
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct TlsModuleId(usize);
impl TlsModuleId {
pub const RESERVED: Self = Self(0);
#[inline]
pub const fn new(raw: usize) -> Self {
Self(raw)
}
#[inline]
pub const fn get(self) -> usize {
self.0
}
#[inline]
pub const fn is_reserved(self) -> bool {
self.0 == Self::RESERVED.0
}
}
impl core::fmt::Display for TlsModuleId {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.fmt(f)
}
}
#[repr(transparent)]
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct TlsTpOffset(isize);
impl TlsTpOffset {
#[inline]
pub const fn new(raw: isize) -> Self {
Self(raw)
}
#[inline]
pub const fn get(self) -> isize {
self.0
}
}
impl core::fmt::Display for TlsTpOffset {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.fmt(f)
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct TlsIndex {
pub ti_module: TlsModuleId,
pub ti_offset: usize,
}
#[repr(C)]
#[derive(Debug)]
#[cfg_attr(not(feature = "tls"), allow(dead_code))]
pub(crate) struct TlsDescDynamicArg {
pub tls_get_addr: usize,
pub ti: TlsIndex,
}