(
        self,
        addr: Optional[int] = None,
        state: Optional[SimState] = None,
        clemory: Optional[cle.Clemory] = None,
        insn_bytes: Optional[bytes] = None,
        arch: Optional[archinfo.Arch] = None,
        size: Optional[int] = None,
        num_inst: Optional[int] = None,
        traceflags: int = 0,
        thumb: bool = False,
        extra_stop_points: Optional[Iterable[int]] = None,
        opt_level: Optional[int] = None,
        strict_block_end: Optional[bool] = None,
        skip_stmts: bool = False,
        collect_data_refs: bool = False,
        cross_insn_opt: Optional[bool] = None,
    )
Lift an IRSB.

        There are many possible valid sets of parameters. You at the very least must pass some
        source of data, some source of an architecture, and some source of an address.

        Sources of data in order of priority: insn_bytes, clemory, state

        Sources of an address, in order of priority: addr, state

        Sources of an architecture, in order of priority: arch, clemory, state

        :param state:           A state to use as a data source.
        :param clemory:         A cle.memory.Clemory object to use as a data source.
        :param addr:            The address at which to start the block.
        :param thumb:           Whether the block should be lifted in ARM's THUMB mode.
        :param opt_level:       Unused for P-Code lifter
        :param insn_bytes:      A string of bytes to use as a data source.
        :param size:            The maximum size of the block, in bytes.
        :param num_inst:        The maximum number of instructions.
        :param traceflags:      Unused by P-Code lifter
        :param strict_block_end: Unused by P-Code lifter
