Moved Object-* files from util to dyninstAPI
[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.1 2000/02/15 23:48:00 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  * BPatch_function
59  *************************************************************************/
60 /*
61  * BPatch_function::BPatch_function
62  *
63  * Constructor that creates a BPatch_function.
64  *
65  */
66 unsigned fbHash(function_base * const &bp ) { return(addrHash4((Address) bp)); }
67
68 dictionary_hash <function_base*, BPatch_function*> PDFuncToBPFunc(fbHash);
69
70 BPatch_function::BPatch_function(process *_proc, function_base *_func,
71         BPatch_module *_mod) :
72         proc(_proc), mod(_mod), func(_func)
73 {
74
75   // there should be at most one BPatch_func for each function_base
76   assert(!PDFuncToBPFunc[_func]);
77
78   localVariables = new BPatch_localVarCollection;
79   funcParameters = new BPatch_localVarCollection;
80   retType = NULL;
81
82   PDFuncToBPFunc[_func] = this;
83 };
84
85 /*
86  * BPatch_function::BPatch_function
87  *
88  * Constructor that creates the BPatch_function with return type.
89  *
90  */
91 BPatch_function::BPatch_function(process *_proc, function_base *_func,
92                                  BPatch_type * _retType, BPatch_module *_mod) :
93         proc(_proc), mod(_mod), func(_func)
94 {
95   localVariables = new BPatch_localVarCollection;
96   funcParameters = new BPatch_localVarCollection;
97   retType = _retType;
98 };
99
100
101 /*
102  * BPatch_function::getName
103  *
104  * Copies the name of the function into a buffer, up to a given maximum
105  * length.  Returns a pointer to the beginning of the buffer that was
106  * passed in.
107  *
108  * s            The buffer into which the name will be copied.
109  * len          The size of the buffer.
110  */
111 char *BPatch_function::getName(char *s, int len)
112 {
113     assert(func);
114     string name = func->prettyName();
115     strncpy(s, name.string_of(), len);
116
117     return s;
118 }
119
120
121 /*
122  * BPatch_function::getBaseAddr
123  *
124  * Returns the starting address of the function.
125  */
126 void *BPatch_function::getBaseAddr()
127 {
128      return (void *)func->getEffectiveAddress(proc);
129 }
130
131
132 /*
133  * BPatch_function::getSize
134  *
135  * Returns the size of the function in bytes.
136  */
137 unsigned int BPatch_function::getSize()
138 {
139   return func->size();
140 }
141
142
143 /*
144  * BPatch_function::findPoint
145  *
146  * Returns a vector of the instrumentation points from a procedure that is
147  * identified by the parameters, or returns NULL upon failure.
148  * (Points are sorted by address in the vector returned.)
149  *
150  * loc          The points within the procedure to return.  The following
151  *              values are valid for this parameter:
152  *                BPatch_entry         The function's entry point.
153  *                BPatch_exit          The function's exit point(s).
154  *                BPatch_subroutine    The points at which the procedure calls
155  *                                     other procedures.
156  *                BPatch_longJump      The points at which the procedure make
157  *                                     long jump calls.
158  *                BPatch_allLocations  All of the points described above.
159  */
160 BPatch_Vector<BPatch_point*> *BPatch_function::findPoint(
161         const BPatch_procedureLocation loc)
162 {
163     // function does not exist!
164     if (func == NULL) return NULL;
165
166     // function is generally uninstrumentable (with current technology)
167     if (func->funcEntry(proc) == NULL) return NULL;
168
169     BPatch_Vector<BPatch_point*> *result = new BPatch_Vector<BPatch_point *>;
170
171     if (loc == BPatch_entry || loc == BPatch_allLocations) {
172         BPatch_point *new_point = new BPatch_point(proc, this,
173                 const_cast<instPoint *>(func->funcEntry(proc)), BPatch_entry);
174         result->push_back(new_point);
175     }
176     switch (loc) {
177       case BPatch_entry: // already done
178           break;
179       case BPatch_allLocations:
180         {
181           const vector<instPoint *> &Rpoints = func->funcExits(proc);
182           const vector<instPoint *> &Cpoints = func->funcCalls(proc);
183           BPatch_point *new_point;
184           unsigned int c=0, r=0;
185           Address cAddr, rAddr;
186           while (c < Cpoints.size() || r < Rpoints.size()) {
187               if (c < Cpoints.size()) cAddr = Cpoints[c]->iPgetAddress();
188               else                    cAddr = (Address)(-1);
189               if (r < Rpoints.size()) rAddr = Rpoints[r]->iPgetAddress();
190               else                    rAddr = (Address)(-1);
191               if (cAddr <= rAddr) {
192                   new_point = new BPatch_point(proc, this, Cpoints[c], 
193                         BPatch_subroutine);
194                   c++;
195               } else {
196                   new_point = new BPatch_point(proc, this, Rpoints[r], 
197                         BPatch_exit);
198                   r++;
199               }
200               result->push_back(new_point);
201           }
202           break;
203         }
204       case BPatch_exit:
205         {
206           const vector<instPoint *> &points = func->funcExits(proc);
207           for (unsigned i = 0; i < points.size(); i++) {
208               BPatch_point *new_point = new BPatch_point(proc, this, points[i],
209                                                          BPatch_exit);
210               result->push_back(new_point);
211           }
212           break;
213         }
214       case BPatch_subroutine:
215         {
216           const vector<instPoint *> &points = func->funcCalls(proc);
217           for (unsigned i = 0; i < points.size(); i++) {
218               BPatch_point *new_point = new BPatch_point(proc, this, points[i],
219                                                          BPatch_subroutine);
220               result->push_back(new_point);
221           }
222           break;
223         }
224       case BPatch_longJump:
225         /* XXX Not yet implemented */
226       default:
227         assert( 0 );
228     }
229
230     return result;
231 }
232
233 /*
234  * BPatch_function::addParam()
235  *
236  * This function adds a function parameter to the BPatch_function parameter
237  * vector.
238  */
239 void BPatch_function::addParam(char * _name, BPatch_type *_type, int _linenum,
240                                int _frameOffset, int _sc)
241 {
242   BPatch_localVar * param = new BPatch_localVar(_name, _type, _linenum,
243                                                 _frameOffset, _sc);
244
245   // Add parameter to list of parameters
246   params.push_back(param);
247 }
248
249 /*
250  * BPatch_function::findLocalVar()
251  *
252  * This function searchs for a local variable in the BPatch_function's
253  * local variable collection.
254  */
255 BPatch_localVar * BPatch_function::findLocalVar(const char * name)
256 {
257
258   BPatch_localVar * var = localVariables->findLocalVar(name);
259   return (var);
260
261 }
262
263 /*
264  * BPatch_function::findLocalParam()
265  *
266  * This function searchs for a function parameter in the BPatch_function's
267  * parameter collection.
268  */
269 BPatch_localVar * BPatch_function::findLocalParam(const char * name)
270 {
271
272   BPatch_localVar * var = funcParameters->findLocalVar(name);
273   return (var);
274
275 }