From d3d6253cdbb2996a99a7a0350e3624e08beb7b91 Mon Sep 17 00:00:00 2001 From: Paho Lurie-Gregg Date: Thu, 15 Apr 2021 13:08:36 -0700 Subject: [PATCH] Allow stripping of dead code The `-Clink-dead-code` flag was added to fix an error with certain targets. However, it can also cause problems. Example: You depend on crate A which links to library B. A includes an unused reference to `B::foo`. If the specific version of B we have is missing `foo`, we now get a linker error whereas we would not if stripping dead code. --- src/options.rs | 6 ++++++ src/project.rs | 7 +++++-- tests/tests/main.rs | 26 ++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/options.rs b/src/options.rs index 6e71fee..0957027 100644 --- a/src/options.rs +++ b/src/options.rs @@ -123,6 +123,11 @@ pub struct BuildOptions { /// The attribute takes a default value `false`, ensuring that by default, /// the coverage option will be disabled). pub coverage: bool, + + /// Dead code is linked by default to prevent a potential error with some + /// optimized targets. This flag allows you to opt out of it. + #[structopt(long)] + pub strip_dead_code: bool, } impl stdfmt::Display for BuildOptions { @@ -200,6 +205,7 @@ mod test { unstable_flags: Vec::new(), target_dir: None, coverage: false, + strip_dead_code: false, }; let opts = vec![ diff --git a/src/project.rs b/src/project.rs index 794aab5..fc8f42c 100644 --- a/src/project.rs +++ b/src/project.rs @@ -162,10 +162,13 @@ impl FuzzProject { -Cllvm-args=-sanitizer-coverage-level=4 \ -Cllvm-args=-sanitizer-coverage-trace-compares \ -Cllvm-args=-sanitizer-coverage-inline-8bit-counters \ - -Cllvm-args=-sanitizer-coverage-pc-table \ - -Clink-dead-code" + -Cllvm-args=-sanitizer-coverage-pc-table" .to_owned(); + if !build.strip_dead_code { + rustflags.push_str(" -Clink-dead-code"); + } + if build.coverage { rustflags.push_str(" -Zinstrument-coverage"); } diff --git a/tests/tests/main.rs b/tests/tests/main.rs index 63422ab..2745aa8 100644 --- a/tests/tests/main.rs +++ b/tests/tests/main.rs @@ -810,3 +810,29 @@ fn build_dev() { assert!(a_bin.is_file()); assert!(b_bin.is_file()); } + +#[test] +fn build_stripping_dead_code() { + let project = project("build_strip").with_fuzz().build(); + + // Create some targets. + project + .cargo_fuzz() + .arg("add") + .arg("build_strip_a") + .assert() + .success(); + + project + .cargo_fuzz() + .arg("build") + .arg("--strip-dead-code") + .arg("--dev") + .assert() + .success(); + + let build_dir = project.fuzz_build_dir().join("debug"); + + let a_bin = build_dir.join("build_strip_a"); + assert!(a_bin.is_file(), "Not a file: {}", a_bin.display()); +}