decompiler  1.0.0
Public Member Functions | Private Member Functions | Private Attributes | List of all members
ghidra::SplitFlow Class Reference

Class for splitting up Varnodes that hold 2 logical variables. More...

#include <subflow.hh>

Inheritance diagram for ghidra::SplitFlow:
ghidra::TransformManager

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...
 
FuncdatagetFunction (void) const
 Get function being transformed.
 
void clearVarnodeMarks (void)
 Clear mark for all Varnodes in the map.
 
TransformVarnewPreexistingVarnode (Varnode *vn)
 Make placeholder for preexisting Varnode. More...
 
TransformVarnewUnique (int4 size)
 Make placeholder for new unique space Varnode. More...
 
TransformVarnewConstant (int4 size, int4 lsbOffset, uintb val)
 Make placeholder for constant Varnode. More...
 
TransformVarnewIop (Varnode *vn)
 Make placeholder for special iop constant. More...
 
TransformVarnewPiece (Varnode *vn, int4 bitSize, int4 lsbOffset)
 Make placeholder for piece of a Varnode. More...
 
TransformVarnewSplit (Varnode *vn, const LaneDescription &description)
 Create placeholder nodes splitting a Varnode into its lanes. More...
 
TransformVarnewSplit (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...
 
TransformOpnewOpReplace (int4 numParams, OpCode opc, PcodeOp *replace)
 Create a new placeholder op intended to replace an existing op. More...
 
TransformOpnewOp (int4 numParams, OpCode opc, TransformOp *follow)
 Create a new placeholder op that will not replace an existing op. More...
 
TransformOpnewPreexistingOp (int4 numParams, OpCode opc, PcodeOp *originalOp)
 Create a new placeholder op for an existing PcodeOp. More...
 
TransformVargetPreexistingVarnode (Varnode *vn)
 Get (or create) placeholder for preexisting Varnode. More...
 
TransformVargetPiece (Varnode *vn, int4 bitSize, int4 lsbOffset)
 Get (or create) placeholder piece. More...
 
TransformVargetSplit (Varnode *vn, const LaneDescription &description)
 Find (or create) placeholder nodes splitting a Varnode into its lanes. More...
 
TransformVargetSplit (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

TransformVarsetReplacement (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...
 

Detailed Description

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.

Member Function Documentation

◆ addOp()

bool ghidra::SplitFlow::addOp ( PcodeOp op,
TransformVar rvn,
int4  slot 
)
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.

Parameters
opis the given op
rvnis a known parameter of the op
slotis the incoming slot of the known parameter (-1 means parameter is output)
Returns
true if the op is successfully split

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().

◆ doTrace()

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.

Returns
true if a full transform has been constructed that can perform the split

References ghidra::TransformManager::clearVarnodeMarks(), processNextWork(), and worklist.

Referenced by ghidra::RuleSplitFlow::applyOp().

◆ processNextWork()

bool ghidra::SplitFlow::processNextWork ( void  )
private

Process the next logical value on the worklist.

Returns
true if the logical split was successfully pushed through its local operators

References ghidra::SubvariableFlow::traceBackward(), ghidra::SubvariableFlow::traceForward(), and ghidra::SubvariableFlow::worklist.

Referenced by doTrace().

◆ setReplacement()

TransformVar * ghidra::SplitFlow::setReplacement ( Varnode vn)
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.

Parameters
vnis the Varnode that needs to be split
Returns
the array of placeholders describing the split or null

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().

◆ traceBackward()

bool ghidra::SplitFlow::traceBackward ( TransformVar rvn)
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.

Parameters
rvnis the logical value to examine
Returns
false if the trace is not possible

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().

◆ traceForward()

bool ghidra::SplitFlow::traceForward ( TransformVar rvn)
private

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