Added several calls to API (waitForStatusChange, BPatch_variableExpr
[dyninst.git] / dyninstAPI / src / instPoint-x86.h
1 // instPoint-x86.C
2
3 /*
4  * Copyright (c) 1996 Barton P. Miller
5  * 
6  * We provide the Paradyn Parallel Performance Tools (below
7  * described as Paradyn") on an AS IS basis, and do not warrant its
8  * validity or performance.  We reserve the right to update, modify,
9  * or discontinue this software at any time.  We shall have no
10  * obligation to supply such updates or modifications or any other
11  * form of support to you.
12  * 
13  * This license is for research uses.  For such uses, there is no
14  * charge. We define "research use" to mean you may freely use it
15  * inside your organization for whatever purposes you see fit. But you
16  * may not re-distribute Paradyn or parts of Paradyn, in any form
17  * source or binary (including derivatives), electronic or otherwise,
18  * to any other organization or entity without our permission.
19  * 
20  * (for other uses, please contact us at paradyn@cs.wisc.edu)
21  * 
22  * All warranties, including without limitation, any warranty of
23  * merchantability or fitness for a particular purpose, are hereby
24  * excluded.
25  * 
26  * By your use of Paradyn, you understand and agree that we (or any
27  * other person or entity with proprietary rights in Paradyn) are
28  * under no obligation to provide either maintenance services,
29  * update services, notices of latent defects, or correction of
30  * defects for Paradyn.
31  * 
32  * Even if advised of the possibility of such damages, under no
33  * circumstances shall we (or any other person or entity with
34  * proprietary rights in the software licensed hereunder) be liable
35  * to you or any third party for direct, indirect, or consequential
36  * damages of any character regardless of type of action, including,
37  * without limitation, loss of profits, loss of use, loss of good
38  * will, or computer failure or malfunction.  You agree to indemnify
39  * us (and any other person or entity with proprietary rights in the
40  * software licensed hereunder) for any and all liability it may
41  * incur to third parties resulting from your use of Paradyn.
42  */
43
44 #ifndef _INST_POINT_X86_H_
45 #define _INST_POINT_X86_H_
46
47 /************************************************************************
48  *
49  *  class instPoint: representation of instrumentation points
50  *
51  ***********************************************************************/
52
53 class instPoint {
54
55  public:
56
57   instPoint(pd_Function *f, const image *, Address adr, instruction inst) {
58     addr_   = adr;
59     func_   = f;
60     callee_ = NULL;
61
62     jumpAddr_     = 0;
63     insnAtPoint_  = inst;
64     insnBeforePt_ = 0;
65     insnAfterPt_  = 0;
66   };
67
68   ~instPoint() {
69     if (insnBeforePt_) delete insnBeforePt_;
70     if (insnAfterPt_) delete insnAfterPt_;
71   };
72
73
74   const function_base *iPgetFunction() const { return func();    }
75   const function_base *iPgetCallee()   const { return callee();  }
76   const image         *iPgetOwner()    const { return owner();   }
77         Address        iPgetAddress()  const { return address(); }
78
79
80   Address address() const { return addr_; }
81   pd_Function *func() const { return func_; }
82
83   const instruction &insnAtPoint() const { return insnAtPoint_; }
84
85   // add an instruction before the point. Instructions should be added in reverse
86   // order, the instruction closest to the point first.
87   void addInstrBeforePt(instruction inst) {
88     if (!insnBeforePt_) insnBeforePt_ = new vector<instruction>;
89     (*insnBeforePt_) += inst;
90   };
91
92   // add an instruction after the point.
93   void addInstrAfterPt(instruction inst) {
94     if (!insnAfterPt_) insnAfterPt_ = new vector<instruction>;
95     (*insnAfterPt_) += inst;
96   }
97
98   const instruction &insnBeforePt(unsigned index) const 
99     { assert(insnBeforePt_); return ((*insnBeforePt_)[index]); }
100
101   const instruction &insnAfterPt(unsigned index) const 
102     { assert(insnAfterPt_); return ((*insnAfterPt_)[index]); }
103
104   unsigned insnsBefore() const
105     { if (insnBeforePt_) return (*insnBeforePt_).size(); return 0; }
106
107   unsigned insnsAfter() const 
108     { if (insnAfterPt_) return (*insnAfterPt_).size(); return 0; }
109
110   Address jumpAddr() const { assert(jumpAddr_); return jumpAddr_; }
111
112   Address returnAddr() const {
113     Address ret = addr_ + insnAtPoint_.size();
114     for (unsigned u = 0; u < insnsAfter(); u++)
115       ret += (*insnAfterPt_)[u].size();
116     return ret;
117   }
118
119   image *owner() const { return func()->file()->exec(); }
120
121   // return the size of all instructions in this point
122   // size may change after point is checked
123   unsigned size() const {
124     unsigned tSize = insnAtPoint_.size();
125     for (unsigned u1 = 0; u1 < insnsBefore(); u1++)
126       tSize += (*insnBeforePt_)[u1].size();
127     for (unsigned u2 = 0; u2 < insnsAfter(); u2++)
128       tSize += (*insnAfterPt_)[u2].size();
129     return tSize;
130   }
131
132   // check for jumps to instructions before and/or after this point, and discard
133   // instructions when there is a jump.
134   // Can only be done after an image has been parsed (that is, all inst. points
135   // in the image have been found.
136   void checkInstructions ();
137
138   pd_Function *callee() const { 
139     if (insnAtPoint().isCall()) {
140       if (insnAtPoint().isCallIndir())
141         return NULL;
142       else {
143         Address addr = insnAtPoint().getTarget(address());
144         pd_Function *pdf = owner()->findFunction(addr);
145         return pdf;
146       }
147     }
148     return NULL;
149   }
150
151   Address getTargetAddress() {
152     if (insnAtPoint().isCall()) {
153       if (insnAtPoint().isCallIndir()) {
154         return 0;
155       }
156       else {
157         return insnAtPoint().getTarget(address());
158       }
159     }
160     return 0;
161   }
162
163   // can't set this in the constructor because call points can't be classified until
164   // all functions have been seen -- this might be cleaned up
165   void set_callee(pd_Function * to) { callee_ = to;  }
166
167 #ifdef BPATCH_LIBRARY
168   bool usesTrap(process *proc);
169   bool canUseExtraSlot(process *proc) const;
170 #endif
171
172  private:
173   Address      addr_;    //The address of this instPoint: this is the address
174                          // of the actual point (i.e. a function entry point,
175                          // a call or a return instruction)
176   pd_Function *func_;    //The function where this instPoint belongs to
177   pd_Function *callee_;  //If this point is a call, the function being called
178
179   Address              jumpAddr_;     //This is the address where we insert the jump.
180                                       // It may be an instruction before the point
181   instruction          insnAtPoint_;  //The instruction at this point
182   vector<instruction> *insnBeforePt_; //Additional instructions before the point
183   vector<instruction> *insnAfterPt_;  //Additional instructions after the point
184
185 };
186
187 #endif