From ef21231cf3df7d796514e8a67049bc51482b9261 Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Thu, 14 Sep 2023 13:17:44 +0300 Subject: [PATCH] feat(wasm-gen): create config for precise sys-calls --- utils/wasm-gen/src/config/syscalls.rs | 8 ++-- utils/wasm-gen/src/config/syscalls/amount.rs | 37 +++++++++++-------- utils/wasm-gen/src/generator/syscalls.rs | 10 +++++ .../src/generator/syscalls/imports.rs | 4 +- 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/utils/wasm-gen/src/config/syscalls.rs b/utils/wasm-gen/src/config/syscalls.rs index b9a37a4ed17..c69980e14f9 100644 --- a/utils/wasm-gen/src/config/syscalls.rs +++ b/utils/wasm-gen/src/config/syscalls.rs @@ -57,7 +57,7 @@ impl SysCallsConfigBuilder { /// Set whether `gr_send*` sys-calls must use `gr_source` result for message destination. pub fn with_source_msg_dest(mut self) -> Self { self.0.sending_message_destination = MessageDestination::Source; - self.enable_sys_call(SysCallName::Source); + self.enable_sys_call(InvocableSysCall::Loose(SysCallName::Source)); self } @@ -81,7 +81,7 @@ impl SysCallsConfigBuilder { /// Choosing gear export to log data is done from best `init` to worse `handle`. pub fn with_log_info(mut self, log: String) -> Self { self.0.log_info = Some(log); - self.enable_sys_call(SysCallName::Debug); + self.enable_sys_call(InvocableSysCall::Loose(SysCallName::Debug)); self } @@ -93,7 +93,7 @@ impl SysCallsConfigBuilder { self } - fn enable_sys_call(&mut self, name: SysCallName) { + fn enable_sys_call(&mut self, name: InvocableSysCall) { let range = self.0.injection_amounts.get(name); let range_start = *range.start(); @@ -145,7 +145,7 @@ pub struct SysCallsConfig { impl SysCallsConfig { /// Get possible number of times (range) the sys-call can be injected in the wasm. - pub fn injection_amounts(&self, name: SysCallName) -> RangeInclusive { + pub fn injection_amounts(&self, name: InvocableSysCall) -> RangeInclusive { self.injection_amounts.get(name) } diff --git a/utils/wasm-gen/src/config/syscalls/amount.rs b/utils/wasm-gen/src/config/syscalls/amount.rs index 10653a8ab74..ba830c8a0b4 100644 --- a/utils/wasm-gen/src/config/syscalls/amount.rs +++ b/utils/wasm-gen/src/config/syscalls/amount.rs @@ -20,36 +20,43 @@ //! //! Types here are used to create [`crate::SysCallsConfig`]. +use crate::InvocableSysCall; + use gear_wasm_instrument::syscalls::SysCallName; use std::{collections::HashMap, ops::RangeInclusive}; /// Possible injection amount ranges for each sys-call. #[derive(Debug, Clone)] -pub struct SysCallsInjectionAmounts(HashMap>); +pub struct SysCallsInjectionAmounts(HashMap>); impl SysCallsInjectionAmounts { - /// Instantiate a sys-calls amounts ranges map, where each gear sys-call is injected into wasm-module only once. - pub fn all_once() -> Self { + fn new_with_range(range: RangeInclusive) -> Self { + let sys_calls = SysCallName::instrumentable(); Self( - SysCallName::instrumentable() - .into_iter() - .map(|name| (name, (1..=1))) + sys_calls + .iter() + .cloned() + .map(|name| (InvocableSysCall::Loose(name), range.clone())) + .chain(sys_calls.iter().cloned().filter_map(|name| { + InvocableSysCall::has_precise_variant(name) + .then_some((InvocableSysCall::Precise(name), range.clone())) + })) .collect(), ) } + /// Instantiate a sys-calls amounts ranges map, where each gear sys-call is injected into wasm-module only once. + pub fn all_once() -> Self { + Self::new_with_range(1..=1) + } + /// Instantiate a sys-calls amounts ranges map, where no gear sys-call is ever injected into wasm-module. pub fn all_never() -> Self { - Self( - SysCallName::instrumentable() - .into_iter() - .map(|name| (name, (0..=0))) - .collect(), - ) + Self::new_with_range(0..=0) } /// Get amount possible sys-call amount range. - pub fn get(&self, name: SysCallName) -> RangeInclusive { + pub fn get(&self, name: InvocableSysCall) -> RangeInclusive { self.0 .get(&name) .cloned() @@ -57,14 +64,14 @@ impl SysCallsInjectionAmounts { } /// Sets possible amount range for the the sys-call. - pub fn set(&mut self, name: SysCallName, min: u32, max: u32) { + pub fn set(&mut self, name: InvocableSysCall, min: u32, max: u32) { self.0.insert(name, min..=max); } /// Same as [`SysCallsAmountRanges::set`], but sets amount ranges for multiple sys-calls. pub fn set_multiple( &mut self, - sys_calls_freqs: impl Iterator)>, + sys_calls_freqs: impl Iterator)>, ) { self.0.extend(sys_calls_freqs) } diff --git a/utils/wasm-gen/src/generator/syscalls.rs b/utils/wasm-gen/src/generator/syscalls.rs index 5b667c216fe..7675c1c38ca 100644 --- a/utils/wasm-gen/src/generator/syscalls.rs +++ b/utils/wasm-gen/src/generator/syscalls.rs @@ -113,6 +113,16 @@ impl InvocableSysCall { } } + pub(crate) fn has_precise_variant(sys_call: SysCallName) -> bool { + matches!( + sys_call, + SysCallName::ReservationSend + | SysCallName::ReservationReply + | SysCallName::SendCommit + | SysCallName::SendCommitWGas + ) + } + // If syscall changes from fallible into infallible or vice versa in future, // we'll see it by analyzing code coverage stats produced by fuzzer. pub(crate) fn is_fallible(&self) -> bool { diff --git a/utils/wasm-gen/src/generator/syscalls/imports.rs b/utils/wasm-gen/src/generator/syscalls/imports.rs index 8389f943f08..b066513fabb 100644 --- a/utils/wasm-gen/src/generator/syscalls/imports.rs +++ b/utils/wasm-gen/src/generator/syscalls/imports.rs @@ -223,7 +223,9 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { &mut self, sys_call: SysCallName, ) -> Result> { - let sys_call_amount_range = self.config.injection_amounts(sys_call); + let sys_call_amount_range = self + .config + .injection_amounts(InvocableSysCall::Loose(sys_call)); let sys_call_amount = self.unstructured.int_in_range(sys_call_amount_range)?; Ok((sys_call_amount != 0).then(|| { let call_indexes_handle = self.insert_sys_call_import(sys_call);