BPatch functions that block are now locked (on a finer grain than the rest of the...
[dyninst.git] / dyninstAPI / src / BPatch_thread.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: BPatch_thread.C,v 1.123 2005/02/25 07:04:46 jaw Exp $
43
44 #ifdef sparc_sun_solaris2_4
45 #include <dlfcn.h>
46 #endif
47
48 #define BPATCH_FILE
49
50
51 #include "process.h"
52 #include "signalhandler.h"
53 #include "inst.h"
54 #include "instP.h"
55 #include "instPoint.h"
56 #include "function.h" // int_function
57 #include "codeRange.h"
58 #include "func-reloc.h"
59
60 #include "BPatch_asyncEventHandler.h"
61 #include "BPatch.h"
62 #include "BPatch_thread.h"
63 #include "LineInformation.h"
64
65
66
67 /*
68  * class OneTimeCodeInfo
69  *
70  * This is used by the oneTimeCode (inferiorRPC) mechanism to keep per-RPC
71  * information.
72  */
73 class OneTimeCodeInfo {
74     bool synchronous;
75     bool completed;
76     void *userData;
77     void *returnValue;
78 public:
79     OneTimeCodeInfo(bool _synchronous, void *_userData) :
80         synchronous(_synchronous), completed(false), userData(_userData) { };
81
82     bool isSynchronous() { return synchronous; }
83
84     bool isCompleted() const { return completed; }
85     void setCompleted(bool _completed) { completed = _completed; }
86
87     void *getUserData() { return userData; }
88
89     void setReturnValue(void *_returnValue) { returnValue = _returnValue; }
90     void *getReturnValue() { return returnValue; }
91 };
92
93 /*
94  * BPatch_thread::getImage
95  *
96  * Return the BPatch_image this object.
97  */
98 BPatch_image *BPatch_thread::getImageInt()
99 {
100     return image;
101 }
102
103 /*
104  * BPatch_thread::getPid
105  *
106  * Return the process ID of the thread associated with this object.
107  */
108 int BPatch_thread::getPidInt()
109 {
110     return proc->getPid();
111 }
112
113
114 /* Not sure if this is necessary... */
115
116 static void insertVForkInst(BPatch_thread *thread)
117 {
118     return;
119
120     BPatch_image *appImage = thread->getImage();
121     if (!appImage) return;
122
123 #if !defined(i386_unknown_nt4_0) \
124  && !defined(mips_unknown_ce2_11) //ccw 20 july 2000 : 28 mar 2001
125
126     BPatch_Vector<BPatch_function *>  dyninst_vforks;
127     if (NULL == appImage->findFunction("DYNINSTvfork", dyninst_vforks) || 
128         !dyninst_vforks.size()) {
129       bpfatal( "%s[%d]:  FATAL  : findFunction(`DYNINSTvfork`, ...), "
130               "no DYNINSTvfork found!\n", __FILE__, __LINE__);
131       return;
132     }
133     
134     if (dyninst_vforks.size() > 1)
135       bperr("%s[%d]:  SERIOUS  : found %d functions called 'DYNINSTvfork' "
136               "in image, might be picking the wrong one\n", __FILE__, __LINE__, 
137               dyninst_vforks.size());
138
139     BPatch_function *vforkFunc = dyninst_vforks[0];
140
141     BPatch_Vector<BPatch_function *>  vforks;
142     if (NULL == appImage->findFunction("vfork", vforks) || !vforks.size()) {
143       bpfatal( "%s[%d]:  FATAL  : findFunction(`vfork`, ...), no vfork found!\n",
144               __FILE__, __LINE__);
145       return;
146     }
147     
148     if (vforks.size() > 1)
149       // we should really go through the modules and make sure we have the right one here -- JAW
150       bperr( "%s[%d]:  SERIOUS  : found %d functions called 'vfork' in image, "
151               "might be picking the wrong one\n", __FILE__, __LINE__, vforks.size());
152     
153     BPatch_function *one_vfork = vforks[0];
154     assert(one_vfork);
155
156     BPatch_Vector<BPatch_point *> *points = one_vfork->findPoint(BPatch_exit);
157
158     if (vforkFunc && points) {
159         BPatch_Vector<BPatch_snippet *> args;
160         BPatch_constExpr pidExpr(thread->getPid());
161         args.push_back(&pidExpr);
162
163         BPatch_snippet *ret = new BPatch_funcCallExpr(*vforkFunc, args);
164         if (!ret) {
165             bperr("error creating function\n");
166             return;
167         }
168
169         thread->insertSnippet(*ret, *points);
170     }
171 #endif
172 }
173
174 /*
175  * BPatch_thread::BPatch_thread
176  *
177  * Starts a new process and associates it with the BPatch_thread being
178  * constructed.  The new process is placed into a stopped state before
179  * executing any code.
180  *
181  * path         Pathname of the executable to start.
182  * argv         A list of pointers to character strings which are the
183  *              arguments for the new process, terminated by a NULL pointer.
184  * envp         A list of pointers to character strings which are the
185  *              environment variables for the new process, terminated by a
186  *              NULL pointer.  If NULL, the default environment will be used.
187  */
188 BPatch_thread::BPatch_thread(const char *path, char *argv[], char *envp[],
189                              int stdin_fd, int stdout_fd, int stderr_fd)
190   : proc(NULL), image(NULL), lastSignal(-1), exitCode(-1),
191     exitedNormally(false), exitedViaSignal(false), mutationsActive(true), 
192     createdViaAttach(false), detached(false),
193     unreportedStop(false), unreportedTermination(false)
194 {
195     pdvector<pdstring> argv_vec;
196     pdvector<pdstring> envp_vec;
197
198     // Contruct a vector out of the contents of argv
199     for(int i = 0; argv[i] != NULL; i++)
200        argv_vec.push_back(argv[i]);
201
202     if(envp) {
203         // Construct a vector out of the contents of envp
204         for(int i = 0; envp[i] != NULL; ++i)
205             envp_vec.push_back(envp[i]);
206     }
207
208     pdstring directoryName = "";
209
210 #if !defined(i386_unknown_nt4_0) \
211  && !defined(mips_unknown_ce2_11) // i.e. for all unixes
212
213     // this fixes a problem on linux and alpha platforms where pathless
214     // filenames are searched for either in a standard, predefined path, or
215     // in $PATH by execvp.  thus paths that should resolve to "./" are
216     // missed.  Note that the previous use of getcwd() here for the alpha
217     // platform was dangerous since this is an API and we don't know where
218     // the user's code will leave the cwd pointing.
219     const char *dotslash = "./";
220     if (NULL == strchr(path, '/'))
221       directoryName = dotslash;
222 #endif
223
224     //#if defined(alpha_dec_osf4_0)
225     //char buf[1024];
226     //(void*) getcwd(buf, sizeof(buf));
227     //directoryName = buf;
228     //#endif
229     
230     proc = ll_createProcess(path, &argv_vec, (envp ? &envp_vec : NULL), directoryName,
231                             stdin_fd, stdout_fd, stderr_fd);
232     // XXX Should do something more sensible.
233     if (proc == NULL) { 
234         BPatch::bpatch->reportError(BPatchFatal, 68, "BPatch_thread constructor:  process is NULL!");
235         cerr << "Process is NULL!" << endl;
236         return;
237     }
238     
239     proc->bpatch_thread = this;
240
241     // Add this object to the list of threads
242     // XXX Should be conditional on success of creating process
243     assert(BPatch::bpatch != NULL);
244     BPatch::bpatch->registerThread(this);
245     
246     image = new BPatch_image(this);
247
248     while (!proc->isBootstrappedYet() && !statusIsTerminated())
249         BPatch::bpatch->getThreadEvent(false);
250
251     if (BPatch::bpatch->postForkCallback) {
252       insertVForkInst(this);
253     }
254 }
255
256
257 /*
258  * BPatch_thread::BPatch_thread
259  *
260  * Constructs a new BPatch_thread and associates it with a running process.
261  * Stops execution of the process.
262  *
263  * path         Pathname of the executable file for the process.
264  * pid          Process ID of the target process.
265  */
266 BPatch_thread::BPatch_thread(const char *path, int pid)
267   : proc(NULL), image(NULL), lastSignal(-1), exitCode(-1),
268     exitedNormally(false), exitedViaSignal(false), mutationsActive(true), 
269     createdViaAttach(true), detached(false),
270     unreportedStop(false), unreportedTermination(false)
271 {
272     /* For some reason, on Irix, evaluating the return value of
273        attachProcess directly (i.e. no "ret" variable) causes the
274        expression to be incorrectly evaluated as false.  This appears
275        to be a compiler bug ("g++ -mabi=64 -O3"). */
276     // Giving this another try -- bernat, JAN03 */
277     proc = ll_attachProcess(path, pid);
278     if (!proc) {
279         cerr << "attachProcess failed" << endl;
280       // XXX Should do something more sensible
281         return;
282     }
283
284     // Just to be sure, pause the process....
285     proc->pause();
286
287     proc->bpatch_thread = this;
288
289     // Add this object to the list of threads
290     assert(BPatch::bpatch != NULL);
291     BPatch::bpatch->registerThread(this);
292
293     image = new BPatch_image(this);
294
295     while (!proc->isBootstrappedYet() && !statusIsTerminated()) {
296         BPatch::bpatch->getThreadEventOnly(false);
297         proc->getRpcMgr()->launchRPCs(false);
298     }
299     
300         /* Why is this unconditional?  (The insertVForkInst() above is not.) */
301     insertVForkInst(this);
302 }
303
304 /*
305  * BPatch_thread::BPatch_thread
306  *
307  * Constructs a new BPatch_thread and associates it with a forked process.
308  *
309  * parentPid          Pathname of the executable file for the process.
310  * childPid           Process ID of the target process.
311  */
312 BPatch_thread::BPatch_thread(int /*pid*/, process *nProc)
313   : proc(nProc), image(NULL), lastSignal(-1), exitCode(-1),
314     exitedNormally(false), exitedViaSignal(false), mutationsActive(true), 
315     createdViaAttach(true), detached(false),
316     unreportedStop(false), unreportedTermination(false)
317 {
318     proc->bpatch_thread = this;
319
320     // Add this object to the list of threads
321     assert(BPatch::bpatch != NULL);
322     BPatch::bpatch->registerThread(this);
323
324     image = new BPatch_image(this);
325 }
326
327
328 /*
329  * BPatch_thread::~BPatch_thread
330  *
331  * Destructor for BPatch_thread.  Detaches from the running thread.
332  */
333 void BPatch_thread::BPatch_thread_dtor()
334 {
335 #if !defined (os_osf) && !defined (os_windows) && !defined (os_irix) && !defined (arch_ia64)
336     if (  (!detached) )
337       if ( proc && !proc->hasExited()) {
338         fprintf(stderr, "%s[%d]:  before detachFromProcess\n", __FILE__, __LINE__);
339         if (!BPatch::bpatch->eventHandler->detachFromProcess(this)) {
340           bperr("%s[%d]:  trouble decoupling async event handler for process %d\n",
341                __FILE__, __LINE__, getPid());
342       }
343     }
344 #endif
345     if (image) delete image;
346
347     // XXX Make sure that anything else that needs to be deallocated
348     //     gets taken care of.
349     if (!proc) return;
350
351     // If we attached to the process, then we detach and leave it be
352     if (createdViaAttach)
353       proc->detachProcess(true);
354     else {
355       // We want to terminate the process. Note that the process could already
356       // be dead (if the Dyninst mutator killed it and consumed the notification)
357       // so our termination needs to be tolerant.
358       terminateExecution();
359     }
360     delete proc;
361     assert(BPatch::bpatch != NULL);
362     BPatch::bpatch->unRegisterThread(getPid());
363 }
364
365
366 /*
367  * BPatch_thread::stopExecution
368  *
369  * Puts the thread into the stopped state.
370  */
371 bool BPatch_thread::stopExecutionInt()
372 {
373     assert(BPatch::bpatch);
374     BPatch::bpatch->getThreadEvent(false);
375
376     return proc->pause();
377 }
378
379
380 /*
381  * BPatch_thread::continueExecution
382  *
383  * Puts the thread into the running state.
384  */
385 bool BPatch_thread::continueExecutionInt()
386 {
387     assert(BPatch::bpatch);
388     BPatch::bpatch->getThreadEvent(false);
389     if (proc->continueProc()) {
390         setUnreportedStop(false);
391         return true;
392     }
393
394     return false;
395 }
396
397
398 /*
399  * BPatch_thread::terminateExecution
400  *
401  * Kill the thread.
402  */
403 bool BPatch_thread::terminateExecutionInt()
404 {
405     if (!proc || !proc->terminateProc())
406         return false;
407     // Wait for the process to die
408     while (!isTerminated()) ;
409
410     return true;
411 }
412
413
414 /*
415  * BPatch_thread::isStopped
416  *
417  * Returns true if the thread has stopped, and false if it has not.  This may
418  * involve checking for thread events that may have recently changed this
419  * thread's status.  This function also updates the unreportedStop flag if a
420  * stop is detected, in order to indicate that the stop has been reported to
421  * the user.
422  */
423 bool BPatch_thread::isStoppedInt()
424 {
425     assert(BPatch::bpatch);
426
427     //getThreadEvent could change the status of the process from stopped
428     // to running, so we check if the process is stopped before calling
429     // it.
430     if (statusIsStopped()) {
431        setUnreportedStop(false);
432        return true;
433     }
434
435     BPatch::bpatch->getThreadEvent(false);
436     if (statusIsStopped()) {
437         setUnreportedStop(false);
438         return true;
439     } else
440         return false;
441 }
442
443
444 /*
445  * BPatch_thread::statusIsStopped
446  *
447  * Returns true if the thread is stopped, and false if it is not.
448  */
449 bool BPatch_thread::statusIsStopped()
450 {
451     return proc->status() == stopped;
452 }
453
454
455 /*
456  * BPatch_thread::stopSignal
457  *
458  * Returns the number of the signal which caused the thread to stop.
459  */
460 int BPatch_thread::stopSignalInt()
461 {
462     if (proc->status() != neonatal && proc->status() != stopped)
463         return -1;
464     else
465         return lastSignal;
466 }
467
468
469 /*
470  * BPatch_thread::isTerminated
471  *
472  * Returns true if the thread has terminated, and false if it has not.  This
473  * may involve checking for thread events that may have recently changed this
474  * thread's status.  This function also updates the unreportedTermination flag
475  * if the program terminated, in order to indicate that the termination has
476  * been reported to the user.
477  */
478 bool BPatch_thread::isTerminatedInt()
479 {
480     // First see if we've already terminated to avoid 
481     // checking process status too often.
482     if (statusIsTerminated()) {
483         proc->terminateProc();
484         setUnreportedTermination(false);
485         return true;
486     }
487
488     // Check for status changes.
489     assert(BPatch::bpatch);
490     BPatch::bpatch->getThreadEvent(false);
491
492     // Check again
493     if (statusIsTerminated()) {
494         proc->terminateProc();
495         setUnreportedTermination(false);
496         return true;
497     } else {
498         return false;
499     }
500 }
501
502
503 /*
504  * BPatch_thread::statusIsTerminated
505  *
506  * Returns true if the process has terminated, false if it has not.
507  */
508 bool BPatch_thread::statusIsTerminated()
509 {
510     if (proc == NULL) return true;
511     return proc->status() == exited;
512 }
513
514 /*
515  * BPatch_thread::terminationStatus
516  *
517  * Indicates how the program exited.  Returns one of NoExit, ExitedNormally,
518  * or ExitedViaSignal.
519  *
520  */
521 BPatch_exitType BPatch_thread::terminationStatusInt() {
522    if(exitedNormally)
523       return ExitedNormally;
524    else if(exitedViaSignal)
525       return ExitedViaSignal;   
526    else
527       return NoExit;
528
529    assert(false);
530 }
531
532 /*
533  * BPatch_thread::getExitCode
534  *
535  * Returns exit code of applications
536  *
537  */
538 int BPatch_thread::getExitCodeInt() 
539 {
540   return exitCode;
541 }
542
543 /*
544  * BPatch_thread::getExitSignal
545  *
546  * Returns signal number that caused application to exit.
547  *
548  */
549 int BPatch_thread::getExitSignalInt()
550 {
551   return lastSignal;
552 }
553
554 /*
555  * BPatch_thread::detach
556  *
557  * Detach from the thread represented by this object.
558  *
559  * cont         True if the thread should be continued as the result of the
560  *              detach, false if it should not.
561  */
562 bool BPatch_thread::detachInt(bool cont)
563 {
564     // CHANGED: API_detach to detach
565     if (!BPatch::bpatch->eventHandler->detachFromProcess(this)) {
566       bperr("%s[%d]:  trouble decoupling async event handler for process %d\n",
567            __FILE__, __LINE__, getPid());
568     }
569
570     detached = proc->detachProcess(cont);
571     return detached;
572 }
573
574 /*
575  * BPatch_thread::isDetacedh
576  *
577  * Returns whether dyninstAPI is detached from this mutatee
578  *
579  */
580 bool BPatch_thread::isDetachedInt()
581 {
582   return detached;
583 }
584
585 /*
586  * BPatch_thread::dumpCore
587  *
588  * Causes the thread to dump its state to a file, and optionally to terminate.
589  * Returns true upon success, and false upon failure.
590  *
591  * file         The name of the file to which the state should be written.
592  * terminate    Indicates whether or not the thread should be terminated after
593  *              dumping core.  True indicates that it should, false that is
594  *              should not.
595  */
596 bool BPatch_thread::dumpCoreInt(const char *file, bool terminate)
597 {
598     bool was_stopped;
599     bool had_unreportedStop = unreportedStop;
600     if (isStopped()) was_stopped = true;
601     else was_stopped = false;
602     
603     stopExecution();
604
605     bool ret = proc->dumpCore(file);
606     if (ret && terminate) {
607         terminateExecution();
608     } else if (was_stopped) {
609         unreportedStop = had_unreportedStop;
610     } else {
611         continueExecution();
612     }
613     
614     return ret;
615 }
616
617 /*
618  * BPatch_thread::dumpPatchedImage
619  *
620  * Writes the mutated file back to disk,
621  * in ELF format.  (Solaris only)
622  *
623  *
624  */
625 char* BPatch_thread::dumpPatchedImageInt(const char* file){ //ccw 28 oct 2001
626
627 #if !defined(sparc_sun_solaris2_4) \
628  && !defined(i386_unknown_linux2_0) \
629  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
630  && !defined(rs6000_ibm_aix4_1)
631         return NULL;
632 #else
633     bool was_stopped;
634     bool had_unreportedStop = unreportedStop;
635     if (isStopped()) was_stopped = true;
636     else was_stopped = false;
637
638     stopExecution();
639     char* ret = proc->dumpPatchedImage(file);
640     if (was_stopped) {
641         unreportedStop = had_unreportedStop;
642     } else {
643         continueExecution();
644     }
645
646     return ret;
647 #endif
648 }
649
650
651 /*
652  * BPatch_thread::dumpImage
653  *
654  * Writes the contents of memory into a file.
655  * Returns true upon success, and false upon failure.
656  *
657  * file         The name of the file to which the image should be written.
658  */
659 bool BPatch_thread::dumpImageInt(const char *file)
660 {
661 #if defined(i386_unknown_nt4_0) \
662  || defined(mips_unknown_ce2_11) //ccw 20 july 2000 : 28 mar 2001
663     return false;
664 #else
665     bool was_stopped;
666     bool had_unreportedStop = unreportedStop;
667     if (isStopped()) was_stopped = true;
668     else was_stopped = false;
669
670     stopExecution();
671
672     bool ret = proc->dumpImage(file);
673     if (was_stopped) {
674        unreportedStop = had_unreportedStop;
675     } else {
676        continueExecution();
677     }
678
679     return ret;
680 #endif
681 }
682
683
684 /*
685  * BPatch_thread::malloc
686  *
687  * Allocate memory in the thread's address space.
688  *
689  * n    The number of bytes to allocate.
690  *
691  * Returns:
692  *      A pointer to a BPatch_variableExpr representing the memory.
693  *
694  */
695 BPatch_variableExpr *BPatch_thread::mallocInt(int n)
696 {
697     assert(BPatch::bpatch != NULL);
698
699     void *ptr = (void *) proc->inferiorMalloc(n, dataHeap);
700     if (!ptr) {
701         return NULL;
702     }
703
704     BPatch_variableExpr *ret;
705     ret =  new BPatch_variableExpr(this, ptr, Null_Register, BPatch::bpatch->type_Untyped);
706     return ret;
707 }
708
709
710 /*
711  * BPatch_thread::malloc
712  *
713  * Allocate memory in the thread's address space for a variable of the given
714  * type.
715  *
716  * type         The type of variable for which to allocate space.
717  *
718  * Returns:
719  *      A pointer to a BPatch_variableExpr representing the memory.
720  *
721  * XXX Should return NULL on failure, but the function which it calls,
722  *     inferiorMalloc, calls exit rather than returning an error, so this
723  *     is not currently possible.
724  */
725 BPatch_variableExpr *BPatch_thread::mallocByType(const BPatch_type &type)
726 {
727     void *mem = (void *)proc->inferiorMalloc(type.getSize(), dataHeap);
728
729     if (!mem) return NULL;
730
731     return new BPatch_variableExpr(this, mem, Null_Register, &type);
732 }
733
734
735 /*
736  * BPatch_thread::free
737  *
738  * Free memory that was allocated with BPatch_thread::malloc.
739  *
740  * ptr          A BPatch_variableExpr representing the memory to free.
741  */
742 bool BPatch_thread::freeInt(BPatch_variableExpr &ptr)
743 {
744     proc->inferiorFree((Address)ptr.getBaseAddr());
745     return true;
746 }
747
748
749 /*
750  * BPatch_thread::getInheritedVariable
751  *
752  * Allows one to retrieve a variable which exists in a child process which 
753  * was inherited from and originally created in the parent process.
754  * Function is invoked on the child BPatch_thread (created from a fork in 
755  * the application).
756  *
757  * parentVar   A BPatch_variableExpr created in the parent thread
758  *
759  * Returns:    The corresponding BPatch_variableExpr from the child thread
760  *             or NULL if the variable argument hasn't been malloced
761  *             in a parent process.
762  */
763 BPatch_variableExpr *BPatch_thread::getInheritedVariableInt(
764                                           BPatch_variableExpr &parentVar)
765 {
766   if(! isInferiorAllocated(proc, (Address)parentVar.getBaseAddr())) {
767     // isn't defined in this process so must not have been defined in a
768     // parent process
769     return NULL;
770   }
771   return new BPatch_variableExpr(this, parentVar.getBaseAddr(), Null_Register,
772                                  parentVar.getType());
773 }
774
775
776 /*
777  * BPatch_thread::getInheritedSnippet
778  *
779  * Allows one to retrieve a snippet which exists in a child process which 
780  * was inherited from and originally created in the parent process.
781  * Function is invoked on the child BPatch_thread (created from a fork in 
782  * the application).
783  *
784  * Allows one to retrieve a snippet which exists in a child process which
785  * was inherited from and originally created in the parent process.
786  * Function is invoked on the child BPatch_thread (created from a fork in
787  * the application).
788  *
789  * parentSnippet: A BPatchSnippetHandle created in the parent thread
790  *
791  * Returns:       The corresponding BPatchSnippetHandle from the child thread.
792  *
793  */
794 BPatchSnippetHandle *BPatch_thread::getInheritedSnippetInt(
795                                           BPatchSnippetHandle &parentSnippet)
796 {
797   // a BPatchSnippetHandle has an miniTrampHandle for each point that
798   // the instrumentation is inserted at
799   BPatch_Vector<miniTrampHandle *> parent_mtHandles;
800   parentSnippet.getMiniTrampHandles(&parent_mtHandles);
801
802   BPatchSnippetHandle *childSnippet = new BPatchSnippetHandle(proc);
803   for(unsigned i=0; i<parent_mtHandles.size(); i++) {
804       miniTrampHandle *childMT = NULL;
805       if(! getInheritedMiniTramp(parent_mtHandles[i], 
806                                  childMT, 
807                                  proc)) {
808           // error, couldn't find a snippet
809           return NULL;
810       }
811       childSnippet->add(childMT);
812   }
813   return childSnippet;
814 }
815
816
817 /*
818  * BPatch_thread::insertSnippet
819  *
820  * Insert a code snippet at a given instrumentation point.  Upon succes,
821  * returns a handle to the created instance of the snippet, which can be used
822  * to delete it.  Otherwise returns NULL.
823  *
824  * expr         The snippet to insert.
825  * point        The point at which to insert it.
826  */
827 BPatchSnippetHandle *BPatch_thread::insertSnippetInt(const BPatch_snippet &expr,
828                                                   BPatch_point &point,
829                                                   BPatch_snippetOrder order)
830 {
831       BPatch_callWhen when;
832
833       // which one depends on the type of the point
834       // need to cast away const since getPointType isn't const
835       if (((BPatch_point)point).getPointType() == BPatch_exit) {
836           when = BPatch_callAfter;
837       } else {
838           when = BPatch_callBefore;
839       }
840
841       return insertSnippet(expr, point, when, order);
842 }
843
844 /*
845  * BPatch_thread::insertSnippet
846  *
847  * Insert a code snippet at a given instrumentation point.  Upon succes,
848  * returns a handle to the created instance of the snippet, which can be used
849  * to delete it.  Otherwise returns NULL.
850  *
851  * expr         The snippet to insert.
852  * point        The point at which to insert it.
853  */
854 BPatchSnippetHandle *BPatch_thread::insertSnippetWhen(const BPatch_snippet &expr,
855                                                   BPatch_point &point,
856                                                   BPatch_callWhen when,
857                                                   BPatch_snippetOrder order)
858 {
859     // Can't insert code when mutations are not active.
860     if (!mutationsActive)
861         return NULL;
862
863     // code is null (possibly an empy sequence or earlier error)
864     if (!expr.ast) return NULL;
865
866     callWhen    _when;
867     callOrder   _order;
868
869     switch (when) {
870   case BPatch_callBefore:
871       _when = callPreInsn;
872       break;
873   case BPatch_callAfter:
874       _when = callPostInsn;
875       break;
876   default:
877       return NULL;
878     };
879
880     switch (order) {
881       case BPatch_firstSnippet:
882         _order = orderFirstAtPoint;
883         break;
884       case BPatch_lastSnippet:
885         _order = orderLastAtPoint;
886         break;
887       default:
888         return NULL;
889     }
890
891     assert(BPatch::bpatch != NULL);     // We'll use this later
892
893     //
894     // Check for valid combinations of BPatch_procedureLocation & call*
895     //  Right now we don't allow
896     //          BPatch_callBefore + BPatch_exit
897     //          BPatch_callAfter + BPatch_entry
898     //
899     //  These combinations are intended to be used to mark the point that
900     //      is the last, first valid point where the local variables are
901     //      valid.  This is deifferent than the first/last instruction of
902     //      a subroutine which is what the other combinations of BPatch_entry
903     //      and BPatch_exit refer to.
904     //
905     //  jkh 3/1/00 (based on agreement reached at dyninst Jan'00 meeting)
906     //
907     if ((when == BPatch_callBefore) && 
908         (point.getPointType() == BPatch_exit)) {
909         BPatch_reportError(BPatchSerious, 113,
910                "BPatch_callBefore at BPatch_exit not supported yet");
911         return NULL;
912     } else if ((when == BPatch_callAfter) && 
913                (point.getPointType() == BPatch_entry)) {
914         BPatch_reportError(BPatchSerious, 113,
915                "BPatch_callAfter at BPatch_entry not supported yet");
916         return NULL;
917     }
918
919     if ((point.getPointType() == BPatch_exit)) {
920         //  XXX - Hack! 
921         //  The semantics of pre/post insn at exit are setup for the new
922         //  defintion of using this to control before/after stack creation,
923         //  but the lower levels of dyninst don't know about this yet.
924         _when = callPreInsn;
925     }
926
927     // XXX Really only need to type check once per function the snippet is
928     // being inserted into, not necessarily once per point.
929     if (BPatch::bpatch->isTypeChecked()) {
930         assert(expr.ast);
931         if (expr.ast->checkType() == BPatch::bpatch->type_Error) {
932             // XXX Type check error - should call callback
933             return NULL;
934         }
935     }
936
937     BPatchSnippetHandle *handle = new BPatchSnippetHandle(proc);
938
939     AstNode *ast = (AstNode *)expr.ast;  /* XXX no const */
940
941     
942     instPoint *&ip = (instPoint*&) point.point;
943
944     if(point.proc != proc) {
945       cerr << "insertSnippet: the given instPoint isn't from the same process "
946            << "as the invoked BPatch_thread\n";
947       return NULL;
948     }
949
950 #if defined(rs6000_ibm_aix4_1) \
951  || defined(rs6000_ibm_aix5_1)
952
953         bool isMain=false;
954         BPatch_function *tmpFunc = const_cast<BPatch_function *>(point.getFunction());
955
956         char tmpFuncName[1024];
957
958         if(proc->collectSaveWorldData){
959                 tmpFunc->getName(tmpFuncName, 1024);
960
961                 if( !strncmp(tmpFuncName,"main",4)){
962
963                         isMain = true;
964                 
965                 }
966                 
967         }
968
969 #endif
970
971     // XXX We just pass false for the "noCost" parameter here - do we want
972     // to make that an option?
973     miniTrampHandle *mtHandle;
974     
975     loadMiniTramp_result res = addInstFunc(proc, mtHandle, ip, ast, _when, 
976                                            _order, false,
977                                            // Do we want the base tramp (if any) created allowing
978                                            // recursion? 
979 #if defined(mips_sgi_irix6_4)
980                                            // On MIPS, we can't have recursive guards on arbitrary
981                                            // inst point.
982                                            point.getPointType() == BPatch_arbitrary ?  true : 
983 #endif
984                                            
985 #if defined(rs6000_ibm_aix4_1) \
986  || defined(rs6000_ibm_aix5_1)
987                                            (isMain ? true :BPatch::bpatch->isTrampRecursive()),
988 #else
989                                            BPatch::bpatch->isTrampRecursive(),
990 #endif
991                                            true
992                                            );
993     
994     if(res == success_res) {
995         handle->add(mtHandle);
996     } else {
997         delete handle;
998         return NULL;
999     }
1000     return handle;
1001 }
1002
1003
1004 /*
1005  * BPatch_thread::insertSnippet
1006  *
1007  * Insert a code snippet at each of a list of instrumentation points.  Upon
1008  * success, Returns a handle to the created instances of the snippet, which
1009  * can be used to delete them (as a unit).  Otherwise returns NULL.
1010  *
1011  * expr         The snippet to insert.
1012  * points       The list of points at which to insert it.
1013  */
1014 BPatchSnippetHandle *BPatch_thread::insertSnippetAtPointsWhen(
1015                                     const BPatch_snippet &expr,
1016                                     const BPatch_Vector<BPatch_point *> &points,
1017                                     BPatch_callWhen when,
1018                                     BPatch_snippetOrder order)
1019 {
1020     BPatchSnippetHandle *handle = new BPatchSnippetHandle(proc);
1021
1022     for (unsigned int i = 0; i < points.size(); i++) {
1023         BPatch_point *point = points[i];
1024
1025         BPatchSnippetHandle *ret = insertSnippet(expr, *point, when, order);
1026         if (ret) {
1027             for (unsigned int j=0; j < ret->mtHandles.size(); j++) {
1028                 handle->add(ret->mtHandles[j]);
1029             }
1030             delete ret;
1031         } else {
1032             delete handle;
1033             return NULL;
1034         }
1035     }
1036
1037     return handle;
1038 }
1039
1040
1041 /*
1042  * BPatch_thread::insertSnippet
1043  *
1044  * Insert a code snippet at each of a list of instrumentation points.  Upon
1045  * success, Returns a handle to the created instances of the snippet, which
1046  * can be used to delete them (as a unit).  Otherwise returns NULL.
1047  *
1048  * expr         The snippet to insert.
1049  * points       The list of points at which to insert it.
1050  */
1051 BPatchSnippetHandle *BPatch_thread::insertSnippetAtPoints(
1052                                     const BPatch_snippet &expr,
1053                                     const BPatch_Vector<BPatch_point *> &points,
1054                                     BPatch_snippetOrder order)
1055 {
1056     BPatchSnippetHandle *handle = new BPatchSnippetHandle(proc);
1057
1058     for (unsigned int i = 0; i < points.size(); i++) {
1059         BPatch_point *point = points[i]; // Cast away const
1060
1061         BPatch_callWhen when;
1062
1063         // which one depends on the type of the point
1064         // need to cast away const since getPointType isn't const
1065         if (point->getPointType() == BPatch_exit) {
1066             when = BPatch_callAfter;
1067         } else {
1068             when = BPatch_callBefore;
1069         }
1070
1071         BPatchSnippetHandle *ret = insertSnippet(expr, *point, when, order);
1072         if (ret) {
1073             for (unsigned int j=0; j < ret->mtHandles.size(); j++) {
1074                 handle->add(ret->mtHandles[j]);
1075             }
1076             delete ret;
1077         } else {
1078             delete handle;
1079             return NULL;
1080         }
1081     }
1082
1083     return handle;
1084 }
1085
1086 /*
1087  * BPatch_thread::deleteSnippet
1088  * 
1089  * Deletes an instance of a snippet.
1090  *
1091  * handle       The handle returned by insertSnippet when the instance to
1092  *              deleted was created.
1093  */
1094 bool BPatch_thread::deleteSnippetInt(BPatchSnippetHandle *handle)
1095 {
1096     
1097     if (handle->proc == proc) {
1098         for (unsigned int i=0; i < handle->mtHandles.size(); i++) {
1099             deleteInst(proc, handle->mtHandles[i]);
1100         }
1101         delete handle;
1102         return true;
1103     } else { // Handle isn't to a snippet instance in this process
1104         cerr << "Error: wrong process in deleteSnippet" << endl;
1105         
1106         return false;
1107     }
1108 }
1109
1110
1111 /*
1112  * BPatch_thread::setMutationsActive
1113  *
1114  * Enable or disable the execution of all snippets for the thread.
1115  * 
1116  * activate     If set to true, execution of snippets is enabled.  If false,
1117  *              execution is disabled.
1118  */
1119 bool BPatch_thread::setMutationsActiveInt(bool activate)
1120 {
1121     // If not activating or deactivating, just return.
1122     if ((activate && mutationsActive) || (!activate && !mutationsActive))
1123        return true;
1124
1125 #if 0
1126     // The old implementation
1127     dictionary_hash_iter<const instPoint*, trampTemplate *> bmi(proc->baseMap);
1128
1129     const instPoint *point;
1130     trampTemplate   *tramp;
1131
1132     while (bmi.next(point, tramp)) {
1133
1134         /*
1135         if (tramp->retInstance != NULL) {
1136             if (activate)
1137                 tramp->retInstance->installReturnInstance(proc);
1138             else
1139                 tramp->retInstance->unInstallReturnInstance(proc);
1140         }
1141         */
1142     }
1143 #endif
1144
1145 #ifdef BPATCH_SET_MUTATIONS_ACTIVE
1146     if (activate)
1147        proc->reinstallMutations();
1148     else
1149        proc->uninstallMutations();
1150
1151     mutationsActive = activate;
1152 #endif
1153     return true;
1154 }
1155
1156
1157 /*
1158  * BPatch_thread::replaceFunctionCall
1159  *
1160  * Replace a function call with a call to a different function.  Returns true
1161  * upon success, false upon failure.
1162  * 
1163  * point        The call site that is to be changed.
1164  * newFunc      The function that the call site will now call.
1165  */
1166 bool BPatch_thread::replaceFunctionCallInt(BPatch_point &point,
1167                                         BPatch_function &newFunc)
1168 {
1169     // Can't make changes to code when mutations are not active.
1170     if (!mutationsActive)
1171         return false;
1172
1173     assert(point.point && newFunc.func);
1174
1175     return proc->replaceFunctionCall(point.point, newFunc.func);
1176 }
1177
1178
1179 /*
1180  * BPatch_thread::removeFunctionCall
1181  *
1182  * Replace a function call with a NOOP.  Returns true upon success, false upon
1183  * failure.
1184  * 
1185  * point        The call site that is to be NOOPed out.
1186  */
1187 bool BPatch_thread::removeFunctionCallInt(BPatch_point &point)
1188 {
1189     // Can't make changes to code when mutations are not active.
1190     if (!mutationsActive)
1191         return false;
1192
1193     assert(point.point);
1194
1195     return proc->replaceFunctionCall(point.point, NULL);
1196 }
1197
1198
1199 /*
1200  * BPatch_thread::replaceFunction
1201  *
1202  * Replace all calls to function OLDFUNC with calls to NEWFUNC.
1203  * Returns true upon success, false upon failure.
1204  * 
1205  * oldFunc      The function to replace
1206  * newFunc      The replacement function
1207  */
1208 bool BPatch_thread::replaceFunctionInt(BPatch_function &oldFunc,
1209                                     BPatch_function &newFunc)
1210 {
1211 #if defined(sparc_sun_solaris2_4) \
1212  || defined(alpha_dec_osf4_0) \
1213  || defined(i386_unknown_linux2_0) \
1214  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1215  || defined(i386_unknown_nt4_0) \
1216  || defined(ia64_unknown_linux2_4)
1217     // Can't make changes to code when mutations are not active.
1218     if (!mutationsActive)
1219         return false;
1220
1221     assert(oldFunc.func && newFunc.func);
1222
1223     // Self replacement is a nop
1224     if (oldFunc.func == newFunc.func)
1225          return true;
1226
1227     /* mihai
1228      *
1229      */
1230     bool old_recursion_flag = BPatch::bpatch->isTrampRecursive();
1231     BPatch::bpatch->setTrampRecursive( true );
1232
1233     // We replace functions by instrumenting the entry of OLDFUNC with
1234     // a non-linking jump to NEWFUNC.  Calls to OLDFUNC do actually
1235     // transfer to OLDFUNC, but then our jump shunts them to NEWFUNC.
1236     // The non-linking jump ensures that when NEWFUNC returns, it
1237     // returns directly to the caller of OLDFUNC.
1238     BPatch_Vector<BPatch_point *> *pts = oldFunc.findPoint(BPatch_entry);
1239     if (! pts || ! pts->size())
1240          return false;
1241     BPatch_funcJumpExpr fje(newFunc);
1242     BPatchSnippetHandle * result = insertSnippet(fje, *pts, BPatch_callBefore);
1243
1244     /* mihai
1245      *
1246      */
1247     BPatch::bpatch->setTrampRecursive( old_recursion_flag );
1248
1249     return (NULL != result);
1250 #else
1251     BPatch_reportError(BPatchSerious, 109,
1252                        "replaceFunction is not implemented on this platform");
1253     return false;
1254 #endif
1255 }
1256
1257 /*
1258  * BPatch_thread::oneTimeCode
1259  *
1260  * execute argument <expr> once.
1261  *
1262 */
1263
1264 void *BPatch_thread::oneTimeCodeInt(const BPatch_snippet &expr)
1265 {
1266   return oneTimeCodeInternal(expr, NULL, true);
1267 }
1268
1269 /*
1270  * BPatch_thread::oneTimeCodeCallbackDispatch
1271  *
1272  * This function is registered with the lower-level code as the callback for
1273  * inferior RPC completion.  It determines what thread the RPC was executed on
1274  * and then calls the API's higher-level callback routine for that thread.
1275  *
1276  * theProc      The process in which the RPC completed.
1277  * userData     This is a value that can be set when we invoke an inferior RPC
1278  *              and which will be returned to us in this callback.
1279  * returnValue  The value returned by the RPC.
1280  */
1281 void BPatch_thread::oneTimeCodeCallbackDispatch(process *theProc,
1282                                                 unsigned /* rpcid */, 
1283                                                 void *userData,
1284                                                 void *returnValue)
1285 {
1286     assert(BPatch::bpatch != NULL);
1287
1288     OneTimeCodeInfo *info = (OneTimeCodeInfo *)userData;
1289
1290     BPatch_thread *theThread =
1291         BPatch::bpatch->getThreadByPid(theProc->getPid());
1292
1293     assert(theThread != NULL);
1294     assert(info && !info->isCompleted());
1295
1296     info->setReturnValue(returnValue);
1297     info->setCompleted(true);
1298
1299     if (!info->isSynchronous()) {
1300         if (BPatch::bpatch->oneTimeCodeCallback)
1301             BPatch::bpatch->oneTimeCodeCallback(theThread, info->getUserData(), returnValue);
1302
1303         delete info;
1304     }
1305
1306 #ifdef IBM_BPATCH_COMPAT
1307     if (BPatch::bpatch->RPCdoneCallback) {
1308         bperr("invoking IBM thread callback function\n");
1309         BPatch::bpatch->RPCdoneCallback(theThread, userData, returnValue);
1310     }
1311 #endif
1312 }
1313
1314
1315
1316
1317 /*
1318  * BPatch_thread::oneTimeCodeInternal
1319  *
1320  * Causes a snippet expression to be evaluated once in the mutatee at the next
1321  * available opportunity.  Optionally, Dyninst will call a callback function
1322  * when the snippet has executed in the mutatee, and can wait until the
1323  * snippet has executed to return.
1324  *
1325  * expr         The snippet to evaluate.
1326  * userData     This value is given to the callback function along with the
1327  *              return value for the snippet.  Can be used by the caller to
1328  *              store per-oneTimeCode information.
1329  * synchronous  True means wait until the snippet has executed, false means
1330  *              return immediately.
1331  */
1332 void *BPatch_thread::oneTimeCodeInternal(const BPatch_snippet &expr,
1333                                          void *userData,
1334                                          bool synchronous)
1335 {
1336     bool needToResume = false;
1337     if (synchronous && !statusIsStopped()) {
1338         stopExecution();
1339
1340         if (!statusIsStopped()) {
1341             cerr << "Failed to run oneTimeCodeInternal" << endl;
1342             return NULL;
1343         }
1344         needToResume = true;
1345     }
1346
1347     OneTimeCodeInfo *info = new OneTimeCodeInfo(synchronous, userData);
1348
1349     proc->getRpcMgr()->postRPCtoDo(expr.ast,
1350                                    false, // XXX = calculate cost - is this what we want?
1351                                    BPatch_thread::oneTimeCodeCallbackDispatch, // Callback
1352                                    (void *)info, // User data
1353                                    false,
1354                                    NULL, NULL); // Process-wide  
1355     
1356     if (synchronous) {
1357         do {
1358             proc->getRpcMgr()->launchRPCs(false);
1359             BPatch::bpatch->getThreadEvent(false);
1360         } while (!info->isCompleted() && !statusIsTerminated());
1361         
1362         void *ret = info->getReturnValue();
1363         delete info;
1364
1365         if (needToResume) {
1366             continueExecution();
1367         }
1368         
1369         return ret;
1370     } else {
1371         proc->getRpcMgr()->launchRPCs(proc->status() == running);
1372         return NULL;
1373     }
1374 }
1375
1376 //  BPatch_thread::oneTimeCodeAsync
1377 //
1378 //  Have the specified code be executed by the mutatee once.  Dont wait until done.
1379 bool BPatch_thread::oneTimeCodeAsyncInt(const BPatch_snippet &expr, 
1380                                         void *userData)
1381 {
1382   oneTimeCodeInternal(expr, userData, false);
1383   return true;
1384 }
1385
1386 /*
1387  * BPatch_thread::loadLibrary
1388  *
1389  * Load a dynamically linked library into the address space of the mutatee.
1390  *
1391  * libname      The name of the library to load.
1392  */
1393 bool BPatch_thread::loadLibraryInt(const char *libname, bool reload)
1394 {
1395 #if defined(sparc_sun_solaris2_4) \
1396  || defined(i386_unknown_solaris2_5) \
1397  || defined(i386_unknown_linux2_0) \
1398  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1399  || defined(mips_sgi_irix6_4) \
1400  || defined(alpha_dec_osf4_0) \
1401  || defined(rs6000_ibm_aix4_1) \
1402  || defined(ia64_unknown_linux2_4) \
1403  || defined(i386_unknown_nt4_0)
1404     if (!statusIsStopped()) {
1405         cerr << "Process not stopped in loadLibrary" << endl;
1406         return false;
1407     }
1408     BPatch_Vector<BPatch_snippet *> args;
1409
1410     BPatch_constExpr nameArg(libname);
1411     // BPatch_constExpr modeArg(RTLD_NOW | RTLD_GLOBAL);
1412
1413     args.push_back(&nameArg);
1414     // args.push_back(&modeArg);
1415     BPatch_Vector<BPatch_function *> bpfv;
1416     if ((NULL == image->findFunction("DYNINSTloadLibrary", bpfv) || !bpfv.size())) {
1417       cout << __FILE__ << ":" << __LINE__ << ": FATAL:  Cannot find Internal Function "
1418            << "DYNINSTloadLibrary" << endl;
1419       abort();
1420     }
1421
1422     if (bpfv.size() > 1) {
1423       pdstring msg = pdstring("Found ") + pdstring(bpfv.size()) 
1424         + pdstring("functions called DYNINSTloadLibrary -- not fatal but weird");
1425       BPatch_reportError(BPatchSerious, 100, msg.c_str());
1426     }
1427
1428     BPatch_function *dlopen_func = bpfv[0]; 
1429     if (dlopen_func == NULL) return false;
1430
1431     BPatch_funcCallExpr call_dlopen(*dlopen_func, args);
1432     
1433     if (!oneTimeCodeInternal(call_dlopen, NULL, true)) {
1434       // dlopen FAILED
1435       // find the (global var) error string in the RT Lib and send it to the
1436       // error reporting mechanism
1437       BPatch_variableExpr *dlerror_str_var = image->findVariable("gLoadLibraryErrorString");
1438       assert(NULL != dlerror_str_var);
1439       
1440       char dlerror_str[256];
1441       dlerror_str_var->readValue((void *)dlerror_str, 256);
1442       cerr << dlerror_str << endl;
1443       BPatch_reportError(BPatchSerious, 124, dlerror_str);
1444       return false;
1445     }
1446
1447 #ifdef BPATCH_LIBRARY //ccw 14 may 2002
1448 #if defined(sparc_sun_solaris2_4) \
1449  || defined(i386_unknown_linux2_0) \
1450  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1451  || defined(rs6000_ibm_aix4_1) \
1452  || defined(r6000_ibm_aix5_1)
1453         if(proc->collectSaveWorldData && reload){
1454                 proc->saveWorldloadLibrary(libname);    
1455         }
1456 #endif
1457 #endif
1458     return true;
1459 #else
1460     return false;
1461 #endif
1462 }
1463
1464 /** method that retrieves the line number and file name for a given
1465   * address. In failure it returns false. user is responsible to
1466   * to supply the buffer to write the file name and has to give the
1467   * size of the buffer available. The name of the file will be null
1468   * terminated by the program.
1469   */
1470 bool BPatch_thread::getLineAndFileInt(unsigned long addr,unsigned short& lineNo,
1471                                    char* fileName,int size)
1472 {
1473         // /* DEBUG */ bperr( "Looking for addr 0x%lx.\n", addr );
1474
1475         if(!fileName || (size <= 0)){
1476                 return false;
1477         }
1478         size--;
1479         LineInformation* lineInformation = NULL;
1480         BPatch_Vector<BPatch_module*>* appModules = image->getModules();
1481         for(unsigned int i=0;i<appModules->size();i++){
1482                 lineInformation = (*appModules)[i]->getLineInformation();
1483                 if(!lineInformation) {
1484                   // /* DEBUG */ bperr( "No line information for module %d\n", i );
1485                   cerr << __FILE__ << __LINE__ << ": found NULL lineInformation "<< endl;
1486                   continue;
1487                 }
1488 #ifdef OLD_LINE_INFO
1489                 
1490                 Address inexactitude;
1491                 Address leastInexactitude = 0xFFFFFFFF;
1492                 unsigned short tempLineNo;
1493                 
1494                 for(int j=0;j<lineInformation->getSourceFileCount();j++){
1495                         pdstring* fileN = lineInformation->sourceFileList[j];
1496                         // /* DEBUG */ bperr( "Looking for information on source file '%s'.\n", fileN->c_str() );
1497                         FileLineInformation* fInfo = 
1498                                 lineInformation->lineInformationList[j];
1499                         if (!fInfo) {
1500                           // /* DEBUG */ bperr( "No information available on source file '%s'.\n", fileN->c_str() );
1501                           cerr << "found NULL FileLineInformation! "<< endl;
1502                           continue;
1503                         }
1504                         
1505                         if( ! fInfo->getLineFromAddr( * fileN, tempLineNo, addr, true, false, & inexactitude ) ) { continue; }
1506                         // /* DEBUG */ bperr( "%s: %d (0x%lx)\n", fileN->c_str(), tempLineNo, inexactitude );
1507
1508                         /* If the match got better, record its inexactitude, lineNo, and name as
1509                            our best match. */
1510                         if( inexactitude < leastInexactitude ) {
1511                                 // /* DEBUG */ bperr( "Inexactitude decreased: 0x%lx\n", inexactitude );
1512                                 leastInexactitude = inexactitude;
1513                                 lineNo = tempLineNo;
1514                                 
1515                                 if( fileN->length() < (unsigned)size ) {
1516                                         size = fileN->length();
1517                                         }
1518                                 strncpy( fileName, fileN->c_str(), size );
1519                                 fileName[size] = '\0';
1520                                 }
1521                         
1522                         /* If the match is perfect, we're done; don't bother to iterate over the
1523                            rest of the files. */
1524                         if( inexactitude == 0 ) {
1525                                 // /* DEBUG */ bperr( "Found perfect match.\n" );
1526                                 return true;
1527                                 }
1528                         } /* end by-file iteraition */
1529
1530                 if( ! (leastInexactitude < 0xFFFFFFFF) ) {
1531                         return false;
1532                         }
1533                 else {
1534                         return true;
1535                         }
1536 #else
1537                 if (lineInformation->getLineAndFile(addr, lineNo, fileName, size))
1538                     return true;
1539 #endif
1540         }
1541
1542         return false;
1543 }
1544
1545
1546 /*
1547  * BPatch_thread::findFunctionByAddr
1548  *
1549  * Returns the function that contains the specified address, or NULL if the
1550  * address is not within a function.
1551  *
1552  * addr         The address to use for the lookup.
1553  */
1554 BPatch_function *BPatch_thread::findFunctionByAddrInt(void *addr)
1555 {
1556     int_function *func;
1557
1558     codeRange *range = proc->findCodeRangeByAddress((Address) addr);
1559     if (!range)
1560         return NULL;
1561
1562     if (range->is_relocated_func())
1563       func = range->is_relocated_func()->func();
1564     else
1565       func = range->is_function();
1566     
1567     if (!func)
1568       return NULL;
1569     
1570     return proc->findOrCreateBPFunc(func);
1571 }
1572
1573
1574 /* 
1575         this function sets a flag in process that 
1576         forces the collection of data for saveworld. //ccw 23 jan 2002
1577 */
1578 void BPatch_thread::enableDumpPatchedImageInt(){
1579         proc->collectSaveWorldData=true;
1580 }
1581
1582
1583 /*
1584  * BPatch_thread::getCallStack
1585  *
1586  * Returns information about the frames currently on the thread's stack.
1587  *
1588  * stack        The vector to fill with the stack trace information.
1589  */
1590 bool BPatch_thread::getCallStackInt(BPatch_Vector<BPatch_frame>& stack)
1591 {
1592     pdvector<pdvector<Frame> > stackWalks;
1593
1594     proc->walkStacks(stackWalks);
1595
1596     // We can only handle one thread right now; change when we begin to handle
1597     // multiple threads.
1598     assert(stackWalks.size() == 1);
1599
1600     // The internal representation of a stack walk treats instrumentation
1601     // as part of the original instrumented function. That is to say, if A() 
1602     // calls B(), and B() is instrumented, the stack will appear as so:
1603     // A()
1604     // instrumentation
1605
1606     // We want it to look like so:
1607     // A()
1608     // B()
1609     // instrumentation
1610
1611     // We handle this by adding a synthetic frame to the stack walk whenever
1612     // we discover an instrumentation frame.
1613
1614     for (unsigned int i = 0; i < stackWalks[0].size(); i++) {
1615         bool isSignalFrame = false;
1616         bool isInstrumentation = false;
1617
1618         Frame frame = stackWalks[0][i];
1619         if (frame.frameType_ != FRAME_unset) {
1620             isSignalFrame = frame.isSignalFrame();
1621             isInstrumentation = frame.isInstrumentation();
1622         }
1623         else {
1624             codeRange *range = frame.getRange();
1625             if (range) {
1626                 // Check if we're in a base or minitramp
1627                 trampTemplate *bt = range->is_basetramp();
1628                 miniTrampHandle *mt = range->is_minitramp();
1629                 multitrampTemplate *mtt = range->is_multitramp();
1630                 if (bt || mt || mtt) isInstrumentation = true;
1631             }
1632         }
1633
1634         stack.push_back(BPatch_frame(this,
1635                                      (void*)stackWalks[0][i].getPC(),
1636                                      (void*)stackWalks[0][i].getFP(),
1637                                      isSignalFrame, isInstrumentation));
1638         if (isInstrumentation) {
1639             // Fake a frame at the address of the instrumentation
1640             codeRange *range = frame.getRange();
1641             if (range) {
1642                 // Get the minitramp -> base tramp -> location
1643                 trampTemplate *bt = range->is_basetramp();
1644                 miniTrampHandle *mt = range->is_minitramp();
1645                 multitrampTemplate *mtt = range->is_multitramp();
1646                 
1647                 Address ipAddr = 0;                
1648                 if( !bt && !mt && mtt ) {
1649                         ipAddr = mtt->location->absPointAddr(proc);
1650                         }
1651                 if( !bt && mt )
1652                     bt = mt->baseTramp;
1653                 if( bt ) {
1654                     ipAddr = bt->location->absPointAddr(proc);
1655                     }
1656                 if( ipAddr != 0 ) {
1657                     stack.push_back(BPatch_frame(this,
1658                                                  (void *)ipAddr,
1659                                                  // Fake this
1660                                                  (void *)frame.getFP(),
1661                                                  false, // not signal handler,
1662                                                  false)); // not inst.
1663                 }
1664             }
1665         }
1666     }
1667     return true;
1668 }
1669
1670 bool BPatch_thread::registerThreadEventCallbackInt(BPatch_asyncEventType type,
1671                                                    BPatchThreadEventCallback cb)
1672 {
1673   bool ret = false;
1674   BPatch_asyncEventHandler *handler = BPatch::bpatch->eventHandler;
1675   ret = handler->registerThreadEventCallback(this, type, cb);
1676   if (ret) BPatch::bpatch->asyncActive = true;
1677   return ret;
1678 }
1679
1680 bool BPatch_thread::removeThreadEventCallbackInt(BPatch_asyncEventType type,
1681                                                  BPatchThreadEventCallback cb)
1682 {
1683   bool ret = false;
1684   BPatch_asyncEventHandler *handler = BPatch::bpatch->eventHandler;
1685   ret =  handler->removeThreadEventCallback(this, type, cb);
1686   if (ret) BPatch::bpatch->asyncActive = true;
1687   return ret;
1688 }
1689
1690 bool BPatch_thread::registerThreadEventCallbackMutateeSide(BPatch_asyncEventType type,
1691                                                            BPatch_function *cb)
1692 {
1693   BPatch_asyncEventHandler *handler = BPatch::bpatch->eventHandler;
1694   return handler->registerThreadEventCallback(this, type, cb);
1695 }
1696
1697 bool BPatch_thread::removeThreadEventCallbackMutateeSide(BPatch_asyncEventType type,
1698                                                          BPatch_function *cb)
1699 {
1700   BPatch_asyncEventHandler *handler = BPatch::bpatch->eventHandler;
1701   return handler->removeThreadEventCallback(this, type, cb);
1702 }
1703
1704
1705 #ifdef IBM_BPATCH_COMPAT
1706 bool BPatch_thread::isThreaded()
1707 {
1708   return false;
1709 }
1710
1711 bool BPatch_thread::addSharedObject(const char *name, const unsigned long loadaddr)
1712 {
1713   //  in IBM's code, this is a wrapper for _BPatch_thread->addSharedObject (linux)
1714   // which is in turn a wrapper for creating a new ibmBpatchElf32Reader(name, addr)
1715   //
1716   bperr( "%s[%d]: inside addSharedObject(%s, %lu), which is not properly implemented\n"
1717           "using loadLibrary(char* = %s)\n",
1718           __FILE__, __LINE__, name, loadaddr, name);
1719
1720   return loadLibrary(name);
1721 }
1722
1723 #endif
1724
1725
1726 /***************************************************************************
1727  * BPatch_snippetHandle
1728  ***************************************************************************/
1729
1730 /*
1731  * BPatchSnippetHandle::add
1732  *
1733  * Add an instance of a snippet to the list of instances held by the
1734  * BPatchSnippetHandle.
1735  *
1736  * instance     The instance to add.
1737  */
1738 void BPatchSnippetHandle::add(miniTrampHandle *pointInstance)
1739 {
1740     mtHandles.push_back(pointInstance);
1741 }
1742
1743
1744 /*
1745  * BPatchSnippetHandle::~BPatchSnippetHandle
1746  *
1747  * Destructor for BPatchSnippetHandle.  Delete the snippet instance(s)
1748  * associated with the BPatchSnippetHandle.
1749  */
1750 void BPatchSnippetHandle::BPatchSnippetHandle_dtor()
1751 {
1752     // don't delete inst instances since they are might have been copied
1753 }
1754
1755
1756 /***************************************************************************
1757  * BPatch_frame
1758  ***************************************************************************/
1759
1760 /*
1761  * BPatch_frame::getFrameType()
1762  *
1763  * Returns the type of frame: BPatch_frameNormal for the stack frame for a
1764  * function, BPatch_frameSignal for the stack frame created when a signal is
1765  * delivered, or BPatch_frameTrampoline for a stack frame for a trampoline.
1766  */
1767 BPatch_frameType BPatch_frame::getFrameTypeInt()
1768 {
1769         if( isSignalFrame ) { return BPatch_frameSignal; }
1770         else if( isTrampoline ) { return BPatch_frameTrampoline; }
1771         else { return BPatch_frameNormal; } 
1772 }
1773
1774 void *BPatch_frame::getPCInt() 
1775 {
1776   return pc;
1777 }
1778 void *BPatch_frame::getFPInt()
1779 {
1780   return fp;
1781 }
1782
1783 /*
1784  * BPatch_frame::findFunction()
1785  *
1786  * Returns the function associated with the stack frame, or NULL if there is
1787  * none.
1788  */
1789 BPatch_function *BPatch_frame::findFunctionInt()
1790 {
1791     return thread->findFunctionByAddr(getPC());
1792 }