forked from Ports/goldeneye-pc-port
@
D131: restore truncated module ptr in seg_addr (Jungle -level_37) explosionRenderPropSmoke passes a compiled .bss matrix symbol (&dword_CODE_bss_8007A100) through osVirtualToPhysical() -- a u32-returning shim -- into gSPMatrix, truncating the 0x1_00000000 module high word. w1 lands as 0x40xxxxxx and seg_addr() returns it raw -> wild deref in gfx_sp_matrix when the first explosion draws (~frame 300). Fix: seg_addr() restores the module high word for any fallthrough w1 in [0x40000000, 0x70000000) (module fixed-based at 0x140000000, no ASLR; DRAM/KSEG0/segmented/phys are all handled in earlier branches). Covers the ~30 latent osVirtualToPhysical(<compiled matrix/vtx symbol>) sites in explosion/glass/blood/bondview2. Verified: Jungle renders to frame 1500-2400+ crash-free at 91.7% content; -level_20/-level_24 unregressed. Sweep 18->19/21 (note: -level_09 has a separate pre-existing boot crash regressed since M-18 -- see HANDOFF). @
This commit is contained in:
1 parent
1c4efdaaf2
commit
bb14baf3bf
6 files changed
+227
-14
No files matched your search
@@ -2405,6 +2405,23 @@ static inline void *seg_addr(uintptr_t w1) {
|
||||
if (w1 < 0x800000) {
|
||||
return (void *)(w1 + 0x80000000);
|
||||
}
|
||||
// D131: a GBI DL built by game code can reference a COMPILED symbol via
|
||||
// osVirtualToPhysical() (a u32-returning shim), which truncates the
|
||||
// module's 0x1_00000000 high word. Seen in explosionRenderPropSmoke:
|
||||
// gSPMatrix(gdl++, osVirtualToPhysical((void*)&dword_CODE_bss_8007A100),
|
||||
// ..MODELVIEW) -> w1 == 0x40xxxxxx -> wild deref in gfx_sp_matrix. The
|
||||
// module is based at 0x140000000 (fixed, no ASLR), and nothing legit
|
||||
// reaches this fallthrough with a value in [0x40000000, DRAM_V1): DRAM
|
||||
// (>=0x70000000), KSEG0 (>=0x80000000), segmented addrs and sub-0x800000
|
||||
// physical offsets are all handled above. Restore the high word from
|
||||
// this TU's own load address.
|
||||
{
|
||||
static const uintptr_t mod_hi =
|
||||
((uintptr_t)(void *)&segmentPointers[0]) & 0xffffffff00000000ULL;
|
||||
if (mod_hi && w1 >= 0x40000000 && w1 < 0x70000000) {
|
||||
return (void *)(mod_hi | w1);
|
||||
}
|
||||
}
|
||||
return (void *)w1;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user