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

Class for splitting larger registers holding smaller logical lanes. More...

#include <transform.hh>

Inheritance diagram for ghidra::TransformManager:
ghidra::LaneDivide ghidra::SplitFlow ghidra::SubfloatFlow

Public Member Functions

 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.
 

Static Public Member Functions

static bool preexistingGuard (int4 slot, TransformVar *rvn)
 Should newPreexistingOp be called. More...
 

Private Member Functions

void specialHandling (TransformOp &rop)
 Handle some special PcodeOp marking If a PcodeOp is an INDIRECT creation, we need to do special marking of the op and Varnodes. More...
 
void createOps (void)
 Create a new op for each placeholder. More...
 
void createVarnodes (vector< TransformVar *> &inputList)
 Create a Varnode for each placeholder. More...
 
void removeOld (void)
 Remove old preexisting PcodeOps and Varnodes that are now obsolete.
 
void transformInputVarnodes (vector< TransformVar *> &inputList)
 Remove old input Varnodes, mark new input Varnodes. More...
 
void placeInputs (void)
 Set input Varnodes for all new ops.
 

Private Attributes

Funcdatafd
 Function being operated on.
 
map< int4, TransformVar * > pieceMap
 Map from large Varnodes to their new pieces.
 
list< TransformVarnewVarnodes
 Storage for Varnode placeholder nodes.
 
list< TransformOpnewOps
 Storage for PcodeOp placeholder nodes.
 

Detailed Description

Class for splitting larger registers holding smaller logical lanes.

Given a starting Varnode in the data-flow, look for evidence of the Varnode being interpreted as disjoint logical values concatenated together (lanes). If the interpretation is consistent for data-flow involving the Varnode, split Varnode and data-flow into explicit operations on the lanes.

Member Function Documentation

◆ createOps()

void ghidra::TransformManager::createOps ( void  )
private

Create a new op for each placeholder.

Run through the list of TransformOp placeholders and create the actual PcodeOp object. If the op has an output Varnode, create it. Make sure all the new ops are inserted in control flow.

◆ createVarnodes()

void ghidra::TransformManager::createVarnodes ( vector< TransformVar *> &  inputList)
private

◆ getPiece()

TransformVar * ghidra::TransformManager::getPiece ( Varnode vn,
int4  bitSize,
int4  lsbOffset 
)

Get (or create) placeholder piece.

Given a big Varnode, find the placeholder corresponding to the logical value given by a size and significance offset. If it doesn't exist, create it.

Parameters
vnis the big Varnode containing the logical value
bitSizeis the size of the logical value in bytes
lsbOffsetis the signficance offset of the logical value within the Varnode
Returns
the found/created placeholder

References ghidra::TransformVar::bitSize, ghidra::Varnode::getCreateIndex(), and ghidra::TransformVar::val.

◆ getPreexistingVarnode()

TransformVar * ghidra::TransformManager::getPreexistingVarnode ( Varnode vn)

Get (or create) placeholder for preexisting Varnode.

Check if a placeholder node was created for the preexisting Varnode for, otherwise create a new one.

Parameters
vnis the preexisting Varnode to find a placeholder for
Returns
the placeholder node

References ghidra::Varnode::getCreateIndex(), ghidra::Varnode::getOffset(), ghidra::Varnode::getSize(), and ghidra::Varnode::isConstant().

Referenced by ghidra::LaneDivide::buildLoad(), ghidra::LaneDivide::buildPiece(), and ghidra::LaneDivide::buildStore().

◆ getSplit() [1/2]

TransformVar * ghidra::TransformManager::getSplit ( Varnode vn,
const LaneDescription description 
)

Find (or create) placeholder nodes splitting a Varnode into its lanes.

Given a big Varnode and a lane description, look up placeholders for all its explicit pieces. If they don't exist, create them.

Parameters
vnis the big Varnode to split
descriptionshows how the big Varnode will be split
Returns
an array of the TransformVar placeholders from least to most significant

References ghidra::Varnode::getCreateIndex().

