Skip to content
Snippets Groups Projects
Commit af44f383 authored by Per's avatar Per
Browse files

painc

parent 7772df35
No related branches found
No related tags found
No related merge requests found
# klee-sys # klee-sys
Low-level bindings to LLVM-KLEE. 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!()`, any failing assertion will generate a concrete test.
Variables (or rather memory locations) can be made symbolic, through the C API.
``` Rust
pub fn klee_make_symbolic(
ptr: *mut core::ffi::c_void, // pointer do the data
size: usize, // size (in bytes)
name: *const i8 // pointer to zero-teriminted C string
);
```
The internal Rust abstraction:
``` Rust
fn klee_make_symbolic<T>(
t: &mut T, // reference to generic type
name: &'static CStr // pointer to CString
) {...}
```
However dealing with CStr is cumbersome in user code so we provide a macro, `klee_mk_symbol!(&mut T, &str)`, that zero-termintes the `&str`. You can use
``` Rust
...
let mut a = 0;
klee_make_symbolic(&mut a, "a");
```
#![no_std] #![no_std]
// use core::intrinsics; use core::ffi::c_void;
// use core::panic::PanicInfo; #[doc(hidden)]
pub use cstr_core::CStr;
// #[panic_handler]
// fn panic(_info: &PanicInfo) -> ! {
// unsafe { intrinsics::abort() }
// }
// #[lang = "eh_personality"]
// extern "C" fn eh_personality() {}
// extern crate cstr_core;
// // #[cfg(feature = "klee-analysis")]
// // mod lang_items;
// #[cfg(feature = "klee-analysis")]
// pub mod ll;
// #[cfg(feature = "klee-analysis")]
// use core::ffi::c_void;
// #[doc(hidden)]
// pub use cstr_core::CStr;
// /// Aborts the path in KLEE mode, does nothing otherwise
// #[macro_export]
// macro_rules! kabort {
// () => {
// #[cfg(feature = "klee-analysis")]
// unsafe { $crate::ll::abort() };
// };
// }
// #[cfg(feature = "klee-analysis")]
// pub fn kassume(cond: bool) {
// unsafe {
// ll::klee_assume(cond);
// }
// }
// #[cfg(not(feature = "klee-analysis"))] pub mod ll;
// pub fn kassume(_cond: bool) {}
// #[cfg(feature = "klee-analysis")] pub mod panic;
// pub fn kmksymbol<T>(t: &mut T, name: &'static CStr) {
// unsafe {
// ll::klee_make_symbolic(
// t as *mut T as *mut c_void,
// core::mem::size_of::<T>(),
// name.as_ptr(),
// )
// }
// }
// #[cfg(not(feature = "klee-analysis"))] //#[inline(always)]
// pub fn kmksymbol<T>(_t: &mut T, _name: &'static CStr) {} #[inline(never)]
pub fn klee_abort() -> ! {
unsafe { ll::abort() };
}
// #[macro_export] #[inline(always)]
// macro_rules! ksymbol { pub fn klee_assume(cond: bool) {
// (&mut $id:expr, $name:expr) => { unsafe {
// $crate::kmksymbol(unsafe { &mut $id }, unsafe { ll::klee_assume(cond);
// $crate::CStr::from_bytes_with_nul_unchecked(concat!($name, "\0").as_bytes()) }
// }) }
// };
// }
// /// If in KLEE mode, the assertion is made. // #[inline(always)]
// /// Otherwise, this is does nothing. // pub fn klee_assert(cond: bool) {
// #[macro_export] // if !cond {
// macro_rules! kassert { // klee_abort();
// ($e:expr) => {
// #[cfg(feature = "klee-analysis")]
// {
// if !$e {
// $crate::kabort!();
// }
// } // }
// };
// } // }
use core::ffi::c_void; #[inline(always)]
fn klee_make_symbolic<T>(t: &mut T, name: &'static CStr) {
unsafe {
ll::klee_make_symbolic(
t as *mut T as *mut c_void,
core::mem::size_of::<T>(),
name.as_ptr() as *const u8,
)
}
}
extern "C" { #[macro_export]
pub fn abort() -> !; macro_rules! klee_make_symbolic {
pub fn klee_assume(cond: bool); (&mut $id:expr, $name:expr) => {
pub fn klee_make_symbolic(ptr: *mut c_void, size: usize, name: *const i8); $crate::klee_make_symbolic(unsafe { &mut $id }, unsafe {
$crate::CStr::from_bytes_with_nul_unchecked(concat!($name, "\0").as_bytes())
})
};
} }
extern "C" {
#[inline(always)]
pub fn abort() -> !;
#[inline(always)]
pub fn klee_assume(cond: bool);
#[inline(always)]
pub fn klee_make_symbolic(ptr: *mut core::ffi::c_void, size: usize, name: *const u8);
}
#[cfg(not(test))] // avoid warning duplicate lang-item
#[panic_handler]
#[inline(never)]
fn panic(_info: &core::panic::PanicInfo) -> ! {
// abort symbol caught by LLVM-KLEE
unsafe { crate::ll::abort() }
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment