mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-06 10:17:14 +00:00
SCI: Continue disasm until no jumps go past the current opcode
This should ensure disasm will disassemble an entire function, and not stop at an intermediate ret opcode.
This commit is contained in:
parent
fa10ee66e4
commit
6fe95780d3
@ -2601,7 +2601,6 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
|
||||
DebugPrintf("Valid options are:\n");
|
||||
DebugPrintf(" bwt : Print byte/word tag\n");
|
||||
DebugPrintf(" bc : Print bytecode\n");
|
||||
DebugPrintf(" rX : Continue after X ret opcodes before stopping decompilation\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2640,17 +2639,19 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
|
||||
printBWTag = true;
|
||||
else if (!scumm_stricmp(argv[i], "bc"))
|
||||
printBytecode = true;
|
||||
else if (argv[i][0] == 'r')
|
||||
ignoreXret = atoi(argv[i] + 1);
|
||||
}
|
||||
|
||||
reg_t farthestTarget = addr;
|
||||
do {
|
||||
reg_t prevAddr = addr;
|
||||
addr = disassemble(_engine->_gamestate, addr, printBWTag, printBytecode);
|
||||
if (addr.isNull() && ignoreXret) {
|
||||
addr = prevAddr + 1; // skip past the ret
|
||||
ignoreXret--;
|
||||
reg_t jumpTarget;
|
||||
if (isJumpOpcode(_engine->_gamestate, addr, jumpTarget)) {
|
||||
if (jumpTarget > farthestTarget)
|
||||
farthestTarget = jumpTarget;
|
||||
}
|
||||
addr = disassemble(_engine->_gamestate, addr, printBWTag, printBytecode);
|
||||
if (addr.isNull() && prevAddr < farthestTarget)
|
||||
addr = prevAddr + 1; // skip past the ret
|
||||
} while (addr.offset > 0);
|
||||
|
||||
return true;
|
||||
|
@ -37,6 +37,7 @@ class SciEngine;
|
||||
struct List;
|
||||
|
||||
reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode);
|
||||
bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpOffset);
|
||||
|
||||
class Console : public GUI::Debugger {
|
||||
public:
|
||||
|
@ -281,6 +281,35 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget)
|
||||
{
|
||||
SegmentObj *mobj = s->_segMan->getSegment(pos.segment, SEG_TYPE_SCRIPT);
|
||||
if (!mobj)
|
||||
return false;
|
||||
Script *script_entity = (Script *)mobj;
|
||||
|
||||
const byte *scr = script_entity->getBuf();
|
||||
int scr_size = script_entity->getBufSize();
|
||||
|
||||
if (pos.offset >= scr_size)
|
||||
return false;
|
||||
|
||||
int16 opparams[4];
|
||||
byte opsize;
|
||||
int bytecount = readPMachineInstruction(scr + pos.offset, opsize, opparams);
|
||||
const byte opcode = opsize >> 1;
|
||||
|
||||
switch (opcode) {
|
||||
case op_bt:
|
||||
case op_bnt:
|
||||
case op_jmp:
|
||||
jumpTarget = pos + bytecount + opparams[0];
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SciEngine::scriptDebug() {
|
||||
EngineState *s = _gamestate;
|
||||
|
Loading…
x
Reference in New Issue
Block a user