use crate::{
Result,
elf::{ElfLayout, ElfPhdr, Lifecycle, NativeElfLayout},
input::Path,
segment::ElfSegments,
sync::Arc,
};
use alloc::boxed::Box;
pub struct LoadHookContext<'a, L: ElfLayout = NativeElfLayout> {
path: &'a Path,
phdr: &'a ElfPhdr<L>,
segments: &'a ElfSegments,
}
impl<'a, L: ElfLayout> LoadHookContext<'a, L> {
pub(crate) fn new(path: &'a Path, phdr: &'a ElfPhdr<L>, segments: &'a ElfSegments) -> Self {
Self {
path,
phdr,
segments,
}
}
pub fn path(&self) -> &Path {
self.path
}
pub fn phdr(&self) -> &ElfPhdr<L> {
self.phdr
}
pub fn segments(&self) -> &ElfSegments {
self.segments
}
}
pub trait LoadHook<L: ElfLayout = NativeElfLayout> {
fn call<'a>(&mut self, ctx: &'a LoadHookContext<'a, L>) -> Result<()>;
}
impl<L, F> LoadHook<L> for F
where
L: ElfLayout,
F: for<'a> FnMut(&'a LoadHookContext<'a, L>) -> Result<()>,
{
fn call<'a>(&mut self, ctx: &'a LoadHookContext<'a, L>) -> Result<()> {
(self)(ctx)
}
}
impl<L: ElfLayout> LoadHook<L> for () {
fn call<'a>(&mut self, _ctx: &'a LoadHookContext<'a, L>) -> Result<()> {
Ok(())
}
}
pub trait LifecycleHandler: Send + Sync {
fn call(&self, ctx: &Lifecycle<'_>);
}
impl<F> LifecycleHandler for F
where
F: Fn(&Lifecycle<'_>) + Send + Sync,
{
fn call(&self, ctx: &Lifecycle<'_>) {
(self)(ctx)
}
}
pub(crate) type DynLifecycleHandler = Arc<Box<dyn LifecycleHandler>>;