|
decompiler 1.0.0
|
Simplify expressions explicitly using ZPULL and SPULL p-code ops. More...
#include <bitfield.hh>
Public Member Functions | |
| RulePullAbsorb (const string &g) | |
| Constructor. | |
| virtual Rule * | clone (const ActionGroupList &grouplist) const |
| Clone the Rule. | |
| virtual void | getOpList (vector< uint4 > &oplist) const |
| List of op codes this rule operates on. | |
| virtual int4 | applyOp (PcodeOp *op, Funcdata &data) |
| Attempt to apply this Rule. | |
Public Member Functions inherited from ghidra::Rule | |
| Rule (const string &g, uint4 fl, const string &nm) | |
| Construct given group, properties name. | |
| virtual | ~Rule (void) |
| Destructor. | |
| const string & | getName (void) const |
| Return the name of this Rule. | |
| const string & | getGroup (void) const |
| Return the group this Rule belongs to. | |
| uint4 | getNumTests (void) |
| Get number of attempted applications. | |
| uint4 | getNumApply (void) |
| Get number of successful applications. | |
| void | setBreak (uint4 tp) |
| Set a breakpoint on this Rule. | |
| void | clearBreak (uint4 tp) |
| Clear a breakpoint on this Rule. | |
| void | clearBreakPoints (void) |
| Clear all breakpoints on this Rule. | |
| void | turnOnWarnings (void) |
| Enable warnings for this Rule. | |
| void | turnOffWarnings (void) |
| Disable warnings for this Rule. | |
| bool | isDisabled (void) const |
| Return true if this Rule is disabled. | |
| void | setDisable (void) |
| Disable this Rule (within its pool) | |
| void | clearDisable (void) |
| Enable this Rule (within its pool) | |
| bool | checkActionBreak (void) |
| Check if an action breakpoint is turned on. | |
| uint4 | getBreakPoint (void) const |
| Return breakpoint toggles. | |
| virtual void | reset (Funcdata &data) |
| Reset this Rule. | |
| virtual void | resetStats (void) |
| Reset Rule statistics. | |
| virtual void | printStatistics (ostream &s) const |
| Print statistics for this Rule. | |
Private Member Functions | |
| int4 | absorbRight (Funcdata &data, PcodeOp *rightOp, PcodeOp *pullOp) |
Perform transforms involving the expression: field >> #c | |
| int4 | absorbRightAndCompZero (Funcdata &data, PcodeOp *rightOp, PcodeOp *andOp, PcodeOp *pullOp) |
Perform transform: ((sfield >> #n) & #1) == #0 => #0 <= sfield | |
| int4 | absorbLeft (Funcdata &data, PcodeOp *leftOp, PcodeOp *pullOp) |
Perform transforms involving the expression: field << #c | |
| int4 | absorbLeftRight (Funcdata &data, PcodeOp *rightOp, PcodeOp *leftOp, PcodeOp *pullOp) |
Perform the transform: (field << #c) >> #d => field >> (#d-#c) | |
| int4 | absorbLeftAnd (Funcdata &data, PcodeOp *andOp, PcodeOp *leftOp, PcodeOp *pullOp) |
Perform the transform: ((field << #c) & #b) == #d => (field & #b>>c) == #d>>c | |
| int4 | absorbAnd (Funcdata &data, PcodeOp *andOp, PcodeOp *pullOp) |
Perform transform: field & #signbit == #0 => field < 0 | |
| int4 | absorbCompare (Funcdata &data, PcodeOp *compOp, PcodeOp *leftOp, PcodeOp *pullOp) |
| Perform transforms involving comparisons: INT_LESS, INT_SLESS. | |
| int4 | absorbExt (Funcdata &data, PcodeOp *extOp, PcodeOp *pullOp) |
Perform transform: y = SEXT( SPULL( x, #p, #n ) ) => y = SPULL( x, #p, #n ) | |
| int4 | absorbSubpiece (Funcdata &data, PcodeOp *subOp, PcodeOp *pullOp) |
Perform transform: y = SUB( PULL( x, #p, #n ) ) => y = PULL( x, #p, #n ) | |
| int4 | absorbCompZero (Funcdata &data, PcodeOp *compOp, PcodeOp *pullOp) |
Perform transform: ZPULL( x, #p, #1) != #0 => ZPULL(x, #p, #1) | |
Additional Inherited Members | |
Public Types inherited from ghidra::Rule | |
| enum | typeflags { type_disable = 1 , rule_debug = 2 , warnings_on = 4 , warnings_given = 8 } |
| Properties associated with a Rule. More... | |
Simplify expressions explicitly using ZPULL and SPULL p-code ops.
|
private |
Perform transform: field & #signbit == #0 => field < 0
| data | is the function |
| andOp | is the INT_AND op |
| pullOp | is the ZPULL or SPULL op |
References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::Varnode::constantMatch(), ghidra::CPUI_INT_EQUAL, ghidra::CPUI_INT_NOTEQUAL, ghidra::CPUI_INT_SLESS, ghidra::CPUI_INT_SLESSEQUAL, ghidra::CPUI_SPULL, ghidra::Funcdata::destroyVarnodeRecursive(), ghidra::Varnode::endDescend(), ghidra::Funcdata::getArch(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), ghidra::Varnode::getType(), ghidra::Varnode::isConstant(), ghidra::Funcdata::newConstant(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), ghidra::TypeFactory::resizeInteger(), ghidra::Architecture::types, and ghidra::Varnode::updateType().
Referenced by applyOp().
|
private |
Perform transforms involving comparisons: INT_LESS, INT_SLESS.
Perform transforms:
(boolfield << #c) s< #0 => boolfield#0 s< (boolfield << #c) => !boolfield(field << #c) < (#d<<#c) => field < #d(#d<<#c) < (field << #c) => #d < field| data | is the function |
| compOp | is the INT_LESS or INT_SLESS op |
| leftOp | is the INT_LEFT op |
| pullOp | is the ZPULL or SPULL op |
References ghidra::calc_mask(), ghidra::PcodeOp::code(), ghidra::CPUI_BOOL_NEGATE, ghidra::CPUI_INT_SLESS, ghidra::Funcdata::destroyVarnodeRecursive(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), ghidra::Varnode::isConstant(), ghidra::Funcdata::newConstant(), ghidra::Funcdata::opRemoveInput(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), and ghidra::Funcdata::totalReplace().
Referenced by absorbLeft(), and applyOp().
|
private |
Perform transform: ZPULL( x, #p, #1) != #0 => ZPULL(x, #p, #1)
Also transform the variant ZPULL( x, #p, #1) == #0 => !ZPULL(x, #p, #1)
| data | is the function |
| compOp | is the INT_EQUAL or INT_NOTEQUAL op |
| pullOp | is the ZPULL or SPULL op |
References ghidra::PcodeOp::code(), ghidra::Varnode::constantMatch(), ghidra::CPUI_BOOL_NEGATE, ghidra::CPUI_INT_EQUAL, ghidra::CPUI_SPULL, ghidra::Funcdata::deleteVarnode(), ghidra::Funcdata::destroyVarnodeRecursive(), ghidra::Varnode::getAddr(), ghidra::Funcdata::getArch(), ghidra::TypeFactory::getBase(), ghidra::PcodeOp::getIn(), ghidra::Datatype::getMetatype(), ghidra::Varnode::getOffset(), ghidra::BitFieldExpression::getPullField(), ghidra::Varnode::getSize(), ghidra::Varnode::getSpace(), ghidra::Varnode::isAddrTied(), ghidra::AddrSpace::isBigEndian(), ghidra::Varnode::loneDescend(), ghidra::Funcdata::newVarnodeOut(), ghidra::Funcdata::opInsertInput(), ghidra::Funcdata::opRemoveInput(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), ghidra::Funcdata::opUnsetOutput(), ghidra::TypeBitField::type, ghidra::TYPE_BOOL, ghidra::Architecture::types, and ghidra::Varnode::updateType().
Referenced by applyOp().
|
private |
Perform transform: y = SEXT( SPULL( x, #p, #n ) ) => y = SPULL( x, #p, #n )
Also transform: y = ZEXT( ZPULL( x, #p, #n ) ) => y = ZPULL( x, #p, #n )
| data | is the function |
| extOp | is the INT_SEXT or INT_ZEXT op |
| pullOp | is the ZPULL or SPULL op |
References ghidra::PcodeOp::code(), ghidra::CPUI_INT_SEXT, ghidra::CPUI_SPULL, ghidra::Funcdata::destroyVarnodeRecursive(), ghidra::PcodeOp::getIn(), ghidra::Varnode::loneDescend(), ghidra::Funcdata::opInsertInput(), ghidra::Funcdata::opSetInput(), and ghidra::Funcdata::opSetOpcode().
Referenced by applyOp().
|
private |
Perform transforms involving the expression: field << #c
| data | is the function |
| leftOp | is the INT_LEFT op |
| pullOp | is the ZPULL or SPULL op |
References absorbCompare(), absorbLeftAnd(), absorbLeftRight(), ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_INT_AND, ghidra::CPUI_INT_RIGHT, ghidra::CPUI_INT_SLESS, ghidra::Varnode::endDescend(), and ghidra::PcodeOp::getOut().
Referenced by applyOp().
|
private |
Perform the transform: ((field << #c) & #b) == #d => (field & #b>>c) == #d>>c
| data | is the function |
| andOp | is the INT_AND op |
| leftOp | is the INT_LEFT op |
| pullOp | is the ZPULL or SPULL op |
References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_INT_EQUAL, ghidra::CPUI_INT_NOTEQUAL, ghidra::Funcdata::destroyVarnodeRecursive(), ghidra::Varnode::endDescend(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), ghidra::Varnode::getType(), ghidra::Varnode::isConstant(), ghidra::Funcdata::newConstant(), ghidra::Funcdata::opSetInput(), and ghidra::Varnode::updateType().
Referenced by absorbLeft().
|
private |
Perform the transform: (field << #c) >> #d => field >> (#d-#c)
| data | is the function |
| rightOp | is the INT_RIGHT op |
| leftOp | is the INT_LEFT op |
| pullOp | is the ZPULL or SPULL op |
References ghidra::CPUI_INT_LEFT, ghidra::Funcdata::destroyVarnodeRecursive(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), ghidra::Varnode::isConstant(), ghidra::Funcdata::newConstant(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), and ghidra::Funcdata::totalReplace().
Referenced by absorbLeft().
|
private |
Perform transforms involving the expression: field >> #c
| data | is the function |
| rightOp | is the INT_RIGHT or INT_SRIGHT op |
| pullOp | is the ZPULL or SPULL op |
References absorbRightAndCompZero(), ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_INT_AND, ghidra::Varnode::endDescend(), and ghidra::PcodeOp::getOut().
Referenced by applyOp().
|
private |
Perform transform: ((sfield >> #n) & #1) == #0 => #0 <= sfield
Perform the variant: ((sfield >> #n) & #1) != #0 => sfield < #0
| data | is the function |
| rightOp | is the INT_RIGHT or INT_SRIGHT op |
| andOp | is the INT_AND |
| pullOp | is the ZPULL or SPULL op |
References ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::Varnode::constantMatch(), ghidra::CPUI_INT_EQUAL, ghidra::CPUI_INT_LESSEQUAL, ghidra::CPUI_INT_NOTEQUAL, ghidra::CPUI_INT_SLESS, ghidra::CPUI_SPULL, ghidra::Funcdata::destroyVarnodeRecursive(), ghidra::Varnode::endDescend(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getOut(), ghidra::Varnode::isConstant(), ghidra::Funcdata::opSetInput(), and ghidra::Funcdata::opSetOpcode().
Referenced by absorbRight().
|
private |
Perform transform: y = SUB( PULL( x, #p, #n ) ) => y = PULL( x, #p, #n )
| data | is the function |
| subOp | is the SUBPIECE op |
| pullOp | is the ZPULL or SPULL op |
References ghidra::PcodeOp::code(), ghidra::Funcdata::destroyVarnodeRecursive(), ghidra::PcodeOp::getIn(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), ghidra::Varnode::loneDescend(), ghidra::Funcdata::opInsertInput(), ghidra::Funcdata::opSetInput(), and ghidra::Funcdata::opSetOpcode().
Referenced by applyOp().
Attempt to apply this Rule.
This method contains the main logic for applying the Rule. It must use a given PcodeOp as the point at which the Rule applies. If it does apply, changes are made directly to the function and 1 (non-zero) is returned, otherwise 0 is returned.
Reimplemented from ghidra::Rule.
References absorbAnd(), absorbCompare(), absorbCompZero(), absorbExt(), absorbLeft(), absorbRight(), absorbSubpiece(), ghidra::Varnode::beginDescend(), ghidra::PcodeOp::code(), ghidra::CPUI_INT_AND, ghidra::CPUI_INT_EQUAL, ghidra::CPUI_INT_LEFT, ghidra::CPUI_INT_LESS, ghidra::CPUI_INT_NOTEQUAL, ghidra::CPUI_INT_RIGHT, ghidra::CPUI_INT_SEXT, ghidra::CPUI_INT_SLESS, ghidra::CPUI_INT_SRIGHT, ghidra::CPUI_INT_ZEXT, ghidra::CPUI_SUBPIECE, ghidra::Varnode::endDescend(), and ghidra::PcodeOp::getOut().
|
inlinevirtual |
Clone the Rule.
If this Rule is a member of one of the groups in the grouplist, this returns a clone of the Rule, otherwise NULL is returned.
| grouplist | is the list of groups being cloned |
Implements ghidra::Rule.
References ghidra::ActionGroupList::contains(), and ghidra::Rule::getGroup().
|
virtual |
List of op codes this rule operates on.
Populate the given array with all possible OpCodes this Rule might apply to. By default, this method returns all possible OpCodes
| oplist | is the array to populate |
Reimplemented from ghidra::Rule.
References ghidra::CPUI_SPULL, and ghidra::CPUI_ZPULL.