How to use the gilgamesh.snes.instruction.StackManipulation 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 / disassembly / disassembly.py View on Github external
def add_line(*args) -> None:
            add(*args)
            tokens.append(Token(T.NEWLINE))

        # Label.
        label = self.log.get_label(instr.pc, instr.subroutine_pc)
        if label:
            if instr.pc in self.log.jump_table_targets:
                add_line(T.JUMP_TABLE_LABEL, label)
            else:
                add_line(T.LABEL, label)

        # Stack manipulation.
        if verbose and instr.stack_manipulation != StackManipulation.NONE:
            if instr.stack_manipulation == StackManipulation.CAUSES_UNKNOWN_STATE:
                add_line(T.FATAL_STACK_MANIPULATION_HEADER)
            else:
                add_line(T.STACK_MANIPULATION_HEADER)

        # Operation + Operand.
        tokens.append(Token(T.OPERATION, instr.name))
        if instr.argument_alias:
            if instr.argument_alias in hw_registers:
                add(T.HW_REGISTER, instr.argument_alias)
            elif instr.argument_alias in self.preview_excluded_labels:
                add(T.HIGHLIGHTED_OPERAND_LABEL, instr.argument_alias)
            elif instr.pc in self.log.jump_table_targets:
                add(T.JUMP_TABLE_OPERAND_LABEL, instr.argument_alias)
            else:
                add(T.OPERAND_LABEL, instr.argument_alias)
        else:
github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
# No custom assertion, we need to stop here.
        unknown_reason = unknown_reason or UnknownReason.UNKNOWN
        self.state_change = StateChange(unknown_reason=unknown_reason)
        self.log.add_subroutine_state(
            self.subroutine_pc, instruction.pc, copy(self.state_change)
        )

        # If the unknown state is due to stack manipulation:
        if unknown_reason == UnknownReason.STACK_MANIPULATION:
            # If we know which instruction performed the
            # manipulation, we flag it.
            if stack_manipulator:
                self.subroutine.has_stack_manipulation = True
                stack_manipulator.stack_manipulation = (
                    StackManipulation.CAUSES_UNKNOWN_STATE
                )

        return False
github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
def change_stack(self, i: Instruction) -> None:
        if i.operation == Op.TCS:
            a = self.registers.a.get_whole()
            self.stack.set_pointer(i, a)
            if a is not None:
                return
        # We keep the disassembly going if the stack manipulation
        # doesn't otherwise influence the state of the processor.
        i.stack_manipulation = StackManipulation.HARMLESS
github AndreaOrru / gilgamesh / gilgamesh / snes / instruction.py View on Github external
registers: Dict[str, Optional[int]],
        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 / disassembly / disassembly.py View on Github external
tokens.append(Token(*args))

        def add_line(*args) -> None:
            add(*args)
            tokens.append(Token(T.NEWLINE))

        # Label.
        label = self.log.get_label(instr.pc, instr.subroutine_pc)
        if label:
            if instr.pc in self.log.jump_table_targets:
                add_line(T.JUMP_TABLE_LABEL, label)
            else:
                add_line(T.LABEL, label)

        # Stack manipulation.
        if verbose and instr.stack_manipulation != StackManipulation.NONE:
            if instr.stack_manipulation == StackManipulation.CAUSES_UNKNOWN_STATE:
                add_line(T.FATAL_STACK_MANIPULATION_HEADER)
            else:
                add_line(T.STACK_MANIPULATION_HEADER)

        # Operation + Operand.
        tokens.append(Token(T.OPERATION, instr.name))
        if instr.argument_alias:
            if instr.argument_alias in hw_registers:
                add(T.HW_REGISTER, instr.argument_alias)
            elif instr.argument_alias in self.preview_excluded_labels:
                add(T.HIGHLIGHTED_OPERAND_LABEL, instr.argument_alias)
            elif instr.pc in self.log.jump_table_targets:
                add(T.JUMP_TABLE_OPERAND_LABEL, instr.argument_alias)
            else:
                add(T.OPERAND_LABEL, instr.argument_alias)
github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
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
        # an unknown state.
        else:
            self._unknown_subroutine_state(
                i,