decompiler
1.0.0
|
Class for splitting up Varnodes that hold 2 logical variables. More...
#include <subflow.hh>
Public Member Functions | |
SplitFlow (Funcdata *f, Varnode *root, int4 lowSize) | |
Constructor. | |
bool | doTrace (void) |
Trace split through data-flow, constructing transform. More... | |
Public Member Functions inherited from ghidra::TransformManager | |
TransformManager (Funcdata *f) | |
Constructor. | |
virtual | ~TransformManager (void) |
Destructor. | |
virtual bool | preserveAddress (Varnode *vn, int4 bitSize, int4 lsbOffset) const |
Should the address of the given Varnode be preserved when constructing a piece. More... | |
Funcdata * | getFunction (void) const |
Get function being transformed. | |
void | clearVarnodeMarks (void) |
Clear mark for all Varnodes in the map. | |
TransformVar * | newPreexistingVarnode (Varnode *vn) |
Make placeholder for preexisting Varnode. More... | |
TransformVar * | newUnique (int4 size) |
Make placeholder for new unique space Varnode. More... | |
TransformVar * | newConstant (int4 size, int4 lsbOffset, uintb val) |
Make placeholder for constant Varnode. More... | |
TransformVar * | newIop (Varnode *vn) |
Make placeholder for special iop constant. More... | |
TransformVar * | newPiece (Varnode *vn, int4 bitSize, int4 lsbOffset) |
Make placeholder for piece of a Varnode. More... | |
TransformVar * | newSplit (Varnode *vn, const LaneDescription &description) |
Create placeholder nodes splitting a Varnode into its lanes. More... | |
TransformVar * | newSplit (Varnode *vn, const LaneDescription &description, int4 numLanes, int4 startLane) |
Create placeholder nodes splitting a Varnode into a subset of lanes in the given description. More... | |
TransformOp * | newOpReplace (int4 numParams, OpCode opc, PcodeOp *replace) |
Create a new placeholder op intended to replace an existing op. More... | |
TransformOp * | newOp (int4 numParams, OpCode opc, TransformOp *follow) |
Create a new placeholder op that will not replace an existing op. More... | |
TransformOp * | newPreexistingOp (int4 numParams, OpCode opc, PcodeOp *originalOp) |
Create a new placeholder op for an existing PcodeOp. More... | |
TransformVar * | getPreexistingVarnode (Varnode *vn) |
Get (or create) placeholder for preexisting Varnode. More... | |
TransformVar * | getPiece (Varnode *vn, int4 bitSize, int4 lsbOffset) |
Get (or create) placeholder piece. More... | |
TransformVar * | getSplit (Varnode *vn, const LaneDescription &description) |
Find (or create) placeholder nodes splitting a Varnode into its lanes. More... | |
TransformVar * | getSplit (Varnode *vn, const LaneDescription &description, int4 numLanes, int4 startLane) |
Find (or create) placeholder nodes splitting a Varnode into a subset of lanes from a description. More... | |
void | opSetInput (TransformOp *rop, TransformVar *rvn, int4 slot) |
Mark given variable as input to given op. More... | |
void | opSetOutput (TransformOp *rop, TransformVar *rvn) |
Mark given variable as output of given op. More... | |
void | apply (void) |
Apply the full transform to the function. | |
Private Member Functions | |
TransformVar * | setReplacement (Varnode *vn) |
Find or build the placeholder objects for a Varnode that needs to be split. More... | |
bool | addOp (PcodeOp *op, TransformVar *rvn, int4 slot) |
Split given op into its lanes. More... | |
bool | traceForward (TransformVar *rvn) |
Try to trace the pair of logical values, forward, through ops that read them. More... | |
bool | traceBackward (TransformVar *rvn) |
Try to trace the pair of logical values, backward, through the defining op. More... | |
bool | processNextWork (void) |
Process the next logical value on the worklist. More... | |
Private Attributes | |
LaneDescription | laneDescription |
Description of how to split Varnodes. | |
vector< TransformVar * > | worklist |
Pending work list of Varnodes to push the split through. | |
Additional Inherited Members | |
Static Public Member Functions inherited from ghidra::TransformManager | |
static bool | preexistingGuard (int4 slot, TransformVar *rvn) |
Should newPreexistingOp be called. More... | |
Class for splitting up Varnodes that hold 2 logical variables.
Starting from a root Varnode provided to the constructor, this class looks for data-flow that consistently holds 2 logical values in a single Varnode. If doTrace() returns true, a consistent view has been created and invoking apply() will split all Varnodes and PcodeOps involved in the data-flow into their logical pieces.
|
private |
Split given op into its lanes.
We assume op is a logical operation, or a COPY, or an INDIRECT. It must have an output. All inputs and output have their placeholders generated and added to the worklist if appropriate.
op | is the given op |
rvn | is a known parameter of the op |
slot | is the incoming slot of the known parameter (-1 means parameter is output) |
References ghidra::PcodeOp::code(), ghidra::CPUI_INDIRECT, ghidra::TransformVar::getDef(), ghidra::PcodeOp::getIn(), ghidra::PcodeOp::getOut(), ghidra::PcodeOp::numInput(), and ghidra::SubvariableFlow::setReplacement().
Referenced by ghidra::SplitDatatype::RootPointer::backUpPointer().
bool ghidra::SplitFlow::doTrace | ( | void | ) |
Trace split through data-flow, constructing transform.
Push the logical split around, setting up the explicit transforms as we go. If at any point, the split cannot be naturally pushed, return false.
References ghidra::TransformManager::clearVarnodeMarks(), processNextWork(), and worklist.
Referenced by ghidra::RuleSplitFlow::applyOp().
|
private |
Process the next logical value on the worklist.
References ghidra::SubvariableFlow::traceBackward(), ghidra::SubvariableFlow::traceForward(), and ghidra::SubvariableFlow::worklist.
Referenced by doTrace().
|
private |
Find or build the placeholder objects for a Varnode that needs to be split.
Mark the Varnode so it doesn't get revisited. Decide if the Varnode needs to go into the worklist.
vn | is the Varnode that needs to be split |
References ghidra::Datatype::getMetatype(), ghidra::Varnode::getType(), ghidra::Varnode::isConstant(), ghidra::Varnode::isFree(), ghidra::Varnode::isInput(), ghidra::Varnode::isMark(), ghidra::Varnode::isTypeLock(), ghidra::Varnode::setMark(), ghidra::TYPE_PARTIALSTRUCT, and ghidra::SubvariableFlow::worklist.
Referenced by SplitFlow().
|
private |
Try to trace the pair of logical values, backward, through the defining op.
Create part of transform related to the defining op, and update the worklist as necessary.
rvn | is the logical value to examine |
References ghidra::PcodeOp::code(), ghidra::CPUI_COPY, ghidra::CPUI_INDIRECT, ghidra::CPUI_INT_AND, ghidra::CPUI_INT_LEFT, ghidra::CPUI_INT_OR, ghidra::CPUI_INT_XOR, ghidra::CPUI_INT_ZEXT, ghidra::CPUI_MULTIEQUAL, ghidra::CPUI_PIECE, ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::TransformVar::getOriginal(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), ghidra::Varnode::isConstant(), ghidra::Varnode::isFree(), and ghidra::Varnode::isWritten().
|
private |
Try to trace the pair of logical values, forward, through ops that read them.
Try to trace pieces of TransformVar pair forward, through reading ops, update worklist
rvn | is the TransformVar pair to trace, as an array |
References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_COPY, ghidra::CPUI_INDIRECT, ghidra::CPUI_INT_AND, ghidra::CPUI_INT_LEFT, ghidra::CPUI_INT_OR, ghidra::CPUI_INT_RIGHT, ghidra::CPUI_INT_SEXT, ghidra::CPUI_INT_SRIGHT, ghidra::CPUI_INT_XOR, ghidra::CPUI_INT_ZEXT, ghidra::CPUI_MULTIEQUAL, ghidra::CPUI_SUBPIECE, ghidra::Varnode::endDescend(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::TransformVar::getOriginal(), ghidra::TransformOp::getOut(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), ghidra::PcodeOp::getSlot(), ghidra::Varnode::isConstant(), ghidra::Varnode::isMark(), ghidra::Varnode::isPrecisHi(), and ghidra::Varnode::isPrecisLo().