#ifndef __CORE_ACTION__
#define __CORE_ACTION__
#include "ruleaction.hh"
#include "blockaction.hh"
#include "funcdata.hh"
class ActionStart : public Action {
public:
ActionStart(const string &g) : Action(0,"start",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionStart(getGroup());
}
virtual int4 apply(Funcdata &data) {
data.startProcessing(); return 0; }
};
class ActionStop : public Action {
public:
ActionStop(const string &g) : Action(0,"stop",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionStop(getGroup());
}
virtual int4 apply(Funcdata &data) {
data.stopProcessing(); return 0; }
};
class ActionStartCleanUp : public Action {
public:
ActionStartCleanUp(const string &g) : Action(0,"startcleanup",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionStartCleanUp(getGroup());
}
virtual int4 apply(Funcdata &data) {
data.startCleanUp(); return 0; }
};
class ActionStartTypes : public Action {
public:
ActionStartTypes(const string &g) : Action(0,"starttypes",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionStartTypes(getGroup());
}
virtual int4 apply(Funcdata &data) {
if (data.startTypeRecovery()) count+=1;
return 0;
}
};
class ActionStackPtrFlow : public Action {
AddrSpace *stackspace; bool analysis_finished; static void analyzeExtraPop(Funcdata &data,AddrSpace *stackspace,int4 spcbase);
static bool isStackRelative(Varnode *spcbasein,Varnode *vn,uintb &constval);
static bool adjustLoad(Funcdata &data,PcodeOp *loadop,PcodeOp *storeop);
static int4 repair(Funcdata &data,AddrSpace *id,Varnode *spcbasein,PcodeOp *loadop,uintb constz);
static int4 checkClog(Funcdata &data,AddrSpace *id,int4 spcbase);
public:
ActionStackPtrFlow(const string &g,AddrSpace *ss) : Action(0,"stackptrflow",g) { stackspace = ss; } virtual void reset(Funcdata &data) { analysis_finished = false; }
virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionStackPtrFlow(getGroup(),stackspace);
}
virtual int4 apply(Funcdata &data);
};
class ActionLaneDivide : public Action {
void collectLaneSizes(Varnode *vn,const LanedRegister &allowedLanes,LanedRegister &checkLanes);
bool processVarnode(Funcdata &data,Varnode *vn,const LanedRegister &lanedRegister,int4 mode);
public:
ActionLaneDivide(const string &g) : Action(rule_onceperfunc,"lanedivide",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionLaneDivide(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionSegmentize : public Action {
int4 localcount; public:
ActionSegmentize(const string &g) : Action(0,"segmentize",g) {} virtual void reset(Funcdata &data) { localcount = 0; }
virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionSegmentize(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionForceGoto : public Action {
public:
ActionForceGoto(const string &g) : Action(0,"forcegoto",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionForceGoto(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionMultiCse : public Action {
static bool preferredOutput(Varnode *out1,Varnode *out2); static PcodeOp *findMatch(BlockBasic *bl,PcodeOp *target,Varnode *in); bool processBlock(Funcdata &data,BlockBasic *bl); public:
ActionMultiCse(const string &g) : Action(0,"multicse",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionMultiCse(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionShadowVar : public Action {
public:
ActionShadowVar(const string &g) : Action(0,"shadowvar",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionShadowVar(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionConstantPtr : public Action {
int4 localcount; static AddrSpace *searchForLoadStore(Varnode *vn,PcodeOp *op);
static AddrSpace *selectInferSpace(Varnode *vn,PcodeOp *op,const vector<AddrSpace *> &spaceList);
static SymbolEntry *isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,int4 slot,
Address &rampoint,uintb &fullEncoding,Funcdata &data);
public:
ActionConstantPtr(const string &g) : Action(0,"constantptr",g) {} virtual void reset(Funcdata &data) { localcount = 0; }
virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionConstantPtr(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionDeindirect : public Action {
public:
ActionDeindirect(const string &g) : Action(0,"deindirect",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionDeindirect(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionVarnodeProps : public Action {
public:
ActionVarnodeProps(const string &g) : Action(0,"varnodeprops",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionVarnodeProps(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionDirectWrite : public Action {
bool propagateIndirect; public:
ActionDirectWrite(const string &g,bool prop) : Action(0,"directwrite",g) { propagateIndirect=prop; } virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionDirectWrite(getGroup(),propagateIndirect);
}
virtual int4 apply(Funcdata &data);
};
class ActionConstbase : public Action {
public:
ActionConstbase(const string &g) : Action(0,"constbase",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionConstbase(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionSpacebase : public Action {
public:
ActionSpacebase(const string &g) : Action(0,"spacebase",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionSpacebase(getGroup());
}
virtual int4 apply(Funcdata &data) {
data.spacebase(); return 0; }
};
class ActionHeritage : public Action {
public:
ActionHeritage(const string &g) : Action(0,"heritage",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionHeritage(getGroup());
}
virtual int4 apply(Funcdata &data) { data.opHeritage(); return 0; }
};
class ActionNonzeroMask : public Action {
public:
ActionNonzeroMask(const string &g) : Action(0,"nonzeromask",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionNonzeroMask(getGroup());
}
virtual int4 apply(Funcdata &data) { data.calcNZMask(); return 0; }
};
class ActionSetCasts : public Action {
static bool testStructOffset0(Varnode *vn,Datatype *ct,CastStrategy *castStrategy);
static bool isOpIdentical(Datatype *ct1,Datatype *ct2);
static int4 castOutput(PcodeOp *op,Funcdata &data,CastStrategy *castStrategy);
static int4 castInput(PcodeOp *op,int4 slot,Funcdata &data,CastStrategy *castStrategy);
public:
ActionSetCasts(const string &g) : Action(rule_onceperfunc,"setcasts",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionSetCasts(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionAssignHigh : public Action {
public:
ActionAssignHigh(const string &g) : Action(rule_onceperfunc,"assignhigh",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionAssignHigh(getGroup());
}
virtual int4 apply(Funcdata &data) { data.setHighLevel(); return 0; }
};
class ActionMarkIndirectOnly : public Action {
public:
ActionMarkIndirectOnly(const string &g) : Action(rule_onceperfunc, "markindirectonly",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionMarkIndirectOnly(getGroup());
}
virtual int4 apply(Funcdata &data) {
data.markIndirectOnly(); return 0; }
};
class ActionMergeRequired : public Action {
public:
ActionMergeRequired(const string &g) : Action(rule_onceperfunc,"mergerequired",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionMergeRequired(getGroup());
}
virtual int4 apply(Funcdata &data) {
data.getMerge().mergeAddrTied(); data.getMerge().mergeMarker(); return 0; }
};
class ActionMergeAdjacent : public Action {
public:
ActionMergeAdjacent(const string &g) : Action(rule_onceperfunc,"mergeadjacent",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionMergeAdjacent(getGroup());
}
virtual int4 apply(Funcdata &data) { data.getMerge().mergeAdjacent(); return 0; }
};
class ActionMergeCopy : public Action {
public:
ActionMergeCopy(const string &g) : Action(rule_onceperfunc,"mergecopy",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionMergeCopy(getGroup());
}
virtual int4 apply(Funcdata &data) { data.getMerge().mergeOpcode(CPUI_COPY); return 0; }
};
class ActionMergeMultiEntry : public Action {
public:
ActionMergeMultiEntry(const string &g) : Action(rule_onceperfunc,"mergemultientry",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionMergeMultiEntry(getGroup());
}
virtual int4 apply(Funcdata &data) { data.getMerge().mergeMultiEntry(); return 0; }
};
class ActionMergeType : public Action {
public:
ActionMergeType(const string &g) : Action(rule_onceperfunc,"mergetype",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionMergeType(getGroup());
}
virtual int4 apply(Funcdata &data) {
data.getMerge().mergeByDatatype(data.beginLoc(),data.endLoc()); return 0; }
};
class ActionMarkExplicit : public Action {
struct OpStackElement {
Varnode *vn; int4 slot; int4 slotback; OpStackElement(Varnode *v); };
static int4 baseExplicit(Varnode *vn,int4 maxref); static int4 multipleInteraction(vector<Varnode *> &multlist); static void processMultiplier(Varnode *vn,int4 max); static void checkNewToConstructor(Funcdata &data,Varnode *vn); public:
ActionMarkExplicit(const string &g) : Action(rule_onceperfunc,"markexplicit",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionMarkExplicit(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionMarkImplied : public Action {
struct DescTreeElement {
Varnode *vn; list<PcodeOp *>::const_iterator desciter; DescTreeElement(Varnode *v) {
vn = v; desciter = v->beginDescend(); } };
static bool isPossibleAliasStep(Varnode *vn1,Varnode *vn2); static bool isPossibleAlias(Varnode *vn1,Varnode *vn2,int4 depth); static bool checkImpliedCover(Funcdata &data,Varnode *vn); public:
ActionMarkImplied(const string &g) : Action(rule_onceperfunc,"markimplied",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionMarkImplied(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionNameVars : public Action {
struct OpRecommend {
Datatype *ct; string namerec; };
static void makeRec(ProtoParameter *param,Varnode *vn,map<HighVariable *,OpRecommend> &recmap);
static void lookForBadJumpTables(Funcdata &data); static void lookForFuncParamNames(Funcdata &data,const vector<Varnode *> &varlist);
static void linkSpacebaseSymbol(Varnode *vn,Funcdata &data,vector<Varnode *> &namerec);
static void linkSymbols(Funcdata &data,vector<Varnode *> &namerec);
public:
ActionNameVars(const string &g) : Action(rule_onceperfunc,"namevars",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionNameVars(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionUnreachable : public Action {
public:
ActionUnreachable(const string &g) : Action(0,"unreachable",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionUnreachable(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionDoNothing : public Action {
public:
ActionDoNothing(const string &g) : Action(rule_repeatapply,"donothing",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionDoNothing(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionRedundBranch : public Action {
public:
ActionRedundBranch(const string &g) : Action(0,"redundbranch",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionRedundBranch(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionDeterminedBranch : public Action {
public:
ActionDeterminedBranch(const string &g) : Action(0,"determinedbranch",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionDeterminedBranch(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionDeadCode : public Action {
static void pushConsumed(uintb val,Varnode *vn,vector<Varnode *> &worklist);
static void propagateConsumed(vector<Varnode *> &worklist);
static bool neverConsumed(Varnode *vn,Funcdata &data);
static void markConsumedParameters(FuncCallSpecs *fc,vector<Varnode *> &worklist);
static uintb gatherConsumedReturn(Funcdata &data);
static bool isEventualConstant(Varnode *vn,int4 addCount,int4 loadCount);
static bool lastChanceLoad(Funcdata &data,vector<Varnode *> &worklist);
public:
ActionDeadCode(const string &g) : Action(0,"deadcode",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionDeadCode(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionConditionalConst : public Action {
public:
ActionConditionalConst(const string &g) : Action(0,"condconst",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionConditionalConst(getGroup());
}
virtual int4 apply(Funcdata &data);
void propagateConstant(Varnode *varVn,Varnode *constVn,FlowBlock *constBlock,Funcdata &data);
};
class ActionSwitchNorm : public Action {
public:
ActionSwitchNorm(const string &g) : Action(0,"switchnorm",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionSwitchNorm(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionNormalizeSetup : public Action {
public:
ActionNormalizeSetup(const string &g) : Action(rule_onceperfunc,"normalizesetup",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionNormalizeSetup(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionPrototypeTypes: public Action {
public:
void extendInput(Funcdata &data,Varnode *invn,ProtoParameter *param,BlockBasic *topbl);
ActionPrototypeTypes(const string &g) : Action(rule_onceperfunc,"prototypetypes",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionPrototypeTypes(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionDefaultParams : public Action {
public:
ActionDefaultParams(const string &g) : Action(rule_onceperfunc,"defaultparams",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionDefaultParams(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionExtraPopSetup : public Action {
AddrSpace *stackspace; public:
ActionExtraPopSetup(const string &g,AddrSpace *ss) : Action(rule_onceperfunc,"extrapopsetup",g) { stackspace = ss; } virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionExtraPopSetup(getGroup(),stackspace);
}
virtual int4 apply(Funcdata &data);
};
class ActionFuncLink : public Action {
friend class ActionFuncLinkOutOnly;
static void funcLinkInput(FuncCallSpecs *fc,Funcdata &data);
static void funcLinkOutput(FuncCallSpecs *fc,Funcdata &data);
public:
ActionFuncLink(const string &g) : Action(rule_onceperfunc,"funclink",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionFuncLink(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionFuncLinkOutOnly : public Action {
public:
ActionFuncLinkOutOnly(const string &g) : Action(rule_onceperfunc,"funclink_outonly",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionFuncLinkOutOnly(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionParamDouble : public Action {
public:
ActionParamDouble(const string &g) : Action(0, "paramdouble",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionParamDouble(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionActiveParam : public Action {
public:
ActionActiveParam(const string &g) : Action( 0, "activeparam",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionActiveParam(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionActiveReturn : public Action {
public:
ActionActiveReturn(const string &g) : Action( 0, "activereturn",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionActiveReturn(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionReturnRecovery : public Action {
static void buildReturnOutput(ParamActive *active,PcodeOp *retop,Funcdata &data);
public:
ActionReturnRecovery(const string &g) : Action( 0, "returnrecovery",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionReturnRecovery(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionRestrictLocal : public Action {
public:
ActionRestrictLocal(const string &g) : Action(0,"restrictlocal",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionRestrictLocal(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionLikelyTrash : public Action {
static uint4 countMarks(PcodeOp *op);
static bool traceTrash(Varnode *vn,vector<PcodeOp *> &indlist);
public:
ActionLikelyTrash(const string &g) : Action(0,"likelytrash",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionLikelyTrash(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionRestructureVarnode : public Action {
int4 numpass; public:
ActionRestructureVarnode(const string &g) : Action(0,"restructure_varnode",g) {} virtual void reset(Funcdata &data) { numpass = 0; }
virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionRestructureVarnode(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionRestructureHigh : public Action {
public:
ActionRestructureHigh(const string &g) : Action(0,"restructure_high",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionRestructureHigh(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionMapGlobals : public Action {
public:
ActionMapGlobals(const string &g) : Action(rule_onceperfunc,"mapglobals",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionMapGlobals(getGroup());
}
virtual int4 apply(Funcdata &data) { data.mapGlobals(); return 0; }
};
class ActionInputPrototype : public Action {
public:
ActionInputPrototype(const string &g) : Action(rule_onceperfunc,"inputprototype",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionInputPrototype(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionOutputPrototype : public Action {
public:
ActionOutputPrototype(const string &g) : Action(rule_onceperfunc,"outputprototype",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionOutputPrototype(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionUnjustifiedParams : public Action {
public:
ActionUnjustifiedParams(const string &g) : Action(0,"unjustparams",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionUnjustifiedParams(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionInferTypes : public Action {
#ifdef TYPEPROP_DEBUG
static void propagationDebug(Architecture *glb,Varnode *vn,const Datatype *newtype,PcodeOp *op,int4 slot,Varnode *ptralias);
#endif
int4 localcount; static void buildLocaltypes(Funcdata &data); static bool writeBack(Funcdata &data); static int4 propagateAddPointer(uintb &off,PcodeOp *op,int4 slot,int4 sz); static Datatype *propagateAddIn2Out(TypeFactory *typegrp,PcodeOp *op,int4 inslot);
static bool propagateGoodEdge(PcodeOp *op,int4 inslot,int4 outslot,Varnode *invn);
static bool propagateTypeEdge(TypeFactory *typegrp,PcodeOp *op,int4 inslot,int4 outslot);
static void propagateOneType(TypeFactory *typegrp,Varnode *vn);
static void propagateRef(Funcdata &data,Varnode *vn,const Address &addr);
static void propagateSpacebaseRef(Funcdata &data,Varnode *spcvn);
static PcodeOp *canonicalReturnOp(Funcdata &data);
static void propagateAcrossReturns(Funcdata &data);
public:
ActionInferTypes(const string &g) : Action(0,"infertypes",g) {} virtual void reset(Funcdata &data) { localcount = 0; }
virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionInferTypes(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionHideShadow : public Action {
public:
ActionHideShadow(const string &g) : Action(rule_onceperfunc,"hideshadow",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionHideShadow(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionDominantCopy : public Action {
public:
ActionDominantCopy(const string &g) : Action(rule_onceperfunc,"dominantcopy",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionDominantCopy(getGroup());
}
virtual int4 apply(Funcdata &data) { data.getMerge().processCopyTrims(); return 0; }
};
class ActionCopyMarker : public Action {
public:
ActionCopyMarker(const string &g) : Action(rule_onceperfunc,"copymarker",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionCopyMarker(getGroup());
}
virtual int4 apply(Funcdata &data) { data.getMerge().markInternalCopies(); return 0; }
};
class ActionDynamicMapping : public Action {
public:
ActionDynamicMapping(const string &g) : Action(0,"dynamicmapping",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionDynamicMapping(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionDynamicSymbols : public Action {
public:
ActionDynamicSymbols(const string &g) : Action(rule_onceperfunc,"dynamicsymbols",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionDynamicSymbols(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class ActionPrototypeWarnings : public Action {
public:
ActionPrototypeWarnings(const string &g) : Action(rule_onceperfunc,"prototypewarnings",g) {} virtual Action *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Action *)0;
return new ActionPrototypeWarnings(getGroup());
}
virtual int4 apply(Funcdata &data);
};
class PropagationState {
public:
Varnode *vn; list<PcodeOp *>::const_iterator iter; PcodeOp *op; int4 inslot; int4 slot; PropagationState(Varnode *v); void step(void); bool valid(void) const { return (op != (PcodeOp *)0); } };
class PcodeOpEdge {
PcodeOp *op; int4 slot; Varnode *vn; PcodeOp *mult; public:
PcodeOpEdge(PcodeOp *o,int4 s,PcodeOp *m) { op = o; slot = s; vn = op->getIn(slot); mult=m; } PcodeOp *getMultiplier(void) const { return mult; } PcodeOp *getOp(void) const { return op; } int4 getSlot(void) const { return slot; } Varnode *getVarnode(void) const { return vn; } };
class TermOrder {
PcodeOp *root; vector<PcodeOpEdge> terms; vector<PcodeOpEdge *> sorter; static bool additiveCompare(const PcodeOpEdge *op1,const PcodeOpEdge *op2);
public:
TermOrder(PcodeOp *rt) { root = rt; } int4 getSize(void) const { return terms.size(); } void collect(void); void sortTerms(void); const vector<PcodeOpEdge *> &getSort(void) { return sorter; } };
inline bool TermOrder::additiveCompare(const PcodeOpEdge *op1,const PcodeOpEdge *op2) {
return (-1 == op1->getVarnode()->termOrder(op2->getVarnode())); }
#endif