[Scummvm-devel] Broken Sword 2 problem
yotam barnoy
yotambarnoy at gmail.com
Tue Aug 31 13:24:25 CEST 2010
If anyone's interested, the problem with BS2 on the PSP was a bug in gcc.
Here's the problematic code:
void Logic::logicUp(uint32 new_script) {
debug(5, "new pc = %d", new_script & 0xffff);
// going up a level - and we'll keep going this cycle
_curObjectHub.setLogicLevel(_curObjectHub.getLogicLevel() + 1);
assert(_curObjectHub.getLogicLevel() < 3); // Can be 0, 1, 2
logicReplace(new_script);
}
void Logic::logicReplace(uint32 new_script) {
uint32 level = _curObjectHub.getLogicLevel();
_curObjectHub.setScriptId(level, new_script);
_curObjectHub.setScriptPc(level, new_script & 0xffff);
}
G++ optimized these 2 functions into 1 and came up with this code:
8934bc0 <_ZN6Sword25Logic7logicUpEj>:
8934bc0: 27bdfff0 addiu sp,sp,-16
8934bc4: afb20008 sw s2,8(sp)
8934bc8: afb10004 sw s1,4(sp)
8934bcc: 30b2ffff andi s2,a1,0xffff # s2 = new_scip & 0xffff
8934bd0: 00a08821 move s1,a1 # s1 = new_scipt
8934bd4: 3c0508aa lui a1,0x8aa # a1 = 0x8aa0000
8934bd8: afb00000 sw s0,0(sp)
8934bdc: 24a50d68 addiu a1,a1,3432 # a1 = 0x8aa3432
8934be0: 00808021 move s0,a0 # s0 = this
8934be4: 02403021 move a2,s2 # a2 = new_script & 0xffff
8934be8: afbf000c sw ra,12(sp)
8934bec: 0e286377 jal 8a18ddc <_Z5debugiPKcz>
8934bf0: 24040005 li a0,5 # a0 = 5 (jump)
8934bf4: 8e0400d8 lw a0,216(s0) # a0 = *(this + 216)
8934bf8: 88850007 lwl a1,7(a0) # a1 =
8934bfc: 98850004 lwr a1,4(a0) # a1 = logicLevel
8934c00: 24a20001 addiu v0,a1,1 # v0 = logicLevel + 1
8934c04: a8820007 swl v0,7(a0) # 7(a0) = 0.5 new logicLevel
8934c08: 2ca30003 sltiu v1,a1,3 # v1 = a1 < 3?
8934c0c: 10600011 beqz v1,8934c54 <_ZN6Sword25Logic7logicUpEj+0x94> # assert
8934c10: b8820004 swr v0,4(a0) # 4(a0) = 0.5 new logicLevel
8934c14: 24a20005 addiu v0,a1,5 # v0 = logicLevel + 5 ???
8934c18: 00021080 sll v0,v0,0x2 # v0 = 4*logicLevel + 20 (scriptId offset)
8934c1c: 00821021 addu v0,a0,v0 # v0 = &scriptId
8934c20: 24a30008 addiu v1,a1,8 # v1 = logicLevel + 8
8934c24: a8510003 swl s1,3(v0) # scriptId[3] = new_script
8934c28: 00031880 sll v1,v1,0x2 # v1 = logicLevel * 4 + 32
8934c2c: b8510000 swr s1,0(v0) # scriptId[0] = new_script
8934c30: 00831821 addu v1,a0,v1 # v1 = *(this + 216)
Note the mistake in line 8934c00. v0 is used for incrementing the
logicLevel, and v0 is indeed saved into memory (ie.
_curObjectHub.setLogicLevel(_curObjectHub.getLogicLevel() + 1); )
But the optimization gcc made prevents it from realizing it needs to
use the newly incremented logicLevel value for the other calculations,
so instead it keeps using a1 in the rest of the function. This causes
it to write the new scriptId value in the wrong place, which causes
the VM to think its next scriptId is 0.
This is a very serious mistake in gcc 4.3.3.
Yotam
2010/8/27 yotam barnoy <yotambarnoy at gmail.com>:
> OK well thanks for trying.
>
> Just to keep everyone up to date on this suspenseful bug :)
>
> I've found the problematic addition -- it was simply the code of
> BufferedWriteStream, even when completely unused(!) Once I figured
> that out, I took this patch and applied it at different points in the
> history. Bisecting yielded another innocuous addition of a couple of
> variables to the BS2 class. This is starting to look more and more
> like the 'perfect storm' theory. I bisected yet again, and found
> another addition of variables. I'm hoping that eventually I'll get to
> something more substantial. My guess is that there's something either
> from BS2 itself or from the PSP code, and I'm already digging in code
> from around a year ago.
>
> I'd appreciate it if someone could try running the current SVN code
> (~52398) on the PS2 (another MIPS target). Try restarting and skipping
> both intro videos and check if it crashes.
>
> Thanks
> Yotam
>
>
> 2010/8/26 Torbjörn Andersson <eriktorbjorn at telia.com>:
>> On 2010-08-26 10:27, yotam barnoy wrote:
>>
>>> Can someone please run valgrind on Broken Sword 2 and see if they find
>>> anything? I'm trying to debug using assembly dumps but it seems the
>>> problem is too complex to corner that way.
>>
>> I played the very beginning of the game (freeing George from the ropes)
>> under Valgrind, and it didn't report any problems. I'm afraid I have no
>> theories whatsoever.
>>
>> Torbjörn Andersson
>>
>
More information about the Scummvm-devel
mailing list