decompiler  1.0.0
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
PcodeOp Class Reference

Lowest level operation of the p-code language. More...

#include <op.hh>

Public Types

enum  {
  startbasic = 1, branch = 2, call = 4, returns = 0x8,
  nocollapse = 0x10, dead = 0x20, marker = 0x40, booloutput = 0x80,
  boolean_flip = 0x100, fallthru_true = 0x200, indirect_source = 0x400, coderef = 0x800,
  startmark = 0x1000, mark = 0x2000, commutative = 0x4000, unary = 0x8000,
  binary = 0x10000, special = 0x20000, ternary = 0x40000, splittingbranch = 0x80000,
  nonprinting = 0x100000, halt = 0x200000, badinstruction = 0x400000, unimplemented = 0x800000,
  noreturn = 0x1000000, missing = 0x2000000, spacebase_ptr = 0x4000000, indirect_creation = 0x8000000,
  calculated_bool = 0x10000000, has_callspec = 0x20000000, ptrflow = 0x40000000, indirect_store = 0x80000000
}
 
enum  {
  special_prop = 1, special_print = 2, modified = 4, warning = 8,
  incidental_copy = 0x10, is_cpool_transformed = 0x20
}
 

Public Member Functions

 PcodeOp (int4 s, const SeqNum &sq)
 Construct an unattached PcodeOp. More...
 
 ~PcodeOp (void)
 Destructor.
 
int4 numInput (void) const
 Get the number of inputs to this op.
 
VarnodegetOut (void)
 Get the output Varnode of this op or null.
 
const VarnodegetOut (void) const
 Get the output Varnode of this op or null.
 
VarnodegetIn (int4 slot)
 Get a specific input Varnode to this op.
 
const VarnodegetIn (int4 slot) const
 Get a specific input Varnode to this op.
 
const BlockBasicgetParent (void) const
 Get the parent basic block.
 
BlockBasicgetParent (void)
 Get the parent basic block.
 
const AddressgetAddr (void) const
 Get the instruction address associated with this op.
 
uintm getTime (void) const
 Get the time index indicating when this op was created.
 
const SeqNumgetSeqNum (void) const
 Get the sequence number associated with this op.
 
list< PcodeOp * >::iterator getInsertIter (void) const
 Get position within alive/dead list.
 
list< PcodeOp * >::iterator getBasicIter (void) const
 
int4 getSlot (const Varnode *vn) const
 Get the slot number of the indicated input varnode.
 
int4 getRepeatSlot (const Varnode *vn, int4 firstSlot, list< PcodeOp * >::const_iterator iter) const
 Find the slot for a given Varnode, which may be take up multiple input slots. More...
 
uint4 getEvalType (void) const
 Get the evaluation type of this op.
 
uint4 getHaltType (void) const
 Get type which indicates unusual halt in control-flow.
 
bool isDead (void) const
 Return true if this op is dead.
 
bool isAssignment (void) const
 Return true is this op has an output.
 
bool isCall (void) const
 
bool isCallWithoutSpec (void) const
 Return true if this op acts as call but does not have a full specification.
 
bool isMarker (void) const
 Return true is a special SSA form op.
 
bool isIndirectCreation (void) const
 Return true if op creates a varnode indirectly.
 
bool isIndirectStore (void) const
 
bool notPrinted (void) const
 Return true if this op is not directly represented in C output.
 
bool isBoolOutput (void) const
 Return true if this op produces a boolean output.
 
bool isBranch (void) const
 
bool isCallOrBranch (void) const
 Return true if this op is a call or branch.
 
bool isFlowBreak (void) const
 Return true if this op breaks fall-thru flow.
 
bool isBooleanFlip (void) const
 Return true if this op flips the true/false meaning of its control-flow branching.
 
bool isFallthruTrue (void) const
 Return true if the fall-thru branch is taken when the boolean input is true.
 
bool isCodeRef (void) const
 Return true if the first input is a code reference.
 
bool isInstructionStart (void) const
 Return true if this starts an instruction.
 
bool isBlockStart (void) const
 Return true if this starts a basic block.
 
bool isModified (void) const
 Return true if this is modified by the current action.
 
bool isMark (void) const
 Return true if this op has been marked.
 
void setMark (void) const
 Set the mark on this op.
 
bool isWarning (void) const
 Return true if a warning has been generated for this op.
 
void clearMark (void) const
 Clear any mark on this op.
 
bool isIndirectSource (void) const
 Return true if this causes an INDIRECT.
 
void setIndirectSource (void)
 Mark this op as source of INDIRECT.
 
void clearIndirectSource (void)
 Clear INDIRECT source flag.
 
bool isPtrFlow (void) const
 Return true if this produces/consumes ptrs.
 
void setPtrFlow (void)
 Mark this op as consuming/producing ptrs.
 
bool isSplitting (void) const
 Return true if this branch splits.
 
bool doesSpecialPropagation (void) const
 Return true if this does datatype propagation.
 
bool doesSpecialPrinting (void) const
 Return true if this needs to special printing.
 
bool isIncidentalCopy (void) const
 
bool isCalculatedBool (void) const
 Return true if output is 1-bit boolean.
 
bool isCpoolTransformed (void) const
 Return true if we have already examined this cpool.
 
bool isCollapsible (void) const
 
bool usesSpacebasePtr (void) const
 Return true if this LOADs or STOREs from a dynamic spacebase pointer.
 
uintm getCseHash (void) const
 Return hash indicating possibility of common subexpression elimination. More...
 
bool isCseMatch (const PcodeOp *op) const
 Return true if this and op represent common subexpressions. More...
 
TypeOpgetOpcode (void) const
 Get the opcode for this op.
 
OpCode code (void) const
 Get the opcode id (enum) for this op.
 
bool isCommutative (void) const
 Return true if inputs commute.
 
uintb collapse (bool &markedInput) const
 Calculate the constant output produced by this op. More...
 
void collapseConstantSymbol (Varnode *newConst) const
 Propagate constant symbol from inputs to given output. More...
 
PcodeOpnextOp (void) const
 Return the next op in the control-flow from this or null.
 
PcodeOppreviousOp (void) const
 Return the previous op within this op's basic block or null. More...
 
PcodeOptarget (void) const
 Return starting op for instruction associated with this op. More...
 
uintb getNZMaskLocal (bool cliploop) const
 Calculate known zero bits for output to this op. More...
 
int4 compareOrder (const PcodeOp *bop) const
 Compare the control-flow order of this and bop. More...
 
void printRaw (ostream &s) const
 Print raw info about this op to stream.
 
const string & getOpName (void) const
 Return the name of this op.
 
void printDebug (ostream &s) const
 Print debug description of this op to stream. More...
 
void saveXml (ostream &s) const
 
DatatypeoutputTypeLocal (void) const
 Calculate the local output type.
 
DatatypeinputTypeLocal (int4 slot) const
 Calculate the local input type.
 
bool markExplicitUnsigned (int4 slot)
 Decide on unsignedness printing.
 
bool inheritsSign (void) const
 Does this token inherit its sign from operands.
 

Static Public Member Functions

static PcodeOpgetOpFromConst (const Address &addr)
 Retrieve the PcodeOp encoded as the address addr.
 

Private Member Functions

void setOpcode (TypeOp *t_op)
 Set the opcode for this PcodeOp. More...
 
void setOutput (Varnode *vn)
 Set the output Varnode of this op.
 
void clearInput (int4 slot)
 Clear a specific input Varnode to null.
 
void setInput (Varnode *vn, int4 slot)
 Set a specific input Varnode.
 
void setFlag (uint4 fl)
 Set specific boolean attribute(s) on this op.
 
void clearFlag (uint4 fl)
 Clear specific boolean attribute(s)
 
void setAdditionalFlag (uint4 fl)
 Set specific boolean attribute.
 
void clearAdditionalFlag (uint4 fl)
 Clear specific boolean atribute.
 
void flipFlag (uint4 fl)
 Flip the setting of specific boolean attribute(s)
 
void setNumInputs (int4 num)
 Make sure this op has num inputs. More...
 
void removeInput (int4 slot)
 Eliminate a specific input Varnode. More...
 
void insertInput (int4 slot)
 Make room for a new input Varnode at a specific position. More...
 
void setOrder (uintm ord)
 Order this op within the ops for a single instruction.
 
void setParent (BlockBasic *p)
 Set the parent basic block of this op.
 
void setBasicIter (list< PcodeOp * >::iterator iter)
 Store the iterator into this op's basic block.
 

Private Attributes

TypeOpopcode
 Pointer to class providing behavioral details of the operation.
 
uint4 flags
 Collection of boolean attributes on this op.
 
uint4 addlflags
 Additional boolean attributes for this op.
 
SeqNum start
 What instruction address is this attached to.
 
BlockBasicparent
 Basic block in which this op is contained.
 
list< PcodeOp * >::iterator basiciter
 Iterator within basic block.
 
list< PcodeOp * >::iterator insertiter
 Position in alive/dead list.
 
list< PcodeOp * >::iterator codeiter
 Position in opcode list.
 
Varnodeoutput
 The one possible output Varnode of this op.
 
vector< Varnode * > inrefs
 The ordered list of input Varnodes for this op.
 

Friends

class BlockBasic
 
class Funcdata
 
class PcodeOpBank
 
class VarnodeBank
 

Detailed Description

Lowest level operation of the p-code language.

The philosophy here is to have only one version of any type of operation, and to be completely explicit about all effects. All operations except the control flow operations have exactly one explicit output. Any given operation can have multiple inputs, but all are listed explicitly.

Input and output size for an operation are specified explicitly. All inputs must be of the same size. Except for the above restrictions, input and output can be any size in bytes.

P-code can be either big or little endian, this is determined by the language being translated from

Member Enumeration Documentation

anonymous enum

Boolean attributes (flags) that can be placed on a PcodeOp. Even though this enum is public, these are all set and read internally, although many are read publicly via get or is methods.

Enumerator
startbasic 

This instruction starts a basic block.

branch 

This instruction is a branch.

call 

This instruction calls a subroutine.

returns 

This instruction returns to caller.

nocollapse 

This op cannot be collapsed further.

dead 

This operation is dead.

marker 

special placeholder op (multiequal or indirect) or CPUI_COPY between different copies of same variable

booloutput 

Boolean operation.

boolean_flip 

Set if condition must be false to take branch.

fallthru_true 

Set if fallthru happens on true condition.

indirect_source 

Op is source of (one or more) CPUI_INDIRECTs.

coderef 

The first parameter to this op is a coderef.

startmark 

This op is the first in its instruction.

mark 

Used by many algorithms that need to detect loops or avoid repeats.

commutative 

Order of input parameters does not matter.

unary 

Evaluate as unary expression.

binary 

Evaluate as binary expression.

special 

Cannot be evaluated (without special processing)

ternary 

Evaluate as ternary operator (or higher)

splittingbranch 

Dead edge cannot be removed as it splits.

nonprinting 

Op should not be directly printed as source.

halt 

instruction causes processor or process to halt

badinstruction 

placeholder for bad instruction data

unimplemented 

placeholder for unimplemented instruction

noreturn 

placeholder for previous call that doesn't exit

missing 

ops at this address were not generated

spacebase_ptr 

Loads or stores from a dynamic pointer into a spacebase.

indirect_creation 

Output varnode is created by indirect effect.

calculated_bool 

Output has been determined to be a 1-bit boolean value.

has_callspec 

Op has a call specification associated with it.

ptrflow 

Op consumes or produces a ptr.

indirect_store 

CPUI_INDIRECT is caused by CPUI_STORE.

anonymous enum
Enumerator
special_prop 

Does some special form of datatype propagation.

special_print 

Op is marked for special printing.

modified 

This op has been modified by the current action.

warning 

Warning has been generated for this op.

incidental_copy 

Treat this as incidental for parameter recovery algorithms.

is_cpool_transformed 

Have we checked for cpool transforms.

Constructor & Destructor Documentation

PcodeOp::PcodeOp ( int4  s,
const SeqNum sq 
)

Construct an unattached PcodeOp.

Construct a completely unattached PcodeOp. Space is reserved for input and output Varnodes but all are set initially to null.

Parameters
sindicates the number of input slots reserved
sqis the sequence number to associate with the new PcodeOp

References addlflags, flags, inrefs, opcode, output, and parent.

Referenced by PcodeOpBank::create().

Member Function Documentation

uintb PcodeOp::collapse ( bool &  markedInput) const

Calculate the constant output produced by this op.

Assuming all the inputs to this op are constants, compute the constant result of evaluating this op on this inputs. If one if the inputs has attached symbol information, pass-back "the fact of" as we may want to propagate the info to the new constant. Throw an exception if a constant result cannot be produced.

Parameters
markedInputwill pass-back whether or not one of the inputs is a marked constant
Returns
the constant result

References binary, TypeOp::evaluateBinary(), TypeOp::evaluateUnary(), getEvalType(), getIn(), Varnode::getOffset(), Varnode::getSize(), Varnode::getSymbolEntry(), opcode, output, and unary.

Referenced by RuleCollapseConstants::applyOp().

void PcodeOp::collapseConstantSymbol ( Varnode newConst) const

Propagate constant symbol from inputs to given output.

Knowing that this PcodeOp has collapsed its constant inputs, one of which has symbol content, figure out if the symbol should propagate to the new given output constant.

Parameters
newConstis the given output constant

References code(), Varnode::copySymbolIfValid(), CPUI_COPY, CPUI_INT_2COMP, CPUI_INT_ADD, CPUI_INT_AND, CPUI_INT_LEFT, CPUI_INT_MULT, CPUI_INT_NEGATE, CPUI_INT_OR, CPUI_INT_RIGHT, CPUI_INT_SRIGHT, CPUI_INT_XOR, CPUI_INT_ZEXT, CPUI_SUBPIECE, getIn(), Varnode::getOffset(), and Varnode::getSymbolEntry().

Referenced by RuleCollapseConstants::applyOp().

int4 PcodeOp::compareOrder ( const PcodeOp bop) const

Compare the control-flow order of this and bop.

Compare the execution order of -this- and -bop-, if -this- executes earlier (dominates) return -1; if -bop- executes earlier return 1, otherwise return 0. Note that 0 is returned if there is no absolute execution order.

Parameters
bopis the PcodeOp to compare this to
Returns
-1, 0, or 1, depending on the comparison

References FlowBlock::findCommonBlock(), SeqNum::getOrder(), parent, and start.

Referenced by RuleOrPredicate::applyOp().

list<PcodeOp *>::iterator PcodeOp::getBasicIter ( void  ) const
inline
uintm PcodeOp::getCseHash ( void  ) const

Return hash indicating possibility of common subexpression elimination.

Produce a hash of the following attributes: output size, the opcode, and the identity of each input varnode. This is suitable for determining if two PcodeOps calculate identical values

Returns
the calculated hash or 0 if the op is not cse hashable

References binary, code(), CPUI_COPY, Varnode::getCreateIndex(), getEvalType(), getIn(), Varnode::getOffset(), Varnode::getSize(), inrefs, Varnode::isConstant(), output, and unary.

Referenced by RuleSelectCse::applyOp().

uintb PcodeOp::getNZMaskLocal ( bool  cliploop) const

Calculate known zero bits for output to this op.

Compute nonzeromask assuming inputs to op have their masks properly defined. Assume the op has an output. For any inputs to this op, that have zero bits where their nzmasks have zero bits, then the output produced by this op is guaranteed to have zero bits at every location in the nzmask calculated by this function.

Parameters
cliploopindicates the calculation shouldn't include inputs from known looping edges
Returns
the calculated non-zero mask

References calc_mask(), coveringmask(), CPUI_BOOL_AND, CPUI_BOOL_NEGATE, CPUI_BOOL_OR, CPUI_BOOL_XOR, CPUI_CALL, CPUI_CALLIND, CPUI_COPY, CPUI_CPOOLREF, CPUI_FLOAT_EQUAL, CPUI_FLOAT_LESS, CPUI_FLOAT_LESSEQUAL, CPUI_FLOAT_NAN, CPUI_FLOAT_NOTEQUAL, CPUI_INT_ADD, CPUI_INT_AND, CPUI_INT_CARRY, CPUI_INT_DIV, CPUI_INT_EQUAL, CPUI_INT_LEFT, CPUI_INT_LESS, CPUI_INT_LESSEQUAL, CPUI_INT_MULT, CPUI_INT_NOTEQUAL, CPUI_INT_OR, CPUI_INT_REM, CPUI_INT_RIGHT, CPUI_INT_SBORROW, CPUI_INT_SCARRY, CPUI_INT_SEXT, CPUI_INT_SLESS, CPUI_INT_SLESSEQUAL, CPUI_INT_SRIGHT, CPUI_INT_XOR, CPUI_INT_ZEXT, CPUI_MULTIEQUAL, CPUI_PIECE, CPUI_POPCOUNT, CPUI_SUBPIECE, getIn(), Varnode::getNZMask(), Varnode::getOffset(), TypeOp::getOpcode(), Varnode::getSize(), inrefs, isCalculatedBool(), Varnode::isConstant(), FlowBlock::isLoopIn(), leastsigbit_set(), mostsigbit_set(), opcode, output, parent, pcode_left(), pcode_right(), popcount(), and sign_extend().

Referenced by Funcdata::calcNZMask().

int4 PcodeOp::getRepeatSlot ( const Varnode vn,
int4  firstSlot,
list< PcodeOp * >::const_iterator  iter 
) const

Find the slot for a given Varnode, which may be take up multiple input slots.

In the rare case that this PcodeOp takes the same Varnode as input multiple times, use the specific descendant iterator producing this PcodeOp to work out the corresponding slot. Every slot containing the given Varnode will be produced exactly once over the course of iteration.

Parameters
vnis the given Varnode
firstSlotis the first instance of the Varnode in this input list
iteris the specific descendant iterator producing this
Returns
the slot corresponding to the iterator

References Varnode::beginDescend(), and inrefs.

Referenced by SubvariableFlow::traceForward(), SubfloatFlow::traceForward(), and SubvariableFlow::traceForwardSext().

void PcodeOp::insertInput ( int4  slot)
private

Make room for a new input Varnode at a specific position.

Insert space for a new Varnode before slot. The new space is filled with null.

Parameters
slotis index of the slot where the new space is inserted

References inrefs.

Referenced by Funcdata::opInsertInput(), and Funcdata::spacebaseConstant().

bool PcodeOp::isBranch ( void  ) const
inline
bool PcodeOp::isCall ( void  ) const
inline
bool PcodeOp::isCollapsible ( void  ) const

Return true if this can be collapsed to a COPY of a constant

Can this be collapsed to a copy op, i.e. are all inputs constants

Returns
true if this op can be callapsed

References code(), CPUI_COPY, flags, getIn(), getOut(), Varnode::getSize(), inrefs, isAssignment(), Varnode::isConstant(), and nocollapse.

Referenced by RuleCollapseConstants::applyOp().

bool PcodeOp::isCseMatch ( const PcodeOp op) const

Return true if this and op represent common subexpressions.

Do these two ops represent a common subexpression? This is the full test of matching indicated by getCseHash

Parameters
opis the PcodeOp to compare with this
Returns
true if the two ops are a common subexpression match

References binary, code(), CPUI_COPY, getEvalType(), getIn(), Varnode::getOffset(), Varnode::getSize(), inrefs, Varnode::isConstant(), output, and unary.

Referenced by RuleTrivialArith::applyOp(), and cseEliminateList().

bool PcodeOp::isIncidentalCopy ( void  ) const
inline

Return true if this COPY is incidental

References booloutput, calculated_bool, and incidental_copy.

Referenced by Funcdata::ancestorOpUse(), and AncestorRealistic::enterNode().

bool PcodeOp::isIndirectStore ( void  ) const
inline
PcodeOp * PcodeOp::previousOp ( void  ) const

Return the previous op within this op's basic block or null.

Find the previous op that flowed uniquely into this op, if it exists. This routine will not search farther than the basic block containing this.

Returns
the previous PcodeOp or null

References basiciter, BlockBasic::beginOp(), and parent.

Referenced by ActionShadowVar::apply(), FuncCallSpecs::collectOutputTrialVarnodes(), Heritage::reprocessFreeStores(), and FuncCallSpecs::transferLockedOutputParam().

void PcodeOp::printDebug ( ostream &  s) const

Print debug description of this op to stream.

Print an address and a raw representation of this op to the stream, suitable for console debugging apps

Parameters
sis the stream to print to

References isDead(), parent, printRaw(), and start.

Referenced by PcodeEmitFd::dump().

void PcodeOp::removeInput ( int4  slot)
private

Eliminate a specific input Varnode.

Remove the input Varnode in a specific slot. The slot is eliminated and all Varnodes beyond this slot are renumbered. All the other Varnodes are otherwise undisturbed.

Parameters
slotis the index of the Varnode to remove

References inrefs.

Referenced by Funcdata::opRemoveInput().

void PcodeOp::saveXml ( ostream &  s) const

Write an XML description of this op to stream

Write a description including: the opcode name, the sequence number, and separate xml tags providing a reference number for each input and output Varnode

Parameters
sis the stream to write to

References a_v_i(), a_v_u(), code(), CPUI_INDIRECT, CPUI_LOAD, CPUI_STORE, Varnode::getAddr(), Varnode::getCreateIndex(), getIn(), AddrSpace::getName(), getOpFromConst(), getSeqNum(), Varnode::getSpace(), Address::getSpaceFromConst(), SeqNum::getTime(), AddrSpace::getType(), inrefs, IPTR_CONSTANT, IPTR_IOP, output, SeqNum::saveXml(), and start.

Referenced by Funcdata::saveXmlTree().

void PcodeOp::setNumInputs ( int4  num)
private

Make sure this op has num inputs.

Make sure there are exactly num input slots for this op. All slots, regardless of the total being increased or decreased, are set to null.

Parameters
numis the number of inputs to set

References inrefs.

Referenced by Funcdata::nodeSplitInputPatch(), and Funcdata::opSetAllInput().

void PcodeOp::setOpcode ( TypeOp t_op)
private

Set the opcode for this PcodeOp.

Set the behavioral class (opcode) of this operation. For most applications this should only be called by the PcodeOpBank. This is fairly low-level but does cache various boolean flags associated with the opcode

Parameters
t_opis the behavioural class to set

References binary, booloutput, branch, call, coderef, commutative, flags, TypeOp::getFlags(), marker, nocollapse, opcode, returns, special, and unary.

Referenced by PcodeOpBank::changeOpcode().

PcodeOp * PcodeOp::target ( void  ) const

Return starting op for instruction associated with this op.

Scan backward within the basic block containing this op and find the first op marked as the start of an instruction. This also works if basic blocks haven't been calculated yet, and all the ops are still in the dead list. The starting op may be from a different instruction if this op was from an instruction in a delay slot

Returns
the starting PcodeOp

References basiciter, flags, insertiter, isDead(), and startmark.

Referenced by PcodeOpBank::target().


The documentation for this class was generated from the following files: