19 #ifndef __CPUI_JUMPTABLE__ 20 #define __CPUI_JUMPTABLE__ 51 void saveXml(ostream &s)
const;
53 static void collapseTable(vector<LoadTable> &table);
71 RootedOp(
PcodeOp *o,int4 root) { op = o; rootVn = root; }
73 vector<Varnode *> commonVn;
74 vector<RootedOp> opMeld;
75 void internalIntersect(vector<int4> &parentMap);
76 int4 meldOps(
const vector<PcodeOp *> &path,int4 cutOff,
const vector<int4> &parentMap);
77 void truncatePaths(int4 cutPoint);
80 void set(
const vector<PcodeOp *> &path,
const vector<int4> &slot);
84 void meld(vector<PcodeOp *> &path,vector<int4> &slot);
85 void markPaths(
bool val,int4 startVarnode);
87 int4
numOps(
void)
const {
return opMeld.size(); }
91 PcodeOp *getEarliestOp(int4 pos)
const;
92 bool empty(
void)
const {
return commonVn.empty(); }
102 map<Varnode *,uintb> varnodeMap;
104 vector<LoadTable> loadpoints;
105 virtual void executeLoad(
void);
106 virtual void executeBranch(
void);
107 virtual void executeBranchind(
void);
108 virtual void executeCall(
void);
109 virtual void executeCallind(
void);
110 virtual void executeCallother(
void);
111 virtual void fallthruOp(
void);
115 virtual void setExecuteAddress(
const Address &addr);
116 virtual uintb getVarnodeValue(
Varnode *vn)
const;
117 virtual void setVarnodeValue(
Varnode *vn,uintb val);
119 void collectLoadPoints(vector<LoadTable> &res)
const;
145 int4 valueMatch(
Varnode *vn2,
Varnode *baseVn2,int4 bitsPreserved2)
const;
159 virtual void truncate(int4 nm)=0;
160 virtual uintb getSize(
void)
const=0;
161 virtual bool contains(uintb val)
const=0;
166 virtual bool initializeForReading(
void)
const=0;
168 virtual bool next(
void)
const=0;
169 virtual uintb getValue(
void)
const=0;
170 virtual Varnode *getStartVarnode(
void)
const=0;
171 virtual PcodeOp *getStartOp(
void)
const=0;
172 virtual bool isReversible(
void)
const=0;
187 virtual void truncate(int4 nm);
188 virtual uintb getSize(
void)
const;
189 virtual bool contains(uintb val)
const;
190 virtual bool initializeForReading(
void)
const;
191 virtual bool next(
void)
const;
192 virtual uintb getValue(
void)
const;
193 virtual Varnode *getStartVarnode(
void)
const;
194 virtual PcodeOp *getStartOp(
void)
const;
207 mutable bool lastvalue;
212 virtual uintb getSize(
void)
const;
213 virtual bool contains(uintb val)
const;
214 virtual bool initializeForReading(
void)
const;
215 virtual bool next(
void)
const;
216 virtual Varnode *getStartVarnode(
void)
const;
217 virtual PcodeOp *getStartOp(
void)
const;
238 virtual bool isOverride(
void)
const=0;
239 virtual int4 getTableSize(
void)
const=0;
249 virtual bool recoverModel(
Funcdata *fd,
PcodeOp *indop,uint4 matchsize,uint4 maxtablesize)=0;
259 virtual void buildAddresses(
Funcdata *fd,
PcodeOp *indop,vector<Address> &addresstable,vector<LoadTable> *loadpoints)
const=0;
268 virtual void findUnnormalized(uint4 maxaddsub,uint4 maxleftright,uint4 maxext)=0;
280 virtual void buildLabels(
Funcdata *fd,vector<Address> &addresstable,vector<uintb> &label,
const JumpModel *orig)
const=0;
308 virtual bool sanityCheck(
Funcdata *fd,
PcodeOp *indop,vector<Address> &addresstable)=0;
328 virtual bool recoverModel(
Funcdata *fd,
PcodeOp *indop,uint4 matchsize,uint4 maxtablesize);
329 virtual void buildAddresses(
Funcdata *fd,
PcodeOp *indop,vector<Address> &addresstable,vector<LoadTable> *loadpoints)
const;
331 virtual void buildLabels(
Funcdata *fd,vector<Address> &addresstable,vector<uintb> &label,
const JumpModel *orig)
const;
352 static bool isprune(
Varnode *vn);
353 static bool ispoint(
Varnode *vn);
354 static int4 getStride(
Varnode *vn);
356 void findDeterminingVarnodes(
PcodeOp *op,int4 slot);
357 void analyzeGuards(
BlockBasic *bl,int4 pathout);
359 void findSmallestNormal(uint4 matchsize);
360 void findNormalized(
Funcdata *fd,
BlockBasic *rootbl,int4 pathout,uint4 matchsize,uint4 maxtablesize);
361 void markFoldableGuards();
362 void markModel(
bool val);
382 virtual bool recoverModel(
Funcdata *fd,
PcodeOp *indop,uint4 matchsize,uint4 maxtablesize);
383 virtual void buildAddresses(
Funcdata *fd,
PcodeOp *indop,vector<Address> &addresstable,vector<LoadTable> *loadpoints)
const;
384 virtual void findUnnormalized(uint4 maxaddsub,uint4 maxleftright,uint4 maxext);
385 virtual void buildLabels(
Funcdata *fd,vector<Address> &addresstable,vector<uintb> &label,
const JumpModel *orig)
const;
388 virtual bool sanityCheck(
Funcdata *fd,
PcodeOp *indop,vector<Address> &addresstable);
390 virtual void clear(
void);
408 bool checkNormalDominance(
void)
const;
412 void initializeStart(
const PathMeld &pathMeld);
413 virtual bool recoverModel(
Funcdata *fd,
PcodeOp *indop,uint4 matchsize,uint4 maxtablesize);
414 virtual void findUnnormalized(uint4 maxaddsub,uint4 maxleftright,uint4 maxext);
416 virtual void clear(
void);
427 vector<uintb> values;
428 vector<Address> addrtable;
435 void setupTrivial(
void);
437 void clearCopySpecific(
void);
440 void setAddresses(
const vector<Address> &adtable);
445 virtual bool recoverModel(
Funcdata *fd,
PcodeOp *indop,uint4 matchsize,uint4 maxtablesize);
446 virtual void buildAddresses(
Funcdata *fd,
PcodeOp *indop,vector<Address> &addresstable,vector<LoadTable> *loadpoints)
const;
448 virtual void buildLabels(
Funcdata *fd,vector<Address> &addresstable,vector<uintb> &label,
const JumpModel *orig)
const;
453 virtual void clear(
void);
454 virtual void saveXml(ostream &s)
const;
482 virtual bool recoverModel(
Funcdata *fd,
PcodeOp *indop,uint4 matchsize,uint4 maxtablesize);
483 virtual void buildAddresses(
Funcdata *fd,
PcodeOp *indop,vector<Address> &addresstable,vector<LoadTable> *loadpoints)
const;
485 virtual void buildLabels(
Funcdata *fd,vector<Address> &addresstable,vector<uintb> &label,
const JumpModel *orig)
const;
504 IndexPair(int4 pos,int4 index) { blockPosition = pos; addressIndex = index; }
505 bool operator<(
const IndexPair &op2)
const;
506 static bool compareByPosition(
const IndexPair &op1,
const IndexPair &op2);
511 vector<Address> addresstable;
512 vector<IndexPair> block2addr;
514 vector<LoadTable> loadpoints;
517 uintb switchVarConsume;
527 void trivialSwitchOver(
void);
529 int4 block2Position(
const FlowBlock *bl)
const;
530 static bool isReachable(
PcodeOp *op);
537 bool isOverride(
void)
const;
539 int4
getStage(
void)
const {
return recoverystage; }
548 maxaddsub = maddsub; maxleftright = mleftright; maxext = mext; }
549 void setOverride(
const vector<Address> &addrtable,
const Address &naddr,uintb h,uintb sv);
550 int4 numIndicesByBlock(
const FlowBlock *bl)
const;
551 int4 getIndexByBlock(
const FlowBlock *bl,int4 i)
const;
553 void setLastAsMostCommon(
void);
556 void addBlockToSwitch(
BlockBasic *bl,uintb lab);
557 void switchOver(
const FlowInfo &flow);
559 void foldInNormalization(
Funcdata *fd);
561 void recoverAddresses(
Funcdata *fd);
562 void recoverMultistage(
Funcdata *fd);
564 bool checkForMultistage(
Funcdata *fd);
566 void saveXml(ostream &s)
const;
567 void restoreXml(
const Element *el);
572 inline bool JumpTable::IndexPair::operator<(
const IndexPair &op2)
const 575 if (blockPosition != op2.blockPosition)
return (blockPosition < op2.blockPosition);
576 return (addressIndex < op2.addressIndex);
582 inline bool JumpTable::IndexPair::compareByPosition(
const IndexPair &op1,
const IndexPair &op2)
585 return (op1.blockPosition < op2.blockPosition);
void setDefaultVn(Varnode *vn)
Set the associated start Varnode.
Definition: jumptable.hh:210
void setLoadCollect(bool val)
Set whether we collect LOAD information.
Definition: jumptable.hh:114
Varnode * normqvn
Varnode representing the normalized switch variable.
Definition: jumptable.hh:180
Description of a control-flow block containing PcodeOps.
Definition: block.hh:60
JumpBasic2(JumpTable *jt)
Constructor.
Definition: jumptable.hh:411
Address getAddressByIndex(int4 i) const
Get the i-th address table entry.
Definition: jumptable.hh:552
Exception thrown for a thunk mechanism that looks like a jump-table.
Definition: jumptable.hh:28
PathMeld pathMeld
Set of PcodeOps and Varnodes producing the final target addresses.
Definition: jumptable.hh:347
uintb getSwitchVarConsume(void) const
Get bits of switch variable consumed by this table.
Definition: jumptable.hh:541
single entry switch variable that can take a range of values
Definition: jumptable.hh:177
virtual Varnode * foldInNormalization(Funcdata *fd, PcodeOp *indop)
Do normalization of the given switch specific to this model.
Definition: jumptable.hh:332
virtual void findUnnormalized(uint4 maxaddsub, uint4 maxleftright, uint4 maxext)
Recover the unnormalized switch variable.
Definition: jumptable.hh:330
void setStartingValue(uintb val)
Set the starting value for the normalized range.
Definition: jumptable.hh:442
const Address & getAddr(void) const
Get the instruction address associated with this op.
Definition: op.hh:151
int4 getPath(void) const
Get the specific path index going towards the switch.
Definition: jumptable.hh:142
bool isPossibleMultistage(void) const
Return true if this could be multi-staged.
Definition: jumptable.hh:538
JumpModel(JumpTable *jt)
Construct given a parent jump-table.
Definition: jumptable.hh:236
Container for data structures associated with a single function.
Definition: funcdata.hh:45
vector< GuardRecord > selectguards
Any guards associated with model.
Definition: jumptable.hh:348
A class for generating the control-flow structure for a single function.
Definition: flow.hh:56
virtual void clear(void)
Clear any non-permanent aspects of the model.
Definition: jumptable.hh:490
A description where and how data was loaded from memory.
Definition: jumptable.hh:41
bool operator<(const LoadTable &op2) const
Compare this with another table by address.
Definition: jumptable.hh:50
uintb curval
The current value pointed to be the iterator.
Definition: jumptable.hh:182
int4 getDefaultBlock(void) const
Get the out-edge corresponding to the default switch destination.
Definition: jumptable.hh:542
void setMaxTableSize(uint4 val)
Set the maximum entries allowed in the address table.
Definition: jumptable.hh:546
A trivial jump-table model, where the BRANCHIND input Varnode is the switch variable.
Definition: jumptable.hh:322
void clear(void)
Mark this guard as unused.
Definition: jumptable.hh:144
Documentation for the CircleRange class.
int4 numEntries(void) const
Return the size of the address table for this jump-table.
Definition: jumptable.hh:540
PcodeOp * getOp(int4 i) const
Get the i-th PcodeOp.
Definition: jumptable.hh:90
virtual bool isOverride(void) const
Return true if this model was manually overridden.
Definition: jumptable.hh:480
PcodeOp * getBranch(void) const
Get the CBRANCH associated with this guard.
Definition: jumptable.hh:140
A jump-table model assisted by pseudo-op directives in the code.
Definition: jumptable.hh:472
virtual bool foldInGuards(Funcdata *fd, JumpTable *jump)=0
Eliminate any guard code involved in computing the switch destination.
virtual uintb getSize(void) const
Return the number of values the variables can take.
Definition: jumptable.cc:268
bool isRecovered(void) const
Return true if a model has been recovered.
Definition: jumptable.hh:535
JumpAssisted(JumpTable *jt)
Constructor.
Definition: jumptable.hh:478
A jump-table execution model.
Definition: jumptable.hh:232
bool isLabelled(void) const
Return true if case labels are computed.
Definition: jumptable.hh:536
JumpValuesRange * jrange
Range of values for the (normalized) switch variable.
Definition: jumptable.hh:346
A class for manipulating integer value ranges.
Definition: rangeutil.hh:48
uintb getLabelByIndex(int4 index) const
Given a case index, get its label.
Definition: jumptable.hh:558
virtual bool isOverride(void) const
Return true if this model was manually overridden.
Definition: jumptable.hh:326
Lowest level operation of the p-code language.
Definition: op.hh:58
The basic switch model.
Definition: jumptable.hh:344
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
virtual bool isReversible(void) const
Return true if the current value can be reversed to get a label.
Definition: jumptable.hh:218
PcodeOp * getReadOp(void) const
Get the PcodeOp immediately causing the restriction.
Definition: jumptable.hh:141
A user defined p-code op for assisting the recovery of jump tables.
Definition: userop.hh:229
virtual void saveXml(ostream &s) const
Save this model as an XML tag.
Definition: jumptable.hh:312
virtual int4 getTableSize(void) const
Return the number of entries in the address table.
Definition: jumptable.hh:327
Varnode * getVarnode(int4 i) const
Get the i-th common Varnode.
Definition: jumptable.hh:88
bool foldInGuards(Funcdata *fd)
Hide any guard code for this switch.
Definition: jumptable.hh:560
virtual void clear(void)
Clear any non-permanent aspects of the model.
Definition: jumptable.hh:311
bool empty(void) const
Return true if this container holds no paths.
Definition: jumptable.hh:92
const CircleRange & getRange(void) const
Get the range of values causing the switch path to be taken.
Definition: jumptable.hh:143
JumptableThunkError(const string &s)
Construct with an explanatory string.
Definition: jumptable.hh:29
virtual bool sanityCheck(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable)
Perform a sanity check on recovered addresses.
Definition: jumptable.hh:488
Manager for all the major decompiler subsystems.
Definition: architecture.hh:117
virtual bool sanityCheck(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable)
Perform a sanity check on recovered addresses.
Definition: jumptable.hh:451
void setDefaultBlock(int4 bl)
Set out-edge of the switch destination considered to be default.
Definition: jumptable.hh:554
A (putative) switch variable Varnode and a constraint imposed by a CBRANCH.
Definition: jumptable.hh:130
A basic jump-table model with an added default address path.
Definition: jumptable.hh:405
virtual bool sanityCheck(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable)
Perform a sanity check on recovered addresses.
Definition: jumptable.hh:334
void setStartVn(Varnode *vn)
Set the normalized switch Varnode explicitly.
Definition: jumptable.hh:185
The lowest level error generated by the decompiler.
Definition: error.hh:44
JumpModelTrivial(JumpTable *jt)
Construct given a parent JumpTable.
Definition: jumptable.hh:325
A basic jump-table model incorporating manual override information.
Definition: jumptable.hh:425
virtual bool foldInGuards(Funcdata *fd, JumpTable *jump)
Eliminate any guard code involved in computing the switch destination.
Definition: jumptable.hh:333
int4 numCommonVarnode(void) const
Return the number of Varnodes common to all paths.
Definition: jumptable.hh:86
int4 getStage(void) const
Return what stage of recovery this jump-table is in.
Definition: jumptable.hh:539
void setStartOp(PcodeOp *op)
Set the starting PcodeOp explicitly.
Definition: jumptable.hh:186
void setRange(const CircleRange &rng)
Set the range of values explicitly.
Definition: jumptable.hh:184
A low-level variable or contiguous set of bytes described by an Address and a size.
Definition: varnode.hh:65
A basic block for p-code operations.
Definition: block.hh:363
virtual void restoreXml(const Element *el, Architecture *glb)
Restore this model from an XML tag.
Definition: jumptable.hh:313
A map from values to control-flow targets within a function.
Definition: jumptable.hh:499
An XML element. A node in the DOM tree.
Definition: xml.hh:150
LoadTable(const Address &ad, int4 sz)
Constructor for a single entry table.
Definition: jumptable.hh:48
void setLoadCollect(bool val)
Set whether LOAD records should be collected.
Definition: jumptable.hh:555
virtual bool isReversible(void) const
Return true if the current value can be reversed to get a label.
Definition: jumptable.hh:195
JumpTable * jumptable
The jump-table that is building this model.
Definition: jumptable.hh:234
A jump-table starting range with two possible execution paths.
Definition: jumptable.hh:203
PcodeOp * getIndirectOp(void) const
Get the BRANCHIND PcodeOp.
Definition: jumptable.hh:544
PcodeOp * startop
First PcodeOp in the jump-table calculation.
Definition: jumptable.hh:181
A light-weight emulator to calculate switch targets from switch variables.
Definition: jumptable.hh:100
virtual bool isOverride(void) const
Return true if this model was manually overridden.
Definition: jumptable.hh:443
LoadTable(const Address &ad, int4 sz, int4 nm)
Construct a full table.
Definition: jumptable.hh:49
JumpBasic(JumpTable *jt)
Construct given a parent JumpTable.
Definition: jumptable.hh:376
Emulation based on (existing) PcodeOps and Varnodes.
Definition: emulateutil.hh:41
CircleRange range
Acceptable range of values for the normalized switch variable.
Definition: jumptable.hh:179
void setDefaultOp(PcodeOp *op)
Set the associated start PcodeOp.
Definition: jumptable.hh:211
void setIndirectOp(PcodeOp *ind)
Set the BRANCHIND PcodeOp.
Definition: jumptable.hh:545
virtual void findUnnormalized(uint4 maxaddsub, uint4 maxleftright, uint4 maxext)
Recover the unnormalized switch variable.
Definition: jumptable.hh:484
virtual int4 getTableSize(void) const
Return the number of entries in the address table.
Definition: jumptable.hh:481
const PathMeld & getPathMeld(void) const
Get the possible of paths to the switch.
Definition: jumptable.hh:377
virtual int4 getTableSize(void) const
Return the number of entries in the address table.
Definition: jumptable.hh:381
Architecture * glb
The underlying Architecture for the program being emulated.
Definition: emulateutil.hh:43
Exception thrown is there are no legal flows to a switch.
Definition: jumptable.hh:33
Varnode * switchvn
Unnormalized switch Varnode.
Definition: jumptable.hh:351
An iterator over values a switch variable can take.
Definition: jumptable.hh:156
Varnode * getOpParent(int4 i) const
Get the split-point for the i-th PcodeOp.
Definition: jumptable.hh:89
All paths from a (putative) switch variable to the CPUI_BRANCHIND.
Definition: jumptable.hh:63
void setNorm(const Address &addr, uintb h)
Set the normalized switch variable.
Definition: jumptable.hh:441
Varnode * normalvn
Normalized switch Varnode.
Definition: jumptable.hh:350
virtual ~JumpModel(void)
Destructor.
Definition: jumptable.hh:237
const Address & getOpAddress(void) const
Get the address of the BRANCHIND for the switch.
Definition: jumptable.hh:543
virtual int4 getTableSize(void) const
Return the number of entries in the address table.
Definition: jumptable.hh:444
virtual bool foldInGuards(Funcdata *fd, JumpTable *jump)
Eliminate any guard code involved in computing the switch destination.
Definition: jumptable.hh:450
JumptableNotReachableError(const string &s)
Constructor.
Definition: jumptable.hh:34
int4 numOps(void) const
Return the number of PcodeOps across all paths.
Definition: jumptable.hh:87
(Lightweight) emulation interface for executing PcodeOp objects within a syntax tree or for executing...
void setNormMax(uint4 maddsub, uint4 mleftright, uint4 mext)
Set the switch variable normalization model restrictions.
Definition: jumptable.hh:547
virtual bool isOverride(void) const
Return true if this model was manually overridden.
Definition: jumptable.hh:380
const JumpValuesRange * getValueRange(void) const
Get the normalized value iterator.
Definition: jumptable.hh:378
void setExtraValue(uintb val)
Set the extra value explicitly.
Definition: jumptable.hh:209
int4 varnodeIndex
Position of the normalized switch Varnode within PathMeld.
Definition: jumptable.hh:349