aboutsummaryrefslogtreecommitdiffstats
path: root/fw/ta_re.py
diff options
context:
space:
mode:
authoruser <user@clank>2026-10-01 16:54:38 +0200
committeruser <user@clank>2026-10-01 16:54:38 +0200
commit4f3bd8d555fa2847ac4cd7854d9b3a8cf4f847e1 (patch)
tree2158848da185be8af6dba56710cad950aa52610b /fw/ta_re.py
parentstop discarding the names the decompiler already knows: 35% -> 63% of functio... (diff)
downloadamd-psp-re-4f3bd8d555fa2847ac4cd7854d9b3a8cf4f847e1.tar.gz
amd-psp-re-4f3bd8d555fa2847ac4cd7854d9b3a8cf4f847e1.tar.xz
amd-psp-re-4f3bd8d555fa2847ac4cd7854d9b3a8cf4f847e1.zip
name functions through the call graph, and fix a rename counter that hid every failure
Byte and mnemonic porting only names a function whose own body still resembles the reference. A function's position in the CALL GRAPH is independent evidence: if reference function A matches target A' and both make the same number of calls, the Nth callee of A' is the Nth callee of A. fw/ta_cgname.py applies that, with three restrictions chosen because positional alignment is exactly the sort of heuristic that quietly invents names: the call counts must be EQUAL or the anchor is skipped entirely rather than aligned partially; every anchor reaching a target must agree on the name, or it is left alone; and the candidate must be within a factor of two of the size of the function whose name it is taking. Rounds iterate, so a function named in one round becomes an anchor in the next. The anchor mismatch rate is reported as its own control, because a high rate means the builds have diverged too far for position to mean anything. For ASD it is 4-8% (9-17 mismatched against 63-269 aligned), which is why the result is trustworthy. For RAS the same tool finds only 4-12 usable anchors and produces nothing at all -- its reference shares too little with the corpus builds, and that is reported rather than worked around. 843 names applied across ASD's 17 non-reference builds, taking ASD from 62.5% to 66.0% named and the corpus overall past two thirds. Found and fixed while debugging why the first run applied zero: the rename response is {"func":[...], "summary":{"ok":N,"failed":M}}, and both this tool and fw/ta_re.py were looking for a "result" list that does not exist. In ta_re.py that meant the rename-error counter reported zero unconditionally for the entire effort -- it could never have told me about a failed rename. Both now read the summary. The symptom was visible only because this tool counted successes rather than failures; the ta_re.py version failed silently in the safe direction, which is why it went unnoticed.
Diffstat (limited to 'fw/ta_re.py')
-rw-r--r--fw/ta_re.py6
1 files changed, 4 insertions, 2 deletions
diff --git a/fw/ta_re.py b/fw/ta_re.py
index 7920ef9..0162091 100644
--- a/fw/ta_re.py
+++ b/fw/ta_re.py
@@ -898,8 +898,10 @@ def run_type(ta: str, outdir: Path, limit: int | None, validate_only: bool) -> i
items = [{"addr": a, "name": n} for a, (n, _t2) in assigned.items()]
rr = client.call(remote_ops.rename,
batch={"func": items, "allow_overwrite": False})
- errs = sum(1 for cat in (rr.get("result") or [])
- for row in (cat.get("func") or []) if row.get("error"))
+ # rename returns {"func":[...], "summary":{"ok":N,"failed":M}}; the old
+ # reading looked for a "result" list that never exists, so this counter
+ # reported zero errors unconditionally and hid every failed rename.
+ errs = int((rr.get("summary") or {}).get("failed", 0))
if errs:
print(" %d rename errors" % errs, flush=True)
# 1. TYPES FIRST. A prototype that names a struct is rejected if the struct is