My Project
funcdata.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  */
16 #ifndef __CPUI_FUNCDATA__
17 #define __CPUI_FUNCDATA__
18 
21 
22 #include "architecture.hh"
23 #include "override.hh"
24 #include "heritage.hh"
25 #include "merge.hh"
26 #include "dynamic.hh"
27 
28 class FlowInfo;
29 
45 class Funcdata {
46  enum {
47  highlevel_on = 1,
48  blocks_generated = 2,
49  blocks_unreachable = 4,
50  processing_started = 8,
51  processing_complete = 0x10,
52  typerecovery_on = 0x20,
53  no_code = 0x40,
54  jumptablerecovery_on = 0x80,
55  jumptablerecovery_dont = 0x100,
56  restart_pending = 0x200,
57  unimplemented_present = 0x400,
58  baddata_present = 0x800,
59  double_precis_on = 0x1000,
60  big_varnodes_generated = 0x2000
61  };
62  uint4 flags;
63  uint4 clean_up_index;
64  uint4 high_level_index;
65  uint4 cast_phase_index;
66  Architecture *glb;
67  string name;
68  int4 size;
69  Address baseaddr;
70  FuncProto funcp;
71  ScopeLocal *localmap;
72 
73  vector<FuncCallSpecs *> qlst;
74  vector<JumpTable *> jumpvec;
75 
76  VarnodeBank vbank;
77  PcodeOpBank obank;
78  BlockGraph bblocks;
79  BlockGraph sblocks;
80  Heritage heritage;
81  Merge covermerge;
82  ParamActive *activeoutput;
83  Override localoverride;
84  map<VarnodeData,const LanedRegister *> lanedMap;
85 
86  // Low level Varnode functions
87  void setVarnodeProperties(Varnode *vn) const;
88  HighVariable *assignHigh(Varnode *vn);
89  bool syncVarnodesWithSymbol(VarnodeLocSet::const_iterator &iter,uint4 flags,Datatype *ct);
90  bool descend2Undef(Varnode *vn);
91 
92  void splitUses(Varnode *vn);
93  Varnode *cloneVarnode(const Varnode *vn);
94  void destroyVarnode(Varnode *vn);
95  // Low level op functions
96  void opZeroMulti(PcodeOp *op);
97  // Low level block functions
98  void blockRemoveInternal(BlockBasic *bb,bool unreachable);
99  void branchRemoveInternal(BlockBasic *bb,int4 num);
100  void pushMultiequals(BlockBasic *bb);
101  void clearBlocks(void);
102  void structureReset(void);
103  int4 stageJumpTable(JumpTable *jt,PcodeOp *op,FlowInfo *flow);
104  void switchOverJumpTables(const FlowInfo &flow);
105  void clearJumpTables(void);
106 
107  void sortCallSpecs(void);
108  void deleteCallSpecs(PcodeOp *op);
109  void clearCallSpecs(void);
110 
111  BlockBasic *nodeSplitBlockEdge(BlockBasic *b,int4 inedge);
112  PcodeOp *nodeSplitCloneOp(PcodeOp *op);
113  void nodeSplitCloneVarnode(PcodeOp *op,PcodeOp *newop);
114  void nodeSplitRawDuplicate(BlockBasic *b,BlockBasic *bprime);
115  void nodeSplitInputPatch(BlockBasic *b,BlockBasic *bprime,int4 inedge);
116  static bool descendantsOutside(Varnode *vn);
117  static void saveVarnodeXml(ostream &s,VarnodeLocSet::const_iterator iter,VarnodeLocSet::const_iterator enditer);
118  static bool checkIndirectUse(Varnode *vn);
119  static PcodeOp *findPrimaryBranch(PcodeOpTree::const_iterator iter,PcodeOpTree::const_iterator enditer,
120  bool findbranch,bool findcall,bool findreturn);
121 public:
122  Funcdata(const string &nm,Scope *conf,const Address &addr,int4 sz=0);
123  ~Funcdata(void);
124  const string &getName(void) const { return name; }
125  const Address &getAddress(void) const { return baseaddr; }
126  int4 getSize(void) const { return size; }
127  Architecture *getArch(void) const { return glb; }
128  bool isHighOn(void) const { return ((flags&highlevel_on)!=0); }
129  bool isProcStarted(void) const { return ((flags&processing_started)!=0); }
130  bool isProcComplete(void) const { return ((flags&processing_complete)!=0); }
131  bool hasUnreachableBlocks(void) const { return ((flags&blocks_unreachable)!=0); }
132  bool isTypeRecoveryOn(void) const { return ((flags&typerecovery_on)!=0); }
133  bool hasNoCode(void) const { return ((flags & no_code)!=0); }
134  void setNoCode(bool val) { if (val) flags |= no_code; else flags &= ~no_code; }
135  bool isLanedRegComplete(void) const { return ((flags&big_varnodes_generated)!=0); }
136  void setLanedRegGenerated(void) { flags |= big_varnodes_generated; }
137 
141  void setJumptableRecovery(bool val) { if (val) flags &= ~jumptablerecovery_dont; else flags |= jumptablerecovery_dont; }
142 
143  bool isJumptableRecoveryOn(void) const { return ((flags & jumptablerecovery_on)!=0); }
144 
148  void setDoublePrecisRecovery(bool val) { if (val) flags |= double_precis_on; else flags &= ~double_precis_on; }
149 
150  bool isDoublePrecisOn(void) const { return ((flags & double_precis_on)!=0); }
151  bool hasNoStructBlocks(void) const { return (sblocks.getSize() == 0); }
152  void clear(void);
153  void warning(const string &txt,const Address &ad) const;
154  void warningHeader(const string &txt) const;
155  void startProcessing(void);
156  void stopProcessing(void);
157  bool startTypeRecovery(void);
158  void startCastPhase(void) { cast_phase_index = vbank.getCreateIndex(); }
159  uint4 getCastPhaseIndex(void) const { return cast_phase_index; }
160  uint4 getHighLevelIndex(void) const { return high_level_index; }
161  void startCleanUp(void) { clean_up_index = vbank.getCreateIndex(); }
162  uint4 getCleanUpIndex(void) const { return clean_up_index; }
163 
164  void followFlow(const Address &baddr,const Address &eadddr,uint4 insn_max);
165  void truncatedFlow(const Funcdata *fd,const FlowInfo *flow);
166  bool inlineFlow(Funcdata *inlinefd,FlowInfo &flow,PcodeOp *callop);
167  void overrideFlow(const Address &addr,uint4 type);
168  void doLiveInject(InjectPayload *payload,const Address &addr,BlockBasic *bl,list<PcodeOp *>::iterator pos);
169 
170  void printRaw(ostream &s) const;
171  void printVarnodeTree(ostream &s) const;
172  void printBlockTree(ostream &s) const;
173  void printLocalRange(ostream &s) const;
174  void saveXml(ostream &s,uint8 id,bool savetree) const;
175  uint8 restoreXml(const Element *el);
176  void saveXmlJumpTable(ostream &s) const;
177  void restoreXmlJumpTable(const Element *el);
178  void saveXmlTree(ostream &s) const;
179  void saveXmlHigh(ostream &s) const;
180 
181  Override &getOverride(void) { return localoverride; }
182 
186  void setRestartPending(bool val) { flags = val ? (flags|restart_pending) : (flags & ~((uint4)restart_pending)); }
187 
191  bool hasRestartPending(void) const { return ((flags&restart_pending)!=0); }
192 
196  bool hasUnimplemented(void) const { return ((flags&unimplemented_present)!=0); }
197 
198  bool hasBadData(void) const { return ((flags&baddata_present)!=0); }
199  void spacebase(void);
202  void spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const Address &rampoint,uintb origval,int4 origsize);
203 
208  int4 numHeritagePasses(AddrSpace *spc) { return heritage.numHeritagePasses(spc); }
209 
213  void seenDeadcode(AddrSpace *spc) { heritage.seenDeadCode(spc); }
214 
219  void setDeadCodeDelay(AddrSpace *spc,int4 delay) { heritage.setDeadCodeDelay(spc,delay); }
220 
225  bool deadRemovalAllowed(AddrSpace *spc) const { return heritage.deadRemovalAllowed(spc); }
226 
231  bool deadRemovalAllowedSeen(AddrSpace *spc) { return heritage.deadRemovalAllowedSeen(spc); }
232 
237  bool isHeritaged(Varnode *vn) { return (heritage.heritagePass(vn->getAddr())>=0); }
238 
239  const list<LoadGuard> &getLoadGuards(void) const { return heritage.getLoadGuards(); }
240  const list<LoadGuard> &getStoreGuards(void) const { return heritage.getStoreGuards(); }
241  const LoadGuard *getStoreGuard(PcodeOp *op) const { return heritage.getStoreGuard(op); }
242 
243  // Function prototype and call specification routines
244  int4 numCalls(void) const { return qlst.size(); }
245  FuncCallSpecs *getCallSpecs(int4 i) const { return qlst[i]; }
246  FuncCallSpecs *getCallSpecs(const PcodeOp *op) const;
248  int4 fillinExtrapop(void);
249 
250  // Varnode routines
251  int4 numVarnodes(void) const { return vbank.numVarnodes(); }
252  Varnode *newVarnodeOut(int4 s,const Address &m,PcodeOp *op);
253  Varnode *newUniqueOut(int4 s,PcodeOp *op);
254  Varnode *newVarnode(int4 s,const Address &m,Datatype *ct=(Datatype *)0);
255  Varnode *newConstant(int4 s,uintb constant_val);
256  Varnode *newVarnode(int4 s,AddrSpace *base,uintb off);
260  Varnode *newUnique(int4 s,Datatype *ct=(Datatype *)0);
261  Varnode *newCodeRef(const Address &m);
263  void adjustInputVarnodes(const Address &addr,int4 size);
264  void deleteVarnode(Varnode *vn) { vbank.destroy(vn); }
265 
271  Varnode *findCoveredInput(int4 s,const Address &loc) const { return vbank.findCoveredInput(s,loc); }
272 
278  Varnode *findCoveringInput(int4 s,const Address &loc) const { return vbank.findCoveringInput(s,loc); }
279 
285  Varnode *findVarnodeInput(int4 s,const Address &loc) const { return vbank.findInput(s,loc); }
286 
294  Varnode *findVarnodeWritten(int4 s,const Address &loc,const Address &pc,uintm uniq=~((uintm)0)) const {
295  return vbank.find(s,loc,pc,uniq); }
296 
298  VarnodeLocSet::const_iterator beginLoc(void) const { return vbank.beginLoc(); }
299 
301  VarnodeLocSet::const_iterator endLoc(void) const { return vbank.endLoc(); }
302 
304  VarnodeLocSet::const_iterator beginLoc(AddrSpace *spaceid) const { return vbank.beginLoc(spaceid); }
305 
307  VarnodeLocSet::const_iterator endLoc(AddrSpace *spaceid) const { return vbank.endLoc(spaceid); }
308 
310  VarnodeLocSet::const_iterator beginLoc(const Address &addr) const { return vbank.beginLoc(addr); }
311 
313  VarnodeLocSet::const_iterator endLoc(const Address &addr) const { return vbank.endLoc(addr); }
314 
316  VarnodeLocSet::const_iterator beginLoc(int4 s,const Address &addr) const { return vbank.beginLoc(s,addr); }
317 
319  VarnodeLocSet::const_iterator endLoc(int4 s,const Address &addr) const { return vbank.endLoc(s,addr); }
320 
322  VarnodeLocSet::const_iterator beginLoc(int4 s,const Address &addr,uint4 fl) const { return vbank.beginLoc(s,addr,fl); }
323 
325  VarnodeLocSet::const_iterator endLoc(int4 s,const Address &addr,uint4 fl) const { return vbank.endLoc(s,addr,fl); }
326 
328  VarnodeLocSet::const_iterator beginLoc(int4 s,const Address &addr,const Address &pc,uintm uniq=~((uintm)0)) const {
329  return vbank.beginLoc(s,addr,pc,uniq); }
330 
332  VarnodeLocSet::const_iterator endLoc(int4 s,const Address &addr,const Address &pc,uintm uniq=~((uintm)0)) const {
333  return vbank.endLoc(s,addr,pc,uniq); }
334 
336  VarnodeDefSet::const_iterator beginDef(void) const { return vbank.beginDef(); }
337 
339  VarnodeDefSet::const_iterator endDef(void) const { return vbank.endDef(); }
340 
342  VarnodeDefSet::const_iterator beginDef(uint4 fl) const { return vbank.beginDef(fl); }
343 
345  VarnodeDefSet::const_iterator endDef(uint4 fl) const { return vbank.endDef(fl); }
346 
348  VarnodeDefSet::const_iterator beginDef(uint4 fl,const Address &addr) const { return vbank.beginDef(fl,addr); }
349 
351  VarnodeDefSet::const_iterator endDef(uint4 fl,const Address &addr) const { return vbank.endDef(fl,addr); }
352 
353  void markLanedVarnode(Varnode *vn,const LanedRegister *lanedReg);
354  map<VarnodeData,const LanedRegister *>::const_iterator beginLaneAccess(void) const { return lanedMap.begin(); }
355  map<VarnodeData,const LanedRegister *>::const_iterator endLaneAccess(void) const { return lanedMap.end(); }
356  void clearLanedAccessMap(void) { lanedMap.clear(); }
357 
358  HighVariable *findHigh(const string &name) const;
359  void mapGlobals(void);
360  bool checkCallDoubleUse(const PcodeOp *opmatch,const PcodeOp *op,const Varnode *vn,const ParamTrial &trial) const;
361  bool onlyOpUse(const Varnode *invn,const PcodeOp *opmatch,const ParamTrial &trial) const;
362  bool ancestorOpUse(int4 maxlevel,const Varnode *invn,const PcodeOp *op,ParamTrial &trial) const;
363  bool syncVarnodesWithSymbols(const ScopeLocal *lm,bool typesyes);
364  void transferVarnodeProperties(Varnode *vn,Varnode *newVn,int4 lsbOffset);
365  bool fillinReadOnly(Varnode *vn);
366  bool replaceVolatile(Varnode *vn);
367  void markIndirectOnly(void);
368  void totalReplace(Varnode *vn,Varnode *newvn);
369  void totalReplaceConstant(Varnode *vn,uintb val);
370  ScopeLocal *getScopeLocal(void) { return localmap; }
371  const ScopeLocal *getScopeLocal(void) const { return localmap; }
372  FuncProto &getFuncProto(void) { return funcp; }
373  const FuncProto &getFuncProto(void) const { return funcp; }
374  void initActiveOutput(void);
375  void clearActiveOutput(void) {
377  if (activeoutput != (ParamActive *)0) delete activeoutput;
378  activeoutput = (ParamActive *)0;
379  }
380  ParamActive *getActiveOutput(void) const { return activeoutput; }
381  void setHighLevel(void);
382  void clearDeadVarnodes(void);
383  void calcNZMask(void);
384  void clearDeadOps(void) { obank.destroyDead(); }
385  void clearSymbolLinks(HighVariable *high);
386  void remapVarnode(Varnode *vn,Symbol *sym,const Address &usepoint);
387  void remapDynamicVarnode(Varnode *vn,Symbol *sym,const Address &usepoint,uint8 hash);
388  Symbol *linkSymbol(Varnode *vn);
390  Varnode *findLinkedVarnode(SymbolEntry *entry) const;
391  void findLinkedVarnodes(SymbolEntry *entry,vector<Varnode *> &res) const;
392  void buildDynamicSymbol(Varnode *vn);
393  bool attemptDynamicMapping(SymbolEntry *entry,DynamicHash &dhash);
395  Merge &getMerge(void) { return covermerge; }
396 
397  // op routines
398  PcodeOp *newOp(int4 inputs,const Address &pc);
399  PcodeOp *newOp(int4 inputs,const SeqNum &sq);
400  PcodeOp *newOpBefore(PcodeOp *follow,OpCode opc,Varnode *in1,Varnode *in2,Varnode *in3=(Varnode *)0);
401  PcodeOp *cloneOp(const PcodeOp *op,const SeqNum &seq);
402  PcodeOp *getFirstReturnOp(void) const;
403  PcodeOp *newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 size,uint4 extraFlags);
404  PcodeOp *newIndirectCreation(PcodeOp *indeffect,const Address &addr,int4 size,bool possibleout);
405  void markIndirectCreation(PcodeOp *indop,bool possibleOutput);
406  PcodeOp *findOp(const SeqNum &sq) { return obank.findOp(sq); }
407  void opInsertBefore(PcodeOp *op,PcodeOp *follow);
408  void opInsertAfter(PcodeOp *op,PcodeOp *prev);
409  void opInsertBegin(PcodeOp *op,BlockBasic *bl);
410  void opInsertEnd(PcodeOp *op,BlockBasic *bl);
411 
413  void opDeadInsertAfter(PcodeOp *op,PcodeOp *prev) { obank.insertAfterDead(op,prev); }
414 
415  void opHeritage(void) { heritage.heritage(); }
416  void opSetOpcode(PcodeOp *op,OpCode opc);
417  void opMarkHalt(PcodeOp *op,uint4 flag);
418  void opSetOutput(PcodeOp *op,Varnode *vn);
419  void opUnsetOutput(PcodeOp *op);
420  void opSetInput(PcodeOp *op,Varnode *vn,int4 slot);
421  void opSwapInput(PcodeOp *op,int4 slot1,int4 slot2);
422  void opUnsetInput(PcodeOp *op,int4 slot);
423  void opInsert(PcodeOp *op,BlockBasic *bl,list<PcodeOp *>::iterator iter);
424  void opUninsert(PcodeOp *op);
425  void opUnlink(PcodeOp *op);
426  void opDestroy(PcodeOp *op);
427  void opDestroyRaw(PcodeOp *op);
428  void opDeadAndGone(PcodeOp *op) { obank.destroy(op); }
429  void opSetAllInput(PcodeOp *op,const vector<Varnode *> &vvec);
430  void opRemoveInput(PcodeOp *op,int4 slot);
431  void opInsertInput(PcodeOp *op,Varnode *vn,int4 slot);
432  void opMarkStartBasic(PcodeOp *op) { op->setFlag(PcodeOp::startbasic); }
433  void opMarkStartInstruction(PcodeOp *op) { op->setFlag(PcodeOp::startmark); }
434  void opMarkNonPrinting(PcodeOp *op) { op->setFlag(PcodeOp::nonprinting); }
435  void opMarkSpecialPrint(PcodeOp *op) { op->setAdditionalFlag(PcodeOp::special_print); }
436  void opMarkNoCollapse(PcodeOp *op) { op->setFlag(PcodeOp::nocollapse); }
439  void opMarkSpacebasePtr(PcodeOp *op) { op->setFlag(PcodeOp::spacebase_ptr); }
440  void opClearSpacebasePtr(PcodeOp *op) { op->clearFlag(PcodeOp::spacebase_ptr); }
441  void opFlipCondition(PcodeOp *op) { op->flipFlag(PcodeOp::boolean_flip); }
442  PcodeOp *target(const Address &addr) const { return obank.target(addr); }
443  Varnode *createStackRef(AddrSpace *spc,uintb off,PcodeOp *op,Varnode *stackptr,bool insertafter);
444  Varnode *opStackLoad(AddrSpace *spc,uintb off,uint4 sz,PcodeOp *op,Varnode *stackptr,bool insertafter);
445  PcodeOp *opStackStore(AddrSpace *spc,uintb off,PcodeOp *op,bool insertafter);
446  void opUndoPtradd(PcodeOp *op,bool finalize);
447 
449  list<PcodeOp *>::const_iterator beginOp(OpCode opc) const { return obank.begin(opc); }
450 
452  list<PcodeOp *>::const_iterator endOp(OpCode opc) const { return obank.end(opc); }
453 
455  list<PcodeOp *>::const_iterator beginOpAlive(void) const { return obank.beginAlive(); }
456 
458  list<PcodeOp *>::const_iterator endOpAlive(void) const { return obank.endAlive(); }
459 
461  list<PcodeOp *>::const_iterator beginOpDead(void) const { return obank.beginDead(); }
462 
464  list<PcodeOp *>::const_iterator endOpDead(void) const { return obank.endDead(); }
465 
467  PcodeOpTree::const_iterator beginOpAll(void) const { return obank.beginAll(); }
468 
470  PcodeOpTree::const_iterator endOpAll(void) const { return obank.endAll(); }
471 
473  PcodeOpTree::const_iterator beginOp(const Address &addr) const { return obank.begin(addr); }
474 
476  PcodeOpTree::const_iterator endOp(const Address &addr) const { return obank.end(addr); }
477 
478  // Jumptable routines
480  JumpTable *findJumpTable(const PcodeOp *op) const;
481  JumpTable *installJumpTable(const Address &addr);
482  JumpTable *recoverJumpTable(PcodeOp *op,FlowInfo *flow,int4 &failuremode);
483  int4 numJumpTables(void) const { return jumpvec.size(); }
484  JumpTable *getJumpTable(int4 i) { return jumpvec[i]; }
485  void removeJumpTable(JumpTable *jt);
486 
487  // Block routines
488  BlockGraph &getStructure(void) { return sblocks; }
489  const BlockGraph &getStructure(void) const { return sblocks; }
490  const BlockGraph &getBasicBlocks(void) const { return bblocks; }
491 
497  void setBasicBlockRange(BlockBasic *bb,const Address &beg,const Address &end) { bb->setInitialRange(beg, end); }
498 
499  void removeDoNothingBlock(BlockBasic *bb);
500  bool removeUnreachableBlocks(bool issuewarning,bool checkexistence);
501  void pushBranch(BlockBasic *bb,int4 slot,BlockBasic *bbnew);
502  void removeBranch(BlockBasic *bb,int4 num);
504  bool fora_block1ishigh,bool forb_block1ishigh,const Address &addr);
505  void nodeSplit(BlockBasic *b,int4 inedge);
506  bool forceGoto(const Address &pcop,const Address &pcdest);
507  void removeFromFlowSplit(BlockBasic *bl,bool swap);
508  void switchEdge(FlowBlock *inblock,BlockBasic *outbefore,FlowBlock *outafter);
509  void spliceBlockBasic(BlockBasic *bl);
510  void installSwitchDefaults(void);
511  static bool replaceLessequal(Funcdata &data,PcodeOp *op);
512  static bool compareCallspecs(const FuncCallSpecs *a,const FuncCallSpecs *b);
513 
514 #ifdef OPACTION_DEBUG
515  void (*jtcallback)(Funcdata &orig,Funcdata &fd);
516  vector<PcodeOp *> modify_list;
517  vector<string> modify_before;
518  int4 opactdbg_count;
519  int4 opactdbg_breakcount;
520  bool opactdbg_on;
521  bool opactdbg_active;
522  bool opactdbg_breakon;
523  vector<Address> opactdbg_pclow;
524  vector<Address> opactdbg_pchigh;
525  vector<uintm> opactdbg_uqlow;
526  vector<uintm> opactdbg_uqhigh;
527  void enableJTCallback(void (*jtcb)(Funcdata &orig,Funcdata &fd)) { jtcallback = jtcb; }
528  void disableJTCallback(void) { jtcallback = (void (*)(Funcdata &orig,Funcdata &fd))0; }
529  void debugActivate(void) { if (opactdbg_on) opactdbg_active=true; }
530  void debugDeactivate(void) { opactdbg_active = false; }
531  void debugModCheck(PcodeOp *op);
532  void debugModClear(void);
533  void debugModPrint(const string &actionname);
534  bool debugBreak(void) const { return opactdbg_on&&opactdbg_breakon; }
535  int4 debugSize(void) const { return opactdbg_pclow.size(); }
536  void debugEnable(void) { opactdbg_on = true; opactdbg_count = 0; }
537  void debugDisable(void) { opactdbg_on = false; }
538  void debugClear(void) {
539  opactdbg_pclow.clear(); opactdbg_pchigh.clear(); opactdbg_uqlow.clear(); opactdbg_uqhigh.clear(); }
540  bool debugCheckRange(PcodeOp *op);
541  void debugSetRange(const Address &pclow,const Address &pchigh,
542  uintm uqlow=~((uintm)0),uintm uqhigh=~((uintm)0));
543  void debugHandleBreak(void) { opactdbg_breakon = false; }
544  void debugSetBreak(int4 count) { opactdbg_breakcount = count; }
545  void debugPrintRange(int4 i) const;
546 #endif
547 };
548 
553 class PcodeEmitFd : public PcodeEmit {
554  Funcdata *fd;
555  virtual void dump(const Address &addr,OpCode opc,VarnodeData *outvar,VarnodeData *vars,int4 isize);
556 public:
557  void setFuncdata(Funcdata *f) { fd = f; }
558 };
559 
568  class State {
569  public:
570  enum {
571  seen_solid0 = 1,
572  seen_solid1 = 2,
573  seen_kill = 4
574  };
575  PcodeOp *op;
576  Varnode *vn;
577  int4 slot;
578  uint4 flags;
579 
584  State(PcodeOp *o,int4 s) {
585  op = o;
586  slot = s;
587  vn = op->getIn(slot);
588  flags = 0;
589  }
590  int4 getSolidSlot(void) const { return ((flags & seen_solid0)!=0) ? 0 : 1; }
591  void markSolid(int4 slot) { flags |= (slot==0) ? seen_solid0 : seen_solid1; }
592  void markKill(void) { flags |= seen_kill; }
593  bool seenSolid(void) const { return ((flags & (seen_solid0|seen_solid1))!=0); }
594  bool seenKill(void) const { return ((flags & seen_kill)!=0); }
595  };
597  enum {
598  enter_node,
599  pop_success,
600  pop_solid,
601  pop_fail,
602  pop_failkill
603  };
604  ParamTrial *trial;
605  vector<State> stateStack;
606  vector<const Varnode *> markedVn;
607  int4 multiDepth;
608  bool allowFailingPath;
609 
613  void mark(Varnode *vn) {
614  markedVn.push_back(vn);
615  vn->setMark();
616  }
617 
618  int4 enterNode(State &state);
619  int4 uponPop(State &state,int4 command);
620  bool checkConditionalExe(State &state);
621 public:
622  bool execute(PcodeOp *op,int4 slot,ParamTrial *t,bool allowFail);
623 };
624 
625 extern int4 opFlipInPlaceTest(PcodeOp *op,vector<PcodeOp *> &fliplist);
626 extern void opFlipInPlaceExecute(Funcdata &data,vector<PcodeOp *> &fliplist);
627 
629 extern PcodeOp *cseFindInBlock(PcodeOp *op,Varnode *vn,BlockBasic *bl,PcodeOp *earliest);
630 extern PcodeOp *cseElimination(Funcdata &data,PcodeOp *op1,PcodeOp *op2);
631 extern void cseEliminateList(Funcdata &data,vector< pair<uintm,PcodeOp *> > &list,
632  vector<Varnode *> &outlist);
633 
634 #endif
bool attemptDynamicMapping(SymbolEntry *entry, DynamicHash &dhash)
Map properties of a dynamic symbol to a Varnode.
Definition: funcdata_varnode.cc:1124
bool deadRemovalAllowed(AddrSpace *spc) const
Return true if it is safe to remove dead code.
Definition: heritage.cc:2397
void updateOpFromSpec(FuncCallSpecs *fc)
Update CALL PcodeOp properties based on its corresponding call specification.
Definition: funcdata.cc:426
void stopProcessing(void)
Mark that processing has completed for this function.
Definition: funcdata.cc:144
A region where processor data is stored.
Definition: space.hh:73
bool hasUnimplemented(void) const
Does this function have instructions marked as unimplemented.
Definition: funcdata.hh:196
A class for analyzing parameters to a sub-function call.
Definition: fspec.hh:1436
PcodeOpTree::const_iterator beginOp(const Address &addr) const
Start of all (alive) PcodeOp objects attached to a specific Address.
Definition: funcdata.hh:473
int4 opFlipInPlaceTest(PcodeOp *op, vector< PcodeOp *> &fliplist)
Trace a boolean value to a set of PcodeOps that can be changed to flip the boolean value...
Definition: funcdata_op.cc:1023
Utilities for building Static Single Assignment (SSA) form.
Description of a control-flow block containing PcodeOps.
Definition: block.hh:60
void clear(void)
Clear out old disassembly.
Definition: funcdata.cc:64
void startCastPhase(void)
Start the cast insertion phase.
Definition: funcdata.hh:158
PcodeOp * newIndirectCreation(PcodeOp *indeffect, const Address &addr, int4 size, bool possibleout)
Build a CPUI_INDIRECT op that indirectly creates a Varnode.
Definition: funcdata_op.cc:660
VarnodeDefSet::const_iterator endDef(void) const
End of all Varnodes sorted by definition address.
Definition: funcdata.hh:339
void opInsertEnd(PcodeOp *op, BlockBasic *bl)
Insert given PcodeOp at the end of a basic block.
Definition: funcdata_op.cc:405
The base datatype class for the decompiler.
Definition: type.hh:62
int4 fillinExtrapop(void)
Recover and return the extrapop for this function.
Definition: funcdata.cc:490
void calcNZMask(void)
Calculate non-zero masks for all Varnodes.
Definition: funcdata_varnode.cc:720
const string & getName(void) const
Get the function&#39;s local symbol name.
Definition: funcdata.hh:124
void removeBranch(BlockBasic *bb, int4 num)
Remove the indicated branch from a basic block.
Definition: funcdata_block.cc:215
Op is marked for special printing.
Definition: op.hh:107
map< VarnodeData, const LanedRegister * >::const_iterator beginLaneAccess(void) const
Beginning iterator over laned accesses.
Definition: funcdata.hh:354
A storage location for a particular Symbol.
Definition: database.hh:51
Varnode * newVarnodeOut(int4 s, const Address &m, PcodeOp *op)
Create a new output Varnode.
Definition: funcdata_varnode.cc:99
void opDestroy(PcodeOp *op)
Remove given PcodeOp and destroy its Varnode operands.
Definition: funcdata_op.cc:201
PcodeOp * newOp(int4 inputs, const Address &pc)
Definition: funcdata_op.cc:295
bool isLanedRegComplete(void) const
Have potential laned registers been generated.
Definition: funcdata.hh:135
VarnodeLocSet::const_iterator endLoc(void) const
End of location list.
Definition: varnode.hh:355
This op cannot be collapsed further.
Definition: op.hh:71
OpCode
The op-code defining a specific p-code operation (PcodeOp)
Definition: opcodes.hh:35
Architecture and associated classes that help manage a single processor architecture and load image...
void warningHeader(const string &txt) const
Add a warning comment as part of the function header.
Definition: funcdata.cc:111
PcodeOp * newIndirectOp(PcodeOp *indeffect, const Address &addr, int4 size, uint4 extraFlags)
Find a representative CPUI_RETURN op for this function.
Definition: funcdata_op.cc:633
bool hasBadData(void) const
Does this function flow into bad data.
Definition: funcdata.hh:198
const FuncProto & getFuncProto(void) const
Get the function&#39;s prototype object.
Definition: funcdata.hh:373
Class for merging low-level Varnodes into high-level HighVariables.
Definition: merge.hh:80
Abstract class for emitting pcode to an application.
Definition: translate.hh:76
Varnode * opStackLoad(AddrSpace *spc, uintb off, uint4 sz, PcodeOp *op, Varnode *stackptr, bool insertafter)
Create a LOAD expression at an offset relative to a spacebase register for a given address space...
Definition: funcdata_op.cc:511
void truncatedFlow(const Funcdata *fd, const FlowInfo *flow)
Generate a clone with truncated control-flow given a partial function.
Definition: funcdata_op.cc:745
void opMarkStartInstruction(PcodeOp *op)
Mark PcodeOp as starting its instruction.
Definition: funcdata.hh:433
JumpTable * getJumpTable(int4 i)
Get the i-th jump-table.
Definition: funcdata.hh:484
Varnode * find(int4 s, const Address &loc, const Address &pc, uintm uniq=~((uintm) 0)) const
Find a Varnode.
Definition: varnode.cc:1064
A hash utility to uniquely identify a temporary Varnode in data-flow.
Definition: dynamic.hh:60
void markIndirectOnly(void)
Mark illegal input Varnodes used only in INDIRECTs.
Definition: funcdata_varnode.cc:679
VarnodeLocSet::const_iterator endLoc(int4 s, const Address &addr) const
End of Varnodes with given storage.
Definition: funcdata.hh:319
Container for data structures associated with a single function.
Definition: funcdata.hh:45
void markIndirectCreation(PcodeOp *indop, bool possibleOutput)
Convert CPUI_INDIRECT into an indirect creation.
Definition: funcdata_op.cc:686
A class for generating the control-flow structure for a single function.
Definition: flow.hh:56
void opUninsert(PcodeOp *op)
Remove the given PcodeOp from its basic block.
Definition: funcdata_op.cc:162
int4 numHeritagePasses(AddrSpace *spc) const
Get the number times heritage was performed for the given address space.
Definition: heritage.cc:2347
uint4 getCleanUpIndex(void) const
Get creation index at the start of clean-up phase.
Definition: funcdata.hh:162
This op is the first in its instruction.
Definition: op.hh:81
VarnodeLocSet::const_iterator beginLoc(int4 s, const Address &addr, uint4 fl) const
Start of Varnodes matching storage and properties.
Definition: funcdata.hh:322
VarnodeLocSet::const_iterator endLoc(void) const
End of all Varnodes sorted by storage.
Definition: funcdata.hh:301
PcodeOpTree::const_iterator endAll(void) const
End of all PcodeOps in sequence number order.
Definition: op.hh:282
bool hasRestartPending(void) const
Does this function need to restart its analysis.
Definition: funcdata.hh:191
const list< LoadGuard > & getStoreGuards(void) const
Get list of STORE ops that are guarded.
Definition: heritage.hh:286
int4 numHeritagePasses(AddrSpace *spc)
Get the number of heritage passes performed for the given address space.
Definition: funcdata.hh:208
void mapGlobals(void)
Make sure there is a Symbol entry for all global Varnodes.
Definition: funcdata_varnode.cc:1302
void setBasicBlockRange(BlockBasic *bb, const Address &beg, const Address &end)
Set the initial ownership range for the given basic block.
Definition: funcdata.hh:497
void clearDeadOps(void)
Delete any dead PcodeOps.
Definition: funcdata.hh:384
PcodeOp * newOpBefore(PcodeOp *follow, OpCode opc, Varnode *in1, Varnode *in2, Varnode *in3=(Varnode *) 0)
Allocate a new PcodeOp with sequence number.
Definition: funcdata_op.cc:606
void overrideFlow(const Address &addr, uint4 type)
Override the control-flow p-code for a particular instruction.
Definition: funcdata_op.cc:917
void opUndoPtradd(PcodeOp *op, bool finalize)
Convert a CPUI_PTRADD back into a CPUI_INT_ADD.
Definition: funcdata_op.cc:529
void removeJumpTable(JumpTable *jt)
Remove/delete the given jump-table.
Definition: funcdata_block.cc:62
void saveXmlTree(ostream &s) const
Save an XML description of the p-code tree to stream.
Definition: funcdata.cc:636
PcodeOp * target(const Address &addr) const
Find the first executing PcodeOp for a target address.
Definition: op.cc:824
bool forceGoto(const Address &pcop, const Address &pcdest)
Force a specific control-flow edge to be marked as unstructured.
Definition: funcdata_block.cc:658
Varnode * getIn(int4 slot)
Get a specific input Varnode to this op.
Definition: op.hh:147
void opInsertBefore(PcodeOp *op, PcodeOp *follow)
Insert given PcodeOp before a specific op.
Definition: funcdata_op.cc:318
uint8 restoreXml(const Element *el)
Restore the state of this function from an XML description.
Definition: funcdata.cc:719
list< PcodeOp * >::const_iterator endOpDead(void) const
End of PcodeOp objects in the dead list.
Definition: funcdata.hh:464
void opMarkCpoolTransformed(PcodeOp *op)
Mark cpool record was visited.
Definition: funcdata.hh:437
bool syncVarnodesWithSymbols(const ScopeLocal *lm, bool typesyes)
Update Varnode properties based on (new) Symbol information.
Definition: funcdata_varnode.cc:804
PcodeOpTree::const_iterator beginOpAll(void) const
Start of all (alive) PcodeOp objects sorted by sequence number.
Definition: funcdata.hh:467
Varnode * createStackRef(AddrSpace *spc, uintb off, PcodeOp *op, Varnode *stackptr, bool insertafter)
Create an INT_ADD PcodeOp calculating an offset to the spacebase register.
Definition: funcdata_op.cc:429
void opUnsetOutput(PcodeOp *op)
Remove output Varnode from the given PcodeOp.
Definition: funcdata_op.cc:50
Utilities for merging low-level Varnodes into high-level variables.
bool hasUnreachableBlocks(void) const
Did this function exhibit unreachable code.
Definition: funcdata.hh:131
bool onlyOpUse(const Varnode *invn, const PcodeOp *opmatch, const ParamTrial &trial) const
Test if the given Varnode seems to only be used by a CALL.
Definition: funcdata_varnode.cc:1411
list< PcodeOp * >::const_iterator endDead(void) const
End of all PcodeOps marked as dead.
Definition: op.hh:300
void printRaw(ostream &s) const
Print raw p-code op descriptions to a stream.
Definition: funcdata.cc:181
PcodeOp * cloneOp(const PcodeOp *op, const SeqNum &seq)
Definition: funcdata_op.cc:566
bool ancestorOpUse(int4 maxlevel, const Varnode *invn, const PcodeOp *op, ParamTrial &trial) const
Test if the given trial Varnode is likely only used for parameter passing.
Definition: funcdata_varnode.cc:1484
void opInsert(PcodeOp *op, BlockBasic *bl, list< PcodeOp *>::iterator iter)
Insert the given PcodeOp at specific point in a basic block.
Definition: funcdata_op.cc:148
FuncProto & getFuncProto(void)
Get the function&#39;s prototype object.
Definition: funcdata.hh:372
void startCleanUp(void)
Start clean-up phase.
Definition: funcdata.hh:161
list< PcodeOp * >::const_iterator beginDead(void) const
Start of all PcodeOps marked as dead.
Definition: op.hh:297
void spliceBlockBasic(BlockBasic *bl)
Merge the given basic block with the block it flows into.
Definition: funcdata_block.cc:971
Merge & getMerge(void)
Get the Merge object for this function.
Definition: funcdata.hh:395
void totalReplace(Varnode *vn, Varnode *newvn)
Replace all read references to the first Varnode with a second Varnode.
Definition: funcdata_varnode.cc:1205
list< PcodeOp * >::const_iterator endOp(OpCode opc) const
End of PcodeOp objects with the given op-code.
Definition: funcdata.hh:452
PcodeOp * opStackStore(AddrSpace *spc, uintb off, PcodeOp *op, bool insertafter)
Create a STORE expression at an offset relative to a spacebase register for a given address space...
Definition: funcdata_op.cc:478
const list< LoadGuard > & getStoreGuards(void) const
Get the list of guarded STOREs.
Definition: funcdata.hh:240
PcodeOp * earliestUseInBlock(Varnode *vn, BlockBasic *bl)
Get the earliest use/read of a Varnode in a specified basic block.
Definition: funcdata_op.cc:1123
void opDestroyRaw(PcodeOp *op)
Remove the given raw PcodeOp.
Definition: funcdata_op.cc:226
int4 getSize(void) const
Get the number of components.
Definition: block.hh:288
void opSetInput(PcodeOp *op, Varnode *vn, int4 slot)
Set a specific input operand for the given PcodeOp.
Definition: funcdata_op.cc:102
A system for sending override commands to the decompiler.
void cseEliminateList(Funcdata &data, vector< pair< uintm, PcodeOp *> > &list, vector< Varnode *> &outlist)
Perform Common Subexpression Elimination on a list of Varnode descendants.
Definition: funcdata_op.cc:1247
VarnodeDefSet::const_iterator beginDef(uint4 fl, const Address &addr) const
Start of (input or free) Varnodes at a given storage address.
Definition: funcdata.hh:348
Output has been determined to be a 1-bit boolean value.
Definition: op.hh:97
void opInsertInput(PcodeOp *op, Varnode *vn, int4 slot)
Insert a new Varnode into the operand list for the given PcodeOp.
Definition: funcdata_op.cc:281
list< PcodeOp * >::const_iterator beginOpAlive(void) const
Start of PcodeOp objects in the alive list.
Definition: funcdata.hh:455
void destroy(PcodeOp *op)
Destroy/retire the given PcodeOp.
Definition: op.cc:724
const BlockGraph & getStructure(void) const
Get the current control-flow structuring hierarchy.
Definition: funcdata.hh:489
void transferVarnodeProperties(Varnode *vn, Varnode *newVn, int4 lsbOffset)
Copy properties from an existing Varnode to a new Varnode.
Definition: funcdata_varnode.cc:490
VarnodeDefSet::const_iterator endDef(uint4 fl) const
End of Varnodes with a given definition property.
Definition: funcdata.hh:345
An active container for a set of p-code operations that can be injected into data-flow.
Definition: pcodeinject.hh:78
VarnodeLocSet::const_iterator endLoc(AddrSpace *spaceid) const
End of Varnodes stored in a given address space.
Definition: funcdata.hh:307
bool isHeritaged(Varnode *vn)
Check if a specific Varnode has been linked in fully to the syntax tree (SSA)
Definition: funcdata.hh:237
ParamActive * getActiveOutput(void) const
Get the return prototype recovery object.
Definition: funcdata.hh:380
void opMarkCalculatedBool(PcodeOp *op)
Mark PcodeOp as having boolean output.
Definition: funcdata.hh:438
void setDoublePrecisRecovery(bool val)
Toggle whether double precision analysis is used.
Definition: funcdata.hh:148
void setFuncdata(Funcdata *f)
Establish the container for this emitter.
Definition: funcdata.hh:557
void setHighLevel(void)
Turn on HighVariable objects for all Varnodes.
Definition: funcdata_varnode.cc:471
list< PcodeOp * >::const_iterator endAlive(void) const
End of all PcodeOps marked as alive.
Definition: op.hh:294
bool isJumptableRecoveryOn(void) const
Is this used for jump-table recovery.
Definition: funcdata.hh:143
map< VarnodeData, const LanedRegister * >::const_iterator endLaneAccess(void) const
Ending iterator over laned accesses.
Definition: funcdata.hh:355
void opMarkHalt(PcodeOp *op, uint4 flag)
Mark given CPUI_RETURN op as a special halt.
Definition: funcdata_op.cc:35
Lowest level operation of the p-code language.
Definition: op.hh:58
void deleteVarnode(Varnode *vn)
Delete the given varnode.
Definition: funcdata.hh:264
void warning(const string &txt, const Address &ad) const
Add a warning comment in the function body.
Definition: funcdata.cc:95
JumpTable * installJumpTable(const Address &addr)
Install a new jump-table for the given Address.
Definition: funcdata_block.cc:458
VarnodeLocSet::const_iterator beginLoc(void) const
Start of all Varnodes sorted by storage.
Definition: funcdata.hh:298
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
void nodeSplit(BlockBasic *b, int4 inedge)
Split control-flow into a basic block, duplicating its p-code into a new block.
Definition: funcdata_block.cc:906
bool isProcStarted(void) const
Has processing of the function started.
Definition: funcdata.hh:129
Varnode * newUniqueOut(int4 s, PcodeOp *op)
Create a new temporary output Varnode.
Definition: funcdata_varnode.cc:122
PcodeOpTree::const_iterator end(const Address &addr) const
End of all PcodeOps at one Address.
Definition: op.cc:887
Set if condition must be false to take branch.
Definition: op.hh:77
void destroyDead(void)
Destroy/retire all PcodeOps in the dead list.
Definition: op.cc:706
void remapDynamicVarnode(Varnode *vn, Symbol *sym, const Address &usepoint, uint8 hash)
Remap a Symbol to a given Varnode using a new dynamic mapping.
Definition: funcdata_varnode.cc:960
bool hasNoCode(void) const
Return true if this function has no code body.
Definition: funcdata.hh:133
VarnodeLocSet::const_iterator endLoc(int4 s, const Address &addr, const Address &pc, uintm uniq=~((uintm) 0)) const
End of Varnodes matching storage and definition address.
Definition: funcdata.hh:332
bool attemptDynamicMappingLate(SymbolEntry *entry, DynamicHash &dhash)
Map the name of a dynamic symbol to a Varnode.
Definition: funcdata_varnode.cc:1154
Varnode * findVarnodeInput(int4 s, const Address &loc) const
Find the input Varnode with the given size and storage address.
Definition: funcdata.hh:285
Container class for PcodeOps associated with a single function.
Definition: op.hh:245
void removeFromFlowSplit(BlockBasic *bl, bool swap)
Remove a basic block splitting its control-flow into two distinct paths.
Definition: funcdata_block.cc:944
void doLiveInject(InjectPayload *payload, const Address &addr, BlockBasic *bl, list< PcodeOp *>::iterator pos)
Inject p-code from a payload into this live function.
Definition: funcdata.cc:804
void totalReplaceConstant(Varnode *vn, uintb val)
Replace every read reference of the given Varnode with a constant value.
Definition: funcdata_varnode.cc:1227
void printLocalRange(ostream &s) const
Print description of memory ranges associated with local scopes.
Definition: funcdata.cc:542
VarnodeLocSet::const_iterator endLoc(int4 s, const Address &addr, uint4 fl) const
End of Varnodes matching storage and properties.
Definition: funcdata.hh:325
list< PcodeOp * >::const_iterator beginOpDead(void) const
Start of PcodeOp objects in the dead list.
Definition: funcdata.hh:461
void setDeadCodeDelay(AddrSpace *spc, int4 delay)
Set delay for a specific space.
Definition: heritage.cc:2383
int4 heritagePass(const Address &addr) const
Get the pass number when the given address was heritaged.
Definition: heritage.hh:274
Varnode * findSpacebaseInput(AddrSpace *id) const
Definition: funcdata.cc:263
void markLanedVarnode(Varnode *vn, const LanedRegister *lanedReg)
Mark Varnode as potential laned register.
Definition: funcdata_varnode.cc:288
PcodeOp * getFirstReturnOp(void) const
Clone a PcodeOp into this function.
Definition: funcdata_op.cc:582
void insertAfterDead(PcodeOp *op, PcodeOp *prev)
Insert the given PcodeOp after a point in the dead list.
Definition: op.cc:774
bool isHighOn(void) const
Are high-level variables assigned to Varnodes.
Definition: funcdata.hh:128
const Address & getAddress(void) const
Get the entry point address.
Definition: funcdata.hh:125
void seenDeadCode(AddrSpace *spc)
Inform system of dead code removal in given space.
Definition: heritage.cc:2359
Symbol * linkSymbolReference(Varnode *vn)
Discover and attach Symbol to a constant reference.
Definition: funcdata_varnode.cc:1007
int4 numJumpTables(void) const
Get the number of jump-tables for this function.
Definition: funcdata.hh:483
uint4 getCreateIndex(void) const
Get the next creation index to be assigned.
Definition: varnode.hh:353
void setRestartPending(bool val)
Toggle whether analysis needs to be restarted for this function.
Definition: funcdata.hh:186
Manager for all the major decompiler subsystems.
Definition: architecture.hh:117
const LoadGuard * getStoreGuard(PcodeOp *op) const
Get LoadGuard associated with STORE op.
Definition: funcdata.hh:241
void remapVarnode(Varnode *vn, Symbol *sym, const Address &usepoint)
Remap a Symbol to a given Varnode using a static mapping.
Definition: funcdata_varnode.cc:944
bool isTypeRecoveryOn(void) const
Has data-type recovery processes started.
Definition: funcdata.hh:132
Op should not be directly printed as source.
Definition: op.hh:89
void clearDeadVarnodes(void)
Delete any dead Varnodes.
Definition: funcdata_varnode.cc:696
bool hasNoStructBlocks(void) const
Return true if no block structuring was performed.
Definition: funcdata.hh:151
void saveXmlHigh(ostream &s) const
Save an XML description of all HighVariables to stream.
Definition: funcdata.cc:607
Description of a LOAD operation that needs to be guarded.
Definition: heritage.hh:105
VarnodeDefSet::const_iterator endDef(uint4 fl, const Address &addr) const
End of (input or free) Varnodes at a given storage address.
Definition: funcdata.hh:351
uint4 getHighLevelIndex(void) const
Get creation index at the start of HighVariable creation.
Definition: funcdata.hh:160
A control-flow block built out of sub-components.
Definition: block.hh:270
void setDeadCodeDelay(AddrSpace *spc, int4 delay)
Set a delay before removing dead code for a specific address space.
Definition: funcdata.hh:219
list< PcodeOp * >::const_iterator beginOp(OpCode opc) const
Start of PcodeOp objects with the given op-code.
Definition: funcdata.hh:449
void clearLanedAccessMap(void)
Clear records from the laned access list.
Definition: funcdata.hh:356
void seenDeadcode(AddrSpace *spc)
Mark that dead Varnodes have been seen in a specific address space.
Definition: funcdata.hh:213
Varnode * newVarnodeSpace(AddrSpace *spc)
Create a constant Varnode referring to an address space.
Definition: funcdata_varnode.cc:179
void opClearSpacebasePtr(PcodeOp *op)
Unmark PcodeOp as using spacebase ptr.
Definition: funcdata.hh:440
void opFlipInPlaceExecute(Funcdata &data, vector< PcodeOp *> &fliplist)
Perform op-code flips (in-place) to change a boolean value.
Definition: funcdata_op.cc:1083
Varnode * newVarnodeCallSpecs(FuncCallSpecs *fc)
Create a call specification annotation Varnode.
Definition: funcdata_varnode.cc:194
A low-level variable or contiguous set of bytes described by an Address and a size.
Definition: varnode.hh:65
HighVariable * findHigh(const string &name) const
Find a high-level variable by name.
Definition: funcdata_varnode.cc:303
A basic block for p-code operations.
Definition: block.hh:363
void findLinkedVarnodes(SymbolEntry *entry, vector< Varnode *> &res) const
Find Varnodes that map to the given SymbolEntry.
Definition: funcdata_varnode.cc:1071
Varnode * findLinkedVarnode(SymbolEntry *entry) const
Find a Varnode matching the given Symbol mapping.
Definition: funcdata_varnode.cc:1032
Varnode * setInputVarnode(Varnode *vn)
Mark a Varnode as an input to the function.
Definition: funcdata_varnode.cc:327
VarnodeLocSet::const_iterator beginLoc(void) const
Beginning of location list.
Definition: varnode.hh:354
Varnode * findVarnodeWritten(int4 s, const Address &loc, const Address &pc, uintm uniq=~((uintm) 0)) const
Find a defined Varnode via its storage address and its definition address.
Definition: funcdata.hh:294
bool fillinReadOnly(Varnode *vn)
Replace the given Varnode with its (constant) value in the load image.
Definition: funcdata_varnode.cc:505
A map from values to control-flow targets within a function.
Definition: jumptable.hh:499
PcodeOp * findOp(const SeqNum &sq)
Find PcodeOp with given sequence number.
Definition: funcdata.hh:406
An XML element. A node in the DOM tree.
Definition: xml.hh:150
FuncCallSpecs * getCallSpecs(int4 i) const
Get the i-th call specification.
Definition: funcdata.hh:245
void opUnlink(PcodeOp *op)
Unset inputs/output and remove given PcodeOP from its basic block.
Definition: funcdata_op.cc:177
void printVarnodeTree(ostream &s) const
Print a description of all Varnodes to a stream.
Definition: funcdata.cc:524
uint4 getCastPhaseIndex(void) const
Get creation index at the start of cast insertion.
Definition: funcdata.hh:159
void installSwitchDefaults(void)
Make sure default switch cases are properly labeled.
Definition: funcdata_block.cc:604
void opMarkSpacebasePtr(PcodeOp *op)
Mark PcodeOp as LOAD/STORE from spacebase ptr.
Definition: funcdata.hh:439
void pushBranch(BlockBasic *bb, int4 slot, BlockBasic *bbnew)
Move a control-flow edge from one block to another.
Definition: funcdata_block.cc:398
Varnode * findCoveringInput(int4 s, const Address &loc) const
Find an input Varnode covering a range.
Definition: varnode.cc:1137
void heritage(void)
Perform one pass of heritage.
Definition: heritage.cc:2234
void opInsertAfter(PcodeOp *op, PcodeOp *prev)
Insert given PcodeOp after a specific op.
Definition: funcdata_op.cc:346
Override & getOverride(void)
Get the Override object for this function.
Definition: funcdata.hh:181
const LoadGuard * getStoreGuard(PcodeOp *op) const
Get LoadGuard record associated with given PcodeOp.
Definition: heritage.cc:2330
void saveXml(ostream &s, uint8 id, bool savetree) const
Emit an XML description of this function to stream.
Definition: funcdata.cc:687
const Address & getAddr(void) const
Get the storage Address.
Definition: varnode.hh:167
A container of commands that override the decompiler&#39;s default behavior for a single function...
Definition: override.hh:40
const list< LoadGuard > & getLoadGuards(void) const
Get the list of guarded LOADs.
Definition: funcdata.hh:239
Varnode * findCoveringInput(int4 s, const Address &loc) const
Find the input Varnode that contains the given range.
Definition: funcdata.hh:278
VarnodeDefSet::const_iterator endDef(void) const
End of Varnodes sorted by definition.
Definition: varnode.hh:367
void buildDynamicSymbol(Varnode *vn)
Build a dynamic Symbol associated with the given Varnode.
Definition: funcdata_varnode.cc:1097
PcodeOp * cseElimination(Funcdata &data, PcodeOp *op1, PcodeOp *op2)
Perform a Common Subexpression Elimination step.
Definition: funcdata_op.cc:1184
const ScopeLocal * getScopeLocal(void) const
Get the local function scope.
Definition: funcdata.hh:371
Varnode * newCodeRef(const Address &m)
Create a code address annotation Varnode.
Definition: funcdata_varnode.cc:211
list< PcodeOp * >::const_iterator endOpAlive(void) const
End of PcodeOp objects in the alive list.
Definition: funcdata.hh:458
int4 getSize(void) const
Get the function body size in bytes.
Definition: funcdata.hh:126
void adjustInputVarnodes(const Address &addr, int4 size)
Adjust input Varnodes contained in the given range.
Definition: funcdata_varnode.cc:370
Have we checked for cpool transforms.
Definition: op.hh:98
A function prototype.
Definition: fspec.hh:1147
VarnodeDefSet::const_iterator beginDef(uint4 fl) const
Start of Varnodes with a given definition property.
Definition: funcdata.hh:342
This instruction starts a basic block.
Definition: op.hh:67
Varnode * findCoveredInput(int4 s, const Address &loc) const
Find the first input Varnode covered by the given range.
Definition: funcdata.hh:271
VarnodeLocSet::const_iterator beginLoc(AddrSpace *spaceid) const
Start of Varnodes stored in a given address space.
Definition: funcdata.hh:304
void opSetOpcode(PcodeOp *op, OpCode opc)
Set the op-code for a specific PcodeOp.
Definition: funcdata_op.cc:23
A p-code emitter for building PcodeOp objects.
Definition: funcdata.hh:553
PcodeOp * findOp(const SeqNum &num) const
Find a PcodeOp by sequence number.
Definition: op.cc:834
void opHeritage(void)
Perform an entire heritage pass linking Varnode reads to writes.
Definition: funcdata.hh:415
const list< LoadGuard > & getLoadGuards(void) const
Get list of LOAD ops that are guarded.
Definition: heritage.hh:285
VarnodeLocSet::const_iterator beginLoc(const Address &addr) const
Start of Varnodes at a storage address.
Definition: funcdata.hh:310
VarnodeDefSet::const_iterator beginDef(void) const
Start of all Varnodes sorted by definition address.
Definition: funcdata.hh:336
BlockGraph & getStructure(void)
Get the current control-flow structuring hierarchy.
Definition: funcdata.hh:488
bool removeUnreachableBlocks(bool issuewarning, bool checkexistence)
Remove any unreachable basic blocks.
Definition: funcdata_block.cc:341
Manage the construction of Static Single Assignment (SSA) form.
Definition: heritage.hh:170
The base class for a symbol in a symbol table or scope.
Definition: database.hh:153
void restoreXmlJumpTable(const Element *el)
Restore jump-tables from an XML description.
Definition: funcdata.cc:558
VarnodeLocSet::const_iterator endLoc(const Address &addr) const
End of Varnodes at a storage address.
Definition: funcdata.hh:313
static bool compareCallspecs(const FuncCallSpecs *a, const FuncCallSpecs *b)
Compare call specification objects by call site address.
Definition: funcdata.cc:449
int4 numVarnodes(void) const
Get number of Varnodes this contains.
Definition: varnode.hh:339
JumpTable * recoverJumpTable(PcodeOp *op, FlowInfo *flow, int4 &failuremode)
Recover destinations for a BRANCHIND by analyzing nearby data and control-flow.
Definition: funcdata_block.cc:559
VarnodeDefSet::const_iterator beginDef(void) const
Beginning of Varnodes sorted by definition.
Definition: varnode.hh:366
A high-level variable modeled as a list of low-level variables, each written once.
Definition: variable.hh:38
void opMarkStartBasic(PcodeOp *op)
Mark PcodeOp as starting a basic block.
Definition: funcdata.hh:432
Container class for ParamTrial objects.
Definition: fspec.hh:223
~Funcdata(void)
Destructor.
Definition: funcdata.cc:162
bool deadRemovalAllowed(AddrSpace *spc) const
Check if dead code removal is allowed for a specific address space.
Definition: funcdata.hh:225
bool inlineFlow(Funcdata *inlinefd, FlowInfo &flow, PcodeOp *callop)
In-line the p-code from another function into this function.
Definition: funcdata_op.cc:806
void setLanedRegGenerated(void)
Mark that laned registers have been collected.
Definition: funcdata.hh:136
void setMark(void) const
Mark this Varnode for breadcrumb algorithms.
Definition: varnode.hh:276
void opFlipCondition(PcodeOp *op)
Flip output condition of given CBRANCH.
Definition: funcdata.hh:441
Architecture * getArch(void) const
Get the program/architecture owning the function.
Definition: funcdata.hh:127
int4 numCalls(void) const
Get the number of calls made by this function.
Definition: funcdata.hh:244
A container for Varnode objects from a specific function.
Definition: varnode.hh:325
Funcdata(const string &nm, Scope *conf, const Address &addr, int4 sz=0)
Constructor.
Definition: funcdata.cc:23
A register or memory register that may be used to pass a parameter or return value.
Definition: fspec.hh:157
void opSwapInput(PcodeOp *op, int4 slot1, int4 slot2)
Swap two input operands in the given PcodeOp.
Definition: funcdata_op.cc:129
Symbol * linkSymbol(Varnode *vn)
Find or create Symbol associated with given Varnode.
Definition: funcdata_varnode.cc:973
VarnodeLocSet::const_iterator beginLoc(int4 s, const Address &addr) const
Start of Varnodes with given storage.
Definition: funcdata.hh:316
void removeDoNothingBlock(BlockBasic *bb)
Remove a basic block from control-flow that performs no operations.
Definition: funcdata_block.cc:322
Varnode * findInput(int4 s, const Address &loc) const
Find an input Varnode.
Definition: varnode.cc:1089
Varnode * newUnique(int4 s, Datatype *ct=(Datatype *) 0)
Create a new temporary Varnode.
Definition: funcdata_varnode.cc:81
void opInsertBegin(PcodeOp *op, BlockBasic *bl)
Insert given PcodeOp at the beginning of a basic block.
Definition: funcdata_op.cc:383
bool isProcComplete(void) const
Is processing of the function complete.
Definition: funcdata.hh:130
Varnode * findCoveredInput(int4 s, const Address &loc) const
Find an input Varnode contained within this range.
Definition: varnode.cc:1109
bool isDoublePrecisOn(void) const
Is double precision analysis enabled.
Definition: funcdata.hh:150
bool deadRemovalAllowedSeen(AddrSpace *spc)
Check if dead code removal is safe and mark that removal has happened.
Definition: heritage.cc:2411
void opDeadAndGone(PcodeOp *op)
Free resources for the given dead PcodeOp.
Definition: funcdata.hh:428
BlockBasic * nodeJoinCreateBlock(BlockBasic *block1, BlockBasic *block2, BlockBasic *exita, BlockBasic *exitb, bool fora_block1ishigh, bool forb_block1ishigh, const Address &addr)
Create a new basic block for holding a merged CBRANCH.
Definition: funcdata_block.cc:696
void opSetAllInput(PcodeOp *op, const vector< Varnode *> &vvec)
Set all input Varnodes for the given PcodeOp simultaneously.
Definition: funcdata_op.cc:240
int4 numVarnodes(void) const
Get the total number of Varnodes.
Definition: funcdata.hh:251
bool checkCallDoubleUse(const PcodeOp *opmatch, const PcodeOp *op, const Varnode *vn, const ParamTrial &trial) const
Test for legitimate double use of a parameter trial.
Definition: funcdata_varnode.cc:1369
void followFlow(const Address &baddr, const Address &eadddr, uint4 insn_max)
Generate raw p-code for the function.
Definition: funcdata_op.cc:708
PcodeOpTree::const_iterator endOp(const Address &addr) const
End of all (alive) PcodeOp objects attached to a specific Address.
Definition: funcdata.hh:476
void clearActiveOutput(void)
Clear any analysis of the function&#39;s return prototype.
Definition: funcdata.hh:376
list< PcodeOp * >::const_iterator beginAlive(void) const
Start of all PcodeOps marked as alive.
Definition: op.hh:291
bool startTypeRecovery(void)
Mark that data-type analysis has started.
Definition: funcdata.cc:154
bool replaceVolatile(Varnode *vn)
Replace accesses of the given Varnode with volatile operations.
Definition: funcdata_varnode.cc:587
void saveXmlJumpTable(ostream &s) const
Emit an XML description of jump-tables to stream.
Definition: funcdata.cc:573
Varnode * newConstant(int4 s, uintb constant_val)
Create a new constant Varnode.
Definition: funcdata_varnode.cc:64
void destroy(Varnode *vn)
Remove a Varnode from the container.
Definition: varnode.cc:900
void opMarkNoCollapse(PcodeOp *op)
Mark PcodeOp as not collapsible.
Definition: funcdata.hh:436
void startProcessing(void)
Start processing for this function.
Definition: funcdata.cc:126
void opMarkSpecialPrint(PcodeOp *op)
Mark PcodeOp as needing special printing.
Definition: funcdata.hh:435
void setJumptableRecovery(bool val)
Toggle whether this is being used for jump-table recovery.
Definition: funcdata.hh:141
void opUnsetInput(PcodeOp *op, int4 slot)
Clear an input operand slot for the given PcodeOp.
Definition: funcdata_op.cc:90
Varnode * newVarnodeIop(PcodeOp *op)
Create a PcodeOp annotation Varnode.
Definition: funcdata_varnode.cc:165
bool deadRemovalAllowedSeen(AddrSpace *spc)
Check if dead Varnodes have been removed for a specific address space.
Definition: funcdata.hh:231
void spacebase(void)
Mark registers that map to a virtual address space.
Definition: funcdata.cc:202
void setNoCode(bool val)
Toggle whether this has a body.
Definition: funcdata.hh:134
void opDeadInsertAfter(PcodeOp *op, PcodeOp *prev)
Moved given PcodeOp to specified point in the dead list.
Definition: funcdata.hh:413
PcodeOpTree::const_iterator beginAll(void) const
Start of all PcodeOps in sequence number order.
Definition: op.hh:279
PcodeOp * cseFindInBlock(PcodeOp *op, Varnode *vn, BlockBasic *bl, PcodeOp *earliest)
Find a duplicate calculation of a given PcodeOp reading a specific Varnode.
Definition: funcdata_op.cc:1151
Helper class for determining if Varnodes can trace their value from a legitimate source.
Definition: funcdata.hh:566
Loads or stores from a dynamic pointer into a spacebase.
Definition: op.hh:95
static bool replaceLessequal(Funcdata &data, PcodeOp *op)
Replace INT_LESSEQUAL and INT_SLESSEQUAL expressions.
Definition: funcdata_op.cc:978
const BlockGraph & getBasicBlocks(void) const
Get the basic blocks container.
Definition: funcdata.hh:490
void opMarkNonPrinting(PcodeOp *op)
Mark PcodeOp as not being printed.
Definition: funcdata.hh:434
void clearSymbolLinks(HighVariable *high)
Clear Symbols attached to Varnodes in the given HighVariable.
Definition: funcdata_varnode.cc:927
void opSetOutput(PcodeOp *op, Varnode *vn)
Set a specific output Varnode for the given PcodeOp.
Definition: funcdata_op.cc:68
void switchEdge(FlowBlock *inblock, BlockBasic *outbefore, FlowBlock *outafter)
Switch an outgoing edge from the given source block to flow into another block.
Definition: funcdata_block.cc:960
void opRemoveInput(PcodeOp *op, int4 slot)
Remove a specific input slot for the given PcodeOp.
Definition: funcdata_op.cc:264
JumpTable * findJumpTable(const PcodeOp *op) const
Find a jump-table associated with a given BRANCHIND.
Definition: funcdata_block.cc:440
Varnode * newVarnode(int4 s, const Address &m, Datatype *ct=(Datatype *) 0)
Create a new unattached Varnode object.
Definition: funcdata_varnode.cc:139
void printBlockTree(ostream &s) const
Print a description of control-flow structuring to a stream.
Definition: funcdata_block.cc:25
A Symbol scope for local variables of a particular function.
Definition: varmap.hh:182
JumpTable * linkJumpTable(PcodeOp *op)
Link jump-table with a given BRANCHIND.
Definition: funcdata_block.cc:421
void spacebaseConstant(PcodeOp *op, int4 slot, SymbolEntry *entry, const Address &rampoint, uintb origval, int4 origsize)
Convert a constant pointer into a ram CPUI_PTRSUB.
Definition: funcdata.cc:291
Varnode * newSpacebasePtr(AddrSpace *id)
Construct a new spacebase register for a given address space.
Definition: funcdata.cc:247
Utilities for making references to dynamic variables: defined as locations and constants that can onl...
PcodeOp * target(const Address &addr) const
Look up a PcodeOp by an instruction Address.
Definition: funcdata.hh:442
ScopeLocal * getScopeLocal(void)
Get the local function scope.
Definition: funcdata.hh:370
PcodeOpTree::const_iterator begin(const Address &addr) const
Start of all PcodeOps at one Address.
Definition: op.cc:881
void initActiveOutput(void)
Definition: funcdata_varnode.cc:461
PcodeOpTree::const_iterator endOpAll(void) const
End of all (alive) PcodeOp objects sorted by sequence number.
Definition: funcdata.hh:470
VarnodeLocSet::const_iterator beginLoc(int4 s, const Address &addr, const Address &pc, uintm uniq=~((uintm) 0)) const
Start of Varnodes matching storage and definition address.
Definition: funcdata.hh:328
Describes a (register) storage location and the ways it might be split into lanes.
Definition: transform.hh:88
Data defining a specific memory location.
Definition: pcoderaw.hh:33
A collection of Symbol objects within a single (namespace or functional) scope.
Definition: database.hh:413
A class for uniquely labelling and comparing PcodeOps.
Definition: address.hh:111