Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/dwarves

crates/dwarves-tune-graph/src/main.rs

//! `dwarves-tune-graph --graph <graph.json> --profile <probe.json|oci.json> [--json]`
//!
//! The cross-check of a Graph JSON file (the POSSIBLE syscalls, written by the
//! owner's engine) with what a Heimdall probe SAW. Text by default, the
//! report document with `--json`. Exit 0 = a report, 2 = a usage or input
//! error. It guides review and tests only; it never widens a filter.

use std::path::PathBuf;
use std::process::ExitCode;

const USAGE: &str =
    "usage: dwarves-tune-graph --graph <graph.json> --profile <probe.json|oci.json> [--json]";

fn fail(msg: impl std::fmt::Display) -> ExitCode {
    eprintln!("dwarves-tune-graph: {msg}");
    ExitCode::from(2)
}

fn main() -> ExitCode {
    let mut graph: Option<PathBuf> = None;
    let mut profile: Option<PathBuf> = None;
    let mut json = false;
    let mut binary: Option<String> = None;
    let mut args = std::env::args().skip(1);
    while let Some(a) = args.next() {
        match a.as_str() {
            "--graph" => graph = args.next().map(PathBuf::from),
            "--profile" => profile = args.next().map(PathBuf::from),
            "--json" => json = true,
            "-h" | "--help" => {
                println!("{USAGE}");
                return ExitCode::SUCCESS;
            }
            s if s.starts_with('-') => return fail(format!("unknown flag {s}\n{USAGE}")),
            s => binary = Some(s.to_string()),
        }
    }
    let Some(graph) = graph else {
        return fail(format!(
            "{}: the possible syscalls come from a Graph JSON file (the owner's engine): pass --graph <graph.json>\n{USAGE}",
            binary.as_deref().unwrap_or("no graph")
        ));
    };
    let Some(profile) = profile else {
        return fail(format!("name the probe file: --profile <probe.json|oci.json>\n{USAGE}"));
    };
    let g = match dwarves_tune_graph::read_graph(&graph) {
        Ok(g) => g,
        Err(e) => return fail(e),
    };
    let s = match dwarves_tune_graph::read_seen(&profile) {
        Ok(s) => s,
        Err(e) => return fail(e),
    };
    let r = dwarves_tune_graph::cross_check(&g, &s);
    if json {
        println!("{}", serde_json::to_string_pretty(&r).expect("a report serializes"));
    } else {
        print!("{}", dwarves_tune_graph::render_text(&r));
    }
    ExitCode::SUCCESS
}