Preserve padded OT allocations with indexed late-packet relocation

This commit is contained in:
Matthew Stanley
2026-10-07 09:33:59 -07:00
parent d1d35c32e5
commit 5cf009df84
2 changed files with 18 additions and 1 deletions
+11 -1
View File
@@ -266,7 +266,17 @@ public:
if((change.value&0x1fffffu)!=end)return refuse(__LINE__);
splice_writes.push_back({change.address,(current_cursor&0xffe00000u)|new_end});
} else {
if(word(ram,change.address)!=word(after_core.data(),change.address))return refuse(__LINE__);
// The real tail's ordinary state updates are authoritative.
// Core replay can change temporary counters/bounds, so matching
// every RAM word against the original core rejects valid draw
// output. Only refuse a tail write that aliases CURRENT packet
// storage; the surrounding sandbox restores gameplay state.
const auto next=std::upper_bound(now.begin(),now.end(),change.address,
[](uint32_t address,const Node& node){return address<node.address;});
if(next!=now.begin()) {
const Node& node=*(next-1);
if(change.address<node.address+4u+(node.header>>24)*4u)return refuse(__LINE__);
}
splice_writes.push_back(change);
}
}
+7
View File
@@ -98,8 +98,10 @@ int main() {
put(ram,0x1310,0x02001300u);
put(ram,0x1314,0x64000000);put(ram,0x1318,0x00100020);
put(ram,OT,0x1310);put(ram,0x1800,0x80001320);
put(ram,0x1900,0x1234); // real tail advances an ordinary scratch counter
CHECK(relocated.prepare(ram.data(),ram.size(),0x80001320));
ram=recorded_core;put(ram,0x1800,0x80001340);
put(ram,0x1900,0xabcd); // interpolation changed the temporary core value
put(ram,0x1348,0x12345678);put(ram,0x134c,0x87654321);
CHECK(relocated.prepare_splice(ram.data(),ram.size(),OT,0x80001340,0x1800));
relocated.apply_splice(ram.data());
@@ -108,6 +110,11 @@ int main() {
CHECK(PSXOTRelocation::word(ram.data(),0x1348)==0x12345678);
CHECK(PSXOTRelocation::word(ram.data(),0x134c)==0x87654321);
CHECK(PSXOTRelocation::word(ram.data(),0x1800)==0x80001360);
CHECK(PSXOTRelocation::word(ram.data(),0x1900)==0x1234);
ram=recorded_core;put(ram,0x1800,0x80001340);
put(ram,OT,0x18fc);put(ram,0x18fc,0x02000000u|Core);
put(ram,0x1900,0x64000000);put(ram,0x1904,0x10002000);
CHECK(!relocated.prepare_splice(ram.data(),ram.size(),OT,0x80001340,0x1800));
ram=recorded_core;put(ram,0x1800,0x80001340);
// A packet outside the actual producer interval is still refused.
CHECK(relocated.prepare_splice(ram.data(),ram.size(),OT,0x801ffff0,0x1800)==false);