Ghidra 11.3.2
Ghidra internal decompiler documentation.
Loading...
Searching...
No Matches
ghidra::SplitVarnode Class Reference

A logical value whose storage is split between two Varnodes. More...

#include <double.hh>

Collaboration diagram for ghidra::SplitVarnode:
[legend]

Public Member Functions

 SplitVarnode (void)
 Construct an uninitialized SplitVarnode.
 
 SplitVarnode (int4 sz, uintb v)
 Construct a double precision constant.
 
 SplitVarnode (Varnode *l, Varnode *h)
 Construct from lo and hi piece.
 
void initAll (Varnode *w, Varnode *l, Varnode *h)
 Construct given Varnode pieces and a known whole Varnode.
 
void initPartial (int4 sz, uintb v)
 (Re)initialize this SplitVarnode as a constant
 
void initPartial (int4 sz, Varnode *l, Varnode *h)
 (Re)initialize this SplitVarnode given Varnode pieces
 
bool inHandHi (Varnode *h)
 Try to initialize given just the most significant piece split from whole.
 
bool inHandLo (Varnode *l)
 Try to initialize given just the least significant piece split from whole.
 
bool inHandLoNoHi (Varnode *l)
 Try to initialize given just the least significant piece (other piece may be zero)
 
bool inHandHiOut (Varnode *h)
 Try to initialize given just the most significant piece concatenated into whole.
 
bool inHandLoOut (Varnode *l)
 Try to initialize given just the least significant piece concatenated into whole.
 
bool isConstant (void) const
 Return true if this is a constant.
 
bool hasBothPieces (void) const
 Return true if both pieces are initialized.
 
int4 getSize (void) const
 Get the size of this SplitVarnode as a whole in bytes.
 
VarnodegetLo (void) const
 Get the least significant Varnode piece.
 
VarnodegetHi (void) const
 Get the most significant Varnode piece.
 
VarnodegetWhole (void) const
 Get the Varnode representing this as a whole.
 
PcodeOpgetDefPoint (void) const
 Get the(final) defining PcodeOp of this.
 
BlockBasicgetDefBlock (void) const
 Get the defining basic block of this.
 
uintb getValue (void) const
 Get the value of this, assuming it is a constant.
 
bool isWholeFeasible (PcodeOp *existop)
 Does a whole Varnode already exist or can it be created before the given PcodeOp.
 
bool isWholePhiFeasible (FlowBlock *bl)
 Does a whole Varnode already exist or can it be created before the given basic block.
 
void findCreateWhole (Funcdata &data)
 Create a whole Varnode for this, if it doesn't already exist.
 
void findCreateOutputWhole (Funcdata &data)
 Create a whole Varnode that will be a PcodeOp output.
 
void createJoinedWhole (Funcdata &data)
 Create a whole Varnode from pieces, respecting piece storage.
 
void buildLoFromWhole (Funcdata &data)
 Rebuild the least significant piece as a CPUI_SUBPIECE of the whole.
 
void buildHiFromWhole (Funcdata &data)
 Rebuild the most significant piece as a CPUI_SUBPIECE of the whole.
 
PcodeOpfindEarliestSplitPoint (void)
 Find the earliest definition point of the lo and hi pieces.
 
PcodeOpfindOutExist (void)
 Find the point at which the output whole must exist.
 
bool exceedsConstPrecision (void) const
 Check if this is a constant that exceeds precision limits.
 

Static Public Member Functions

static bool adjacentOffsets (Varnode *vn1, Varnode *vn2, uintb size1)
 Check if the values in the given Varnodes differ by the given size.
 
static bool testContiguousPointers (PcodeOp *most, PcodeOp *least, PcodeOp *&first, PcodeOp *&second, AddrSpace *&spc)
 Verify that the pointers into the given LOAD/STORE PcodeOps address contiguous memory.
 
static bool isAddrTiedContiguous (Varnode *lo, Varnode *hi, Address &res)
 Return true if the given pieces can be melded into a contiguous storage location.
 
static void wholeList (Varnode *w, vector< SplitVarnode > &splitvec)
 Create a list of all the possible pairs that contain the same logical value as the given Varnode.
 
static void findCopies (const SplitVarnode &in, vector< SplitVarnode > &splitvec)
 Find copies from (the pieces of) the given SplitVarnode.
 
static void getTrueFalse (PcodeOp *boolop, bool flip, BlockBasic *&trueout, BlockBasic *&falseout)
 For the given CBRANCH PcodeOp, pass back the true and false basic blocks.
 
static bool otherwiseEmpty (PcodeOp *branchop)
 Return true if the basic block containing the given CBRANCH PcodeOp performs no other operation.
 
static bool verifyMultNegOne (PcodeOp *op)
 Verify that the given PcodeOp is a CPUI_INT_MULT by -1.
 
static PcodeOpprepareBinaryOp (SplitVarnode &out, SplitVarnode &in1, SplitVarnode &in2)
 Check that the logical version of a (generic) binary double-precision operation can be created.
 
static void createBinaryOp (Funcdata &data, SplitVarnode &out, SplitVarnode &in1, SplitVarnode &in2, PcodeOp *existop, OpCode opc)
 Rewrite a double precision binary operation by replacing the pieces with unified Varnodes.
 
static PcodeOpprepareShiftOp (SplitVarnode &out, SplitVarnode &in)
 Make sure input and output operands of a double precision shift operation are compatible.
 
