#![warn(missing_debug_implementations, rust_2018_idioms, missing_docs)]
#![forbid(unsafe_code)]
#[cfg(feature = "armv4t")]
pub mod armv4t;
#[cfg(feature = "m6502")]
pub mod m6502;
#[cfg(feature = "m6809")]
pub mod m6809;
#[cfg(feature = "mips")]
pub mod mips;
#[cfg(feature = "z80")]
pub mod z80;
mod sequence;
pub use sequence::Sequence;
pub mod test;
mod genetic;
pub use genetic::Generate;
mod bruteforce;
pub use bruteforce::{BruteForce, ToBruteForce};
mod subroutine;
mod trace;
pub use trace::{ToTrace, Trace};
pub mod branches;
pub mod dataflow;
pub use branches::Branch;
pub struct StaticAnalysis<Instruction> {
pub offset: usize,
advance: fn(&mut Instruction) -> IterationResult,
pub reason: &'static str,
}
impl<Instruction> StaticAnalysis<Instruction> {
pub fn set_offset(&self, offset: usize) -> Self {
let Self {
offset: _,
advance,
reason,
} = self;
Self {
offset,
advance: *advance,
reason,
}
}
}
impl<Instruction> std::fmt::Debug for StaticAnalysis<Instruction> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
write!(f, "StaticAnalysis {} offset {}", self.reason, self.offset)
}
}
pub trait Step {
fn next(&mut self) -> IterationResult;
fn first() -> Self;
}
pub trait BruteforceSearch<Insn> {
fn analyze_this(&self) -> Result<(), StaticAnalysis<Insn>>;
fn analyze(&mut self) -> Result<(), StaticAnalysis<Insn>> {
self.inner().analyze()?;
self.analyze_this()
}
fn inner(&mut self) -> &mut dyn BruteforceSearch<Insn>;
fn step(&mut self) {
self.inner().step();
self.fixup();
}
fn apply(&mut self, static_analysis: &StaticAnalysis<Insn>) {
self.inner().apply(static_analysis);
}
fn fixup(&mut self) {
while let Err(sa) = self.analyze() {
self.apply(&sa);
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum StepError {
End,
}
pub type IterationResult = Result<(), StepError>;
#[derive(Debug, PartialEq, Eq)]
pub enum RunError {
RanAmok,
NotDefined,
}
pub type RunResult<T> = Result<T, RunError>;
pub trait AsBruteforce<
Insn,
InputParameters,
ReturnType: Clone,
Function: Callable<InputParameters, ReturnType>,
>: Callable<InputParameters, ReturnType> + Clone + BruteforceSearch<Insn>
{
fn bruteforce(
self,
function: Function,
) -> BruteForce<Insn, InputParameters, ReturnType, Function, Self>;
}
pub trait Disassemble {
fn dasm(&self);
}
pub trait Mutate {
fn random() -> Self;
fn mutate(&mut self);
}
pub trait Crossover {
fn crossover(a: &Self, b: &Self) -> Self;
}
pub trait Goto<Insn> {
fn goto(&mut self, destination: &[Insn]);
}
impl<Insn: Clone, S: Clone + AsMut<Sequence<Insn>>> Goto<Insn> for S {
fn goto(&mut self, destination: &[Insn]) {
let s = self.as_mut();
s.goto(destination);
}
}
pub trait Encode<T> {
fn len(&self) -> usize {
self.encode().len()
}
fn is_empty(&self) -> bool {
self.len() == 0
}
fn encode(&self) -> Vec<T>;
}
pub trait Callable<InputParameters, ReturnValue> {
fn call(&self, parameters: InputParameters) -> RunResult<ReturnValue>;
}
impl<InputParameters, ReturnValue> Callable<InputParameters, ReturnValue>
for fn(InputParameters) -> RunResult<ReturnValue>
{
fn call(&self, parameters: InputParameters) -> RunResult<ReturnValue> {
(self)(parameters)
}
}
pub trait Objective<Something> {
fn score(&self, something: &Something) -> f64;
}