decompiler
1.0.0
|
Class for splitting larger registers holding smaller logical lanes. More...
#include <transform.hh>
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... | |
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. | |
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 | |
Funcdata * | fd |
Function being operated on. | |
map< int4, TransformVar * > | pieceMap |
Map from large Varnodes to their new pieces. | |
list< TransformVar > | newVarnodes |
Storage for Varnode placeholder nodes. | |
list< TransformOp > | newOps |
Storage for PcodeOp placeholder nodes. | |
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.
|
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.
|
private |
Create a Varnode for each placeholder.
Record any input vars in the given container
inputList | will hold any inputs |
References ghidra::TransformVar::createReplacement(), ghidra::TransformVar::flags, ghidra::TransformVar::input_duplicate, ghidra::Varnode::isInput(), ghidra::Varnode::isMark(), ghidra::TransformVar::piece, ghidra::Varnode::setMark(), ghidra::TransformVar::split_terminator, ghidra::TransformVar::type, and ghidra::TransformVar::vn.
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.
vn | is the big Varnode containing the logical value |
bitSize | is the size of the logical value in bytes |
lsbOffset | is the signficance offset of the logical value within the Varnode |
References ghidra::TransformVar::bitSize, ghidra::Varnode::getCreateIndex(), and ghidra::TransformVar::val.
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.
vn | is the preexisting Varnode to find a placeholder for |
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().
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.
References ghidra::Varnode::getCreateIndex().
Referenced by ghidra::LaneDivide::setReplacement().
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.
vn | is the big Varnode to split |
description | describes all the possible lanes |
numLanes | is the number of lanes in the subset |
startLane | is the starting (least significant) lane in the subset |
References ghidra::Varnode::getCreateIndex().
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.
size | is the size in bytes of the new constant |
lsbOffset | is the number of bits to strip off of the existing value |
val | is the value of the constant |
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().
TransformVar * ghidra::TransformManager::newIop | ( | Varnode * | vn | ) |
Make placeholder for special iop constant.
Used for creating INDIRECT placeholders.
vn | is the original iop parameter to the INDIRECT |
References ghidra::TransformVar::constant_iop, ghidra::Varnode::getOffset(), ghidra::Varnode::getSize(), and ghidra::TransformVar::initialize().
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.
numParams | is the number of Varnode inputs intended for the new op |
opc | is the opcode of the new op |
follow | is the placeholder for the op that follow the new op when it is created |
References ghidra::TransformOp::input, ghidra::TransformOp::op, and ghidra::PcodeOp::special.
Referenced by ghidra::LaneDivide::buildLoad(), ghidra::SplitDatatype::buildPointers(), and ghidra::LaneDivide::buildStore().
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.
numParams | is the number of Varnode inputs intended for the new op |
opc | is the opcode of the new op |
replace | is the existing op the new op will replace |
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().
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.
vn | is the large Varnode |
bitSize | is the size of the logical value in bits |
lsbOffset | is the number of least significant bits of the Varnode dropped from the value |
References ghidra::TransformVar::flags, ghidra::Varnode::getCreateIndex(), ghidra::TransformVar::initialize(), ghidra::TransformVar::piece, ghidra::TransformVar::piece_temp, and ghidra::TransformVar::split_terminator.
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.
numParams | is the number of Varnode inputs intended for the transformed op |
opc | is the opcode of the transformed op |
originalOp | is the preexisting PcodeOp |
References ghidra::TransformOp::op, ghidra::TransformOp::op_preexisting, and ghidra::PcodeOp::special.
Referenced by ghidra::LaneDivide::traceForward().
TransformVar * ghidra::TransformManager::newPreexistingVarnode | ( | Varnode * | vn | ) |
Make placeholder for preexisting Varnode.
vn | is the preexisting Varnode to create a placeholder for |
References ghidra::TransformVar::flags, ghidra::Varnode::getCreateIndex(), ghidra::Varnode::getSize(), ghidra::TransformVar::initialize(), ghidra::TransformVar::preexisting, and ghidra::TransformVar::split_terminator.
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.
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().
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.
vn | is the big Varnode to split |
description | gives a list of potentional lanes |
numLanes | is the number of lanes in the subset |
startLane | is the starting (least significant) lane in the subset |
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.
TransformVar * ghidra::TransformManager::newUnique | ( | int4 | size | ) |
Make placeholder for new unique space Varnode.
size | is the size in bytes of the new unique Varnode |
References ghidra::TransformVar::initialize(), and ghidra::TransformVar::normal_temp.
Referenced by ghidra::LaneDivide::buildLoad(), and ghidra::LaneDivide::buildStore().
|
inline |
Mark given variable as input to given op.
rop | is the given placeholder op whose input is set |
rvn | is the placeholder variable to set |
slot | is 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().
|
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.
rop | is the given op |
rvn | is 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().
|
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.
slot | is the incoming slot along which the op is visited |
rvn | is the other input |
References ghidra::TransformVar::piece, ghidra::TransformVar::piece_temp, and ghidra::TransformVar::type.
|
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.
vn | is the given Varnode |
bitSize | is the logical size of the Varnode piece being constructed |
lsbOffset | is the least significant bit position of the logical value within the given Varnode |
Reimplemented in ghidra::SubfloatFlow.
References ghidra::Varnode::getSpace(), ghidra::AddrSpace::getType(), and ghidra::IPTR_INTERNAL.
|
private |
Handle some special PcodeOp marking If a PcodeOp is an INDIRECT creation, we need to do special marking of the op and Varnodes.
rop | is 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.
|
private |
Remove old input Varnodes, mark new input Varnodes.
Remove all input Varnodes from the given container. Mark all the replacement Varnodes as inputs.
inputList | is the given container of input placeholders |
References ghidra::TransformVar::flags, ghidra::TransformVar::input_duplicate, ghidra::TransformVar::replacement, and ghidra::TransformVar::vn.