1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#[macro_use]
pub mod util;

pub mod disassemble;
pub mod engine;
pub mod path_exploration;
pub mod solver;

use engine::{Bug, Engine, EngineError, EngineOptions};
use riscu::{load_object_file, Program};
use std::path::Path;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum MonsterError {
    #[error("I/O error")]
    IoError(anyhow::Error),

    #[error("preprocessing failed with error")]
    Preprocessing(anyhow::Error),

    #[error("execution stopped with error")]
    Execution(EngineError),
}

pub fn load_elf<P>(input: P) -> Result<Program, MonsterError>
where
    P: AsRef<Path>,
{
    load_object_file(input).map_err(|e| {
        MonsterError::IoError(anyhow::Error::new(e).context("Failed to load object file"))
    })
}

pub fn execute(program: &Program) -> Result<Option<Bug>, MonsterError> {
    let options = EngineOptions::default();
    let solver = solver::MonsterSolver::default();
    let strategy = path_exploration::ShortestPathStrategy::compute_for(program)
        .map_err(MonsterError::Preprocessing)?;

    execute_with(program, &options, &strategy, &solver)
}

pub fn execute_elf<P: AsRef<Path>>(input: P) -> Result<Option<Bug>, MonsterError> {
    let program = load_elf(input)?;

    execute(&program)
}

pub fn execute_with<Solver, Strategy>(
    program: &Program,
    options: &EngineOptions,
    strategy: &Strategy,
    solver: &Solver,
) -> Result<Option<Bug>, MonsterError>
where
    Strategy: path_exploration::ExplorationStrategy,
    Solver: solver::Solver,
{
    let mut engine = Engine::new(&program, &options, strategy, solver);

    engine.run().map_err(MonsterError::Execution)
}

pub fn execute_elf_with<P, Solver, Strategy>(
    input: P,
    options: &EngineOptions,
    strategy: &Strategy,
    solver: &Solver,
) -> Result<Option<Bug>, MonsterError>
where
    P: AsRef<Path>,
    Strategy: path_exploration::ExplorationStrategy,
    Solver: solver::Solver,
{
    let program = load_elf(input)?;

    execute_with(&program, options, strategy, solver)
}