Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / InstrucIter.h
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #ifndef _InstrucIter_h_
33 #define _InstrucIter_h_
34
35 #include "common/h/Types.h"
36 #include "BPatch_Set.h"
37 #include "BPatch_eventLock.h" // CONST_EXPORT...
38 #include <vector>
39 #include <set>
40
41 class InstrucIter;
42 class InstructionSource;
43
44 class instruction;
45 class image_parRegion;
46 class image_basicBlock;
47 class image_func;
48
49 class bblInstance;
50 class int_basicBlock;
51 class int_function;
52
53 class BPatch_parRegion;
54 class BPatch_memoryAccess;
55 class BPatch_basicBlock;
56 class BPatch_instruction;
57
58 class process;
59 class AddressSpace;
60
61
62 /*
63    VG (02/19/02): New abstraction layer for instruction parsing.
64
65    Functionality/design:
66    - Allows iteration over instructions, forward and backward.
67    - To guarantee backward iteration we only allow iteration
68      over well known address spaces (right now only function bodies).
69    - The only state stored is the offset position relative to the
70      starting address.
71    - Any other state, like caching a instruction pointer list for CISC
72      cpus is saved via a callback. Typically the container of the
73      address space (e.g. function) should store this.
74    - Any number of iterators may be created over a given address space.
75    - Creating another iterator that starts from the current position 
76      is done via the copy constructor.
77    - Supports basic predicates abut the current instruction.
78    - Gives additional information about certain instructions (jump/calls,
79      load/stores etc.)
80    - Finding a certain instruction (type) from this point forward. Backward
81      search should also be easy to do.
82
83    Most code is derived from Tikir's AddressHandle, but it has:
84    - Better (if not complete) encapsulation of the underlying instruction
85      class making it transparent for the user. This allows for instance
86      the new IA-32 decoder to replace the x86 one transparently.
87    - All predicate functions are now methods that test the current instruction.
88    - Pimple (pointer-to-implementation) separation for machine specific
89      stuff. This does away with ifdefs.
90    - A new name :)
91 */
92
93 /** class for manipulating the address space in an image for a given
94   * range. Such as the valid addresses and the instructions in the addresses
95   * and iteration on the address apce range for instructions
96   */
97 class InstrucIter {
98     friend class BPatch_instruction;
99  private:
100     
101     /* We can iterate either over a process address space or 
102        within a parsed image */
103     // By making the process and image share a common interface class (InstructionSource),
104     // we can remove much of the code duplication that was dependent on where we were iterating
105     // BW, 7-07
106     InstructionSource *instructions_;
107     
108
109     /* Starting address/offset */
110     Address base;
111     
112     /** the range/length of the address space in bytes */
113     unsigned range;
114     
115     /** current address of the address spce which will be used 
116      * to iterate through the address space
117      */
118     Address current;
119
120     void initializeInsn();
121
122     // For iterating backwards over architectures with variable-length
123     // instructions.  When you go forwards, you push the address on;
124     // when you go back, you pop.
125
126     std::vector<std::pair<Address, void*> >prevInsns;
127
128     instruction insn;
129     void* instPtr;
130
131 #if defined(arch_ia64)
132     // We need the bundle to iterate correctly
133     IA64_bundle bundle;
134 #endif
135
136  public:
137     
138     /** returns the instruction in the address of handle */
139     virtual instruction getInstruction();
140     
141     // And a pointer if we need to worry about virtualization. This is
142     // "user needs to get rid of it" defined.
143     virtual instruction *getInsnPtr();
144
145 #if defined(arch_ia64)
146     // Convenient access to correct virtual instruction::getType()
147     instruction::insnType getInsnType();
148 #endif
149     
150  public:
151     /** static method that returns true if the delay instruction is supported */
152     static bool delayInstructionSupported ();
153
154     InstrucIter (Address start, image_parRegion *parR);
155
156     InstrucIter (image_basicBlock *b);
157     
158     InstrucIter(bblInstance *b);
159         
160     InstrucIter( CONST_EXPORT BPatch_basicBlock* bpBasicBlock);
161
162     InstrucIter( CONST_EXPORT BPatch_parRegion* bpParRegion);
163
164     InstrucIter (int_basicBlock *ibb);
165
166  protected:
167     // For InstrucIterFunction
168     InstrucIter() : base(0), range(1), current(0)    
169     {    
170     }
171     
172  public:    
173
174     /** copy constructor
175      * @param ii InstrucIter to copy
176      */
177     InstrucIter(const InstrucIter& ii);
178     
179     // Generic "address, process" iterator.
180     InstrucIter( Address addr, unsigned size, AddressSpace *space);
181     InstrucIter( Address addr, AddressSpace *space); 
182
183     InstrucIter(image_func* func);
184     InstrucIter(Address start, image_func* func);
185
186   virtual ~InstrucIter() {  }
187
188   /** return true iff the address is in the space represented by
189    * the InstrucIter
190    */
191   bool containsAddress(Address addr);
192
193   /** method that returns the targets of a multi-branch instruction
194    * it assumes the currentAddress of the handle instance points to the
195    * multi branch instruction
196    */
197
198 #if defined(arch_x86) || defined(arch_x86_64)
199   bool getMultipleJumpTargets( BPatch_Set< Address >& result, 
200                                instruction& tableInsn, 
201                                instruction& maxSwitchInsn, 
202                                instruction& branchInsn,
203                                bool isAddressInJmp,
204                                bool foundJccAlongTaken,
205                                Address tableOffsetFromThunk = 0);
206 #else
207   
208   bool getMultipleJumpTargets( BPatch_Set< Address >& result );
209
210 #endif
211
212
213   /** method that returns true if there are more instructions to iterate */
214   virtual bool hasMore();
215
216   /** method that returns true if there are instruction previous to the
217    * current one */
218   virtual bool hasPrev();
219
220   /** Peek at the previous address */
221   virtual Address peekPrev();
222
223   /** And the next address */
224   virtual Address peekNext();
225
226   /** set the content of the handle to the argument 
227    * @param addr the value that handle will be set to
228    */
229   virtual void setCurrentAddress(Address);
230   virtual Address getCurrentAddress(){return current;}
231   
232 #if defined(i386_unknown_linux2_0) \
233  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
234  || defined(i386_unknown_nt4_0)
235   /** does the address point to an instruction */
236   bool isInstruction();
237 #endif
238
239   /** returns the content of the address  handle */
240   virtual Address operator*() const;
241   virtual Address begin() const
242   {
243     return base;
244   }
245   virtual Address end() const
246   {
247     return base + range;
248   }
249   
250
251   /** prefix increment operation */
252   virtual Address operator++ ();
253
254   /** prefix decrement operation */
255   virtual Address operator-- ();
256
257   /** postfix increment operation */
258   virtual Address operator++ (int);
259
260   /** postfix decrement operation */
261   virtual Address operator-- (int);
262
263   /* Predicates */
264    
265   bool isALeaveInstruction();
266   bool isAReturnInstruction();
267   bool isACondReturnInstruction();
268   bool isACondBranchInstruction();
269   bool isAJumpInstruction();
270   bool isACallInstruction();
271   bool isADynamicCallInstruction();
272   bool isAnneal();
273   bool isStackFramePreamble(int &frameSize);
274   bool isReturnValueSave();
275   bool isFramePush();
276   bool isFrameSetup();
277   bool isANopInstruction();
278   bool isAnAbortInstruction();
279   bool isAnAllocInstruction();
280   bool isAnInterruptInstruction(); 
281   bool isDelaySlot();
282   bool isSyscall();
283   
284   /* Power only */
285   bool isA_RT_WriteInstruction();
286   bool isA_RA_WriteInstruction(); 
287  
288   bool isA_RT_ReadInstruction();
289   bool isA_RA_ReadInstruction(); 
290   bool isA_RB_ReadInstruction();
291
292   bool isA_FRT_WriteInstruction(); 
293   bool isA_FRA_WriteInstruction(); 
294
295   bool isA_FRT_ReadInstruction(); 
296   bool isA_FRA_ReadInstruction(); 
297   bool isA_FRB_ReadInstruction();
298   bool isA_FRC_ReadInstruction();
299
300   bool isA_MX_Instruction();
301
302   bool isA_MRT_ReadInstruction();
303   bool isA_MRT_WriteInstruction();
304
305   bool usesSPR(std::set<Register> &);
306   bool definesSPR(std::set<Register> &);
307
308   unsigned getRTValue();
309   unsigned getRAValue();
310   unsigned getRBValue();
311   unsigned getFRTValue();
312   unsigned getFRAValue();
313   unsigned getFRBValue();
314   unsigned getFRCValue();
315   signed getDFormDValue();
316
317   bool isClauseInstruction();
318   bool isRegConstantAssignment(int * regArray, Address *);
319
320   bool isACondBDZInstruction();
321   bool isACondBDNInstruction();
322
323   /* END Power only */
324
325   /* Sparc Only */
326   bool isAOMPDoFor();
327   bool isTstInsn();
328   bool isACondBLEInstruction();
329
330   /* END Sparc Only */
331
332
333   // Thought: since we check, we can probably get the data for
334   // free.
335   bool isInterModuleCallSnippet(Address &info);
336
337   Address getBranchTargetOffset();
338   Address getBranchTargetAddress(bool *isAbsolute = NULL);
339   Address getCallTarget();
340
341
342   BPatch_memoryAccess* isLoadOrStore();
343   BPatch_instruction* getBPInstruction();
344
345   void printOpCode();
346
347   /* x86 Only */
348   void readWriteRegisters(int * readRegs, int * writeRegs);
349   bool isFPWrite();
350   bool isFPRead();
351   void getAllRegistersUsedAndDefined(std::set<Register>& used, std::set<Register> &defined);
352   /* END x86 Only */
353
354   bool isAIndirectJumpInstruction();
355
356 #if defined(arch_sparc)
357   // Delay slot happiness. Thing is, a jump ends a basic block (especially
358   // since you can branch into the delay slot, and we don't like overlapping
359   // basic blocks). And I want to keep that. But we still need a way to say
360   // "grab me the delay slot insn", which might _not_ be in a basic block
361   // (say, unconditional jump). So I've added two instructions that go by 
362   // address and grab delay slot (and aggregate doohickey)
363
364   void getAndSkipDSandAgg(instruction* &ds,
365                           instruction* &agg);
366   bool isASaveInstruction();
367   bool isARestoreInstruction();
368   void adjustRegNumbers(int* readRegs, int* writeRegs,int window);
369   int adjustRegNumbers(int regNum, int window);
370 #endif
371
372 };
373
374 #endif /* _InstrucIter_h_ */