From b26d9a6f1e0bad4700d0fce22732bf5cf4af04a0 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 12 Apr 2017 17:58:28 +0300 Subject: [PATCH] gas utility initial --- gas/.gitignore | 1 + gas/Cargo.lock | 23 ++++++++++++++++++ gas/Cargo.toml | 7 ++++++ gas/src/main.rs | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+) create mode 100644 gas/.gitignore create mode 100644 gas/Cargo.lock create mode 100644 gas/Cargo.toml create mode 100644 gas/src/main.rs diff --git a/gas/.gitignore b/gas/.gitignore new file mode 100644 index 0000000..1de5659 --- /dev/null +++ b/gas/.gitignore @@ -0,0 +1 @@ +target \ No newline at end of file diff --git a/gas/Cargo.lock b/gas/Cargo.lock new file mode 100644 index 0000000..7adb829 --- /dev/null +++ b/gas/Cargo.lock @@ -0,0 +1,23 @@ +[root] +name = "gas" +version = "0.1.0" +dependencies = [ + "parity-wasm 0.2.0 (git+https://github.com/nikvolf/parity-wasm)", +] + +[[package]] +name = "byteorder" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "parity-wasm" +version = "0.2.0" +source = "git+https://github.com/nikvolf/parity-wasm#cafc5058357f6ea84daaec870057da8455bf74e8" +dependencies = [ + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8" +"checksum parity-wasm 0.2.0 (git+https://github.com/nikvolf/parity-wasm)" = "" diff --git a/gas/Cargo.toml b/gas/Cargo.toml new file mode 100644 index 0000000..9f0e103 --- /dev/null +++ b/gas/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gas" +version = "0.1.0" +authors = ["NikVolf "] + +[dependencies] +parity-wasm = { git="https://github.com/nikvolf/parity-wasm" } \ No newline at end of file diff --git a/gas/src/main.rs b/gas/src/main.rs new file mode 100644 index 0000000..f451242 --- /dev/null +++ b/gas/src/main.rs @@ -0,0 +1,64 @@ +extern crate parity_wasm; + +use std::env; +use parity_wasm::{builder, elements}; + +pub fn update_call_index(opcodes: &mut elements::Opcodes, inserted_index: u32) { + use parity_wasm::elements::Opcode::*; + for opcode in opcodes.elements_mut().iter_mut() { + match opcode { + &mut Block(_, ref mut block) | &mut If(_, ref mut block) => { + update_call_index(block, inserted_index) + }, + &mut Call(ref mut call_index) | &mut CallIndirect(ref mut call_index, _) => { + if *call_index >= inserted_index { *call_index += 1} + }, + _ => { } + } + } +} + +fn main() { + + let args = env::args().collect::>(); + if args.len() != 3 { + println!("Usage: {} input_file.wasm output_file.wasm", args[0]); + return; + } + + // Loading module + let module = parity_wasm::deserialize_file(&args[1]).unwrap(); + + // Injecting gas counting external + let mut mbuilder = builder::from_module(module); + let import_sig = mbuilder.push_signature( + builder::signature() + .param().i32() + .param().i32() + .return_type().i32() + .build_sig() + ); + + let gas_func = mbuilder.push_import( + builder::import() + .module("env") + .field("gas") + .external().func(import_sig) + .build() + ); + + // Updating calling addresses (all calls to function index >= `gas_func` should be incremented) + let mut module = mbuilder.build(); + for section in module.sections_mut() { + match section { + &mut elements::Section::Code(ref mut code_section) => { + for ref mut func_body in code_section.bodies_mut() { + update_call_index(func_body.code_mut(), gas_func); + } + }, + _ => { } + } + } + + parity_wasm::serialize_to_file(&args[2], module).unwrap(); +}