Skip to content

Load ELF files from memory/storage and efficient static/dynamic runtime linking.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

weizhiao/rust-elfloader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

license elf_loader on docs.rs Rust Build Status

elf loader

English | δΈ­ζ–‡

⚑ High-performance, cross-platform, no-std compatible ELF file loader ⚑

elf_loader can load various forms of ELF files from either memory or storage, and provides efficient runtime linking, including both static and dynamic linking. Whether you are developing an OS kernel, an embedded system, a JIT compiler, or an application that requires dynamic loading of ELF libraries, elf_loader delivers exceptional performance and flexibility.

Documentation | Examples


🎯 Core Use Cases

  • Operating System Development - As an ELF file loader in kernel
  • Dynamic Linker Implementation - Building a Rust version of the dynamic linker
  • Embedded Systems - Loading ELF dynamic libraries on resource-constrained devices
  • JIT Compilation Systems - As a low-level linker for Just-In-Time compilers
  • Cross-platform Development - Loading ELF dynamic libraries on Windows (see windows-elf-loader)

✨ Outstanding Features

πŸš€ Extreme Performance

Drawing on the implementation essence of musl and glibc's ld.so, combined with Rust's zero-cost abstractions, it delivers near-native performance:

# Performance benchmark comparison
elf_loader:new   36.478 Β΅s  
libloading:new   47.065 Β΅s

elf_loader:get   10.477 ns 
libloading:get   93.369 ns

πŸ“¦ Ultra Lightweight

The core implementation is extremely compact. The mini-loader built on elf_loader compiles to only 34KB!

πŸ”§ No-std Compatible

Fully supports no_std environments without enforcing libc or OS dependencies, seamlessly usable in kernels and embedded devices.

πŸ›‘οΈ Compile-time Safety

Utilizing Rust's lifetime mechanism to check ELF dependency relationships at compile-time, preventing dangling pointers and use-after-free errors:

// Compilation will fail if dependent libraries are dropped prematurely!
let liba = load_dylib!("liba.so")?;
let libb = load_dylib!("libb.so")?; // Depends on liba
// Dropping liba before libb will cause a compile error

πŸ”„ Advanced Features Support

  • Lazy Binding - Symbols resolved on first call, improving startup performance
  • RELR Relocation - Supports modern relative relocation format, reducing memory footprint
  • Async Interface - Provides asynchronous loading capabilities for high-concurrency scenarios
  • Highly Extensible - Easily port to new platforms through the trait system

πŸ—οΈ Architecture Design

Easy to Port

Just implement the Mmap and ElfObject traits for your platform to complete the port. Refer to our default implementation for quick start.

Hook Function Extension

Extend functionality through hook functions to implement custom loading logic. See dlopen-rs hook example.


πŸ“‹ Platform Support

Architecture Dynamic Linking Lazy Binding Static Linking Test Coverage
x86_64 βœ… βœ… βœ… CI
AArch64 βœ… βœ… TODO CI
RISC-V 64/32 βœ… βœ… TODO CI/Manual
LoongArch64 βœ… βœ… TODO CI
x86 βœ… βœ… TODO CI
ARM βœ… βœ… TODO CI

πŸš€ Quick Start

Add Dependency

[dependencies]
elf_loader = "0.1"

Basic Usage

use elf_loader::load_dylib;
use std::collections::HashMap;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Provide symbols required by the dynamic library
    let mut symbols = HashMap::new();
    symbols.insert("print", print as *const ());
    
    let pre_find = |name: &str| -> Option<*const ()> {
        symbols.get(name).copied()
    };

    // Load and relocate dynamic library
    let lib = load_dylib!("target/libexample.so")?
        .easy_relocate([].iter(), &pre_find)?;
    
    // Call function in the library
    let func = unsafe { lib.get::<fn() -> i32>("example_function")? };
    println!("Result: {}", func());
    
    Ok(())
}

fn print(s: &str) {
    println!("{}", s);
}

βš™οΈ Feature Flags

Feature Description
use-syscall Use Linux system calls as backend
version Use version information when resolving symbols
log Enable logging output
rel Use REL as relocation type
portable-atomic Support targets without native pointer size atomic operations

Note: Disable the use-syscall feature in environments without an operating system.


πŸ’‘ System Requirements

  • Minimum Rust Version: 1.88.0+
  • Supported Platforms: All major architectures (see platform support table)

🀝 Contribution and Support

We warmly welcome community contributions! Whether it's improving core functionality, adding examples, perfecting documentation, or fixing issues, your participation will be highly appreciated.

  • Issue Reporting: GitHub Issues
  • Feature Requests: Welcome new feature suggestions
  • Code Contribution: Submit Pull Requests

If this project is helpful to you, please give us a ⭐ to show your support!

🎈Contributors

Contributors

Start using elf_loader now to bring efficient ELF loading capabilities to your project! πŸŽ‰

About

Load ELF files from memory/storage and efficient static/dynamic runtime linking.

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published

Languages