Referenced by ghidra::LaneDivide::setReplacement().

◆ getSplit() [2/2]

TransformVar * ghidra::TransformManager::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.

Given a big Varnode and a specific subset of a lane description, look up placeholders for all the explicit pieces. If they don't exist, create them.

Parameters
vnis the big Varnode to split
descriptiondescribes all the possible lanes
numLanesis the number of lanes in the subset
startLaneis the starting (least significant) lane in the subset
Returns
an array of the TransformVar placeholders from least to most significant

References ghidra::Varnode::getCreateIndex().

◆ newConstant()

TransformVar * ghidra::TransformManager::newConstant ( int4  size,
int4  lsbOffset,
uintb  val 
)

Make placeholder for constant Varnode.

Create a new constant in the transform view. A piece of an existing constant can be created by giving the existing value and the least significant offset.

Parameters
sizeis the size in bytes of the new constant
lsbOffsetis the number of bits to strip off of the existing value
valis the value of the constant
Returns
the new placeholder node

References ghidra::calc_mask(), ghidra::TransformVar::constant, and ghidra::TransformVar::initialize().

Referenced by ghidra::LaneDivide::buildLoad(), ghidra::LaneDivide::buildRightShift(), ghidra::LaneDivide::buildStore(), and ghidra::LaneDivide::traceForward().

◆ newIop()

TransformVar * ghidra::TransformManager::newIop ( Varnode vn)

Make placeholder for special iop constant.

Used for creating INDIRECT placeholders.

Parameters
vnis the original iop parameter to the INDIRECT
Returns
the new placeholder node

References ghidra::TransformVar::constant_iop, ghidra::Varnode::getOffset(), ghidra::Varnode::getSize(), and ghidra::TransformVar::initialize().

◆ newOp()

TransformOp * ghidra::TransformManager::newOp ( int4  numParams,
OpCode  opc,
TransformOp follow 
)

Create a new placeholder op that will not replace an existing op.

An uninitialized placeholder for the new op is created. When (if) the new op is created it will not replace an existing op. The op that follows it must be given.

Parameters
numParamsis the number of Varnode inputs intended for the new op
opcis the opcode of the new op
followis the placeholder for the op that follow the new op when it is created
Returns
the new placeholder node

References ghidra::TransformOp::input, ghidra::TransformOp::op, and ghidra::PcodeOp::special.

Referenced by ghidra::LaneDivide::buildLoad(), ghidra::SplitDatatype::buildPointers(), and ghidra::LaneDivide::buildStore().

◆ newOpReplace()

TransformOp * ghidra::TransformManager::newOpReplace ( int4  numParams,
OpCode  opc,
PcodeOp replace 
)

Create a new placeholder op intended to replace an existing op.

An uninitialized placeholder for the new op is created.

Parameters
numParamsis the number of Varnode inputs intended for the new op
opcis the opcode of the new op
replaceis the existing op the new op will replace
Returns
the new placeholder node

References ghidra::TransformOp::op, ghidra::TransformOp::op_replacement, and ghidra::PcodeOp::special.

Referenced by ghidra::LaneDivide::buildBinaryOp(), ghidra::LaneDivide::buildLoad(), ghidra::LaneDivide::buildMultiequal(), ghidra::LaneDivide::buildPiece(), ghidra::LaneDivide::buildRightShift(), ghidra::LaneDivide::buildStore(), and ghidra::LaneDivide::buildUnaryOp().

◆ newPiece()

TransformVar * ghidra::TransformManager::newPiece ( Varnode vn,
int4  bitSize,
int4  lsbOffset 
)

Make placeholder for piece of a Varnode.

Given a single logical value within a larger Varnode, create a placeholder for that logical value.

Parameters
vnis the large Varnode
bitSizeis the size of the logical value in bits
lsbOffsetis the number of least significant bits of the Varnode dropped from the value
Returns
the placeholder variable

References ghidra::TransformVar::flags, ghidra::Varnode::getCreateIndex(), ghidra::TransformVar::initialize(), ghidra::TransformVar::piece, ghidra::TransformVar::piece_temp, and ghidra::TransformVar::split_terminator.

