mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-2470 Support for partial enums
This commit is contained in:
parent
d5f4d3b9bc
commit
55a026b3ba
21 changed files with 1176 additions and 706 deletions
|
@ -18,7 +18,8 @@
|
|||
#ifndef __SUBFLOW_HH__
|
||||
#define __SUBFLOW_HH__
|
||||
|
||||
#include "funcdata.hh"
|
||||
#include "ruleaction.hh"
|
||||
#include "transform.hh"
|
||||
|
||||
namespace ghidra {
|
||||
|
||||
|
@ -128,6 +129,89 @@ public:
|
|||
void doReplacement(void); ///< Perform the discovered transform, making logical values explicit
|
||||
};
|
||||
|
||||
/// \brief Perform SubVariableFlow analysis triggered by INT_AND
|
||||
class RuleSubvarAnd : public Rule {
|
||||
public:
|
||||
RuleSubvarAnd(const string &g) : Rule( g, 0, "subvar_and") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleSubvarAnd(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief Perform SubVariableFlow analysis triggered by SUBPIECE
|
||||
class RuleSubvarSubpiece : public Rule {
|
||||
public:
|
||||
RuleSubvarSubpiece(const string &g) : Rule( g, 0, "subvar_subpiece") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleSubvarSubpiece(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief Perform SubvariableFlow analysis triggered by testing of a single bit
|
||||
///
|
||||
/// Given a comparison (INT_EQUAL or INT_NOTEEQUAL_ to a constant,
|
||||
/// check that input has only 1 bit that can possibly be non-zero
|
||||
/// and that the constant is testing this. This then triggers
|
||||
/// the full SubvariableFlow analysis.
|
||||
class RuleSubvarCompZero : public Rule {
|
||||
public:
|
||||
RuleSubvarCompZero(const string &g) : Rule( g, 0, "subvar_compzero") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleSubvarCompZero(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief Perform SubvariableFlow analysis triggered by INT_RIGHT
|
||||
///
|
||||
/// If the INT_RIGHT input has only 1 bit that can possibly be non-zero
|
||||
/// and it is getting shifted into the least significant bit position,
|
||||
/// trigger the full SubvariableFlow analysis.
|
||||
class RuleSubvarShift : public Rule {
|
||||
public:
|
||||
RuleSubvarShift(const string &g) : Rule( g, 0, "subvar_shift") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleSubvarShift(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief Perform SubvariableFlow analysis triggered by INT_ZEXT
|
||||
class RuleSubvarZext : public Rule {
|
||||
public:
|
||||
RuleSubvarZext(const string &g) : Rule( g, 0, "subvar_zext") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleSubvarZext(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief Perform SubvariableFlow analysis triggered by INT_SEXT
|
||||
class RuleSubvarSext : public Rule {
|
||||
int4 isaggressive; ///< Is it guaranteed the root is a sub-variable needing to be trimmed
|
||||
public:
|
||||
RuleSubvarSext(const string &g) : Rule( g, 0, "subvar_sext") { isaggressive = false; } ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleSubvarSext(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
virtual void reset(Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief Class for splitting up Varnodes that hold 2 logical variables
|
||||
///
|
||||
/// Starting from a \e root Varnode provided to the constructor, \b this class looks for data-flow
|
||||
|
@ -147,6 +231,22 @@ public:
|
|||
bool doTrace(void); ///< Trace split through data-flow, constructing transform
|
||||
};
|
||||
|
||||
/// \brief Try to detect and split artificially joined Varnodes
|
||||
///
|
||||
/// Look for SUBPIECE coming from a PIECE that has come through INDIRECTs and/or MULTIEQUAL
|
||||
/// Then: check if the input to SUBPIECE can be viewed as two independent pieces
|
||||
/// If so: split the pieces into independent data-flows
|
||||
class RuleSplitFlow : public Rule {
|
||||
public:
|
||||
RuleSplitFlow(const string &g) : Rule( g, 0, "splitflow") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleSplitFlow(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief Split a p-code COPY, LOAD, or STORE op based on underlying composite data-type
|
||||
///
|
||||
/// During the cleanup phase, if a COPY, LOAD, or STORE occurs on a partial structure or array
|
||||
|
@ -208,6 +308,51 @@ public:
|
|||
static Datatype *getValueDatatype(PcodeOp *loadStore,int4 size,TypeFactory *tlst);
|
||||
};
|
||||
|
||||
/// \brief Split COPY ops based on TypePartialStruct
|
||||
///
|
||||
/// If more than one logical component of a structure or array is copied at once,
|
||||
/// rewrite the COPY operator as multiple COPYs.
|
||||
class RuleSplitCopy : public Rule {
|
||||
public:
|
||||
RuleSplitCopy(const string &g) : Rule( g, 0, "splitcopy") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleSplitCopy(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief Split LOAD ops based on TypePartialStruct
|
||||
///
|
||||
/// If more than one logical component of a structure or array is loaded at once,
|
||||
/// rewrite the LOAD operator as multiple LOADs.
|
||||
class RuleSplitLoad : public Rule {
|
||||
public:
|
||||
RuleSplitLoad(const string &g) : Rule( g, 0, "splitload") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleSplitLoad(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief Split STORE ops based on TypePartialStruct
|
||||
///
|
||||
/// If more than one logical component of a structure or array is stored at once,
|
||||
/// rewrite the STORE operator as multiple STOREs.
|
||||
class RuleSplitStore : public Rule {
|
||||
public:
|
||||
RuleSplitStore(const string &g) : Rule( g, 0, "splitstore") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleSplitStore(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief 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
|
||||
|
@ -242,6 +387,18 @@ public:
|
|||
bool doTrace(void); ///< Trace logical value as far as possible
|
||||
};
|
||||
|
||||
/// \brief Perform SubfloatFlow analysis triggered by FLOAT_FLOAT2FLOAT
|
||||
class RuleSubfloatConvert : public Rule {
|
||||
public:
|
||||
RuleSubfloatConvert(const string &g) : Rule( g, 0, "subfloat_convert") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleSubfloatConvert(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief Class for splitting data-flow on \e laned registers
|
||||
///
|
||||
/// From a root Varnode and a description of its \e lanes, trace data-flow as far as
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue