Expand description
§Relink
Relink is a high-performance, no_std-friendly ELF loader and runtime linker for Rust.
It maps ELF images from files or memory, performs relocations at runtime, and exposes
typed symbol lookups with Rust lifetimes.
§Start with Loader
- Use
Loader::loadto auto-detect whether the input is a dylib, executable, or relocatable object. - Use
Loader::scanto classify executable or dynamic ELF metadata without mapping it. - Use
Loader::load_dyliborLoader::load_execwhen you want strict type checks. - Use
Loader::load_dynamicwhen you want anyPT_DYNAMICimage, including a dynamicET_EXEC. - Use
Loader::scanandLoader::load_scanned_dynamicto split dynamic metadata discovery from mapping. - Use
Loader::load_objectto loadET_RELobject files when theobjectfeature is enabled. - Inputs can come from file paths,
input::Path/input::PathBuf, raw bytes,input::ElfFile, orinput::ElfBinary.
§Highlights
- Safer symbol lifetimes. Typed symbols borrow the loaded image, so they cannot outlive the library that produced them.
- Hybrid linking. Compose
.so,.o, and synthetic modules at runtime withscope()andextend_scope(). - Explicit dependency loading. Build your own dependency policy with an
actual
Loader,linker::KeyResolver,Linker, andLinkContext. - Deep customization. Inject host or bridge symbols with
image::SyntheticModuleand intercept relocations with handlers. - Optional advanced features. TLS relocation handling, lazy binding, relocatable object loading, logging, and versioned symbol lookup are feature-gated.
§Example
use elf_loader::{
Loader, Relocator, Result,
image::{SyntheticSymbol, SyntheticModule},
};
extern "C" fn host_double(value: i32) -> i32 {
value * 2
}
fn main() -> Result<()> {
let host = SyntheticModule::new(
"__host",
[SyntheticSymbol::function("host_double", host_double as *const ())],
);
let lib = Relocator::new()
.run(Loader::new().load_dylib("path/to/plugin.so")?)
.scope([host])
.relocate()?;
let run = unsafe {
lib.get::<extern "C" fn(i32) -> i32>("run")
.expect("symbol `run` not found")
};
assert_eq!(run(21), 42);
Ok(())
}§Loading Dependencies With Linker
Use Linker::load when you want a reusable LinkContext
and resolver-driven DT_NEEDED dependency loading. The built-in
linker::SearchPathResolver covers the common filesystem search-path case;
implement linker::KeyResolver when dependencies come from memory,
package stores, or another registry.
use elf_loader::{
LinkContext, Linker, Result,
input::PathBuf,
linker::SearchPathResolver,
};
fn main() -> Result<()> {
let root = PathBuf::from("path/to/plugin.so");
let mut context: LinkContext<PathBuf, ()> = LinkContext::new();
let loaded = Linker::new()
.resolver(SearchPathResolver::new())
.load(&mut context, root)?;
let run = unsafe {
loaded
.get::<extern "C" fn() -> i32>("run")
.expect("symbol `run` not found")
};
let _ = run();
Ok(())
}§Observer Hooks
Observers are attached to a single loader or linker run, so reusable
Loader and Linker configuration can stay immutable while each run
decides which events to inspect or override.
use elf_loader::{
Loader, Result,
arch::NativeArch,
observer::{BeforeLoadEvent, LoadObserver},
relocation::RelocationArch,
};
struct TraceLoads;
impl LoadObserver for TraceLoads {
fn on_before_load(
&mut self,
event: BeforeLoadEvent<'_, (), <NativeArch as RelocationArch>::Layout>,
) -> Result<()> {
let _path = event.path();
let _is_dynamic = event.is_dynamic();
Ok(())
}
}
fn main() -> Result<()> {
let _raw = Loader::new()
.run()
.with_observer(TraceLoads)
.load_dylib("path/to/lib.so")?;
Ok(())
}§Feature Flags
tls(default): enables TLS relocation handling. For TLS-using modules, start fromLoader::with_default_tls_resolveror provide a custom TLS resolver.lazy-binding: enablesRelocator::lazyand PLT/GOT lazy binding.object: enablesLoader::load_objectand relocatable object (ET_REL) loading.version: enables version-aware symbol lookup viaElfCore::get_version.log,portable-atomic, anduse-syscall: optional integrations for diagnostics and specialized targets.
§More
- The
examplesdirectory covers loading from memory,Linker::load, scan-first linking, observer hooks, and object loading. - The crate currently targets
x86_64,x86,aarch64,arm,riscv64,riscv32, andloongarch64. - Relocatable object support is currently centered on
x86_64andriscv64.
Re-exports§
pub use error::Error;pub use linker::LinkContext;pub use linker::Linker;pub use linker::LinkerRun;pub use loader::Loader;pub use loader::LoaderRun;pub use relocation::Relocator;pub use relocation::RelocatorRun;
Modules§
- arch
- Architecture-specific definitions and relocation logic.
- elf
- ELF (Executable and Linkable Format) parsing and data structures.
- error
- Error types returned by Relink APIs.
- image
- Public image types returned by the loader and relocation pipeline.
- input
- ELF input traits and built-in data sources.
- lazy
- Lazy PLT binding support.
- linker
- Explicit linking and dependency-resolution primitives.
- loader
- Loading entry points and customization hooks.
- memory
- Virtual memory and mapped image abstractions.
- object
object - Relocatable-object loading, layout, and export helpers.
- observer
- Observer traits and event payloads for load and relocation hooks.
- os
- Operating system and environment abstractions.
- relocation
- Relocation configuration, symbol scopes, and binding policy.
- runtime
- Runtime execution abstractions for mapped images.
- tls
- Thread Local Storage (TLS) management.
Traits§
- Byte
Repr - Types that can be safely viewed from arbitrary bytes.
Type Aliases§
- Result
- A type alias for
Results returned byelf_loaderfunctions.