M3: vtable scan + MSVC RTTI walk + 3 new tables
Adds detection of statically-allocated MSVC vtables in .rdata/.data: - New `xenia_analysis::vtables` walks read-only sections looking for runs of ≥3 contiguous big-endian u32 values where each value lands on a known function start (from M1's corrected functions table). 2-slot runs are rejected to keep false-positive rate down. - For each candidate the MSVC RTTI walk vtable[-1] → CompleteObjectLocator → TypeDescriptor → mangled name is attempted; on success the demangled class name is recorded along with a best-effort RTTIClassHierarchyDescriptor walk to fill base_classes_json. On failure (RTTI stripped — common for shipped game binaries) the class is named ANON_Class_<fnv1a-hash> keyed by sorted method-PC list, so identical vtables collapse to one entry. - DB: new tables `vtables`, `methods`, `classes` with indices on function_address and rtti_present. `write_analysis_results` takes a `&[Vtable]` slice; `write_disasm` (back-compat) passes empty. - cmd_dis wires the scan after xref analysis using `func_analysis.functions.keys()` as the function-start oracle. Validation on Sylpheed (RTTI stripped, as expected): 722 vtables / 499 unique classes / 5571 methods. Sanity invariant: every methods.function_address joins to functions.address (0 broken refs). Largest vtable: 131 slots. Tests 617→621 (+4 vtable unit tests covering 3-slot detect, 2-slot reject, synth name stability, and synth name divergence). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -106,7 +106,7 @@ fn db_schema_matches_expected_columns() {
|
||||
w.write_base(&info).expect("write_base");
|
||||
w.ingest_instructions(&pe, &info, &func_analysis, &labels)
|
||||
.expect("ingest_instructions");
|
||||
w.write_analysis_results(&pe, &info, &func_analysis, &labels, &xrefs)
|
||||
w.write_analysis_results(&pe, &info, &func_analysis, &labels, &xrefs, &[])
|
||||
.expect("write_analysis_results");
|
||||
w.create_sql_views().expect("create_sql_views");
|
||||
}
|
||||
@@ -181,6 +181,27 @@ fn db_schema_matches_expected_columns() {
|
||||
("method_name", "VARCHAR"),
|
||||
("params_signature", "VARCHAR"),
|
||||
]),
|
||||
("vtables", &[
|
||||
("address", "BIGINT"),
|
||||
("length", "BIGINT"),
|
||||
("col_address", "BIGINT"),
|
||||
("class_name", "VARCHAR"),
|
||||
("rtti_present", "BOOLEAN"),
|
||||
("base_classes_json", "VARCHAR"),
|
||||
]),
|
||||
("methods", &[
|
||||
("vtable_address", "BIGINT"),
|
||||
("slot", "BIGINT"),
|
||||
("function_address", "BIGINT"),
|
||||
("mangled_name", "VARCHAR"),
|
||||
("demangled_name", "VARCHAR"),
|
||||
]),
|
||||
("classes", &[
|
||||
("name", "VARCHAR"),
|
||||
("vtable_address", "BIGINT"),
|
||||
("rtti_present", "BOOLEAN"),
|
||||
("base_classes_json", "VARCHAR"),
|
||||
]),
|
||||
("xrefs", &[
|
||||
("source", "BIGINT"),
|
||||
("target", "BIGINT"),
|
||||
|
||||
Reference in New Issue
Block a user