◆ newPreexistingOp()

TransformOp * ghidra::TransformManager::newPreexistingOp ( int4  numParams,
OpCode  opc,
PcodeOp originalOp 
)

Create a new placeholder op for an existing PcodeOp.

An uninitialized placeholder for the existing op is created. When applied, this causes the op to be transformed as described by the placeholder, changing its opcode and inputs. The output however is unaffected.

Parameters
numParamsis the number of Varnode inputs intended for the transformed op
opcis the opcode of the transformed op
originalOpis the preexisting PcodeOp
Returns
the new placeholder node

References ghidra::TransformOp::op, ghidra::TransformOp::op_preexisting, and ghidra::PcodeOp::special.

Referenced by ghidra::LaneDivide::traceForward().

◆ newPreexistingVarnode()

TransformVar * ghidra::TransformManager::newPreexistingVarnode ( Varnode vn)

Make placeholder for preexisting Varnode.

Parameters
vnis the preexisting Varnode to create a placeholder for
Returns
the new placeholder node

References ghidra::TransformVar::flags, ghidra::Varnode::getCreateIndex(), ghidra::Varnode::getSize(), ghidra::TransformVar::initialize(), ghidra::TransformVar::preexisting, and ghidra::TransformVar::split_terminator.

◆ newSplit() [1/2]

TransformVar * ghidra::TransformManager::newSplit ( Varnode vn,
const LaneDescription description 
)

Create placeholder nodes splitting a Varnode into its lanes.

Given a big Varnode and a lane description, create placeholders for all the explicit pieces that the big Varnode will be split into.

Parameters
vnis the big Varnode to split
descriptionshows how the big Varnode will be split
Returns
an array of the new TransformVar placeholders from least to most significant

References ghidra::calc_mask(), ghidra::TransformVar::constant, ghidra::TransformVar::flags, ghidra::Varnode::getCreateIndex(), ghidra::LaneDescription::getNumLanes(), ghidra::Varnode::getOffset(), ghidra::LaneDescription::getPosition(), ghidra::LaneDescription::getSize(), ghidra::TransformVar::initialize(), ghidra::Varnode::isConstant(), ghidra::TransformVar::piece, ghidra::TransformVar::piece_temp, and ghidra::TransformVar::split_terminator.

Referenced by ghidra::LaneDivide::setReplacement().

◆ newSplit() [2/2]

TransformVar * ghidra::TransformManager::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.

Given a big Varnode and specific subset of a lane description, create placeholders for all the explicit pieces that the big Varnode will be split into.

Parameters
vnis the big Varnode to split
descriptiongives a list of potentional lanes
numLanesis the number of lanes in the subset
startLaneis the starting (least significant) lane in the subset
Returns
an array of the new TransformVar placeholders from least to most significant

References ghidra::calc_mask(), ghidra::TransformVar::constant, ghidra::TransformVar::flags, ghidra::Varnode::getCreateIndex(), ghidra::Varnode::getOffset(), ghidra::LaneDescription::getPosition(), ghidra::LaneDescription::getSize(), ghidra::TransformVar::initialize(), ghidra::Varnode::isConstant(), ghidra::TransformVar::piece, ghidra::TransformVar::piece_temp, and ghidra::TransformVar::split_terminator.

◆ newUnique()

TransformVar * ghidra::TransformManager::newUnique ( int4  size)

Make placeholder for new unique space Varnode.

Parameters
sizeis the size in bytes of the new unique Varnode
Returns
the new placeholder node

References ghidra::TransformVar::initialize(), and ghidra::TransformVar::normal_temp.

Referenced by ghidra::LaneDivide::buildLoad(), and ghidra::LaneDivide::buildStore().

◆ opSetInput()

void ghidra::TransformManager::opSetInput ( TransformOp rop,
TransformVar rvn,
int4  slot 
)
inline

Mark given variable as input to given op.

