diff options
| author | Alasdair | 2020-05-15 10:54:59 +0100 |
|---|---|---|
| committer | Alasdair | 2020-05-15 10:54:59 +0100 |
| commit | ffaa84fe0a79a013da2169bcca76a23d4213d526 (patch) | |
| tree | 4b127a22ec4ef44bd83c743bdd053b479e236c4d /lib/coverage | |
| parent | 806e97ffbc0193a3539d5c0dc8902465d71fe0bd (diff) | |
Add coverage tracking tool
See sailcov/README.md for a short description
Fix many location info bugs discovered by eyeballing output
Diffstat (limited to 'lib/coverage')
| -rw-r--r-- | lib/coverage/Cargo.toml | 11 | ||||
| -rw-r--r-- | lib/coverage/Makefile | 3 | ||||
| -rw-r--r-- | lib/coverage/src/lib.rs | 132 |
3 files changed, 146 insertions, 0 deletions
diff --git a/lib/coverage/Cargo.toml b/lib/coverage/Cargo.toml new file mode 100644 index 00000000..f4fdf1d7 --- /dev/null +++ b/lib/coverage/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "sail-coverage" +version = "0.1.0" +authors = ["Alasdair <alasdair.armstrong@cl.cam.ac.uk>"] +edition = "2018" + +[dependencies] +lazy_static = "1.4.0" + +[lib] +crate-type = ["staticlib"] diff --git a/lib/coverage/Makefile b/lib/coverage/Makefile new file mode 100644 index 00000000..55ed9fdc --- /dev/null +++ b/lib/coverage/Makefile @@ -0,0 +1,3 @@ +libsail_coverage.a: src/*.rs Cargo.toml Makefile + cargo build --release + cp target/release/libsail_coverage.a . diff --git a/lib/coverage/src/lib.rs b/lib/coverage/src/lib.rs new file mode 100644 index 00000000..003f8b88 --- /dev/null +++ b/lib/coverage/src/lib.rs @@ -0,0 +1,132 @@ +extern crate lazy_static; +use lazy_static::lazy_static; + +use std::collections::HashSet; +use std::ffi::{CStr, CString}; +use std::fs::{OpenOptions, File}; +use std::io::Write; +use std::os::raw::{c_char, c_int}; +use std::sync::Mutex; + +#[derive(Eq, PartialEq, Hash)] +struct Span { + sail_file: CString, + line1: i32, + char1: i32, + line2: i32, + char2: i32, +} + +lazy_static! { + static ref BRANCHES: Mutex<HashSet<Span>> = Mutex::new(HashSet::new()); + static ref FUNCTIONS: Mutex<HashSet<Span>> = Mutex::new(HashSet::new()); +} + +fn function_entry(_function_name: &CStr, span: Span) { + FUNCTIONS.lock().unwrap().insert(span); +} + +fn branch_taken(_branch_id: i32, span: Span) { + BRANCHES.lock().unwrap().insert(span); +} + +fn branch_reached(_branch_id: i32, _span: Span) { + () +} + +fn write_locations(file: &mut File, kind: char, spans: &Mutex<HashSet<Span>>) -> bool { + for span in spans.lock().unwrap().iter() { + let res = write!( + file, + "{} \"{}\", {}, {}, {}, {}\n", + kind, + span.sail_file.to_string_lossy(), + span.line1, + span.char1, + span.line2, + span.char2, + ); + if res.is_err() { + return false; + } + }; + true +} + +#[no_mangle] +pub extern "C" fn sail_coverage_exit() -> c_int { + if let Ok(mut file) = OpenOptions::new().create(true).append(true).open("sail_coverage") { + if !write_locations(&mut file, 'B', &BRANCHES) { + return 1 + } + if !write_locations(&mut file, 'F', &FUNCTIONS) { + return 1 + } + 0 + } else { + 1 + } +} + +#[no_mangle] +pub unsafe extern "C" fn sail_function_entry( + function_name: *const c_char, + sail_file: *const c_char, + l1: c_int, + c1: c_int, + l2: c_int, + c2: c_int, +) { + function_entry( + CStr::from_ptr(function_name), + Span { + sail_file: CStr::from_ptr(sail_file).into(), + line1: l1 as i32, + char1: c1 as i32, + line2: l2 as i32, + char2: c2 as i32, + }, + ) +} + +#[no_mangle] +pub unsafe extern "C" fn sail_branch_taken( + branch_id: c_int, + sail_file: *const c_char, + l1: c_int, + c1: c_int, + l2: c_int, + c2: c_int, +) { + branch_taken( + branch_id as i32, + Span { + sail_file: CStr::from_ptr(sail_file).into(), + line1: l1 as i32, + char1: c1 as i32, + line2: l2 as i32, + char2: c2 as i32, + }, + ) +} + +#[no_mangle] +pub unsafe extern "C" fn sail_branch_reached( + branch_id: c_int, + sail_file: *const c_char, + l1: c_int, + c1: c_int, + l2: c_int, + c2: c_int, +) { + branch_reached( + branch_id as i32, + Span { + sail_file: CStr::from_ptr(sail_file).into(), + line1: l1 as i32, + char1: c1 as i32, + line2: l2 as i32, + char2: c2 as i32, + }, + ) +} |
