Ghidra Decompiler Analysis Engine
jumptable.hh
Go to the documentation of this file.
1 /* ###
2  * IP: GHIDRA
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
18 
19 #ifndef __CPUI_JUMPTABLE__
20 #define __CPUI_JUMPTABLE__
21 
22 #include "emulateutil.hh"
23 #include "rangeutil.hh"
24 
25 class EmulateFunction;
26 
29  JumptableThunkError(const string &s) : LowlevelError(s) {}
30 };
31 
34  JumptableNotReachableError(const string &s) : LowlevelError(s) {}
35 };
36 
41 class LoadTable {
42  friend class EmulateFunction;
43  Address addr;
44  int4 size;
45  int4 num;
46 public:
47  LoadTable(void) {} // Constructor for use with restoreXml
48  LoadTable(const Address &ad,int4 sz) { addr = ad, size = sz; num = 1; }
49  LoadTable(const Address &ad,int4 sz,int4 nm) { addr = ad; size = sz; num = nm; }
50  bool operator<(const LoadTable &op2) const { return (addr < op2.addr); }
51  void saveXml(ostream &s) const;
52  void restoreXml(const Element *el,Architecture *glb);
53  static void collapseTable(vector<LoadTable> &table);
54 };
55 
63 class PathMeld {
64 
68  struct RootedOp {
69  PcodeOp *op;
70  int4 rootVn;
71  RootedOp(PcodeOp *o,int4 root) { op = o; rootVn = root; }
72  };
73  vector<Varnode *> commonVn;
74  vector<RootedOp> opMeld;
75  void internalIntersect(vector<int4> &parentMap);
76  int4 meldOps(const vector<PcodeOpNode> &path,int4 cutOff,const vector<int4> &parentMap);
77  void truncatePaths(int4 cutPoint);
78 public:
79  void set(const PathMeld &op2);
80  void set(const vector<PcodeOpNode> &path);
81  void set(PcodeOp *op,Varnode *vn);
82  void append(const PathMeld &op2);
83  void clear(void);
84  void meld(vector<PcodeOpNode> &path);
85  void markPaths(bool val,int4 startVarnode);
86  int4 numCommonVarnode(void) const { return commonVn.size(); }
87  int4 numOps(void) const { return opMeld.size(); }
88  Varnode *getVarnode(int4 i) const { return commonVn[i]; }
89  Varnode *getOpParent(int4 i) const { return commonVn[ opMeld[i].rootVn ]; }
90  PcodeOp *getOp(int4 i) const { return opMeld[i].op; }
91  PcodeOp *getEarliestOp(int4 pos) const;
92  bool empty(void) const { return commonVn.empty(); }
93 };
94 
101  Funcdata *fd;
102  map<Varnode *,uintb> varnodeMap;
103  bool collectloads;
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);
112 public:
114  void setLoadCollect(bool val) { collectloads = val; }
115  virtual void setExecuteAddress(const Address &addr);
116  virtual uintb getVarnodeValue(Varnode *vn) const;
117  virtual void setVarnodeValue(Varnode *vn,uintb val);
118  uintb emulatePath(uintb val,const PathMeld &pathMeld,PcodeOp *startop,Varnode *startvn);
119  void collectLoadPoints(vector<LoadTable> &res) const;
120 };
121 
122 class FlowInfo;
123 class JumpTable;
124 
130 class GuardRecord {
131  PcodeOp *cbranch;
132  PcodeOp *readOp;
133  int4 indpath;
134  CircleRange range;
135  Varnode *vn;
136  Varnode *baseVn;
137  int4 bitsPreserved;
138 public:
139  GuardRecord(PcodeOp *bOp,PcodeOp *rOp,int4 path,const CircleRange &rng,Varnode *v);
140  PcodeOp *getBranch(void) const { return cbranch; }
141  PcodeOp *getReadOp(void) const { return readOp; }
142  int4 getPath(void) const { return indpath; }
143  const CircleRange &getRange(void) const { return range; }
144  void clear(void) { cbranch = (PcodeOp *)0; }
145  int4 valueMatch(Varnode *vn2,Varnode *baseVn2,int4 bitsPreserved2) const;
146  static int4 oneOffMatch(PcodeOp *op1,PcodeOp *op2);
147  static Varnode *quasiCopy(Varnode *vn,int4 &bitsPreserved);
148 };
149 
156 class JumpValues {
157 public:
158  virtual ~JumpValues(void) {}
159  virtual void truncate(int4 nm)=0;
160  virtual uintb getSize(void) const=0;
161  virtual bool contains(uintb val) const=0;
162 
166  virtual bool initializeForReading(void) const=0;
167 
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;
173  virtual JumpValues *clone(void) const=0;
174 };
175 
177 class JumpValuesRange : public JumpValues {
178 protected:
182  mutable uintb curval;
183 public:
184  void setRange(const CircleRange &rng) { range = rng; }
185  void setStartVn(Varnode *vn) { normqvn = vn; }
186  void setStartOp(PcodeOp *op) { startop = op; }
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;
195  virtual bool isReversible(void) const { return true; }
196  virtual JumpValues *clone(void) const;
197 };
198 
204  uintb extravalue;
205  Varnode *extravn;
206  PcodeOp *extraop;
207  mutable bool lastvalue;
208 public:
209  void setExtraValue(uintb val) { extravalue = val; }
210  void setDefaultVn(Varnode *vn) { extravn = vn; }
211  void setDefaultOp(PcodeOp *op) { extraop = op; }
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;
218  virtual bool isReversible(void) const { return !lastvalue; } // The -extravalue- is not reversible
219  virtual JumpValues *clone(void) const;
220 };
221 
232 class JumpModel {
233 protected:
235 public:
236  JumpModel(JumpTable *jt) { jumptable = jt; }
237  virtual ~JumpModel(void) {}
238  virtual bool isOverride(void) const=0;
239  virtual int4 getTableSize(void) const=0;
240 
249  virtual bool recoverModel(Funcdata *fd,PcodeOp *indop,uint4 matchsize,uint4 maxtablesize)=0;
250 
259  virtual void buildAddresses(Funcdata *fd,PcodeOp *indop,vector<Address> &addresstable,vector<LoadTable> *loadpoints) const=0;
260 
268  virtual void findUnnormalized(uint4 maxaddsub,uint4 maxleftright,uint4 maxext)=0;
269 
280  virtual void buildLabels(Funcdata *fd,vector<Address> &addresstable,vector<uintb> &label,const JumpModel *orig) const=0;
281 
290  virtual Varnode *foldInNormalization(Funcdata *fd,PcodeOp *indop)=0;
291 
297  virtual bool foldInGuards(Funcdata *fd,JumpTable *jump)=0;
298 
308  virtual bool sanityCheck(Funcdata *fd,PcodeOp *indop,vector<Address> &addresstable)=0;
309 
310  virtual JumpModel *clone(JumpTable *jt) const=0;
311  virtual void clear(void) {}
312  virtual void saveXml(ostream &s) const {}
313  virtual void restoreXml(const Element *el,Architecture *glb) {}
314 };
315 
322 class JumpModelTrivial : public JumpModel {
323  uint4 size;
324 public:
325  JumpModelTrivial(JumpTable *jt) : JumpModel(jt) { size = 0; }
326  virtual bool isOverride(void) const { return false; }
327  virtual int4 getTableSize(void) const { return size; }
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;
330  virtual void findUnnormalized(uint4 maxaddsub,uint4 maxleftright,uint4 maxext) {}
331  virtual void buildLabels(Funcdata *fd,vector<Address> &addresstable,vector<uintb> &label,const JumpModel *orig) const;
332  virtual Varnode *foldInNormalization(Funcdata *fd,PcodeOp *indop) { return (Varnode *)0; }
333  virtual bool foldInGuards(Funcdata *fd,JumpTable *jump) { return false; }
334  virtual bool sanityCheck(Funcdata *fd,PcodeOp *indop,vector<Address> &addresstable) { return true; }
335  virtual JumpModel *clone(JumpTable *jt) const;
336 };
337 
344 class JumpBasic : public JumpModel {
345 protected:
348  vector<GuardRecord> selectguards;
352  static bool isprune(Varnode *vn);
353  static bool ispoint(Varnode *vn);
354  static int4 getStride(Varnode *vn);
355  static uintb backup2Switch(Funcdata *fd,uintb output,Varnode *outvn,Varnode *invn);
356  void findDeterminingVarnodes(PcodeOp *op,int4 slot);
357  void analyzeGuards(BlockBasic *bl,int4 pathout);
358  void calcRange(Varnode *vn,CircleRange &rng) const;
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);
363  bool flowsOnlyToModel(Varnode *vn,PcodeOp *trailOp);
364 
374  virtual bool foldInOneGuard(Funcdata *fd,GuardRecord &guard,JumpTable *jump);
375 public:
376  JumpBasic(JumpTable *jt) : JumpModel(jt) { jrange = (JumpValuesRange *)0; }
377  const PathMeld &getPathMeld(void) const { return pathMeld; }
378  const JumpValuesRange *getValueRange(void) const { return jrange; }
379  virtual ~JumpBasic(void);
380  virtual bool isOverride(void) const { return false; }
381  virtual int4 getTableSize(void) const { return jrange->getSize(); }
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;
386  virtual Varnode *foldInNormalization(Funcdata *fd,PcodeOp *indop);
387  virtual bool foldInGuards(Funcdata *fd,JumpTable *jump);
388  virtual bool sanityCheck(Funcdata *fd,PcodeOp *indop,vector<Address> &addresstable);
389  virtual JumpModel *clone(JumpTable *jt) const;
390  virtual void clear(void);
391 };
392 
405 class JumpBasic2 : public JumpBasic {
406  Varnode *extravn;
407  PathMeld origPathMeld;
408  bool checkNormalDominance(void) const;
409  virtual bool foldInOneGuard(Funcdata *fd,GuardRecord &guard,JumpTable *jump);
410 public:
411  JumpBasic2(JumpTable *jt) : JumpBasic(jt) {}
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);
415  virtual JumpModel *clone(JumpTable *jt) const;
416  virtual void clear(void);
417 };
418 
425 class JumpBasicOverride : public JumpBasic {
426  set<Address> adset;
427  vector<uintb> values;
428  vector<Address> addrtable;
429  uintb startingvalue;
430  Address normaddress;
431  uint8 hash;
432  bool istrivial;
433  int4 findStartOp(Varnode *vn);
434  int4 trialNorm(Funcdata *fd,Varnode *trialvn,uint4 tolerance);
435  void setupTrivial(void);
436  Varnode *findLikelyNorm(void);
437  void clearCopySpecific(void);
438 public:
440  void setAddresses(const vector<Address> &adtable);
441  void setNorm(const Address &addr,uintb h) { normaddress = addr; hash = h; }
442  void setStartingValue(uintb val) { startingvalue = val; }
443  virtual bool isOverride(void) const { return true; }
444  virtual int4 getTableSize(void) const { return addrtable.size(); }
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;
447  // findUnnormalized inherited from JumpBasic
448  virtual void buildLabels(Funcdata *fd,vector<Address> &addresstable,vector<uintb> &label,const JumpModel *orig) const;
449  // foldInNormalization inherited from JumpBasic
450  virtual bool foldInGuards(Funcdata *fd,JumpTable *jump) { return false; }
451  virtual bool sanityCheck(Funcdata *fd,PcodeOp *indop,vector<Address> &addresstable) { return true; }
452  virtual JumpModel *clone(JumpTable *jt) const;
453  virtual void clear(void);
454  virtual void saveXml(ostream &s) const;
455  virtual void restoreXml(const Element *el,Architecture *glb);
456 };
457 
458 class JumpAssistOp;
459 
472 class JumpAssisted : public JumpModel {
473  PcodeOp *assistOp;
474  JumpAssistOp *userop;
475  int4 sizeIndices;
476  Varnode *switchvn;
477 public:
478  JumpAssisted(JumpTable *jt) : JumpModel(jt) { assistOp = (PcodeOp *)0; switchvn = (Varnode *)0; sizeIndices=0; }
479 // virtual ~JumpAssisted(void);
480  virtual bool isOverride(void) const { return false; }
481  virtual int4 getTableSize(void) const { return sizeIndices+1; }
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;
484  virtual void findUnnormalized(uint4 maxaddsub,uint4 maxleftright,uint4 maxext) {}
485  virtual void buildLabels(Funcdata *fd,vector<Address> &addresstable,vector<uintb> &label,const JumpModel *orig) const;
486  virtual Varnode *foldInNormalization(Funcdata *fd,PcodeOp *indop);
487  virtual bool foldInGuards(Funcdata *fd,JumpTable *jump);
488  virtual bool sanityCheck(Funcdata *fd,PcodeOp *indop,vector<Address> &addresstable) { return true; }
489  virtual JumpModel *clone(JumpTable *jt) const;
490  virtual void clear(void) { assistOp = (PcodeOp *)0; switchvn = (Varnode *)0; }
491 };
492 
499 class JumpTable {
501  struct IndexPair {
502  int4 blockPosition;
503  int4 addressIndex;
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);
507  };
508  Architecture *glb;
509  JumpModel *jmodel;
510  JumpModel *origmodel;
511  vector<Address> addresstable;
512  vector<IndexPair> block2addr;
513  vector<uintb> label;
514  vector<LoadTable> loadpoints;
515  Address opaddress;
516  PcodeOp *indirect;
517  uintb switchVarConsume;
518  int4 defaultBlock;
519  int4 lastBlock;
520  uint4 maxtablesize;
521  uint4 maxaddsub;
522  uint4 maxleftright;
523  uint4 maxext;
524  int4 recoverystage;
525  bool collectloads;
526  void recoverModel(Funcdata *fd);
527  void trivialSwitchOver(void);
528  void sanityCheck(Funcdata *fd);
529  int4 block2Position(const FlowBlock *bl) const;
530  static bool isReachable(PcodeOp *op);
531 public:
533  JumpTable(const JumpTable *op2);
534  ~JumpTable(void);
535  bool isRecovered(void) const { return !addresstable.empty(); }
536  bool isLabelled(void) const { return !label.empty(); }
537  bool isOverride(void) const;
538  bool isPossibleMultistage(void) const { return (addresstable.size()==1); }
539  int4 getStage(void) const { return recoverystage; }
540  int4 numEntries(void) const { return addresstable.size(); }
541  uintb getSwitchVarConsume(void) const { return switchVarConsume; }
542  int4 getDefaultBlock(void) const { return defaultBlock; }
543  const Address &getOpAddress(void) const { return opaddress; }
544  PcodeOp *getIndirectOp(void) const { return indirect; }
545  void setIndirectOp(PcodeOp *ind) { opaddress = ind->getAddr(); indirect = ind; }
546  void setMaxTableSize(uint4 val) { maxtablesize = val; }
547  void setNormMax(uint4 maddsub,uint4 mleftright,uint4 mext) {
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;
552  Address getAddressByIndex(int4 i) const { return addresstable[i]; }
553  void setLastAsMostCommon(void);
554  void setDefaultBlock(int4 bl) { defaultBlock = bl; }
555  void setLoadCollect(bool val) { collectloads = val; }
556  void addBlockToSwitch(BlockBasic *bl,uintb lab);
557  void switchOver(const FlowInfo &flow);
558  uintb getLabelByIndex(int4 index) const { return label[index]; }
559  void foldInNormalization(Funcdata *fd);
560  bool foldInGuards(Funcdata *fd) { return jmodel->foldInGuards(fd,this); }
561  void recoverAddresses(Funcdata *fd);
562  void recoverMultistage(Funcdata *fd);
563  bool recoverLabels(Funcdata *fd);
564  bool checkForMultistage(Funcdata *fd);
565  void clear(void);
566  void saveXml(ostream &s) const;
567  void restoreXml(const Element *el);
568 };
569 
572 inline bool JumpTable::IndexPair::operator<(const IndexPair &op2) const
573 
574 {
575  if (blockPosition != op2.blockPosition) return (blockPosition < op2.blockPosition);
576  return (addressIndex < op2.addressIndex);
577 }
578 
582 inline bool JumpTable::IndexPair::compareByPosition(const IndexPair &op1,const IndexPair &op2)
583 
584 {
585  return (op1.blockPosition < op2.blockPosition);
586 }
587 
588 #endif
PathMeld::clear
void clear(void)
Clear this to be an empty container.
Definition: jumptable.cc:907
PathMeld::getEarliestOp
PcodeOp * getEarliestOp(int4 pos) const
Find earliest PcodeOp that has a specific common Varnode as input.
Definition: jumptable.cc:973
rangeutil.hh
Documentation for the CircleRange class.
JumpModel::buildAddresses
virtual void buildAddresses(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable, vector< LoadTable > *loadpoints) const =0
Construct the explicit list of target addresses (the Address Table) from this model.
JumpBasicOverride::setAddresses
void setAddresses(const vector< Address > &adtable)
Manually set the address table for this model.
Definition: jumptable.cc:1649
EmulatePcodeOp::glb
Architecture * glb
The underlying Architecture for the program being emulated.
Definition: emulateutil.hh:43
JumpValuesRange::clone
virtual JumpValues * clone(void) const
Clone this iterator.
Definition: jumptable.cc:312
GuardRecord::oneOffMatch
static int4 oneOffMatch(PcodeOp *op1, PcodeOp *op2)
Return 1 if the two given PcodeOps produce exactly the same value, 0 if otherwise.
Definition: jumptable.cc:634
GuardRecord
A (putative) switch variable Varnode and a constraint imposed by a CBRANCH.
Definition: jumptable.hh:130
EmulateFunction::setExecuteAddress
virtual void setExecuteAddress(const Address &addr)
Set the address of the next instruction to emulate.
Definition: jumptable.cc:131
JumpBasicOverride::getTableSize
virtual int4 getTableSize(void) const
Return the number of entries in the address table.
Definition: jumptable.hh:444
JumpModelTrivial::buildLabels
virtual void buildLabels(Funcdata *fd, vector< Address > &addresstable, vector< uintb > &label, const JumpModel *orig) const
Recover case labels associated with the Address table.
Definition: jumptable.cc:399
JumpTable::isOverride
bool isOverride(void) const
Return true if this table was manually overridden.
Definition: jumptable.cc:2277
JumpModelTrivial::isOverride
virtual bool isOverride(void) const
Return true if this model was manually overridden.
Definition: jumptable.hh:326
FlowBlock
Description of a control-flow block containing PcodeOps.
Definition: block.hh:60
JumpBasic2::findUnnormalized
virtual void findUnnormalized(uint4 maxaddsub, uint4 maxleftright, uint4 maxext)
Recover the unnormalized switch variable.
Definition: jumptable.cc:1603
LowlevelError
The lowest level error generated by the decompiler.
Definition: error.hh:44
JumpAssisted::sanityCheck
virtual bool sanityCheck(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable)
Perform a sanity check on recovered addresses.
Definition: jumptable.hh:488
JumpAssisted::clone
virtual JumpModel * clone(JumpTable *jt) const
Clone this model.
Definition: jumptable.cc:2078
JumpTable::switchOver
void switchOver(const FlowInfo &flow)
Convert absolute addresses to block indices.
Definition: jumptable.cc:2358
JumpValuesRangeDefault::getStartOp
virtual PcodeOp * getStartOp(void) const
Get the PcodeOp associated with the current value.
Definition: jumptable.cc:362
JumpTable::clear
void clear(void)
Clear instance specific data for this jump-table.
Definition: jumptable.cc:2574
JumpValuesRange::isReversible
virtual bool isReversible(void) const
Return true if the current value can be reversed to get a label.
Definition: jumptable.hh:195
JumpModel::findUnnormalized
virtual void findUnnormalized(uint4 maxaddsub, uint4 maxleftright, uint4 maxext)=0
Recover the unnormalized switch variable.
JumpValuesRangeDefault::getSize
virtual uintb getSize(void) const
Return the number of values the variables can take.
Definition: jumptable.cc:322
EmulatePcodeOp
Emulation based on (existing) PcodeOps and Varnodes.
Definition: emulateutil.hh:41
JumpValuesRange::range
CircleRange range
Acceptable range of values for the normalized switch variable.
Definition: jumptable.hh:179
JumpTable
A map from values to control-flow targets within a function.
Definition: jumptable.hh:499
JumpModel::getTableSize
virtual int4 getTableSize(void) const =0
Return the number of entries in the address table.
JumpTable::saveXml
void saveXml(ostream &s) const
Save this jump-table as a <jumptable> XML tag.
Definition: jumptable.cc:2600
JumpValuesRange::getStartVarnode
virtual Varnode * getStartVarnode(void) const
Get the Varnode associated with the current value.
Definition: jumptable.cc:300
JumpValuesRangeDefault::isReversible
virtual bool isReversible(void) const
Return true if the current value can be reversed to get a label.
Definition: jumptable.hh:218
JumpBasic
The basic switch model.
Definition: jumptable.hh:344
JumpAssisted::buildLabels
virtual void buildLabels(Funcdata *fd, vector< Address > &addresstable, vector< uintb > &label, const JumpModel *orig) const
Recover case labels associated with the Address table.
Definition: jumptable.cc:2028
JumpValues::contains
virtual bool contains(uintb val) const =0
Return true if the given value is in the set of possible values.
JumpBasic::findSmallestNormal
void findSmallestNormal(uint4 matchsize)
Find the putative switch variable with the smallest range of values reaching the switch.
Definition: jumptable.cc:1120
JumpModelTrivial::getTableSize
virtual int4 getTableSize(void) const
Return the number of entries in the address table.
Definition: jumptable.hh:327
JumpValuesRange::contains
virtual bool contains(uintb val) const
Return true if the given value is in the set of possible values.
Definition: jumptable.cc:274
JumpModelTrivial::foldInGuards
virtual bool foldInGuards(Funcdata *fd, JumpTable *jump)
Eliminate any guard code involved in computing the switch destination.
Definition: jumptable.hh:333
JumpBasic::isprune
static bool isprune(Varnode *vn)
Do we prune in here in our depth-first search for the normalized switch variable.
Definition: jumptable.cc:416
LoadTable::restoreXml
void restoreXml(const Element *el, Architecture *glb)
Read in this table from a <loadtable> XML description.
Definition: jumptable.cc:34
JumpBasicOverride::buildAddresses
virtual void buildAddresses(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable, vector< LoadTable > *loadpoints) const
Construct the explicit list of target addresses (the Address Table) from this model.
Definition: jumptable.cc:1850
JumpBasic::getTableSize
virtual int4 getTableSize(void) const
Return the number of entries in the address table.
Definition: jumptable.hh:381
JumpAssisted::buildAddresses
virtual void buildAddresses(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable, vector< LoadTable > *loadpoints) const
Construct the explicit list of target addresses (the Address Table) from this model.
Definition: jumptable.cc:1993
JumpValuesRangeDefault::contains
virtual bool contains(uintb val) const
Return true if the given value is in the set of possible values.
Definition: jumptable.cc:328
JumpValuesRangeDefault::initializeForReading
virtual bool initializeForReading(void) const
Initialize this for iterating over the set of possible values.
Definition: jumptable.cc:336
JumpBasic::varnodeIndex
int4 varnodeIndex
Position of the normalized switch Varnode within PathMeld.
Definition: jumptable.hh:349
JumpBasic::isOverride
virtual bool isOverride(void) const
Return true if this model was manually overridden.
Definition: jumptable.hh:380
JumpAssisted::findUnnormalized
virtual void findUnnormalized(uint4 maxaddsub, uint4 maxleftright, uint4 maxext)
Recover the unnormalized switch variable.
Definition: jumptable.hh:484
FlowInfo
A class for generating the control-flow structure for a single function.
Definition: flow.hh:56
JumpModelTrivial::foldInNormalization
virtual Varnode * foldInNormalization(Funcdata *fd, PcodeOp *indop)
Do normalization of the given switch specific to this model.
Definition: jumptable.hh:332
Element
An XML element. A node in the DOM tree.
Definition: xml.hh:150
GuardRecord::quasiCopy
static Varnode * quasiCopy(Varnode *vn, int4 &bitsPreserved)
Compute the source of a quasi-COPY chain for the given Varnode.
Definition: jumptable.cc:669
JumpValuesRangeDefault::clone
virtual JumpValues * clone(void) const
Clone this iterator.
Definition: jumptable.cc:368
BlockBasic
A basic block for p-code operations.
Definition: block.hh:365
JumpTable::JumpTable
JumpTable(Architecture *g, Address ad=Address())
Constructor.
Definition: jumptable.cc:2210
JumpBasic::analyzeGuards
void analyzeGuards(BlockBasic *bl, int4 pathout)
Analyze CBRANCHs leading up to the given basic-block as a potential switch guard.
Definition: jumptable.cc:996
JumpAssisted::foldInGuards
virtual bool foldInGuards(Funcdata *fd, JumpTable *jump)
Eliminate any guard code involved in computing the switch destination.
Definition: jumptable.cc:2070
PcodeOp
Lowest level operation of the p-code language.
Definition: op.hh:58
JumpBasicOverride::sanityCheck
virtual bool sanityCheck(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable)
Perform a sanity check on recovered addresses.
Definition: jumptable.hh:451
Architecture
Manager for all the major decompiler subsystems.
Definition: architecture.hh:119
JumpBasic::sanityCheck
virtual bool sanityCheck(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable)
Perform a sanity check on recovered addresses.
Definition: jumptable.cc:1445
JumpValuesRange::getValue
virtual uintb getValue(void) const
Get the current value.
Definition: jumptable.cc:294
JumpValuesRange::normqvn
Varnode * normqvn
Varnode representing the normalized switch variable.
Definition: jumptable.hh:180
JumpValues::isReversible
virtual bool isReversible(void) const =0
Return true if the current value can be reversed to get a label.
JumptableThunkError
Exception thrown for a thunk mechanism that looks like a jump-table.
Definition: jumptable.hh:28
PathMeld
All paths from a (putative) switch variable to the CPUI_BRANCHIND.
Definition: jumptable.hh:63
JumpBasic::pathMeld
PathMeld pathMeld
Set of PcodeOps and Varnodes producing the final target addresses.
Definition: jumptable.hh:347
JumpTable::setOverride
void setOverride(const vector< Address > &addrtable, const Address &naddr, uintb h, uintb sv)
Force manual override information on this jump-table.
Definition: jumptable.cc:2296
JumpAssisted::isOverride
virtual bool isOverride(void) const
Return true if this model was manually overridden.
Definition: jumptable.hh:480
JumpValues::getSize
virtual uintb getSize(void) const =0
Return the number of values the variables can take.
JumpBasicOverride::isOverride
virtual bool isOverride(void) const
Return true if this model was manually overridden.
Definition: jumptable.hh:443
JumpModelTrivial::findUnnormalized
virtual void findUnnormalized(uint4 maxaddsub, uint4 maxleftright, uint4 maxext)
Recover the unnormalized switch variable.
Definition: jumptable.hh:330
LoadTable
A description where and how data was loaded from memory.
Definition: jumptable.hh:41
JumpTable::recoverLabels
bool recoverLabels(Funcdata *fd)
Recover the case labels for this jump-table.
Definition: jumptable.cc:2522
JumpBasic::foldInNormalization
virtual Varnode * foldInNormalization(Funcdata *fd, PcodeOp *indop)
Do normalization of the given switch specific to this model.
Definition: jumptable.cc:1419
LoadTable::collapseTable
static void collapseTable(vector< LoadTable > &table)
Collapse a sequence of table descriptions.
Definition: jumptable.cc:51
JumpModel::jumptable
JumpTable * jumptable
The jump-table that is building this model.
Definition: jumptable.hh:234
JumpModelTrivial::clone
virtual JumpModel * clone(JumpTable *jt) const
Clone this model.
Definition: jumptable.cc:406
Varnode
A low-level variable or contiguous set of bytes described by an Address and a size.
Definition: varnode.hh:65
PathMeld::meld
void meld(vector< PcodeOpNode > &path)
Meld a new path into this container.
Definition: jumptable.cc:918
JumpTable::recoverMultistage
void recoverMultistage(Funcdata *fd)
Recover jump-table addresses keeping track of a possible previous stage.
Definition: jumptable.cc:2478
LoadTable::saveXml
void saveXml(ostream &s) const
Save a description of this as an <loadtable> XML tag.
Definition: jumptable.cc:21
JumpBasic2
A basic jump-table model with an added default address path.
Definition: jumptable.hh:405
JumpBasic::buildLabels
virtual void buildLabels(Funcdata *fd, vector< Address > &addresstable, vector< uintb > &label, const JumpModel *orig) const
Recover case labels associated with the Address table.
Definition: jumptable.cc:1379
JumpTable::addBlockToSwitch
void addBlockToSwitch(BlockBasic *bl, uintb lab)
Force a given basic-block to be a switch destination.
Definition: jumptable.cc:2343
EmulateFunction::emulatePath
uintb emulatePath(uintb val, const PathMeld &pathMeld, PcodeOp *startop, Varnode *startvn)
Execute from a given starting point and value to the common end-point of the path set.
Definition: jumptable.cc:180
JumpBasic::jrange
JumpValuesRange * jrange
Range of values for the (normalized) switch variable.
Definition: jumptable.hh:346
JumpBasic::backup2Switch
static uintb backup2Switch(Funcdata *fd, uintb output, Varnode *outvn, Varnode *invn)
Back up the constant value in the output Varnode to the value in the input Varnode.
Definition: jumptable.cc:464
emulateutil.hh
(Lightweight) emulation interface for executing PcodeOp objects within a syntax tree or for executing...
JumpModel::isOverride
virtual bool isOverride(void) const =0
Return true if this model was manually overridden.
JumpTable::numIndicesByBlock
int4 numIndicesByBlock(const FlowBlock *bl) const
Return the number of address table entries that target the given basic-block.
Definition: jumptable.cc:2268
JumpBasic::normalvn
Varnode * normalvn
Normalized switch Varnode.
Definition: jumptable.hh:350
JumpBasic::ispoint
static bool ispoint(Varnode *vn)
Is it possible for the given Varnode to be a switch variable?
Definition: jumptable.cc:428
EmulateFunction::getVarnodeValue
virtual uintb getVarnodeValue(Varnode *vn) const
Given a specific Varnode, retrieve the current value for it from the machine state.
Definition: jumptable.cc:143
JumpBasic::markModel
void markModel(bool val)
Mark (or unmark) all PcodeOps involved in the model.
Definition: jumptable.cc:1208
JumpValues::getValue
virtual uintb getValue(void) const =0
Get the current value.
JumpModel
A jump-table execution model.
Definition: jumptable.hh:232
Address
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
JumpValuesRange::getSize
virtual uintb getSize(void) const
Return the number of values the variables can take.
Definition: jumptable.cc:268
GuardRecord::valueMatch
int4 valueMatch(Varnode *vn2, Varnode *baseVn2, int4 bitsPreserved2) const
Determine if this guard applies to the given Varnode.
Definition: jumptable.cc:587
JumpTable::setLastAsMostCommon
void setLastAsMostCommon(void)
Set the most common jump-table target to be the last address in the table.
Definition: jumptable.cc:2332
JumpBasic::findUnnormalized
virtual void findUnnormalized(uint4 maxaddsub, uint4 maxleftright, uint4 maxext)
Recover the unnormalized switch variable.
Definition: jumptable.cc:1335
Funcdata
Container for data structures associated with a single function.
Definition: funcdata.hh:45
JumpValues::getStartOp
virtual PcodeOp * getStartOp(void) const =0
Get the PcodeOp associated with the current value.
EmulateFunction::EmulateFunction
EmulateFunction(Funcdata *f)
Constructor.
Definition: jumptable.cc:124
LowlevelError::LowlevelError
LowlevelError(const string &s)
Initialize the error with an explanatory string.
Definition: error.hh:47
JumpValuesRange
single entry switch variable that can take a range of values
Definition: jumptable.hh:177
EmulateFunction
A light-weight emulator to calculate switch targets from switch variables.
Definition: jumptable.hh:100
JumpAssistOp
A user defined p-code op for assisting the recovery of jump tables.
Definition: userop.hh:229
JumpBasicOverride::buildLabels
virtual void buildLabels(Funcdata *fd, vector< Address > &addresstable, vector< uintb > &label, const JumpModel *orig) const
Recover case labels associated with the Address table.
Definition: jumptable.cc:1856
JumpBasicOverride::foldInGuards
virtual bool foldInGuards(Funcdata *fd, JumpTable *jump)
Eliminate any guard code involved in computing the switch destination.
Definition: jumptable.hh:450
JumpValues::truncate
virtual void truncate(int4 nm)=0
Truncate the number of values to the given number.
JumpBasic::markFoldableGuards
void markFoldableGuards()
Mark the guard CBRANCHs that are truly part of the model.
Definition: jumptable.cc:1194
JumpBasic::foldInOneGuard
virtual bool foldInOneGuard(Funcdata *fd, GuardRecord &guard, JumpTable *jump)
Eliminate the given guard to this switch.
Definition: jumptable.cc:1241
JumpModelTrivial
A trivial jump-table model, where the BRANCHIND input Varnode is the switch variable.
Definition: jumptable.hh:322
JumpValuesRange::startop
PcodeOp * startop
First PcodeOp in the jump-table calculation.
Definition: jumptable.hh:181
CircleRange
A class for manipulating integer value ranges.
Definition: rangeutil.hh:48
JumpBasicOverride
A basic jump-table model incorporating manual override information.
Definition: jumptable.hh:425
JumpBasicOverride::recoverModel
virtual bool recoverModel(Funcdata *fd, PcodeOp *indop, uint4 matchsize, uint4 maxtablesize)
Attempt to recover details of the model, given a specific BRANCHIND.
Definition: jumptable.cc:1822
JumpBasic::switchvn
Varnode * switchvn
Unnormalized switch Varnode.
Definition: jumptable.hh:351
JumpModelTrivial::buildAddresses
virtual void buildAddresses(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable, vector< LoadTable > *loadpoints) const
Construct the explicit list of target addresses (the Address Table) from this model.
Definition: jumptable.cc:388
EmulateFunction::collectLoadPoints
void collectLoadPoints(vector< LoadTable > &res) const
Recover any LOAD table descriptions.
Definition: jumptable.cc:223
JumpTable::getIndexByBlock
int4 getIndexByBlock(const FlowBlock *bl, int4 i) const
Get the index of the i-th address table entry that corresponds to the given basic-block.
Definition: jumptable.cc:2315
JumpValues::getStartVarnode
virtual Varnode * getStartVarnode(void) const =0
Get the Varnode associated with the current value.
JumpValuesRange::initializeForReading
virtual bool initializeForReading(void) const
Initialize this for iterating over the set of possible values.
Definition: jumptable.cc:280
JumpModelTrivial::sanityCheck
virtual bool sanityCheck(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable)
Perform a sanity check on recovered addresses.
Definition: jumptable.hh:334
JumpModel::foldInGuards
virtual bool foldInGuards(Funcdata *fd, JumpTable *jump)=0
Eliminate any guard code involved in computing the switch destination.
PathMeld::markPaths
void markPaths(bool val, int4 startVarnode)
Mark PcodeOps paths from the given start.
Definition: jumptable.cc:950
JumpModelTrivial::recoverModel
virtual bool recoverModel(Funcdata *fd, PcodeOp *indop, uint4 matchsize, uint4 maxtablesize)
Attempt to recover details of the model, given a specific BRANCHIND.
Definition: jumptable.cc:381
JumpValues::initializeForReading
virtual bool initializeForReading(void) const =0
Initialize this for iterating over the set of possible values.
JumpTable::checkForMultistage
bool checkForMultistage(Funcdata *fd)
Check if this jump-table requires an additional recovery stage.
Definition: jumptable.cc:2685
JumpBasic::foldInGuards
virtual bool foldInGuards(Funcdata *fd, JumpTable *jump)
Eliminate any guard code involved in computing the switch destination.
Definition: jumptable.cc:1428
EmulateFunction::setVarnodeValue
virtual void setVarnodeValue(Varnode *vn, uintb val)
Given a specific Varnode, set the given value for it in the current machine state.
Definition: jumptable.cc:158
JumpBasic::getStride
static int4 getStride(Varnode *vn)
Get the step/stride associated with the Varnode.
Definition: jumptable.cc:441
JumpBasic2::initializeStart
void initializeStart(const PathMeld &pathMeld)
Pass in the prior PathMeld calculation.
Definition: jumptable.cc:1521
JumpModel::buildLabels
virtual void buildLabels(Funcdata *fd, vector< Address > &addresstable, vector< uintb > &label, const JumpModel *orig) const =0
Recover case labels associated with the Address table.
PathMeld::append
void append(const PathMeld &op2)
Append a new set of paths to this set of paths.
Definition: jumptable.cc:897
JumpBasic::recoverModel
virtual bool recoverModel(Funcdata *fd, PcodeOp *indop, uint4 matchsize, uint4 maxtablesize)
Attempt to recover details of the model, given a specific BRANCHIND.
Definition: jumptable.cc:1290
JumpValuesRange::getStartOp
virtual PcodeOp * getStartOp(void) const
Get the PcodeOp associated with the current value.
Definition: jumptable.cc:306
JumpValues::next
virtual bool next(void) const =0
Advance the iterator, return true if there is another value.
JumpValuesRange::next
virtual bool next(void) const
Advance the iterator, return true if there is another value.
Definition: jumptable.cc:288
JumpTable::restoreXml
void restoreXml(const Element *el)
Recover this jump-table from a <jumptable> XML tag.
Definition: jumptable.cc:2633
JumpModel::sanityCheck
virtual bool sanityCheck(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable)=0
Perform a sanity check on recovered addresses.
JumpValuesRange::truncate
virtual void truncate(int4 nm)
Definition: jumptable.cc:257
JumpTable::foldInNormalization
void foldInNormalization(Funcdata *fd)
Hide the normalization code for the switch.
Definition: jumptable.cc:2404
JumpValuesRange::curval
uintb curval
The current value pointed to be the iterator.
Definition: jumptable.hh:182
JumpBasic::calcRange
void calcRange(Varnode *vn, CircleRange &rng) const
Calculate the range of values in the given Varnode that direct control-flow to the switch.
Definition: jumptable.cc:1065
JumpBasic2::clone
virtual JumpModel * clone(JumpTable *jt) const
Clone this model.
Definition: jumptable.cc:1623
JumpBasic::selectguards
vector< GuardRecord > selectguards
Any guards associated with model.
Definition: jumptable.hh:348
JumpAssisted::getTableSize
virtual int4 getTableSize(void) const
Return the number of entries in the address table.
Definition: jumptable.hh:481
JumptableNotReachableError
Exception thrown is there are no legal flows to a switch.
Definition: jumptable.hh:33
JumpModel::recoverModel
virtual bool recoverModel(Funcdata *fd, PcodeOp *indop, uint4 matchsize, uint4 maxtablesize)=0
Attempt to recover details of the model, given a specific BRANCHIND.
JumpBasicOverride::clone
virtual JumpModel * clone(JumpTable *jt) const
Clone this model.
Definition: jumptable.cc:1877
JumpModel::clone
virtual JumpModel * clone(JumpTable *jt) const =0
Clone this model.
JumpBasic::clone
virtual JumpModel * clone(JumpTable *jt) const
Clone this model.
Definition: jumptable.cc:1483
JumpValuesRangeDefault
A jump-table starting range with two possible execution paths.
Definition: jumptable.hh:203
JumpBasic::flowsOnlyToModel
bool flowsOnlyToModel(Varnode *vn, PcodeOp *trailOp)
Check if the given Varnode flows to anything other than this model.
Definition: jumptable.cc:1228
JumpValues
An iterator over values a switch variable can take.
Definition: jumptable.hh:156
JumpBasic::buildAddresses
virtual void buildAddresses(Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable, vector< LoadTable > *loadpoints) const
Construct the explicit list of target addresses (the Address Table) from this model.
Definition: jumptable.cc:1306
JumpBasic::findDeterminingVarnodes
void findDeterminingVarnodes(PcodeOp *op, int4 slot)
Calculate the initial set of Varnodes that might be switch variables.
Definition: jumptable.cc:506
JumpAssisted::recoverModel
virtual bool recoverModel(Funcdata *fd, PcodeOp *indop, uint4 matchsize, uint4 maxtablesize)
Attempt to recover details of the model, given a specific BRANCHIND.
Definition: jumptable.cc:1955
JumpValues::clone
virtual JumpValues * clone(void) const =0
Clone this iterator.
GuardRecord::GuardRecord
GuardRecord(PcodeOp *bOp, PcodeOp *rOp, int4 path, const CircleRange &rng, Varnode *v)
Constructor.
Definition: jumptable.cc:564
JumpBasic::findNormalized
void findNormalized(Funcdata *fd, BlockBasic *rootbl, int4 pathout, uint4 matchsize, uint4 maxtablesize)
Do all the work necessary to recover the normalized switch variable.
Definition: jumptable.cc:1159
JumpModel::foldInNormalization
virtual Varnode * foldInNormalization(Funcdata *fd, PcodeOp *indop)=0
Do normalization of the given switch specific to this model.
JumpAssisted
A jump-table model assisted by pseudo-op directives in the code.
Definition: jumptable.hh:472
JumpAssisted::foldInNormalization
virtual Varnode * foldInNormalization(Funcdata *fd, PcodeOp *indop)
Do normalization of the given switch specific to this model.
Definition: jumptable.cc:2055
JumpTable::recoverAddresses
void recoverAddresses(Funcdata *fd)
Recover the raw jump-table addresses (the address table)
Definition: jumptable.cc:2453
JumpBasic2::recoverModel
virtual bool recoverModel(Funcdata *fd, PcodeOp *indop, uint4 matchsize, uint4 maxtablesize)
Attempt to recover details of the model, given a specific BRANCHIND.
Definition: jumptable.cc:1533
JumpValuesRangeDefault::getStartVarnode
virtual Varnode * getStartVarnode(void) const
Get the Varnode associated with the current value.
Definition: jumptable.cc:356
JumpTable::~JumpTable
~JumpTable(void)
Destructor.
Definition: jumptable.cc:2255
JumpValuesRangeDefault::next
virtual bool next(void) const
Advance the iterator, return true if there is another value.
Definition: jumptable.cc:345
PathMeld::set
void set(const PathMeld &op2)
Copy paths from another container.
Definition: jumptable.cc:863
JumpBasicOverride::JumpBasicOverride
JumpBasicOverride(JumpTable *jt)
Constructor.
Definition: jumptable.cc:1640