use lief_ffi as ffi;
use crate::common::{AsFFI, FromFFI, into_optional};
use crate::to_slice;
use std::marker::PhantomData;
use crate::pe::DataDirectory;
use crate::pe::Section;
pub struct TLS<'a> {
ptr: cxx::UniquePtr<ffi::PE_TLS>,
_owner: PhantomData<&'a ffi::PE_Binary>,
}
impl std::fmt::Debug for TLS<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TLS")
.field("callbacks", &self.callbacks())
.field("addressof_index", &self.addressof_index())
.field("addressof_callbacks", &self.addressof_callbacks())
.field("sizeof_zero_fill", &self.sizeof_zero_fill())
.field("characteristics", &self.characteristics())
.finish()
}
}
impl TLS<'_> {
pub fn new() -> TLS<'static> {
TLS::from_ffi(lief_ffi::PE_TLS::create())
}
pub fn callbacks(&self) -> Vec<u64> {
Vec::from(self.ptr.callbacks().as_slice())
}
pub fn addressof_index(&self) -> u64 {
self.ptr.addressof_index()
}
pub fn addressof_callbacks(&self) -> u64 {
self.ptr.addressof_callbacks()
}
pub fn sizeof_zero_fill(&self) -> u32 {
self.ptr.sizeof_zero_fill()
}
pub fn characteristics(&self) -> u32 {
self.ptr.characteristics()
}
pub fn data_template(&self) -> &[u8] {
to_slice!(self.ptr.data_template());
}
pub fn addressof_raw_data(&self) -> (u64, u64) {
let vec = Vec::from(self.ptr.addressof_raw_data().as_slice());
if vec.len() != 2 {
return (0, 0);
}
(vec[0], vec[1])
}
pub fn section(&self) -> Option<Section<'_>> {
into_optional(self.ptr.section())
}
pub fn directory(&self) -> Option<DataDirectory<'_>> {
into_optional(self.ptr.data_directory())
}
pub fn add_callback(&mut self, addr: u64) -> &mut Self {
self.ptr.pin_mut().add_callback(addr);
self
}
pub fn set_callbacks(&mut self, callbacks: &[u64]) -> &mut Self {
unsafe {
self.ptr
.pin_mut()
.set_callbacks(callbacks.as_ptr(), callbacks.len());
}
self
}
pub fn set_addressof_index(&mut self, addr: u64) -> &mut Self {
self.ptr.pin_mut().set_addressof_index(addr);
self
}
pub fn set_addressof_callback(&mut self, addr: u64) -> &mut Self {
self.ptr.pin_mut().set_addressof_callback(addr);
self
}
pub fn set_sizeof_zero_fill(&mut self, size: u32) -> &mut Self {
self.ptr.pin_mut().set_sizeof_zero_fill(size);
self
}
pub fn set_characteristics(&mut self, characteristics: u32) -> &mut Self {
self.ptr.pin_mut().set_characteristics(characteristics);
self
}
pub fn set_data_template(&mut self, data: &[u8]) -> &mut Self {
unsafe {
self.ptr
.pin_mut()
.set_data_template(data.as_ptr(), data.len());
}
self
}
}
impl<'a> FromFFI<ffi::PE_TLS> for TLS<'a> {
fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_TLS>) -> Self {
TLS {
ptr,
_owner: PhantomData,
}
}
}
impl<'a> AsFFI<ffi::PE_TLS> for TLS<'a> {
fn as_ffi(&self) -> &ffi::PE_TLS {
self.ptr.as_ref().unwrap()
}
fn as_mut_ffi(&mut self) -> std::pin::Pin<&mut ffi::PE_TLS> {
self.ptr.pin_mut()
}
}