Lift an IRSB.
Lift an IRSB .
def lift_pcode(
        self,
        addr: Optional[int] = None,
        state: Optional[SimState] = None,
        clemory: Optional[cle.Clemory] = None,
        insn_bytes: Optional[bytes] = None,
        arch: Optional[archinfo.Arch] = None,
        size: Optional[int] = None,
        num_inst: Optional[int] = None,
        traceflags: int = 0,
        thumb: bool = False,
        extra_stop_points: Optional[Iterable[int]] = None,
        opt_level: Optional[int] = None,
        strict_block_end: Optional[bool] = None,
        skip_stmts: bool = False,
        collect_data_refs: bool = False,
        cross_insn_opt: Optional[bool] = None,
    ):
        """
        Lift an IRSB.

        There are many possible valid sets of parameters. You at the very least must pass some
        source of data, some source of an architecture, and some source of an address.

        Sources of data in order of priority: insn_bytes, clemory, state

        Sources of an address, in order of priority: addr, state

        Sources of an architecture, in order of priority: arch, clemory, state

        :param state:           A state to use as a data source.
        :param clemory:         A cle.memory.Clemory object to use as a data source.
        :param addr:            The address at which to start the block.
        :param thumb:           Whether the block should be lifted in ARM's THUMB mode.
        :param opt_level:       Unused for P-Code lifter
        :param insn_bytes:      A string of bytes to use as a data source.
        :param size:            The maximum size of the block, in bytes.
        :param num_inst:        The maximum number of instructions.
        :param traceflags:      Unused by P-Code lifter
        :param strict_block_end: Unused by P-Code lifter
        """
        if cross_insn_opt:
            l.debug('cross_insn_opt is ignored for p-code lifter')

        # phase 0: sanity check
        if not state and not clemory and not insn_bytes:
            raise ValueError("Must provide state or clemory or insn_bytes!")
        if not state and not clemory and not arch:
            raise ValueError("Must provide state or clemory or arch!")
        if addr is None and not state:
            raise ValueError("Must provide state or addr!")
        if arch is None:
            arch = clemory._arch if clemory else state.arch
        if arch.name.startswith("MIPS") and self._single_step:
            l.error("Cannot specify single-stepping on MIPS.")
            self._single_step = False

        # phase 1: parameter defaults
        if addr is None:
            addr = state.solver.eval(state._ip)
        if size is not None:
            size = min(size, IRSB_MAX_SIZE)
        if size is None:
            size = IRSB_MAX_SIZE
        if num_inst is not None:
            num_inst = min(num_inst, IRSB_MAX_INST)
        if num_inst is None and self._single_step:
            num_inst = 1
        if opt_level is None:
            if state and o.OPTIMIZE_IR in state.options:
                opt_level = 1
            else:
                opt_level = self._default_opt_level
        if strict_block_end is None:
            strict_block_end = self.default_strict_block_end
        if self._support_selfmodifying_code:
            if opt_level > 0:
                if once("vex-engine-smc-opt-warning"):
                    l.warning(
                        "Self-modifying code is not always correctly optimized by"
                        " PyVEX. To guarantee correctness, VEX optimizations have been"
                        " disabled."
                    )
                opt_level = 0
                if state and o.OPTIMIZE_IR in state.options:
                    state.options.remove(o.OPTIMIZE_IR)
        if skip_stmts is not True:
            skip_stmts = False

        use_cache = self._use_cache
        if skip_stmts or collect_data_refs:
            # Do not cache the blocks if skip_stmts or collect_data_refs are enabled
            use_cache = False

        # phase 2: thumb normalization
        thumb = int(thumb)
        if isinstance(arch, ArchARM):
            if addr % 2 == 1:
                thumb = 1
            if thumb:
                addr &= ~1
        elif thumb:
            l.error("thumb=True passed on non-arm architecture!")
            thumb = 0

        # phase 3: check cache
        cache_key = None
        if use_cache:
            cache_key = (
                addr,
                insn_bytes,
                size,
                num_inst,
                thumb,
                opt_level,
                strict_block_end,
            )
            if cache_key in self._block_cache:
                self._block_cache_hits += 1
                irsb = self._block_cache[cache_key]
                stop_point = self._first_stoppoint(irsb, extra_stop_points)
                if stop_point is None:
                    return irsb
                else:
                    size = stop_point - addr
                    # check the cache again
                    cache_key = (
                        addr,
                        insn_bytes,
                        size,
                        num_inst,
                        thumb,
                        opt_level,
                        strict_block_end,
                    )
                    if cache_key in self._block_cache:
                        self._block_cache_hits += 1
                        return self._block_cache[cache_key]
                    else:
                        self._block_cache_misses += 1
            else:
                # a special case: `size` is used as the maximum allowed size
                tmp_cache_key = (
                    addr,
                    insn_bytes,
                    IRSB_MAX_SIZE,
                    num_inst,
                    thumb,
                    opt_level,
                    strict_block_end,
                )
                try:
                    irsb = self._block_cache[tmp_cache_key]
                    if irsb.size <= size:
                        self._block_cache_hits += 1
                        return self._block_cache[tmp_cache_key]
                except KeyError:
                    self._block_cache_misses += 1

        # vex_lift breakpoints only triggered when the cache isn't used
        if state:
            state._inspect(
                "vex_lift", BP_BEFORE, mem_read_address=addr, mem_read_length=size
            )

        # phase 4: get bytes
        if insn_bytes is not None:
            buff, size = insn_bytes, len(insn_bytes)
        else:
            buff, size = self._load_bytes(addr, size, state, clemory)

        if not buff or size == 0:
            raise SimEngineError("No bytes in memory for block starting at %#x." % addr)

        # phase 5: lift to pcode
        l.debug("Creating pcode.IRSB of arch %s at %#x", arch.name, addr)
        try:
            for subphase in range(2):
                irsb = lift(
                    buff,
                    addr + thumb,
                    arch,
                    max_bytes=size,
                    max_inst=num_inst,
                    bytes_offset=thumb,
                    traceflags=traceflags,
                    opt_level=opt_level,
                    strict_block_end=strict_block_end,
                    skip_stmts=skip_stmts,
                    collect_data_refs=collect_data_refs,
                )

                if subphase == 0 and irsb.statements is not None:
                    # check for possible stop points
                    stop_point = self._first_stoppoint(irsb, extra_stop_points)
                    if stop_point is not None:
                        size = stop_point - addr
                        continue

                if use_cache:
                    self._block_cache[cache_key] = irsb
                if state:
                    state._inspect(
                        "vex_lift",
                        BP_AFTER,
                        mem_read_address=addr,
                        mem_read_length=size,
                    )
                return irsb

        # phase x: error handling
        except PyVEXError as e:
            l.debug("VEX translation error at %#x", addr)
            # FIXME
            # if isinstance(buff, bytes):
            #     l.debug("Using bytes: %r", buff)
            # else:
            #     l.debug("Using bytes: %r", pyvex.ffi.buffer(buff, size))
            raise SimTranslationError("Unable to translate bytecode") from e
