Esempio n. 1
0
def generateStacktrace(state: programState.ProgramState,
                       error: programState.RunError, fileName: str,
                       lines: List[str]) -> str:
    # Get return addresses from the stack
    sp: int = state.getReg("SP")
    stackSize = state.getLabelAddress("__STACKSIZE")
    stack: List[nodes.Node] = state.memory[sp >> 2:stackSize >> 2]
    callbacks = list(
        map(
            lambda n: generateStacktraceElement(state, n.value, fileName, lines
                                                ),
            filter(
                lambda x: isinstance(x, nodes.DataNode) and x.source == "LR",
                stack)))

    # Generate the error
    res = f"\033[31m"  # Red color
    res += "Traceback (most recent call first):\n"
    res += generateStacktraceElement(state, state.getReg("PC"), fileName,
                                     lines) + '\n'
    if not state.hasReturned:
        res += generateStacktraceElement(state, state.getReg("LR"), fileName,
                                         lines) + '\n'
    if len(callbacks) > 0:
        res += reduce(lambda a, b: a + "\n" + b, callbacks) + '\n'
    res += error.message + '\n'
    return res + f"\033[0m"  # Normal color
Esempio n. 2
0
 def ldrLabel(state: programState.ProgramState) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]:
     val: Union[int, programState.RunError] = state.getLabelAddress(label.label)
     if isinstance(val, programState.RunError):
         return state, val
     else:
         state.setReg(dest.contents, val)
         return state, None
def branchToLabel(state: programState.ProgramState, label: str) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]:
    # Save return address in LR
    state.setReg("LR", state.getReg("PC"))

    address: Union[int, programState.RunError] = state.getLabelAddress(label)
    if isinstance(address, programState.RunError):
        return state, programState.RunError(f"Unknown startup label: {label}", programState.RunError.ErrorType.Error)
    else:
        # Subtract 4 because we will add 4 to the address later in the run loop and we need to start at address and not address+4
        state.setReg("PC", address - 4)
        state.hasReturned = False
        return state, None
Esempio n. 4
0
 def branchTo(
     state: programState.ProgramState
 ) -> Tuple[programState.ProgramState, Union[programState.RunError,
                                             None]]:
     if condition(state.status):
         address: Union[int,
                        programState.RunError] = state.getLabelAddress(
                            label.contents)
         if isinstance(address, programState.RunError):
             return state, address
         else:
             # Subtract 4 because we will add 4 to the address later in the run loop and we need to start at address and not address+4
             state.setReg("PC", address - 4)
     return state, None
Esempio n. 5
0
    def pop(state: programState.ProgramState) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]:
        if len(regs) == 0:
            return state, None
        # head, *tail = registers

        address = state.getReg("SP")
        # check address is in 0...stacksize
        if address > (state.getLabelAddress("__STACKSIZE")) or address < 0:
            return state, programState.RunError("All stack entries have been pop'ed already", programState.RunError.ErrorType.Error)
        for reg in regs:
            err = state.loadRegister(address, 32, False, reg)
            address += 4
            if err is not None:
                return state, err
        state.setReg("SP", address)
        return state, None
Esempio n. 6
0
    def push(state: programState.ProgramState) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]:
        if len(regs) == 0:
            return state, None
        # head, *tail = registers

        address = state.getReg("SP")
        # check address is in 0...stacksize
        if address > (state.getLabelAddress("__STACKSIZE")) or address < 0:
            return state, programState.RunError("Stack overflow", programState.RunError.ErrorType.Error)

        for reg in regs:
            address -= 4
            err = state.storeRegister(address, reg, 32)
            if err is not None:
                return state, err
        state.setReg("SP", address)
        return state, None
Esempio n. 7
0
        def branchTo(
            state: programState.ProgramState
        ) -> Tuple[programState.ProgramState, Union[programState.RunError,
                                                    None]]:
            # Save return address in LR
            pc, _ = state.getReg("PC")
            state.setReg("LR", pc)

            address: Union[int, programState.RunError] = state.getLabelAddress(
                label.contents)
            if isinstance(address, programState.RunError):
                return state, address
            else:
                # Subtract 4 because we will add 4 to the address later in the run loop and we need to start at address and not address+4
                state.setReg("PC", address - 4)
                state.hasReturned = False
                return state, None