use super::{super::ModuleKey, ResolveRequest};
use crate::{
Result, arch::NativeArch, image::ModuleHandle, input::ElfReader, relocation::RelocationArch,
tls::TlsResolver,
};
use alloc::{boxed::Box, vec::Vec};
pub(crate) enum ResolvedKind<'cfg, Arch: RelocationArch = NativeArch, Tls: TlsResolver<Arch> = ()> {
Load(Box<dyn ElfReader + 'cfg>),
Module {
module: ModuleHandle<Arch, Tls>,
deps: Vec<ResolvedDependency<'cfg, Arch, Tls>>,
},
}
pub struct ResolvedKey<'cfg, Arch: RelocationArch = NativeArch, Tls: TlsResolver<Arch> = ()> {
kind: ResolvedKind<'cfg, Arch, Tls>,
pinned: bool,
}
pub struct ResolvedDependency<'cfg, Arch: RelocationArch = NativeArch, Tls: TlsResolver<Arch> = ()>
{
pub(crate) key: ModuleKey,
pub(crate) resolved: ResolvedKey<'cfg, Arch, Tls>,
}
impl<'cfg, Arch: RelocationArch, Tls: TlsResolver<Arch>> ResolvedDependency<'cfg, Arch, Tls> {
#[inline]
pub fn new(key: impl Into<ModuleKey>, resolved: ResolvedKey<'cfg, Arch, Tls>) -> Self {
Self {
key: key.into(),
resolved,
}
}
}
impl<'cfg, Arch: RelocationArch, Tls: TlsResolver<Arch>> ResolvedKey<'cfg, Arch, Tls> {
#[inline]
pub fn load(reader: impl ElfReader + 'cfg) -> Self {
Self {
kind: ResolvedKind::Load(Box::new(reader)),
pinned: false,
}
}
#[inline]
pub fn module(
module: impl Into<ModuleHandle<Arch, Tls>>,
deps: impl Into<Vec<ResolvedDependency<'cfg, Arch, Tls>>>,
) -> Self {
Self {
kind: ResolvedKind::Module {
module: module.into(),
deps: deps.into(),
},
pinned: false,
}
}
#[inline]
pub const fn pinned(mut self) -> Self {
self.pinned = true;
self
}
#[inline]
pub(crate) fn into_parts(self) -> (ResolvedKind<'cfg, Arch, Tls>, bool) {
(self.kind, self.pinned)
}
}
pub trait KeyResolver<Arch: RelocationArch = NativeArch, Tls: TlsResolver<Arch> = ()> {
type Root;
fn root_key<'a>(&self, root: &'a Self::Root) -> &'a str;
fn resolve<'cfg>(
&self,
req: ResolveRequest<'_, Self::Root>,
) -> Result<ResolvedKey<'cfg, Arch, Tls>>;
}