Mic92/formatelf
{ "createdAt": "2026-06-26T09:45:20Z", "defaultBranch": "main", "description": "Modify dynamic linker, RPATH and other ELF metadata of executables", "fullName": "Mic92/formatelf", "homepage": "", "language": "Rust", "name": "formatelf", "pushedAt": "2026-07-03T18:28:43Z", "stargazersCount": 5, "topics": [], "updatedAt": "2026-07-03T22:04:30Z", "url": "https://github.com/Mic92/formatelf"}formatelf
Section titled “formatelf”Status: beta, currently under testing in https://github.com/numtide/llm-agents.nix
A reimplementation of patchelf in Rust: modify the dynamic linker, RPATH, and other ELF metadata of executables and shared libraries.
It is CLI-compatible with patchelf and the Nix package installs a patchelf
symlink, so it works as a drop-in replacement.
Install
Section titled “Install”nix build github:Mic92/formatelf # result/bin/formatelf (+ patchelf symlink)nix run github:Mic92/formatelf -- --versionTo build without the patchelf symlink:
nix build --expr '(builtins.getFlake (toString ./.)).packages.x86_64-linux.default.override { patchelfSymlink = false; }'Without Nix:
cargo build --release # target/release/formatelfformatelf --set-interpreter /lib/ld-linux-x86-64.so.2 ./progformatelf --set-rpath '$ORIGIN/../lib' ./progformatelf --print-needed ./progformatelf --replace-needed libfoo.so.1 libbar.so.1 ./progRun formatelf --help for the full option list. The flags mirror patchelf,
including --set-interpreter, --set-rpath/--add-rpath/--shrink-rpath,
--add-needed/--remove-needed/--replace-needed, --set-soname,
--set-os-abi, --clear-symbol-version, --set-execstack/--clear-execstack,
--rename-dynamic-symbols, and the NixOS --build-resolution-cache.
Beyond patchelf
Section titled “Beyond patchelf”The read-only operations (--print-rpath, --print-needed,
--print-interpreter, --print-soname) work on binaries whose section
headers have been stripped, recovering the data from PT_DYNAMIC and
PT_INTERP. Reference patchelf refuses these outright.
Development
Section titled “Development”The flake’s dev shell provides the toolchain:
nix developcargo testcargo clippy --testsTests build their own ELF fixtures with zig cc on demand (no binaries are
committed). The differential tests compare output byte-for-byte against a
reference patchelf; they skip themselves when zig or the reference is absent.
PATCHELF_REFERENCE overrides the reference binary’s path.
Fuzzing
Section titled “Fuzzing”cargo-fuzz targets cover the read path (parse), the write path (mutate),
and the argument parser (cli). They build on stable via RUSTC_BOOTSTRAP:
RUSTC_BOOTSTRAP=1 cargo fuzz run parse -s noneLicense
Section titled “License”MIT