ship one record per function: merge the release set, gen reads it, descriptions as doc comments, gates for what was only claimed; v3.0
Some checks failed
CI / fuzz (push) Successful in 2m2s
CI / lint (push) Successful in 15s
CI / test (push) Failing after 18s

This commit is contained in:
Kamal Tufekcic 2026-08-02 22:01:36 +03:00
commit 3410a79b6a
28 changed files with 30596 additions and 955 deletions

View file

@ -17,6 +17,23 @@ use iced_x86::{Decoder, DecoderOptions, FlowControl, OpKind};
use std::collections::BTreeSet;
use std::path::{Path, PathBuf};
/// Every plausible function ENTRY in the image, sorted and deduped: relocation code-pointers (every vtable
/// slot, every stored function pointer) decoded `call` targets `.eh_frame` FDE starts.
///
/// The union is the point, and it is why this is one function rather than four lines repeated. CS2 strips
/// `.eh_frame` from the game code — the FDE list covers the statically-linked runtime tail, roughly 8,327
/// of libserver's ~70,000 functions — so an FDE-only list misses the entire gameplay region, while a
/// relocation/call-target-only list misses the runtime tail that has no code pointer taken. Six callers
/// need exactly this set: the xref index, the ConVar and VScript readers, the change digest, and both
/// anchor passes. A fork adding PLT or ifunc entries edits here, once.
pub fn function_entries(img: &CodeImage) -> Vec<u64> {
let mut entries = candidate_entries(img);
entries.extend(img.eh_frame_functions().into_iter().map(|(s, _)| s));
entries.sort_unstable();
entries.dedup();
entries
}
/// Every plausible function entry address in `img`: relocation values that point into code, plus
/// the targets of direct near `call`s found by a linear sweep. Sorted, de-duplicated.
pub fn candidate_entries(img: &CodeImage) -> Vec<u64> {