static void createShiftOp (Funcdata &data, SplitVarnode &out, SplitVarnode &in, Varnode *sa, PcodeOp *existop, OpCode opc)
 Rewrite a double precision shift by replacing hi/lo pieces with unified Varnodes.
 
static void replaceBoolOp (Funcdata &data, PcodeOp *boolop, SplitVarnode &in1, SplitVarnode &in2, OpCode opc)
 Rewrite a double precision boolean operation by replacing the input pieces with unified Varnodes.
 
static bool prepareBoolOp (SplitVarnode &in1, SplitVarnode &in2, PcodeOp *testop)
 Make sure input operands of a double precision compare operation are compatible.
 
static void createBoolOp (Funcdata &data, PcodeOp *cbranch, SplitVarnode &in1, SplitVarnode &in2, OpCode opc)
 Create a new compare PcodeOp, replacing the boolean Varnode taken as input by the given CBRANCH.
 
static PcodeOppreparePhiOp (SplitVarnode &out, vector< SplitVarnode > &inlist)
 Check that the logical version of a CPUI_MULTIEQUAL operation can be created.
 
static void createPhiOp (Funcdata &data, SplitVarnode &out, vector< SplitVarnode > &inlist, PcodeOp *existop)
 Rewrite a double precision MULTIEQUAL operation by replacing the pieces with unified Varnodes.
 
static bool prepareIndirectOp (SplitVarnode &in, PcodeOp *affector)
 Check that the logical version of a CPUI_INDIRECT operation can be created.
 
static void replaceIndirectOp (Funcdata &data, SplitVarnode &out, SplitVarnode &in, PcodeOp *affector)
 Rewrite a double precision INDIRECT operation by replacing the pieces with unified Varnodes.
 
static void replaceCopyForce (Funcdata &data, const Address &addr, SplitVarnode &in, PcodeOp *copylo, PcodeOp *copyhi)
 Rewrite the double precision version of a COPY to an address forced Varnode.
 
static int4 applyRuleIn (SplitVarnode &in, Funcdata &data)
 Try to perform one transform on a logical double precision operation given a specific input.
 

Private Member Functions

bool findWholeSplitToPieces (void)
 Find whole out of which hi and lo are split.
 
bool findDefinitionPoint (void)
 Find the earliest PcodeOp where both lo and hi are defined.
 
bool findWholeBuiltFromPieces (void)
 Find whole Varnode formed as a CPUI_PIECE of hi and lo.
 

Private Attributes

Varnodelo
 Least significant piece of the double precision object.
 
Varnodehi
 Most significant piece of the double precision object.
 
Varnodewhole
 A representative of the whole object.
 
PcodeOpdefpoint
 Operation at which both lo and hi are defined.
 
BlockBasicdefblock
 Block in which both lo and hi are defined.
 
uintb val
 Value of a double precision constant.
 
int4 wholesize
 Size in bytes of the (virtual) whole.
 

Detailed Description

A logical value whose storage is split between two Varnodes.

This is usually a pair of Varnodes lo and hi holding the least and most significant part of the logical value respectively. Its possible for the logical value to be a constant, in which case lo and hi are set to null and val holds the actual constant. Its also possible for hi to be null by itself, indicating that most signficant part of the variable is zero, and the logical variable is the zero extension of lo.

Constructor & Destructor Documentation

◆ SplitVarnode()

ghidra::SplitVarnode::SplitVarnode ( int4  sz,
uintb  v 
)

Construct a double precision constant.

Internally, the lo and hi Varnodes are set to null, and the val field holds the constant value.

Parameters
szis the size in bytes of the constant
vis the constant value

References defblock, defpoint, hi, lo, val, whole, and wholesize.

Member Function Documentation

◆ adjacentOffsets()

bool ghidra::SplitVarnode::adjacentOffsets ( Varnode vn1,
Varnode vn2,
uintb  size1 
)
static

Check if the values in the given Varnodes differ by the given size.

Return true, if the (possibly dynamic) value represented by the given vn1 plus size1 produces the value in the given vn2. For constants, the values can be computed directly, but otherwise vn1 and vn2 must be defined by INT_ADD operations from a common ancestor.

Parameters
vn1is the first given Varnode
vn2is the second given Varnode
size1is the given size to add to vn1
Returns
true if the values in vn1 and vn2 are related by the given size

References ghidra::PcodeOp::code(), ghidra::CPUI_INT_ADD, ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::Varnode::isConstant(), and ghidra::Varnode::isWritten().

Referenced by testContiguousPointers().

◆ applyRuleIn()

int4 ghidra::SplitVarnode::applyRuleIn ( SplitVarnode in,
Funcdata data 
)
static

Try to perform one transform on a logical double precision operation given a specific input.

All the various double precision forms are lined up against the input. The first one that matches has its associated transform performed and then 1 is returned. If no form matches, 0 is returned.

Parameters
inis the given double precision input
datais the function owning the Varnodes
Returns
a count of the number of transforms applied, 0 or 1

