Skip to content

Commit

Permalink
feat(wasm-gen): create config for precise sys-calls
Browse files Browse the repository at this point in the history
  • Loading branch information
StackOverflowExcept1on committed Sep 14, 2023
1 parent 4e263f0 commit ef21231
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 20 deletions.
8 changes: 4 additions & 4 deletions utils/wasm-gen/src/config/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
}
Expand All @@ -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();
Expand Down Expand Up @@ -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<u32> {
pub fn injection_amounts(&self, name: InvocableSysCall) -> RangeInclusive<u32> {
self.injection_amounts.get(name)
}

Expand Down
37 changes: 22 additions & 15 deletions utils/wasm-gen/src/config/syscalls/amount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,51 +20,58 @@
//!
//! 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<SysCallName, RangeInclusive<u32>>);
pub struct SysCallsInjectionAmounts(HashMap<InvocableSysCall, RangeInclusive<u32>>);

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<u32>) -> 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<u32> {
pub fn get(&self, name: InvocableSysCall) -> RangeInclusive<u32> {
self.0
.get(&name)
.cloned()
.expect("instantiated with all sys-calls set")
}

/// 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<Item = (SysCallName, RangeInclusive<u32>)>,
sys_calls_freqs: impl Iterator<Item = (InvocableSysCall, RangeInclusive<u32>)>,
) {
self.0.extend(sys_calls_freqs)
}
Expand Down
10 changes: 10 additions & 0 deletions utils/wasm-gen/src/generator/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 3 additions & 1 deletion utils/wasm-gen/src/generator/syscalls/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,9 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> {
&mut self,
sys_call: SysCallName,
) -> Result<Option<(u32, CallIndexesHandle)>> {
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);
Expand Down

0 comments on commit ef21231

Please sign in to comment.