fold/docs/research/vendor-architecture-map-2026-05-31.md

4.5 KiB

Vendor Architecture Map

Date: 2026-05-31; updated after Ghidra x86/x86-64 and P-Code summary work. Reading list: docs/research/vendor-library-study-2026-05-31.md.

Architecture decision

Fold has three vendor-facing lanes:

  1. Ghidra/SLEIGH owns binary semantics. It produces raw/high P-Code and def-use evidence for binary detectors.
  2. LIEF is the next metadata candidate. It can replace or supplement r2 for ELF/PE/Mach-O structure, symbols, sections, imports, exports, and entry points.
  3. Souffle is the next fact-engine candidate. It should consume Fold-owned MidIR facts only after stable IDs and provenance exist.

Everything else is deferred research. RetDec, Remill/McSema, PhASAR, and Crab/Clam should not have active Meson options or third_party/ slots until a fixture proves need.

Binary path

Binary
  ├─ r2 metadata now ───────────────▶ metadata facts + heuristic findings
  ├─ LIEF metadata candidate ───────▶ stable ELF/PE/Mach-O metadata facts
  ├─ Ghidra raw P-Code ─────────────▶ op-level hazards for Z3/observers
  └─ Ghidra high P-Code / SSA ──────▶ def-use, write summaries, call evidence

Ghidra and LIEF are complementary: Ghidra models instructions; LIEF models file structure.

Lane ownership

Lane Owner Output Status
Binary metadata r2 now; LIEF candidate format, arch, sections, symbols, imports, exports, entry point r2 active; LIEF manifest-only
Binary semantics Ghidra/SLEIGH P-Code ops, varnodes, def-use, path/call/write evidence active behind -Dghidra=enabled
Source semantics Clang AST/CFG source observer hooks, source findings active
Interprocedural facts native graph code now; Souffle candidate reachability, taint, transitive calls Souffle manifest-only
Final proof/query Fold Z3 encoder proved/heuristic/syntactic findings active

Required provenance

Every future fact or finding must identify its producer:

backend: source | binary | rust | swift
lane: clang | r2-metadata | lief-metadata | ghidra-raw | ghidra-ssa | souffle-fact
precision: exact | heuristic | over-approximated | bailed
location: source location or binary address/range

Do not widen core::AnalysisBackend for vendor-specific payloads. Add small adapter structs or MidIR/fact records instead.

Integration sequence

1. Continue Ghidra stabilization

  • Keep Ghidra types isolated in src/binary/ghidra_* and P-Code modules.
  • Expand P-Code path predicates and summary tests before broadening hazard gates.
  • Keep checked-in .sla runtime copies plus Meson-generated .sla validation.
  • Preserve binary/source provenance on every finding.

2. Prototype LIEF metadata

  • Inventory current r2 metadata fields used by R2Backend reports.
  • Map those fields to LIEF C++ APIs for ELF, Mach-O, and PE.
  • Emit read-only metadata facts with lief-metadata provenance.
  • Keep r2 fallback until LIEF covers all fields needed by binary reports.

3. Define MidIR/fact IDs

Required before Souffle or any other fact producer:

FunctionId = backend + artifact + entry/source-name
BlockId    = FunctionId + block ordinal/address
OpId       = FunctionId + op ordinal + original address/source loc
ValueId    = lane + varnode/register/local/temp identity

4. Prototype Souffle facts

  • Start with standalone TSV facts and .dl rules.
  • First relations: Reachable, ValueFlowsTo, TaintedAt, CallsTransitively.
  • Treat outputs as derived facts with provenance, not as silent detector filters.
  • Consider generated C++ only after the standalone prototype shows value.

Deferred-lane policy

Candidate Revisit only when
RetDec Ghidra misses a concrete binary semantic class that LLVM lifting preserves.
Remill/McSema A single-block Remill prototype demonstrates needed precision over Ghidra.
PhASAR Fold commits to LLVM IR as a first-class input.
Crab/Clam Native summaries cannot close a concrete numeric range false positive.

Guardrails

  • Keep source and binary backends separate.
  • Do not decompile binary to C and route it through source detectors.
  • Do not link optional vendors into fold-core without a fixture-backed reason.
  • Keep binary metadata metrics separate from binary semantic metrics.
  • Do not let derived facts hide source or binary coverage unless the user explicitly requested a capped/filtered scan.