Skip to content
Snippets Groups Projects
Commit 65bda15f authored by Per Lindgren's avatar Per Lindgren
Browse files

move to clap 4

parent 55e3fdf5
No related branches found
No related tags found
No related merge requests found
......@@ -9,7 +9,7 @@ pub fn get_hash(s: &str) -> Option<String> {
}
pub fn get_out_dir(s: &str) -> Option<String> {
let re = Regex::new(r"(--out-dir)( )([[:alpha:]\d/-]*)").unwrap();
let re = Regex::new(r"(--out-dir)( )([[:alpha:]\d/-_]*)").unwrap();
let cap = re.captures(s)?;
Some(cap[3].to_string())
}
......
......@@ -90,12 +90,12 @@ fn main() -> Result<(), Error> {
.arg("--")
// ignore linking
.args(&["-C", "linker=true"])
// force LTO, to get a single oject file
// force LTO, to get a single object file
.args(&["-C", "lto"])
// output the LLVM-IR (.ll file) for KLEE analysis
.arg("--emit=llvm-ir")
.arg("--emit=llvm-ir");
// force panic=abort in all crates, override .cargo settings
.env("RUSTFLAGS", "-C panic=abort");
// .env("RUSTFLAGS", "-C panic=abort");
// TODO, force `incremental=false`, `codegen-units=1`?
println!("cargo {:?}", cargo);
......@@ -136,7 +136,9 @@ fn main() -> Result<(), Error> {
println!("out_dir {}", out_dir);
println!("hash {}", hash);
let ll = format!("{}/{}-{}.ll", out_dir, file, hash);
let binary = format!("{}/{}-{}", out_dir, file, hash);
let ll = format!("{}.ll", binary);
println!("ll {}", ll);
// KLEE analysis
......@@ -154,6 +156,7 @@ fn main() -> Result<(), Error> {
// --disable-very to suppress know issue in klee https://github.com/klee/klee/issues/937
klee.arg("--disable-verify")
// enable coloring of output
// Notice, seem not to work as expected
.arg("--color")
// ll file to analyse
.arg(ll.clone());
......@@ -166,12 +169,12 @@ fn main() -> Result<(), Error> {
// eprintln!("{}", stderr);
// Workaround using `.status` to propagate `klee` output to `stderr`.
let output = klee
.stdout(Stdio::piped())
let status = klee
// .stdout(Stdio::piped())
.status()
.expect("failed to invoke `klee`, exiting `cargo-klee`");
if !output.success() {
if !status.success() {
return Err(anyhow!("`klee` failed, exiting `cargo-klee`"));
}
}
......@@ -182,26 +185,40 @@ fn main() -> Result<(), Error> {
let mut llc = Command::new("llc");
llc.arg("-filetype=obj")
.arg("-relocation-model=pic")
.arg("-opaque-pointers")
.arg(ll.clone());
if args.verbose {
eprintln!("\n{:?}\n", llc);
}
let output = llc
.stdout(Stdio::piped())
println!("LLC: \n{:?}\n", llc);
let status = llc
.status()
.expect("failed to invoke `llc`, exiting `cargo-klee`");
.expect("failed to launch `llc`, exiting `cargo-klee`");
if !output.success() {
if !status.success() {
return Err(anyhow!("`llc` failed, exiting `cargo-klee`"));
}
// let output = llc
// //.stdout(Stdio::piped())
// .output()
// .expect("failed to invoke `llc`, exiting `cargo-klee`");
// if !output.status.success() {
// return Err(anyhow!("`llc` failed, exiting `cargo-klee`"));
// }
// println!("llc stdout {:?}", output.stdout);
// println!("llc stderr {:?}", output.stderr);
// 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);
let obj_name = format!("{}.o", binary);
let replay_name = format!("{}.replay", binary);
clang
.arg(obj_name)
......@@ -213,15 +230,28 @@ fn main() -> Result<(), Error> {
eprintln!("\n{:?}\n", clang);
}
let output = llc
.stdout(Stdio::piped())
println!("CLANG: \n{:?}\n", clang);
let status = clang
.status()
.expect("failed to invoke `clang`, exiting `cargo-klee`");
.expect("failed to launch `clang`, exiting `cargo-klee`");
if !output.success() {
if !status.success() {
return Err(anyhow!("`clang` failed, exiting `cargo-klee`"));
}
// let output = llc
// // .stdout(Stdio::piped())
// .output()
// .expect("failed to invoke `clang`, exiting `cargo-klee`");
// println!("llc stdout {:?}", output.stdout);
// println!("llc stderr {:?}", output.stderr);
// if !output.status.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`
......@@ -238,12 +268,23 @@ fn main() -> Result<(), Error> {
eprintln!("\n{:?}\n", gdb);
}
let output = gdb
.stdout(Stdio::piped())
println!("GDB: \n{:?}\n", gdb);
// let output = gdb
// // .stdout(Stdio::piped())
// .output()
// .expect("failed to invoke `gdb`, exiting `cargo-klee`");
// if !output.status.success() {
// return Err(anyhow!("`gdb` failed, exiting `cargo-klee`"));
// }
let status = gdb
// .stdout(Stdio::piped())
.status()
.expect("failed to invoke `gdb`, exiting `cargo-klee`");
if !output.success() {
if !status.success() {
return Err(anyhow!("`gdb` failed, exiting `cargo-klee`"));
}
}
......@@ -252,306 +293,3 @@ fn main() -> Result<(), Error> {
Ok(())
}
// fn run() -> Result<i32, failure::Error> {
// let matches = App::new("cargo-klee")
// .version("0.4.0")
// .author("Lulea University of Technology (LTU)")
// .about("KLEE analysis of Rust application")
// // as this is used as a Cargo sub-command the first argument will be the name of the binary
// // we ignore this argument
// .arg(Arg::with_name("binary-name").hidden(true))
// // TODO: custom target support (for now only target host is supported)
// // .arg(
// // Arg::with_name("target")
// // .long("target")
// // .takes_value(true)
// // .value_name("TRIPLE")
// // .help("Target triple for which the code is compiled"),
// // )
// .arg(
// Arg::with_name("verbose")
// .long("verbose")
// .short("v")
// .help("Use verbose output"),
// )
// .arg(
// Arg::with_name("example")
// .long("example")
// .takes_value(true)
// .value_name("NAME")
// .required_unless("bin")
// .conflicts_with("bin")
// .help("Build only the specified example"),
// )
// .arg(
// Arg::with_name("bin")
// .long("bin")
// .takes_value(true)
// .value_name("NAME")
// .required_unless("example")
// .conflicts_with("example")
// .help("Build only the specified binary"),
// )
// .arg(
// Arg::with_name("release")
// .long("release")
// .help("Build artifacts in release mode, with optimizations"),
// )
// .arg(
// Arg::with_name("features")
// .long("features")
// .takes_value(true)
// .value_name("FEATURES")
// .help("Space-separated list of features to activate"),
// )
// .arg(
// Arg::with_name("all-features")
// .long("all-features")
// .takes_value(false)
// .help("Activate all available features"),
// )
// // TODO, support additional parameters to KLEE
// .arg(
// Arg::with_name("klee")
// .long("klee")
// .short("k")
// .help("Run KLEE test generation [default enabled unless --replay]"),
// )
// .arg(
// Arg::with_name("replay")
// .long("replay")
// .short("r")
// .help("Generate replay binary in target directory"),
// )
// .arg(
// Arg::with_name("gdb")
// .long("gdb")
// .short("g")
// .help("Run the generated replay binary in `gdb`. The environment variable `GDB_CWD` determines the `gdb` working directory, if unset `gdb` will execute in the current working directory"),
// )
// .get_matches();
// let is_example = matches.is_present("example");
// let is_binary = matches.is_present("bin");
// let verbose = matches.is_present("verbose");
// let is_release = matches.is_present("release");
// let is_replay = matches.is_present("replay");
// let is_ktest = matches.is_present("klee");
// let is_gdb = matches.is_present("gdb");
// // let target_flag = matches.value_of("target"); // not currently supported
// // we rely on `clap` for either `example` or `bin`
// let file = if is_example {
// matches.value_of("example").unwrap()
// } else {
// matches.value_of("bin").unwrap()
// };
// // turn `cargo klee --example foo` into `cargo rustc --example foo -- (..)`
// let mut cargo = Command::new("cargo");
// cargo
// // compile using rustc
// .arg("rustc")
// // verbose output for debugging purposes
// .arg("-v");
// // set features, always including `klee-analysis`
// if matches.is_present("all-features") {
// cargo.arg("--all-features");
// } else {
// if let Some(features) = matches.value_of("features") {
// let mut vec: Vec<&str> = features.split(" ").collect::<Vec<&str>>();
// vec.push("klee-analysis");
// cargo.args(&["--features", &vec.join(" ")]);
// } else {
// cargo.args(&["--features", "klee-analysis"]);
// }
// }
// // select (single) application to compile
// // derive basic settings from `cargo`
// if is_example {
// cargo.args(&["--example", file]);
// } else {
// cargo.args(&["--bin", file]);
// }
// // default is debug mode
// if is_release {
// cargo.arg("--release");
// }
// cargo
// // enable shell coloring of result
// .arg("--color=always")
// .arg("--")
// // ignore linking
// .args(&["-C", "linker=true"])
// // force LTO, to get a single oject file
// .args(&["-C", "lto"])
// // output the LLVM-IR (.ll file) for KLEE analysis
// .arg("--emit=llvm-ir")
// // force panic=abort in all crates, override .cargo settings
// .env("RUSTFLAGS", "-C panic=abort");
// // TODO, force `incremental=false`, `codegen-units=1`?
// if verbose {
// eprintln!("\n{:?}\n", cargo);
// }
// // execute the command and unwrap the result into status
// let status = cargo.status()?;
// if !status.success() {
// return Ok(status.code().unwrap_or(1));
// }
// let cwd = env::current_dir()?;
// let meta = rustc_version::version_meta()?;
// let host = meta.host;
// let project = Project::query(cwd)?;
// let profile = if is_release {
// Profile::Release
// } else {
// Profile::Dev
// };
// let mut path: PathBuf = if is_example {
// project.path(Artifact::Example(file), profile, None, &host)?
// } else {
// project.path(Artifact::Bin(file), profile, None, &host)?
// };
// // llvm-ir file
// let mut ll = None;
// // most recently modified
// let mut mrm = SystemTime::UNIX_EPOCH;
// let prefix = format!("{}-", file.replace('-', "_"));
// path = path.parent().expect("unreachable").to_path_buf();
// if is_binary {
// path = path.join("deps"); // the .ll file is placed in ../deps
// }
// // lookup the latest .ll file
// // TODO: stable support for `metadata` from Cargo.
// for e in fs::read_dir(path)? {
// let e = e?;
// let p = e.path();
// if p.extension().map(|e| e == "ll").unwrap_or(false) {
// if p.file_stem()
// .expect("unreachable")
// .to_str()
// .expect("unreachable")
// .starts_with(&prefix)
// {
// let modified = e.metadata()?.modified()?;
// if ll.is_none() {
// ll = Some(p);
// mrm = modified;
// } else {
// if modified > mrm {
// ll = Some(p);
// mrm = modified;
// }
// }
// }
// }
// }
// let mut obj = ll.clone().unwrap();
// let replay_name = obj.with_file_name(file).with_extension("replay");
// // replay compilation
// if is_replay {
// // 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().unwrap());
// if verbose {
// eprintln!("\n{:?}\n", llc);
// }
// // TODO: better error handling, e.g., if `llc` is not installed/in path
// let status = llc.status()?;
// if !status.success() {
// println!("llc failed: {:?}", status.code().unwrap_or(1));
// } else {
// // compile to executable for replay using `clang`
// let mut clang = Command::new("clang");
// obj = obj.with_extension("o");
// clang
// .arg(obj)
// .arg("--rtlib=compiler-rt")
// .arg("-lkleeRuntest")
// .args(&["-o", replay_name.to_str().unwrap()]);
// if verbose {
// eprintln!("\n{:?}\n", clang);
// }
// // TODO: better error handling, e.g., if `clang` in not installed/in path
// let status = clang.status()?;
// if !status.success() {
// println!("clang failed: {:?}", status.code().unwrap_or(1));
// }
// }
// }
// // klee analysis
// if is_ktest || !is_replay {
// let mut klee = Command::new("klee");
// klee
// // --disable-very to suppress know issue in klee https://github.com/klee/klee/issues/937
// .arg("--disable-verify")
// // --silent-klee-assume, to silence provably false assumptions
// .arg("--silent-klee-assume")
// // ll file to analyse
// .arg(ll.unwrap());
// // execute the command and unwrap the result into status
// let status = klee.status()?;
// if !status.success() {
// return Ok(status.code().unwrap_or(1));
// }
// }
// // replay execution in `gdb`
// if is_gdb {
// 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);
// // set replay name to be loaded by `gdb`
// gdb.arg(replay_name);
// } else {
// // set gdb current dir to the target directory
// gdb.current_dir(replay_name.parent().unwrap());
// // set replay name to be loaded by gdb
// gdb.arg(replay_name.file_name().unwrap());
// };
// if verbose {
// eprintln!("\n{:?}\n", gdb);
// }
// // TODO: better error handling, e.g., if `gdb` is not installed/in path
// let status = gdb.status()?;
// if !status.success() {
// println!("gdb failed: {:?}", status.code().unwrap_or(1));
// }
// }
// // return to shell without error
// Ok(0)
// }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment