BPatch functions that block are now locked (on a finer grain than the rest of the...
[dyninst.git] / dyninstAPI / src / solaris.C
1 /*
2  * Copyright (c) 1996-2004 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: solaris.C,v 1.173 2005/02/25 07:04:47 jaw Exp $
43
44 #include "dyninstAPI/src/symtab.h"
45 #include "common/h/headers.h"
46 #include "dyninstAPI/src/process.h"
47 #include "dyninstAPI/src/dyn_thread.h"
48 #include "dyninstAPI/src/stats.h"
49 #include "common/h/Types.h"
50 #include <sys/ioctl.h>
51 #include <fcntl.h>
52 #include <sys/termios.h>
53 #include <unistd.h>
54 #include "dyninstAPI/src/showerror.h"
55 #include "common/h/pathName.h" // concat_pathname_components()
56 #include "common/h/debugOstream.h"
57 #include "common/h/solarisKludges.h"
58
59 #if defined (sparc_sun_solaris2_4)
60 #include "dyninstAPI/src/inst-sparc.h"
61 #else
62 #include "dyninstAPI/src/inst-x86.h"
63 #endif
64
65 #include "instPoint.h"
66
67 #include <procfs.h>
68 #include <stropts.h>
69 #include <link.h>
70 #include <dlfcn.h>
71
72 #include "dyn_lwp.h"
73
74 #define DLOPEN_MODE (RTLD_NOW | RTLD_GLOBAL)
75
76 int (*P_native_demangle)(const char *, char *, size_t);
77
78 extern "C" {
79 extern long sysconf(int);
80 };
81
82 // The following were defined in process.C
83
84 extern unsigned enable_pd_attach_detach_debug;
85
86 #if ENABLE_DEBUG_CERR == 1
87 #define attach_cerr if (enable_pd_attach_detach_debug) cerr
88 #else
89 #define attach_cerr if (0) cerr
90 #endif /* ENABLE_DEBUG_CERR == 1 */
91
92 extern unsigned enable_pd_inferior_rpc_debug;
93
94 #if ENABLE_DEBUG_CERR == 1
95 #define inferiorrpc_cerr if (enable_pd_inferior_rpc_debug) cerr
96 #else
97 #define inferiorrpc_cerr if (0) cerr
98 #endif /* ENABLE_DEBUG_CERR == 1 */
99
100 extern unsigned enable_pd_shm_sampling_debug;
101
102 #if ENABLE_DEBUG_CERR == 1
103 #define shmsample_cerr if (enable_pd_shm_sampling_debug) cerr
104 #else
105 #define shmsample_cerr if (0) cerr
106 #endif /* ENABLE_DEBUG_CERR == 1 */
107
108 extern unsigned enable_pd_fork_exec_debug;
109
110 #if ENABLE_DEBUG_CERR == 1
111 #define forkexec_cerr if (enable_pd_fork_exec_debug) cerr
112 #else
113 #define forkexec_cerr if (0) cerr
114 #endif /* ENABLE_DEBUG_CERR == 1 */
115
116 extern unsigned enable_pd_signal_debug;
117
118 #if ENABLE_DEBUG_CERR == 1
119 #define signal_cerr if (enable_pd_signal_debug) cerr
120 #else
121 #define signal_cerr if (0) cerr
122 #endif /* ENABLE_DEBUG_CERR == 1 */
123
124 /*
125    Define the indices of some registers to be used with pr_reg.
126    These values are different on sparc and x86 platforms.
127    RETVAL_REG: the registers that holds the return value of calls ($o0 on sparc,
128                %eax on x86).
129    PC_REG: program counter
130    FP_REG: frame pointer (%i7 on sparc, %ebp on x86) 
131 */
132 #ifdef sparc_sun_solaris2_4
133 #define PARAM1_REG (R_O0)
134 #define RETVAL_REG (R_O0)
135 #define PC_REG (R_PC)
136 #define FP_REG (R_O6)
137 #endif
138 #ifdef i386_unknown_solaris2_5
139 #define RETVAL_REG (EAX)
140 #define SP_REG (UESP)
141 #define PC_REG (EIP)
142 #define FP_REG (EBP)
143 #endif
144
145
146 extern void generateBreakPoint(instruction &insn);
147
148
149 // already setup on this FD.
150 // disconnect from controlling terminal 
151 void OS::osDisconnect(void) {
152   //This is the POSIX-compliant way of disconnecting from the terminal 
153   setpgrp();
154 }
155
156 /*
157  * The set operations (set_entry_syscalls and set_exit_syscalls) are defined
158  * in sol_proc.C
159  */
160
161
162 // Compatibility for /proc
163 bool process::get_entry_syscalls(sysset_t *entry)
164 {
165     pstatus_t status;
166     if (!get_status(&status)) return false;
167     
168     memcpy(entry, &(status.pr_sysentry), sizeof(sysset_t));    
169     return true;
170 }
171
172 bool process::get_exit_syscalls(sysset_t *exit)
173 {
174     pstatus_t status;
175     if (!get_status(&status)) return false;
176
177     memcpy(exit, &(status.pr_sysexit), sizeof(sysset_t));
178     return true;
179 }    
180
181 char* process::dumpPatchedImage(pdstring imageFileName){ //ccw 28 oct 2001
182
183         writeBackElf *newElf;
184         addLibrary *addLibraryElf;
185         void *data, *paddedData;
186         unsigned int errFlag=0;
187         char name[50];  
188         pdvector<imageUpdate*> compactedUpdates;
189         pdvector<imageUpdate*> compactedHighmemUpdates;
190         Address guardFlagAddr= trampGuardAddr();
191         char *mutatedSharedObjects=0;
192         int mutatedSharedObjectsSize = 0, mutatedSharedObjectsIndex=0;
193         char *directoryName = 0;
194         shared_object *sh_obj;
195         if(!collectSaveWorldData){
196                 BPatch_reportError(BPatchSerious,122,"dumpPatchedImage: BPatch_thread::enableDumpPatchedImage() not called.  No mutated binary saved\n");
197                 return NULL;
198         }
199
200
201         directoryName = saveWorldFindDirectory();
202
203         if(!directoryName){
204                 return NULL;
205         }
206         strcat(directoryName, "/");
207
208         unsigned int dl_debug_statePltEntry = 0x00016574;//a pretty good guess
209         unsigned int dyninst_SharedLibrariesSize = 0, mutatedSharedObjectsNumb;
210
211         dl_debug_statePltEntry = saveWorldSaveSharedLibs(mutatedSharedObjectsSize, 
212                 dyninst_SharedLibrariesSize,directoryName, mutatedSharedObjectsNumb);
213
214         if(mutatedSharedObjectsSize){
215
216                 //UPDATED: 24 jul 2003 to include flag.
217                 //the flag denotes whether the shared lib is Dirty (1) or only DirtyCalled (0)
218                 // This is going to be a section that looks like this:
219                 // string
220                 // addr
221                 // flag
222                 // ...
223                 // string
224                 // addr
225                 // flag
226                 
227                 mutatedSharedObjectsSize += mutatedSharedObjectsNumb * sizeof(unsigned int);
228                 mutatedSharedObjects = new char[mutatedSharedObjectsSize ];
229                 for(unsigned i=0;shared_objects && i<shared_objects->size() ; i++) {
230                         sh_obj = (*shared_objects)[i];
231                         //i ignore the dyninst RT lib here and in process::saveWorldSaveSharedLibs
232                         if(sh_obj->isDirty() || sh_obj->isDirtyCalled()&& NULL==strstr(sh_obj->getName().c_str(),"libdyninstAPI_RT")){ //ccw 24 jul 2003
233                                 memcpy(  & ( mutatedSharedObjects[mutatedSharedObjectsIndex]),
234                                         sh_obj->getName().c_str(),
235                                         strlen(sh_obj->getName().c_str())+1);
236                                 mutatedSharedObjectsIndex += strlen(
237                                         sh_obj->getName().c_str())+1;
238                                 unsigned int baseAddr = sh_obj->getBaseAddress();
239                                 memcpy( & (mutatedSharedObjects[mutatedSharedObjectsIndex]),
240                                         &baseAddr, sizeof(unsigned int));
241                                 mutatedSharedObjectsIndex += sizeof(unsigned int);      
242
243                                 //set flag
244                                 unsigned int tmpFlag = ((sh_obj->isDirty()
245                                                         &&  NULL==strstr(sh_obj->getName().c_str(),"libc")) ?1:0);      
246                                 memcpy( &(mutatedSharedObjects[mutatedSharedObjectsIndex]), &tmpFlag, sizeof(unsigned int));
247                                 mutatedSharedObjectsIndex += sizeof(unsigned int);      
248
249                         }
250                 }       
251         }
252         char *dyninst_SharedLibrariesData =saveWorldCreateSharedLibrariesSection(dyninst_SharedLibrariesSize);
253
254         newElf = new writeBackElf(( char*) getImage()->file().c_str(),
255                 "/tmp/dyninstMutatee",errFlag);
256         newElf->registerProcess(this);
257
258         imageUpdates.sort(imageUpdateSort);// imageUpdate::mysort ); 
259
260         newElf->compactLoadableSections(imageUpdates,compactedUpdates);
261
262         highmemUpdates.sort(imageUpdateSort);
263
264         newElf->compactSections(highmemUpdates, compactedHighmemUpdates);
265
266         newElf->alignHighMem(compactedHighmemUpdates);
267
268         int sectionsAdded = 0;
269         unsigned int newSize, nextPage, paddedDiff;
270         unsigned int pageSize = getpagesize();
271
272
273         //This adds the LOADABLE HEAP TRAMP sections
274         //if new platforms require this it will be moved
275         //to process.C proper. Right now, only solaris uses it
276         for(unsigned int i=0;i<compactedUpdates.size();i++) {
277                 data = new char[compactedUpdates[i]->size];
278                 readDataSpace((void*) compactedUpdates[i]->address, 
279                                                   compactedUpdates[i]->size, data, true);
280
281                 //the TrampGuardFlag must be set to 1 to get the
282                 //tramps to run. it is not necessary set to 1 yet so
283                 //we set it to 1 before we save the file.
284                 if(guardFlagAddr){
285                         if(compactedUpdates[i]->address < guardFlagAddr &&
286                         guardFlagAddr < compactedUpdates[i]->address+compactedUpdates[i]->size){
287                                 ((char*) data)[guardFlagAddr -
288                                         compactedUpdates[i]->address ] = 0x1;
289                         }
290                 }
291
292                 sprintf(name,"dyninstAPI_%08x",sectionsAdded);
293
294                 // what i want to do is this: 
295                 // I want MMAP rather than MEMCPY as much into place 
296                 // as i can. 
297                 // My assumptions:
298                 // there can be any number of heap trampoline sections
299                 // Only the first section could have valid (non heap tramp) data on the
300                 // beginning of its first page. Any subsequent sections will begin on
301                 // a different page than the previous page ends on [by the way 
302                 // compactLoadableSections works] and the heap has been moved
303                 // beyond the last heap tramp section so the mutatee cannot
304                 // put data there.
305                 // 
306                 // for the first section, i=0, make
307                 // two sections, where the first one is everything up to the first
308                 // page break, which will be memcpy'ed to memory
309                 // the second and subsequent sections will be aligned to be
310                 // mmaped ..... which means some sections will get bigger.
311                 
312                 if( i == 0 ){
313                         /* create memcpy section */
314                         nextPage = compactedUpdates[i]->address - (compactedUpdates[i]->address%pageSize);
315                         nextPage +=pageSize;
316                         newSize = nextPage - compactedUpdates[i]->address;      
317                         newElf->addSection(compactedUpdates[i]->address,data ,newSize,name);
318                         sectionsAdded ++;
319
320                         if(compactedUpdates[i]->size > newSize){
321                                 /* only create this section if the size of the update
322                                         spans beyond the first memcpy section*/ 
323                                 /* create mmap section */
324                                 sprintf(name,"dyninstAPI_%08x",sectionsAdded);
325                                 newElf->addSection(nextPage, &(((char*) data)[newSize]) ,
326                                         compactedUpdates[i]->size- newSize,name);
327                                 sectionsAdded ++;
328                         }
329                 }else{
330                         /* create section padded out backwards to a page boundry */
331                         paddedDiff = (compactedUpdates[i]->address%pageSize);
332                         paddedData = new char[paddedDiff + compactedUpdates[i]->size];
333                         memset(paddedData, '\0', paddedDiff + compactedUpdates[i]->size); //necessary?
334                         memcpy(&( ((char*) paddedData)[paddedDiff]), data, compactedUpdates[i]->size);
335
336                         newElf->addSection(compactedUpdates[i]->address-paddedDiff, paddedData,
337                                 paddedDiff + compactedUpdates[i]->size, name);
338                         delete [] (char*) paddedData;
339                                 
340                 }
341                 delete [] (char*) data;
342         }
343
344         saveWorldCreateHighMemSections(compactedHighmemUpdates, highmemUpdates, (void*) newElf);
345
346         if(mutatedSharedObjectsSize){
347                 newElf->addSection(0, mutatedSharedObjects, mutatedSharedObjectsSize,
348                                                                  "dyninstAPI_mutatedSO", false);
349         }
350
351         unsigned int k;
352         
353         for( k=0;k<imageUpdates.size();k++){
354                 delete imageUpdates[k];
355         }
356
357         for( k=0;k<highmemUpdates.size();k++){
358                 delete highmemUpdates[k];
359         }
360         for(  k=0;k<compactedUpdates.size();k++){
361                 delete compactedUpdates[k];
362         }
363
364         for(  k=0;k<compactedHighmemUpdates.size();k++){
365                 delete compactedHighmemUpdates[k];
366         }
367
368         //the following is for the dlopen problem 
369         newElf->addSection(dl_debug_statePltEntry, dyninst_SharedLibrariesData, 
370         dyninst_SharedLibrariesSize, "dyninstAPI_SharedLibraries", false);
371
372         delete [] dyninst_SharedLibrariesData;
373
374         //the following reloads any shared libraries loaded into the
375         //mutatee using BPatch_thread::loadLibrary
376         saveWorldAddSharedLibs((void*)newElf); // ccw 14 may 2002 
377
378         saveWorldCreateDataSections((void*)newElf);
379         
380         newElf->createElf();
381         char* fullName = new char[strlen(directoryName) + strlen ( (char*)imageFileName.c_str())+1];
382         strcpy(fullName, directoryName);
383         strcat(fullName, (char*)imageFileName.c_str());
384         
385         addLibraryElf = new addLibrary();
386         elf_update(newElf->getElf(), ELF_C_WRITE);
387         if(!addLibraryElf->driver(newElf->getElf(), fullName, "libdyninstAPI_RT.so.1")) {
388                 //ccw 27 jun 2003
389                 BPatch_reportError(BPatchSerious,122,"dumpPatchedImage: addLibraryElf() failed!  No mutated binary saved\n");
390                 delete [] directoryName;
391                 return NULL;
392
393         }
394         delete [] fullName;
395         if(mutatedSharedObjects){
396                 delete [] mutatedSharedObjects;
397         }
398         return directoryName;
399 }
400
401 bool process::dumpImage(pdstring imageFileName) 
402 {
403    int newFd;
404    image *im;
405    pdstring command;
406    
407    im = getImage();
408    pdstring origFile = im->file();
409    
410    // first copy the entire image file
411    command = "cp ";
412    command += origFile;
413    command += " ";
414    command += imageFileName;
415    system(command.c_str());
416    
417    // now open the copy
418    newFd = open(imageFileName.c_str(), O_RDWR, 0);
419    if (newFd < 0) {
420       // log error
421       return false;
422    }
423
424    Elf *elfp = elf_begin(newFd, ELF_C_READ, 0);
425    Elf_Scn *scn = 0;
426    Address baseAddr = 0;
427    int length = 0;
428    int offset = 0;
429    
430    Elf32_Ehdr*  ehdrp;
431    Elf_Scn* shstrscnp  = 0;
432    Elf_Data* shstrdatap = 0;
433    Elf32_Shdr* shdrp;
434    
435    assert(ehdrp = elf32_getehdr(elfp));
436    assert(((shstrscnp = elf_getscn(elfp, ehdrp->e_shstrndx)) != 0) &&
437           ((shstrdatap = elf_getdata(shstrscnp, 0)) != 0));
438    const char* shnames = (const char *) shstrdatap->d_buf;
439    
440    while ((scn = elf_nextscn(elfp, scn)) != 0) {
441       const char* name;
442       
443       shdrp = elf32_getshdr(scn);
444       name = (const char *) &shnames[shdrp->sh_name];
445       if (!strcmp(name, ".text")) {
446          offset = shdrp->sh_offset;
447          length = shdrp->sh_size;
448          baseAddr = shdrp->sh_addr;
449          break;
450       }
451    }
452    
453
454    char *tempCode = new char[length];
455    
456    
457    bool ret = readTextSpace((void *) baseAddr, length, tempCode);
458    if (!ret) {
459       // log error
460       return false;
461    }
462    
463    lseek(newFd, offset, SEEK_SET);
464    write(newFd, tempCode, length);
465    delete[] tempCode;
466    close(newFd);
467
468    return true;
469 }
470
471 /* Auxiliary function */
472 bool checkAllThreadsForBreakpoint(process *proc, Address break_addr)
473 {
474    pdvector<Frame> activeFrames;
475    if (!proc->getAllActiveFrames(activeFrames)) return false;
476    for(unsigned frame_iter = 0; frame_iter < activeFrames.size(); frame_iter++)
477    {
478       if (activeFrames[frame_iter].getPC() == break_addr) {
479          return true;
480       }
481    }
482    
483    return false;
484 }
485
486 bool process::trapAtEntryPointOfMain(Address)
487 {
488     if (main_brk_addr == 0x0) return false;
489     return checkAllThreadsForBreakpoint(this, main_brk_addr);
490 }
491
492 bool process::handleTrapAtEntryPointOfMain()
493 {
494     assert(main_brk_addr);
495     
496   // restore original instruction 
497 #if defined(sparc_sun_solaris2_4)
498     writeDataSpace((void *)main_brk_addr, 
499                    sizeof(instruction), (char *)savedCodeBuffer);
500 #else // x86
501     writeDataSpace((void *)main_brk_addr, 2, 
502                    (char *)savedCodeBuffer);
503 #endif
504     main_brk_addr = 0;
505     return true;
506 }
507
508 bool process::insertTrapAtEntryPointOfMain()
509 {
510
511     int_function *f_main = findOnlyOneFunction("main");
512     if (!f_main) {
513         // we can't instrument main - naim
514         showErrorCallback(108,"main() uninstrumentable");
515         return false;
516     }
517     assert(f_main);
518     Address addr = f_main->get_address(); 
519     // save original instruction first
520 #if defined(sparc_sun_solaris2_4)
521     readDataSpace((void *)addr, sizeof(instruction), savedCodeBuffer, true);
522 #else // x86
523     readDataSpace((void *)addr, 2, savedCodeBuffer, true);
524 #endif
525     
526     // and now, insert trap
527     instruction insnTrap;
528     generateBreakPoint(insnTrap);
529     
530 #if defined(sparc_sun_solaris2_4)
531     writeDataSpace((void *)addr, sizeof(instruction), (char *)&insnTrap);  
532 #else //x86. have to use SIGILL instead of SIGTRAP
533     writeDataSpace((void *)addr, 2, insnTrap.ptr());  
534 #endif
535     main_brk_addr = addr;
536     
537     char buffer[256];
538     readDataSpace((void *)addr, sizeof(instruction), buffer, true);
539     return true;
540 }
541
542 bool process::getDyninstRTLibName() {
543    if (dyninstRT_name.length() == 0) {
544       // Get env variable
545       if (getenv("DYNINSTAPI_RT_LIB") != NULL) {
546          dyninstRT_name = getenv("DYNINSTAPI_RT_LIB");
547       }
548       else {
549          pdstring msg = pdstring("Environment variable ") +
550                         pdstring("DYNINSTAPI_RT_LIB") +
551                         pdstring(" has not been defined for process ") +
552                         pdstring(pid);
553          showErrorCallback(101, msg);
554          return false;
555       }
556    }
557    // Check to see if the library given exists.
558    if (access(dyninstRT_name.c_str(), R_OK)) {
559       pdstring msg = pdstring("Runtime library ") + dyninstRT_name +
560                      pdstring(" does not exist or cannot be accessed!");
561       showErrorCallback(101, msg);
562       return false;
563    }
564    return true;
565 }
566
567 bool process::loadDYNINSTlib() {
568   // we will write the following into a buffer and copy it into the
569   // application process's address space
570   // [....LIBRARY's NAME...|code for DLOPEN]
571
572   // write to the application at codeOffset. This won't work if we
573   // attach to a running process.
574   //Address codeBase = this->getImage()->codeOffset();
575   // ...let's try "_start" instead
576   int_function *_startfn = this->findOnlyOneFunction("_start");
577   if (NULL == _startfn) {
578     pdvector<int_function *> funcs;
579     if (!this->findAllFuncsByName("_start", funcs) || !funcs.size()) {
580        fprintf(stderr, "%s[%d]:  could not find _start()\n", __FILE__, __LINE__);
581        return false;
582     }
583     fprintf(stderr, "%s[%d]:  WARN:  found %d matches for _start()\n", 
584             __FILE__, __LINE__, funcs.size()); 
585     int select_fn = 0;
586     for (unsigned int i = 0; i < funcs.size(); ++i) {
587       const char *modname = funcs[i]->pdmod()->fileName().c_str();
588       fprintf(stderr, "\t[%d]\tin module %s\n",i, modname);
589       if (strstr(modname, "libc.") || strstr(modname, "libdl."))
590          select_fn = i;        
591     }
592     fprintf(stderr, "%s[%d]: selecting %d\n", __FILE__, __LINE__, select_fn);
593     _startfn = funcs[select_fn];
594   }
595
596   Address codeBase = _startfn->getEffectiveAddress(this);
597   assert(codeBase);
598
599   // Or should this be readText... it seems like they are identical
600   // the remaining stuff is thanks to Marcelo's ideas - this is what 
601   // he does in NT. The major change here is that we use AST's to 
602   // generate code for dlopen.
603
604   // savedCodeBuffer[BYTES_TO_SAVE] is declared in process.h
605   readDataSpace((void *)codeBase, sizeof(savedCodeBuffer), savedCodeBuffer, true);
606
607   unsigned char scratchCodeBuffer[BYTES_TO_SAVE];
608   pdvector<AstNode*> dlopenAstArgs(2);
609
610   Address count = 0;
611
612 //ccw 18 apr 2002 : SPLIT
613   AstNode *dlopenAst;
614
615   // deadList and deadListSize are also used in inst-sparc.C
616   // registers 8 to 15: out registers 
617   // registers 16 to 22: local registers
618   Register deadList[10] = { 16, 17, 18, 19, 20, 21, 22, 0, 0, 0 };
619   unsigned dead_reg_count = 7;
620   if(! multithread_capable()) {
621      deadList[7] = 23;
622      dead_reg_count++;
623   }
624
625   registerSpace *dlopenRegSpace =
626      new registerSpace(dead_reg_count, deadList, (unsigned)0,
627                        NULL, multithread_capable());
628   dlopenRegSpace->resetSpace();
629
630   // we need to make 2 calls to dlopen: one to load libsocket.so.1 and another
631   // one to load libdyninst.so.1 - naim
632
633 //ccw 18 apr 2002 : SPLIT
634   dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void*)0);
635   // library name. We use a scratch value first. We will update this parameter
636   // later, once we determine the offset to find the string - naim
637   dlopenAstArgs[1] = new AstNode(AstNode::Constant, (void*)DLOPEN_MODE); // mode
638   dlopenAst = new AstNode("dlopen",dlopenAstArgs);
639   removeAst(dlopenAstArgs[0]);
640   removeAst(dlopenAstArgs[1]);
641
642   Address dyninst_count = 0;
643   dlopenAst->generateCode(this, dlopenRegSpace, (char *)scratchCodeBuffer,
644                           dyninst_count, true, true);
645   writeDataSpace((void *)(codeBase+count), dyninst_count, (char *)scratchCodeBuffer);
646 // the following seems to be a redundant relic
647 //#if defined(sparc_sun_solaris2_4)
648 //  dyninst_count += sizeof(instruction);
649 //#endif
650   count += dyninst_count;
651
652   instruction insnTrap;
653   generateBreakPoint(insnTrap);
654 #if defined(sparc_sun_solaris2_4)
655   writeDataSpace((void *)(codeBase + count), sizeof(instruction), 
656                  (char *)&insnTrap);
657   dyninstlib_brk_addr = codeBase + count;
658   count += sizeof(instruction);
659 #else //x86
660   writeDataSpace((void *)(codeBase + count), 2, insnTrap.ptr());
661   dyninstlib_brk_addr = codeBase + count;
662   count += 2;
663 #endif
664
665 //ccw 18 apr 2002 : SPLIT
666   const char DyninstEnvVar[]="DYNINSTAPI_RT_LIB";
667
668   if (dyninstRT_name.length()) {
669     // use the library name specified on the start-up command-line
670   } else {
671     // check the environment variable
672     if (getenv(DyninstEnvVar) != NULL) {
673       dyninstRT_name = getenv(DyninstEnvVar);
674     } else {
675       pdstring msg = pdstring("Environment variable " + pdstring(DyninstEnvVar)
676                    + " has not been defined for process ") + pdstring(pid);
677       showErrorCallback(101, msg);
678       return false;
679     }
680   }
681   if (access(dyninstRT_name.c_str(), R_OK)) {
682     pdstring msg = pdstring("Runtime library ") + dyninstRT_name +
683                    pdstring(" does not exist or cannot be accessed!");
684     showErrorCallback(101, msg);
685     return false;
686   }
687
688   Address dyninstlib_addr = codeBase + count;
689
690   writeDataSpace((void *)(codeBase + count), dyninstRT_name.length()+1,
691                  (caddr_t)const_cast<char*>(dyninstRT_name.c_str()));
692   count += dyninstRT_name.length()+1;
693   // we have now written the name of the library after the trap - naim
694
695 //ccw 18 apr 2002 : SPLIT
696   assert(count<=BYTES_TO_SAVE);
697   // The dyninst API doesn't load the socket library
698
699 //ccw 18 apr 2002 : SPLIT
700   count = 0; // reset count
701
702   // at this time, we know the offset for the library name, so we fix the
703   // call to dlopen and we just write the code again! This is probably not
704   // very elegant, but it is easy and it works - naim
705   removeAst(dlopenAst); // to avoid leaking memory
706   dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void *)(dyninstlib_addr));
707   dlopenAstArgs[1] = new AstNode(AstNode::Constant, (void*)DLOPEN_MODE);
708   dlopenAst = new AstNode("dlopen",dlopenAstArgs);
709   removeAst(dlopenAstArgs[0]);
710   removeAst(dlopenAstArgs[1]);
711   dyninst_count = 0; // reset count
712   dlopenAst->generateCode(this, dlopenRegSpace, (char *)scratchCodeBuffer,
713                           dyninst_count, true, true);
714   writeDataSpace((void *)(codeBase+count), dyninst_count,
715                  (char *)scratchCodeBuffer);
716   removeAst(dlopenAst);
717   count += dyninst_count;
718
719   // save registers
720   savedRegs = new dyn_saved_regs;
721   bool status = getRepresentativeLWP()->getRegisters(savedRegs);
722   assert(status == true);
723
724 #if defined(i386_unknown_solaris2_5)
725   /* Setup a new stack frame large enough for arguments to functions
726      called during bootstrap, as generated by the FuncCall AST.  */
727   prgregset_t regs;
728   regs = *(prgregset_t*)&savedRegs;
729   Address theESP = regs[SP_REG];
730   if (!changeIntReg(FP_REG, theESP)) {
731     logLine("WARNING: changeIntReg failed in loadDYNINSTlib\n");
732     assert(0);
733   }
734   if (!changeIntReg(SP_REG, theESP-32)) {
735     logLine("WARNING: changeIntReg failed in loadDYNINSTlib\n");
736     assert(0);
737   }
738 #endif
739   if (!getRepresentativeLWP()->changePC(codeBase, NULL)) {
740     logLine("WARNING: changePC failed in loadDYNINSTlib\n");
741     assert(0);
742   }
743   setBootstrapState(loadingRT);
744   return true;
745 }
746
747 bool process::trapDueToDyninstLib()
748 {
749   if (dyninstlib_brk_addr == 0) return(false);
750   return checkAllThreadsForBreakpoint(this, dyninstlib_brk_addr);
751 }
752
753 bool process::loadDYNINSTlibCleanup()
754 {
755   // rewrite original instructions in the text segment we use for 
756   // the inferiorRPC - naim
757   unsigned count = sizeof(savedCodeBuffer);
758   //Address codeBase = getImage()->codeOffset();
759
760   int_function *_startfn = this->findOnlyOneFunction("_start");
761   if (NULL == _startfn) {
762     pdvector<int_function *> funcs;
763     if (!this->findAllFuncsByName("_start", funcs) || !funcs.size()) {
764        fprintf(stderr, "%s[%d]:  could not find _start()\n", __FILE__, __LINE__);
765        return false;
766     }
767     fprintf(stderr, "%s[%d]:  WARN:  found %d matches for _start()\n",
768             __FILE__, __LINE__, funcs.size());
769     int select_fn = 0;
770     for (unsigned int i = 0; i < funcs.size(); ++i) {
771       const char *modname = funcs[i]->pdmod()->fileName().c_str();
772       fprintf(stderr, "\t[%d]\tin module %s\n",i, modname);
773       if (strstr(modname, "libc.") || strstr(modname, "libdl."))
774          select_fn = i;
775     }
776     fprintf(stderr, "%s[%d]: selecting %d\n", __FILE__, __LINE__, select_fn);
777     _startfn = funcs[select_fn];
778   }
779
780   Address codeBase = _startfn->getEffectiveAddress(this);
781   assert(codeBase);
782   if (!writeDataSpace((void *)codeBase, count, (char *)savedCodeBuffer))
783      return false;
784
785   // restore registers
786   if (!getRepresentativeLWP()->restoreRegisters(*savedRegs))
787      return false;
788   delete savedRegs;
789   savedRegs = NULL;
790   return true;
791 }
792
793 fileDescriptor *getExecFileDescriptor(pdstring filename, int &, bool)
794 {
795     fileDescriptor *desc = new fileDescriptor(filename);
796     return desc;
797 }
798
799 #if defined(USES_DYNAMIC_INF_HEAP)
800 static const Address lowest_addr = 0x0;
801 void process::inferiorMallocConstraints(Address near, Address &lo, Address &hi,
802                                         inferiorHeapType /* type */)
803 {
804   if (near)
805     {
806       lo = region_lo(near);
807       hi = region_hi(near);  
808     }
809 }
810
811 void process::inferiorMallocAlign(unsigned &size)
812 {
813      /* 32 byte alignment.  Should it be 64? */
814   size = (size + 0x1f) & ~0x1f;
815 }
816 #endif
817
818 bool process::dumpCore_(const pdstring coreName) 
819 {
820   char command[100];
821
822   sprintf(command, "gcore %d 2> /dev/null; mv core.%d %s", getPid(), getPid(), 
823           coreName.c_str());
824
825   detach(false);
826   system(command);
827   attach();
828
829   return false;
830 }
831
832 int getNumberOfCPUs()
833 {
834   // _SC_NPROCESSORS_CONF is the number of processors configured in the
835   // system and _SC_NPROCESSORS_ONLN is the number of those processors that
836   // are online.
837   int numberOfCPUs;
838   numberOfCPUs = (int) sysconf(_SC_NPROCESSORS_ONLN);
839   if (numberOfCPUs) 
840     return(numberOfCPUs);
841   else 
842     return(1);
843 }  
844
845 Frame Frame::getCallerFrame()
846 {
847    Frame ret;
848    ret.lwp_ = lwp_;
849    ret.thread_ = thread_;
850    ret.proc_ = proc_;
851    ret.pid_ = pid_;
852    ret.thread_ = thread_;
853    ret.lwp_ = lwp_;
854    if (uppermost_) {
855      codeRange *range = getRange();
856        int_function *func = range->is_function();
857        if (func) {
858            if (func->hasNoStackFrame()) { // formerly "isLeafFunc()"
859                if (lwp_) { // We have a LWP and are prepared to use it
860                    struct dyn_saved_regs regs;
861                    bool status = lwp_->getRegisters(&regs);
862                    assert(status == true);
863                    ret.pc_ = regs.theIntRegs[R_O7] + 8;
864                    ret.fp_ = fp_; // frame pointer unchanged
865                    ret.frameType_ = FRAME_normal;
866                    return ret;
867                    
868                }
869                else if (thread_)
870                    cerr << "Not implemented yet" << endl;
871                else {
872                    struct dyn_saved_regs regs;
873                    bool status = getProc()->getRepresentativeLWP()->getRegisters(&regs);
874                    assert(status == true);
875                    ret.pc_ = regs.theIntRegs[R_O7] + 8;
876                    ret.fp_ = fp_;
877                    ret.frameType_ = FRAME_normal;
878                    return ret;
879                }
880            }
881        }
882    }
883    //
884    // For the sparc, register %i7 is the return address - 8 and the fp is
885    // register %i6. These registers can be located in %fp+14*5 and
886    // %fp+14*4 respectively, but to avoid two calls to readDataSpace,
887    // we bring both together (i.e. 8 bytes of memory starting at %fp+14*4
888    // or %fp+56).
889    // These values are copied to the stack when the application is paused,
890    // so we are assuming that the application is paused at this point
891    
892    struct {
893       Address fp;
894       Address rtn;
895    } addrs;
896    
897    if (getProc()->readDataSpace((caddr_t)(fp_ + 56), 2*sizeof(int),
898                         (caddr_t)&addrs, true))
899    {
900       ret.fp_ = addrs.fp;
901       ret.pc_ = addrs.rtn + 8;
902       
903       // Check if we're in a sig handler, since we don't know if the
904       // _current_ frame has its type set at all.
905       if (getProc()->isInSignalHandler(pc_)) {
906          // get the value of the saved PC: this value is stored in the
907          // address specified by the value in register i2 + 44. Register i2
908          // must contain the address of some struct that contains, among
909          // other things, the saved PC value.
910          u_int reg_i2;
911          if (getProc()->readDataSpace((caddr_t)(fp_+40), sizeof(u_int),
912                               (caddr_t)&reg_i2,true)) {
913             Address saved_pc;
914             if (getProc()->readDataSpace((caddr_t) (reg_i2+44), sizeof(int),
915                                  (caddr_t) &saved_pc,true)) {
916                
917                int_function *func = getProc()->findFuncByAddr(saved_pc);
918                
919                ret.pc_ = saved_pc;
920                if (func && func->hasNoStackFrame())
921                   ret.fp_ = fp_;
922                return ret;
923             }
924          }
925          return Frame();
926       }
927       
928       // If we're in a base tramp, skip this frame (return getCallerFrame)
929       // as we only return minitramps
930       codeRange *range = getRange();
931       if (range->is_basetramp())
932           return ret.getCallerFrame();
933
934       if(getProc()->multithread_capable()) {
935          // MT thread adds another copy of the start function
936          // to the top of the stack... this breaks instrumentation
937          // since we think we're at a function entry.
938          if (ret.fp_ == 0) ret.pc_ = 0;
939       }
940
941       // Check if the _current_ PC is in a signal handler, and if so set the type
942       if (getProc()->isInSignalHandler(ret.pc_)) {
943           ret.frameType_ = FRAME_signalhandler;
944       }
945
946       return ret;
947    }
948   
949    return Frame(); // zero frame
950 }
951
952 bool Frame::setPC(Address newpc) {
953   fprintf(stderr, "Implement me! Changing frame PC from %x to %x\n",
954           pc_, newpc);
955   return true;
956 }
957
958
959 #if !defined(BPATCH_LIBRARY)
960 rawTime64 dyn_lwp::getRawCpuTime_hw()
961 {
962   return 0;
963 }
964
965 /* return unit: nsecs */
966 rawTime64 dyn_lwp::getRawCpuTime_sw() 
967 {
968   // returns user time from the u or proc area of the inferior process,
969   // which in turn is presumably obtained by using a /proc ioctl to obtain
970   // it (solaris).  It must not stop the inferior process in order to obtain
971   // the result, nor can it assure that the inferior has been stopped.  The
972   // result MUST be "in sync" with rtinst's DYNINSTgetCPUtime().
973   
974   rawTime64 result;
975   prusage_t theUsage;
976
977 #ifdef PURE_BUILD
978   // explicitly initialize "theUsage" struct (to pacify Purify)
979   memset(&theUsage, '\0', sizeof(prusage_t));
980 #endif
981
982   // compute the CPU timer for the whole process
983   if(is_attached()) {
984      if(pread(usage_fd(), &theUsage, sizeof(prusage_t), 0) 
985         != sizeof(prusage_t))
986      {
987         perror("getInfCPU: read");
988         return -1;  // perhaps the process ended
989      }
990   }
991   else return -1; // perhaps the process ended
992
993   result =  (theUsage.pr_utime.tv_sec + theUsage.pr_stime.tv_sec) * 1000000000LL;
994   result += (theUsage.pr_utime.tv_nsec+ theUsage.pr_stime.tv_nsec);
995
996   if (result < sw_previous_) // Time ran backwards?
997   {
998       // When the process exits we often get a final time call.
999       // If the result is 0(.0), don't print an error.
1000       if (result) {
1001           char errLine[150];
1002           sprintf(errLine,"process::getRawCpuTime_sw - time going backwards in "
1003                   "daemon - cur: %lld, prev: %lld\n", result, sw_previous_);
1004           cerr << errLine;
1005           logLine(errLine);
1006       }
1007       result = sw_previous_;
1008   }
1009   else sw_previous_=result;
1010   
1011   return result;
1012 }
1013 #endif // BPATCH_LIBRARY
1014
1015
1016 bool process::instrSideEffect(Frame &frame, instPoint *inst)
1017 {
1018   int_function *instFunc = inst->pointFunc();
1019   if (!instFunc) return false;
1020
1021   codeRange *range = frame.getRange();
1022   if (range->is_function() != instFunc) {
1023     return true;
1024   }
1025
1026   if (inst->getPointType() == callSite) {
1027     Address insnAfterPoint = inst->absPointAddr(this) + 2*sizeof(instruction);
1028
1029     if (frame.getPC() == insnAfterPoint) {
1030       frame.setPC(baseMap[inst]->baseAddr + baseMap[inst]->skipPostInsOffset);
1031     }
1032   }
1033
1034   return true;
1035 }
1036
1037 #if 0
1038 // needToAddALeafFrame: returns true if the between the current frame 
1039 // and the next frame there is a leaf function (this occurs when the 
1040 // current frame is the signal handler and the function that was executing
1041 // when the sighandler was called is a leaf function)
1042 bool process::needToAddALeafFrame(Frame current_frame, Address &leaf_pc){
1043
1044    // check to see if the current frame is the signal handler 
1045    Address frame_pc = current_frame.getPC();
1046    Address sig_addr = 0;
1047    const image *sig_image = (signal_handler->file())->exec();
1048    if(getBaseAddress(sig_image, sig_addr)){
1049        sig_addr += signal_handler->getAddress(0);
1050    } else {
1051        sig_addr = signal_handler->getAddress(0);
1052    }
1053    u_int sig_size = signal_handler->size();
1054    if(signal_handler&&(frame_pc >= sig_addr)&&(frame_pc < (sig_addr+sig_size))){
1055        // get the value of the saved PC: this value is stored in the address
1056        // specified by the value in register i2 + 44. Register i2 must contain
1057        // the address of some struct that contains, among other things, the 
1058        // saved PC value.  
1059        u_int reg_i2;
1060        int fp = current_frame.getFP();
1061        if (readDataSpace((caddr_t)(fp+40),sizeof(u_int),(caddr_t)&reg_i2,true)){
1062           if (readDataSpace((caddr_t) (reg_i2+44), sizeof(int),
1063                             (caddr_t) &leaf_pc,true)){
1064               // if the function is a leaf function return true
1065               int_function *func = findFuncByAddr(leaf_pc);
1066               if(func && func->hasNoStackFrame()) { // formerly "isLeafFunc()"
1067                   return(true);
1068               }
1069           }
1070       }
1071    }
1072    return false;
1073 }
1074 #endif
1075
1076 void print_read_error_info(const relocationEntry entry, 
1077                            int_function *&target_pdf, Address base_addr) {
1078
1079    sprintf(errorLine, "  entry      : target_addr 0x%lx\n",
1080            entry.target_addr());
1081    logLine(errorLine);
1082    sprintf(errorLine, "               rel_addr 0x%lx\n", entry.rel_addr());
1083    logLine(errorLine);
1084    sprintf(errorLine, "               name %s\n", (entry.name()).c_str());
1085    logLine(errorLine);
1086    
1087    if (target_pdf) {
1088       sprintf(errorLine, "  target_pdf : symTabName %s\n",
1089               (target_pdf->symTabName()).c_str());
1090       logLine(errorLine);    
1091       sprintf(errorLine , "              prettyName %s\n",
1092               (target_pdf->symTabName()).c_str());
1093       logLine(errorLine);
1094       sprintf(errorLine , "              size %i\n",
1095               target_pdf->get_size());
1096       logLine(errorLine);
1097       sprintf(errorLine , "              addr 0x%lx\n",
1098               target_pdf->get_address());
1099       logLine(errorLine);
1100    }
1101
1102    sprintf(errorLine, "  base_addr  0x%lx\n", base_addr);
1103    logLine(errorLine);
1104 }
1105
1106 // hasBeenBound: returns true if the runtime linker has bound the
1107 // function symbol corresponding to the relocation entry in at the address
1108 // specified by entry and base_addr.  If it has been bound, then the callee 
1109 // function is returned in "target_pdf", else it returns false.
1110 bool process::hasBeenBound(const relocationEntry entry, 
1111                            int_function *&target_pdf, Address base_addr) {
1112
1113 // TODO: the x86 and sparc versions should really go in seperate files 
1114 #if defined(i386_unknown_solaris2_5)
1115
1116     if (status() == exited) return false;
1117
1118     // if the relocationEntry has not been bound yet, then the value
1119     // at rel_addr is the address of the instruction immediately following
1120     // the first instruction in the PLT entry (which is at the target_addr) 
1121     // The PLT entries are never modified, instead they use an indirrect 
1122     // jump to an address stored in the _GLOBAL_OFFSET_TABLE_.  When the 
1123     // function symbol is bound by the runtime linker, it changes the address
1124     // in the _GLOBAL_OFFSET_TABLE_ corresponding to the PLT entry
1125
1126     Address got_entry = entry.rel_addr() + base_addr;
1127     Address bound_addr = 0;
1128     if(!readDataSpace((const void*)got_entry, sizeof(Address), 
1129                         &bound_addr, true)){
1130         sprintf(errorLine, "read error in process::hasBeenBound "
1131                 "addr 0x%lx, pid=%d\n (readDataSpace returns 0)",
1132                 got_entry, pid);
1133         logLine(errorLine);
1134         print_read_error_info(entry, target_pdf, base_addr);
1135         return false;
1136     }
1137
1138     if( !( bound_addr == (entry.target_addr()+6+base_addr)) ) {
1139         // the callee function has been bound by the runtime linker
1140         // find the function and return it
1141         target_pdf = findFuncByAddr(bound_addr);
1142         if(!target_pdf){
1143             return false;
1144         }
1145         return true;    
1146     }
1147     return false;
1148
1149 #else
1150     // if the relocationEntry has not been bound yet, then the second instr 
1151     // in this PLT entry branches to the fist PLT entry.  If it has been   
1152     // bound, then second two instructions of the PLT entry have been changed 
1153     // by the runtime linker to jump to the address of the function.  
1154     // Here is an example:   
1155     //     before binding                       after binding
1156     //     --------------                       -------------
1157     //     sethi  %hi(0x15000), %g1             sethi  %hi(0x15000), %g1
1158     //     b,a  <_PROCEDURE_LINKAGE_TABLE_>     sethi  %hi(0xef5eb000), %g1
1159     //     nop                                  jmp  %g1 + 0xbc ! 0xef5eb0bc
1160
1161     instruction next_insn;
1162     Address next_insn_addr = entry.target_addr() + base_addr + 4; 
1163     if( !(readDataSpace((caddr_t)next_insn_addr, sizeof(next_insn), 
1164                        (char *)&next_insn, true)) ) {
1165         sprintf(errorLine, "read error in process::hasBeenBound addr 0x%lx"
1166                 " (readDataSpace next_insn_addr returned 0)\n",
1167                 next_insn_addr);
1168         logLine(errorLine);
1169         print_read_error_info(entry, target_pdf, base_addr);
1170     }
1171     // if this is a b,a instruction, then the function has not been bound
1172     if((next_insn.branch.op == FMT2op)  && (next_insn.branch.op2 == BICCop2) 
1173        && (next_insn.branch.anneal == 1) && (next_insn.branch.cond == BAcond)) {
1174         return false;
1175     } 
1176
1177     // if this is a sethi instruction, then it has been bound...get target_addr
1178     instruction third_insn;
1179     Address third_addr = entry.target_addr() + base_addr + 8; 
1180     if( !(readDataSpace((caddr_t)third_addr, sizeof(third_insn), 
1181                        (char *)&third_insn, true)) ) {
1182         sprintf(errorLine, "read error in process::hasBeenBound addr 0x%lx"
1183                 " (readDataSpace third_addr returned 0)\n",
1184                 third_addr);
1185         logLine(errorLine);
1186         print_read_error_info(entry,target_pdf, base_addr);
1187     }
1188
1189     // get address of bound function, and return the corr. int_function
1190     if((next_insn.sethi.op == FMT2op) && (next_insn.sethi.op2 == SETHIop2)
1191         && (third_insn.rest.op == RESTop) && (third_insn.rest.i == 1)
1192         && (third_insn.rest.op3 == JMPLop3)) {
1193         
1194         Address new_target = (next_insn.sethi.imm22 << 10) & 0xfffffc00; 
1195         new_target |= third_insn.resti.simm13;
1196
1197         target_pdf = findFuncByAddr(new_target);
1198         if(!target_pdf){
1199             return false;
1200         }
1201         return true;
1202     }
1203     // this is a messed up entry
1204     return false;
1205 #endif
1206
1207 }
1208
1209
1210
1211 // findCallee: finds the function called by the instruction corresponding
1212 // to the instPoint "instr". If the function call has been bound to an
1213 // address, then the callee function is returned in "target" and the 
1214 // instPoint "callee" data member is set to pt to callee's int_function.  
1215 // If the function has not yet been bound, then "target" is set to the 
1216 // int_function associated with the name of the target function (this is 
1217 // obtained by the PLT and relocation entries in the image), and the instPoint
1218 // callee is not set.  If the callee function cannot be found, (ex. function
1219 // pointers, or other indirect calls), it returns false.
1220 // Returns false on error (ex. process doesn't contain this instPoint).
1221 //
1222 // The assumption here is that for all processes sharing the image containing
1223 // this instPoint they are going to bind the call target to the same function. 
1224 // For shared objects this is always true, however this may not be true for
1225 // dynamic executables.  Two a.outs can be identical except for how they are
1226 // linked, so a call to fuction foo in one version of the a.out may be bound
1227 // to function foo in libfoo.so.1, and in the other version it may be bound to 
1228 // function foo in libfoo.so.2.  We are currently not handling this case, since
1229 // it is unlikely to happen in practice.
1230 bool process::findCallee(instPoint &instr, int_function *&target){
1231    if((target = instr.getCallee())) {
1232       return true; // callee already set
1233    }
1234
1235    // find the corresponding image in this process  
1236    image *owner = instr.getOwner();
1237    bool found_image = false;
1238    Address base_addr = 0;
1239    if(symbols == owner) {  found_image = true; } 
1240    else if(shared_objects){
1241       for(u_int i=0; i < shared_objects->size(); i++){
1242          if(owner == ((*shared_objects)[i])->getImage()) {
1243             found_image = true;
1244             base_addr = ((*shared_objects)[i])->getBaseAddress();
1245             break;
1246          }
1247       }
1248    } 
1249    if(!found_image) {
1250       target = 0;
1251       return false; // image not found...this is bad
1252    }
1253
1254    // get the target address of this function
1255    Address target_addr = 0;
1256    //    Address insn_addr = instr.pointAddr(); 
1257    target_addr = instr.getTargetAddress();
1258
1259    if(!target_addr) {  
1260       // this is either not a call instruction or an indirect call instr
1261       // that we can't get the target address
1262       target = 0;
1263       return false;
1264    }
1265
1266 #if defined(sparc_sun_solaris2_4)
1267    /*
1268    // I don't see how this is possible -- we relocate after we've determined static
1269    // callees -- bernat, 13OCT03
1270    // If this instPoint is from a function that was relocated to the heap
1271    // then need to get the target address relative to this image   
1272    if(target_addr && instr.relocated_) {
1273    assert(target_addr > base_addr);
1274    target_addr -= base_addr;
1275    }
1276    */
1277 #endif
1278
1279    // see if there is a function in this image at this target address
1280    // if so return it
1281    int_function *pdf = 0;
1282    if( (pdf = owner->findFuncByEntry(target_addr)) ) {
1283       target = pdf;
1284       instr.setCallee(pdf);
1285       return true; // target found...target is in this image
1286    }
1287
1288    // else, get the relocation information for this image
1289    const Object &obj = owner->getObject();
1290    const pdvector<relocationEntry> *fbt;
1291    if(!obj.get_func_binding_table_ptr(fbt)) {
1292       target = 0;
1293       return false; // target cannot be found...it is an indirect call.
1294    }
1295
1296    // find the target address in the list of relocationEntries
1297    for(u_int i=0; i < fbt->size(); i++) {
1298       if((*fbt)[i].target_addr() == target_addr) {
1299          // check to see if this function has been bound yet...if the
1300          // PLT entry for this function has been modified by the runtime
1301          // linker
1302          int_function *target_pdf = 0;
1303          if(hasBeenBound((*fbt)[i], target_pdf, base_addr)) {
1304             target = target_pdf;
1305             instr.setCallee(target_pdf);
1306             return true;  // target has been bound
1307          } 
1308          else {
1309             // just try to find a function with the same name as entry 
1310             pdvector<int_function *> pdfv;
1311             bool found = findAllFuncsByName((*fbt)[i].name(), pdfv);
1312             if(found) {
1313                assert(pdfv.size());
1314 #ifdef BPATCH_LIBRARY
1315                if(pdfv.size() > 1)
1316                   cerr << __FILE__ << ":" << __LINE__ 
1317                        << ": WARNING:  findAllFuncsByName found " 
1318                        << pdfv.size() << " references to function " 
1319                        << (*fbt)[i].name() << ".  Using the first.\n";
1320 #endif
1321                target = pdfv[0];
1322                return true;
1323             }
1324             else {  
1325                // KLUDGE: this is because we are not keeping more than
1326                // one name for the same function if there is more
1327                // than one.  This occurs when there are weak symbols
1328                // that alias global symbols (ex. libm.so.1: "sin" 
1329                // and "__sin").  In most cases the alias is the same as 
1330                // the global symbol minus one or two leading underscores,
1331                // so here we add one or two leading underscores to search
1332                // for the name to handle the case where this string 
1333                // is the name of the weak symbol...this will not fix 
1334                // every case, since if the weak symbol and global symbol
1335                // differ by more than leading underscores we won't find
1336                // it...when we parse the image we should keep multiple
1337                // names for int_functions
1338
1339                pdstring s("_");
1340                s += (*fbt)[i].name();
1341                found = findAllFuncsByName(s, pdfv);
1342                if(found) {
1343                   assert(pdfv.size());
1344 #ifdef BPATCH_LIBRARY
1345                   if(pdfv.size() > 1)
1346                      cerr << __FILE__ << ":" << __LINE__ 
1347                           << ": WARNING: findAllFuncsByName found " 
1348                           << pdfv.size() << " references to function " 
1349                           << s << ".  Using the first.\n";
1350 #endif
1351                   target = pdfv[0];
1352                   return true;
1353                }
1354                     
1355                s = pdstring("__");
1356                s += (*fbt)[i].name();
1357                found = findAllFuncsByName(s, pdfv);
1358                if(found) {
1359                   assert(pdfv.size());
1360 #ifdef BPATCH_LIBRARY
1361                   if(pdfv.size() > 1)
1362                      cerr << __FILE__ << ":" << __LINE__ 
1363                           << ": WARNING: findAllFuncsByName found " 
1364                           << pdfv.size() << " references to function "
1365                           << s << ".  Using the first.\n";
1366 #endif
1367                   target = pdfv[0];
1368                   return true;
1369                }
1370                //                   else
1371                //                       cerr << __FILE__ << ":" << __LINE__
1372                //                            << ": WARNING: findAllFuncsByName found no "
1373                //                            << "matches for function " << (*fbt)[i].name() 
1374                //                            << " or its possible aliases\n";
1375             }
1376          }
1377          target = 0;
1378          return false;
1379       }
1380    }
1381    target = 0;
1382    return false;  
1383 }
1384
1385 void loadNativeDemangler() {
1386   
1387   P_native_demangle = NULL;
1388   void *hDemangler = dlopen("libdemangle.so", DLOPEN_MODE);
1389   if (hDemangler != NULL)
1390     P_native_demangle = (int (*) (const char *, char *, size_t)) 
1391       dlsym(hDemangler, "cplus_demangle");
1392 }