From 34a940f6965c9a9f0bbaeab44ddb0f104b69710a Mon Sep 17 00:00:00 2001 From: Afonso Bordado Date: Thu, 25 Aug 2022 17:33:41 +0100 Subject: [PATCH] cranelift: Revert back to fuzzing udivi64 --- cranelift/fuzzgen/src/function_generator.rs | 4 ++-- cranelift/interpreter/src/interpreter.rs | 8 ++++---- cranelift/interpreter/src/step.rs | 4 ++++ fuzz/fuzz_targets/cranelift-fuzzgen.rs | 10 ++++++---- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/cranelift/fuzzgen/src/function_generator.rs b/cranelift/fuzzgen/src/function_generator.rs index a61aa50f09fb..9c68e873d4ae 100644 --- a/cranelift/fuzzgen/src/function_generator.rs +++ b/cranelift/fuzzgen/src/function_generator.rs @@ -833,9 +833,9 @@ where let signature = self.generate_signature()?; (name, signature) } else { - // Use ishli64 as an example of a libcall function. + // Use udivi64 as an example of a libcall function. // TODO: Expand this to more libcall's - let libcall = LibCall::IshlI64; + let libcall = LibCall::UdivI64; let signature = libcall.signature(CallConv::Fast); (ExternalName::LibCall(libcall), signature) }; diff --git a/cranelift/interpreter/src/interpreter.rs b/cranelift/interpreter/src/interpreter.rs index 85fa09681ed1..291c6529d9ca 100644 --- a/cranelift/interpreter/src/interpreter.rs +++ b/cranelift/interpreter/src/interpreter.rs @@ -13,7 +13,7 @@ use cranelift_codegen::data_value::DataValue; use cranelift_codegen::ir::condcodes::{FloatCC, IntCC}; use cranelift_codegen::ir::{ ArgumentPurpose, Block, FuncRef, Function, GlobalValue, GlobalValueData, Heap, LibCall, - StackSlot, Type, Value as ValueRef, + StackSlot, TrapCode, Type, Value as ValueRef, }; use log::trace; use smallvec::SmallVec; @@ -192,7 +192,7 @@ pub enum HeapInit { FromBacking(HeapBacking), } -pub type LibCallHandler<'a, V> = &'a dyn Fn(SmallVec<[V; 1]>) -> SmallVec<[V; 1]>; +pub type LibCallHandler<'a, V> = &'a dyn Fn(SmallVec<[V; 1]>) -> Result, TrapCode>; /// Maintains the [Interpreter]'s state, implementing the [State] trait. pub struct InterpreterState<'a> { @@ -1083,10 +1083,10 @@ mod tests { let state = InterpreterState::default() .with_function_store(env) .with_libcall(LibCall::UdivI64, &|args| { - smallvec![match &args[..] { + Ok(smallvec![match &args[..] { [DataValue::I64(a), DataValue::I64(b)] => DataValue::I64(a / b), _ => panic!("Unexpected args"), - }] + }]) }); let result = Interpreter::new(state) diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index d1bbf0ed081e..d741b04f3959 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -349,6 +349,10 @@ where // We don't transfer control to a libcall, we just execute it and return the results let res = handler(args); + let res = match res { + Err(trap) => return Ok(ControlFlow::Trap(CraneliftTrap::User(trap))), + Ok(rets) => rets, + }; // Check that what the handler returned is what we expect. let rets_diff = res diff --git a/fuzz/fuzz_targets/cranelift-fuzzgen.rs b/fuzz/fuzz_targets/cranelift-fuzzgen.rs index 65429b0a2d17..b87a740c8f2b 100644 --- a/fuzz/fuzz_targets/cranelift-fuzzgen.rs +++ b/fuzz/fuzz_targets/cranelift-fuzzgen.rs @@ -3,7 +3,7 @@ use libfuzzer_sys::fuzz_target; use cranelift_codegen::data_value::DataValue; -use cranelift_codegen::ir::LibCall; +use cranelift_codegen::ir::{LibCall, TrapCode}; use cranelift_codegen::settings; use cranelift_codegen::settings::Configurable; use cranelift_filetests::function_runner::{CompiledFunction, SingleFunctionCompiler}; @@ -61,9 +61,11 @@ fuzz_target!(|testcase: TestCase| { let state = InterpreterState::default() .with_function_store(env) - .with_libcall(LibCall::IshlI64, &|args| match &args[..] { - [DataValue::I64(_), DataValue::I64(b)] if *b > 63 => smallvec![DataValue::I64(0)], - [DataValue::I64(a), DataValue::I64(b)] => smallvec![DataValue::I64(a.shl(b))], + .with_libcall(LibCall::UdivI64, &|args| match &args[..] { + [DataValue::I64(a), DataValue::I64(b)] => a + .checked_div(b) + .map(|res| Ok(smallvec![DataValue::I64(res)])) + .unwrap_or(Err(TrapCode::IntegerDivisionByZero)), _ => unreachable!(), }); let interpreter = Interpreter::new(state).with_fuel(Some(INTERPRETER_FUEL));