An ahead-of-time binary translator that converts Linux applications to WebAssembly for both browser and WASI runtimes.
- No source code needed — Port pre-built binaries directly to Wasm, even when source code is unavailable
- Linux syscall emulation — Emulates Linux syscalls missing in Wasm environments (e.g.,
fork/execve), enabling unmodified Linux apps to run - Language-agnostic — No per-language compiler support needed; works with any language that compiles to Linux/ELF
fork/execvesupport- elfconv experimentally supports
fork()andexecve()system calls in Wasm in browsers. This enables running more complex Linux applications that rely on multi-process architectures, such as shells, build systems, and server applications that spawn child processes (e.g., GNU Bash + BusyBox on the demo page).
- elfconv experimentally supports
- Existing projects use CPU emulators (e.g., v86, container2wasm) to port Linux applications to Wasm, but incur severe slowdowns of 10× or more. In contrast, elfconv applies AOT compilation to translate machine code directly to LLVM IR, achieving much smaller performance degradation (ref. Performance section).
Warning
elfconv is WORK IN PROGRESS. You may encounter failures when compiling ELF binaries or executing generated Wasm binaries.
- Architecture Support: Only AArch64 ELF binaries are currently supported
- x86-64 support is under development
- Linking: No support for Linux shared objects
- Only statically-linked binaries are supported
- System Calls: Partial Linux syscall implementation
- See
runtime/syscalls/for currently supported syscalls
- See
We measured the performance of Wasm generated by elfconv against Wasm compiled directly from source using Emscripten or WASI-SDK. The workflow is:
- Compile source code → AArch64 ELF binary (using gcc/clang)
- Convert ELF binary → Wasm using elfconv
- Compare with: Source code → Wasm directly (using Emscripten/WASI-SDK)
Blog: elfconv: Linux Apps to High-Performance Wasm Binary Translator
| Target Program | from source code | elfconv |
|---|---|---|
eratosthenes_sieve (↓ better) |
0.567 (s) (100%) | 0.692 (s) (82%) |
LINPACK benchmark (↑ better) |
1617 (MFLOPS) (100%) | 1256 (MFLOPS) (78%) |
mnist-neural-network-plain-c (during 30 steps) (↑ better) |
2.138 (s) (100%) | 2.255 (s) (96%) |
| Target Program | from source code | elfconv |
|---|---|---|
eratosthenes_sieve (↓ better) |
0.362 (s) (100%) | 0.608 (s) (60%) |
LINPACK benchmark (↑ better) |
4821 (MFLOPS) (100%) | 2720 (MFLOPS) (56%) |
mnist-neural-network-plain-c (during 30 steps) (↑ better) |
2.271 (s) (100%) | 2.302 (s) (96%) |
Pull pre-built image (recommended):
# For ARM64 hosts
$ docker pull ghcr.io/yomaytk/elfconv:arm64
# For x86-64 hosts
$ docker pull ghcr.io/yomaytk/elfconv:amd64Build from Dockerfile:
$ git clone --recursive https://github.com/yomaytk/elfconv
$ cd elfconv
# For AArch64 ELF target
$ docker build . --build-arg ECV_AARCH64=1
# For x86-64 ELF target
$ docker build . --build-arg ECV_X86=1For detailed build commands and environment variables, see scripts/README.md.
# 1. Run container with port forwarding
$ docker run -it -p 8080:8080 <image-name>
# 2. Convert ELF to Wasm
~/elfconv# cd bin
~/elfconv/bin# TARGET=aarch64-wasm INITWASM=1 ./exe.sh /path/to/ELF
# Example: TARGET=aarch64-wasm INITWASM=1 ./exe.sh ../examples/hello/c/a.aarch64
# 3. Start web server
~/elfconv/bin# emrun --no_browser --port 8080 <ELFNAME>.htmlAccess the Wasm application from your browser at http://localhost:8080/<ELFNAME>.html
# 1. Run container
$ docker run -it <image-name>
# 2. Convert ELF to Wasm
~/elfconv# cd bin
~/elfconv/bin# TARGET=aarch64-wasi32 ./exe.sh /path/to/ELF
# Example: TARGET=aarch64-wasi32 ./exe.sh ../examples/hello/c/a.aarch64
# 3. Execute with WasmEdge (preinstalled)
~/elfconv/bin# wasmedge <ELFNAME>.wasmWe'd love your help making it better!
- Instruction Support — Implement missing AArch64 instructions or advance x86-64 instruction support.
- System Call Implementation — Add Linux syscall support in
runtime/syscalls/ - Testing — Test with various Linux applications and report issues
For questions or discussions, feel free to open an issue or start a discussion.
elfconv uses or references some projects as follows. Great thanks to all its developers!
- Remill (Apache Lisence 2.0)
- Original Source: https://github.com/lifting-bits/remill
- elfconv uses Remill to convert machine codes to LLVM IR instructions. The source code is contained in
./backend/remilland is modified for using from front-end and supporting additional instructions.
- MyAOT (Apache Lisence 2.0)
- Original Source: https://github.com/AkihiroSuda/myaot
- An experimental AOT-ish compiler (Linux/riscv32 ELF → Linux/x86_64 ELF, Mach-O, Wasm, ...)
- elfconv has started as the successor project of MyAOT.
