diff options
author | iximeow <me@iximeow.net> | 2021-07-21 00:19:36 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2021-07-21 00:36:24 -0700 |
commit | d0723a4abfd8b77b15f7b8e0355e86a25e387750 (patch) | |
tree | c91c48b501bbb8fcb16a8b216616dda030475e66 /src/main.rs | |
parent | 12ee099cad10cf93948239bb4b44966d60ffc8af (diff) |
update decoders to yaxpeax_arch 0.2 versions, add lc87 and x86_160.2.5
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 175 |
1 files changed, 119 insertions, 56 deletions
diff --git a/src/main.rs b/src/main.rs index f577a42..0c6a5fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,5 @@ -use yaxpeax_arch::{AddressBase, Arch, Decoder, Instruction, LengthedInstruction}; - use clap::*; -use num_traits::identities::Zero; -use std::fmt; use std::fs::File; use std::io::Read; use std::collections::BTreeSet; @@ -17,17 +13,19 @@ fn main() { .long("--architecture") .takes_value(true) .validator(|a| { - if ["x86_64", "x86:32", "ia64", "armv7", "armv8", "avr", "mips", "msp430", - "pic17", "pic18", "m16c", "6502"].contains(&&a[..]) || + if ["x86_64", "x86_32", "x86_16", + "x86:64", "x86:32", "x86:16", + "ia64", "armv7", "armv8", "avr", "mips", "msp430", + "pic17", "pic18", "m16c", "6502", "lc87"].contains(&&a[..]) || (["sh", "sh2", "sh3", "sh4", "j2"].contains( &&a[0..a.find(|c| c == '+' || c == '-').unwrap_or(a.len())]) && a.split(|c| c == '+' || c == '-').skip(1).all( |f| ["be", "mmu", "fpu", "f64", "j2"].contains(&f))) { Ok(()) } else { - Err("possible values: x86_64, x86:32, ia64, armv7, armv8, avr, mips, \ - msp430, pic17, pic18, m16c, 6502, \ - {sh{,2,3,4},j2}[[+-]{be,mmu,fpu,f64,j2}]*" + Err("possible values: x86_64, x86_32, x86_16, x86:64, x86:32, x86:16, \ + ia64, armv7, armv8, avr, mips, msp430, pic17, pic18, \ + m16c, 6502, lc87, {sh{,2,3,4},j2}[[+-]{be,mmu,fpu,f64,j2}]*" .to_string()) } }) @@ -84,23 +82,28 @@ fn main() { let verbose = matches.occurrences_of("verbose") > 0; match arch_str { - "x86_64" => decode_input::<yaxpeax_x86::long_mode::Arch>(&buf, verbose), - "x86:32" => decode_input::<yaxpeax_x86::protected_mode::Arch>(&buf, verbose), - "ia64" => decode_input::<yaxpeax_ia64::IA64>(&buf, verbose), - "avr" => decode_input::<yaxpeax_avr::AVR>(&buf, verbose), - "armv7" => decode_input::<yaxpeax_arm::armv7::ARMv7>(&buf, verbose), - "armv8" => decode_input::<yaxpeax_arm::armv8::a64::ARMv8>(&buf, verbose), - "mips" => decode_input::<yaxpeax_mips::MIPS>(&buf, verbose), - "msp430" => decode_input::<yaxpeax_msp430::MSP430>(&buf, verbose), - "pic17" => decode_input::<yaxpeax_pic17::PIC17>(&buf, verbose), - "pic18" => decode_input::<yaxpeax_pic18::PIC18>(&buf, verbose), - "m16c" => decode_input::<yaxpeax_m16c::M16C>(&buf, verbose), - "6502" => decode_input::<yaxpeax_6502::N6502>(&buf, verbose), + "x86_64" | + "x86:64" => crate::current_arch::decode_input::<yaxpeax_x86::long_mode::Arch>(&buf, verbose), + "x86_32" | + "x86:32" => crate::current_arch::decode_input::<yaxpeax_x86::protected_mode::Arch>(&buf, verbose), + "x86_16" | + "x86:16" => crate::current_arch::decode_input::<yaxpeax_x86::real_mode::Arch>(&buf, verbose), + "ia64" => crate::current_arch::decode_input::<yaxpeax_ia64::IA64>(&buf, verbose), + "avr" => crate::current_arch::decode_input::<yaxpeax_avr::AVR>(&buf, verbose), + "armv7" => crate::current_arch::decode_input::<yaxpeax_arm::armv7::ARMv7>(&buf, verbose), + "armv8" => crate::current_arch::decode_input::<yaxpeax_arm::armv8::a64::ARMv8>(&buf, verbose), + "mips" => crate::current_arch::decode_input::<yaxpeax_mips::MIPS>(&buf, verbose), + "msp430" => crate::current_arch::decode_input::<yaxpeax_msp430::MSP430>(&buf, verbose), + "pic17" => crate::current_arch::decode_input::<yaxpeax_pic17::PIC17>(&buf, verbose), + "pic18" => crate::current_arch::decode_input::<yaxpeax_pic18::PIC18>(&buf, verbose), + "m16c" => crate::current_arch::decode_input::<yaxpeax_m16c::M16C>(&buf, verbose), + "6502" => crate::legacy_arch::decode_input::<yaxpeax_6502::N6502>(&buf, verbose), + "lc87" => crate::current_arch::decode_input::<yaxpeax_lc87::LC87>(&buf, verbose), // "pic24" => decode_input::<yaxpeax_pic24::PIC24>(buf), other => { let seg_idx = arch_str.find(|c| c == '+' || c == '-').unwrap_or(arch_str.len()); let wps = |base| with_parsed_superh(base, &arch_str[seg_idx..], - |decoder| decode_input_with_decoder::<yaxpeax_superh::SuperH>(decoder, &buf, verbose)); + |decoder| crate::legacy_arch::decode_input_with_decoder::<yaxpeax_superh::SuperH>(decoder, &buf, verbose)); match &arch_str[0..seg_idx] { "sh" => wps(yaxpeax_superh::SuperHDecoder::SH1), "sh2" => wps(yaxpeax_superh::SuperHDecoder::SH2), @@ -150,46 +153,106 @@ fn with_parsed_superh<F: FnOnce(yaxpeax_superh::SuperHDecoder)>( }) } -fn decode_input<A: Arch>(buf: &[u8], verbose: bool) -where - A::Instruction: fmt::Display, -{ - decode_input_with_decoder::<A>(A::Decoder::default(), buf, verbose); -} +// yaxpeax-arch, implemented by all decoders here, is required at incompatible versions by +// different decoders. implement the actual decode-and-print behavior on both versions of +// yaxpeax-arch while older decoders are still being updated. +mod current_arch { + use yaxpeax_arch_02::{AddressBase, Arch, Decoder, Instruction, LengthedInstruction, Reader, U8Reader}; + use std::fmt; + use num_traits::identities::Zero; -fn decode_input_with_decoder<A: Arch>(decoder: A::Decoder, buf: &[u8], verbose: bool) -where - A::Instruction: fmt::Display, -{ - let start = A::Address::zero(); - let mut addr = start; - loop { - match decoder.decode(buf[addr.to_linear()..].iter().cloned()) { - Ok(inst) => { - println!( - "{:#010x}: {:14}: {}", - addr.to_linear(), - hex::encode( - &buf[addr.to_linear()..] - [..A::Address::zero().wrapping_offset(inst.len()).to_linear()] - ), - inst - ); - if verbose { - println!(" {:?}", inst); - if !inst.well_defined() { - println!(" not well-defined"); + pub(crate) fn decode_input<A: Arch>(buf: &[u8], verbose: bool) + where + A::Instruction: fmt::Display, for<'data> U8Reader<'data>: Reader<A::Address, A::Word>, + { + decode_input_with_decoder::<A>(A::Decoder::default(), buf, verbose); + } + + pub(crate) fn decode_input_with_decoder<A: Arch>(decoder: A::Decoder, buf: &[u8], verbose: bool) + where + A::Instruction: fmt::Display, for<'data> U8Reader<'data>: Reader<A::Address, A::Word>, + { + let start = A::Address::zero(); + let mut addr = start; + loop { + let mut reader = U8Reader::new(&buf[addr.to_linear()..]); + match decoder.decode(&mut reader) { + Ok(inst) => { + println!( + "{:#010x}: {:14}: {}", + addr.to_linear(), + hex::encode( + &buf[addr.to_linear()..] + [..A::Address::zero().wrapping_offset(inst.len()).to_linear()] + ), + inst + ); + if verbose { + println!(" {:?}", inst); + if !inst.well_defined() { + println!(" not well-defined"); + } } + addr += inst.len(); + } + Err(e) => { + println!("{:#010x}: {}", addr.to_linear(), e); + addr += A::Instruction::min_size(); } - addr += inst.len(); } - Err(e) => { - println!("{:#010x}: {}", addr.to_linear(), e); - addr += A::Instruction::min_size(); + if addr.to_linear() >= buf.len() { + break; } } - if addr.to_linear() >= buf.len() { - break; + } +} + +mod legacy_arch { + use yaxpeax_arch_01::{AddressBase, Arch, Decoder, Instruction, LengthedInstruction}; + use std::fmt; + use num_traits::identities::Zero; + + pub(crate) fn decode_input<A: Arch>(buf: &[u8], verbose: bool) + where + A::Instruction: fmt::Display, + { + decode_input_with_decoder::<A>(A::Decoder::default(), buf, verbose); + } + + pub(crate) fn decode_input_with_decoder<A: Arch>(decoder: A::Decoder, buf: &[u8], verbose: bool) + where + A::Instruction: fmt::Display, + { + let start = A::Address::zero(); + let mut addr = start; + loop { + match decoder.decode(buf[addr.to_linear()..].iter().cloned()) { + Ok(inst) => { + println!( + "{:#010x}: {:14}: {}", + addr.to_linear(), + hex::encode( + &buf[addr.to_linear()..] + [..A::Address::zero().wrapping_offset(inst.len()).to_linear()] + ), + inst + ); + if verbose { + println!(" {:?}", inst); + if !inst.well_defined() { + println!(" not well-defined"); + } + } + addr += inst.len(); + } + Err(e) => { + println!("{:#010x}: {}", addr.to_linear(), e); + addr += A::Instruction::min_size(); + } + } + if addr.to_linear() >= buf.len() { + break; + } } } } |