Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
1 result

klee-sys

  • Clone with SSH
  • Clone with HTTPS
  • Forked from KLEE / klee-sys
    12 commits ahead of the upstream repository.
    Name Last commit Last update
    .vscode
    src
    .gitignore
    Cargo.toml
    README.md

    klee-sys

    Low-level bindings to LLVM-KLEE.

    Design

    LLVM KLEE performs symbolic execution of LLVM-IR programs. For each path KLEE will generate a concrete test.

    A path is termintated either by executing to end or hitting the abort symbol. We bind the Rust panic_handler to the abort symbol, thus any panic!() will result in path termination (and consequitively a concrete test).

    As assert!()/assert_eq!() etc. expands to conditional panic!(), thus a failing assertion will be caught.

    Variables (or rather memory objects) can be made symbolic, through the KLEE C API. We bind the KLEE API in the ll module.

    pub fn klee_make_symbolic(
            ptr: *mut core::ffi::c_void,    // pointer to the data
            size: usize,                    // size (in bytes)
            name: *const cstr_core::c_char, // pointer to zero-terminated C string
        );
    }

    The internal Rust abstraction, calls into the FFI binding.

    #[inline(always)]
    pub fn klee_make_symbolic<T>(t: &mut T, name: &'static CStr) {
        unsafe {
            crate::ll::klee_make_symbolic(
                t as *mut T as *mut c_void,
                core::mem::size_of::<T>(),
                name.as_ptr() as *const c_char,
            )
        }
    } 

    However dealing with CStr is cumbersome in Rust user code so we provide a macro, klee_make_symbolic!(&mut T, &str), that zero-terminates the &str and cast it to the appropriate type.

    Example usage:

        ...
        let mut a = 0;
        klee_make_symbolic(&mut a, "a");

    KLEE test case generation

    LLVM KLEE strives to cover all feasible paths. When generating tests for errors encountered (paths to abort), KLEE will generate one test for each unique position in the source code that lead up to the abort. Code that emits a Rust panic!(), will all reach the same panic_handler (which calls into abort), and KLEE will detect the panic_handler as the source of the error, and consequently generate one such test. (Perhaps there is a way to force KLEE to generate one test per unique path leading up to the panic_handler, but we have not yet found it. Tech note: The panic implementation can unfortunately not be inlined as far as we have seen.)

    As a consequence, you have to eliminate sources of panic!() one by one, which may be time consuming.

    We provide a set of macros klee_abort, klee_assert and klee_assert_eq, that gets fully inlined, allowing KLEE to generate specific tests for each failing assertion. Using these, all errors will be covered by unique test.

    License

    Copyright Per Lindgren.

    All rights reserved, use restricted for non-commercial purpose.