Make debuginfo parsing optional.

This commit is contained in:
Chris Fallin 2023-02-16 16:20:54 -08:00
parent d7c5dc934b
commit 0e2e5bf098
7 changed files with 59 additions and 34 deletions

View file

@ -2,7 +2,7 @@
use libfuzzer_sys::{arbitrary, fuzz_target}; use libfuzzer_sys::{arbitrary, fuzz_target};
use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::atomic::{AtomicU64, Ordering};
use waffle::Module; use waffle::{FrontendOptions, Module};
fn reject(bytes: &[u8]) -> bool { fn reject(bytes: &[u8]) -> bool {
let parser = wasmparser::Parser::new(0); let parser = wasmparser::Parser::new(0);
@ -134,8 +134,9 @@ fuzz_target!(|module: wasm_smith::ConfiguredModule<Config>| {
} }
}; };
let mut parsed_module = Module::from_wasm_bytes(&orig_bytes[..]).unwrap(); let mut parsed_module =
parsed_module.optimize(); 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(); let roundtrip_bytes = parsed_module.to_wasm_bytes().unwrap();
if let Ok(filename) = std::env::var("FUZZ_DUMP_WASM") { if let Ok(filename) = std::env::var("FUZZ_DUMP_WASM") {

View file

@ -1,9 +1,10 @@
#![no_main] #![no_main]
use libfuzzer_sys::fuzz_target; use libfuzzer_sys::fuzz_target;
use waffle::Module; use waffle::{FrontendOptions, Module};
fuzz_target!(|module: wasm_smith::Module| { fuzz_target!(|module: wasm_smith::Module| {
let _ = env_logger::try_init(); 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();
}); });

View file

@ -1,13 +1,14 @@
#![no_main] #![no_main]
use libfuzzer_sys::fuzz_target; use libfuzzer_sys::fuzz_target;
use waffle::{FrontendError, Module}; use waffle::{FrontendError, FrontendOptions, Module};
fuzz_target!(|module: wasm_smith::Module| { fuzz_target!(|module: wasm_smith::Module| {
let _ = env_logger::try_init(); let _ = env_logger::try_init();
log::debug!("original module: {:?}", module); log::debug!("original module: {:?}", module);
let orig_bytes = module.to_bytes(); let orig_bytes = module.to_bytes();
let mut parsed_module = match Module::from_wasm_bytes(&orig_bytes[..]) { let mut parsed_module =
match Module::from_wasm_bytes(&orig_bytes[..], &FrontendOptions::default()) {
Ok(m) => m, Ok(m) => m,
Err(e) => { Err(e) => {
match e.downcast::<FrontendError>() { match e.downcast::<FrontendError>() {
@ -25,6 +26,6 @@ fuzz_target!(|module: wasm_smith::Module| {
} }
}; };
parsed_module.expand_all_funcs().unwrap(); parsed_module.expand_all_funcs().unwrap();
parsed_module.optimize(); parsed_module.per_func_body(|body| body.optimize());
let _ = parsed_module.to_wasm_bytes(); let _ = parsed_module.to_wasm_bytes();
}); });

View file

@ -1,17 +1,19 @@
#![no_main] #![no_main]
use libfuzzer_sys::fuzz_target; use libfuzzer_sys::fuzz_target;
use waffle::Module; use waffle::{FrontendOptions, Module};
fuzz_target!(|module: wasm_smith::Module| { fuzz_target!(|module: wasm_smith::Module| {
let _ = env_logger::try_init(); let _ = env_logger::try_init();
log::debug!("original module: {:?}", module); log::debug!("original module: {:?}", module);
let orig_bytes = module.to_bytes(); let orig_bytes = module.to_bytes();
let parsed_module = Module::from_wasm_bytes(&orig_bytes[..]).unwrap(); let parsed_module =
let roundtrip_bytes = parsed_module.to_wasm_bytes(); 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") { if let Ok(filename) = std::env::var("ROUNDTRIP_WASM_SAVE") {
std::fs::write(filename, &roundtrip_bytes[..]).unwrap(); 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(); let _ = parsed_roundtrip_module.to_wasm_bytes();
}); });

View file

@ -4,7 +4,7 @@ use anyhow::Result;
use log::debug; use log::debug;
use std::path::PathBuf; use std::path::PathBuf;
use structopt::StructOpt; use structopt::StructOpt;
use waffle::Module; use waffle::{FrontendOptions, Module};
#[derive(Debug, StructOpt)] #[derive(Debug, StructOpt)]
#[structopt(name = "waffle-util", about = "WAFFLE utility.")] #[structopt(name = "waffle-util", about = "WAFFLE utility.")]
@ -18,6 +18,13 @@ struct Options {
)] )]
basic_opts: bool, 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")] #[structopt(help = "Transform to maximal SSA", long = "max-ssa")]
max_ssa: bool, max_ssa: bool,
@ -61,18 +68,21 @@ fn main() -> Result<()> {
} }
let _ = logger.try_init(); let _ = logger.try_init();
let mut options = FrontendOptions::default();
options.debug = opts.debug_info;
match &opts.command { match &opts.command {
Command::PrintIR { wasm } => { Command::PrintIR { wasm } => {
let bytes = std::fs::read(wasm)?; let bytes = std::fs::read(wasm)?;
debug!("Loaded {} bytes of Wasm data", bytes.len()); 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)?; apply_options(&opts, &mut module)?;
println!("{}", module.display()); println!("{}", module.display());
} }
Command::RoundTrip { input, output } => { Command::RoundTrip { input, output } => {
let bytes = std::fs::read(input)?; let bytes = std::fs::read(input)?;
debug!("Loaded {} bytes of Wasm data", bytes.len()); 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)?; apply_options(&opts, &mut module)?;
let produced = module.to_wasm_bytes()?; let produced = module.to_wasm_bytes()?;
std::fs::write(output, &produced[..])?; std::fs::write(output, &produced[..])?;

View file

@ -16,7 +16,12 @@ use wasmparser::{
BlockType, DataKind, ExternalKind, Name, NameSectionReader, Parser, Payload, TypeRef, BlockType, DataKind, ExternalKind, Name, NameSectionReader, Parser, Payload, TypeRef,
}; };
pub fn wasm_to_ir(bytes: &[u8]) -> Result<Module<'_>> { #[derive(Clone, Copy, Debug, Default)]
pub struct FrontendOptions {
pub debug: bool,
}
pub fn wasm_to_ir<'a>(bytes: &'a [u8], options: &FrontendOptions) -> Result<Module<'a>> {
let mut module = Module::with_orig_bytes(bytes); let mut module = Module::with_orig_bytes(bytes);
let parser = Parser::new(0); let parser = Parser::new(0);
let mut next_func = 0; let mut next_func = 0;
@ -36,8 +41,11 @@ pub fn wasm_to_ir(bytes: &[u8]) -> Result<Module<'_>> {
gimli::LocationLists::new(extra_sections.debug_loc, extra_sections.debug_loclists); gimli::LocationLists::new(extra_sections.debug_loc, extra_sections.debug_loclists);
dwarf.ranges = dwarf.ranges =
gimli::RangeLists::new(extra_sections.debug_ranges, extra_sections.debug_rnglists); gimli::RangeLists::new(extra_sections.debug_ranges, extra_sections.debug_rnglists);
if options.debug {
let debug_map = DebugMap::from_dwarf(dwarf, &mut module.debug, extra_sections.code_offset)?; let debug_map = DebugMap::from_dwarf(dwarf, &mut module.debug, extra_sections.code_offset)?;
module.debug_map = debug_map; module.debug_map = debug_map;
}
Ok(module) Ok(module)
} }

View file

@ -4,6 +4,8 @@ use crate::ir::{Debug, DebugMap, FunctionBody};
use crate::{backend, frontend}; use crate::{backend, frontend};
use anyhow::Result; use anyhow::Result;
pub use crate::frontend::FrontendOptions;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Module<'a> { pub struct Module<'a> {
pub orig_bytes: &'a [u8], pub orig_bytes: &'a [u8],
@ -159,8 +161,8 @@ impl<'a> Module<'a> {
}) })
} }
pub fn from_wasm_bytes(bytes: &'a [u8]) -> Result<Self> { pub fn from_wasm_bytes(bytes: &'a [u8], options: &FrontendOptions) -> Result<Self> {
frontend::wasm_to_ir(bytes) frontend::wasm_to_ir(bytes, options)
} }
pub fn to_wasm_bytes(&self) -> Result<Vec<u8>> { pub fn to_wasm_bytes(&self) -> Result<Vec<u8>> {