Skip to main content

Crate elf_loader

Crate elf_loader 

Source
Expand description

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

§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 with scope() and extend_scope().
  • Explicit dependency loading. Build your own dependency policy with an actual Loader, linker::KeyResolver, Linker, and LinkContext.
  • Deep customization. Inject host or bridge symbols with image::SyntheticModule and 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 from Loader::with_default_tls_resolver or provide a custom TLS resolver.
  • lazy-binding: enables Relocator::lazy and PLT/GOT lazy binding.
  • object: enables Loader::load_object and relocatable object (ET_REL) loading.
  • version: enables version-aware symbol lookup via ElfCore::get_version.
  • log, portable-atomic, and use-syscall: optional integrations for diagnostics and specialized targets.

§More

  • The examples directory 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, and loongarch64.
  • Relocatable object support is currently centered on x86_64 and riscv64.

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.
objectobject
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§

ByteRepr
Types that can be safely viewed from arbitrary bytes.

Type Aliases§

Result
A type alias for Results returned by elf_loader functions.