AkihiroSuda / elfconv

An experimental AOT compiler that translates Linux ELF binary to WebAssemlby

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

elfconv

elfconv is an experimental AOT compiler that translates a Linux ELF binary to executable WebAssembly. elfconv converts an original ELF binary to the LLVM bitcode using remill (library for lifting machine code to LLVM bitcode) and elfconv uses emscripten (for browser) or wasi-sdk (for WASI runtimes) to generate the WASM binary from the LLVM bitcode file.

Status

"elfconv is a work in progress" and the test is insufficient, so you may fail to compile your ELF binary or execute the generated WASM binary. Current limitations are as follows.

  • Only support of aarch64 ELF binary as an input binary
    • Furthermore, a part of aarch64 instructions are not supported. If your ELF binary's instruction is not supported, elfconv outputs the message ([WARNING] Unsupported instruction at 0x...)
  • No support for stripped binaries
  • No support for shared objects
  • a lot of Linux system calls are unimplemented (ref: runtime/syscalls/)

Quick Start

You can try elfconv using the docker container (amd64 and arm64) by executing the commands as follows and can execute the WASM application on the both browser and host environment (WASI runtimes).

Warning

The container generated by the Dockerfile includes the installation of wasi-sdk. However, wasi-sdk doesn't release the package for arm64, so we build wasi-sdk in the arm64 container image, and it takes a long time. If you try elfconv, it might be good to use elfconv release packages, or comment out the lines of the installation of wasi-sdk (The relevant part is as follows in the Dockerfile) and try to execute only in the browser.

elif [ "$( uname -m )" = "aarch64" ]; then \
    cd /root && git clone --recursive https://github.com/WebAssembly/wasi-sdk.git; \
    cd wasi-sdk && NINJA_FLAGS=-v make package; \
fi

Browser

$ git clone --recursive https://github.com/yomaytk/elfconv
$ cd elfconv
elfconv/$ docker build . -t elfconv-image
elfconv/$ docker run -it --rm -p 8080:8080 --name elfconv-container elfconv-image
### ENTRYPOINT: elfconv/scripts/container-entry-point.sh
### running build and test ...
# You can test elfconv using `bin/elfconv.sh`
~/elfconv# cd bin
~/elfconv/bin# TARGET=wasm-browser ./elfconv.sh /path/to/ELF # e.g. ../examples/eratosthenes_sieve/a.out
~/elfconv/bin# emrun --no_browser --port 8080 exe.wasm.html
Web server root directory: /root/elfconv/bin
Now listening at http://0.0.0.0:8080/

Now, the WASM application server has started, so that you can access it (e.g. http://localhost:8080/exe.wasm.html) from outside the container.

Host (WASI runtimes)

$ git clone --recursive https://github.com/yomaytk/elfconv
$ cd elfconv
$ docker build . -t elfconv-image
$ docker run -it --name elfconv-container elfconv-image
### ENTRYPOINT: elfconv/scripts/container-entry-point.sh
### running build and test ...
# You can test elfconv using `bin/elfconv.sh`
~/elfconv# cd bin
~/elfconv/bin# TARGET=wasm-host ./elfconv.sh /path/to/ELF # e.g. ../examples/eratosthenes_sieve/a.out
~/elfconv/bin# wasmedge exe.wasm # wasmedge is preinstalled

Source code build

1. Dev Container

elfconv provides the Dev Container environment using the root Dockerfile and .devcontainer.json, so you can develop without making the build environment if you can use Dev Container on your editor (Please refer to the official website of your editor for using Dev Container). The entry point of the elfconv container is ./scripts/container-entry-point.sh that includes the building of elfconv.

2. Local Environment

Dependencies

The libraries required for the build are almost the same as those for remill, and the main libraries are as follows. The other required libraries are automatically installed using cxx-common.

Name Version
Git Latest
CMake 3.14+
Google Flags Latest
Google Log Latest
Google Test Latest
LLVM 16
Clang 16+
Intel XED Latest
Unzip Latest
ccache Latest

Build

If you prepare these libraries, you can easily build elfconv by executing scripts/build.sh as follows.

$ git clone --recursive https://github.com/yomaytk/elfconv
$ cd elfconv
/elfconv$ ./scripts/build.sh

Note

If you fail to build elfconv, please feel free to submit an issue!

Develop

After finishing the build, you can find the directory elfconv/build/, and you can build the 'lifter' ('lifter' is the module that converts the ELF binary to LLVM bitcode and those source codes are mainly located in the backend/remill/ and lifter/) by ninja after modifying the 'lifter' codes.

You can compile the ELF binary to the WASM binary using scripts/dev.sh as follows. dev.sh execute the translation (ELF -> LLVM bitcode by 'lifter') and compiles the runtime/ (statically linked with generated LLVM bitcode) and generate the WASM binary. when you execute the script, you should explicitly specify the path of the elfconv directory (/root/elfconv on the container) with NEW_ROOT or rewrite the ROOT_DIR in dev.sh.

### Browser
~/elfconv/build# NEW_ROOT=/path/to/elfconv TARGET=wasm-browser ../scripts/dev.sh path/to/ELF # generate the WASM binary under the elfconv/build/lifter
~/elfconv/build# emrun --no_browser --port 8080 ./lifter/exe.wasm.html # execute the generated WASM binary with emscripten
------------------------
### Host (WASI Runtimes)
~/elfconv/build# NEW_ROOT=/path/to/elfconv WASISDK=1 TARGET=wasm-host ../scripts/dev.sh path/to/ELF
~/elfconv/build# wasmedge ./lifter/exe.wasm

Acknowledgement

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

About

An experimental AOT compiler that translates Linux ELF binary to WebAssemlby

License:Apache License 2.0


Languages

Language:C++ 71.4%Language:Assembly 24.7%Language:C 1.3%Language:CMake 1.2%Language:Python 0.7%Language:Shell 0.6%Language:Batchfile 0.1%Language:Dockerfile 0.1%Language:GDB 0.0%Language:Makefile 0.0%