From 0e2e5bf09801fd58bab165bbdb86a61670418c04 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Thu, 16 Feb 2023 16:20:54 -0800 Subject: [PATCH] Make debuginfo parsing optional. --- fuzz/fuzz_targets/differential.rs | 7 +++-- fuzz/fuzz_targets/parse_ir.rs | 5 ++-- fuzz/fuzz_targets/roundtrip.rs | 35 ++++++++++++------------ fuzz/fuzz_targets/roundtrip_roundtrip.rs | 10 ++++--- src/bin/waffle-util.rs | 16 +++++++++-- src/frontend.rs | 14 ++++++++-- src/ir/module.rs | 6 ++-- 7 files changed, 59 insertions(+), 34 deletions(-) diff --git a/fuzz/fuzz_targets/differential.rs b/fuzz/fuzz_targets/differential.rs index 425f9b9..e9926a0 100644 --- a/fuzz/fuzz_targets/differential.rs +++ b/fuzz/fuzz_targets/differential.rs @@ -2,7 +2,7 @@ use libfuzzer_sys::{arbitrary, fuzz_target}; use std::sync::atomic::{AtomicU64, Ordering}; -use waffle::Module; +use waffle::{FrontendOptions, Module}; fn reject(bytes: &[u8]) -> bool { let parser = wasmparser::Parser::new(0); @@ -134,8 +134,9 @@ fuzz_target!(|module: wasm_smith::ConfiguredModule| { } }; - let mut parsed_module = Module::from_wasm_bytes(&orig_bytes[..]).unwrap(); - parsed_module.optimize(); + let mut parsed_module = + Module::from_wasm_bytes(&orig_bytes[..], &FrontendOptions::default()).unwrap(); + parsed_module.per_func_body(|body| body.optimize()); let roundtrip_bytes = parsed_module.to_wasm_bytes().unwrap(); if let Ok(filename) = std::env::var("FUZZ_DUMP_WASM") { diff --git a/fuzz/fuzz_targets/parse_ir.rs b/fuzz/fuzz_targets/parse_ir.rs index 6fbdc0a..3c6e50c 100644 --- a/fuzz/fuzz_targets/parse_ir.rs +++ b/fuzz/fuzz_targets/parse_ir.rs @@ -1,9 +1,10 @@ #![no_main] use libfuzzer_sys::fuzz_target; -use waffle::Module; +use waffle::{FrontendOptions, Module}; fuzz_target!(|module: wasm_smith::Module| { let _ = env_logger::try_init(); - let _parsed_module = Module::from_wasm_bytes(&module.to_bytes()[..]).unwrap(); + let _parsed_module = + Module::from_wasm_bytes(&module.to_bytes()[..], &FrontendOptions::default()).unwrap(); }); diff --git a/fuzz/fuzz_targets/roundtrip.rs b/fuzz/fuzz_targets/roundtrip.rs index 66958f7..1375a97 100644 --- a/fuzz/fuzz_targets/roundtrip.rs +++ b/fuzz/fuzz_targets/roundtrip.rs @@ -1,30 +1,31 @@ #![no_main] use libfuzzer_sys::fuzz_target; -use waffle::{FrontendError, Module}; +use waffle::{FrontendError, FrontendOptions, Module}; fuzz_target!(|module: wasm_smith::Module| { let _ = env_logger::try_init(); log::debug!("original module: {:?}", module); let orig_bytes = module.to_bytes(); - let mut parsed_module = match Module::from_wasm_bytes(&orig_bytes[..]) { - Ok(m) => m, - Err(e) => { - match e.downcast::() { - Ok(FrontendError::UnsupportedFeature(_)) | Ok(FrontendError::TooLarge(_)) => { - // Just skip this case. - return; - } - Ok(e) => { - panic!("Frontend error: {:?}", e); - } - Err(e) => { - panic!("Other error when parsing module: {:?}", e); + let mut parsed_module = + match Module::from_wasm_bytes(&orig_bytes[..], &FrontendOptions::default()) { + Ok(m) => m, + Err(e) => { + match e.downcast::() { + Ok(FrontendError::UnsupportedFeature(_)) | Ok(FrontendError::TooLarge(_)) => { + // Just skip this case. + return; + } + Ok(e) => { + panic!("Frontend error: {:?}", e); + } + Err(e) => { + panic!("Other error when parsing module: {:?}", e); + } } } - } - }; + }; parsed_module.expand_all_funcs().unwrap(); - parsed_module.optimize(); + parsed_module.per_func_body(|body| body.optimize()); let _ = parsed_module.to_wasm_bytes(); }); diff --git a/fuzz/fuzz_targets/roundtrip_roundtrip.rs b/fuzz/fuzz_targets/roundtrip_roundtrip.rs index 7beb722..1bffc5b 100644 --- a/fuzz/fuzz_targets/roundtrip_roundtrip.rs +++ b/fuzz/fuzz_targets/roundtrip_roundtrip.rs @@ -1,17 +1,19 @@ #![no_main] use libfuzzer_sys::fuzz_target; -use waffle::Module; +use waffle::{FrontendOptions, Module}; fuzz_target!(|module: wasm_smith::Module| { let _ = env_logger::try_init(); log::debug!("original module: {:?}", module); let orig_bytes = module.to_bytes(); - let parsed_module = Module::from_wasm_bytes(&orig_bytes[..]).unwrap(); - let roundtrip_bytes = parsed_module.to_wasm_bytes(); + let parsed_module = + Module::from_wasm_bytes(&orig_bytes[..], &FrontendOptions::default()).unwrap(); + let roundtrip_bytes = parsed_module.to_wasm_bytes().unwrap(); if let Ok(filename) = std::env::var("ROUNDTRIP_WASM_SAVE") { std::fs::write(filename, &roundtrip_bytes[..]).unwrap(); } - let parsed_roundtrip_module = Module::from_wasm_bytes(&roundtrip_bytes[..]).unwrap(); + let parsed_roundtrip_module = + Module::from_wasm_bytes(&roundtrip_bytes[..], &FrontendOptions::default()).unwrap(); let _ = parsed_roundtrip_module.to_wasm_bytes(); }); diff --git a/src/bin/waffle-util.rs b/src/bin/waffle-util.rs index 3d378fb..0b4b14b 100644 --- a/src/bin/waffle-util.rs +++ b/src/bin/waffle-util.rs @@ -4,7 +4,7 @@ use anyhow::Result; use log::debug; use std::path::PathBuf; use structopt::StructOpt; -use waffle::Module; +use waffle::{FrontendOptions, Module}; #[derive(Debug, StructOpt)] #[structopt(name = "waffle-util", about = "WAFFLE utility.")] @@ -18,6 +18,13 @@ struct Options { )] basic_opts: bool, + #[structopt( + help = "Enable parsing of debug-info from input", + short = "g", + long = "debug-info" + )] + debug_info: bool, + #[structopt(help = "Transform to maximal SSA", long = "max-ssa")] max_ssa: bool, @@ -61,18 +68,21 @@ fn main() -> Result<()> { } let _ = logger.try_init(); + let mut options = FrontendOptions::default(); + options.debug = opts.debug_info; + match &opts.command { Command::PrintIR { wasm } => { let bytes = std::fs::read(wasm)?; debug!("Loaded {} bytes of Wasm data", bytes.len()); - let mut module = Module::from_wasm_bytes(&bytes[..])?; + let mut module = Module::from_wasm_bytes(&bytes[..], &options)?; apply_options(&opts, &mut module)?; println!("{}", module.display()); } Command::RoundTrip { input, output } => { let bytes = std::fs::read(input)?; debug!("Loaded {} bytes of Wasm data", bytes.len()); - let mut module = Module::from_wasm_bytes(&bytes[..])?; + let mut module = Module::from_wasm_bytes(&bytes[..], &options)?; apply_options(&opts, &mut module)?; let produced = module.to_wasm_bytes()?; std::fs::write(output, &produced[..])?; diff --git a/src/frontend.rs b/src/frontend.rs index ae98a79..a0e1ce2 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -16,7 +16,12 @@ use wasmparser::{ BlockType, DataKind, ExternalKind, Name, NameSectionReader, Parser, Payload, TypeRef, }; -pub fn wasm_to_ir(bytes: &[u8]) -> Result> { +#[derive(Clone, Copy, Debug, Default)] +pub struct FrontendOptions { + pub debug: bool, +} + +pub fn wasm_to_ir<'a>(bytes: &'a [u8], options: &FrontendOptions) -> Result> { let mut module = Module::with_orig_bytes(bytes); let parser = Parser::new(0); let mut next_func = 0; @@ -36,8 +41,11 @@ pub fn wasm_to_ir(bytes: &[u8]) -> Result> { gimli::LocationLists::new(extra_sections.debug_loc, extra_sections.debug_loclists); dwarf.ranges = gimli::RangeLists::new(extra_sections.debug_ranges, extra_sections.debug_rnglists); - let debug_map = DebugMap::from_dwarf(dwarf, &mut module.debug, extra_sections.code_offset)?; - module.debug_map = debug_map; + + if options.debug { + let debug_map = DebugMap::from_dwarf(dwarf, &mut module.debug, extra_sections.code_offset)?; + module.debug_map = debug_map; + } Ok(module) } diff --git a/src/ir/module.rs b/src/ir/module.rs index ae2e75c..b610b71 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -4,6 +4,8 @@ use crate::ir::{Debug, DebugMap, FunctionBody}; use crate::{backend, frontend}; use anyhow::Result; +pub use crate::frontend::FrontendOptions; + #[derive(Clone, Debug)] pub struct Module<'a> { pub orig_bytes: &'a [u8], @@ -159,8 +161,8 @@ impl<'a> Module<'a> { }) } - pub fn from_wasm_bytes(bytes: &'a [u8]) -> Result { - frontend::wasm_to_ir(bytes) + pub fn from_wasm_bytes(bytes: &'a [u8], options: &FrontendOptions) -> Result { + frontend::wasm_to_ir(bytes, options) } pub fn to_wasm_bytes(&self) -> Result> {