My Project
heritage.hh
Go to the documentation of this file.
1 /* ###
2  * IP: GHIDRA
3  * NOTE: Phi placement and renaming based on ACM journal articles
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
19 
20 #ifndef __CPUI_HERITAGE__
21 #define __CPUI_HERITAGE__
22 
23 #include "block.hh"
24 
27 typedef map<Address,vector<Varnode *> > VariableStack;
28 
30 struct SizePass {
31  int4 size;
32  int4 pass;
33 };
34 
42 class LocationMap {
43 public:
45  typedef map<Address,SizePass>::iterator iterator;
46 private:
47  map<Address,SizePass> themap;
48 public:
49  iterator add(Address addr,int4 size,int4 pass,int4 &intersect);
50  iterator find(Address addr);
51  int4 findPass(Address addr) const;
52  void erase(iterator iter) { themap.erase(iter); }
53  iterator begin(void) { return themap.begin(); }
54  iterator end(void) { return themap.end(); }
55  void clear(void) { themap.clear(); }
56 };
57 
65  vector<vector<FlowBlock *> > queue;
66  int4 curdepth;
67 public:
68  PriorityQueue(void) { curdepth = -2; }
69  void reset(int4 maxdepth);
70  void insert(FlowBlock *bl,int4 depth);
71  FlowBlock *extract(void);
72  bool empty(void) const { return (curdepth==-1); }
73 };
74 
75 class Funcdata;
76 class FuncCallSpecs;
77 
85 class HeritageInfo {
86  friend class Heritage;
87  AddrSpace *space;
88  int4 delay;
89  int4 deadcodedelay;
90  int4 deadremoved;
91  bool loadGuardSearch;
92  bool warningissued;
93  void set(AddrSpace *spc,int4 dl,int4 dcdl) {
94  space=spc; delay=dl; deadcodedelay=dcdl; deadremoved=0; warningissued=false; loadGuardSearch = false; }
95  bool isHeritaged(void) const { return (space != (AddrSpace *)0); }
96  void reset(void) {
97  deadremoved = 0; deadcodedelay = delay; warningissued = false; loadGuardSearch = false; }
98 };
99 
105 class LoadGuard {
106  friend class Heritage;
107  PcodeOp *op;
108  AddrSpace *spc;
109  uintb pointerBase;
110  uintb minimumOffset;
111  uintb maximumOffset;
112  int4 step;
113  int4 analysisState;
114  void establishRange(const ValueSetRead &valueSet);
115  void finalizeRange(const ValueSetRead &valueSet);
116 
122  void set(PcodeOp *o,AddrSpace *s,uintb off) {
123  op = o; spc = s; pointerBase=off; minimumOffset=0; maximumOffset=s->getHighest(); step=0; analysisState=0;
124  }
125 public:
126  PcodeOp *getOp(void) const { return op; }
127  uintb getMinimum(void) const { return minimumOffset; }
128  uintb getMaximum(void) const { return maximumOffset; }
129  int4 getStep(void) const { return step; }
130  bool isGuarded(const Address &addr) const;
131  bool isRangeLocked(void) const { return (analysisState == 2); }
132  bool isValid(OpCode opc) const { return (!op->isDead() && op->code() == opc); }
133 };
134 
170 class Heritage {
172  enum heritage_flags {
173  boundary_node = 1,
174  mark_node = 2,
175  merged_node = 4
176  };
177 
179  struct StackNode {
180  enum {
181  nonconstant_index = 1,
182  multiequal = 2
183  };
184  Varnode *vn;
185  uintb offset;
186  uint4 traversals;
187  list<PcodeOp *>::const_iterator iter;
188 
193  StackNode(Varnode *v,uintb o,uint4 trav) {
194  vn = v;
195  offset = o;
196  iter = v->beginDescend();
197  traversals = trav;
198  }
199  };
200 
201  Funcdata *fd;
202  LocationMap globaldisjoint;
203  LocationMap disjoint;
204  vector<vector<FlowBlock *> > domchild;
205  vector<vector<FlowBlock *> > augment;
206  vector<uint4> flags;
207  vector<int4> depth;
208  int4 maxdepth;
209  int4 pass;
210 
211  PriorityQueue pq;
212  vector<FlowBlock *> merge;
213  vector<HeritageInfo> infolist;
214  list<LoadGuard> loadGuard;
215  list<LoadGuard> storeGuard;
216  vector<PcodeOp *> loadCopyOps;
217  void clearInfoList(void);
218 
220  HeritageInfo *getInfo(AddrSpace *spc) { return &(infolist[spc->getIndex()]); }
221 
223  const HeritageInfo *getInfo(AddrSpace *spc) const { return &(infolist[spc->getIndex()]); }
224 
225  void splitJoinLevel(vector<Varnode *> &lastcombo,vector<Varnode *> &nextlev,JoinRecord *joinrec);
226  void splitJoinRead(Varnode *vn,JoinRecord *joinrec);
227  void splitJoinWrite(Varnode *vn,JoinRecord *joinrec);
228  void floatExtensionRead(Varnode *vn,JoinRecord *joinrec);
229  void floatExtensionWrite(Varnode *vn,JoinRecord *joinrec);
230  void processJoins(void);
231  void buildADT(void);
232  int4 collect(Address addr,int4 size,vector<Varnode *> &read,vector<Varnode *> &write,vector<Varnode *> &input) const;
233  bool callOpIndirectEffect(const Address &addr,int4 size,PcodeOp *op) const;
234  Varnode *normalizeReadSize(Varnode *vn,const Address &addr,int4 size);
235  Varnode *normalizeWriteSize(Varnode *vn,const Address &addr,int4 size);
236  Varnode *concatPieces(const vector<Varnode *> &vnlist,PcodeOp *insertop,Varnode *finalvn);
237  void splitPieces(const vector<Varnode *> &vnlist,PcodeOp *insertop,const Address &addr,int4 size,Varnode *startvn);
238  void findAddressForces(vector<PcodeOp *> &copySinks,vector<PcodeOp *> &forces);
239  void propagateCopyAway(PcodeOp *op);
240  void handleNewLoadCopies(void);
241  void analyzeNewLoadGuards(void);
242  void generateLoadGuard(StackNode &node,PcodeOp *op,AddrSpace *spc);
243  void generateStoreGuard(StackNode &node,PcodeOp *op,AddrSpace *spc);
244  bool protectFreeStores(AddrSpace *spc,vector<PcodeOp *> &freeStores);
245  bool discoverIndexedStackPointers(AddrSpace *spc,vector<PcodeOp *> &freeStores,bool checkFreeStores);
246  void reprocessFreeStores(AddrSpace *spc,vector<PcodeOp *> &freeStores);
247  void guard(const Address &addr,int4 size,vector<Varnode *> &read,vector<Varnode *> &write,vector<Varnode *> &inputvars);
248  void guardInput(const Address &addr,int4 size,vector<Varnode *> &input);
249  void guardCallOverlappingInput(FuncCallSpecs *fc,const Address &addr,const Address &transAddr,int4 size);
250  void guardCalls(uint4 flags,const Address &addr,int4 size,vector<Varnode *> &write);
251  void guardStores(const Address &addr,int4 size,vector<Varnode *> &write);
252  void guardLoads(uint4 flags,const Address &addr,int4 size,vector<Varnode *> &write);
253  void guardReturns(uint4 flags,const Address &addr,int4 size,vector<Varnode *> &write);
254  static void buildRefinement(vector<int4> &refine,const Address &addr,int4 size,const vector<Varnode *> &vnlist);
255  void splitByRefinement(Varnode *vn,const Address &addr,const vector<int4> &refine,vector<Varnode *> &split);
256  void refineRead(Varnode *vn,const Address &addr,const vector<int4> &refine,vector<Varnode *> &newvn);
257  void refineWrite(Varnode *vn,const Address &addr,const vector<int4> &refine,vector<Varnode *> &newvn);
258  void refineInput(Varnode *vn,const Address &addr,const vector<int4> &refine,vector<Varnode *> &newvn);
259  void remove13Refinement(vector<int4> &refine);
260  bool refinement(const Address &addr,int4 size,const vector<Varnode *> &readvars,const vector<Varnode *> &writevars,const vector<Varnode *> &inputvars);
261  void visitIncr(FlowBlock *qnode,FlowBlock *vnode);
262  void calcMultiequals(const vector<Varnode *> &write);
263  void renameRecurse(BlockBasic *bl,VariableStack &varstack);
264  void bumpDeadcodeDelay(Varnode *vn);
265  void placeMultiequals(void);
266  void rename(void);
267 public:
268  Heritage(Funcdata *data);
269 
274  int4 heritagePass(const Address &addr) const { return globaldisjoint.findPass(addr); }
275  int4 numHeritagePasses(AddrSpace *spc) const;
276  void seenDeadCode(AddrSpace *spc);
277  int4 getDeadCodeDelay(AddrSpace *spc) const;
278  void setDeadCodeDelay(AddrSpace *spc,int4 delay);
279  bool deadRemovalAllowed(AddrSpace *spc) const;
280  bool deadRemovalAllowedSeen(AddrSpace *spc);
281  void buildInfoList(void);
282  void forceRestructure(void) { maxdepth = -1; }
283  void clear(void);
284  void heritage(void);
285  const list<LoadGuard> &getLoadGuards(void) const { return loadGuard; }
286  const list<LoadGuard> &getStoreGuards(void) const { return storeGuard; }
287  const LoadGuard *getStoreGuard(PcodeOp *op) const;
288 };
289 
290 #endif
A region where processor data is stored.
Definition: space.hh:73
A class for analyzing parameters to a sub-function call.
Definition: fspec.hh:1436
Description of a control-flow block containing PcodeOps.
Definition: block.hh:60
bool isDead(void) const
Return true if this op is dead.
Definition: op.hh:164
OpCode code(void) const
Get the opcode id (enum) for this op.
Definition: op.hh:213
OpCode
The op-code defining a specific p-code operation (PcodeOp)
Definition: opcodes.hh:35
int4 size
Size of the range (in bytes)
Definition: heritage.hh:31
Label for describing extent of address range that has been heritaged.
Definition: heritage.hh:30
Map object for keeping track of which address ranges have been heritaged.
Definition: heritage.hh:42
Container for data structures associated with a single function.
Definition: funcdata.hh:45
const list< LoadGuard > & getStoreGuards(void) const
Get list of STORE ops that are guarded.
Definition: heritage.hh:286
uintb getMaximum(void) const
Get maximum offset of the guarded range.
Definition: heritage.hh:128
int4 pass
Pass when the range was heritaged.
Definition: heritage.hh:32
map< Address, SizePass >::iterator iterator
Iterator into the main map.
Definition: heritage.hh:45
map< Address, vector< Varnode * > > VariableStack
Definition: heritage.hh:27
int4 getStep(void) const
Get the calculated step associated with the range (or 0)
Definition: heritage.hh:129
PriorityQueue(void)
Constructor.
Definition: heritage.hh:68
PcodeOp * getOp(void) const
Get the PcodeOp being guarded.
Definition: heritage.hh:126
iterator end(void)
Get ending iterator over heritaged ranges.
Definition: heritage.hh:54
Lowest level operation of the p-code language.
Definition: op.hh:58
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
Information about heritage passes performed for a specific address space.
Definition: heritage.hh:85
Priority queue for the phi-node (MULTIEQUAL) placement algorithm.
Definition: heritage.hh:64
void clear(void)
Clear the map of heritaged ranges.
Definition: heritage.hh:55
int4 heritagePass(const Address &addr) const
Get the pass number when the given address was heritaged.
Definition: heritage.hh:274
bool isValid(OpCode opc) const
Return true if the record still describes an active LOAD.
Definition: heritage.hh:132
Classes related to basic blocks and control-flow structuring.
void forceRestructure(void)
Force regeneration of basic block structures.
Definition: heritage.hh:282
void erase(iterator iter)
Remove a particular entry from the map.
Definition: heritage.hh:52
Description of a LOAD operation that needs to be guarded.
Definition: heritage.hh:105
A record describing how logical values are split.
Definition: translate.hh:195
A low-level variable or contiguous set of bytes described by an Address and a size.
Definition: varnode.hh:65
A basic block for p-code operations.
Definition: block.hh:363
bool empty(void) const
Return true if this queue is empty.
Definition: heritage.hh:72
uintb getMinimum(void) const
Get minimum offset of the guarded range.
Definition: heritage.hh:127
bool isRangeLocked(void) const
Return true if the range is fully determined.
Definition: heritage.hh:131
iterator begin(void)
Get starting iterator over heritaged ranges.
Definition: heritage.hh:53
list< PcodeOp * >::const_iterator beginDescend(void) const
Get iterator to list of syntax tree descendants (reads)
Definition: varnode.hh:184
const list< LoadGuard > & getLoadGuards(void) const
Get list of LOAD ops that are guarded.
Definition: heritage.hh:285
Manage the construction of Static Single Assignment (SSA) form.
Definition: heritage.hh:170
uintb getHighest(void) const
Get the highest byte-scaled address.
Definition: space.hh:339
int4 findPass(Address addr) const
Look up if/how given address was heritaged.
Definition: heritage.cc:83
int4 getIndex(void) const
Get the integer identifier.
Definition: space.hh:317
A special form of ValueSet associated with the read point of a Varnode.
Definition: rangeutil.hh:176