An LLVM-based AN encoder (originally developed by Norman Rink).
Encoding an application with AN code requires the following steps:
- Encode and decode the input and output of the application
- Generate LLVM bitcode for the application
- Applies AN code to instructions in bitcode
- Generate binary
Step 1 requires the user to annotate the source code with encoding/decoding macros.
Step 2 and 4 is done using clang
.
Step 3 is fullfiled with a series of LLVM passess wrapped in a single binary called encode
.
OpenSUSE 42.3
with gcc 4.8.5
and cmake 3.12
mkdir llvm-3.5-build && cd llvm-3.5-build
cmake ../llvm-3.5-src
cmake --build . -j 4
These commands should build LLVM 3.5 and Clang 3.5 in llvm-3.5-build
.
mkdir encoder-build && cd encoder-build
cmake .. -DLLVM_DIR=<$root_dir/llvm-3.5-build/cmake/modules/CMakeFiles> -DLLVM_MORE_INCLUDE_DIRS=<$root_dir/llvm-3.5-src/include>
cmake --build .
where $root_dir
is the root directory of this repository.
These commands should build the encode
binary in the encoder-build/bin
directory.
- Create a directory for the application to encode under the
encode/tests
directory. - Annotate the source code to encode/decode input and ouput, respectively.
- Add a
CMakeLists.txt
for the application in the created directory. - Open
encode/tests/CMakeLists.txt
and add the created directory withadd_subdirectory
. - Modify the encoding profile (see below).
- Rebuild
An encoding profile is used to configure the AN encoder. It consists of a list of directives delimitted by semicolons. There are two types of directives: profile directives and operation-position directives.
Here is the default encoding profile at encode/tests/test.ep
:
Store: Before;
CheckAfterDecode;
The first line is an operation-position directive, which specifies error checking should be performed before each store.
The second line is a profile directives, which specifies error checking should happen after each decode operation.
Decode operations are inserted in the following scenarios:
- Library function calls
- Store operations (since address needs decoding)
- Specific operations (e.g., bitwise and)
This binary takes in an LLVM bitcode, applies AN-code, and outputs transformed bitcode. The basic usage is:
./encode -p <encoding_profile> -o <output_bitcode> <input_bitcode>
Run ./encode --help
for other flags.