aboutsummaryrefslogtreecommitdiffstats
path: root/fw/ta_re.py
diff options
context:
space:
mode:
authoruser <user@clank>2026-10-01 15:58:53 +0200
committeruser <user@clank>2026-10-01 15:58:53 +0200
commitb263d133a992c6b3280516f159c664dae6863b5d (patch)
tree2119426cc3556ef8273728ee226a2249d30fce8b /fw/ta_re.py
parentcorrect asd_link_cfg, which was a truncated view, and type by offset signature (diff)
downloadamd-psp-re-b263d133a992c6b3280516f159c664dae6863b5d.tar.gz
amd-psp-re-b263d133a992c6b3280516f159c664dae6863b5d.tar.xz
amd-psp-re-b263d133a992c6b3280516f159c664dae6863b5d.zip
type the formatting-state helpers the hash-name rule cannot see, using size as a second check
First, a truncation audit of the structures already declared, prompted by asd_link_cfg turning out to be half its real size. The check looks for a variable that has BOTH field accesses and leftover raw dereferences, which is what an undersized structure produces. Across every module and build there are none, so no other declared structure is being overrun in the artifacts. Worth noting the limit of that check: it could not have caught asd_link_cfg either, because the functions that overran it were unnamed and therefore untyped, with no field accesses to compare against. The gain this pass is 88 functions across gcp, powerplay, wspe and xgmi that dereference a1 over exactly {0x08, 0x18, 0x1C, 0x20} -- a subset of tee_fmt_state -- but carry no hash-cluster name, so they appear as sub_*/ANON and the name-keyed rule could not reach them. 802 dereferences. Four offsets alone are a weak signature and were not trusted on their own. SIZE is required as a second discriminator: a candidate must be the same byte length as a function that IS a confirmed cluster member. 86 of the 88 satisfy both conditions, and the four sizes involved -- 112, 178, 606, 758 -- all occur among confirmed members. The contrast with the ASD rule is deliberate: there a fifteen-offset signature was specific enough alone, here it is not, and the code says so rather than reusing the same threshold blindly. Measured across fw/decomp: typed field accesses 9058 -> 10789, raw pointer-arithmetic dereferences 10107 -> 9323, field share 47.3% -> 53.6%, struct-typed signatures 5.7% -> 6.0%. More than half of all structured memory access in the artifacts is now through named fields.
Diffstat (limited to 'fw/ta_re.py')
-rw-r--r--fw/ta_re.py34
1 files changed, 34 insertions, 0 deletions
diff --git a/fw/ta_re.py b/fw/ta_re.py
index e115502..d49f3c5 100644
--- a/fw/ta_re.py
+++ b/fw/ta_re.py
@@ -1058,6 +1058,40 @@ def run_type(ta: str, outdir: Path, limit: int | None, validate_only: bool) -> i
% (nret, len(want)), flush=True)
# Signature-based a1 typing for functions no name-keyed rule reaches.
+ # Signature+size typing for the shared formatting state, every module.
+ try:
+ fmt_off = set(_ti0.FMT_SIG_OFFSETS); fmt_sz = set(_ti0.FMT_SIG_SIZES)
+ fmt_ty = _ti0.FMT_SIG_TYPE; fmt_min = _ti0.FMT_SIG_MIN_DEREFS
+ except Exception:
+ fmt_off, fmt_sz, fmt_ty = set(), set(), None
+ nfmt = 0
+ if fmt_off and fmt_ty:
+ for fn3 in funcs:
+ if fn3["size"] not in fmt_sz:
+ continue
+ ad3 = fn3["addr"]
+ nm3 = assigned.get(ad3, (None, None))[0] or fn3["name"]
+ if any(fr in nm3 for fr, _st in shared):
+ continue # already typed by name
+ try:
+ rr3 = client.call(remote_ops.decompile, addr=ad3,
+ include_addresses=False) or {}
+ cf3 = rr3.get("code") or ""
+ except Exception:
+ continue
+ hits3 = re.findall(r"\*\(\s*_?\w+\s*\*\s*\)\s*\(\s*a1\s*\+\s*"
+ r"(\d+|0x[0-9A-Fa-f]+)\s*\)", cf3)
+ if len(hits3) < fmt_min:
+ continue
+ offs3 = {int(x, 0) for x in hits3}
+ if not offs3 or not offs3 <= fmt_off:
+ continue
+ if retype_arg1(client, remote_ops, ad3, nm3, fmt_ty):
+ nfmt += 1
+ if nfmt:
+ print(" fmt-state signature-typed a1 on %d functions" % nfmt,
+ flush=True)
+
if ta == "asd":
core = set(getattr(_ti, "ASD_SIG_CORE", ()) if "_ti" in dir() else ())
try: