Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / BPatch_function.C
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 // $Id: BPatch_function.C,v 1.109 2008/11/03 15:19:24 jaw Exp $
33
34 #define BPATCH_FILE
35
36 #include <string.h>
37 #include <string>
38 #include "symtab.h"
39 #include "process.h"
40 #include "instPoint.h"
41 #include "ast.h"
42
43 #include "BPatch.h"
44 #include "BPatch_function.h"
45 #include "BPatch_type.h"
46 #include "BPatch_collections.h"
47 #include "BPatch_Vector.h"
48 #include "BPatch_flowGraph.h"
49 #include "BPatch_libInfo.h"
50 #include "BPatch_memoryAccess_NP.h"
51 #include "BPatch_basicBlock.h"
52 #include "BPatch_statement.h"
53 #include "mapped_module.h"
54
55 #include "common/h/Types.h"
56 #if !defined(cap_instruction_api)
57 #include "InstrucIter-Function.h"
58 #endif
59
60
61
62
63 /**************************************************************************
64  * BPatch_function
65  *************************************************************************/
66 /*
67  * BPatch_function::BPatch_function
68  *
69  * Constructor that creates a BPatch_function.
70  *
71  */
72
73 int bpatch_function_count = 0;
74
75 BPatch_function::BPatch_function(BPatch_addressSpace *_addSpace, 
76                                  int_function *_func,
77                                  BPatch_module *_mod) :
78         addSpace(_addSpace), 
79    lladdSpace(_func->proc()),
80    mod(_mod),
81    cfg(NULL), 
82    cfgCreated(false), 
83    liveInit(false),
84    func(_func), 
85         varsAndParamsValid(false)
86 {
87    _srcType = BPatch_sourceFunction;
88    
89    localVariables = new BPatch_localVarCollection;
90    funcParameters = new BPatch_localVarCollection;
91    retType = NULL;
92    
93    assert(mod && !mod->func_map.count(func));
94    mod->func_map[func] = this;
95 };
96
97 /*
98  * BPatch_function::BPatch_function
99  *
100  * Constructor that creates the BPatch_function with return type.
101  *
102  */
103 BPatch_function::BPatch_function(BPatch_addressSpace *_addSpace, int_function *_func,
104                                  BPatch_type * _retType, BPatch_module *_mod) :
105         addSpace(_addSpace),
106    lladdSpace(_func->proc()),
107    mod(_mod),
108    cfg(NULL),
109    cfgCreated(false),
110    liveInit(false), 
111    func(_func),
112         varsAndParamsValid(false)
113 {
114   _srcType = BPatch_sourceFunction;
115
116   localVariables = new BPatch_localVarCollection;
117   funcParameters = new BPatch_localVarCollection;
118   retType = _retType;
119
120   assert(mod);
121   mod->func_map[func] = this;
122 };
123
124
125 BPatch_function::~BPatch_function()
126 {
127    if (localVariables) delete localVariables;
128    if (funcParameters) delete funcParameters;
129    
130    if (cfg) delete cfg;
131    
132    // Remove us from the proc map...
133    int num_erased = mod->func_map.erase(lowlevel_func());
134    assert(num_erased == 1);
135 }
136
137 /* 
138  * BPatch_function::getSourceObj()
139  *
140  * Return the contained source objects (e.g. statements).
141  *    This is not currently supported.
142  *
143  */
144 bool BPatch_function::getSourceObj(BPatch_Vector<BPatch_sourceObj *> &children)
145 {
146     // init and empty vector
147     BPatch_Vector<BPatch_sourceObj *> dummy;
148
149     children = dummy;
150     return false;
151 }
152
153
154 BPatch_process * BPatch_function::getProc() const
155 {
156   assert(addSpace->getType() == TRADITIONAL_PROCESS); 
157   return dynamic_cast<BPatch_process *>(addSpace); 
158 }
159
160
161 /*
162  * BPatch_function::getObjParent()
163  *
164  * Return the parent of the function (i.e. the module)
165  *
166  */
167 BPatch_sourceObj *BPatch_function::getObjParent()
168 {
169     return (BPatch_sourceObj *) mod;
170 }
171
172 /*
173  * BPatch_function::getName
174  *
175  * Copies the name of the function into a buffer, up to a given maximum
176  * length.  Returns a pointer to the beginning of the buffer that was
177  * passed in.
178  *
179  * s            The buffer into which the name will be copied.
180  * len          The size of the buffer.
181  */
182 char *BPatch_function::getNameBuffer(char *s, int len)
183 {
184     assert(func);
185     string name = func->prettyName();
186     strncpy(s, name.c_str(), len);
187     return s;
188 }
189
190 #ifdef IBM_BPATCH_COMPAT
191 const char *BPatch_function::getNameDPCL()
192 {
193     assert(func);
194     return func->prettyName().c_str();
195 }
196 #endif
197
198 /*
199  * BPatch_function::getMangledName
200  *
201  * Copies the mangled name of the function into a buffer, up to a given maximum
202  * length.  Returns a pointer to the beginning of the buffer that was
203  * passed in.
204  *
205  * s            The buffer into which the name will be copied.
206  * len          The size of the buffer.
207  */
208 char *BPatch_function::getMangledNameInt(char *s, int len)
209 {
210   assert(func);
211   string mangledname = func->symTabName();
212   strncpy(s, mangledname.c_str(), len);
213   return s;
214 }
215
216 /*
217  * BPatch_function::getTypedName
218  *
219  * Copies the mangled name of the function into a buffer, up to a given maximum
220  * length.  Returns a pointer to the beginning of the buffer that was
221  * passed in.
222  *
223  * s            The buffer into which the name will be copied.
224  * len          The size of the buffer.
225  */
226 char *BPatch_function::getTypedNameInt(char *s, int len)
227 {
228   assert(func);
229   string typedname = func->typedName();
230   strncpy(s, typedname.c_str(), len);
231   return s;
232 }
233
234
235 /*
236  * BPatch_function::getNames
237  *
238  * Copies all names of the function into the provided BPatch_Vector.
239  * Names are represented as const char *s and are
240  * allocated/deallocated by Dyninst.
241  *
242  * names           BPatch_Vector reference
243  */
244
245 bool BPatch_function::getNamesInt(BPatch_Vector<const char *> &names)
246 {
247     assert(func);
248     unsigned pre_size = names.size();
249
250     for (unsigned i = 0; i < func->prettyNameVector().size(); i++) {
251         names.push_back(func->prettyNameVector()[i].c_str());
252     }
253
254     return names.size() > pre_size;
255 }
256
257 /*
258  * BPatch_function::getMangledNames
259  *
260  * Copies all mangled names of the function into the provided
261  * BPatch_Vector.  Names are represented as const char *s and are
262  * allocated/deallocated by Dyninst.
263  *
264  * names           BPatch_Vector reference
265  */
266
267 bool BPatch_function::getMangledNamesInt(BPatch_Vector<const char *> &names)
268 {
269     assert(func);
270     unsigned pre_size = names.size();
271
272     for (unsigned i = 0; i < func->symTabNameVector().size(); i++) {
273         names.push_back(func->symTabNameVector()[i].c_str());
274     }
275
276     return names.size() > pre_size;
277 }
278
279
280
281 /*
282  * BPatch_function::getBaseAddr
283  *
284  * Returns the starting address of the function.
285  */
286 void *BPatch_function::getBaseAddrInt()
287 {
288   return (void *)func->getAddress();
289 }
290
291 /*
292  * BPatch_function::getSize
293  *
294  * Returns the size of the function in bytes.
295  */
296 unsigned int BPatch_function::getSizeInt() 
297 {
298     return func->getSize_NP();
299 }
300
301 /*
302  * BPatch_function::getReturnType
303  *
304  * Returns the return type of the function.
305  */
306 BPatch_type *BPatch_function::getReturnTypeInt()
307 {
308     constructVarsAndParams();
309     return retType;
310 }
311
312 /*
313  * BPatch_function::getModule
314  *
315  * Returns the BPatch_module to which this function belongs.
316  */
317 BPatch_module *BPatch_function::getModuleInt()
318 {
319   return mod;
320 }
321
322 //  BPatch_function::getParams
323 //  Returns a vector of BPatch_localVar, representing this function's parameters
324
325 BPatch_Vector<BPatch_localVar *> * BPatch_function::getParamsInt()
326 {
327     if (!mod->isValid()) return NULL;
328     constructVarsAndParams();
329     return funcParameters->getAllVars();
330 }
331
332 /*
333  * BPatch_function::findPoint
334  *
335  * Returns a vector of the instrumentation points from a procedure that is
336  * identified by the parameters, or returns NULL upon failure.
337  * (Points are sorted by address in the vector returned.)
338  *
339  * loc          The points within the procedure to return.  The following
340  *              values are valid for this parameter:
341  *                BPatch_entry         The function's entry point.
342  *                BPatch_exit          The function's exit point(s).
343  *                BPatch_subroutine    The points at which the procedure calls
344  *                                     other procedures.
345  *                BPatch_longJump      The points at which the procedure make
346  *                                     long jump calls.
347  *                BPatch_allLocations  All of the points described above.
348  */
349 BPatch_Vector<BPatch_point*> *BPatch_function::findPointInt(
350         const BPatch_procedureLocation loc)
351 {
352     // function does not exist!
353     if (func == NULL) return NULL;
354
355     if (!mod->isValid()) return NULL;
356
357     // if the function is not instrumentable, we won't find the point
358     if (!isInstrumentable())
359        return NULL;
360
361     // function is generally uninstrumentable (with current technology)
362     if (func->funcEntries().size() == 0) return NULL;
363
364     BPatch_Vector<BPatch_point*> *result = new BPatch_Vector<BPatch_point *>;
365
366     if (loc == BPatch_entry || loc == BPatch_allLocations) {
367         const pdvector<instPoint *> entries = func->funcEntries();
368         for (unsigned foo = 0; foo < entries.size(); foo++)
369             result->push_back(addSpace->findOrCreateBPPoint(this, 
370                                                         entries[foo], 
371                                                         BPatch_entry));
372     }
373     switch (loc) {
374       case BPatch_entry: // already done
375           break;
376       case BPatch_allLocations:
377         {
378           const pdvector<instPoint *> &Rpoints = func->funcExits();
379           const pdvector<instPoint *> &Cpoints = func->funcCalls();
380           unsigned int c=0, r=0;
381           Address cAddr, rAddr;
382           while (c < Cpoints.size() || r < Rpoints.size()) {
383               if (c < Cpoints.size()) cAddr = Cpoints[c]->addr();
384               else                    cAddr = (Address)(-1);
385               if (r < Rpoints.size()) rAddr = Rpoints[r]->addr();
386               else                    rAddr = (Address)(-1);
387               if (cAddr <= rAddr) {
388                   result->push_back(addSpace->findOrCreateBPPoint(
389                                                               this, Cpoints[c], BPatch_subroutine));
390               c++;
391             } else {
392                  result->push_back(addSpace->findOrCreateBPPoint(
393                                    this, Rpoints[r], BPatch_exit));
394                  r++;
395             }
396           }
397           break;
398         }
399       case BPatch_exit:
400         {
401           const pdvector<instPoint *> &points = func->funcExits();
402           for (unsigned i = 0; i < points.size(); i++) {
403              result->push_back(addSpace->findOrCreateBPPoint(
404                                              this, points[i], BPatch_exit));
405           }
406           break;
407         }
408       case BPatch_subroutine:
409         {
410           const pdvector<instPoint *> &points = func->funcCalls();
411           for (unsigned i = 0; i < points.size(); i++) {
412              result->push_back(addSpace->findOrCreateBPPoint(
413                                           this, points[i], BPatch_subroutine));
414           }
415           break;
416         }
417       case BPatch_longJump:
418         /* XXX Not yet implemented */
419       default:
420         assert( 0 );
421     }
422
423     return result;
424 }
425
426 /*
427  * BPatch_function::findPoint (VG 09/05/01)
428  *
429  * Returns a vector of the instrumentation points from a procedure that is
430  * identified by the parameters, or returns NULL upon failure.
431  * (Points are sorted by address in the vector returned.)
432  *
433  * ops          The points within the procedure to return. A set of op codes
434  *              defined in BPatch_opCode (BPatch_point.h)
435  */
436
437 struct compareByEntryAddr
438 {
439     bool operator()(const BPatch_basicBlock* lhs, const BPatch_basicBlock* rhs)
440     {
441         return const_cast<BPatch_basicBlock*>(lhs)->getStartAddress() < 
442                         const_cast<BPatch_basicBlock*>(rhs)->getStartAddress();
443     }
444 };
445  
446 BPatch_Vector<BPatch_point*> *BPatch_function::findPointByOp(
447         const BPatch_Set<BPatch_opCode>& ops)
448 {
449   // function does not exist!
450   if (func == NULL) return NULL;
451
452     if (!mod->isValid()) return NULL;
453 #if defined(cap_instruction_api)
454   // function is generally uninstrumentable (with current technology)
455   if (func->funcEntries().size() == 0) return NULL;
456
457   std::set<BPatch_basicBlock*, compareByEntryAddr> blocks;
458   std::set<BPatch_basicBlock*> unsorted_blocks;
459   getCFG()->getAllBasicBlocks(unsorted_blocks);
460   std::copy(unsorted_blocks.begin(), unsorted_blocks.end(), std::inserter(blocks, blocks.begin()));
461   BPatch_Vector<BPatch_point*>* ret = new BPatch_Vector<BPatch_point*>;
462   for(std::set<BPatch_basicBlock*, compareByEntryAddr>::iterator curBlk = blocks.begin();
463       curBlk != blocks.end();
464      curBlk++)
465   {
466       BPatch_Vector<BPatch_point*>* tmp = (*curBlk)->findPoint(ops);
467       for (unsigned int i = 0; i < tmp->size(); i++)
468       {
469           ret->push_back((*tmp)[i]);
470       } 
471       
472   }
473   return ret;
474 #else  
475   // Use an instruction iterator
476   InstrucIterFunction ii(func);
477     
478   return BPatch_point::getPoints(ops, ii, this);
479 #endif
480 }
481
482 /*
483  * BPatch_function::addParam()
484  *
485  * This function adds a function parameter to the BPatch_function parameter
486  * vector.
487  */
488 void BPatch_function::addParam(Dyninst::SymtabAPI::localVar *lvar)
489 {
490   BPatch_localVar * param = new BPatch_localVar(lvar);
491   
492   // Add parameter to list of parameters
493   params.push_back(param);
494 }
495
496 #if 0
497 void BPatch_function::addParam(const char * _name, BPatch_type *_type,
498                                int _linenum, long _frameOffset, int _reg,
499                                BPatch_storageClass _sc)
500 {
501   BPatch_localVar * param = new BPatch_localVar(_name, _type, _linenum,
502                                                 _frameOffset, _reg, _sc);
503
504   // Add parameter to list of parameters
505   params.push_back(param);
506 }
507 #endif
508
509 /*
510  * BPatch_function::findLocalVarInt()
511  *
512  * This function searchs for a local variable in the BPatch_function's
513  * local variable collection.
514  */
515 BPatch_localVar * BPatch_function::findLocalVarInt(const char * name)
516 {
517     if (!mod->isValid()) 
518                 return NULL;
519     constructVarsAndParams();
520     BPatch_localVar * var = localVariables->findLocalVar(name);
521     return (var);
522 }
523
524 /*
525  * BPatch_function::findLocalParam()
526  *
527  * This function searchs for a function parameter in the BPatch_function's
528  * parameter collection.
529  */
530 BPatch_localVar * BPatch_function::findLocalParamInt(const char * name)
531 {
532     if (!mod->isValid()) return NULL;
533     constructVarsAndParams();
534     BPatch_localVar * var = funcParameters->findLocalVar(name);
535     return (var);
536 }
537
538 BPatch_flowGraph* BPatch_function::getCFGInt()
539 {
540     assert(mod);
541     if (!mod->isValid()) return NULL;
542     if (cfg)
543         return cfg;
544     bool valid = false;
545     cfg = new BPatch_flowGraph(this, valid);
546     if (!valid) {
547         delete cfg;
548         cfg = NULL;
549         fprintf(stderr, "CFG is NULL in %s\n", lowlevel_func()->symTabName().c_str());
550         return NULL;
551     }
552     return cfg;
553 }
554
555 void BPatch_function::constructVarsAndParams()
556 {
557     if (varsAndParamsValid)
558        return;
559
560     if (mod) 
561         {
562         mod->parseTypesIfNecessary();
563     }
564
565     //Check flag to see if vars & params are already constructed
566     std::vector<localVar *>vars;
567
568     if (lowlevel_func()->ifunc()->getSymtabFunction()->getLocalVariables(vars)) 
569         {
570         for (unsigned i = 0; i< vars.size(); i++) 
571             {
572             if (mod) 
573                         {
574                 vars[i]->fixupUnknown(mod->lowlevel_mod()->pmod()->mod());
575             }
576
577                 localVariables->addLocalVar(new BPatch_localVar(vars[i]));
578             }    
579     }
580
581     std::vector<localVar *>parameters;
582
583     if (lowlevel_func()->ifunc()->getSymtabFunction()->getParams(parameters)) 
584         {
585         for (unsigned i = 0; i< parameters.size(); i++) 
586                 {
587             if (mod) 
588                         {
589                 parameters[i]->fixupUnknown(mod->lowlevel_mod()->pmod()->mod());
590             }
591
592                 BPatch_localVar *lparam = new BPatch_localVar(parameters[i]);
593             funcParameters->addLocalVar(lparam);
594                 params.push_back(lparam);
595         }    
596     }
597
598     if (!lowlevel_func()->ifunc()->getSymtabFunction()->getReturnType()) 
599         {
600         varsAndParamsValid = true;
601         return;
602     }
603         
604         SymtabAPI::Type *ret_type = lowlevel_func()->ifunc()->getSymtabFunction()->getReturnType();
605         assert(ret_type);
606
607         extern AnnotationClass<BPatch_type> TypeUpPtrAnno;
608
609         if (!ret_type->getAnnotation(retType, TypeUpPtrAnno))
610         {
611                 //  BPatch_type ctor adds the annotation to the lowlevel symtab type, so 
612                 //  no need to do it here.
613                 retType = new BPatch_type(ret_type);
614         }
615         else
616                 assert(retType);
617
618     varsAndParamsValid = true;
619 }
620
621 BPatch_Vector<BPatch_localVar *> *BPatch_function::getVarsInt() 
622 {
623     if (!mod->isValid()) return NULL;
624     constructVarsAndParams();
625     return localVariables->getAllVars(); 
626 }
627
628 bool BPatch_function::findVariableInt(const char *name, 
629                                       BPatch_Vector<BPatch_variableExpr *> &vars) 
630 {
631    if (!mod->isValid()) 
632            return false;
633
634    constructVarsAndParams();
635
636    BPatch_localVar *lv = findLocalVar(name);
637
638    if (!lv) 
639    {
640       // look for it in the parameter scope now
641       lv = findLocalParam(name);
642    }
643
644    if (lv) 
645    {
646       // create a local expr with the correct frame offset or absolute
647       //   address if that is what is needed
648       std::map<BPatch_localVar *, BPatch_variableExpr*>::iterator i;
649       i = local_vars.find(lv);
650
651       if (i != local_vars.end()) 
652           {
653          vars.push_back((*i).second);
654          return true;
655       }
656
657       BPatch_Vector<BPatch_point*> *points = findPoint(BPatch_entry);
658       assert(points->size() == 1);
659       BPatch_image *imgPtr = (BPatch_image *) mod->getObjParent();
660
661       BPatch_variableExpr *nv = new BPatch_variableExpr(imgPtr->getAddressSpace(),
662                                                         func->proc(),
663                                                         lv, lv->getType(), (*points)[0]);
664       vars.push_back(nv);
665       return true;
666    }
667
668    // finally check the global scope.
669    BPatch_image *imgPtr = (BPatch_image *) mod->getObjParent();
670    
671    if (!imgPtr) return false;
672    
673    BPatch_variableExpr *var = imgPtr->findVariable(name);
674    if (!var) return false;
675    
676    vars.push_back(var);
677    return true;   
678 }
679
680
681 BPatch_Vector<BPatch_variableExpr *> *BPatch_function::findVariableInt(const char *name)
682 {
683    BPatch_Vector<BPatch_variableExpr *> *vars = new BPatch_Vector<BPatch_variableExpr*>;
684    bool result = findVariableInt(name, *vars);
685    if (!result) {
686       delete vars;
687       return NULL;
688    }
689    return vars;
690 }
691
692 bool BPatch_function::getVariablesInt(BPatch_Vector<BPatch_variableExpr *> &/*vect*/)
693 {
694         return false;
695 }
696
697 char *BPatch_function::getModuleNameInt(char *name, int maxLen) {
698     return getModule()->getName(name, maxLen);
699 }
700
701 BPatch_variableExpr *BPatch_function::getFunctionRefInt() 
702 {
703   Address remoteAddress = (Address)getBaseAddrInt();
704   char *fname = const_cast<char *>(func->prettyName().c_str());
705
706   //  Need to figure out the type for this effective function pointer,
707   //  of the form <return type> (*)(<arg1 type>, ... , <argn type>)
708   
709   //  Note:  getParamsInt allocates the vector
710   assert(retType);
711   char typestr[1024];
712   sprintf(typestr, "%s (*)(", retType->getName());
713   
714   BPatch_Vector<BPatch_localVar *> *params = getParamsInt();
715   assert(params);
716   
717   for (unsigned int i = 0; i < params->size(); ++i) {
718      if (i >= (params->size() -1)) {
719         //  no comma after last parameter
720         sprintf(typestr, "%s %s", typestr, (*params)[i]->getName());
721      } else 
722         sprintf(typestr, "%s %s,", typestr, (*params)[i]->getName());
723   }
724   sprintf(typestr, "%s)", typestr);
725   
726   BPatch_type *type = addSpace->image->findType(typestr);
727   if (!type) {
728      fprintf(stderr, "%s[%d]:  cannot find type '%s'\n", FILE__, __LINE__, typestr);
729   }
730   assert(type);
731   
732   //  only the vector was newly allocated, not the parameters themselves
733   delete [] params;
734   
735 #if defined( arch_ia64 )
736   // IA-64 function pointers actually point to structures.  We insert such
737   // a structure in the mutatee so that instrumentation can use it. */
738   Address entryPoint = (Address)getBaseAddr();
739   
740   //RUTAR, need to change this over when we start to support IA64
741   assert(addSpace->getType() == TRADITIONAL_PROCESS);
742   BPatch_process * proc = dynamic_cast<BPatch_process *>(addSpace);
743   Address gp = proc->llproc->getTOCoffsetInfo( entryPoint );
744   
745   remoteAddress = proc->llproc->inferiorMalloc( sizeof( Address ) * 2 );
746   assert( remoteAddress != (Address)NULL );
747   
748   if (!proc->llproc->writeDataSpace( (void *)remoteAddress, sizeof( Address ), & entryPoint ))
749      fprintf(stderr, "%s[%d]:  writeDataSpace failed\n", FILE__, __LINE__);
750   if (!proc->llproc->writeDataSpace( (void *)(remoteAddress + sizeof( Address )), 
751                                      sizeof( Address ), & gp ))
752      fprintf(stderr, "%s[%d]:  writeDataSpace failed\n", FILE__, __LINE__);
753   
754   
755   AstNodePtr wrapper(AstNode::operandNode(AstNode::Constant, (void *) remoteAddress));
756   // variableExpr owns the AST
757   return new BPatch_variableExpr(fname, proc, lladdSpace, wrapper, 
758                                  type, (void *) remoteAddress); 
759   //return (BPatch_function::voidVoidFunctionPointer)remoteAddress;
760   
761 #else
762   //  For other platforms, the baseAddr of the function should be sufficient.
763   
764   //  In truth it would make more sense for this to be a BPatch_constExpr,
765   //  But since we are adding this as part of the DPCL compatibility process
766   //  we use the IBM API, to eliminate one API difference.
767   
768   AstNodePtr ast(AstNode::operandNode(AstNode::Constant, (void *) remoteAddress));
769   
770   // the variableExpr owns the ast now.
771   return new BPatch_variableExpr(fname, addSpace, lladdSpace, ast, 
772                                  type, (void *) remoteAddress);
773   
774 #endif
775
776 } /* end getFunctionRef() */
777
778 #ifdef IBM_BPATCH_COMPAT
779
780 bool BPatch_function::getLineNumbersInt(unsigned int &start, unsigned int &end) {
781   char name[256];
782   unsigned int length = 255;
783   return getLineAndFileInt(start, end, name, length);
784 }
785
786 void *BPatch_function::getAddressInt() { return getBaseAddr(); }
787     
788 bool BPatch_function::getAddressRangeInt(void * &start, void * &end) {
789         start = getBaseAddr();
790         unsigned long temp = (unsigned long) start;
791         end = (void *) (temp + getSize());
792
793         return true;
794 }
795
796 //BPatch_type *BPatch_function::returnType() { return retType; }
797 void BPatch_function::getIncPointsInt(BPatch_Vector<BPatch_point *> &vect) 
798 {
799     BPatch_Vector<BPatch_point *> *v1 = findPoint(BPatch_allLocations);
800     if (v1) {
801         for (unsigned int i=0; i < v1->size(); i++) {
802             vect.push_back((*v1)[i]);
803         }
804     }
805 }
806
807 int     BPatch_function::getMangledNameLenInt() { return 1024; }
808
809 void BPatch_function::getExcPointsInt(BPatch_Vector<BPatch_point*> &points) {
810   points.clear();
811   abort();
812   return;
813 };
814
815
816 #endif
817
818 /*
819  * BPatch_function::isInstrumentable
820  *
821  * Returns true if the function is instrumentable, false otherwise.
822  */
823 bool BPatch_function::isInstrumentableInt()
824 {
825      return ((int_function *)func)->isInstrumentable();
826 }
827
828 // Return TRUE if the function resides in a shared lib, FALSE otherwise
829
830 bool BPatch_function::isSharedLibInt(){
831   return mod->isSharedLib();
832
833
834 void BPatch_function::fixupUnknown(BPatch_module *module) {
835    if (retType != NULL && retType->getDataClass() == BPatch_dataUnknownType) 
836       retType = module->getModuleTypes()->findType(retType->getID());
837
838    for (unsigned int i = 0; i < params.size(); i++)
839       params[i]->fixupUnknown(module);
840    if (localVariables != NULL) {
841       BPatch_Vector<BPatch_localVar *> *vars = localVariables->getAllVars();
842       for (unsigned int i = 0; i < vars->size(); i++)
843          (*vars)[i]->fixupUnknown(module);
844       delete vars;
845    }
846 }
847
848 bool BPatch_function::containsSharedBlocks() {
849     return func->containsSharedBlocks();
850 }
851
852 // isPrimary: function will now use this name as a primary output name
853 // isMangled: this is the "mangled" name rather than demangled (pretty)
854 const char *BPatch_function::addNameInt(const char *name,
855                                         bool isPrimary, /* = true */
856                                         bool isMangled) { /* = false */
857     // Add to the internal function object
858     //    Add to the container mapped_object name mappings
859     //    Add to the proc-independent function object
860     //       Add to the container image class
861
862     if (isMangled) {
863         func->addSymTabName(std::string(name),
864                             isPrimary);
865     }
866     else {
867         func->addPrettyName(std::string(name),
868                               isPrimary);
869     }
870     return name;
871 }
872
873 /* This function should be deprecated. */
874 bool BPatch_function::getLineAndFileInt( unsigned int & start, 
875                                          unsigned int & end, 
876                                          char * filename, 
877                                          unsigned int max ) 
878 {
879    Address startAddress = func->getAddress();
880    Address endAddress = startAddress + func->getSize_NP();
881         
882    BPatch_Vector<BPatch_statement> startLines;
883    if ( ! mod->getSourceLines( startAddress, startLines ) ) { return false; }
884    if ( startLines.size() == 0 ) { return false; }
885    start = startLines[0].lineNumber();
886         
887    /* Arbitrarily... */
888    strncpy( filename, startLines[0].fileName(), max );
889         
890    BPatch_Vector<BPatch_statement> endLines;
891    if ( ! mod->getSourceLines( endAddress, endLines ) ) { return false; }
892    if ( endLines.size() == 0 ) { return false; }
893    end = endLines[0].lineNumber();
894
895 return true;
896 } /* end getLineAndFile() */
897
898 /* This function should be deprecated. */
899 bool BPatch_function::getLineToAddrInt( unsigned short lineNo, BPatch_Vector< unsigned long > & buffer, bool /* exactMatch */ ) {
900         std::vector< std::pair< unsigned long, unsigned long > > ranges;
901         if( ! mod->getAddressRanges( NULL, lineNo, ranges ) ) { return false; }
902         
903         for( unsigned int i = 0; i < ranges.size(); ++i ) {
904                 buffer.push_back( ranges[i].first );
905                 }
906         
907         return true;
908         } /* end getLineToAddr() */
909
910 unsigned int BPatch_function::getContiguousSizeInt() {
911    Address start, end;
912    start = func->getAddress();
913    end = start + func->getSize_NP();
914     
915     bblInstance* block = func->findBlockInstanceByAddr(start);
916     while (block != NULL) {
917        end = block->firstInsnAddr() + block->getSize();
918        block = func->findBlockInstanceByAddr(end);
919     }
920     return end - start;
921 }
922
923 bool BPatch_function::findOverlappingInt(BPatch_Vector<BPatch_function *> &funcs) {
924     assert(func);
925     assert(addSpace);
926
927     pdvector<int_function *> overlappingIntFuncs;
928     if (!func->getOverlappingFuncs(overlappingIntFuncs)) {
929         // No overlapping functions
930         return false;
931     }
932
933     // We now need to map from int_functions to BPatch_functions
934     for (unsigned i = 0; i < overlappingIntFuncs.size(); i++) {
935         funcs.push_back(addSpace->findOrCreateBPFunc(overlappingIntFuncs[i],
936                                                  mod));
937     }
938
939     return true;
940 }
941