From 5b931e25403d62a1231c117c63baeed533972147 Mon Sep 17 00:00:00 2001 From: Sabaun Taraki Date: Tue, 10 Oct 2023 23:27:21 +0300 Subject: [PATCH] refactor(wasm-gen): Clean-up wasm-gen (#3384) --- utils/node-loader/src/utils.rs | 2 +- utils/runtime-fuzzer/src/gear_calls.rs | 2 +- utils/wasm-gen/src/config.rs | 26 +- utils/wasm-gen/src/config/generator.rs | 10 +- utils/wasm-gen/src/config/module.rs | 13 +- utils/wasm-gen/src/config/syscalls.rs | 52 +-- .../wasm-gen/src/config/syscalls/injection.rs | 66 +-- utils/wasm-gen/src/config/syscalls/param.rs | 8 +- utils/wasm-gen/src/config/syscalls/precise.rs | 8 +- utils/wasm-gen/src/generator.rs | 62 ++- utils/wasm-gen/src/generator/syscalls.rs | 50 +-- .../src/generator/syscalls/additional_data.rs | 21 +- .../src/generator/syscalls/imports.rs | 387 +++++++++--------- .../src/generator/syscalls/invocator.rs | 175 ++++---- utils/wasm-gen/src/tests.rs | 22 +- 15 files changed, 478 insertions(+), 426 deletions(-) diff --git a/utils/node-loader/src/utils.rs b/utils/node-loader/src/utils.rs index 821c798f218..c73cd4bd07a 100644 --- a/utils/node-loader/src/utils.rs +++ b/utils/node-loader/src/utils.rs @@ -224,7 +224,7 @@ pub fn get_wasm_gen_config( (SysCallName::Alloc, 3..=6), (SysCallName::Free, 3..=6), ] - .map(|(sys_call, range)| (InvocableSysCall::Loose(sys_call), range)) + .map(|(syscall, range)| (InvocableSysCall::Loose(syscall), range)) .into_iter(), ); diff --git a/utils/runtime-fuzzer/src/gear_calls.rs b/utils/runtime-fuzzer/src/gear_calls.rs index 5ec2c255dc4..e5dd10e7133 100644 --- a/utils/runtime-fuzzer/src/gear_calls.rs +++ b/utils/runtime-fuzzer/src/gear_calls.rs @@ -420,7 +420,7 @@ fn config( (SysCallName::Alloc, 3..=6), (SysCallName::Free, 3..=6), ] - .map(|(sys_call, range)| (InvocableSysCall::Loose(sys_call), range)) + .map(|(syscall, range)| (InvocableSysCall::Loose(syscall), range)) .into_iter(), ); diff --git a/utils/wasm-gen/src/config.rs b/utils/wasm-gen/src/config.rs index a8edb35f91a..2ec76ebfeb7 100644 --- a/utils/wasm-gen/src/config.rs +++ b/utils/wasm-gen/src/config.rs @@ -22,6 +22,7 @@ //! 1. From scratch by settings fields to corresponding values sometimes using //! related to these fields builders. For example, wasm module configs: //! ```rust +//! # use std::num::NonZeroUsize; //! use gear_wasm_gen::*; //! use arbitrary::{Arbitrary, Result, Unstructured}; //! @@ -38,8 +39,8 @@ //! InstructionKind::Control, //! ], //! max_instructions: 100_000, -//! min_funcs: 15, -//! max_funcs: 30, +//! min_funcs: NonZeroUsize::new(15).unwrap(), +//! max_funcs: NonZeroUsize::new(30).unwrap(), //! unreachable_enabled: true, //! }; //! let arbitrary = ArbitraryParams::arbitrary(u)?; @@ -55,7 +56,7 @@ //! stack_end_page: Some(64), //! }; //! let entry_points_set = EntryPointsSet::InitHandle; -//! let sys_calls_config = SysCallsConfigBuilder::new(SysCallsInjectionTypes::all_once()) +//! let syscalls_config = SysCallsConfigBuilder::new(SysCallsInjectionTypes::all_once()) //! .with_source_msg_dest() //! .with_log_info("I'm from wasm-gen".into()) //! .build(); @@ -64,7 +65,7 @@ //! memory_config: memory_pages_config, //! entry_points_config: entry_points_set, //! remove_recursions: true, -//! sys_calls_config, +//! syscalls_config, //! }; //! ``` //! @@ -144,7 +145,7 @@ pub struct StandardGearWasmConfigsBundle { /// Flag which signals whether `call_indirect` instruction must be used /// during wasm generation. pub call_indirect_enabled: bool, - /// Injection amount ranges for each sys-call. + /// Injection type for each syscall. pub injection_types: SysCallsInjectionTypes, /// Config of gear wasm call entry-points (exports). pub entry_points_set: EntryPointsSet, @@ -152,7 +153,7 @@ pub struct StandardGearWasmConfigsBundle { pub initial_pages: u32, /// Optional stack end pages. pub stack_end_page: Option, - /// Sys-calls params config + /// Syscalls params config pub params_config: SysCallsParamsConfig, /// Flag which signals whether `unreachable` instruction must be used /// during wasm generation. @@ -197,17 +198,16 @@ impl> ConfigsBundle for StandardGearWasmConfigsBundle { ..SelectableParams::default() }; - let mut sys_calls_config_builder = SysCallsConfigBuilder::new(injection_types); + let mut syscalls_config_builder = SysCallsConfigBuilder::new(injection_types); if let Some(log_info) = log_info { - sys_calls_config_builder = sys_calls_config_builder.with_log_info(log_info); + syscalls_config_builder = syscalls_config_builder.with_log_info(log_info); } if let Some(addresses) = existing_addresses { - sys_calls_config_builder = - sys_calls_config_builder.with_data_offset_msg_dest(addresses); + syscalls_config_builder = syscalls_config_builder.with_data_offset_msg_dest(addresses); } else { - sys_calls_config_builder = sys_calls_config_builder.with_source_msg_dest(); + syscalls_config_builder = syscalls_config_builder.with_source_msg_dest(); } - sys_calls_config_builder = sys_calls_config_builder.with_params_config(params_config); + syscalls_config_builder = syscalls_config_builder.with_params_config(params_config); let memory_pages_config = MemoryPagesConfig { initial_size: initial_pages, @@ -216,7 +216,7 @@ impl> ConfigsBundle for StandardGearWasmConfigsBundle { }; let gear_wasm_generator_config = GearWasmGeneratorConfigBuilder::new() .with_recursions_removed(remove_recursion) - .with_sys_calls_config(sys_calls_config_builder.build()) + .with_syscalls_config(syscalls_config_builder.build()) .with_entry_points_config(entry_points_set) .with_memory_config(memory_pages_config) .build(); diff --git a/utils/wasm-gen/src/config/generator.rs b/utils/wasm-gen/src/config/generator.rs index 7d831396143..2c1da46750f 100644 --- a/utils/wasm-gen/src/config/generator.rs +++ b/utils/wasm-gen/src/config/generator.rs @@ -46,9 +46,9 @@ impl GearWasmGeneratorConfigBuilder { self } - /// Defines sys-calls config for the gear wasm generator. - pub fn with_sys_calls_config(mut self, sys_calls_config: SysCallsConfig) -> Self { - self.0.sys_calls_config = sys_calls_config; + /// Defines syscalls config for the gear wasm generator. + pub fn with_syscalls_config(mut self, syscalls_config: SysCallsConfig) -> Self { + self.0.syscalls_config = syscalls_config; self } @@ -76,8 +76,8 @@ pub struct GearWasmGeneratorConfig { pub memory_config: MemoryPagesConfig, /// Entry points config. pub entry_points_config: EntryPointsSet, - /// Sys-calls generator module config. - pub sys_calls_config: SysCallsConfig, + /// Syscalls generator module config. + pub syscalls_config: SysCallsConfig, /// Flag, signalizing whether recursions /// should be removed from resulting module. pub remove_recursions: bool, diff --git a/utils/wasm-gen/src/config/module.rs b/utils/wasm-gen/src/config/module.rs index 4690382a667..709c35a2678 100644 --- a/utils/wasm-gen/src/config/module.rs +++ b/utils/wasm-gen/src/config/module.rs @@ -23,6 +23,8 @@ //! can be arbitrary, but some must be constantly set. That's implemented with [`ArbitraryParams`] //! and [`ConstantParams`]. +use std::num::NonZeroUsize; + use arbitrary::{Arbitrary, Result, Unstructured}; pub use wasm_smith::InstructionKind; use wasm_smith::{InstructionKind::*, InstructionKinds, SwarmConfig}; @@ -88,6 +90,9 @@ impl From<(SelectableParams, ArbitraryParams)> for WasmModuleConfig { unreachable_enabled, } = selectable_params; + let min_funcs = min_funcs.get(); + let max_funcs = max_funcs.get(); + let ArbitraryParams { available_imports, canonicalize_nans, @@ -352,10 +357,10 @@ pub struct SelectableParams { pub max_instructions: usize, /// Minimum amount of functions `wasm-gen` will insert /// into generated wasm. - pub min_funcs: usize, + pub min_funcs: NonZeroUsize, /// Maximum amount of functions `wasm-gen` will insert /// into generated wasm. - pub max_funcs: usize, + pub max_funcs: NonZeroUsize, /// Flag signalizing whether `unreachable` instruction /// must be used or not. pub unreachable_enabled: bool, @@ -369,8 +374,8 @@ impl Default for SelectableParams { Numeric, Reference, Parametric, Variable, Table, Memory, Control, ], max_instructions: 500, - min_funcs: 3, - max_funcs: 5, + min_funcs: NonZeroUsize::new(3).expect("from non zero value; qed."), + max_funcs: NonZeroUsize::new(5).expect("from non zero value; qed."), unreachable_enabled: true, } } diff --git a/utils/wasm-gen/src/config/syscalls.rs b/utils/wasm-gen/src/config/syscalls.rs index 2eab5e4dc5d..143f0ec826f 100644 --- a/utils/wasm-gen/src/config/syscalls.rs +++ b/utils/wasm-gen/src/config/syscalls.rs @@ -16,8 +16,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Configuration for the sys-calls imports generator, additional data injector -//! and sys-calls invocations generator. +//! Configuration for the syscalls imports generator, additional data injector +//! and syscalls invocations generator. mod injection; mod param; @@ -39,26 +39,26 @@ use crate::InvocableSysCall; pub struct SysCallsConfigBuilder(SysCallsConfig); impl SysCallsConfigBuilder { - /// Create a new builder with defined injection amounts for all sys-calls. + /// Create a new builder with defined injection amounts for all syscalls. pub fn new(injection_types: SysCallsInjectionTypes) -> Self { Self(SysCallsConfig { injection_types, params_config: SysCallsParamsConfig::default(), precise_syscalls_config: PreciseSysCallsConfig::default(), - sys_call_destination: SysCallDestination::default(), + syscall_destination: SysCallDestination::default(), error_processing_config: ErrorProcessingConfig::None, log_info: None, }) } - /// Set config for sys-calls params. + /// Set config for syscalls params. pub fn with_params_config(mut self, params_config: SysCallsParamsConfig) -> Self { self.0.params_config = params_config; self } - /// Set config for precise sys-calls. + /// Set config for precise syscalls. pub fn with_precise_syscalls_config( mut self, precise_syscalls_config: PreciseSysCallsConfig, @@ -68,25 +68,25 @@ impl SysCallsConfigBuilder { self } - /// Set whether `gr_send*` and `gr_exit` sys-calls must use `gr_source` result for sys-call destination. + /// Set whether `gr_send*` and `gr_exit` syscalls must use `gr_source` result for syscall destination. pub fn with_source_msg_dest(mut self) -> Self { - self.0.sys_call_destination = SysCallDestination::Source; + self.0.syscall_destination = SysCallDestination::Source; self.0 .injection_types - .enable_sys_call_import(InvocableSysCall::Loose(SysCallName::Source)); + .enable_syscall_import(InvocableSysCall::Loose(SysCallName::Source)); self } - /// Set whether `gr_send*` and `gr_exit` sys-calls must use some address from `addresses` collection - /// as a sys-call destination. + /// Set whether `gr_send*` and `gr_exit` syscalls must use some address from `addresses` collection + /// as a syscall destination. pub fn with_data_offset_msg_dest>(mut self, addresses: NonEmpty) -> Self { let addresses = NonEmpty::collect(addresses.into_iter().map(|pid| HashWithValue { hash: pid.into(), value: 0, })) .expect("collected from non empty"); - self.0.sys_call_destination = SysCallDestination::ExistingAddresses(addresses); + self.0.syscall_destination = SysCallDestination::ExistingAddresses(addresses); self } @@ -99,7 +99,7 @@ impl SysCallsConfigBuilder { self.0.log_info = Some(log); self.0 .injection_types - .enable_sys_call_import(InvocableSysCall::Loose(SysCallName::Debug)); + .enable_syscall_import(InvocableSysCall::Loose(SysCallName::Debug)); self } @@ -141,28 +141,28 @@ impl ErrorProcessingConfig { } } -/// United config for all entities in sys-calls generator module. +/// United config for all entities in syscalls generator module. #[derive(Debug, Clone, Default)] pub struct SysCallsConfig { injection_types: SysCallsInjectionTypes, params_config: SysCallsParamsConfig, precise_syscalls_config: PreciseSysCallsConfig, - sys_call_destination: SysCallDestination, + syscall_destination: SysCallDestination, error_processing_config: ErrorProcessingConfig, log_info: Option, } impl SysCallsConfig { - /// Get possible number of times (range) the sys-call can be injected in the wasm. + /// Get possible number of times (range) the syscall can be injected in the wasm. pub fn injection_types(&self, name: InvocableSysCall) -> SysCallInjectionType { self.injection_types.get(name) } - /// Get defined sys-call destination for `gr_send*` and `gr_exit` sys-calls. + /// Get defined syscall destination for `gr_send*` and `gr_exit` syscalls. /// /// For more info, read [`SysCallDestination`]. - pub fn sys_call_destination(&self) -> &SysCallDestination { - &self.sys_call_destination + pub fn syscall_destination(&self) -> &SysCallDestination { + &self.syscall_destination } /// Get defined log info. @@ -172,12 +172,12 @@ impl SysCallsConfig { self.log_info.as_ref() } - /// Get sys-calls params config. + /// Get syscalls params config. pub fn params_config(&self) -> &SysCallsParamsConfig { &self.params_config } - /// Get precise sys-calls config. + /// Get precise syscalls config. pub fn precise_syscalls_config(&self) -> &PreciseSysCallsConfig { &self.precise_syscalls_config } @@ -188,9 +188,9 @@ impl SysCallsConfig { } } -/// Sys-call destination choice. +/// Syscall destination choice. /// -/// `gr_send*` and `gr_exit` sys-calls generated from this crate can be sent +/// `gr_send*` and `gr_exit` syscalls generated from this crate can be sent /// to different destination in accordance to the config. /// It's either to the message source, to some existing known address, /// or to some random, most probably non-existing, address. @@ -203,17 +203,17 @@ pub enum SysCallDestination { } impl SysCallDestination { - /// Check whether sys-call destination is a result of `gr_source`. + /// Check whether syscall destination is a result of `gr_source`. pub fn is_source(&self) -> bool { matches!(&self, SysCallDestination::Source) } - /// Check whether sys-call destination is defined randomly. + /// Check whether syscall destination is defined randomly. pub fn is_random(&self) -> bool { matches!(&self, SysCallDestination::Random) } - /// Check whether sys-call destination is defined from a collection of existing addresses. + /// Check whether syscall destination is defined from a collection of existing addresses. pub fn is_existing_addresses(&self) -> bool { matches!(&self, SysCallDestination::ExistingAddresses(_)) } diff --git a/utils/wasm-gen/src/config/syscalls/injection.rs b/utils/wasm-gen/src/config/syscalls/injection.rs index c466f552810..5b6694a0c68 100644 --- a/utils/wasm-gen/src/config/syscalls/injection.rs +++ b/utils/wasm-gen/src/config/syscalls/injection.rs @@ -16,8 +16,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Entities describing possible injection types for each sys-call. -//! These entities allows to configure which sys-calls to insert into +//! Entities describing possible injection types for each syscall. +//! These entities allows to configure which syscalls to insert into //! code section of wasm module and which ones to simply import. //! //! Types here are used to create [`crate::SysCallsConfig`]. @@ -27,50 +27,54 @@ use crate::InvocableSysCall; use gear_wasm_instrument::syscalls::SysCallName; use std::{collections::HashMap, ops::RangeInclusive}; -/// This enum defines how the sys-call should be injected into wasm module. +/// This enum defines how the syscall should be injected into wasm module. #[derive(Debug, Clone)] pub enum SysCallInjectionType { /// Don't modify wasm module at all. None, - /// Sys-call import will be injected into import section of wasm module, - /// but the `wasm-gen` generators will not call that sys-call. + /// Syscall import will be injected into import section of wasm module, + /// but the `wasm-gen` generators will not call that syscall. /// - /// It should be used in cases where you don't need to invoke an actual sys-call. - /// For example, `precision_gr_reservation_send` sys-call uses `gr_reserve_gas` under + /// It should be used in cases where you don't need to invoke an actual syscall. + /// For example, `precision_gr_reservation_send` syscall uses `gr_reserve_gas` under /// the hood. In this case, `gr_reserve_gas` will be imported but will not be called. Import, - /// Sys-call import will be injected into import section of wasm module, - /// and the `wasm-gen` generators will insert invoke instructions for that sys-call. + /// Syscall import will be injected into import section of wasm module, + /// and the `wasm-gen` generators can insert invoke instructions for that syscall. /// - /// It also has `sys_call_amount_range: RangeInclusive` - the range from which - /// amount of sys-calls will be generated for injection into code section of wasm module. + /// It wraps syscall amount range `RangeInclusive` - the range from which + /// amount of the syscall invocations will be generated. + /// + /// Setting range to `(0..=n)`, where `n >= 0` can imitate `SysCallInjectionType::Import`, + /// as in case if syscall amount range is zero, then syscall import will be injected, but + /// no invocations will be generated, which is pretty similar to the other variant. Function(RangeInclusive), } -/// Possible injection types for each sys-call. +/// Possible injection types for each syscall. #[derive(Debug, Clone)] pub struct SysCallsInjectionTypes(HashMap); impl SysCallsInjectionTypes { - /// Instantiate a sys-calls map, where each gear sys-call is injected into wasm-module only once. + /// Instantiate a syscalls map, where each gear syscall is injected into wasm-module only once. pub fn all_once() -> Self { Self::new_with_injection_type(SysCallInjectionType::Function(1..=1)) } - /// Instantiate a sys-calls map, where no gear sys-call is ever injected into wasm-module. + /// Instantiate a syscalls map, where no gear syscall is ever injected into wasm-module. pub fn all_never() -> Self { Self::new_with_injection_type(SysCallInjectionType::None) } - /// Instantiate a sys-calls map with given injection type. + /// Instantiate a syscalls map with given injection type. fn new_with_injection_type(injection_type: SysCallInjectionType) -> Self { - let sys_calls = SysCallName::instrumentable(); + let syscalls = SysCallName::instrumentable(); Self( - sys_calls + syscalls .iter() .cloned() .map(|name| (InvocableSysCall::Loose(name), injection_type.clone())) - .chain(sys_calls.iter().cloned().filter_map(|name| { + .chain(syscalls.iter().cloned().filter_map(|name| { InvocableSysCall::has_precise_variant(name) .then_some((InvocableSysCall::Precise(name), injection_type.clone())) })) @@ -78,43 +82,45 @@ impl SysCallsInjectionTypes { ) } - /// Gets injection type for given sys-call. + /// Gets injection type for given syscall. pub fn get(&self, name: InvocableSysCall) -> SysCallInjectionType { self.0 .get(&name) .cloned() - .expect("instantiated with all sys-calls set") + .expect("instantiated with all syscalls set") } - /// Sets possible amount range for the the sys-call. + /// Sets possible amount range for the the syscall. + /// + /// Sets injection type for `name` syscall to `SysCallInjectionType::Function`. pub fn set(&mut self, name: InvocableSysCall, min: u32, max: u32) { self.0 .insert(name, SysCallInjectionType::Function(min..=max)); - if let InvocableSysCall::Precise(sys_call) = name { - let Some(required_imports) = InvocableSysCall::required_imports_for_sys_call(sys_call) else { + if let InvocableSysCall::Precise(syscall) = name { + let Some(required_imports) = InvocableSysCall::required_imports_for_syscall(syscall) else { return; }; - for &sys_call_import in required_imports { - self.enable_sys_call_import(InvocableSysCall::Loose(sys_call_import)); + for &syscall_import in required_imports { + self.enable_syscall_import(InvocableSysCall::Loose(syscall_import)); } } } - /// Imports the given sys-call if necessary. - pub(crate) fn enable_sys_call_import(&mut self, name: InvocableSysCall) { + /// Imports the given syscall, if necessary. + pub(crate) fn enable_syscall_import(&mut self, name: InvocableSysCall) { if let Some(injection_type @ SysCallInjectionType::None) = self.0.get_mut(&name) { *injection_type = SysCallInjectionType::Import; } } - /// Same as [`SysCallsInjectionTypes::set`], but sets amount ranges for multiple sys-calls. + /// Same as [`SysCallsInjectionTypes::set`], but sets amount ranges for multiple syscalls. pub fn set_multiple( &mut self, - sys_calls_freqs: impl Iterator)>, + syscalls_freqs: impl Iterator)>, ) { - for (name, range) in sys_calls_freqs { + for (name, range) in syscalls_freqs { let (min, max) = range.into_inner(); self.set(name, min, max); } diff --git a/utils/wasm-gen/src/config/syscalls/param.rs b/utils/wasm-gen/src/config/syscalls/param.rs index 705bdd580ed..875c6e7c9fb 100644 --- a/utils/wasm-gen/src/config/syscalls/param.rs +++ b/utils/wasm-gen/src/config/syscalls/param.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Entities describing sys-call param, more precisely, it's allowed values. +//! Entities describing syscall param, more precisely, it's allowed values. //! //! Types here are used to create [`crate::SysCallsConfig`]. @@ -26,10 +26,10 @@ use std::{collections::HashMap, ops::RangeInclusive}; pub use gear_wasm_instrument::syscalls::ParamType; -/// Sys-calls params config. +/// Syscalls params config. /// /// This is basically a map, which creates a relationship between each kind of -/// param, that a sys-call can have, and allowed values ("rules") for each of +/// param, that a syscall can have, and allowed values ("rules") for each of /// the params. /// /// # Note: @@ -103,7 +103,7 @@ impl Default for SysCallsParamsConfig { } } -/// Range of allowed values for the sys-call param. +/// Range of allowed values for the syscall param. #[derive(Debug, Clone)] pub struct SysCallParamAllowedValues(RangeInclusive); diff --git a/utils/wasm-gen/src/config/syscalls/precise.rs b/utils/wasm-gen/src/config/syscalls/precise.rs index 32c14483ea2..a207af80f03 100644 --- a/utils/wasm-gen/src/config/syscalls/precise.rs +++ b/utils/wasm-gen/src/config/syscalls/precise.rs @@ -16,11 +16,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Entities describing configuration for precise sys-calls. +//! Entities describing configuration for precise syscalls. use std::ops::RangeInclusive; -/// Represents the configuration for building some parts of precise sys-calls. +/// Represents the configuration for building some parts of precise syscalls. /// Can be used to write unit tests so you don't have to rely on randomness. #[derive(Debug, Clone)] pub struct PreciseSysCallsConfig { @@ -28,14 +28,14 @@ pub struct PreciseSysCallsConfig { } impl PreciseSysCallsConfig { - /// Creates a new configuration for precise sys-calls, filled with the given values. + /// Creates a new configuration for precise syscalls, filled with the given values. pub fn new(range_of_send_push_calls: RangeInclusive) -> Self { Self { range_of_send_push_calls, } } - /// Get the range of `send_push*` sys-calls. + /// Get the range of `send_push*` syscalls. pub fn range_of_send_push_calls(&self) -> RangeInclusive { self.range_of_send_push_calls.clone() } diff --git a/utils/wasm-gen/src/generator.rs b/utils/wasm-gen/src/generator.rs index ffa44d21a90..5277a5fb22e 100644 --- a/utils/wasm-gen/src/generator.rs +++ b/utils/wasm-gen/src/generator.rs @@ -56,7 +56,7 @@ use crate::{utils, GearWasmGeneratorConfig, WasmModule}; use arbitrary::{Result, Unstructured}; use gear_wasm_instrument::parity_wasm::elements::Module; -use std::collections::HashSet; +use std::{collections::HashSet, ops::RangeInclusive}; mod entry_points; mod memory; @@ -132,7 +132,7 @@ impl<'a, 'b> GearWasmGenerator<'a, 'b> { let (disabled_syscalls_invocator, frozen_gear_wasm_gen) = Self::from((disabled_ep_gen, frozen_gear_wasm_gen)) - .generate_sys_calls(mem_imports_gen_proof, ep_gen_proof)?; + .generate_syscalls(mem_imports_gen_proof, ep_gen_proof)?; let config = frozen_gear_wasm_gen.melt(); let module = ModuleWithCallIndexes::from(disabled_syscalls_invocator) @@ -178,25 +178,24 @@ impl<'a, 'b> GearWasmGenerator<'a, 'b> { Ok((disabled_ep_gen, frozen_gear_wasm_gen, ep_gen_proof)) } - /// Generate sys-calls using sys-calls module generators. - pub fn generate_sys_calls( + /// Generate syscalls using syscalls module generators. + pub fn generate_syscalls( self, mem_import_gen_proof: MemoryImportGenerationProof, ep_gen_proof: GearEntryPointGenerationProof, ) -> Result<(DisabledSysCallsInvocator, FrozenGearWasmGenerator<'a, 'b>)> { - let sys_calls_imports_gen_instantiator = + let syscalls_imports_gen_instantiator = SysCallsImportsGeneratorInstantiator::from((self, mem_import_gen_proof, ep_gen_proof)); - let (sys_calls_imports_gen, frozen_gear_wasm_gen) = - sys_calls_imports_gen_instantiator.into(); - let sys_calls_imports_gen_res = sys_calls_imports_gen.generate()?; + let (syscalls_imports_gen, frozen_gear_wasm_gen) = syscalls_imports_gen_instantiator.into(); + let syscalls_imports_gen_res = syscalls_imports_gen.generate()?; - let ad_injector = AdditionalDataInjector::from(sys_calls_imports_gen_res); + let ad_injector = AdditionalDataInjector::from(syscalls_imports_gen_res); let data_injection_res = ad_injector.inject(); - let sys_calls_invocator = SysCallsInvocator::from(data_injection_res); - let disabled_sys_calls_invocator = sys_calls_invocator.insert_invokes()?; + let syscalls_invocator = SysCallsInvocator::from(data_injection_res); + let disabled_syscalls_invocator = syscalls_invocator.insert_invokes()?; - Ok((disabled_sys_calls_invocator, frozen_gear_wasm_gen)) + Ok((disabled_syscalls_invocator, frozen_gear_wasm_gen)) } /// Disable current generator. @@ -217,15 +216,17 @@ struct CallIndexes { /// /// These are indexes of functions which aren't generated from /// `wasm-smith` but from the current crate generators. All gear - /// entry points ([`EntryPointsGenerator`]) and custom reservation send - /// function (generated in [`SysCallsImportsGenerator`]) are considered - /// to be "custom" functions. + /// entry points ([`EntryPointsGenerator`]) and custom precise syscalls + /// (generated in [`SysCallsImportsGenerator`]) are considered to be + /// "custom" functions. /// /// Separating "pre-defined" functions from newly generated ones is important - /// when sys-calls invocator inserts calls of generated sys-calls. For example, + /// when syscalls invocator inserts calls of generated syscalls. For example, /// calls must not be inserted in the custom function, which perofrms `gr_reservation_send`, /// not to pollute it's internal instructions structure which is defined such that /// semantically correct `gr_reservation_send` call is performed. + /// + /// Same immutability is actual for gear exports to keep them as simple as possible. custom_funcs: HashSet, } @@ -251,8 +252,24 @@ impl CallIndexes { self.inner.get(handle_idx).copied() } - fn is_custom_func(&self, idx: usize) -> bool { - self.custom_funcs.contains(&idx) + fn predefined_funcs_indexes(&self) -> RangeInclusive { + let last = if let Some(first_custom_func_idx) = self.custom_funcs.iter().min() { + // Take last predefined func idx + // + // Subtraction is safe, because by config it's guaranteed + // that there's at least one internal function from `wasm-smith`. + // So, if there's only one predefined function, then first idx + // of a custom function is 1. + first_custom_func_idx - 1 + } else { + self.inner + .iter() + .filter_map(FunctionIndex::internal_func_idx) + .max() + .expect("at least 1 func is generated by config definition") as usize + }; + + 0..=last } fn len(&self) -> usize { @@ -283,6 +300,15 @@ enum FunctionIndex { Func(u32), } +impl FunctionIndex { + fn internal_func_idx(&self) -> Option { + match self { + FunctionIndex::Func(idx) => Some(*idx), + _ => None, + } + } +} + /// Frozen gear wasm generator. /// /// Instantce of this generator signals, that some gear wasm generator diff --git a/utils/wasm-gen/src/generator/syscalls.rs b/utils/wasm-gen/src/generator/syscalls.rs index 8e2d34b857d..31f2bb3968e 100644 --- a/utils/wasm-gen/src/generator/syscalls.rs +++ b/utils/wasm-gen/src/generator/syscalls.rs @@ -16,18 +16,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Sys-calls generators entities. +//! Syscalls generators entities. //! //! Generators from this module form a state machine: //! ```text -//! # Zero sys-calls generators nesting level. +//! # Zero syscalls generators nesting level. //! SysCallsImport--->DisabledSysCallsImport--->ModuleWithCallIndexes--->WasmModule //! -//! # First sys-calls generators nesting level. +//! # First syscalls generators nesting level. //! SysCallsImport--->DisabledSysCallsImport--(SysCallsImportsGenerationProof)-->AdditionalDataInjector---\ //! |--->DisabledAdditionalDataInjector--->ModuleWithCallIndexes--->WasmModule //! -//! # Third sys-calls generators nesting level +//! # Third syscalls generators nesting level //! SysCallsImport--->DisabledSysCallsImport--(SysCallsImportsGenerationProof)-->AdditionalDataInjector---\ //! |--->DisabledAdditionalDataInjector--(AddressesInjectionOutcome)-->SysCallsInvocator--->DisabledSysCallsInvocator--->ModuleWithCallIndexes--->WasmModule //! ``` @@ -44,16 +44,16 @@ pub use invocator::*; use gear_wasm_instrument::syscalls::{ParamType, PtrInfo, PtrType, SysCallName, SysCallSignature}; -/// Type of invocable sys-call. +/// Type of invocable syscall. /// -/// Basically, there are 2 types of generated sys-calls: +/// Basically, there are 2 types of generated syscalls: /// 1. Those invocation of which is done regardless of validity of call context (`Loose`). /// 2. Those which are invoked correctly with implementing all call context (`Precise`). /// /// Clarifying that, `gr_reservation_send` requires an existing reservation id, /// which is pretty hard to predict beforehand with a generator. So this call context /// is created from scratch - first `gr_reserve_gas` is called and then it's result -/// is used for the further `gr_reservation_send` call. Those are `Precise` sys-calls. +/// is used for the further `gr_reservation_send` call. Those are `Precise` syscalls. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum InvocableSysCall { Loose(SysCallName), @@ -63,8 +63,8 @@ pub enum InvocableSysCall { impl InvocableSysCall { pub(crate) fn to_str(self) -> &'static str { match self { - InvocableSysCall::Loose(sys_call) => sys_call.to_str(), - InvocableSysCall::Precise(sys_call) => match sys_call { + InvocableSysCall::Loose(syscall) => syscall.to_str(), + InvocableSysCall::Precise(syscall) => match syscall { SysCallName::ReservationSend => "precise_gr_reservation_send", SysCallName::ReservationReply => "precise_gr_reservation_reply", SysCallName::SendCommit => "precise_gr_send_commit", @@ -143,17 +143,25 @@ impl InvocableSysCall { } } - /// Checks whether given sys-call has the precise variant. - pub(crate) fn has_precise_variant(sys_call: SysCallName) -> bool { - Self::required_imports_for_sys_call(sys_call).is_some() + /// Checks whether given syscall has the precise variant. + pub(crate) fn has_precise_variant(syscall: SysCallName) -> bool { + Self::required_imports_for_syscall(syscall).is_some() } - /// Returns the required imports to build precise sys-call. - pub(crate) fn required_imports_for_sys_call( - sys_call: SysCallName, + /// Returns the required imports to build precise syscall, but of a fixed size. + fn required_imports(syscall: SysCallName) -> &'static [SysCallName; N] { + Self::required_imports_for_syscall(syscall) + .expect("failed to find required imports for syscall") + .try_into() + .expect("failed to convert slice") + } + + /// Returns the required imports to build precise syscall. + pub(crate) fn required_imports_for_syscall( + syscall: SysCallName, ) -> Option<&'static [SysCallName]> { - // NOTE: the last sys-call must be pattern itself - Some(match sys_call { + // NOTE: the last syscall must be pattern itself + Some(match syscall { SysCallName::ReservationSend => { &[SysCallName::ReserveGas, SysCallName::ReservationSend] } @@ -175,14 +183,6 @@ impl InvocableSysCall { }) } - /// Returns the required imports to build precise sys-call, but of a fixed size. - fn required_imports(sys_call: SysCallName) -> &'static [SysCallName; N] { - Self::required_imports_for_sys_call(sys_call) - .expect("failed to find required imports for sys-call") - .try_into() - .expect("failed to convert slice") - } - /// Returns the index of the destination param. fn has_destination_param(&self) -> Option { use InvocableSysCall::*; diff --git a/utils/wasm-gen/src/generator/syscalls/additional_data.rs b/utils/wasm-gen/src/generator/syscalls/additional_data.rs index ed31137c446..f7a72917f78 100644 --- a/utils/wasm-gen/src/generator/syscalls/additional_data.rs +++ b/utils/wasm-gen/src/generator/syscalls/additional_data.rs @@ -31,7 +31,7 @@ use gear_wasm_instrument::{ parity_wasm::{builder, elements::Instruction}, syscalls::SysCallName, }; -use std::{collections::BTreeMap, iter::Cycle, vec::IntoIter}; +use std::{collections::BTreeMap, iter::Cycle, num::NonZeroU32, vec::IntoIter}; /// Cycled iterator over wasm module data offsets. /// @@ -58,7 +58,7 @@ impl AddressesOffsets { /// The config, which contains additional data types and values is received from [`DisabledSysCallsImportsGenerator`]. /// /// The generator is instantiated only with having [`SysCallsImportsGenerationProof`], which gives a guarantee. that -/// if log info should be injected, than `gr_debug` sys-call import is generated. +/// if log info should be injected, than `gr_debug` syscall import is generated. pub struct AdditionalDataInjector<'a, 'b> { unstructured: &'b mut Unstructured<'a>, call_indexes: CallIndexes, @@ -66,7 +66,7 @@ pub struct AdditionalDataInjector<'a, 'b> { last_offset: u32, module: WasmModule, addresses_offsets: Vec, - sys_calls_imports: BTreeMap, + syscalls_imports: BTreeMap, CallIndexesHandle)>, } impl<'a, 'b> @@ -76,7 +76,7 @@ impl<'a, 'b> )> for AdditionalDataInjector<'a, 'b> { fn from( - (disabled_gen, _sys_calls_gen_proof): ( + (disabled_gen, _syscalls_gen_proof): ( DisabledSysCallsImportsGenerator<'a, 'b>, SysCallsImportsGenerationProof, ), @@ -91,7 +91,7 @@ impl<'a, 'b> last_offset: data_offset as u32, module: disabled_gen.module, addresses_offsets: Vec::new(), - sys_calls_imports: disabled_gen.sys_calls_imports, + syscalls_imports: disabled_gen.syscalls_imports, call_indexes: disabled_gen.call_indexes, } } @@ -122,7 +122,7 @@ impl<'a, 'b> AdditionalDataInjector<'a, 'b> { DisabledAdditionalDataInjector { module: self.module, call_indexes: self.call_indexes, - sys_calls_imports: self.sys_calls_imports, + syscalls_imports: self.syscalls_imports, config: self.config, unstructured: self.unstructured, } @@ -140,7 +140,7 @@ impl<'a, 'b> AdditionalDataInjector<'a, 'b> { )); } - let SysCallDestination::ExistingAddresses(existing_addresses) = self.config.sys_call_destination() else { + let SysCallDestination::ExistingAddresses(existing_addresses) = self.config.syscall_destination() else { return None; }; @@ -213,10 +213,10 @@ impl<'a, 'b> AdditionalDataInjector<'a, 'b> { .expect("impossible to have no gear export"); let debug_call_indexes_handle = self - .sys_calls_imports + .syscalls_imports .get(&InvocableSysCall::Loose(SysCallName::Debug)) .map(|&(_, handle)| handle as u32) - .expect("impossible by configs generation to have log info printing without debug sys-call generated"); + .expect("impossible by configs generation to have log info printing without debug syscall generated"); self.module.with(|module| { let log_bytes_len = log_bytes.len() as u32; @@ -271,7 +271,8 @@ pub struct DisabledAdditionalDataInjector<'a, 'b> { pub(super) unstructured: &'b mut Unstructured<'a>, pub(super) module: WasmModule, pub(super) call_indexes: CallIndexes, - pub(super) sys_calls_imports: BTreeMap, + pub(super) syscalls_imports: + BTreeMap, CallIndexesHandle)>, pub(super) config: SysCallsConfig, } diff --git a/utils/wasm-gen/src/generator/syscalls/imports.rs b/utils/wasm-gen/src/generator/syscalls/imports.rs index 121151e0532..2f0cf38b8b3 100644 --- a/utils/wasm-gen/src/generator/syscalls/imports.rs +++ b/utils/wasm-gen/src/generator/syscalls/imports.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Sys-calls imports generator module. +//! Syscalls imports generator module. use crate::{ generator::{ @@ -35,18 +35,18 @@ use gear_wasm_instrument::{ syscalls::SysCallName, }; use gsys::{Handle, Hash, Length}; -use std::{collections::BTreeMap, mem}; +use std::{collections::BTreeMap, mem, num::NonZeroU32}; -/// Gear sys-calls imports generator. +/// Gear syscalls imports generator. pub struct SysCallsImportsGenerator<'a, 'b> { unstructured: &'b mut Unstructured<'a>, call_indexes: CallIndexes, module: WasmModule, config: SysCallsConfig, - sys_calls_imports: BTreeMap, + syscalls_imports: BTreeMap, CallIndexesHandle)>, } -/// Sys-calls imports generator instantiator. +/// Syscalls imports generator instantiator. /// /// Serves as a new type in order to create the generator from gear wasm generator and proofs. pub struct SysCallsImportsGeneratorInstantiator<'a, 'b>( @@ -57,12 +57,12 @@ pub struct SysCallsImportsGeneratorInstantiator<'a, 'b>( ), ); -/// The set of sys-calls that need to be imported to create precise sys-call. +/// The set of syscalls that need to be imported to create precise syscall. #[derive(thiserror::Error, Debug)] -#[error("The following sys-calls must be imported: {0:?}")] +#[error("The following syscalls must be imported: {0:?}")] pub struct RequiredSysCalls(&'static [SysCallName]); -/// An error that occurs when generating precise sys-call. +/// An error that occurs when generating precise syscall. #[derive(thiserror::Error, Debug)] pub enum PreciseSysCallError { #[error("{0}")] @@ -101,12 +101,12 @@ impl<'a, 'b> From> _mem_import_gen_proof, _gen_ep_gen_proof, )) = instantiator; - let sys_call_gen = SysCallsImportsGenerator { + let syscall_gen = SysCallsImportsGenerator { unstructured: generator.unstructured, call_indexes: generator.call_indexes, module: generator.module, - config: generator.config.sys_calls_config.clone(), - sys_calls_imports: Default::default(), + config: generator.config.syscalls_config.clone(), + syscalls_imports: Default::default(), }; let frozen = FrozenGearWasmGenerator { config: generator.config, @@ -114,12 +114,12 @@ impl<'a, 'b> From> unstructured: None, }; - (sys_call_gen, frozen) + (syscall_gen, frozen) } } impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { - /// Instantiate a new gear sys-calls imports generator. + /// Instantiate a new gear syscalls imports generator. /// /// The generator instantiations requires having type-level proof that the wasm module has memory import in it. /// This proof could be gotten from memory generator. @@ -140,14 +140,14 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { call_indexes, module, config, - sys_calls_imports: Default::default(), + syscalls_imports: Default::default(), } } /// Disable current generator. pub fn disable(self) -> DisabledSysCallsImportsGenerator<'a, 'b> { log::trace!( - "Random data when disabling sys-calls imports generator - {}", + "Random data when disabling syscalls imports generator - {}", self.unstructured.len() ); DisabledSysCallsImportsGenerator { @@ -155,54 +155,54 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { call_indexes: self.call_indexes, module: self.module, config: self.config, - sys_calls_imports: self.sys_calls_imports, + syscalls_imports: self.syscalls_imports, } } - /// Generates sys-calls imports and a function, that calls `gr_reservation_send` from config, + /// Generates syscalls imports and a function, that calls `gr_reservation_send` from config, /// used to instantiate the generator. /// - /// Returns disabled sys-calls imports generator and a proof that imports from config were generated. + /// Returns disabled syscalls imports generator and a proof that imports from config were generated. pub fn generate( mut self, ) -> Result<( DisabledSysCallsImportsGenerator<'a, 'b>, SysCallsImportsGenerationProof, )> { - log::trace!("Generating sys-calls imports"); + log::trace!("Generating syscalls imports"); - let sys_calls_proof = self.generate_sys_calls_imports()?; - self.generate_precise_sys_calls()?; + let syscalls_proof = self.generate_syscalls_imports()?; + self.generate_precise_syscalls()?; - Ok((self.disable(), sys_calls_proof)) + Ok((self.disable(), syscalls_proof)) } - /// Generates sys-calls imports from config, used to instantiate the generator. - pub fn generate_sys_calls_imports(&mut self) -> Result { + /// Generates syscalls imports from config, used to instantiate the generator. + pub fn generate_syscalls_imports(&mut self) -> Result { log::trace!( - "Random data before sys-calls imports - {}", + "Random data before syscalls imports - {}", self.unstructured.len() ); - for sys_call in SysCallName::instrumentable() { - let sys_call_generation_data = self.generate_sys_call_import(sys_call)?; - if let Some(sys_call_generation_data) = sys_call_generation_data { - self.sys_calls_imports - .insert(InvocableSysCall::Loose(sys_call), sys_call_generation_data); + for syscall in SysCallName::instrumentable() { + let syscall_generation_data = self.generate_syscall_import(syscall)?; + if let Some(syscall_generation_data) = syscall_generation_data { + self.syscalls_imports + .insert(InvocableSysCall::Loose(syscall), syscall_generation_data); } } Ok(SysCallsImportsGenerationProof(())) } - /// Generates precise sys-calls and handles errors if any occurred during generation. - fn generate_precise_sys_calls(&mut self) -> Result<()> { + /// Generates precise syscalls and handles errors if any occurred during generation. + fn generate_precise_syscalls(&mut self) -> Result<()> { use SysCallName::*; #[allow(clippy::type_complexity)] - let sys_calls: [( + let precise_syscalls: [( SysCallName, - fn(&mut Self, SysCallName) -> Result<(), PreciseSysCallError>, + fn(&mut Self, SysCallName) -> Result, ); 4] = [ (ReservationSend, Self::generate_send_from_reservation), (ReservationReply, Self::generate_reply_from_reservation), @@ -210,24 +210,40 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { (SendCommitWGas, Self::generate_send_commit_with_gas), ]; - for (sys_call, generate_method) in sys_calls { - let sys_call_injection_type = self + for (precise_syscall, generate_method) in precise_syscalls { + let syscall_injection_type = self .config - .injection_types(InvocableSysCall::Precise(sys_call)); - if let SysCallInjectionType::Function(sys_call_amount_range) = sys_call_injection_type { - let sys_call_amount = self.unstructured.int_in_range(sys_call_amount_range)?; - for _ in 0..sys_call_amount { - log::trace!( - "Constructing {name} sys-call...", - name = InvocableSysCall::Precise(sys_call).to_str() - ); - - if let Err(err) = generate_method(self, sys_call) { - match err { - PreciseSysCallError::RequiredImports(err) => log::trace!("{err}"), - PreciseSysCallError::Arbitrary(err) => return Err(err), - } + .injection_types(InvocableSysCall::Precise(precise_syscall)); + if let SysCallInjectionType::Function(syscall_amount_range) = syscall_injection_type { + let precise_syscall_amount = + NonZeroU32::new(self.unstructured.int_in_range(syscall_amount_range)?); + log::trace!( + "Constructing `{name}` syscall...", + name = InvocableSysCall::Precise(precise_syscall).to_str() + ); + + if precise_syscall_amount.is_none() { + // Amount is zero. + continue; + } + + match generate_method(self, precise_syscall) { + Ok(call_indexes_handle) => { + self.syscalls_imports.insert( + InvocableSysCall::Precise(precise_syscall), + (precise_syscall_amount, call_indexes_handle), + ); } + Err(PreciseSysCallError::RequiredImports(err)) => { + // By syscalls injection types config all required syscalls for + // precise syscalls are set. + // By generator's implementation, precise calls are generated after + // generating syscalls imports. + panic!( + "Invalid generators configuration or implementation: required syscalls aren't set: {err}" + ) + } + Err(PreciseSysCallError::Arbitrary(err)) => return Err(err), } } } @@ -235,51 +251,55 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { Ok(()) } - /// Generate import of the gear sys-call defined by `sys_call` param. + /// Generate import of the gear syscall defined by `syscall` param. /// - /// Returns [`Option`] which wraps the tuple of amount of sys-call further injections - /// and handle in the call indexes collection, if amount is not zero. Otherwise returns - /// None. - fn generate_sys_call_import( + /// Returns [`Option`] which wraps the tuple of maybe non-zero amount of syscall further injections + /// and handle in the call indexes collection. The amount type is `NonZeroU32` in order to distinguish + /// between syscalls imports that must be generated without further invocation and ones, + /// that must be invoked along with the import generation. + /// If no import is required, `None` is returned. + fn generate_syscall_import( &mut self, - sys_call: SysCallName, - ) -> Result> { - let sys_call_injection_type = self + syscall: SysCallName, + ) -> Result, CallIndexesHandle)>> { + let syscall_injection_type = self .config - .injection_types(InvocableSysCall::Loose(sys_call)); + .injection_types(InvocableSysCall::Loose(syscall)); - let sys_call_amount = match sys_call_injection_type { + let syscall_amount = match syscall_injection_type { SysCallInjectionType::Import => 0, - SysCallInjectionType::Function(sys_call_amount_range) => { - self.unstructured.int_in_range(sys_call_amount_range)? + SysCallInjectionType::Function(syscall_amount_range) => { + self.unstructured.int_in_range(syscall_amount_range)? } _ => return Ok(None), }; - let call_indexes_handle = self.insert_sys_call_import(sys_call); + // Insert import either for case of `SysCallInjectionType::Import`, or + // if `SysCallInjectionType::Function(syscall_amount_range)` yielded zero. + let call_indexes_handle = self.insert_syscall_import(syscall); log::trace!( - " -- Generated {} amount of {} sys-call", - sys_call_amount, - sys_call.to_str() + " -- Syscall `{}` will be invoked {} times", + syscall.to_str(), + syscall_amount, ); - Ok(Some((sys_call_amount, call_indexes_handle))) + Ok(Some((NonZeroU32::new(syscall_amount), call_indexes_handle))) } - /// Inserts gear sys-call defined by the `sys_call` param. - fn insert_sys_call_import(&mut self, sys_call: SysCallName) -> CallIndexesHandle { - let sys_call_import_idx = self.module.count_import_funcs(); + /// Inserts gear syscall defined by the `syscall` param. + fn insert_syscall_import(&mut self, syscall: SysCallName) -> CallIndexesHandle { + let syscall_import_idx = self.module.count_import_funcs(); - // Insert sys-call import to the module + // Insert syscall import to the module self.module.with(|module| { let mut module_builder = builder::from_module(module); // Build signature applicable for the parity-wasm for the sys call - let sys_call_signature = sys_call.signature().func_type(); + let syscall_signature = syscall.signature().func_type(); let signature_idx = module_builder.push_signature( builder::signature() - .with_params(sys_call_signature.params().iter().copied()) - .with_results(sys_call_signature.results().iter().copied()) + .with_params(syscall_signature.params().iter().copied()) + .with_results(syscall_signature.results().iter().copied()) .build_sig(), ); @@ -289,7 +309,7 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { .module("env") .external() .func(signature_idx) - .field(sys_call.to_str()) + .field(syscall.to_str()) .build(), ); @@ -297,98 +317,23 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { }); let call_indexes_handle = self.call_indexes.len(); - self.call_indexes.add_import(sys_call_import_idx); + self.call_indexes.add_import(syscall_import_idx); call_indexes_handle } } impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { - /// The amount of memory used to create a precise sys-call. + /// The amount of memory used to create a precise syscall. const PRECISE_SYS_CALL_MEMORY_SIZE: u32 = 100; - /// Returns the indexes of invocable sys-calls. - fn invocable_sys_calls_indexes( - &self, - sys_calls: &'static [SysCallName; N], - ) -> Result<[usize; N], RequiredSysCalls> { - let mut indexes = [0; N]; - - for (index, &sys_call) in indexes.iter_mut().zip(sys_calls.iter()) { - *index = self - .sys_calls_imports - .get(&InvocableSysCall::Loose(sys_call)) - .map(|&(_, call_indexes_handle)| call_indexes_handle) - .ok_or_else(|| RequiredSysCalls(&sys_calls[..]))?; - } - - Ok(indexes) - } - - /// Generates a function which calls "properly" the given sys-call. - fn generate_proper_sys_call_invocation( - &mut self, - sys_call: SysCallName, - func_instructions: Instructions, - ) { - let invocable_sys_call = InvocableSysCall::Precise(sys_call); - let signature = invocable_sys_call.into_signature(); - - let func_ty = signature.func_type(); - let func_signature = builder::signature() - .with_params(func_ty.params().iter().copied()) - .with_results(func_ty.results().iter().copied()) - .build_sig(); - - let func_idx = self.module.with(|module| { - let mut module_builder = builder::from_module(module); - let idx = module_builder.push_function( - builder::function() - .with_signature(func_signature) - .body() - .with_instructions(func_instructions) - .build() - .build(), - ); - - (module_builder.build(), idx) - }); - - log::trace!( - "Built proper call to {precise_sys_call_name}", - precise_sys_call_name = invocable_sys_call.to_str() - ); - - let call_indexes_handle = self.call_indexes.len(); - self.call_indexes.add_func(func_idx.signature as usize); - - self.sys_calls_imports - .insert(invocable_sys_call, (1, call_indexes_handle)); - } - - /// Returns the size of the memory in bytes that can be used to build precise sys-call. - fn memory_size_in_bytes(&self) -> u32 { - let initial_mem_size: WasmPageCount = self - .module - .initial_mem_size() - .expect("generator is instantiated with a mem import generation proof") - .into(); - initial_mem_size.memory_size() - } - - /// Reserves enough memory build precise sys-call. - fn reserve_memory(&self) -> i32 { - self.memory_size_in_bytes() - .saturating_sub(Self::PRECISE_SYS_CALL_MEMORY_SIZE) as i32 - } - /// Generates a function which calls "properly" the `gr_reservation_send`. fn generate_send_from_reservation( &mut self, - sys_call: SysCallName, - ) -> Result<(), PreciseSysCallError> { + syscall: SysCallName, + ) -> Result { let [reserve_gas_idx, reservation_send_idx] = - self.invocable_sys_calls_indexes(InvocableSysCall::required_imports(sys_call))?; + self.invocable_syscalls_indexes(InvocableSysCall::required_imports(syscall))?; // subtract to be sure we are in memory boundaries. let rid_pid_value_ptr = self.reserve_memory(); @@ -467,19 +412,19 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { Instruction::End, Instruction::End, ]); + let call_indexes_handle = + self.generate_proper_syscall_invocation(syscall, func_instructions); - self.generate_proper_sys_call_invocation(sys_call, func_instructions); - - Ok(()) + Ok(call_indexes_handle) } /// Generates a function which calls "properly" the `gr_reservation_reply`. fn generate_reply_from_reservation( &mut self, - sys_call: SysCallName, - ) -> Result<(), PreciseSysCallError> { + syscall: SysCallName, + ) -> Result { let [reserve_gas_idx, reservation_reply_idx] = - self.invocable_sys_calls_indexes(InvocableSysCall::required_imports(sys_call))?; + self.invocable_syscalls_indexes(InvocableSysCall::required_imports(syscall))?; // subtract to be sure we are in memory boundaries. let rid_value_ptr = self.reserve_memory(); @@ -539,16 +484,19 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { Instruction::End, Instruction::End, ]); + let call_indexes_handle = + self.generate_proper_syscall_invocation(syscall, func_instructions); - self.generate_proper_sys_call_invocation(sys_call, func_instructions); - - Ok(()) + Ok(call_indexes_handle) } /// Generates a function which calls "properly" the `gr_send_commit`. - fn generate_send_commit(&mut self, sys_call: SysCallName) -> Result<(), PreciseSysCallError> { + fn generate_send_commit( + &mut self, + syscall: SysCallName, + ) -> Result { let [send_init_idx, send_push_idx, send_commit_idx] = - self.invocable_sys_calls_indexes(InvocableSysCall::required_imports(sys_call))?; + self.invocable_syscalls_indexes(InvocableSysCall::required_imports(syscall))?; // subtract to be sure we are in memory boundaries. let handle_ptr = self.reserve_memory(); @@ -634,21 +582,20 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { Instruction::End, Instruction::End, ]); - let func_instructions = Instructions::new(elements); + let call_indexes_handle = + self.generate_proper_syscall_invocation(syscall, func_instructions); - self.generate_proper_sys_call_invocation(sys_call, func_instructions); - - Ok(()) + Ok(call_indexes_handle) } /// Generates a function which calls "properly" the `gr_send_commit_wgas`. fn generate_send_commit_with_gas( &mut self, - sys_call: SysCallName, - ) -> Result<(), PreciseSysCallError> { + syscall: SysCallName, + ) -> Result { let [size_idx, send_init_idx, send_push_input_idx, send_commit_wgas_idx] = - self.invocable_sys_calls_indexes(InvocableSysCall::required_imports(sys_call))?; + self.invocable_syscalls_indexes(InvocableSysCall::required_imports(syscall))?; // subtract to be sure we are in memory boundaries. let handle_ptr = self.reserve_memory(); @@ -741,35 +688,109 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { Instruction::End, Instruction::End, ]); - let func_instructions = Instructions::new(elements); + let call_indexes_handle = + self.generate_proper_syscall_invocation(syscall, func_instructions); - self.generate_proper_sys_call_invocation(sys_call, func_instructions); + Ok(call_indexes_handle) + } - Ok(()) + /// Returns the indexes of invocable syscalls. + fn invocable_syscalls_indexes( + &mut self, + syscalls: &'static [SysCallName; N], + ) -> Result<[usize; N], RequiredSysCalls> { + let mut indexes = [0; N]; + + for (index, &syscall) in indexes.iter_mut().zip(syscalls.iter()) { + *index = self + .syscalls_imports + .get(&InvocableSysCall::Loose(syscall)) + .map(|&(_, call_indexes_handle)| call_indexes_handle) + .ok_or_else(|| RequiredSysCalls(&syscalls[..]))?; + } + + Ok(indexes) + } + + /// Reserves enough memory build precise syscall. + fn reserve_memory(&self) -> i32 { + self.memory_size_in_bytes() + .saturating_sub(Self::PRECISE_SYS_CALL_MEMORY_SIZE) as i32 + } + + /// Returns the size of the memory in bytes that can be used to build precise syscall. + fn memory_size_in_bytes(&self) -> u32 { + let initial_mem_size: WasmPageCount = self + .module + .initial_mem_size() + .expect("generator is instantiated with a mem import generation proof") + .into(); + initial_mem_size.memory_size() + } + + /// Generates a function which calls "properly" the given syscall. + fn generate_proper_syscall_invocation( + &mut self, + syscall: SysCallName, + func_instructions: Instructions, + ) -> CallIndexesHandle { + let invocable_syscall = InvocableSysCall::Precise(syscall); + let signature = invocable_syscall.into_signature(); + + let func_ty = signature.func_type(); + let func_signature = builder::signature() + .with_params(func_ty.params().iter().copied()) + .with_results(func_ty.results().iter().copied()) + .build_sig(); + + let func_idx = self.module.with(|module| { + let mut module_builder = builder::from_module(module); + let idx = module_builder.push_function( + builder::function() + .with_signature(func_signature) + .body() + .with_instructions(func_instructions) + .build() + .build(), + ); + + (module_builder.build(), idx) + }); + + log::trace!( + "Built proper call to {precise_syscall_name}", + precise_syscall_name = invocable_syscall.to_str() + ); + + let call_indexes_handle = self.call_indexes.len(); + self.call_indexes.add_func(func_idx.signature as usize); + + call_indexes_handle } } -/// Proof that there was an instance of sys-calls imports generator and `SysCallsImportsGenerator::generate_sys_calls_imports` was called. +/// Proof that there was an instance of syscalls imports generator and `SysCallsImportsGenerator::generate_syscalls_imports` was called. pub struct SysCallsImportsGenerationProof(()); -/// Disabled gear wasm sys-calls generator. +/// Disabled gear wasm syscalls generator. /// -/// Instance of this types signals that there was once active sys-calls generator, +/// Instance of this types signals that there was once active syscalls generator, /// but it ended up it's work. pub struct DisabledSysCallsImportsGenerator<'a, 'b> { pub(super) unstructured: &'b mut Unstructured<'a>, pub(super) call_indexes: CallIndexes, pub(super) module: WasmModule, pub(super) config: SysCallsConfig, - pub(super) sys_calls_imports: BTreeMap, + pub(super) syscalls_imports: + BTreeMap, CallIndexesHandle)>, } impl<'a, 'b> From> for ModuleWithCallIndexes { - fn from(disabled_sys_call_gen: DisabledSysCallsImportsGenerator<'a, 'b>) -> Self { + fn from(disabled_syscall_gen: DisabledSysCallsImportsGenerator<'a, 'b>) -> Self { ModuleWithCallIndexes { - module: disabled_sys_call_gen.module, - call_indexes: disabled_sys_call_gen.call_indexes, + module: disabled_syscall_gen.module, + call_indexes: disabled_syscall_gen.call_indexes, } } } diff --git a/utils/wasm-gen/src/generator/syscalls/invocator.rs b/utils/wasm-gen/src/generator/syscalls/invocator.rs index be68e480bf9..0740a110776 100644 --- a/utils/wasm-gen/src/generator/syscalls/invocator.rs +++ b/utils/wasm-gen/src/generator/syscalls/invocator.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Sys-calls invocator module. +//! Syscalls invocator module. use crate::{ generator::{ @@ -32,8 +32,9 @@ use gear_wasm_instrument::{ syscalls::{ParamType, PtrInfo, PtrType, SysCallName, SysCallSignature}, }; use std::{ - collections::{btree_map::Entry, BTreeMap, BinaryHeap}, + collections::{btree_map::Entry, BTreeMap, BinaryHeap, HashSet}, iter, + num::NonZeroU32, }; #[derive(Debug)] @@ -49,7 +50,7 @@ pub(crate) enum ProcessedSysCallParams { MemoryPtrValue, } -pub(crate) fn process_sys_call_params( +pub(crate) fn process_syscall_params( params: &[ParamType], params_config: &SysCallsParamsConfig, ) -> Vec { @@ -88,15 +89,15 @@ pub(crate) fn process_sys_call_params( res } -/// Sys-calls invocator. +/// Syscalls invocator. /// -/// Inserts sys-calls invokes randomly into internal functions. +/// Inserts syscalls invokes randomly into internal functions. /// /// This type is instantiated from disable additional data injector and /// data injection outcome ([`AddressesInjectionOutcome`]). The latter was introduced /// to give additional guarantees for config and generators consistency. Otherwise, /// if there wasn't any addresses injection outcome, which signals that there was a try to -/// inject addresses, sys-calls invocator could falsely set `gr_send*` and `gr_exit` call's destination param +/// inject addresses, syscalls invocator could falsely set `gr_send*` and `gr_exit` call's destination param /// to random value. For example, existing addresses could have been defined in the config, but /// additional data injector was disabled, before injecting addresses from the config. As a result, /// invocator would set un-intended by config values as messages destination. To avoid such @@ -107,7 +108,7 @@ pub struct SysCallsInvocator<'a, 'b> { module: WasmModule, config: SysCallsConfig, offsets: Option, - sys_call_imports: BTreeMap, + syscalls_imports: BTreeMap, CallIndexesHandle)>, } impl<'a, 'b> @@ -128,7 +129,7 @@ impl<'a, 'b> module: disabled_gen.module, config: disabled_gen.config, offsets: outcome.offsets, - sys_call_imports: disabled_gen.sys_calls_imports, + syscalls_imports: disabled_gen.syscalls_imports, } } } @@ -170,20 +171,20 @@ impl ParamSetter { pub type SysCallInvokeInstructions = Vec; impl<'a, 'b> SysCallsInvocator<'a, 'b> { - /// Insert sys-calls invokes. + /// Insert syscalls invokes. /// - /// The method builds instructions, which describe how each sys-call is called, and then + /// The method builds instructions, which describe how each syscall is called, and then /// insert these instructions into any random function. In the end, all call indexes are resolved. pub fn insert_invokes(mut self) -> Result { log::trace!( - "Random data before inserting all sys-calls invocations - {}", + "Random data before inserting all syscalls invocations - {}", self.unstructured.len() ); - self.insert_sys_calls()?; + self.insert_syscalls()?; log::trace!( - "Random data after inserting all sys-calls invocations - {}", + "Random data after inserting all syscalls invocations - {}", self.unstructured.len() ); @@ -195,63 +196,40 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { }) } - fn insert_sys_calls(&mut self) -> Result<()> { - log::trace!( - "Random data before inserting sys-calls invoke instructions - {}", - self.unstructured.len() - ); - - let code_funcs = self.module.count_code_funcs(); - let insert_into_funcs: Vec<_> = (0..code_funcs) - .filter(|idx| !self.call_indexes.is_custom_func(*idx)) - .collect(); - - let syscalls_to_insert = - self.sys_call_imports - .clone() - .into_iter() - .flat_map(|(syscall, (amount, _))| { - iter::repeat(syscall) - .take(amount as usize) - .collect::>() - }); - - let insertion_mapping = - self.build_syscalls_insertion_mapping(syscalls_to_insert, &insert_into_funcs)?; - + fn insert_syscalls(&mut self) -> Result<()> { + let insertion_mapping = self.build_syscalls_insertion_mapping()?; for (insert_into_fn, syscalls) in insertion_mapping { - self.insert_sys_calls_into_fn(insert_into_fn, syscalls)?; + self.insert_syscalls_into_fn(insert_into_fn, syscalls)?; } - log::trace!( - "Random data after inserting sys-calls invoke instructions - {}", - self.unstructured.len() - ); - Ok(()) } /// Distributes provided syscalls among provided function ids. /// /// Returns mapping `func_id` <-> `syscalls which should be inserted into func_id`. - fn build_syscalls_insertion_mapping( + fn build_syscalls_insertion_mapping( &mut self, - syscalls: I, - insert_into_funcs: &[usize], - ) -> Result>> - where - I: Iterator, - { + ) -> Result>> { + let insert_into_funcs = self.call_indexes.predefined_funcs_indexes(); + let syscalls = self + .syscalls_imports + .clone() + .into_iter() + .filter_map(|(syscall, (amount, _))| amount.map(|a| (syscall, a))); + let mut insertion_mapping: BTreeMap<_, Vec<_>> = BTreeMap::new(); - for syscall in syscalls { - let insert_into = *self.unstructured.choose(insert_into_funcs)?; + for (syscall, amount) in syscalls { + for _ in 0..amount.get() { + let insert_into = self.unstructured.int_in_range(insert_into_funcs.clone())?; - match insertion_mapping.entry(insert_into) { - Entry::Occupied(mut entry) => { - entry.get_mut().push(syscall); - } - Entry::Vacant(entry) => { - entry.insert(vec![syscall]); + match insertion_mapping.entry(insert_into) { + Entry::Occupied(mut entry) => { + entry.get_mut().push(syscall); + } + Entry::Vacant(entry) => { + entry.insert(vec![syscall]); + } } } } @@ -259,13 +237,13 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { Ok(insertion_mapping) } - fn insert_sys_calls_into_fn( + fn insert_syscalls_into_fn( &mut self, insert_into_fn: usize, syscalls: Vec, ) -> Result<()> { log::trace!( - "Random data before inserting sys-calls invoke instructions into function {insert_into_fn} - {}", + "Random data before inserting syscalls invoke instructions into function with index {insert_into_fn} - {}", self.unstructured.len() ); @@ -289,18 +267,18 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { for (pos, syscall) in insertion_positions.zip(syscalls) { let call_indexes_handle = self - .sys_call_imports + .syscalls_imports .get(&syscall) .map(|(_, call_indexes_handle)| *call_indexes_handle) - .expect("Syscall presented in sys_call_imports"); - let instructions = self.build_sys_call_invoke_instructions( + .expect("Syscall presented in syscall_imports"); + let instructions = self.build_syscall_invoke_instructions( syscall, syscall.into_signature(), call_indexes_handle, )?; log::trace!( - " -- Inserting syscall {} into function {insert_into_fn} at position {pos}", + " -- Inserting syscall `{}` into function with index {insert_into_fn} at position {pos}", syscall.to_str() ); @@ -317,28 +295,28 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { } log::trace!( - "Random data after inserting sys-calls invoke instructions into function {insert_into_fn} - {}", + "Random data after inserting syscalls invoke instructions into function {insert_into_fn} - {}", self.unstructured.len() ); Ok(()) } - fn build_sys_call_invoke_instructions( + fn build_syscall_invoke_instructions( &mut self, invocable: InvocableSysCall, signature: SysCallSignature, call_indexes_handle: CallIndexesHandle, ) -> Result { log::trace!( - "Random data before building {} sys-call invoke instructions - {}", + "Random data before building `{}` syscall invoke instructions - {}", invocable.to_str(), self.unstructured.len() ); if let Some(argument_index) = invocable.has_destination_param() { log::trace!( - " -- Generating build call for {} sys-call with destination", + " -- Building call instructions for a `{}` syscall with destination", invocable.to_str() ); @@ -350,7 +328,7 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { ) } else { log::trace!( - " -- Generating build call for common sys-call {}", + " -- Building call for a common syscall `{}`", invocable.to_str() ); @@ -363,18 +341,18 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { invocable: InvocableSysCall, signature: SysCallSignature, call_indexes_handle: CallIndexesHandle, - argument_index: usize, + destination_arg_idx: usize, ) -> Result> { // The value for the destination param is chosen from config. // It's either the result of `gr_source`, some existing address (set in the data section) or a completely random value. let mut original_instructions = self.build_call(invocable, signature, call_indexes_handle)?; - let destination_instructions = if self.config.sys_call_destination().is_source() { - log::trace!(" -- Sys-call destination is result of `gr_source`"); + let destination_instructions = if self.config.syscall_destination().is_source() { + log::trace!(" --- Syscall destination is result of `gr_source`"); let gr_source_call_indexes_handle = self - .sys_call_imports + .syscalls_imports .get(&InvocableSysCall::Loose(SysCallName::Source)) .map(|&(_, call_indexes_handle)| call_indexes_handle as u32) .expect("by config if destination is source, then `gr_source` is generated"); @@ -401,14 +379,14 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { } else { let address_offset = match self.offsets.as_mut() { Some(offsets) => { - assert!(self.config.sys_call_destination().is_existing_addresses()); - log::trace!(" -- Sys-call destination is an existing program address"); + assert!(self.config.syscall_destination().is_existing_addresses()); + log::trace!(" ---- Syscall destination is an existing program address"); offsets.next_offset() } None => { - assert!(self.config.sys_call_destination().is_random()); - log::trace!(" -- Sys-call destination is a random address"); + assert!(self.config.syscall_destination().is_random()); + log::trace!(" ---- Syscall destination is a random address"); self.unstructured.arbitrary()? } @@ -417,7 +395,10 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { vec![Instruction::I32Const(address_offset as i32)] }; - original_instructions.splice(argument_index..argument_index + 1, destination_instructions); + original_instructions.splice( + destination_arg_idx..destination_arg_idx + 1, + destination_instructions, + ); Ok(original_instructions) } @@ -456,7 +437,7 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { fn build_param_setters(&mut self, params: &[ParamType]) -> Result> { log::trace!( - " ---- Random data before SysCallsInvocator::build_param_setters - {}", + " -- Random data before building param setters - {}", self.unstructured.len() ); @@ -469,7 +450,7 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { let mem_size = Into::::into(mem_size_pages).memory_size(); let mut setters = Vec::with_capacity(params.len()); - for processed_param in process_sys_call_params(params, self.config.params_config()) { + for processed_param in process_syscall_params(params, self.config.params_config()) { match processed_param { ProcessedSysCallParams::Alloc { allowed_values } => { let pages_to_alloc = if let Some(allowed_values) = allowed_values { @@ -535,7 +516,7 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { } log::trace!( - " ---- Random data after SysCallsInvocator::build_param_setters - {}", + " -- Random data after building param setters - {}", self.unstructured.len() ); @@ -630,6 +611,7 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { log::trace!("Resolving calls indexes"); let imports_num = self.module.count_import_funcs() as u32; + let mut logged = HashSet::with_capacity(self.call_indexes.len()); self.module.with(|mut module| { let each_func_instructions = module @@ -646,9 +628,19 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { .expect("getting by handle of existing call"); match index_ty { FunctionIndex::Func(idx) => { - log::trace!(" -- Old function index - {idx}"); + let old_idx = *call_indexes_handle; *call_indexes_handle = idx + imports_num; - log::trace!(" -- New function index - {}", *call_indexes_handle); + + // Log only not changed indexes, because loop can receive repeted + // call indexes. + if !logged.contains(&*call_indexes_handle) { + logged.insert(*call_indexes_handle); + + log::trace!( + " -- Old function index - {old_idx}, new index - {}", + *call_indexes_handle + ); + } } FunctionIndex::Import(idx) => *call_indexes_handle = idx, } @@ -676,10 +668,11 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { panic!("Export cannot be to the import function"); }; - log::trace!(" -- Old export function index - {idx}"); + let old_idx = *export_call_indexes_handle; *export_call_indexes_handle = idx + imports_num; + log::trace!( - " -- New export function index - {}", + " -- Old export function index - {old_idx}, new index - {}", *export_call_indexes_handle ); } @@ -689,20 +682,20 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { } } -/// Disabled sys-calls invocator. +/// Disabled syscalls invocator. /// -/// This type signals that sys-calls imports generation, additional data injection and -/// sys-calls invocation (with further call indexes resolution) is done. +/// This type signals that syscalls imports generation, additional data injection and +/// syscalls invocation (with further call indexes resolution) is done. pub struct DisabledSysCallsInvocator { module: WasmModule, call_indexes: CallIndexes, } impl From for ModuleWithCallIndexes { - fn from(disabled_sys_calls_invocator: DisabledSysCallsInvocator) -> Self { + fn from(disabled_syscalls_invocator: DisabledSysCallsInvocator) -> Self { ModuleWithCallIndexes { - module: disabled_sys_calls_invocator.module, - call_indexes: disabled_sys_calls_invocator.call_indexes, + module: disabled_syscalls_invocator.module, + call_indexes: disabled_syscalls_invocator.call_indexes, } } } diff --git a/utils/wasm-gen/src/tests.rs b/utils/wasm-gen/src/tests.rs index 00860fb1677..9acfc5c83c0 100644 --- a/utils/wasm-gen/src/tests.rs +++ b/utils/wasm-gen/src/tests.rs @@ -43,7 +43,7 @@ use gear_wasm_instrument::{ }; use proptest::prelude::*; use rand::{rngs::SmallRng, RngCore, SeedableRng}; -use std::mem; +use std::{mem, num::NonZeroUsize}; const UNSTRUCTURED_SIZE: usize = 1_000_000; @@ -121,7 +121,7 @@ fn injecting_addresses_works() { upper_limit: None, stack_end_page: Some(stack_end_page), }) - .with_sys_calls_config( + .with_syscalls_config( SysCallsConfigBuilder::new(Default::default()) .with_data_offset_msg_dest(addresses) .build(), @@ -193,7 +193,7 @@ fn error_processing_works_for_fallible_syscalls() { }); for syscall in fallible_syscalls { - // Prepare sys-calls config & context settings for test case. + // Prepare syscalls config & context settings for test case. let (params_config, initial_memory_write) = get_params_for_syscall_to_fail(syscall); const INJECTED_SYSCALLS: u32 = 8; @@ -201,13 +201,13 @@ fn error_processing_works_for_fallible_syscalls() { let mut injection_types = SysCallsInjectionTypes::all_never(); injection_types.set(syscall, INJECTED_SYSCALLS, INJECTED_SYSCALLS); - let sys_calls_config_builder = + let syscalls_config_builder = SysCallsConfigBuilder::new(injection_types).with_params_config(params_config); // Assert that syscalls results will be processed. let termination_reason = execute_wasm_with_custom_configs( &mut unstructured, - sys_calls_config_builder + syscalls_config_builder .clone() .set_error_processing_config(ErrorProcessingConfig::All) .build(), @@ -226,7 +226,7 @@ fn error_processing_works_for_fallible_syscalls() { // Assert that syscall results will be ignored. let termination_reason = execute_wasm_with_custom_configs( &mut unstructured2, - sys_calls_config_builder.build(), + syscalls_config_builder.build(), initial_memory_write.clone(), 0, true, @@ -261,7 +261,7 @@ fn precise_syscalls_works() { }); for syscall in precise_syscalls { - // Prepare sys-calls config & context settings for test case. + // Prepare syscalls config & context settings for test case. const INJECTED_SYSCALLS: u32 = 1; let mut injection_types = SysCallsInjectionTypes::all_never(); @@ -322,7 +322,7 @@ fn get_params_for_syscall_to_fail( fn execute_wasm_with_custom_configs( unstructured: &mut Unstructured, - sys_calls_config: SysCallsConfig, + syscalls_config: SysCallsConfig, initial_memory_write: Option, outgoing_limit: u32, imitate_reply: bool, @@ -340,15 +340,15 @@ fn execute_wasm_with_custom_configs( initial_size: INITIAL_PAGES as u32, ..MemoryPagesConfig::default() }) - .with_sys_calls_config(sys_calls_config) + .with_syscalls_config(syscalls_config) .with_entry_points_config(EntryPointsSet::Init) .build(), SelectableParams { call_indirect_enabled: false, allowed_instructions: vec![], max_instructions: 0, - min_funcs: 1, - max_funcs: 1, + min_funcs: NonZeroUsize::new(1).unwrap(), + max_funcs: NonZeroUsize::new(1).unwrap(), unreachable_enabled: true, }, );