References ghidra::CopyForceForm::applyRule(), ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_COPY, ghidra::CPUI_INDIRECT, ghidra::CPUI_INT_ADD, ghidra::CPUI_INT_AND, ghidra::CPUI_INT_EQUAL, ghidra::CPUI_INT_LEFT, ghidra::CPUI_INT_LESS, ghidra::CPUI_INT_LESSEQUAL, ghidra::CPUI_INT_MULT, ghidra::CPUI_INT_NOTEQUAL, ghidra::CPUI_INT_OR, ghidra::CPUI_INT_RIGHT, ghidra::CPUI_INT_SLESS, ghidra::CPUI_INT_SLESSEQUAL, ghidra::CPUI_INT_SRIGHT, ghidra::CPUI_INT_XOR, ghidra::CPUI_MULTIEQUAL, ghidra::Varnode::endDescend(), getHi(), getLo(), ghidra::PcodeOp::getOut(), and ghidra::Varnode::isAddrForce().

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

◆ buildHiFromWhole()

void ghidra::SplitVarnode::buildHiFromWhole ( Funcdata data)

◆ buildLoFromWhole()

void ghidra::SplitVarnode::buildLoFromWhole ( Funcdata data)

Rebuild the least significant piece as a CPUI_SUBPIECE of the whole.

Assume lo was initially defined in some other way but now needs to be defined as a split from a new whole Varnode. The original PcodeOp defining lo is transformed into a CPUI_SUBPIECE. The method findCreateOutputWhole() must already have been called on this.