def lift_pcode ( self , addr : Optional [ int ] = None , state : Optional [ SimState ] = None , clemory : Optional [ cle . Clemory ] = None , insn_bytes : Optional [ bytes ] = None , arch : Optional [ archinfo . Arch ] = None , size : Optional [ int ] = None , num_inst : Optional [ int ] = None , traceflags : int = 0 , thumb : bool = False , extra_stop_points : Optional [ Iterable [ int ] ] = None , opt_level : Optional [ int ] = None , strict_block_end : Optional [ bool ] = None , skip_stmts : bool = False , collect_data_refs : bool = False , cross_insn_opt : Optional [ bool ] = None , ) : if cross_insn_opt : l . debug ( 'cross_insn_opt is ignored for p-code lifter' ) # phase 0: sanity check if not state and not clemory and not insn_bytes : raise ValueError ( "Must provide state or clemory or insn_bytes!" ) if not state and not clemory and not arch : raise ValueError ( "Must provide state or clemory or arch!" ) if addr is None and not state : raise ValueError ( "Must provide state or addr!" ) if arch is None : arch = clemory . _arch if clemory else state . arch if arch . name . startswith ( "MIPS" ) and self . _single_step : l . error ( "Cannot specify single-stepping on MIPS." ) self . _single_step = False # phase 1: parameter defaults if addr is None : addr = state . solver . eval ( state . _ip ) if size is not None : size = min ( size , IRSB_MAX_SIZE ) if size is None : size = IRSB_MAX_SIZE if num_inst is not None : num_inst = min ( num_inst , IRSB_MAX_INST ) if num_inst is None and self . _single_step : num_inst = 1 if opt_level is None : if state and o . OPTIMIZE_IR in state . options : opt_level = 1 else : opt_level = self . _default_opt_level if strict_block_end is None : strict_block_end = self . default_strict_block_end if self . _support_selfmodifying_code : if opt_level > 0 : if once ( "vex-engine-smc-opt-warning" ) : l . warning ( "Self-modifying code is not always correctly optimized by" " PyVEX. To guarantee correctness, VEX optimizations have been" " disabled." ) opt_level = 0 if state and o . OPTIMIZE_IR in state . options : state . options . remove ( o . OPTIMIZE_IR ) if skip_stmts is not True : skip_stmts = False use_cache = self . _use_cache if skip_stmts or collect_data_refs : # Do not cache the blocks if skip_stmts or collect_data_refs are enabled use_cache = False # phase 2: thumb normalization thumb = int ( thumb ) if isinstance ( arch , ArchARM ) : if addr % 2 == 1 : thumb = 1 if thumb : addr &= ~ 1 elif thumb : l . error ( "thumb=True passed on non-arm architecture!" ) thumb = 0 # phase 3: check cache cache_key = None if use_cache : cache_key = ( addr , insn_bytes , size , num_inst , thumb , opt_level , strict_block_end , ) if cache_key in self . _block_cache : self . _block_cache_hits += 1 irsb = self . _block_cache [ cache_key ] stop_point = self . _first_stoppoint ( irsb , extra_stop_points ) if stop_point is None : return irsb else : size = stop_point - addr # check the cache again cache_key = ( addr , insn_bytes , size , num_inst , thumb , opt_level , strict_block_end , ) if cache_key in self . _block_cache : self . _block_cache_hits += 1 return self . _block_cache [ cache_key ] else : self . _block_cache_misses += 1 else : # a special case: `size` is used as the maximum allowed size tmp_cache_key = ( addr , insn_bytes , IRSB_MAX_SIZE , num_inst , thumb , opt_level , strict_block_end , ) try : irsb = self . _block_cache [ tmp_cache_key ] if irsb . size <= size : self . _block_cache_hits += 1 return self . _block_cache [ tmp_cache_key ] except KeyError : self . _block_cache_misses += 1 # vex_lift breakpoints only triggered when the cache isn't used if state : state . _inspect ( "vex_lift" , BP_BEFORE , mem_read_address = addr , mem_read_length = size ) # phase 4: get bytes if insn_bytes is not None : buff , size = insn_bytes , len ( insn_bytes ) else : buff , size = self . _load_bytes ( addr , size , state , clemory ) if not buff or size == 0 : raise SimEngineError ( "No bytes in memory for block starting at %#x." % addr ) # phase 5: lift to pcode l . debug ( "Creating pcode.IRSB of arch %s at %#x" , arch . name , addr ) try : for subphase in range ( 2 ) : irsb = lift ( buff , addr + thumb , arch , max_bytes = size , max_inst = num_inst , bytes_offset = thumb , traceflags = traceflags , opt_level = opt_level , strict_block_end = strict_block_end , skip_stmts = skip_stmts , collect_data_refs = collect_data_refs , ) if subphase == 0 and irsb . statements is not None : # check for possible stop points stop_point = self . _first_stoppoint ( irsb , extra_stop_points ) if stop_point is not None : size = stop_point - addr continue if use_cache : self . _block_cache [ cache_key ] = irsb if state : state . _inspect ( "vex_lift" , BP_AFTER , mem_read_address = addr , mem_read_length = size , ) return irsb # phase x: error handling except PyVEXError as e : l . debug ( "VEX translation error at %#x" , addr ) # FIXME # if isinstance(buff, bytes): #     l.debug("Using bytes: %r", buff) # else: #     l.debug("Using bytes: %r", pyvex.ffi.buffer(buff, size)) raise SimTranslationError ( "Unable to translate bytecode" ) from e