For a list of arguments accepted by PAGAI, run pagai -h
.
PAGAI takes as input LLVM bitcode. Bitcode can be obtained from C programs using Clang. To compile a C file into LLVM bitcode, you can run the script located in the scripts directory of the Git repository:
./scripts/compile_llvm.sh -h
In order to have a nicer PAGAI output, you have to compile your C code with debug infos (option -g
).
With a C input
If you want to use PAGAI with a C input, you first need to setup a pagai.conf
file in
the same directory as the PAGAI executable. This conf file contains only one variable so
far, named ResourceDir
. This variable should be set to the path of your LLVM/Clang
installation. In particular, make sure you set ResourceDir
so that the path
$(ResourceDir)/lib/clang/3.4/include/
exists and contains e.g. float.h
.
The pagai.conf
file should have the form:
"ResourceDir <dir>"
Example:
~$ cat pagai.conf
ResourceDir /Users/julien/work/pagai/external/llvm
With a LLVM .bc
input
The pagai.conf
file is only used for compiling C/C++ code into LLVM bitcode. If you
directly give to PAGAI a bitcode file, it will process it. Note that you will need to
compile into bitcode with clang and the -g
and -emit-llvm
arguments.
Example
How to analyze the following C program:
~$ more gopan.c
#include "../pagai_assert.h"
int main() {
int x = 0;
int y = 0;
while (1) {
if (x <= 50) {
y++;
} else y--;
if (y < 0) break;
x++;
}
assert(x+y<=101);
assert(x <= 102);
}
First, we have to compile this program into LLVM bitcode. We can either use our script, or call clang directly:
~$ clang -emit-llvm -g -c gopan.c -o gopan.bc
or
~$ compile_llvm.sh -g -i gopan.c -o gopan.bc
We can now run PAGAI on the resulting bitcode file. It outputs the C source code with annotations. safe means that the numerical operation cannot overflow, and assert OK means that the assert statement is proved correct.
~$ pagai -i gopan.bc
#include "../pagai_assert.h"
int main() {
int x = 0;
int y = 0;
/* reachable */
while (1) {
/* invariant:
102-x-y >= 0
y >= 0
x-y >= 0
*/
if (x <= 50) {
// safe
y++;
} else // safe
y--;
if (y < 0) break;
// safe
x++;
}
// safe
/* assert OK */
assert(x+y<=101);
/* assert OK */
assert(x <= 102);
/* reachable */
}
Pagai can also output an annotated LLVM bitcode file with the invariants stored as LLVM metadata, so that they can be used by external tools.