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 |
|
private |
Create a Varnode for each placeholder.
Record any input vars in the given container
inputList | will hold any inputs |
References TransformVar::createReplacement(), fd, TransformVar::flags, TransformVar::input_duplicate, Varnode::isInput(), Varnode::isMark(), newVarnodes, TransformVar::piece, pieceMap, Varnode::setMark(), TransformVar::split_terminator, TransformVar::type, and TransformVar::vn.
Referenced by apply().
TransformVar * 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 TransformVar::bitSize, Varnode::getCreateIndex(), newPiece(), pieceMap, and TransformVar::val.
Referenced by SubfloatFlow::setReplacement().
TransformVar * 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 Varnode::getCreateIndex(), Varnode::getOffset(), Varnode::getSize(), Varnode::isConstant(), newConstant(), newPreexistingVarnode(), and pieceMap.
Referenced by LaneDivide::buildLoad(), LaneDivide::buildPiece(), LaneDivide::buildStore(), and SubfloatFlow::traceBackward().
TransformVar * 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 Varnode::getCreateIndex(), newSplit(), and pieceMap.
Referenced by LaneDivide::setReplacement().
TransformVar * 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 Varnode::getCreateIndex(), newSplit(), and pieceMap.
TransformVar * 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 calc_mask(), TransformVar::constant, TransformVar::initialize(), and newVarnodes.
Referenced by LaneDivide::buildLoad(), LaneDivide::buildRightShift(), LaneDivide::buildStore(), getPreexistingVarnode(), SubfloatFlow::setReplacement(), SubfloatFlow::traceBackward(), and LaneDivide::traceForward().
TransformVar * 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 TransformVar::constant_iop, Varnode::getOffset(), Varnode::getSize(), TransformVar::initialize(), and newVarnodes.
TransformOp * 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 TransformOp::input, newOps, TransformOp::op, and PcodeOp::special.
Referenced by LaneDivide::buildLoad(), and LaneDivide::buildStore().
TransformOp * 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 newOps, TransformOp::op, TransformOp::op_replacement, and PcodeOp::special.
Referenced by LaneDivide::buildBinaryOp(), LaneDivide::buildLoad(), LaneDivide::buildMultiequal(), LaneDivide::buildPiece(), LaneDivide::buildRightShift(), LaneDivide::buildStore(), LaneDivide::buildUnaryOp(), SubfloatFlow::traceBackward(), and SubfloatFlow::traceForward().
TransformVar * 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 TransformVar::flags, Varnode::getCreateIndex(), TransformVar::initialize(), TransformVar::piece, TransformVar::piece_temp, pieceMap, preserveAddress(), and TransformVar::split_terminator.
Referenced by getPiece(), and SubfloatFlow::setReplacement().
TransformOp * 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 newOps, TransformOp::op, TransformOp::op_preexisting, and PcodeOp::special.
Referenced by SubfloatFlow::traceForward(), and LaneDivide::traceForward().
TransformVar * TransformManager::newPreexistingVarnode | ( | Varnode * | vn | ) |
Make placeholder for preexisting Varnode.
vn | is the preexisting Varnode to create a placeholder for |
References TransformVar::flags, Varnode::getCreateIndex(), Varnode::getSize(), TransformVar::initialize(), pieceMap, TransformVar::preexisting, and TransformVar::split_terminator.
Referenced by getPreexistingVarnode(), and SubfloatFlow::setReplacement().
TransformVar * 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 calc_mask(), TransformVar::constant, TransformVar::flags, Varnode::getCreateIndex(), LaneDescription::getNumLanes(), Varnode::getOffset(), LaneDescription::getPosition(), LaneDescription::getSize(), TransformVar::initialize(), Varnode::isConstant(), TransformVar::piece, TransformVar::piece_temp, pieceMap, preserveAddress(), and TransformVar::split_terminator.
Referenced by getSplit(), and LaneDivide::setReplacement().
TransformVar * 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 calc_mask(), TransformVar::constant, TransformVar::flags, Varnode::getCreateIndex(), Varnode::getOffset(), LaneDescription::getPosition(), LaneDescription::getSize(), TransformVar::initialize(), Varnode::isConstant(), TransformVar::piece, TransformVar::piece_temp, pieceMap, preserveAddress(), and TransformVar::split_terminator.
TransformVar * TransformManager::newUnique | ( | int4 | size | ) |
Make placeholder for new unique space Varnode.
size | is the size in bytes of the new unique Varnode |
References TransformVar::initialize(), newVarnodes, and TransformVar::normal_temp.
Referenced by LaneDivide::buildLoad(), and 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 TransformOp::input.
Referenced by LaneDivide::buildBinaryOp(), LaneDivide::buildLoad(), LaneDivide::buildMultiequal(), LaneDivide::buildPiece(), LaneDivide::buildRightShift(), LaneDivide::buildStore(), LaneDivide::buildUnaryOp(), SubfloatFlow::traceBackward(), SubfloatFlow::traceForward(), and 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 TransformVar::def, and TransformOp::output.
Referenced by LaneDivide::buildBinaryOp(), LaneDivide::buildLoad(), LaneDivide::buildMultiequal(), LaneDivide::buildPiece(), LaneDivide::buildRightShift(), LaneDivide::buildStore(), LaneDivide::buildUnaryOp(), SubfloatFlow::traceBackward(), and SubfloatFlow::traceForward().
|
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 TransformVar::piece, TransformVar::piece_temp, and TransformVar::type.
Referenced by SubfloatFlow::traceForward().
|
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 SubfloatFlow.
References Varnode::getSpace(), AddrSpace::getType(), and IPTR_INTERNAL.
Referenced by newPiece(), and newSplit().
|
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 fd, TransformOp::indirect_creation, TransformOp::indirect_creation_possible_out, Funcdata::markIndirectCreation(), TransformOp::replacement, and TransformOp::special.
Referenced by placeInputs().
|
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 Funcdata::deleteVarnode(), fd, TransformVar::flags, TransformVar::input_duplicate, TransformVar::replacement, Funcdata::setInputVarnode(), and TransformVar::vn.
Referenced by apply().