aboutsummaryrefslogtreecommitdiffstats
path: root/fw/decomp/ras.summary.json (follow)
Commit message (Collapse)AuthorAge
* generalise SVC-opcode naming corpus-wide after validating it: 501 stubs, ↵user2026-10-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | corpus to 67.0% The opcode decode that closed dtm and csu last commit is not module-specific, so I measured its reach and validated it before applying it anywhere. Validation came free: the libdump already names 299 single-immediate SVC stubs *_rpc_N, which is independent ground truth for exactly this decode. The decoded immediate matches the established number in 296 of 299. The three exceptions are one XGMI function across three builds whose libdump name uses a different numbering scheme, not a bad decode. Applied as a pipeline pass, keyed on bytes rather than addresses so it survives database rebuilds, and only where exactly one in-range immediate survives -- 102 ambiguous stubs stay unnamed rather than guessed. 501 stubs named: hdcp 87 -> 96, fp 92 -> 95, gcp 87 -> 91, opm 62 -> 75, merit 76 -> 79, xgmi 75 -> 76, ras 35 -> 38, asd 64 -> 65, powerplay and wspe smaller. Corpus 19,134 -> 19,405 meaningful names, 66.1% -> 67.0%. A second corroboration turned up after the fact: HDCP's newly decoded hdcp_rpc_161 carries the same service number as ASD's independently libdump-named asd_rpc_161, so two modules calling the same SYS_DRV entry agree without either having been told about the other. Names are uniquified per build; no build contains a duplicate name, checked across all 99. Worth noting what made this possible: the claim being overturned was my own, that these stubs "carry no semantic information whatsoever". It was right about the shared thunks and wrong about the per-module ones, and I had written it down as settled.
* name all five GP entry-point slots from the image header: TMZ reaches 100%user2026-10-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | ta_entry_points read the trampoline's +0xA0 (Create) and +0xB0 (Invoke) slots and threw away the three between them. Those are TA_DestroyEntryPoint, TA_OpenSessionEntryPoint and TA_CloseSessionEntryPoint. That is the whole reason TMZ sat at 50% named: it has six functions and three of the unnamed ones were entry stubs the header identifies exactly. The slot order is read off GCP rather than assumed from the GP spec. GCP has all five named independently and its table reads Create, nullsub(destroy), OpenSession, CloseSession, Invoke, with WSPE and HDCP agreeing and the types agreeing too -- slots 0, 2, 4 return a status, slots 1 and 3 are void. Running the new derivation against GCP reproduces GCP's own names exactly, which is the check that makes this evidence rather than convention. Applied to every module, only where porting left the address unnamed. Per-module: tmz 50 -> 100, rap 76 -> 98, csu 70 -> 92, oc 90 -> 97, dtm 75 -> 89. Corpus 19,038 -> 19,126 meaningful names (65.8% -> 66.1%), field share 75.5% -> 75.8%. RAS disagrees and is deliberately left alone. Its libdump names TA_CreateEntryPoint and TA_DestroyEntryPoint at addresses the header assigns to OpenSession and CloseSession, a systematic two-slot shift across all 18 builds. My first run wrote the header names anyway, which left RAS asserting two different Create entry points -- a contradiction I introduced and then caught by checking for duplicated roles. A guard now refuses to add a second holder of a role, so the conflict is reported on every build and nothing is written. No build has a duplicated entry-point role. Which source is right for RAS stays open: the obvious tiebreaker, argument count, is not decisive on functions IDA never prototyped.
* type the TEE runtime's shared formatting state across every module that names ituser2026-10-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Rather than pick the next target by hand, the artifacts were measured for where raw dereferences through function ARGUMENTS concentrate. That surfaced something better than another per-module struct: the same offset set (0x08, 0x18, 0x1C, 0x20) appears through a1 in gcp, powerplay, wspe and xgmi, in functions whose names are content-hash clusters -- lib_e53fbaaa_32, lib_7fca7c43_82, lib_8680f995_112, lib_366a1ceb_178. RAS is what identifies it. There the same cluster carries real names -- vsnprintf_fmt_int, vsnprintf_fmt_ll, vsnprintf_pad, vsnprintf_prefix -- and adds 0x10, 0x14 and the tail 0x24 byte, 0x25 byte, 0x26 word, closing the layout at 0x28. It is the runtime's string-formatting state. Declaring ONE shared type here is sound where the powerplay ack-word guess was not, and the difference is worth stating: those "_<hash8>_" names come from ta_libmatch.py, which accepts a cluster only when the function bytes match EXACTLY across modules. The functions are literally the same code, so they necessarily share the structure. The earlier ack-word generalisation rested on a resemblance and was wrong. Applied via the first-parameter rewrite, so each function keeps the rest of its recorded signature: 24 functions in RAS, 6 each in wspe and xgmi, 4 each in gcp and powerplay. HDCP was examined and deliberately NOT given a shared struct. Its three heaviest functions -- hdcp2_rx_AKE_Send_Pairing_Info, hdcp2_rx_RepeaterAuth_ReceiverID_List and hdcp2_rx_AKE_Send_Cert, 590 dereferences between them -- share only two offsets, 0x18 and 0x24. They are distinct HDCP2 message layouts, not one structure, and forcing a common type would have misdescribed all three. Honest limit on the reach of this change: the cluster is only NAMED in five modules. In hdcp, opm, merit, auc, fp, rap, csu, oc, dtm and asd the same helpers exist but are still sub_*, so the fragment-keyed typing cannot attach to them. Running the libnames clustering across those modules first would let the same single declaration cover them too -- the clearest next step. Measured across fw/decomp: typed field accesses 5246 -> 7101, raw pointer-arithmetic dereferences 12701 -> 11849, field share 29.2% -> 37.5%, struct-typed signatures 4.8% -> 5.7%.
* apply the prototypes, types and comments the pass had been droppinguser2026-10-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The decompiled artifacts were missing almost all type information. Three things were available in the tree and only one was being used: * declare_type was never called, so no type definitions were parsed at all; * set_type ran only for the four handover types, because fw/libdumps records just {ea,hash,name,size} and the twelve Windows TA types therefore had no signatures to port; * the recorded comments were read into a variable and discarded without ever being applied. All three are now applied, in dependency order, and counted per build so the result is measurable instead of something you have to notice by reading the output. Across 99 builds: 7727 prototypes (was 1232, all of them ASD), 6068 comments (was zero), 309 struct-typed signatures (was zero). The reason prototypes were failing was NOT the missing types, which is what I assumed when I reported "202 of 1434 rejected" without diagnosing it. Declaring the types first changed the rejection count by nothing. 205 of the 239 failures were prototypes recorded in the bare shape 'int()', with no __fastcall for the name-insertion to latch onto, so they were emitted as the unparsable 'int();'. The name now goes before the first parenthesis whatever the shape, and prototypes land 100%: 1434/1434 on the ASD reference, 99/99 HDCP, 9/9 DTM. Worth recording so nobody repeats the detour: the 43 'local_types' in each handover symbol set are ARM NEON and SVE vector typedefs plus va_list and BOOL -- compiler boilerplate with no domain structs in it. Declaring them is harmless and buys nothing. The only real PSP structs in this tree are the seven hand-written ones in fw/ta_ida.py (gcp_ctx, ta_params, gcp_drm_session, gcp_auth_session, gcp_crypto_session, merit_slot, merit_table), which were sitting unused and are now applied: GCP command handlers finally read as '(struct gcp_ctx *ctx, struct ta_params *params)' rather than '(int, int)'. So the remaining type gap is a data gap, not a pipeline one. Thirteen of the sixteen components have no struct definitions anywhere in the repo to apply, and ASD's 6800 prototypes are almost entirely primitive-typed, which is why it shows only 30 struct-typed signatures against 1439 named functions. Closing that needs structs to be defined by hand, component by component.
* extend the decompilation to ASD and the three handover-symbol typesuser2026-10-01
The twelve Windows TA types take their symbols from fw/libdumps; ASD, HDCP, RAS and DTM have theirs in psp_out/handover, in a different shape that also carries prototypes and comments. This adds that reference path, so every component the corpus holds is covered by one pipeline rather than twelve of fifteen. ASD needed its own ELFs. It is driver-class, not a TA: base 0xD00100, and no TA entry trampoline, so dispatcher-anchored naming does not apply to it at all -- its RPC dispatcher hangs off trampoline+0x1C instead. The base is not guessed; it matches psp_out/handover/elf/asd2.elf, whose LOAD segment contains 1562/1562 of the recorded ASD symbols. The frame discriminator used for the TAs is inapplicable here for the same reason the trampoline is: there is none, and it reports "neither" for all 17 builds. Prototypes are applied where recorded. Without them Hex-Rays guesses argument counts and types, which is most of the distance between readable C and a wall of _DWORD; 1232 of 1434 land on the ASD reference and the rest are rejected by IDA, reported rather than hidden. One more false-positive class in the dispatcher cross-check, found by running it on HDCP: the agreement test assumed a ported name encodes its command number, which is GCP's convention and not HDCP's, so every one of HDCP's 16 commands was reported as conflicting. A name can only contradict the dispatcher if it claims a command itself, so the check now requires the ported name to match <ta>_cmd<hex> before judging it. HDCP drops to zero conflicts while GCP's single real one -- the 0xFE07 handler carrying the inherited name gcp_cmdFE03_CreateAuthenticatedSession -- is still reported. Coverage is honest rather than flattering. ASD lands 162-425 named of ~1100-1400 functions per build, and the dominant limiter is ambiguity, not similarity: 677-908 functions per build share a byte signature with a differently-named reference function and are skipped instead of being assigned arbitrarily. ASD is full of identical small stubs, so this is expected, but it means the ASD figures are a floor and a smarter tie-break would raise them. RAS is weaker still at 13-20 named per build.