decompiler
1.0.0
|
Class for tracing changes of precision in floating point variables. More...
#include <subflow.hh>
Public Member Functions | |
SubfloatFlow (Funcdata *f, Varnode *root, int4 prec) | |
virtual bool | preserveAddress (Varnode *vn, int4 bitSize, int4 lsbOffset) const |
Should the address of the given Varnode be preserved when constructing a piece. More... | |
bool | doTrace (void) |
Trace logical value as far as possible. More... | |
Public Member Functions inherited from ghidra::TransformManager | |
TransformManager (Funcdata *f) | |
Constructor. | |
virtual | ~TransformManager (void) |
Destructor. | |
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. | |
Private Member Functions | |
TransformVar * | setReplacement (Varnode *vn) |
Create and return a placeholder associated with the given Varnode. More... | |
bool | traceForward (TransformVar *rvn) |
Try to trace logical variable through descendant Varnodes. More... | |
bool | traceBackward (TransformVar *rvn) |
Trace a logical value backward through defining op one level. More... | |
bool | processNextWork (void) |
Push the trace one hop from the placeholder at the top of the worklist. More... | |
Private Attributes | |
int4 | precision |
Number of bytes of precision in the logical flow. | |
int4 | terminatorCount |
Number of terminating nodes reachable via the root. | |
const FloatFormat * | format |
The floating-point format of the logical value. | |
vector< TransformVar * > | worklist |
Current list of placeholders that still need to be traced. | |
Additional Inherited Members | |
Static Public Member Functions inherited from ghidra::TransformManager | |
static bool | preexistingGuard (int4 slot, TransformVar *rvn) |
Should newPreexistingOp be called. More... | |
Class for tracing changes of precision in floating point variables.
It follows the flow of a logical lower precision value stored in higher precision locations and then rewrites the data-flow in terms of the lower precision, eliminating the precision conversions.
f | is the function being transformed |
root | is the start Varnode containing the logical value |
prec | is the precision to assume for the logical value |
References format, ghidra::Funcdata::getArch(), ghidra::Translate::getFloatFormat(), precision, setReplacement(), and ghidra::Architecture::translate.
bool ghidra::SubfloatFlow::doTrace | ( | void | ) |
Trace logical value as far as possible.
The interpretation that the root Varnode contains a logical value with smaller precision is pushed through the data-flow. If the interpretation is inconsistent, false is returned. Otherwise a transform is constructed that makes the smaller precision the explicit size of Varnodes within the data-flow.
References ghidra::TransformManager::clearVarnodeMarks(), format, processNextWork(), terminatorCount, and worklist.
Referenced by ghidra::RuleSubfloatConvert::applyOp().
|
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 from ghidra::TransformManager.
References ghidra::Varnode::isInput().
|
private |
Push the trace one hop from the placeholder at the top of the worklist.
The logical value for the value on top of the worklist stack is pushed back to the input Varnodes of the operation defining it. Then the value is pushed forward through all operations that read it.
Referenced by doTrace().
|
private |
Create and return a placeholder associated with the given Varnode.
Add the placeholder to the worklist if it hasn't been visited before
vn | is the given Varnode |
References ghidra::Datatype::getMetatype(), ghidra::Varnode::getOffset(), ghidra::Varnode::getSize(), ghidra::Datatype::getSize(), ghidra::Varnode::getType(), ghidra::Varnode::isAddrForce(), ghidra::Varnode::isConstant(), ghidra::Varnode::isFree(), ghidra::Varnode::isInput(), ghidra::Varnode::isMark(), ghidra::Varnode::isTypeLock(), ghidra::Varnode::setMark(), and ghidra::TYPE_PARTIALSTRUCT.
Referenced by ghidra::LaneDivide::buildMultiequal(), ghidra::LaneDivide::buildPiece(), ghidra::LaneDivide::buildRightShift(), ghidra::LaneDivide::buildStore(), SubfloatFlow(), ghidra::LaneDivide::traceBackward(), and ghidra::LaneDivide::traceForward().
|
private |
Trace a logical value backward through defining op one level.
Given an existing variable placeholder look at the op defining it and define placeholder variables for all its inputs. Put the new placeholders onto the worklist if appropriate.
rvn | is the given variable placeholder |
References ghidra::PcodeOp::code(), ghidra::CPUI_COPY, ghidra::CPUI_FLOAT_ABS, ghidra::CPUI_FLOAT_ADD, ghidra::CPUI_FLOAT_CEIL, ghidra::CPUI_FLOAT_DIV, ghidra::CPUI_FLOAT_FLOAT2FLOAT, ghidra::CPUI_FLOAT_FLOOR, ghidra::CPUI_FLOAT_INT2FLOAT, ghidra::CPUI_FLOAT_MULT, ghidra::CPUI_FLOAT_NEG, ghidra::CPUI_FLOAT_ROUND, ghidra::CPUI_FLOAT_SQRT, ghidra::CPUI_FLOAT_SUB, ghidra::CPUI_MULTIEQUAL, ghidra::TransformVar::getDef(), ghidra::Varnode::getDef(), ghidra::TransformOp::getIn(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::TransformVar::getOriginal(), ghidra::Varnode::getSize(), ghidra::Varnode::isConstant(), ghidra::Varnode::isFree(), and ghidra::PcodeOp::numInput().
Referenced by ghidra::LaneDivide::processNextWork().
|
private |
Try to trace logical variable through descendant Varnodes.
Given a Varnode placeholder, look at all descendent PcodeOps and create placeholders for the op and its output Varnode. If appropriate add the output placeholder to the worklist.
rvn | is the given Varnode placeholder |
References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_COPY, ghidra::CPUI_FLOAT_ABS, ghidra::CPUI_FLOAT_ADD, ghidra::CPUI_FLOAT_CEIL, ghidra::CPUI_FLOAT_DIV, ghidra::CPUI_FLOAT_EQUAL, ghidra::CPUI_FLOAT_FLOAT2FLOAT, ghidra::CPUI_FLOAT_FLOOR, ghidra::CPUI_FLOAT_LESS, ghidra::CPUI_FLOAT_LESSEQUAL, ghidra::CPUI_FLOAT_MULT, ghidra::CPUI_FLOAT_NAN, ghidra::CPUI_FLOAT_NEG, ghidra::CPUI_FLOAT_NOTEQUAL, ghidra::CPUI_FLOAT_ROUND, ghidra::CPUI_FLOAT_SQRT, ghidra::CPUI_FLOAT_SUB, ghidra::CPUI_FLOAT_TRUNC, ghidra::CPUI_MULTIEQUAL, ghidra::Varnode::endDescend(), ghidra::PcodeOp::getIn(), ghidra::TransformVar::getOriginal(), ghidra::PcodeOp::getOut(), ghidra::PcodeOp::getRepeatSlot(), ghidra::Varnode::getSize(), ghidra::PcodeOp::getSlot(), ghidra::Varnode::isMark(), and ghidra::PcodeOp::numInput().
Referenced by ghidra::LaneDivide::processNextWork().