References ghidra::PcodeOp::code(), ghidra::CPUI_INDIRECT, ghidra::CPUI_MULTIEQUAL, ghidra::CPUI_SUBPIECE, ghidra::Varnode::getAddr(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::PcodeOp::getOpFromConst(), ghidra::PcodeOp::getParent(), ghidra::PcodeOp::isDead(), lo, ghidra::Funcdata::newConstant(), ghidra::Funcdata::opInsertAfter(), ghidra::Funcdata::opInsertBegin(), ghidra::Funcdata::opSetAllInput(), ghidra::Funcdata::opSetOpcode(), ghidra::Funcdata::opUninsert(), and whole.

Referenced by createBinaryOp(), createPhiOp(), createShiftOp(), and replaceIndirectOp().

◆ createBinaryOp()

void ghidra::SplitVarnode::createBinaryOp ( Funcdata data,
SplitVarnode out,
SplitVarnode in1,
SplitVarnode in2,
PcodeOp existop,
OpCode  opc 
)
static

Rewrite a double precision binary operation by replacing the pieces with unified Varnodes.

This assumes that we have checked that the transformation is possible via the various verify and prepare methods. After this method is called, the logical inputs and output of the calculation will exist as real Varnodes.

Parameters
datais the function owning the operation
outis the output of the binary operation
in1is the first input to the binary operation
in2is the second input to the binary operation
existopis the precalculated PcodeOp where the output whole Varnode must exist
opcis the opcode of the operation

References buildHiFromWhole(), buildLoFromWhole(), ghidra::PcodeOp::code(), ghidra::CPUI_PIECE, findCreateOutputWhole(), findCreateWhole(), ghidra::PcodeOp::getAddr(), getWhole(), ghidra::Funcdata::newOp(), ghidra::Funcdata::opInsertBefore(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), and ghidra::Funcdata::opSetOutput().

◆ createBoolOp()

void ghidra::SplitVarnode::createBoolOp ( Funcdata data,
PcodeOp cbranch,
SplitVarnode in1,
SplitVarnode in2,
OpCode  opc 
)
static

Create a new compare PcodeOp, replacing the boolean Varnode taken as input by the given CBRANCH.

The inputs to the new compare operation are Varnodes representing the logical whole of the double precision pieces.

Parameters
datais the function owning the operation
cbranchis the given CBRANCH PcodeOp
in1is the first input to the compare operation
in2is the second input to the compare operation
opcis the opcode of the compare operation

References findCreateWhole(), ghidra::PcodeOp::getAddr(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), getWhole(), ghidra::Varnode::isWritten(), ghidra::Funcdata::newOp(), ghidra::Funcdata::newUniqueOut(), ghidra::Funcdata::opInsertBefore(), ghidra::Funcdata::opSetInput(), and ghidra::Funcdata::opSetOpcode().

◆ createJoinedWhole()

void ghidra::SplitVarnode::createJoinedWhole ( Funcdata data)

Create a whole Varnode from pieces, respecting piece storage.

If the pieces can be treated as a contiguous whole, use the same storage location to construct the whole, otherwise use a join address for storage.

Parameters
datais the function owning the pieces

References ghidra::AddrSpaceManager::constructJoinAddress(), ghidra::Varnode::getAddr(), ghidra::Funcdata::getArch(), ghidra::Varnode::getSize(), hi, isAddrTiedContiguous(), lo, ghidra::Funcdata::newVarnode(), ghidra::Varnode::setPrecisHi(), ghidra::Varnode::setPrecisLo(), ghidra::Varnode::setWriteMask(), ghidra::Architecture::translate, whole, and wholesize.

Referenced by replaceIndirectOp().

◆ createPhiOp()

void ghidra::SplitVarnode::createPhiOp ( Funcdata data,
SplitVarnode out,
vector< SplitVarnode > &  inlist,
PcodeOp existop 
)
static

Rewrite a double precision MULTIEQUAL operation by replacing the pieces with unified Varnodes.

This assumes that we have checked that the transformation is possible via the various verify and prepare methods. After this method is called, the logical inputs and output of the calculation will exist as real Varnodes.

Parameters
datais the function owning the operation
outis the output of the MULTIEQUAL operation
inlistis the list of input operands to the MULTIEQUAL
existopis the precalculated PcodeOp where the output whole Varnode must exist

References buildHiFromWhole(), buildLoFromWhole(), ghidra::CPUI_MULTIEQUAL, findCreateOutputWhole(), findCreateWhole(), ghidra::PcodeOp::getAddr(), getWhole(), ghidra::Funcdata::newOp(), ghidra::Funcdata::opInsertBefore(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), and ghidra::Funcdata::opSetOutput().

◆ createShiftOp()

void ghidra::SplitVarnode::createShiftOp ( Funcdata data,
SplitVarnode out,
SplitVarnode in,
Varnode sa,
PcodeOp existop,
OpCode  opc 
)
static

Rewrite a double precision shift by replacing hi/lo pieces with unified Varnodes.

This assumes that we have checked that the transformation is possible by calling the appropriate verify and prepare methods. After this method is called, the logical inputs and output of the calculation will exist as real Varnodes. The shift amount is not treated as a double precision variable.

Parameters
datais the function owning the operation
outis the output of the double precision operation
inis the first input of the operation
sais the Varnode indicating the shift amount for the operation
existopis the first PcodeOp where the output whole needs to exist
opcis the opcode of the particular shift operation

References buildHiFromWhole(), buildLoFromWhole(), ghidra::PcodeOp::code(), ghidra::CPUI_PIECE, findCreateOutputWhole(), findCreateWhole(), ghidra::PcodeOp::getAddr(), ghidra::Varnode::getOffset(), ghidra::Varnode::getSize(), getWhole(), ghidra::Varnode::isConstant(), ghidra::Funcdata::newConstant(), ghidra::Funcdata::newOp(), ghidra::Funcdata::opInsertBefore(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), and ghidra::Funcdata::opSetOutput().

◆ exceedsConstPrecision()

bool ghidra::SplitVarnode::exceedsConstPrecision ( void  ) const

Check if this is a constant that exceeds precision limits.

If the logical whole is a constant and is too big to be represented internally return true.

Returns
true if this is a constant and too big

References isConstant(), and wholesize.

◆ findCopies()

void ghidra::SplitVarnode::findCopies ( const SplitVarnode in,
vector< SplitVarnode > &  splitvec 
)
static

Find copies from (the pieces of) the given SplitVarnode.

Scan for each piece being used as input to COPY operations. If the each piece is copied within the same basic block to contiguous storage locations, create a new SplitVarnode from COPY outputs and add it to the list.

Parameters
inis the given SplitVarnode
splitvecis the container for holding SplitVarnode copies

References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_COPY, ghidra::Varnode::endDescend(), ghidra::Varnode::getAddr(), getHi(), getLo(), ghidra::PcodeOp::getOut(), ghidra::PcodeOp::getParent(), ghidra::Varnode::getSize(), getWhole(), hasBothPieces(), initAll(), and ghidra::Address::isBigEndian().

Referenced by wholeList().

◆ findCreateOutputWhole()

void ghidra::SplitVarnode::findCreateOutputWhole ( Funcdata data)

Create a whole Varnode that will be a PcodeOp output.

If the whole does not already exist, it is created as a unique register. The new Varnode must later be set explicitly as the output of some PcodeOp.

Parameters
datais the function owning the Varnode pieces

References hi, lo, ghidra::Funcdata::newUnique(), ghidra::Varnode::setPrecisHi(), ghidra::Varnode::setPrecisLo(), whole, and wholesize.

Referenced by createBinaryOp(), createPhiOp(), and createShiftOp().

◆ findCreateWhole()

void ghidra::SplitVarnode::findCreateWhole ( Funcdata data)

Create a whole Varnode for this, if it doesn't already exist.

This method assumes isWholeFeasible has been called and returned true. If the whole didn't already exist, it is created as the concatenation of its two pieces. If the pieces were constant, a constant whole Varnode is created. If the hi piece was null, the whole is created as a CPUI_ZEXT of the lo.

Parameters
datais the function owning the Varnode pieces

References ghidra::CPUI_INT_ZEXT, ghidra::CPUI_PIECE, defblock, defpoint, ghidra::PcodeOp::getAddr(), ghidra::Funcdata::getBasicBlocks(), ghidra::PcodeOp::getParent(), ghidra::BlockBasic::getStart(), ghidra::BlockGraph::getStartBlock(), hi, isConstant(), lo, ghidra::Funcdata::newConstant(), ghidra::Funcdata::newOp(), ghidra::Funcdata::newUniqueOut(), ghidra::Funcdata::opInsertAfter(), ghidra::Funcdata::opInsertBegin(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), ghidra::Funcdata::opSetOutput(), ghidra::Varnode::setPrecisHi(), ghidra::Varnode::setPrecisLo(), val, whole, and wholesize.

Referenced by createBinaryOp(), createBoolOp(), createPhiOp(), createShiftOp(), replaceBoolOp(), and replaceIndirectOp().

◆ findDefinitionPoint()

bool ghidra::SplitVarnode::findDefinitionPoint ( void  )
private

Find the earliest PcodeOp where both lo and hi are defined.

Set the basic block, defblock, and PcodeOp, defpoint, where they are defined. Its possible that lo and hi are input Varnodes with no natural defining PcodeOp, in which case defpoint is set to null and defblock is set to the function entry block. The method returns true, if the definition point is found, which amounts to returning false if the SplitVarnode is only half constant or half input.

Returns
true if the definition point is located

References defblock, defpoint, ghidra::Varnode::getDef(), ghidra::FlowBlock::getImmedDom(), ghidra::SeqNum::getOrder(), ghidra::PcodeOp::getParent(), ghidra::PcodeOp::getSeqNum(), hi, ghidra::Varnode::isConstant(), ghidra::Varnode::isInput(), ghidra::Varnode::isWritten(), and lo.

Referenced by isWholeFeasible(), and isWholePhiFeasible().

◆ findEarliestSplitPoint()

PcodeOp * ghidra::SplitVarnode::findEarliestSplitPoint ( void  )

Find the earliest definition point of the lo and hi pieces.

If both lo and hi pieces are written, the earlier of the two defining PcodeOps is returned. Otherwise null is returned.

Returns
the earlier of the two defining PcodeOps or null

References ghidra::Varnode::getDef(), ghidra::SeqNum::getOrder(), ghidra::PcodeOp::getParent(), ghidra::PcodeOp::getSeqNum(), hi, ghidra::Varnode::isWritten(), and lo.

Referenced by findOutExist(), and preparePhiOp().

◆ findOutExist()

PcodeOp * ghidra::SplitVarnode::findOutExist ( void  )

Find the point at which the output whole must exist.

Its assumed that this is the output of the double precision operation being performed. The whole Varnode may not yet exist. This method returns the first PcodeOp where the whole needs to exist. If no such PcodeOp exists, null is returned.

Returns
the first PcodeOp where the whole needs to exist or null

References defpoint, findEarliestSplitPoint(), and findWholeBuiltFromPieces().

Referenced by prepareBinaryOp(), and prepareShiftOp().

◆ findWholeBuiltFromPieces()

bool ghidra::SplitVarnode::findWholeBuiltFromPieces ( void  )
private

Find whole Varnode formed as a CPUI_PIECE of hi and lo.

We scan for concatenations formed out of hi and lo, in the correct significance order. We assume hi and lo are defined in the same basic block (or are both inputs) and that the concatenation is also in this block. If such a concatenation is found, whole is set to the concatenated Varnode, the defining block and PcodeOp is filled in, and true is returned.

Returns
true if a whole concatenated from hi and lo is found

References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_PIECE, defblock, defpoint, ghidra::Varnode::endDescend(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::SeqNum::getOrder(), ghidra::PcodeOp::getOut(), ghidra::PcodeOp::getParent(), ghidra::PcodeOp::getSeqNum(), hi, ghidra::FlowBlock::isEntryPoint(), ghidra::Varnode::isInput(), ghidra::Varnode::isWritten(), lo, and whole.

Referenced by findOutExist(), isWholeFeasible(), and isWholePhiFeasible().

◆ findWholeSplitToPieces()

bool ghidra::SplitVarnode::findWholeSplitToPieces ( void  )
private

Find whole out of which hi and lo are split.

Look for CPUI_SUBPIECE operations off of a common Varnode. The whole field is set to this Varnode if found; the definition point and block are filled in and true is returned. Otherwise false is returned.

Returns
true if the whole Varnode is found

References ghidra::PcodeOp::code(), ghidra::CPUI_COPY, ghidra::CPUI_SUBPIECE, defblock, defpoint, ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getParent(), ghidra::Varnode::getSize(), hi, ghidra::Varnode::isInput(), ghidra::Varnode::isWritten(), lo, whole, and wholesize.

Referenced by isWholeFeasible(), and isWholePhiFeasible().

◆ getTrueFalse()

void ghidra::SplitVarnode::getTrueFalse ( PcodeOp boolop,
bool  flip,
BlockBasic *&  trueout,
BlockBasic *&  falseout 
)
static

For the given CBRANCH PcodeOp, pass back the true and false basic blocks.

The result depends on the boolean flip property of the CBRANCH, and the user can also flip the meaning of the branches.

Parameters
boolopis the given CBRANCH PcodeOp
flipis true if the caller wants to flip the meaning of the blocks
trueoutis used to pass back the true fall-through block
falseoutis used to pass back the false fall-through block

References ghidra::FlowBlock::getFalseOut(), ghidra::PcodeOp::getParent(), ghidra::FlowBlock::getTrueOut(), and ghidra::PcodeOp::isBooleanFlip().

◆ inHandHi()

bool ghidra::SplitVarnode::inHandHi ( Varnode h)

Try to initialize given just the most significant piece split from whole.

Verify that the given most significant piece is formed via CPUI_SUBPIECE and search for the least significant piece being formed as a CPUI_SUBPIECE of the same whole.

Parameters
his the given (most significant) Varnode piece
Returns
true if the matching whole and least significant piece is found

References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_SUBPIECE, ghidra::Varnode::endDescend(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), initAll(), ghidra::Varnode::isPrecisHi(), ghidra::Varnode::isPrecisLo(), and ghidra::Varnode::isWritten().

Referenced by ghidra::ActionParamDouble::apply().

◆ inHandHiOut()

bool ghidra::SplitVarnode::inHandHiOut ( Varnode h)

Try to initialize given just the most significant piece concatenated into whole.

Initialize the SplitVarnode given the most significant piece, if it is concatenated together immediately with is least significant piece. The CPUI_PIECE and the matching least significant piece must be unique. If these are found, hi, lo, and whole are all filled in.

Parameters
his the given (most significant) piece
Returns
true if initialization was successful and the least significant piece was found

References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_PIECE, ghidra::Varnode::endDescend(), ghidra::PcodeOp::getIn(), ghidra::PcodeOp::getOut(), initAll(), and ghidra::Varnode::isPrecisLo().

◆ inHandLo()

bool ghidra::SplitVarnode::inHandLo ( Varnode l)

Try to initialize given just the least significant piece split from whole.

Verify that the given least significant piece is formed via CPUI_SUBPIECE and search for the most significant piece being formed as a CPUI_SUBPIECE of the same whole.

Parameters
lis the given (least significant) Varnode piece
Returns
true if the matching whole and most significant piece is found

References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_SUBPIECE, ghidra::Varnode::endDescend(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), initAll(), ghidra::Varnode::isPrecisHi(), ghidra::Varnode::isPrecisLo(), and ghidra::Varnode::isWritten().

Referenced by ghidra::ActionParamDouble::apply().

◆ inHandLoNoHi()

bool ghidra::SplitVarnode::inHandLoNoHi ( Varnode l)

Try to initialize given just the least significant piece (other piece may be zero)

The given least significant Varnode must already be marked as a piece. Initialize the SplitVarnode with the given piece and the whole that it came from. If a matching most significant piece can be found, as another CPUI_SUBPIECE off of the same whole, initialize that as well. Otherwise leave the most significant piece as null.

Parameters
lis the given (least significant) Varnode piece
Returns
true if the SplitVarnode is successfully initialized

References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_SUBPIECE, ghidra::Varnode::endDescend(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), initAll(), ghidra::Varnode::isPrecisHi(), ghidra::Varnode::isPrecisLo(), and ghidra::Varnode::isWritten().

◆ inHandLoOut()

bool ghidra::SplitVarnode::inHandLoOut ( Varnode l)

Try to initialize given just the least significant piece concatenated into whole.

Initialize the SplitVarnode given the least significant piece, if it is concatenated together immediately with is nost significant piece. The CPUI_PIECE and the matching most significant piece must be unique. If these are found, hi, lo, and whole are all filled in.

Parameters
lis the given (least significant) piece
Returns
true if initialization was successful and the most significant piece was found

References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_PIECE, ghidra::Varnode::endDescend(), ghidra::PcodeOp::getIn(), ghidra::PcodeOp::getOut(), initAll(), and ghidra::Varnode::isPrecisHi().

◆ initAll()

void ghidra::SplitVarnode::initAll ( Varnode w,
Varnode l,
Varnode h 
)

Construct given Varnode pieces and a known whole Varnode.

The lo, hi, and whole fields are filled in. The definition point remains uninitialized.

Parameters
wis the given whole Varnode
lis the given (least significant) Varnode piece
his the given (most significant) Varnode piece

References defblock, defpoint, ghidra::Varnode::getSize(), hi, lo, whole, and wholesize.

Referenced by findCopies(), inHandHi(), inHandHiOut(), inHandLo(), inHandLoNoHi(), and inHandLoOut().

◆ initPartial() [1/2]

void ghidra::SplitVarnode::initPartial ( int4  sz,
uintb  v 
)

(Re)initialize this SplitVarnode as a constant

Parameters
szis the size of the constant in bytes
vis the constant value

References defblock, defpoint, hi, lo, val, whole, and wholesize.

Referenced by SplitVarnode().

◆ initPartial() [2/2]

void ghidra::SplitVarnode::initPartial ( int4  sz,
Varnode l,
Varnode h 
)

(Re)initialize this SplitVarnode given Varnode pieces

The Varnode pieces can be constant, in which case a constant SplitVarnode is initialized and a constant value is built from the pieces. The given most significant piece can be null, indicating that the most significant piece of the whole is an implied zero.

Parameters
szis the size of the logical whole in bytes
lis the given (least significant) Varnode piece
his the given (most significant) Varnode piece

References defblock, defpoint, ghidra::Varnode::getOffset(), ghidra::Varnode::getSize(), hi, ghidra::Varnode::isConstant(), lo, val, whole, and wholesize.

◆ isAddrTiedContiguous()

bool ghidra::SplitVarnode::isAddrTiedContiguous ( Varnode lo,
Varnode hi,
Address res 
)
static

Return true if the given pieces can be melded into a contiguous storage location.

The given Varnodes must be address tied, and their storage must line up, respecting their significance as pieces.

Parameters
lois the given least significant piece
hiis the given most significant piece
resis used to pass back the starting address of the contigous range
Returns
true if the pieces are address tied and form a contiguous range

References ghidra::Varnode::getAddr(), ghidra::Varnode::getOffset(), ghidra::Varnode::getSize(), ghidra::Varnode::getSpace(), ghidra::SymbolEntry::getSymbol(), ghidra::Varnode::getSymbolEntry(), hi, ghidra::Varnode::isAddrTied(), ghidra::AddrSpace::isBigEndian(), and lo.

Referenced by ghidra::RuleDoubleOut::applyOp(), createJoinedWhole(), and ghidra::CopyForceForm::verify().

◆ isWholeFeasible()

bool ghidra::SplitVarnode::isWholeFeasible ( PcodeOp existop)

Does a whole Varnode already exist or can it be created before the given PcodeOp.

The whole Varnode must be defined or definable before the given PcodeOp. This is checked by comparing the given PcodeOp to the defining PcodeOp and block for this, which are filled in if they weren't before.

Parameters
existopis the given PcodeOp
Returns
true if a whole Varnode exists or can be defined before the given PcodeOp

References defblock, defpoint, findDefinitionPoint(), findWholeBuiltFromPieces(), findWholeSplitToPieces(), ghidra::FlowBlock::getImmedDom(), ghidra::SeqNum::getOrder(), ghidra::PcodeOp::getParent(), ghidra::PcodeOp::getSeqNum(), hi, isConstant(), ghidra::Varnode::isConstant(), and lo.

Referenced by prepareBinaryOp(), prepareBoolOp(), prepareIndirectOp(), and prepareShiftOp().

◆ isWholePhiFeasible()

bool ghidra::SplitVarnode::isWholePhiFeasible ( FlowBlock bl)

Does a whole Varnode already exist or can it be created before the given basic block.

This is similar to isWholeFeasible(), but the whole must be defined before the end of the given basic block.

Parameters
blis the given basic block
Returns
true if a whole Varnode exists or can be defined before the end of the given basic block

References defblock, findDefinitionPoint(), findWholeBuiltFromPieces(), findWholeSplitToPieces(), ghidra::FlowBlock::getImmedDom(), and isConstant().

Referenced by preparePhiOp().

◆ otherwiseEmpty()

bool ghidra::SplitVarnode::otherwiseEmpty ( PcodeOp branchop)
static

Return true if the basic block containing the given CBRANCH PcodeOp performs no other operation.

The basic block can contain the CBRANCH and the one PcodeOp producing the boolean value. Otherwise false is returned.

Parameters
branchopis the given CBRANCH
Returns
true if the parent basic block performs only the branch operation

References ghidra::BlockBasic::beginOp(), ghidra::BlockBasic::endOp(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::PcodeOp::getParent(), ghidra::Varnode::isWritten(), and ghidra::FlowBlock::sizeIn().

◆ prepareBinaryOp()

PcodeOp * ghidra::SplitVarnode::prepareBinaryOp ( SplitVarnode out,
SplitVarnode in1,
SplitVarnode in2 
)
static

Check that the logical version of a (generic) binary double-precision operation can be created.

This checks only the most generic aspects of the calculation. The input and output whole Varnodes must already exist or be creatable. The point where the output Varnode must exist is identified and returned. If the binary operation cannot be created, null is returned.

Parameters
outis the output of the binary operation
in1is the first input of the binary operation
in2is the second input of the binary operation
Returns
the first PcodeOp where the output whole must exist

References findOutExist(), and isWholeFeasible().

◆ prepareBoolOp()

bool ghidra::SplitVarnode::prepareBoolOp ( SplitVarnode in1,
SplitVarnode in2,
PcodeOp testop 
)
static

Make sure input operands of a double precision compare operation are compatible.

Do generic testing that the input whole Varnodes can be created. If they can be created, return true.

Parameters
in1is the first input operand of the double precision compare operation
in2is the second input operand of the double precision compare operation
Returns
true if the logical transformation can be performed

References isWholeFeasible().

◆ prepareIndirectOp()

bool ghidra::SplitVarnode::prepareIndirectOp ( SplitVarnode in,
PcodeOp affector 
)
static

Check that the logical version of a CPUI_INDIRECT operation can be created.

This checks only the most generic aspects of the calculation. The input whole Varnode must already exist or be creatable. If the INDIRECT operation cannot be created, false is returned.

Parameters
inis the (first) input operand of the INDIRECT
Returns
true if the logical version of the CPUI_INDIRECT can be created

References isWholeFeasible().

◆ preparePhiOp()

PcodeOp * ghidra::SplitVarnode::preparePhiOp ( SplitVarnode out,
vector< SplitVarnode > &  inlist 
)
static

Check that the logical version of a CPUI_MULTIEQUAL operation can be created.

This checks only the most generic aspects of the calculation. The input and output whole Varnodes must already exist or be creatable. The point where the output Varnode must exist is identified and returned. If the MULTIEQUAL operation cannot be created, null is returned.

Parameters
outis the output of the MULTIEQUAL operation
inlistis a vector of the input operands to the MULTIEQUAL
Returns
the first PcodeOp where the output whole must exist

References ghidra::PcodeOp::code(), ghidra::CPUI_MULTIEQUAL, findEarliestSplitPoint(), ghidra::FlowBlock::getIn(), ghidra::PcodeOp::getParent(), and isWholePhiFeasible().

◆ prepareShiftOp()

PcodeOp * ghidra::SplitVarnode::prepareShiftOp ( SplitVarnode out,
SplitVarnode in 
)
static

Make sure input and output operands of a double precision shift operation are compatible.

Do generic testing that the input and output whole Varnodes can be created. Calculate the PcodeOp where the output whole must exist and return it. If logical operation cannot be created, return null.

Parameters
outis the output of the double precision shift operation
inis the (first) input operand of the double precision shift operation
Returns
the PcodeOp where output whole must exist or null

References findOutExist(), and isWholeFeasible().

◆ replaceBoolOp()

void ghidra::SplitVarnode::replaceBoolOp ( Funcdata data,
PcodeOp boolop,
SplitVarnode in1,
SplitVarnode in2,
OpCode  opc 
)
static

Rewrite a double precision boolean operation by replacing the input pieces with unified Varnodes.

This assumes we checked that the transformation is possible by calling the various verify and prepare methods. The inputs to the given PcodeOp producing the final boolean value are replaced with new logical Varnodes, and the opcode is updated. The output Varnode is not affected.

Parameters
datais the function owning the operation
boolopis the given PcodeOp producing the final boolean value
in1is the first input to the operation
in2is the second input to the operation
opcis the opcode of the operation

References findCreateWhole(), getWhole(), ghidra::Funcdata::opSetInput(), and ghidra::Funcdata::opSetOpcode().

◆ replaceCopyForce()

void ghidra::SplitVarnode::replaceCopyForce ( Funcdata data,
const Address addr,
SplitVarnode in,
PcodeOp copylo,
PcodeOp copyhi 
)
static

Rewrite the double precision version of a COPY to an address forced Varnode.

This assumes that we have checked that the transformation is possible. The logical input must already exist, and after this method is called, the logical output will also exist. The original COPY pieces are explicitly destroyed.

Parameters
datais the function owning the COPYs
addris the storage address being COPYed
inis the input to the COPYs
copylois the original least significant COPY
copyhiis the original most significant COPY

References ghidra::CPUI_COPY, ghidra::PcodeOp::getAddr(), ghidra::Varnode::getAddr(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::SeqNum::getOrder(), ghidra::PcodeOp::getSeqNum(), getSize(), getWhole(), ghidra::PcodeOp::isReturnCopy(), ghidra::Funcdata::markReturnCopy(), ghidra::Funcdata::newOp(), ghidra::Funcdata::newVarnodeOut(), ghidra::Funcdata::opDestroy(), ghidra::Funcdata::opInsertBefore(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), and ghidra::Varnode::setAddrForce().

Referenced by ghidra::CopyForceForm::applyRule().

◆ replaceIndirectOp()

void ghidra::SplitVarnode::replaceIndirectOp ( Funcdata data,
SplitVarnode out,
SplitVarnode in,
PcodeOp affector 
)
static

Rewrite a double precision INDIRECT operation by replacing the pieces with unified Varnodes.

This assumes that we have checked that the transformation is possible via the various verify and prepare methods. After this method is called, the logical input and output of the calculation will exist as real Varnodes.

Parameters
datais the function owning the operation
outis the output of the INDIRECT operation
inis the (first) operand of the INDIRECT
affectoris the second operand to the indirect, the PcodeOp producing the indirect affect

References buildHiFromWhole(), buildLoFromWhole(), ghidra::CPUI_INDIRECT, createJoinedWhole(), findCreateWhole(), ghidra::PcodeOp::getAddr(), getWhole(), ghidra::Funcdata::newOp(), ghidra::Funcdata::newVarnodeIop(), ghidra::Funcdata::opInsertBefore(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), and ghidra::Funcdata::opSetOutput().

◆ testContiguousPointers()

bool ghidra::SplitVarnode::testContiguousPointers ( PcodeOp most,
PcodeOp least,
PcodeOp *&  first,
PcodeOp *&  second,
AddrSpace *&  spc 
)
static

Verify that the pointers into the given LOAD/STORE PcodeOps address contiguous memory.

The two given PcodeOps must either both be LOADs or both be STOREs. The pointer for the first PcodeOp is labeled as the most significant piece of the contiguous whole, the second PcodeOp is labeled as the least significant piece. The p-code defining the pointers is examined to determine if the two memory regions being pointed at really form one contiguous region. If the regions are contiguous and the pointer labeling is valid, true is returned, the PcodeOps are sorted into first and second based on Address, and the address space of the memory region is passed back.

Parameters
mostis the given LOAD/STORE PcodeOp referring to the most significant region
leastis the given LOAD/STORE PcodeOp referring to the least significant region
firstis used to pass back the earliest of the address sorted PcodeOps
secondis used to pass back the latest of the address sorted PcodeOps
spcis used to pass back the LOAD address space
sizeresis used to pass back the combined LOAD size
Returns
true if the given PcodeOps are contiguous LOADs

References adjacentOffsets(), ghidra::PcodeOp::code(), ghidra::CPUI_LOAD, ghidra::PcodeOp::getIn(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), ghidra::Varnode::getSpaceFromConst(), ghidra::AddrSpace::isBigEndian(), and ghidra::Varnode::isFree().

Referenced by ghidra::RuleDoubleLoad::applyOp(), and ghidra::RuleDoubleStore::applyOp().

◆ verifyMultNegOne()

bool ghidra::SplitVarnode::verifyMultNegOne ( PcodeOp op)
static

Verify that the given PcodeOp is a CPUI_INT_MULT by -1.

The PcodeOp must be a CPUI_INT_MULT and the second operand must be a constant -1.

Parameters
opis the given PcodeOp
Returns
true if the PcodeOp is a multiple by -1

References ghidra::calc_mask(), ghidra::PcodeOp::code(), ghidra::CPUI_INT_MULT, ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::Varnode::getSize(), and ghidra::Varnode::isConstant().

◆ wholeList()

void ghidra::SplitVarnode::wholeList ( Varnode w,
vector< SplitVarnode > &  splitvec 
)
static

Create a list of all the possible pairs that contain the same logical value as the given Varnode.

The given Varnode is assumed to be the logical whole that is being used in a double precision calculation. At least one of the most or least significant pieces must be extracted from the whole and must be marked as a double precision piece.

Parameters
wis the given Varnode whole
splitvecis the container for holding any discovered SplitVarnodes

References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_SUBPIECE, ghidra::Varnode::endDescend(), findCopies(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), hi, ghidra::Varnode::isPrecisHi(), ghidra::Varnode::isPrecisLo(), lo, whole, and wholesize.

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


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