Installation¶
xollvm ships three ways from one source tree, with no edits to any LLVM file:
| Target | Mechanism | Platforms |
|---|---|---|
| clang/opt toolchain (obfuscator built in) | LLVM static extension (LLVM_EXTERNAL_PROJECTS + LINK_INTO_TOOLS) |
Linux · Windows · macOS |
loadable plugin Obfuscator.so |
standalone build against installed LLVM (-fpass-plugin) |
Linux · macOS |
Windows & loadable plugins
Loadable pass plugins need the host LLVM built with -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON,
which prebuilt toolchains don't ship. On Windows, use the static extension — the pass is
compiled straight into clang/opt.
Prebuilt releases¶
If you just want binaries, skip building — grab a release:
| File | What | OS |
|---|---|---|
xollvm-linux-Release.tar.zst |
clang/opt with the obfuscator built in |
Linux x86_64 |
xollvm-windows-Release.7z |
clang/opt with the obfuscator built in |
Windows x64 |
Obfuscator-linux-x64.so |
loadable -fpass-plugin |
Linux x86_64 |
Backends included: X86 · AArch64 · ARM · RISCV.
Prerequisites¶
Common to every build:
- CMake ≥ 3.20
- Ninja (recommended generator)
- Python 3 (generates the AES stub bitcode header)
- A C++17 compiler
- git
Mode-specific:
| Build | Also needs |
|---|---|
| Static extension | A checkout of stock LLVM (release/22.x) and an external clang on PATH (see below) |
| Loadable plugin | An installed LLVM 22 with CMake config + dev headers (llvm-22-dev) and clang-22 |
Why an external clang? (static extension only)
The AES runtime stub is compiled to LLVM bitcode by clang. When the obfuscator is linked
into the tools (LINK_INTO_TOOLS), it cannot use the in-tree clang being built — that
would form a dependency cycle (clang → LLVMExtensions → Obfuscator → aes → clang). So the
build uses a separate, already-installed clang found on PATH. Any reasonably recent
clang works; LLVM 22 reads its (older) bitcode.
- Linux:
sudo apt-get install -y clang - Windows:
choco install llvm(givesC:\Program Files\LLVM\bin\clang.exe) - macOS: the Xcode/Homebrew
clangonPATH
Static extension (toolchain)¶
Builds clang, opt, etc. with the obfuscator compiled in. The three obfuscator flags are the
whole integration:
LLVM_EXTERNAL_PROJECTS=Obfuscator— register xollvm as an external LLVM projectLLVM_EXTERNAL_OBFUSCATOR_SOURCE_DIR=<xollvm dir>— where itsCMakeLists.txtlivesLLVM_OBFUSCATOR_LINK_INTO_TOOLS=ON— statically link it intoclang/opt
git clone --depth 1 --branch release/22.x https://github.com/llvm/llvm-project
git clone https://github.com/und3ath/xollvm
sudo apt-get install -y ninja-build cmake python3 clang # external clang for the aes stub
cmake -S llvm-project/llvm -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="llvm;clang" \
-DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_EH=ON \
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;ARM;RISCV" \
-DLLVM_INCLUDE_TESTS=OFF -DLLVM_BUILD_TESTS=OFF \
-DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_BUILD_BENCHMARKS=OFF \
-DLLVM_INCLUDE_EXAMPLES=OFF \
-DCLANG_INCLUDE_TESTS=OFF -DCLANG_ENABLE_STATIC_ANALYZER=OFF -DCLANG_ENABLE_ARCMT=OFF \
-DLLVM_ENABLE_ASSERTIONS=OFF \
-DLLVM_DISTRIBUTION_COMPONENTS="clang;clang-resource-headers;opt" \
-DLLVM_EXTERNAL_PROJECTS=Obfuscator \
-DLLVM_EXTERNAL_OBFUSCATOR_SOURCE_DIR="$PWD/xollvm" \
-DLLVM_OBFUSCATOR_LINK_INTO_TOOLS=ON \
-DCMAKE_INSTALL_PREFIX="$PWD/install"
# install-distribution builds ONLY the shipped components (clang, opt + libs),
# not the ~40 other standalone llvm-* tools — a big time saving.
cmake --build build --target install-distribution
From an x64 Native Tools developer prompt (after choco install llvm ninja):
git clone --depth 1 --branch release/22.x https://github.com/llvm/llvm-project
git clone https://github.com/und3ath/xollvm
cmake -S llvm-project\llvm -B build -G Ninja ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL ^
-DLLVM_ENABLE_PROJECTS="llvm;clang" ^
-DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_EH=ON ^
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;ARM;RISCV" ^
-DLLVM_INCLUDE_TESTS=OFF -DLLVM_BUILD_TESTS=OFF ^
-DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_BUILD_BENCHMARKS=OFF ^
-DLLVM_INCLUDE_EXAMPLES=OFF ^
-DCLANG_INCLUDE_TESTS=OFF -DCLANG_ENABLE_STATIC_ANALYZER=OFF -DCLANG_ENABLE_ARCMT=OFF ^
-DLLVM_ENABLE_ASSERTIONS=OFF ^
-DLLVM_PARALLEL_LINK_JOBS=1 ^
-DLLVM_DISTRIBUTION_COMPONENTS="clang;clang-resource-headers;opt" ^
-DLLVM_EXTERNAL_PROJECTS=Obfuscator ^
-DLLVM_EXTERNAL_OBFUSCATOR_SOURCE_DIR=%CD%\xollvm ^
-DLLVM_OBFUSCATOR_LINK_INTO_TOOLS=ON ^
-DCMAKE_INSTALL_PREFIX=%CD%\install
cmake --build build --target install-distribution
LLVM_PARALLEL_LINK_JOBS=1 keeps peak RAM sane during the big links.
Tip
Trim LLVM_TARGETS_TO_BUILD to just what you need (e.g. X86) for a much faster build. Want
the full toolchain (llvm-*, lld, …)? Drop LLVM_DISTRIBUTION_COMPONENTS and build
--target install instead — slower and much larger.
Loadable plugin¶
Builds only the pass, against an installed LLVM 22. No LLVM source build — fast.
# Ubuntu 24.04 lacks clang-22/llvm-22 in default repos; add apt.llvm.org:
wget -qO llvm.sh https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && sudo ./llvm.sh 22
sudo apt-get install -y ninja-build clang-22 llvm-22 llvm-22-dev
git clone https://github.com/und3ath/xollvm
cmake -S xollvm -B build -G Ninja \
-DLLVM_DIR=/usr/lib/llvm-22/lib/cmake/llvm \
-DCMAKE_C_COMPILER=clang-22 -DCMAKE_CXX_COMPILER=clang++-22 \
-DCMAKE_BUILD_TYPE=Release
ninja -C build Obfuscator # -> build/Obfuscator.so
On distros that already ship LLVM 22 (e.g. Ubuntu 26.04) the llvm.sh step is unnecessary — just
apt-get install llvm-22-dev clang-22.
Verify the build¶
cat > ann.c <<'EOF'
#define OBF(spec) __attribute__((annotate("obf: " spec)))
OBF("mba, bcf, split")
int secret(int x){ int a=x*3+7; for(int i=0;i<x;i++) a+=(i^a); return a; }
EOF
clang -O0 -emit-llvm -S ann.c -o ann.ll
@secret should grow substantially; an unannotated function is left untouched.
Troubleshooting¶
| Symptom | Cause / fix |
|---|---|
Unable to locate package clang-22 / llvm-22-dev |
Ubuntu 24.04 default repos lack LLVM 22. Add apt.llvm.org: sudo ./llvm.sh 22. |
fatal error: aes_stub_bc.inc: No such file |
AES stub header not generated before compile. Build with the current CMakeLists.txt; reconfigure from clean. |
aes stub: external clang not found |
No clang on PATH for the stub. Install one — the in-tree clang can't be used under LINK_INTO_TOOLS. |
| dependency-cycle error at configure | The aes stub picked the in-tree clang. Ensure an external clang is found first, or that LLVM_OBFUSCATOR_LINK_INTO_TOOLS=ON is set. |
-load-pass-plugin aborts on Windows |
Loadable plugins aren't supported on Windows. Use the static extension. |
Option '…' registered more than once |
A second copy of LLVM's global state. Don't static-link LLVM into the .so. |