All Superinterfaces:
IEGeneric, IInstruction, IInstructionOperand, IResizableInstruction
All Known Subinterfaces:
IEAssign, IECall, IEJump, IEJumpFar, IEJumpWithOptionalCondition, IENop, IEReturn, IESwitch, IEUntranslatedInstruction

@Ser public interface IEStatement extends IEGeneric, IResizableInstruction
Base class for all IR statements. Statements are specialized expressions. The most common statement is IEAssign. Additional statements introduced as the IR gets optimized and refined are: IENop, IECall, IEReturn, IEJump, and IEJumpFar, IESwitch and the almighty IEUntranslatedInstruction.
  • Field Details

    • FLAG_OPT_BLOCK_PROPAGATION

      static final int FLAG_OPT_BLOCK_PROPAGATION
      Statement having this flag cannot be propagated, i.e. they cannot be the source (replacement) expression in substituted expressions.

      Note: even in aggressive mode, this flag is NOT ignored.

      In the example below, r0 in instruction A will not be propagated to B.

       A) r0 = r1      <---- flagged
       ...
       B) r4 = .... + r0 + ...
       
      See Also:
    • FLAG_OPT_BLOCK_SUBSTITUTIONS

      static final int FLAG_OPT_BLOCK_SUBSTITUTIONS
      Statement having this flag cannot be the recipient of substituted expressions propagated by an expression optimizer.

      Note: even in aggressive mode, this flag is NOT ignored.

      In the example below, r0 in instruction A could be (under conditions) substituted in instruction B. However, if instruction B has FLAG_OPT_BLOCK_SUBSTITUTIONS set, that candidate substitution will be prevented, regardless of other factors.

       A) r0 = r1
       ...
       B) r4 = .... + r0 + ...      <---- flagged
       
      Note that this flag does not prevent the statement itself to be the source of a substitution. (To prevent that, use FLAG_OPT_BLOCK_PROPAGATION.)

      In the example below, r0 of A can be propagated to B (with A ending up discarded), even though A is flagged.

       A) r0 = r1                   <---- flagged
       ...
       B) r4 = .... + r0 + ...
       
      See Also:
    • FLAG_LIKELY_PROLOGUE

      static final int FLAG_LIKELY_PROLOGUE
      This instruction has been identified as being part of a prologue stub.

      A routine's prologue is a small instruction stub responsible for saving registers that need to be preserved as well as allocating some space on the stack.

      See Also:
    • FLAG_LIKELY_EPILOGUE

      static final int FLAG_LIKELY_EPILOGUE
      This instruction has been identified as being part of an epilogue stub.

      A routine's epilogue is a small instruction stub responsible for restoring registers previously saved by the prologue as well as freeing space that may have been allocated on the stack.

      See Also:
  • Method Details

    • getContext

      IERoutineContext getContext()
      Get the decompiled routine context that owns this statement.
      Returns:
    • copyProperties

      void copyProperties(IEStatement srcStm)
      Copy over the generic statement properties of the source statement onto this statement. Only generic (common) properties should be ported. The context is not copied over. Some properties are overwritten, others are completed (augmented).
      Parameters:
      srcStm - source statement
    • addLowerLevelAddress

      void addLowerLevelAddress(long address)
      Add another native instruction address mapping to this IR statement.
      Parameters:
      address -
    • addLowerLevelAddresses

      void addLowerLevelAddresses(Collection<Long> addresses)
      Add a collection of native instructions addresses mapping to this IR statement.
      Parameters:
      addresses -
    • removeLowerLevelAddress

      void removeLowerLevelAddress(long address)
      Remove a native instruction address from the list of mappings.
      Parameters:
      address -
    • setLowerLevelAddress

      void setLowerLevelAddress(long address)
      Reset the current mapping and add a single native instruction address mapping to this IR statement. Watch out! A statement should at least have one associated native address.
      Parameters:
      address -
    • setLowerLevelAddresses

      void setLowerLevelAddresses(Collection<Long> addresses)
      Reset the current mapping and add a collection of native instructions addresses mapping to this IR statement. Watch out! A statement should at least have one associated native address.
      Parameters:
      addresses -
    • resetLowerLevelAddress

      default void resetLowerLevelAddress()
      Reset the current mapping for native instruction addresses for this statement.
    • resetLowerLevelAddresses

      void resetLowerLevelAddresses()
      Reset the current mapping for native instruction addresses for this statement.
    • copyLowerLevelAddresses

      void copyLowerLevelAddresses(IEStatement srcStm)
      Copy (add) the native addresses of the instruction to this statement's mapping. Watch out! The current statement's mapping is not reset before copying.
      Parameters:
      srcStm -
    • getLowerLevelAddresses

      Collection<Long> getLowerLevelAddresses()
      Returns:
      the returned collection does not contain duplicates; the first entry is the primary lower-level address (if there are multiple native addresses mapping to this IR statement, getLowerLevelAddresses() would return 2+ entries)
    • getPrimaryLowerLevelAddress

      Long getPrimaryLowerLevelAddress()
      Returns:
      the primary native address; null if this IR does not contain lower-mapping information
    • setPrimaryLowerLevelAddress

      void setPrimaryLowerLevelAddress(long addr)
    • withLowerLevelAddress

      IEStatement withLowerLevelAddress(long address)
    • withLowerLevelAddresses

      IEStatement withLowerLevelAddresses(Collection<Long> addresses)
    • setSPDelta

      void setSPDelta(Integer delta)
      Set an optional stack-pointer delta indicator. The SP delta represents the native delta in bytes, relative to SP0 (stack pointer at the underlying native routine entry-point), before the closest matching native instruction is executed.
      Parameters:
      delta - optional native SP delta
    • getSPDelta

      Integer getSPDelta()
      Retrieve the optional stack-pointer delta indicator. The SP delta represents the native delta in bytes, relative to SP0 (stack pointer at the underlying native routine entry-point), before the closest matching native instruction is executed.
      Returns:
      optional native SP delta
    • writesMemory

      boolean writesMemory()
      Retrieve an indication regarding whether this statement writes to memory.
      Returns:
    • getDefUse

      void getDefUse(EDefUseInfo defuse)
      A variant of IInstruction.getDefUse(java.util.List, java.util.List, Object) used to retrieve the range of vbits defined and used by the statement.
      Parameters:
      defuse -
    • getDefUseInfo

      EDefUseInfo getDefUseInfo(long instructionAddress, int flags)
      Description copied from interface: IInstruction
      Determine the variables defined and used by the instruction. This method is an extended version of IInstruction.getDefUse(List, List, Object).
      Specified by:
      getDefUseInfo in interface IInstruction
      Parameters:
      instructionAddress - address of the instruction
      flags - see DefUseInfo.XXX static final flags
      Returns:
    • collectSubExpressions

      void collectSubExpressions(Collection<IEGeneric> sink, Boolean usedOnly)
      Perform a shallow collection of the sub-expressions of this statement. All collected expressions are directly rooted in this IRE (i.e. their parent is this IR expression).
      Parameters:
      sink - recipient (elements are appended)
      usedOnly - if null: all top-level elements are collected (same as collectSubExpressions(Collection)); else:
      - if false: only defined (written) top-level sub-expressions are collected
      - if true: only used (read) top-level sub-expressions are collected
    • collectSubExpressions

      default void collectSubExpressions(Collection<IEGeneric> sink)
      Description copied from interface: IEGeneric
      Perform a shallow collection of the sub-expressions of this expression. All collected expressions are directly rooted in this IRE (i.e. their parent is this IR expression).

      This method appends to the provided sink (existing elements are not cleared). The current element (this) is not appended; only the sub-expressions are considered.

      Specified by:
      collectSubExpressions in interface IEGeneric
    • collectUsedExpressions

      void collectUsedExpressions(Collection<Couple<IEGeneric,IEGeneric>> sink)
      Perform a shallow collection of the first-level expressions used by this statement. Invoking this method is not the same as calling collectSubExpressions(sink, true)! This method examines top-level defined (written) expressions that are EMem; the memory reference of those EMems are returned. Therefore, not all values returned by this method are directly rooted in this IRE. It is for that reasons that this method returns a collection of tuples (parent, expression) instead of a simple collection of expressions.
      Parameters:
      sink - a collection of tuples (parent, expression)
    • replaceVar

      int replaceVar(IEVar var, IEGeneric repl, boolean doNotReplaceDefinedVariables) throws IllegalIntermediateExpressionException
      Deep replace. Specialized version allows used-vars replacement only. The implementation is responsible for IRE duplication before statements, to ensure that the resulting statement or group of statement does not contain duplicate references to mutable objects.
      Parameters:
      var - the IEVar to be replaced
      repl - the replacement expression
      doNotReplaceDefinedVariables -
      Returns:
      the number of replacements
      Throws:
      IllegalIntermediateExpressionException - if an illegal replacement was attempted
    • replaceUsedVar

      default int replaceUsedVar(IEVar var, IEGeneric repl) throws IllegalIntermediateExpressionException
      Replace (deep) the variables that are defined by this statement.
      Parameters:
      var - the IEVar to be replaced
      repl - the replacement expression
      Returns:
      the number of replacements
      Throws:
      IllegalIntermediateExpressionException - if an illegal replacement was attempted
    • replaceDefinedVar

      int replaceDefinedVar(IEVar var, IEGeneric repl)
      Replace (deep) the variables that are defined by this statement.
      Parameters:
      var -
      repl -
      Returns:
    • equalsEx

      boolean equalsEx(Object obj, boolean includeType, boolean includeContext)
      Same as #equals(Object) with the possibility to exclude some properties from the comparison.
      Parameters:
      obj - object to compare
      includeType - true to include the type in the equality test
      includeContext - true to include the statement's bound IR context in the equality check
      Returns:
      true if equal
    • equalsEx

      boolean equalsEx(Object obj, boolean includeType, boolean includeContext, boolean includeSize)
      Same as #equals(Object) with the possibility to exclude some properties from the comparison.
      Parameters:
      obj - object to compare
      includeType - true to include the type in the equality test
      includeContext - true to include the statement's bound IR context in the equality check
      includeSize - true to include the statement's size in the equality check
      Returns:
      true if equal
    • preUpdateTypes

      void preUpdateTypes(ETypeInfo ti)
      Called once by the type setter component during the typing stage, before propagating all types to the IR elements. Implementations may perform IRE replacement, unlike updateTypes's.
      Parameters:
      ti - optional type information object that will collect the operation's result
    • postUpdateTypes

      void postUpdateTypes(ETypeInfo ti)
      Called once by the normalizer component in later stages. Implementations may perform IRE replacement, unlike updateTypes's.
      Parameters:
      ti - optional type information object that will collect the operation's result
    • generateC

      ICStatement generateC(IERoutineContext ectx, ICMethod cctx)
      Description copied from interface: IEGeneric
      Generate the C abstract syntax tree portion for this expression.
      Specified by:
      generateC in interface IEGeneric
      Parameters:
      ectx - IR routine context
      cctx - C routine local context
      Returns:
      the C AST element (may contain sub-elements)
    • isAssign

      default boolean isAssign()
    • isAssignTo

      default boolean isAssignTo(IEVar dst)
    • isAssignTo

      default boolean isAssignTo(int dstVarid)
    • isAssignToVar

      default boolean isAssignToVar()
    • asAssign

      default IEAssign asAssign()
    • isCall

      default boolean isCall()
    • asCall

      default IECall asCall()
    • isJump

      default boolean isJump()
    • isUnconditionalJump

      default boolean isUnconditionalJump()
      Determine if this IR is a simple goto, that is, an unconditional IEJump, i.e. IEJumpWithOptionalCondition.getCondition() is null.
      Returns:
    • isConditionalJump

      default boolean isConditionalJump()
      Determine if this IR is a conditional IEJump, i.e. IEJumpWithOptionalCondition.getCondition() is not null.
      Returns:
    • asJump

      default IEJump asJump()
    • isJumpFar

      default boolean isJumpFar()
    • isUnconditionalJumpFar

      default boolean isUnconditionalJumpFar()
    • isConditionalJumpFar

      default boolean isConditionalJumpFar()
    • asJumpFar

      default IEJumpFar asJumpFar()
    • isNop

      default boolean isNop()
    • asNop

      default IENop asNop()
    • isReturn

      default boolean isReturn()
    • asReturn

      default IEReturn asReturn()
    • isSwitch

      default boolean isSwitch()
    • asSwitch

      default IESwitch asSwitch()
    • isUntranslatedInstruction

      default boolean isUntranslatedInstruction()
    • asUntranslated

      default IEUntranslatedInstruction asUntranslated()
    • visitInstruction

      default boolean visitInstruction(IEVisitor visitor)
      Depth-first search, pre-order visit of this statement. The node being visited may be replaced, but the client code is responsible for notifying the visitor.

      Pre-order visits offer more options than post order visits: the visitor may decide to skip children; to skip the destination of assignments. However, replacement of nodes requires additional code to register the new node. Conversely, post-order visits do not offer any specific option, but provide the simplest way to replace nodes.

      Parameters:
      visitor - the visitor object
      Returns:
      true if the visit was successful
    • visitInstruction

      default boolean visitInstruction(IEVisitor visitor, boolean skipAssignmentDestination)
      Depth-first search, pre-order visit of this statement. The node being visited may be replaced, but the client code is responsible for notifying the visitor.

      Pre-order visits offer more options than post order visits: the visitor may decide to skip children; to skip the destination of assignments. However, replacement of nodes requires additional code to register the new node. Conversely, post-order visits do not offer any specific option, but provide the simplest way to replace nodes.

      Parameters:
      visitor - the visitor object
      skipAssignmentDestination - true if the destination of an assignment (if this statement is an EAssign) should not be visited
      Returns:
      true if the visit was successful
    • visitInstructionPostOrder

      default boolean visitInstructionPostOrder(IEVisitor visitor, boolean skipAssignmentDestination)
      Depth-first search, post-order visit of this statement. The node being visited may be replaced without notifying the visitor.

      Pre-order visits offer more options than post order visits: the visitor may decide to skip children; to skip the destination of assignments. However, replacement of nodes requires additional code to register the new node. Conversely, post-order visits do not offer any specific option, but provide the simplest way to replace nodes.

      Parameters:
      visitor - the visitor object
      skipAssignmentDestination - true if the destination of an assignment (if this statement is an EAssign) should not be visited
      Returns:
      true if the visit was successful