Skip to content

Whole Program Analysis (using WLLVM)

Fabian Schiebel edited this page Sep 23, 2025 · 6 revisions

Analyzing a complex project

Within PhASAR, analyses are done on LLVM IR that comes either as human-readable .ll files or binary .bc files. In order to produce LLVM IR, firstly the project should be compiled. For simple projects with only a few source-files, you may manually invoke clang with -emit-llvm to produce IR files, however, this approach does not scale to larger projects. For those, you may want to use WLLVM (or GLLVM), which provides tools for building whole-program LLVM bitcode files. You can use the wllvm compiler wrapper as drop-in replacement for clang or clang++.

After compiling, you can use the WLLVM tool extract-bc (get-bc for gllvm) to produce a LLVM bitcode file for each object file, executable, or library. WLLVM takes care that all bitcode parts of the individual object files are correctly linked together.

Install WLLVM

WLLVM is a pip package. You can just install it by either of these commands:

pip install wllvm
sudo pip install wllvm

Alternative: Install GLLVM

GLLVM is a golang project, so you first need to install go.

Once you have installed go, just follow the installation guide in GLLVM to install gllvm. It should be as easy as:

go install github.com/SRI-CSL/gllvm/cmd/...@latest

Setup WLLVM/GLLVM

Set LLVM_COMPILER environment variable to clang by the following command:

export LLVM_COMPILER=clang

For gllvm, you may want to set the environment variable LLVM_BITCODE_GENERATION_FLAGS to customize IR generation.

# Example: Enforcing debug info in generated IR:
export LLVM_BITCODE_GENERATION_FLAGS="-g"

Example: Generating LLVM IR for libphasar with GLLVM

In the following example, we generate LLVM IR of phasar's own code.

# First, clone phasar:
git clone --recursive https://github.com/secure-software-engineering/phasar.git

# Navigate into the project's root
cd phasar

# Setup the build folder
mkdir -p build && cd build

# Setup the gllvm configuration
export LLVM_COMPILER=clang
export LLVM_BITCODE_GENERATION_FLAGS="-g"
# If you have more than one clang version installed, you need to point 
# to the right clang version for generating the correctly-versioned IR:
# export LLVM_COMPILER_PATH=/your-path-to-llvm-15/bin

# Configure and build the project, replacing the default compilers by gllvm
CC=gclang CXX=gclang++ cmake ..
cmake --build .

# Extract the bitcode (Note: You need -b only for extracting bitcode from static libraries)
# Creates lib/libphasar.a.bc
get-bc -b lib/libphasar.a

# Optional: create human-readable LLVM IR
# Creates lib/libphasar.a.ll
llvm-dis lib/libphasar.a.bc -o lib/libphasar.a.ll

# Run a phasar analysis on phasar:
./tools/phasar-cli/phasar-cli -m ./lib/libphasar.a.bc -D ifds-solvertest --auto-globals=false --emit-raw-results --entry-points=__ALL__
Clone this wiki locally