weizhiao
rust-dynlinker
Rust

A dynamic linker fully implemented in Rust.

Last updated Jun 24, 2026
84
Stars
12
Forks
5
Issues
0
Stars/day
Attention Score
43
Language breakdown
Rust 98.4%
Python 1.5%
Shell 0.2%
โ–ธ Files click to expand
README

dlopen-rs

Crates.io Downloads Docs.rs Build Status MSRV License

A pure-Rust ELF dynamic linker, dlopen compatibility layer, and experimental Linux rtld.

English | ็ฎ€ไฝ“ไธญๆ–‡

dlopen-rs provides a Rust-friendly dynamic library loading API and exports libc-compatible entry points such as dlopen, dlsym, dladdr, and dliteratephdr. The project moves ELF loading, dependency resolution, relocation, symbol lookup, and TLS management into Rust, while steadily growing an rtld implementation that can eventually replace glibc ld.so.

Capabilities

  • Dynamic loading: Load ELF shared objects from paths or in-memory bytes.
  • Dependency resolution: Handle DT_NEEDED, RPATH, RUNPATH, ld.so.cache, and common system search paths.
  • Symbol lookup: Provide Rust APIs and C ABI entry points, including global lookup, dependency scopes, RTLDNEXT, and RTLDDEFAULT.
  • Relocation: Support regular dynamic relocations, PLT/GOT relocation, lazy binding, and RELR.
  • TLS: Support dynamic TLS, static TLS registration, and initial-thread TLS needed during rtld startup.
  • no_std: Run the core loading path without std, with an optional Linux syscall backend via use-syscall.
  • Replacement rtld: Build an experimental ELF interpreter that advertises itself as ld-linux-x86-64.so.2.

Project Status

| Area | Status | | --- | --- | | Rust ElfLibrary API | Usable | | libc-compatible dlopen/dlsym/dladdr/dliteratephdr | Usable | | LD_PRELOAD compatibility library | Usable | | no_std + syscall loading path | Usable, still being refined | | Replacement rtld | Experimental, focused on x86_64 Linux/glibc compatibility |

Installation

For regular Rust programs:

[dependencies]
dlopen-rs = "0.8.0"

For no_std with the syscall backend:

[dependencies]
dlopen-rs = { version = "0.8.0", default-features = false, features = ["use-syscall"] }

Rust API Example

Build the example shared object first:

cargo build --release -p example_dylib

Then run the dlopen-rs example:

cargo run --release --example dlopen

Core usage:

use dlopen_rs::{ElfLibrary, OpenFlags, Result};

fn main() -> Result<()> { let lib = ElfLibrary::dlopen("./target/release/libexample.so", OpenFlags::RTLD_LAZY)?; let add = unsafe { lib.get::<fn(i32, i32) -> i32>("add")? };

println!("add(1, 1) = {}", add(1, 1)); Ok(()) }

LD_PRELOAD Compatibility Library

The cdylib crate builds a libc dlopen-family compatibility library:

cargo build --release -p cdylib
cargo build --release -p example_dylib
cargo build --release --example preload

RUST_LOG=trace \ LD_PRELOAD=./target/release/libdlopen.so \ ./target/release/examples/preload

This is useful for checking how well dlopen-rs can interpose existing dlopen/dlsym calls.

Replacement rtld

The rtld crate builds an experimental ELF interpreter intended to grow into a replacement for glibc ld-linux-x86-64.so.2:

cargo build-rtld

Artifacts are written to:

target/x86_64-unknown-linux-none/release/librtld.so
target/x86_64-unknown-linux-none/release/ld-linux-x86-64.so.2

This path uses x8664-unknown-linux-none, -Z build-std=core,alloc,compilerbuiltins, and custom linker arguments. Use a nightly toolchain, or another toolchain capable of -Z build-std, when building this target.

Development Commands

The repository defines Cargo aliases that keep host/std checks separate from rtld/no_std checks:

cargo check-host
cargo check-rtld
cargo build-rtld

Common validation set:

cargo check-host
cargo check-rtld
cargo check --no-default-features --lib
cargo check --no-default-features --features use-syscall --lib
cargo test --test rtldartifact rtldartifacthasinterpreter_shape

Feature Flags

| Feature | Default | Description | | --- | --- | --- | | std | Yes | Enables standard library integration, host initialization, and ctor support. | | use-syscall | No | Uses the Linux syscall backend, mainly for no_std and rtld paths. | | version | No | Enables ELF symbol version support. |

Architecture Support

| Architecture | Dynamic Loading | Lazy Binding | Replacement rtld | | --- | --- | --- | --- | | x86_64 Linux | Supported | Supported | Experimental | | aarch64 | Supported | Supported | Not enabled | | riscv64 | Supported | Some paths still being validated | Not enabled |

Repository Layout

src/              Rust API, C ABI, loader/register core logic
src/rtld.rs       no_std rtld entry points and rtld-specific TLS glue
src/host_init.rs  std/host import of objects already loaded by the host ld.so
cdylib/           LD_PRELOAD compatibility library
rtld/             replacement ld.so artifact crate
rtld/impl/        no_std rtld implementation
example-dylib/    example shared object
examples/         API and LD_PRELOAD examples
tests/            integration tests and rtld artifact checks

License

Licensed under the Apache License 2.0.

Contributing

Issues and pull requests are welcome. For GDB/rdebug/linkmap related debugging notes, see TroubleshootingGdb.md.

Project Contributors


Minimum Supported Rust Version (MSRV): 1.93.0 or higher.

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท weizhiao/rust-dynlinker ยท Updated daily from GitHub