fork/exec/exit Callbacks.
[dyninst.git] / dyninstAPI / src / BPatch_function.C
1 /*
2  * Copyright (c) 1996 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  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: BPatch_function.C,v 1.2 2000/03/12 23:27:14 hollings Exp $
43
44 #include <string.h>
45 #include "symtab.h"
46 #include "process.h"
47 #include "instPoint.h"
48
49 #include "BPatch.h"
50 #include "BPatch_type.h"
51 #include "BPatch_collections.h"
52 #include "BPatch_Vector.h"
53
54 /* XXX Should be in a dyninst API include file (right now in perfStream.h) */
55 extern double cyclesPerSecond;
56
57
58 /**************************************************************************
59  * BPatch_function
60  *************************************************************************/
61 /*
62  * BPatch_function::BPatch_function
63  *
64  * Constructor that creates a BPatch_function.
65  *
66  */
67 BPatch_function::BPatch_function(process *_proc, function_base *_func,
68         BPatch_module *_mod) :
69         proc(_proc), mod(_mod), func(_func)
70 {
71
72   // there should be at most one BPatch_func for each function_base per process
73   assert(proc->thread && !proc->PDFuncToBPFuncMap[func]);
74
75   _srcType = BPatch_sourceFunction;
76
77   localVariables = new BPatch_localVarCollection;
78   funcParameters = new BPatch_localVarCollection;
79   retType = NULL;
80
81   proc->PDFuncToBPFuncMap[_func] = this;
82 };
83
84 /*
85  * BPatch_function::BPatch_function
86  *
87  * Constructor that creates the BPatch_function with return type.
88  *
89  */
90 BPatch_function::BPatch_function(process *_proc, function_base *_func,
91                                  BPatch_type * _retType, BPatch_module *_mod) :
92         proc(_proc), mod(_mod), func(_func)
93 {
94   _srcType = BPatch_sourceFunction;
95   localVariables = new BPatch_localVarCollection;
96   funcParameters = new BPatch_localVarCollection;
97   retType = _retType;
98 };
99
100
101 BPatch_function::~BPatch_function()
102 {
103     // if (ast != NULL)
104         // removeAst(ast);
105     if (localVariables) delete localVariables;
106     if (funcParameters) delete funcParameters;
107 }
108
109 /* 
110  * BPatch_function::getSourceObj()
111  *
112  * Return the contained source objects (e.g. statements).
113  *    This is not currently supported.
114  *
115  */
116 BPatch_Vector<BPatch_sourceObj *> *BPatch_function::getSourceObj()
117 {
118     return NULL;
119 }
120
121 /*
122  * BPatch_function::getObjParent()
123  *
124  * Return the parent of the function (i.e. the module)
125  *
126  */
127 BPatch_sourceObj *BPatch_function::getObjParent()
128 {
129     return (BPatch_sourceObj *) mod;
130 }
131
132 /*
133  * BPatch_function::getName
134  *
135  * Copies the name of the function into a buffer, up to a given maximum
136  * length.  Returns a pointer to the beginning of the buffer that was
137  * passed in.
138  *
139  * s            The buffer into which the name will be copied.
140  * len          The size of the buffer.
141  */
142 char *BPatch_function::getName(char *s, int len)
143 {
144     assert(func);
145     string name = func->prettyName();
146     strncpy(s, name.string_of(), len);
147
148     return s;
149 }
150
151
152 /*
153  * BPatch_function::getBaseAddr
154  *
155  * Returns the starting address of the function.
156  */
157 void *BPatch_function::getBaseAddr()
158 {
159      return (void *)func->getEffectiveAddress(proc);
160 }
161
162
163 /*
164  * BPatch_function::getSize
165  *
166  * Returns the size of the function in bytes.
167  */
168 unsigned int BPatch_function::getSize()
169 {
170   return func->size();
171 }
172
173
174 /*
175  * BPatch_function::findPoint
176  *
177  * Returns a vector of the instrumentation points from a procedure that is
178  * identified by the parameters, or returns NULL upon failure.
179  * (Points are sorted by address in the vector returned.)
180  *
181  * loc          The points within the procedure to return.  The following
182  *              values are valid for this parameter:
183  *                BPatch_entry         The function's entry point.
184  *                BPatch_exit          The function's exit point(s).
185  *                BPatch_subroutine    The points at which the procedure calls
186  *                                     other procedures.
187  *                BPatch_longJump      The points at which the procedure make
188  *                                     long jump calls.
189  *                BPatch_allLocations  All of the points described above.
190  */
191 BPatch_Vector<BPatch_point*> *BPatch_function::findPoint(
192         const BPatch_procedureLocation loc)
193 {
194     // function does not exist!
195     if (func == NULL) return NULL;
196
197     // function is generally uninstrumentable (with current technology)
198     if (func->funcEntry(proc) == NULL) return NULL;
199
200     BPatch_Vector<BPatch_point*> *result = new BPatch_Vector<BPatch_point *>;
201
202     if (loc == BPatch_entry || loc == BPatch_allLocations) {
203         BPatch_point *new_point = new BPatch_point(proc, this,
204                 const_cast<instPoint *>(func->funcEntry(proc)), BPatch_entry);
205         result->push_back(new_point);
206     }
207     switch (loc) {
208       case BPatch_entry: // already done
209           break;
210       case BPatch_allLocations:
211         {
212           const vector<instPoint *> &Rpoints = func->funcExits(proc);
213           const vector<instPoint *> &Cpoints = func->funcCalls(proc);
214           BPatch_point *new_point;
215           unsigned int c=0, r=0;
216           Address cAddr, rAddr;
217           while (c < Cpoints.size() || r < Rpoints.size()) {
218               if (c < Cpoints.size()) cAddr = Cpoints[c]->iPgetAddress();
219               else                    cAddr = (Address)(-1);
220               if (r < Rpoints.size()) rAddr = Rpoints[r]->iPgetAddress();
221               else                    rAddr = (Address)(-1);
222               if (cAddr <= rAddr) {
223                   new_point = new BPatch_point(proc, this, Cpoints[c], 
224                         BPatch_subroutine);
225                   c++;
226               } else {
227                   new_point = new BPatch_point(proc, this, Rpoints[r], 
228                         BPatch_exit);
229                   r++;
230               }
231               result->push_back(new_point);
232           }
233           break;
234         }
235       case BPatch_exit:
236         {
237           const vector<instPoint *> &points = func->funcExits(proc);
238           for (unsigned i = 0; i < points.size(); i++) {
239               BPatch_point *new_point = new BPatch_point(proc, this, points[i],
240                                                          BPatch_exit);
241               result->push_back(new_point);
242           }
243           break;
244         }
245       case BPatch_subroutine:
246         {
247           const vector<instPoint *> &points = func->funcCalls(proc);
248           for (unsigned i = 0; i < points.size(); i++) {
249               BPatch_point *new_point = new BPatch_point(proc, this, points[i],
250                                                          BPatch_subroutine);
251               result->push_back(new_point);
252           }
253           break;
254         }
255       case BPatch_longJump:
256         /* XXX Not yet implemented */
257       default:
258         assert( 0 );
259     }
260
261     return result;
262 }
263 /*
264  * BPatch_function::addParam()
265  *
266  * This function adds a function parameter to the BPatch_function parameter
267  * vector.
268  */
269 void BPatch_function::addParam(char * _name, BPatch_type *_type, int _linenum,
270                                int _frameOffset, int _sc)
271 {
272   BPatch_localVar * param = new BPatch_localVar(_name, _type, _linenum,
273                                                 _frameOffset, _sc);
274
275   // Add parameter to list of parameters
276   params.push_back(param);
277 }
278
279 /*
280  * BPatch_function::findLocalVar()
281  *
282  * This function searchs for a local variable in the BPatch_function's
283  * local variable collection.
284  */
285 BPatch_localVar * BPatch_function::findLocalVar(const char * name)
286 {
287
288   BPatch_localVar * var = localVariables->findLocalVar(name);
289   return (var);
290
291 }
292
293 /*
294  * BPatch_function::findLocalParam()
295  *
296  * This function searchs for a function parameter in the BPatch_function's
297  * parameter collection.
298  */
299 BPatch_localVar * BPatch_function::findLocalParam(const char * name)
300 {
301
302   BPatch_localVar * var = funcParameters->findLocalVar(name);
303   return (var);
304
305 }