Repository navigation
Home
The OhaLLVM repository contains a set of LLVM analysis tools including a context sensitive and context insensitive version of Andersen's Points-to analysis, and a backward static slicer.
The repository can run these analyses in either traditional mode, or including dynamic run-time information to create a predicated static analysis.
First, download from github:
git clone git@github.com:ddevec/OhaLLVM.git
Install llvm-7
Follow the llvm installation instructions for version 7.0.1. (We use the git tagged version).
Install libbdd and gproftools:
sudo apt-get install -y libbdd-dev libbdd0c2 google-perftools libgoogle-perftools-dev libgoogle-perftools4
Configure the analysis tools (requires cmake):
cd OhaLLVM
mkdir build
cd build
cmake ..
make
This section outlines how to run the analysis tools on your code...
To run analyses tools on codebases the codebases must first be compiled into a monolithic llvm binary. We recommend the use of '-flto' with clang, and the gold versions of binutils: https://llvm.org/docs/GoldPlugin.html|llvm-gold.
This should create in the binary directory a binary (like normal), and an llvm .bc (llvm bitcode) file. We recommend operating on the unoptimized, or very specifically optimized version of the bc file, as some optimizations make the points-to analysis far less accurate.
To run the pure static slicing analyses:
opt [binname.preopt.bc] [Options] [PtsAnalysisFlag] -static-slice -disable-output 2> [your analysis debug output here]
Where PtsAnalysisFlag is:
-SpecAnders - Andersen's Points-to analysis
-SpecAndersCS - Context-sensitive Andersen's Points-to Analysis
Options include:
Slicing:
-slice-no-control-flow - Does data-flow slice (instead of control flow)
-slice-do-random - Slices random instructions
-slice-random-seed=X - sets random seed to X
-slice-save-file=OUTFILE - Saves the sliced sinks to a file
-slice-load-file=INFILE - slices the sinks saved in infile
-slice-outfile=OUTFILE - Saves the output of the slice (for use by other tools) to a file
-slice-reconstruct-outfile=X - Creates a reconstruction of the program from the slice
Points-to:
-anders-no-spec - Disables predicated analysis
-alias-test - Gathers statistics on alias information
-dyn-alias-tester - Tests alias sets against dynamic profiled data (if available)
-specsfs-do-inst - Instruments binary to check for invariant violations
To run predicated static analysis you must first gather dynamic invariants
# No .bc in first arg
# Second arg (and beyond) are libraries that the program needs to be compiled with, like -pthreads or -lgtk
scripts/create-inst [binname.preopt] [library flags]
This will create 4 instrumented binaries:
binname.preopt.edge - Measures basic block use counts (for dead code elimination)
binname.preoopt.indir - Tracks indirect function calls (for indirect function call targets)
binname.preopt.callstack - Gathers callstack checks (for dead callstack elimination)
binname.preopt.alias - Gathers alias information for the dyn alias checker (not needed for predicated analysis)
Run these analyses to gather likely invariants over your tests. When run these analyses will gather likely invariants and save them into a likely invariant file. This file can be specified through the environment variable SFS_LOGFILE at runtime:
SFS_LOGFILE=prof.edge ./binname.preopt.edge <args>
Multiple profile files can be merged together:
# For indir callstack and alias files:
$SFS_DIR/merge_logfiles [infiles] > outfile
# for edge info:
cat [infiles] > outfile
Then, run the speculative optimistic hybrid analysis:
opt [binname.preopt.bc] [Options] [InvFlags] [PtsAnalysisFlag] -static-slice -disable-output 2> [your analysis debug output here]
Where InvFlags are:
-dyn-alias-file=X - load dynamic alias invariants
-dyn-edge-file=X - load dynamic edge count invariants
-indir-info-file=X - load indirect function call invaraints
-dyn-calls-file=X - load callstack invaraint file
This should cause your analyses to run speculatively, with the added invariants (unless the -anders-no-spec flag is passed).