The old src/ppc.rs that re-implemented PPC formatting collapses into a 30-line shim that delegates to xenia-cpu's single-source-of-truth disasm. A new disasm.rs wraps the shared iterator and feeds enriched items (analysis context: function membership, xrefs, mnemonics) into pluggable sinks. Sinks split: text.rs (objdump-like output), json.rs (JSONL stream matching the new xenia dis --json mode), duckdb.rs (the analysis DB ingest). db.rs is restructured into ingest_instructions + write_analysis_results so a run can stop after raw ingest, and a new target_hex column lands on the instructions table. sql_views.rs adds five additive views layered on top of the raw tables. Tests: assert-based JSON-fixture goldens (disasm_goldens) and a PRAGMA-table_info schema golden (db_schema_golden) covering all ingested tables and the SQL views. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
1.7 KiB
Rust
52 lines
1.7 KiB
Rust
//! Analysis-side enrichment over [`xenia_cpu::disasm::iter_disasm`].
|
|
//!
|
|
//! Turns a stream of decoder-only [`xenia_cpu::disasm::DisasmItem`]s into a
|
|
//! stream of [`RichDisasmItem`]s carrying section name + enclosing function +
|
|
//! label name. The three sinks in [`crate::sinks`] (text, JSON, DuckDB) all
|
|
//! consume `RichDisasmItem`.
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use xenia_cpu::disasm::DisasmItem;
|
|
|
|
use crate::func::FuncAnalysis;
|
|
|
|
/// `DisasmItem` plus the analysis context (section/function/label).
|
|
#[derive(Debug, Clone)]
|
|
pub struct RichDisasmItem<'a> {
|
|
pub item: DisasmItem,
|
|
pub section: &'a str,
|
|
pub function: Option<u32>,
|
|
pub label: Option<&'a str>,
|
|
}
|
|
|
|
/// Walk one code section, yielding rich items annotated with section name,
|
|
/// rolling-window enclosing function, and label-at-address.
|
|
///
|
|
/// The `function` field tracks the most recent function-start the iterator
|
|
/// has crossed — matching the legacy `current_func` behaviour in
|
|
/// `db.rs::insert_instructions_streaming`.
|
|
pub fn enrich_section<'a>(
|
|
image: &'a [u8],
|
|
image_base: u32,
|
|
section_name: &'a str,
|
|
va_start: u32,
|
|
va_end: u32,
|
|
func_analysis: &'a FuncAnalysis,
|
|
labels: &'a HashMap<u32, String>,
|
|
) -> impl Iterator<Item = RichDisasmItem<'a>> + 'a {
|
|
let mut current_func: Option<u32> = None;
|
|
xenia_cpu::disasm::iter_disasm(image, image_base, va_start, va_end).map(move |item| {
|
|
if func_analysis.is_function_start(item.addr) {
|
|
current_func = Some(item.addr);
|
|
}
|
|
let label = labels.get(&item.addr).map(|s| s.as_str());
|
|
RichDisasmItem {
|
|
item,
|
|
section: section_name,
|
|
function: current_func,
|
|
label,
|
|
}
|
|
})
|
|
}
|