use crate::{
Result,
elf::ElfPhdr,
image::{ElfCore, LoadedCore, ModuleTls, RawDynamic},
input::Path,
lazy::{LazyBinder, SupportLazy},
memory::{HostRegion, RegionAccess, VmAddr},
observer::RelocationObserver,
relocation::{Relocatable, RelocateArgs, RelocationArch},
segment::ElfSegments,
tls::TlsResolver,
};
use core::fmt::Debug;
pub struct RawDylib<
D,
Arch = crate::arch::NativeArch,
R: RegionAccess = HostRegion,
Tls: TlsResolver<Arch> = (),
> where
D: 'static,
Arch: RelocationArch,
{
pub(crate) inner: RawDynamic<D, Arch, R, Tls>,
}
impl<D, Arch: RelocationArch, R: RegionAccess, Tls: TlsResolver<Arch>> Debug
for RawDylib<D, Arch, R, Tls>
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("RawDylib")
.field("name", &self.inner.name())
.field("needed_libs", &self.inner.needed_libs())
.finish()
}
}
impl<D: 'static, Arch: RelocationArch, R: RegionAccess, Tls: TlsResolver<Arch>> SupportLazy
for RawDylib<D, Arch, R, Tls>
{
}
impl<D: 'static, Arch: RelocationArch, R: RegionAccess, Tls: TlsResolver<Arch>> Relocatable<D>
for RawDylib<D, Arch, R, Tls>
{
type Output = LoadedCore<D, Arch, R, Tls>;
type Arch = Arch;
type Tls = Tls;
fn relocate<Obs, Binder>(
self,
args: RelocateArgs<'_, Arch, Tls, Obs, Binder>,
) -> Result<Self::Output>
where
Obs: RelocationObserver<Arch> + ?Sized,
Binder: LazyBinder<Arch> + ?Sized,
{
Relocatable::relocate(self.inner, args)
}
}
impl<D, Arch: RelocationArch, R: RegionAccess, Tls: TlsResolver<Arch>> RawDylib<D, Arch, R, Tls> {
#[inline]
pub fn from_dynamic(inner: RawDynamic<D, Arch, R, Tls>) -> Self {
Self { inner }
}
#[inline]
pub fn into_dynamic(self) -> RawDynamic<D, Arch, R, Tls> {
self.inner
}
#[inline]
pub fn entry(&self) -> usize {
self.inner.entry()
}
#[inline]
pub fn core_ref(&self) -> &ElfCore<D, Arch, R, Tls> {
self.inner.core_ref()
}
#[inline]
pub fn core(&self) -> ElfCore<D, Arch, R, Tls> {
self.inner.core()
}
#[inline]
pub fn into_core(self) -> ElfCore<D, Arch, R, Tls> {
self.inner.into_core()
}
#[inline]
pub fn is_lazy(&self) -> bool {
self.inner.is_lazy()
}
pub fn tls(&self) -> ModuleTls {
self.inner.tls()
}
#[inline]
pub fn rpath(&self) -> Option<&str> {
self.inner.rpath()
}
#[inline]
pub fn runpath(&self) -> Option<&str> {
self.inner.runpath()
}
#[inline]
pub fn soname(&self) -> Option<&str> {
self.inner.soname()
}
#[inline]
pub fn interp(&self) -> Option<&str> {
self.inner.interp()
}
#[inline]
pub fn path(&self) -> &Path {
self.inner.path()
}
#[inline]
pub fn name(&self) -> &str {
self.inner.name()
}
pub fn phdrs(&self) -> &[ElfPhdr<Arch::Layout>] {
self.inner.phdrs()
}
pub fn base(&self) -> VmAddr {
self.inner.base()
}
pub fn segments(&self) -> &ElfSegments<R> {
self.inner.segments()
}
pub fn needed_libs(&self) -> &[&str] {
self.inner.needed_libs()
}
pub fn user_data(&self) -> &D {
self.inner.user_data()
}
#[inline]
pub fn user_data_mut(&mut self) -> Option<&mut D> {
self.inner.user_data_mut()
}
}