Make debuginfo parsing optional.
This commit is contained in:
parent
d7c5dc934b
commit
0e2e5bf098
|
@ -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") {
|
||||||
|
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -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[..])?;
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>> {
|
||||||
|
|
Loading…
Reference in a new issue