def _set_end(block): target = None if block.warp is not None: target = _get_target(block.warp, allow_end=True) block.warp = nodes.EndWarp() setattr(block.warp, "_target", target)
def _establish_warps(state, instructions): state.blocks[0].warpins_count = 1 for block in state.blocks[:-1]: state.block = block end_addr = block.last_address + 1 start_addr = max(block.last_address - 1, block.first_address) warp = instructions[start_addr:end_addr] block.warp, shift = _build_warp(state, block.last_address, warp) setattr(block, "_last_body_addr", block.last_address - shift) setattr(block.warp, "_addr", block.last_address - shift + 1) last_block = state.blocks[-1] last_block.warp = nodes.EndWarp() setattr(last_block, "_last_body_addr", last_block.last_address) setattr(last_block.warp, "_addr", last_block.last_address)
def _establish_warps(state, instructions): state.blocks[0].warpins_count = 1 enumerated_blocks = enumerate(state.blocks[:-1]) for i, block in enumerated_blocks: if state.blocks.__contains__(block) is None: continue state.block = block end_addr = block.last_address + 1 start_addr = max(block.last_address - 1, block.first_address) # Catch certain double unconditional jumps caused by logical primitives in expressions: if start_addr == (end_addr - 1) \ and end_addr + 1 < len(instructions) \ and instructions[start_addr].opcode == ins.JMP.opcode \ and instructions[end_addr].opcode == ins.JMP.opcode \ and instructions[start_addr].A == instructions[end_addr].A \ and instructions[start_addr].CD == 0: end_instruction_destination = end_addr + instructions[ end_addr].CD + 1 target_instruction_A = instructions[start_addr].A exit_instruction_found = False # When two consecutive jumps are found with the same A operand, lookahead for the end jump. following_destination = -1 for j in range(end_addr + 1, len(instructions) - 1): following_instruction = instructions[j] if following_instruction.opcode == ins.JMP.opcode: if following_instruction.A == target_instruction_A: following_destination = get_jump_destination( j, following_instruction) exit_instruction_found = True break # If we find the exit jump and we're not skipping it (if true then break else), # form the original two jumps into a fake conditional warp. if exit_instruction_found \ and end_instruction_destination <= following_destination: fixed_instruction = ins.ISF() fixed_instruction.CD = ins.SLOT_FALSE instructions[start_addr] = fixed_instruction state.blocks.pop(state.blocks.index(block) + 1) block.last_address += 1 start_addr = max(block.last_address - 1, block.first_address) end_addr = block.last_address + 1 warp = instructions[start_addr:end_addr] block.warp, shift = _build_warp(state, block.last_address, warp) setattr(block, "_last_body_addr", block.last_address - shift) setattr(block.warp, "_addr", block.last_address - shift + 1) last_block = state.blocks[-1] last_block.warp = nodes.EndWarp() setattr(last_block, "_last_body_addr", last_block.last_address) setattr(last_block.warp, "_addr", last_block.last_address)