yomaytk/elfconv

AOT binary translator of Linux/ELF → WebAssembly

C++

441

861 commits

updated Oct 1, 2026

See the code

README

elfconv-logo2

elfconv

Ask DeepWiki

An ahead-of-time binary translator that converts Linux applications to WebAssembly for both browser and WASI runtimes.

[🌎Try Demo]

Why elfconv?

1. Easy Porting to Wasm

  • 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

2. Process Management

  • fork/execve support
    • elfconv experimentally supports fork() and execve() 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).

3. Low Performance Overhead

  • 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).

Current Limitations

[!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

Performance

We measured the performance of Wasm generated by elfconv against Wasm compiled directly from source using Emscripten or WASI-SDK. The workflow is:

  1. Compile source code → AArch64 ELF binary (using gcc/clang)
  2. Convert ELF binary → Wasm using elfconv
  3. Compare with: Source code → Wasm directly (using Emscripten/WASI-SDK)

Blog: elfconv: Linux Apps to High-Performance Wasm Binary Translator

To Wasm (Emscripten)

Target Programfrom source codeelfconv
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%)

To WASI

Target Programfrom source codeelfconv
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%)

Quick Start

Getting the Container

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:amd64

Build 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=1

Usage

For detailed build commands and environment variables, see scripts/README.md.

Browser

# 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>.html

Access the Wasm application from your browser at http://localhost:8080/<ELFNAME>.html

WASI Runtime

# 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>.wasm

Contributing

We'd love your help making it better!

Examples

  • 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.

Acknowledgement

elfconv uses or references some projects as follows. Great thanks to all its developers!

yomaytk/elfconv

AOT binary translator of Linux/ELF → WebAssembly

C++

441

861 commits

updated Oct 1, 2026

See the code

README

elfconv-logo2

elfconv

Ask DeepWiki

An ahead-of-time binary translator that converts Linux applications to WebAssembly for both browser and WASI runtimes.

[🌎Try Demo]

Why elfconv?

1. Easy Porting to Wasm

  • 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

2. Process Management

  • fork/execve support
    • elfconv experimentally supports fork() and execve() 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).

3. Low Performance Overhead

  • 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).

Current Limitations

[!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

Performance

We measured the performance of Wasm generated by elfconv against Wasm compiled directly from source using Emscripten or WASI-SDK. The workflow is:

  1. Compile source code → AArch64 ELF binary (using gcc/clang)
  2. Convert ELF binary → Wasm using elfconv
  3. Compare with: Source code → Wasm directly (using Emscripten/WASI-SDK)

Blog: elfconv: Linux Apps to High-Performance Wasm Binary Translator

To Wasm (Emscripten)

Target Programfrom source codeelfconv
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%)

To WASI

Target Programfrom source codeelfconv
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%)

Quick Start

Getting the Container

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:amd64

Build 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=1

Usage

For detailed build commands and environment variables, see scripts/README.md.

Browser

# 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>.html

Access the Wasm application from your browser at http://localhost:8080/<ELFNAME>.html

WASI Runtime

# 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>.wasm

Contributing

We'd love your help making it better!

Examples

  • 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.

Acknowledgement

elfconv uses or references some projects as follows. Great thanks to all its developers!

Significant stargazers

(top 24 of 50)

Ingvar Stepanyan

1,853 followers · starred Jan 2024

Chris Aniszczyk

828 followers · starred Mar 2026

Devon Govett

3,911 followers · starred Mar 2025

Julien Voisin

556 followers · starred Apr 2025