From 041a348ce4a6101c46d5f185105c8ed3f2fb06dd Mon Sep 17 00:00:00 2001 From: Per Lindgren <per.lindgren@ltu.se> Date: Sun, 2 Oct 2022 23:42:39 +0200 Subject: [PATCH] move to clap 4, wip4, replay almost working --- cargo-klee/src/cli.rs | 2 +- cargo-klee/src/main.rs | 75 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/cargo-klee/src/cli.rs b/cargo-klee/src/cli.rs index e461c6c..b69eced 100644 --- a/cargo-klee/src/cli.rs +++ b/cargo-klee/src/cli.rs @@ -45,7 +45,7 @@ pub struct Cli { /// GDB Replay #[arg(long, short)] - pub replay: bool, + pub gdb: bool, // #[command(subcommand)] // binary: Option<Commands>, } diff --git a/cargo-klee/src/main.rs b/cargo-klee/src/main.rs index db6535f..8964e55 100644 --- a/cargo-klee/src/main.rs +++ b/cargo-klee/src/main.rs @@ -156,7 +156,7 @@ fn main() -> Result<(), Error> { // enable coloring of output .arg("--color") // ll file to analyse - .arg(ll); + .arg(ll.clone()); println!("klee {:?}", klee); @@ -174,11 +174,78 @@ fn main() -> Result<(), Error> { if !output.success() { return Err(anyhow!("`klee` failed, exiting `cargo-klee`")); } + } - let output = klee.stdout(Stdio::piped()).output()?; - let stderr = String::from_utf8(output.stderr)?; + // replay execution in `gdb` + if args.gdb { + // compile to object code for replay using `llc` + let mut llc = Command::new("llc"); + llc.arg("-filetype=obj") + .arg("-relocation-model=pic") + .arg(ll.clone()); - eprintln!("{}", stderr); + if args.verbose { + eprintln!("\n{:?}\n", llc); + } + + let output = llc + .stdout(Stdio::piped()) + .status() + .expect("failed to invoke `llc`, exiting `cargo-klee`"); + + if !output.success() { + return Err(anyhow!("`llc` failed, exiting `cargo-klee`")); + } + + // compile to executable for replay using `clang` + let mut clang = Command::new("clang"); + + let obj_name = format!("{}.o", ll); + let replay_name = format!("{}.replay", ll); + + clang + .arg(obj_name) + .arg("--rtlib=compiler-rt") + .arg("-lkleeRuntest") + .args(&["-o", &replay_name]); + + if args.verbose { + eprintln!("\n{:?}\n", clang); + } + + let output = llc + .stdout(Stdio::piped()) + .status() + .expect("failed to invoke `clang`, exiting `cargo-klee`"); + + if !output.success() { + return Err(anyhow!("`clang` failed, exiting `cargo-klee`")); + } + + let mut gdb = Command::new("gdb"); + if let Ok(cwd) = env::var("GDB_CWD") { + // set gdb current dir to `GDB_CWD` + gdb.current_dir(cwd); + } else { + // set gdb current dir to the target directory + gdb.current_dir(out_dir); + }; + + // set replay name to be loaded by gdb + gdb.arg(replay_name); + + if args.verbose { + eprintln!("\n{:?}\n", gdb); + } + + let output = gdb + .stdout(Stdio::piped()) + .status() + .expect("failed to invoke `gdb`, exiting `cargo-klee`"); + + if !output.success() { + return Err(anyhow!("`gdb` failed, exiting `cargo-klee`")); + } } println!("--- done ---"); -- GitLab