Skip to content

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 (gives C:\Program Files\LLVM\bin\clang.exe)
  • macOS: the Xcode/Homebrew clang on PATH

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 project
  • LLVM_EXTERNAL_OBFUSCATOR_SOURCE_DIR=<xollvm dir> — where its CMakeLists.txt lives
  • LLVM_OBFUSCATOR_LINK_INTO_TOOLS=ON — statically link it into clang/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
./install/bin/opt -passes=obfuscation ann.ll -S -o ann.obf.ll
./install/bin/opt -passes=verify ann.obf.ll -disable-output && echo OK
opt-22 -load-pass-plugin=./build/Obfuscator.so -passes=obfuscation ann.ll -S -o ann.obf.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.