|
Ghidra 11.4.2
Ghidra internal decompiler documentation.
|
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. | |
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. | |
| 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. | |
| TransformVar * | newUnique (int4 size) |
| Make placeholder for new unique space Varnode. | |
| TransformVar * | newConstant (int4 size, int4 lsbOffset, uintb val) |
| Make placeholder for constant Varnode. | |
| TransformVar * | newIop (Varnode *vn) |
| Make placeholder for special iop constant. | |
| TransformVar * | newPiece (Varnode *vn, int4 bitSize, int4 lsbOffset) |
| Make placeholder for piece of a Varnode. | |
| TransformVar * | newSplit (Varnode *vn, const LaneDescription &description) |
| Create placeholder nodes splitting a Varnode into its lanes. | |
| 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. | |
| TransformOp * | newOpReplace (int4 numParams, OpCode opc, PcodeOp *replace) |
| Create a new placeholder op intended to replace an existing op. | |
| TransformOp * | newOp (int4 numParams, OpCode opc, TransformOp *follow) |
| Create a new placeholder op that will not replace an existing op. | |
| TransformOp * | newPreexistingOp (int4 numParams, OpCode opc, PcodeOp *originalOp) |
| Create a new placeholder op for an existing PcodeOp. | |
| TransformVar * | getPreexistingVarnode (Varnode *vn) |
| Get (or create) placeholder for preexisting Varnode. | |
| TransformVar * | getPiece (Varnode *vn, int4 bitSize, int4 lsbOffset) |
| Get (or create) placeholder piece. | |
| TransformVar * | getSplit (Varnode *vn, const LaneDescription &description) |
| Find (or create) placeholder nodes splitting a Varnode into its lanes. | |
| 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. | |
| void | opSetInput (TransformOp *rop, TransformVar *rvn, int4 slot) |
| Mark given variable as input to given op. | |
| void | opSetOutput (TransformOp *rop, TransformVar *rvn) |
| Mark given variable as output of given op. | |
| 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. | |
| bool | addOp (PcodeOp *op, TransformVar *rvn, int4 slot) |
| Split given op into its lanes. | |
| bool | traceForward (TransformVar *rvn) |
| Try to trace the pair of logical values, forward, through ops that read them. | |
| bool | traceBackward (TransformVar *rvn) |
| Try to trace the pair of logical values, backward, through the defining op. | |
| bool | processNextWork (void) |
| Process the next logical value on the worklist. | |
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. | |
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::TransformOp::inheritIndirect(), ghidra::TransformManager::newIop(), ghidra::TransformManager::newOpReplace(), ghidra::PcodeOp::numInput(), ghidra::TransformManager::opSetInput(), ghidra::TransformManager::opSetOutput(), and setReplacement().
Referenced by traceBackward(), and traceForward().
| 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 traceBackward(), traceForward(), and 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::TransformManager::getSplit(), ghidra::Varnode::getType(), ghidra::Varnode::isConstant(), ghidra::Varnode::isFree(), ghidra::Varnode::isInput(), ghidra::Varnode::isMark(), ghidra::Varnode::isTypeLock(), laneDescription, ghidra::TransformManager::newSplit(), ghidra::Varnode::setMark(), ghidra::TYPE_PARTIALSTRUCT, and worklist.
Referenced by addOp(), and 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 addOp(), 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::TransformManager::getPreexistingVarnode(), ghidra::LaneDescription::getSize(), ghidra::Varnode::getSize(), ghidra::LaneDescription::getWholeSize(), ghidra::Varnode::isConstant(), ghidra::Varnode::isFree(), ghidra::Varnode::isWritten(), laneDescription, ghidra::TransformManager::newConstant(), ghidra::TransformManager::newOpReplace(), ghidra::TransformManager::opSetInput(), and ghidra::TransformManager::opSetOutput().
Referenced by processNextWork().
|
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 addOp(), 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::PcodeOp::getOut(), ghidra::TransformOp::getOut(), ghidra::LaneDescription::getSize(), ghidra::Varnode::getSize(), ghidra::PcodeOp::getSlot(), ghidra::LaneDescription::getWholeSize(), ghidra::Varnode::isConstant(), ghidra::Varnode::isMark(), ghidra::Varnode::isPrecisHi(), ghidra::Varnode::isPrecisLo(), laneDescription, ghidra::TransformManager::newConstant(), ghidra::TransformManager::newOp(), ghidra::TransformManager::newPreexistingOp(), ghidra::TransformManager::newUnique(), ghidra::TransformManager::opSetInput(), and ghidra::TransformManager::opSetOutput().
Referenced by processNextWork().