Scripting
Contents
Scripting#
czz-llvm can be scripted using Scheme. The API is unstable, and not yet even particularly well-documented.
Examples#
Override a Checksum to Always Pass#
(define test-c "
#include <stdbool.h>
#include <stdio.h>
bool __attribute__((noinline)) passes_checksum(int x, int checksum) {
return (x % 128 == checksum);
}
int main(int argc, char* argv[]) {
if (passes_checksum(argc, 73)) {
printf(\"~~here~~\\n\");
}
return 0;
}
")
;; Write string test-c to file test.c
(call-with-output-file "test.c" (lambda (out) (display test-c out)))
;; Compile to LLVM bitcode
(system "clang -g -O1 -emit-llvm -fno-discard-value-names -Wall -c test.c -o in.bc")
;; Override the behavior of "passes_checksum" to always return true
(define (passes-checksum sym mem args)
(list mem (czz-llvm-bool sym #t)))
;; Helper of type `Maybe a -> [a]`
(define (maybe-to-list mb) (maybe-maybe (list) (lambda (x) (list x)) mb))
(let* ((llvm-config (czz-llvm-default-config))
;; Translate the program into czz's IR
(trans (czz-llvm-translate llvm-config))
;; Create an override for the LLVM passes_checksum procedure from the
;; Scheme passes-checksum function
(ovs (maybe-to-list (czz-llvm-override trans "passes_checksum" passes-checksum)))
;; Create a fuzzer with the given overrides and configuration
(fuzzer (czz-llvm-fuzzer 1 llvm-config trans ovs)))
;; Start fuzzing
(czz-fuzz fuzzer (czz-default-fuzz-config)))
API Reference#
czz-llvm-default-config
#
LLVMConfig
czz-llvm-bool
#
ExprBuilder -> Bool -> SVal
czz-llvm-expr
#
ExprBuilder -> Expr -> SVal
czz-llvm-fuzzer
#
Number -> LLVMConfig -> LLVMTranslation -> List LLVMOverride -> Fuzzer
czz-llvm-i1
#
ExprBuilder -> Number -> SVal
czz-llvm-i8
#
ExprBuilder -> Number -> SVal
czz-llvm-i16
#
ExprBuilder -> Number -> SVal
czz-llvm-i32
#
ExprBuilder -> Number -> SVal
czz-llvm-i64
#
ExprBuilder -> Number -> SVal
czz-llvm-override
#
Translation ->
String ->
(ExprBuilder -> Mem -> [Val] -> (Mem, Val)) ->
Maybe Override
czz-llvm-translate
#
LLVMConfig -> LLVMTranslation