Parameters
ropis the given placeholder op whose input is set
rvnis the placeholder variable to set
slotis the input position to set

References ghidra::TransformOp::input.

Referenced by ghidra::LaneDivide::buildBinaryOp(), ghidra::LaneDivide::buildLoad(), ghidra::LaneDivide::buildMultiequal(), ghidra::LaneDivide::buildPiece(), ghidra::LaneDivide::buildRightShift(), ghidra::LaneDivide::buildStore(), ghidra::LaneDivide::buildUnaryOp(), and ghidra::LaneDivide::traceForward().

◆ opSetOutput()

void ghidra::TransformManager::opSetOutput ( TransformOp rop,
TransformVar rvn 
)
inline

Mark given variable as output of given op.

Establish that the given op produces the given var as output. Mark both the output field of the TransformOp and the def field of the TransformVar.

Parameters
ropis the given op
rvnis the given variable

References ghidra::TransformVar::def, and ghidra::TransformOp::output.

Referenced by ghidra::LaneDivide::buildBinaryOp(), ghidra::LaneDivide::buildLoad(), ghidra::LaneDivide::buildMultiequal(), ghidra::LaneDivide::buildPiece(), ghidra::LaneDivide::buildRightShift(), ghidra::LaneDivide::buildStore(), and ghidra::LaneDivide::buildUnaryOp().

◆ preexistingGuard()

bool ghidra::TransformManager::preexistingGuard ( int4  slot,
TransformVar rvn 
)
inlinestatic

Should newPreexistingOp be called.

Varnode marking prevents duplicate TransformOp (and TransformVar) records from getting created, except in the case of a preexisting PcodeOp with 2 (or more) non-constant inputs. Because the op is preexisting the output Varnode doesn't get marked, and the op will be visited for each input. This method determines when the TransformOp object should be created, with the goal of creating it exactly once even though the op is visited more than once. It currently assumes the PcodeOp is binary, and the slot along which the op is currently visited is passed in, along with the TransformVar for the other input. It returns true if the TransformOp should be created.

Parameters
slotis the incoming slot along which the op is visited
rvnis the other input

References ghidra::TransformVar::piece, ghidra::TransformVar::piece_temp, and ghidra::TransformVar::type.

◆ preserveAddress()

bool ghidra::TransformManager::preserveAddress ( Varnode vn,
int4  bitSize,
int4  lsbOffset 
) const
virtual

Should the address of the given Varnode be preserved when constructing a piece.

A new Varnode will be created that represents a logical piece of the given Varnode. This routine determines whether the new Varnode should be constructed using storage which overlaps the given Varnode. It returns true if overlapping storage should be used, false if the new Varnode should be constructed as a unique temporary.

Parameters
vnis the given Varnode
bitSizeis the logical size of the Varnode piece being constructed
lsbOffsetis the least significant bit position of the logical value within the given Varnode
Returns
true if overlapping storage should be used in construction

Reimplemented in ghidra::SubfloatFlow.

References ghidra::Varnode::getSpace(), ghidra::AddrSpace::getType(), and ghidra::IPTR_INTERNAL.

◆ specialHandling()

void ghidra::TransformManager::specialHandling ( TransformOp rop)
private

Handle some special PcodeOp marking If a PcodeOp is an INDIRECT creation, we need to do special marking of the op and Varnodes.

Parameters
ropis the placeholder op with the special requirement

References ghidra::TransformOp::indirect_creation, ghidra::TransformOp::indirect_creation_possible_out, ghidra::TransformOp::replacement, and ghidra::TransformOp::special.

◆ transformInputVarnodes()

void ghidra::TransformManager::transformInputVarnodes ( vector< TransformVar *> &  inputList)
private

Remove old input Varnodes, mark new input Varnodes.

Remove all input Varnodes from the given container. Mark all the replacement Varnodes as inputs.

Parameters
inputListis the given container of input placeholders

References ghidra::TransformVar::flags, ghidra::TransformVar::input_duplicate, ghidra::TransformVar::replacement, and ghidra::TransformVar::vn.


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