ship one record per function: merge the release set, gen reads it, descriptions as doc comments, gates for what was only claimed; v3.0
This commit is contained in:
parent
71ce34edd2
commit
3410a79b6a
28 changed files with 30596 additions and 955 deletions
18
src/rtti.rs
18
src/rtti.rs
|
|
@ -18,11 +18,9 @@ pub struct VTable {
|
|||
|
||||
/// One vtable discovered by the whole-binary sweep — the class inventory row.
|
||||
pub struct ClassVtable {
|
||||
pub mangled: String, // the raw `_ZTS` type name, e.g. "11CBaseEntity"
|
||||
pub name: String, // demangled, e.g. "CBaseEntity"
|
||||
pub vtable_va: u64, // vaddr of slot index 0
|
||||
pub offset_to_top: i64, // 0 for the primary (complete-object) vtable; <0 for sub-object tables
|
||||
pub typeinfo: u64, // vaddr of the Itanium typeinfo struct
|
||||
pub slots: Vec<u64>, // method vaddrs; a method's gamedata offset == its index here
|
||||
pub bases: Vec<BaseClass>, // direct base classes (the is-a graph edges)
|
||||
}
|
||||
|
|
@ -143,10 +141,10 @@ fn demangle_type(mangled: &str) -> String {
|
|||
.unwrap_or_else(|| mangled.to_string())
|
||||
}
|
||||
|
||||
/// If `ti` addresses a valid Itanium typeinfo, return its `(mangled, demangled)` class name.
|
||||
/// If `ti` addresses a valid Itanium typeinfo, return its DEMANGLED class name.
|
||||
/// A typeinfo is `[kind_vtable_ptr][name_ptr][ base-class data … ]`: `+0` points at one of the
|
||||
/// C++ runtime's type_info-kind vtables, `+8` at the `_ZTS` name string.
|
||||
fn typeinfo_name(img: &CodeImage, ti: u64, kinds: &RttiKinds) -> Option<(String, String)> {
|
||||
fn typeinfo_name(img: &CodeImage, ti: u64, kinds: &RttiKinds) -> Option<String> {
|
||||
// +0 must be one of the three kind vtables. Prefer the symbol-name-derived tag (the only signal that
|
||||
// survives a DYNAMICALLY-linked C++ runtime, where the three kinds all resolve to the same offline
|
||||
// value); else fall back to the in-image value check (statically-linked / stripped builds).
|
||||
|
|
@ -163,7 +161,7 @@ fn typeinfo_name(img: &CodeImage, ti: u64, kinds: &RttiKinds) -> Option<(String,
|
|||
if !(c0.is_ascii_digit() || matches!(c0, b'N' | b'I' | b'P' | b'K' | b'S')) {
|
||||
return None;
|
||||
}
|
||||
Some((mangled.clone(), demangle_type(&mangled)))
|
||||
Some(demangle_type(&mangled))
|
||||
}
|
||||
|
||||
/// Direct base classes of the typeinfo at `ti`, dispatched on its exact Itanium kind.
|
||||
|
|
@ -187,7 +185,7 @@ fn typeinfo_bases(img: &CodeImage, ti: u64, kinds: &RttiKinds) -> Vec<BaseClass>
|
|||
Some(KindTag::Si) => {
|
||||
// __si_class_type_info: one public, non-virtual base at offset 0; its typeinfo ptr at +16.
|
||||
if let Some(bp) = img.read_ptr(ti.wrapping_add(16))
|
||||
&& let Some((_, name)) = typeinfo_name(img, bp, kinds)
|
||||
&& let Some(name) = typeinfo_name(img, bp, kinds)
|
||||
{
|
||||
return vec![BaseClass {
|
||||
name,
|
||||
|
|
@ -199,7 +197,7 @@ fn typeinfo_bases(img: &CodeImage, ti: u64, kinds: &RttiKinds) -> Vec<BaseClass>
|
|||
}
|
||||
Some(KindTag::Vmi) => {
|
||||
// __vmi_class_type_info: flags@+16, base_count@+20, then 16-byte {typeinfo_ptr, offset_flags}.
|
||||
let Some(count) = img.read_u32(ti + 20) else {
|
||||
let Some(count) = img.read_u32(ti.wrapping_add(20)) else {
|
||||
return Vec::new();
|
||||
};
|
||||
if count == 0 || count > 128 {
|
||||
|
|
@ -211,7 +209,7 @@ fn typeinfo_bases(img: &CodeImage, ti: u64, kinds: &RttiKinds) -> Vec<BaseClass>
|
|||
let Some(bp) = img.read_ptr(e) else {
|
||||
break;
|
||||
};
|
||||
if let Some((_, name)) = typeinfo_name(img, bp, kinds) {
|
||||
if let Some(name) = typeinfo_name(img, bp, kinds) {
|
||||
let of = img.read_i64(e.wrapping_add(8)).unwrap_or(0);
|
||||
bases.push(BaseClass {
|
||||
name,
|
||||
|
|
@ -239,7 +237,7 @@ pub fn enumerate_vtables(img: &CodeImage, max_slots: usize) -> Vec<ClassVtable>
|
|||
if slot < 8 {
|
||||
continue;
|
||||
}
|
||||
let Some((mangled, name)) = typeinfo_name(img, val, &kinds) else {
|
||||
let Some(name) = typeinfo_name(img, val, &kinds) else {
|
||||
continue;
|
||||
};
|
||||
// No de-dup guard: `reloc_slots` iterates a map KEYED by slot vaddr, so every slot — and hence
|
||||
|
|
@ -259,11 +257,9 @@ pub fn enumerate_vtables(img: &CodeImage, max_slots: usize) -> Vec<ClassVtable>
|
|||
}
|
||||
let bases = typeinfo_bases(img, val, &kinds);
|
||||
out.push(ClassVtable {
|
||||
mangled,
|
||||
name,
|
||||
vtable_va,
|
||||
offset_to_top: ott,
|
||||
typeinfo: val,
|
||||
slots,
|
||||
bases,
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue