mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
add --fuzz
option to roc
This commit is contained in:
parent
5652da0562
commit
abc4fd18cc
3 changed files with 46 additions and 27 deletions
|
@ -68,6 +68,7 @@ pub const FLAG_STDIN: &str = "stdin";
|
||||||
pub const FLAG_STDOUT: &str = "stdout";
|
pub const FLAG_STDOUT: &str = "stdout";
|
||||||
pub const FLAG_WASM_STACK_SIZE_KB: &str = "wasm-stack-size-kb";
|
pub const FLAG_WASM_STACK_SIZE_KB: &str = "wasm-stack-size-kb";
|
||||||
pub const FLAG_OUTPUT: &str = "output";
|
pub const FLAG_OUTPUT: &str = "output";
|
||||||
|
pub const FLAG_FUZZ: &str = "fuzz";
|
||||||
pub const ROC_FILE: &str = "ROC_FILE";
|
pub const ROC_FILE: &str = "ROC_FILE";
|
||||||
pub const ROC_DIR: &str = "ROC_DIR";
|
pub const ROC_DIR: &str = "ROC_DIR";
|
||||||
pub const GLUE_DIR: &str = "GLUE_DIR";
|
pub const GLUE_DIR: &str = "GLUE_DIR";
|
||||||
|
@ -139,6 +140,12 @@ pub fn build_app() -> Command {
|
||||||
.value_parser(value_parser!(u32))
|
.value_parser(value_parser!(u32))
|
||||||
.required(false);
|
.required(false);
|
||||||
|
|
||||||
|
let flag_fuzz = Arg::new(FLAG_FUZZ)
|
||||||
|
.long(FLAG_FUZZ)
|
||||||
|
.help("Instrument the roc binary for fuzzing with roc-fuzz")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.required(false);
|
||||||
|
|
||||||
let roc_file_to_run = Arg::new(ROC_FILE)
|
let roc_file_to_run = Arg::new(ROC_FILE)
|
||||||
.help("The .roc file of an app to run")
|
.help("The .roc file of an app to run")
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
|
@ -175,6 +182,7 @@ pub fn build_app() -> Command {
|
||||||
.arg(flag_time.clone())
|
.arg(flag_time.clone())
|
||||||
.arg(flag_linker.clone())
|
.arg(flag_linker.clone())
|
||||||
.arg(flag_prebuilt.clone())
|
.arg(flag_prebuilt.clone())
|
||||||
|
.arg(flag_fuzz.clone())
|
||||||
.arg(flag_wasm_stack_size_kb)
|
.arg(flag_wasm_stack_size_kb)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(FLAG_TARGET)
|
Arg::new(FLAG_TARGET)
|
||||||
|
@ -225,6 +233,7 @@ pub fn build_app() -> Command {
|
||||||
.arg(flag_time.clone())
|
.arg(flag_time.clone())
|
||||||
.arg(flag_linker.clone())
|
.arg(flag_linker.clone())
|
||||||
.arg(flag_prebuilt.clone())
|
.arg(flag_prebuilt.clone())
|
||||||
|
.arg(flag_fuzz.clone())
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(ROC_FILE)
|
Arg::new(ROC_FILE)
|
||||||
.help("The .roc file for the main module")
|
.help("The .roc file for the main module")
|
||||||
|
@ -248,6 +257,7 @@ pub fn build_app() -> Command {
|
||||||
.arg(flag_time.clone())
|
.arg(flag_time.clone())
|
||||||
.arg(flag_linker.clone())
|
.arg(flag_linker.clone())
|
||||||
.arg(flag_prebuilt.clone())
|
.arg(flag_prebuilt.clone())
|
||||||
|
.arg(flag_fuzz.clone())
|
||||||
.arg(roc_file_to_run.clone())
|
.arg(roc_file_to_run.clone())
|
||||||
.arg(args_for_app.clone().last(true))
|
.arg(args_for_app.clone().last(true))
|
||||||
)
|
)
|
||||||
|
@ -262,6 +272,7 @@ pub fn build_app() -> Command {
|
||||||
.arg(flag_time.clone())
|
.arg(flag_time.clone())
|
||||||
.arg(flag_linker.clone())
|
.arg(flag_linker.clone())
|
||||||
.arg(flag_prebuilt.clone())
|
.arg(flag_prebuilt.clone())
|
||||||
|
.arg(flag_fuzz.clone())
|
||||||
.arg(roc_file_to_run.clone())
|
.arg(roc_file_to_run.clone())
|
||||||
.arg(args_for_app.clone().last(true))
|
.arg(args_for_app.clone().last(true))
|
||||||
)
|
)
|
||||||
|
@ -393,6 +404,7 @@ pub fn build_app() -> Command {
|
||||||
.arg(flag_time)
|
.arg(flag_time)
|
||||||
.arg(flag_linker)
|
.arg(flag_linker)
|
||||||
.arg(flag_prebuilt)
|
.arg(flag_prebuilt)
|
||||||
|
.arg(flag_fuzz)
|
||||||
.arg(roc_file_to_run)
|
.arg(roc_file_to_run)
|
||||||
.arg(args_for_app.trailing_var_arg(true))
|
.arg(args_for_app.trailing_var_arg(true))
|
||||||
}
|
}
|
||||||
|
@ -748,6 +760,11 @@ pub fn build(
|
||||||
(cross_compile && !targeting_wasm)
|
(cross_compile && !targeting_wasm)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let fuzz = matches.get_flag(FLAG_FUZZ);
|
||||||
|
if fuzz && !matches!(code_gen_backend, CodeGenBackend::Llvm(_)) {
|
||||||
|
user_error!("Cannot instrument binary for fuzzing while using a dev backend.");
|
||||||
|
}
|
||||||
|
|
||||||
let wasm_dev_stack_bytes: Option<u32> = matches
|
let wasm_dev_stack_bytes: Option<u32> = matches
|
||||||
.try_get_one::<u32>(FLAG_WASM_STACK_SIZE_KB)
|
.try_get_one::<u32>(FLAG_WASM_STACK_SIZE_KB)
|
||||||
.ok()
|
.ok()
|
||||||
|
@ -764,6 +781,7 @@ pub fn build(
|
||||||
opt_level,
|
opt_level,
|
||||||
emit_debug_info,
|
emit_debug_info,
|
||||||
emit_llvm_ir,
|
emit_llvm_ir,
|
||||||
|
fuzz,
|
||||||
};
|
};
|
||||||
|
|
||||||
let load_config = standard_load_config(&triple, build_ordering, threading);
|
let load_config = standard_load_config(&triple, build_ordering, threading);
|
||||||
|
|
|
@ -86,6 +86,7 @@ pub struct CodeGenOptions {
|
||||||
pub opt_level: OptLevel,
|
pub opt_level: OptLevel,
|
||||||
pub emit_debug_info: bool,
|
pub emit_debug_info: bool,
|
||||||
pub emit_llvm_ir: bool,
|
pub emit_llvm_ir: bool,
|
||||||
|
pub fuzz: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
type GenFromMono<'a> = (CodeObject, CodeGenTiming, ExpectMetadata<'a>);
|
type GenFromMono<'a> = (CodeObject, CodeGenTiming, ExpectMetadata<'a>);
|
||||||
|
@ -103,6 +104,7 @@ pub fn gen_from_mono_module<'a>(
|
||||||
let path = roc_file_path;
|
let path = roc_file_path;
|
||||||
let debug = code_gen_options.emit_debug_info;
|
let debug = code_gen_options.emit_debug_info;
|
||||||
let emit_llvm_ir = code_gen_options.emit_llvm_ir;
|
let emit_llvm_ir = code_gen_options.emit_llvm_ir;
|
||||||
|
let fuzz = code_gen_options.fuzz;
|
||||||
let opt = code_gen_options.opt_level;
|
let opt = code_gen_options.opt_level;
|
||||||
|
|
||||||
match code_gen_options.backend {
|
match code_gen_options.backend {
|
||||||
|
@ -131,6 +133,7 @@ pub fn gen_from_mono_module<'a>(
|
||||||
backend_mode,
|
backend_mode,
|
||||||
debug,
|
debug,
|
||||||
emit_llvm_ir,
|
emit_llvm_ir,
|
||||||
|
fuzz,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,6 +151,7 @@ fn gen_from_mono_module_llvm<'a>(
|
||||||
backend_mode: LlvmBackendMode,
|
backend_mode: LlvmBackendMode,
|
||||||
emit_debug_info: bool,
|
emit_debug_info: bool,
|
||||||
emit_llvm_ir: bool,
|
emit_llvm_ir: bool,
|
||||||
|
fuzz: bool,
|
||||||
) -> GenFromMono<'a> {
|
) -> GenFromMono<'a> {
|
||||||
use crate::target::{self, convert_opt_level};
|
use crate::target::{self, convert_opt_level};
|
||||||
use inkwell::attributes::{Attribute, AttributeLoc};
|
use inkwell::attributes::{Attribute, AttributeLoc};
|
||||||
|
@ -284,7 +288,8 @@ fn gen_from_mono_module_llvm<'a>(
|
||||||
|
|
||||||
// annotate the LLVM IR output with debug info
|
// annotate the LLVM IR output with debug info
|
||||||
// so errors are reported with the line number of the LLVM source
|
// so errors are reported with the line number of the LLVM source
|
||||||
let memory_buffer = if cfg!(feature = "sanitizers") && std::env::var("ROC_SANITIZERS").is_ok() {
|
let gen_sanitizers = cfg!(feature = "sanitizers") && std::env::var("ROC_SANITIZERS").is_ok();
|
||||||
|
let memory_buffer = if fuzz || gen_sanitizers {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let dir = tempfile::tempdir().unwrap();
|
||||||
let dir = dir.into_path();
|
let dir = dir.into_path();
|
||||||
|
|
||||||
|
@ -301,33 +306,27 @@ fn gen_from_mono_module_llvm<'a>(
|
||||||
let mut passes = vec![];
|
let mut passes = vec![];
|
||||||
let mut extra_args = vec![];
|
let mut extra_args = vec![];
|
||||||
let mut unrecognized = vec![];
|
let mut unrecognized = vec![];
|
||||||
for sanitizer in std::env::var("ROC_SANITIZERS")
|
if fuzz {
|
||||||
.unwrap()
|
passes.push("sancov-module");
|
||||||
.split(',')
|
extra_args.extend_from_slice(&[
|
||||||
.map(|x| x.trim())
|
"-sanitizer-coverage-level=4",
|
||||||
{
|
"-sanitizer-coverage-inline-8bit-counters",
|
||||||
match sanitizer {
|
"-sanitizer-coverage-pc-table",
|
||||||
"address" => passes.push("asan-module"),
|
"-sanitizer-coverage-trace-compares",
|
||||||
"memory" => passes.push("msan-module"),
|
]);
|
||||||
"thread" => passes.push("tsan-module"),
|
}
|
||||||
"cargo-fuzz" => {
|
if gen_sanitizers {
|
||||||
passes.push("sancov-module");
|
for sanitizer in std::env::var("ROC_SANITIZERS")
|
||||||
extra_args.extend_from_slice(&[
|
.unwrap()
|
||||||
"-sanitizer-coverage-level=3",
|
.split(',')
|
||||||
"-sanitizer-coverage-prune-blocks=0",
|
.map(|x| x.trim())
|
||||||
"-sanitizer-coverage-inline-8bit-counters",
|
{
|
||||||
"-sanitizer-coverage-pc-table",
|
match sanitizer {
|
||||||
]);
|
"address" => passes.push("asan-module"),
|
||||||
|
"memory" => passes.push("msan-module"),
|
||||||
|
"thread" => passes.push("tsan-module"),
|
||||||
|
x => unrecognized.push(x.to_owned()),
|
||||||
}
|
}
|
||||||
"afl.rs" => {
|
|
||||||
passes.push("sancov-module");
|
|
||||||
extra_args.extend_from_slice(&[
|
|
||||||
"-sanitizer-coverage-level=3",
|
|
||||||
"-sanitizer-coverage-prune-blocks=0",
|
|
||||||
"-sanitizer-coverage-trace-pc-guard",
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
x => unrecognized.push(x.to_owned()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !unrecognized.is_empty() {
|
if !unrecognized.is_empty() {
|
||||||
|
@ -1291,6 +1290,7 @@ pub fn build_str_test<'a>(
|
||||||
opt_level: OptLevel::Normal,
|
opt_level: OptLevel::Normal,
|
||||||
emit_debug_info: false,
|
emit_debug_info: false,
|
||||||
emit_llvm_ir: false,
|
emit_llvm_ir: false,
|
||||||
|
fuzz: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let emit_timings = false;
|
let emit_timings = false;
|
||||||
|
|
|
@ -57,6 +57,7 @@ pub fn generate(
|
||||||
opt_level: OptLevel::Development,
|
opt_level: OptLevel::Development,
|
||||||
emit_debug_info: false,
|
emit_debug_info: false,
|
||||||
emit_llvm_ir: false,
|
emit_llvm_ir: false,
|
||||||
|
fuzz: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let load_config = standard_load_config(
|
let load_config = standard_load_config(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue