Ghidra Decompiler Analysis Engine
|
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... | |
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 | isCallWithoutSpec (void) const |
Return true if this op acts as call but does not have a full specification. | |
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 | 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 | 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... | |
bool | isMoveable (const PcodeOp *point) const |
Can this be moved to after point, without disturbing data-flow. More... | |
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... | |
PcodeOp * | nextOp (void) const |
Return the next op in the control-flow from this or null. | |
PcodeOp * | previousOp (void) const |
Return the previous op within this op's basic block or null. More... | |
PcodeOp * | target (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 | printDebug (ostream &s) const |
Print debug description of this op to stream. More... | |
void | saveXml (ostream &s) const |
Static Public Member Functions | |
static PcodeOp * | getOpFromConst (const Address &addr) |
Retrieve the PcodeOp encoded as the address addr. | |
Friends | |
class | BlockBasic |
class | Funcdata |
class | PcodeOpBank |
class | VarnodeBank |
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
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.
anonymous enum |
PcodeOp::PcodeOp | ( | int4 | s, |
const SeqNum & | sq | ||
) |
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.
markedInput | will pass-back whether or not one of the inputs is a marked constant |
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.
newConst | is the given output constant |
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.
bop | is the PcodeOp to compare this to |
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
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.
cliploop | indicates the calculation shouldn't include inputs from known looping edges |
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.
vn | is the given Varnode |
firstSlot | is the first instance of the Varnode in this input list |
iter | is the specific descendant iterator producing this |
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
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
op | is the PcodeOp to compare with this |
bool PcodeOp::isMoveable | ( | const PcodeOp * | point | ) | const |
Can this be moved to after point, without disturbing data-flow.
Its possible for the order of operations to be rearranged in some instances but still keep equivalent data-flow. Test if this operation can be moved to occur immediately after a specified point operation. This currently only tests for movement within a basic block.
point | is the specified point to move this after |
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.
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
s | is the stream to print to |
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
s | is the stream to write to |
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