How to use the gilgamesh.snes.instruction.RetIndirectType function in gilgamesh

To help you get started, we’ve selected a few gilgamesh examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
return standard_return()

        # If the stack is constructed in such a way that
        # we would return to the next instruction, it is
        # effectively a subroutine call.
        if self.stack.match(i.pc, ret_size):
            i.ret_indirect_type = RetIndirectType.CALL
            self.log.assert_jump(i.pc, set_dirty=False)
            for s in self.stack.pop(ret_size):
                if s.instruction:
                    s.instruction.stack_manipulation = StackManipulation.HARMLESS
            return self.call(i, self.log.jump_assertions[i.pc])

        # Otherwise, if we know this is a jump table, then it's a simple jump.
        elif i.is_jump_table:
            i.ret_indirect_type = RetIndirectType.JUMP
            for s in stack_entries:
                if s.instruction:
                    s.instruction.stack_manipulation = StackManipulation.HARMLESS
            self.jump(i, self.log.jump_assertions[i.pc])
            return False

        # We don't know for certain that this is a jump table, signal
        # an unknown state.
        else:
            self._unknown_subroutine_state(
                i,
                unknown_reason=UnknownReason.STACK_MANIPULATION,
                stack_manipulator=stack_manipulator,
            )
            return False
github AndreaOrru / gilgamesh / gilgamesh / snes / instruction.py View on Github external
state_change_before: StateChange,
    ):
        super().__init__()
        self.log = log
        self.pc = pc
        self.state = State(p)
        self.registers = registers

        self.subroutine_pc = subroutine_pc
        self.opcode = opcode
        self._argument = argument

        self.state_change_before = state_change_before
        self.state_change_after = StateChange(unknown_reason=UnknownReason.UNKNOWN)
        self.stack_manipulation = StackManipulation.NONE
        self.ret_indirect_type = RetIndirectType.NONE
github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
if i.operation == Op.RTI:
            return standard_return()

        ret_size = 2 if i.operation == Op.RTS else 3
        stack_entries = self.stack.pop(ret_size)

        # Check for stack manipulations.
        stack_manipulator = self._check_stack_manipulation(i, stack_entries)
        if not stack_manipulator:
            return standard_return()

        # If the stack is constructed in such a way that
        # we would return to the next instruction, it is
        # effectively a subroutine call.
        if self.stack.match(i.pc, ret_size):
            i.ret_indirect_type = RetIndirectType.CALL
            self.log.assert_jump(i.pc, set_dirty=False)
            for s in self.stack.pop(ret_size):
                if s.instruction:
                    s.instruction.stack_manipulation = StackManipulation.HARMLESS
            return self.call(i, self.log.jump_assertions[i.pc])

        # Otherwise, if we know this is a jump table, then it's a simple jump.
        elif i.is_jump_table:
            i.ret_indirect_type = RetIndirectType.JUMP
            for s in stack_entries:
                if s.instruction:
                    s.instruction.stack_manipulation = StackManipulation.HARMLESS
            self.jump(i, self.log.jump_assertions[i.pc])
            return False

        # We don't know for certain that this is a jump table, signal
github AndreaOrru / gilgamesh / gilgamesh / subroutine.py View on Github external
def indirect_jumps(self) -> List[int]:
        return [
            i.pc
            for i in self.instructions.values()
            if i.is_indirect_jump or i.ret_indirect_type != RetIndirectType.NONE
        ]
github AndreaOrru / gilgamesh / gilgamesh / log.py View on Github external
reason = i.state_change_after.unknown_reason

        if i.is_call and reason == UnknownReason.INDIRECT_JUMP:
            return [*jump_table_suggestion(), ("instruction", StateChange())]

        elif i.is_jump and reason == UnknownReason.INDIRECT_JUMP:
            if i.subroutine.does_save_state_in_incipit:
                return [*jump_table_suggestion(), ("subroutine", StateChange())]
            else:
                return [*jump_table_suggestion(), *unified_state_suggestion()]

        elif i.is_return and reason == UnknownReason.STACK_MANIPULATION:
            return unified_state_suggestion()

        elif i.is_return and reason == UnknownReason.INDIRECT_JUMP:
            if i.ret_indirect_type == RetIndirectType.CALL:
                return [*jump_table_suggestion(), ("instruction", StateChange())]
            elif i.ret_indirect_type == RetIndirectType.JUMP:
                return [*jump_table_suggestion(), *unified_state_suggestion()]
            else:
                assert False

        elif unsafe:
            if i.subroutine.is_recursive and reason == UnknownReason.RECURSION:
                return unified_state_suggestion()
            elif i.operation == Op.PLP and reason == UnknownReason.STACK_MANIPULATION:
                return [("instruction", StateChange())]

        return []
github AndreaOrru / gilgamesh / gilgamesh / log.py View on Github external
if i.is_call and reason == UnknownReason.INDIRECT_JUMP:
            return [*jump_table_suggestion(), ("instruction", StateChange())]

        elif i.is_jump and reason == UnknownReason.INDIRECT_JUMP:
            if i.subroutine.does_save_state_in_incipit:
                return [*jump_table_suggestion(), ("subroutine", StateChange())]
            else:
                return [*jump_table_suggestion(), *unified_state_suggestion()]

        elif i.is_return and reason == UnknownReason.STACK_MANIPULATION:
            return unified_state_suggestion()

        elif i.is_return and reason == UnknownReason.INDIRECT_JUMP:
            if i.ret_indirect_type == RetIndirectType.CALL:
                return [*jump_table_suggestion(), ("instruction", StateChange())]
            elif i.ret_indirect_type == RetIndirectType.JUMP:
                return [*jump_table_suggestion(), *unified_state_suggestion()]
            else:
                assert False

        elif unsafe:
            if i.subroutine.is_recursive and reason == UnknownReason.RECURSION:
                return unified_state_suggestion()
            elif i.operation == Op.PLP and reason == UnknownReason.STACK_MANIPULATION:
                return [("instruction", StateChange())]

        return []