Problem 1:
[dyninst.git] / dyninstAPI / src / BPatch_process.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 #ifdef sparc_sun_solaris2_4
43 #include <dlfcn.h>
44 #endif
45
46 #define BPATCH_FILE
47
48
49 #include "process.h"
50 #include "EventHandler.h"
51 #include "mailbox.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 "dyn_thread.h"
59 #include "miniTramp.h"
60
61 #include "mapped_module.h"
62
63 #include "BPatch_libInfo.h"
64 #include "BPatch_asyncEventHandler.h"
65 #include "BPatch.h"
66 #include "BPatch_thread.h"
67 #include "LineInformation.h"
68 #include "BPatch_function.h"
69 #include "callbacks.h"
70
71
72 /*
73  * class OneTimeCodeInfo
74  *
75  * This is used by the oneTimeCode (inferiorRPC) mechanism to keep per-RPC
76  * information.
77  */
78 class OneTimeCodeInfo {
79    bool synchronous;
80    bool completed;
81    void *userData;
82    void *returnValue;
83 public:
84    OneTimeCodeInfo(bool _synchronous, void *_userData) :
85       synchronous(_synchronous), completed(false), userData(_userData) { };
86
87    bool isSynchronous() { return synchronous; }
88
89    bool isCompleted() const { return completed; }
90    void setCompleted(bool _completed) { completed = _completed; }
91
92    void *getUserData() { return userData; }
93
94    void setReturnValue(void *_returnValue) { returnValue = _returnValue; }
95    void *getReturnValue() { return returnValue; }
96 };
97
98
99 /*
100  * BPatch_process::getImage
101  *
102  * Return the BPatch_image this object.
103  */
104 BPatch_image *BPatch_process::getImageInt()
105 {
106    return image;
107 }
108
109 /*
110  * BPatch_process::getPid
111  *
112  * Return the process ID of the thread associated with this object.
113  */
114 int BPatch_process::getPidInt()
115 {
116    return llproc ? (llproc->sh ? llproc->getPid()  : -1 ) : -1;
117 }
118
119 /*
120  * BPatch_process::BPatch_process
121  *
122  * Starts a new process and associates it with the BPatch_process being
123  * constructed.  The new process is placed into a stopped state before
124  * executing any code.
125  *
126  * path         Pathname of the executable to start.
127  * argv         A list of pointers to character strings which are the
128  *              arguments for the new process, terminated by a NULL pointer.
129  * envp         A list of pointers to character strings which are the
130  *              environment variables for the new process, terminated by a
131  *              NULL pointer.  If NULL, the default environment will be used.
132  */
133 BPatch_process::BPatch_process(const char *path, const char *argv[], const char **envp,
134                                int stdin_fd, int stdout_fd, int stderr_fd)
135    : llproc(NULL), image(NULL), lastSignal(-1), exitCode(-1), 
136      exitedNormally(false), exitedViaSignal(false), mutationsActive(true), 
137      createdViaAttach(false), detached(false), unreportedStop(false), 
138      unreportedTermination(false), pendingInsertions(NULL)
139 {
140    func_map = new BPatch_funcMap();
141    instp_map = new BPatch_instpMap();
142
143    pdvector<pdstring> argv_vec;
144    pdvector<pdstring> envp_vec;
145    // Contruct a vector out of the contents of argv
146    if (argv) {
147       for(int i = 0; argv[i] != NULL; i++)
148          argv_vec.push_back(argv[i]);
149    }
150     
151    // Construct a vector out of the contents of envp
152    if(envp) {
153       for(int i = 0; envp[i] != NULL; ++i)
154          envp_vec.push_back(envp[i]);
155    }
156    
157    pdstring directoryName = "";
158
159 #if !defined(os_windows)
160    // this fixes a problem on linux and alpha platforms where pathless
161    // filenames are searched for either in a standard, predefined path, or
162    // in $PATH by execvp.  thus paths that should resolve to "./" are
163    // missed.  Note that the previous use of getcwd() here for the alpha
164    // platform was dangerous since this is an API and we don't know where
165    // the user's code will leave the cwd pointing.
166    const char *dotslash = "./";
167    if (NULL == strchr(path, '/'))
168       directoryName = dotslash;
169 #endif
170
171    llproc = ll_createProcess(path, &argv_vec, (envp ? &envp_vec : NULL), 
172                            directoryName, stdin_fd, stdout_fd, stderr_fd);
173    if (llproc == NULL) { 
174       fprintf(stderr, "%s[%d][%s]: ll_createProcess failed\n", __FILE__, __LINE__, getThreadStr(getExecThreadID()));
175       BPatch::bpatch->reportError(BPatchFatal, 68, 
176            "Dyninst was unable to create the specified process");
177       return;
178    }
179    
180    llproc->registerFunctionCallback(createBPFuncCB);
181    llproc->registerInstPointCallback(createBPPointCB);
182
183    // Add this object to the list of processes
184    assert(BPatch::bpatch != NULL);
185    BPatch::bpatch->registerProcess(this);
186
187    // Create an initial thread
188    dyn_thread *dynthr = llproc->getInitialThread();
189    BPatch_thread *initial_thread = new BPatch_thread(this, dynthr);
190    threads.push_back(initial_thread);
191
192    image = new BPatch_image(this);
193
194    assert(llproc->isBootstrappedYet());
195
196    // Let's try to profile memory usage
197 #if defined(PROFILE_MEM_USAGE)
198    void *mem_usage = sbrk(0);
199    fprintf(stderr, "Post BPatch_process: sbrk %p\n", mem_usage);
200 #endif
201
202    isVisiblyStopped = true;
203 }
204
205 /*
206  * BPatch_process::BPatch_process
207  *
208  * Constructs a new BPatch_process and associates it with a running process.
209  * Stops execution of the process.
210  *
211  * path         Pathname of the executable file for the process.
212  * pid          Process ID of the target process.
213  */
214 BPatch_process::BPatch_process(const char *path, int pid)
215    : llproc(NULL), image(NULL), lastSignal(-1), exitCode(-1), 
216      exitedNormally(false), exitedViaSignal(false), mutationsActive(true), 
217      createdViaAttach(true), detached(false), unreportedStop(false), 
218      unreportedTermination(false), pendingInsertions(NULL)
219 {
220    func_map = new BPatch_funcMap();
221    instp_map = new BPatch_instpMap();
222
223    // Add this object to the list of threads
224    assert(BPatch::bpatch != NULL);
225    BPatch::bpatch->registerProcess(this, pid);
226
227    image = new BPatch_image(this);
228
229    llproc = ll_attachProcess(path, pid);
230    if (!llproc) {
231       BPatch::bpatch->unRegisterProcess(pid);
232       BPatch::bpatch->reportError(BPatchFatal, 68, 
233              "Dyninst was unable to attach to the specified process");
234       return;
235    }
236
237    // Create an initial thread
238    dyn_thread *dynthr = llproc->getInitialThread();
239    BPatch_thread *initial_thread = new BPatch_thread(this, dynthr);
240    threads.push_back(initial_thread);
241
242    llproc->registerFunctionCallback(createBPFuncCB);
243    llproc->registerInstPointCallback(createBPPointCB);
244
245    assert(llproc->isBootstrappedYet());
246    assert(llproc->status() == stopped);
247
248    isVisiblyStopped = true;
249 }
250
251 /*
252  * BPatch_process::BPatch_process
253  *
254  * Constructs a new BPatch_process and associates it with a forked process.
255  *
256  * parentPid          Pathname of the executable file for the process.
257  * childPid           Process ID of the target process.
258  */
259 BPatch_process::BPatch_process(process *nProc)
260    : llproc(nProc), image(NULL), lastSignal(-1), exitCode(-1),
261      exitedNormally(false), exitedViaSignal(false), mutationsActive(true), 
262      createdViaAttach(true), detached(false),
263      unreportedStop(false), unreportedTermination(false), 
264      pendingInsertions(NULL)
265 {
266    // Add this object to the list of threads
267    assert(BPatch::bpatch != NULL);
268    BPatch::bpatch->registerProcess(this);
269
270    func_map = new BPatch_funcMap();
271    instp_map = new BPatch_instpMap();
272
273    // Create an initial thread
274    dyn_thread *dynthr = llproc->getInitialThread();
275    BPatch_thread *initial_thread = new BPatch_thread(this, dynthr);
276    threads.push_back(initial_thread);
277
278    llproc->registerFunctionCallback(createBPFuncCB);
279    llproc->registerInstPointCallback(createBPPointCB);
280
281    image = new BPatch_image(this);
282
283    isVisiblyStopped = true;
284 }
285
286 /*
287  * BPatch_process::~BPatch_process
288  *
289  * Destructor for BPatch_process.  Detaches from the running thread.
290  */
291 void BPatch_process::BPatch_process_dtor()
292 {
293    if (!detached &&
294        !getAsync()->detachFromProcess(this)) {
295       bperr("%s[%d]:  trouble decoupling async event handler for process %d\n",
296             __FILE__, __LINE__, getPid());
297    }
298
299    for (int i=threads.size()-1; i>=0; i--)
300    {
301       deleteBPThread(threads[i]);
302    }
303
304    if (image) 
305       delete image;
306    
307    image = NULL;
308
309    if (func_map)
310       delete func_map;
311    func_map = NULL;
312    if (instp_map)
313       delete instp_map;
314    instp_map = NULL;
315
316    if (pendingInsertions) {
317        for (unsigned f = 0; f < pendingInsertions->size(); f++) {
318            delete (*pendingInsertions)[f];
319        }
320        delete pendingInsertions;
321        pendingInsertions = NULL;
322    }
323
324    if (!llproc) { 
325       return; 
326    }
327
328    //  unRegister process before doing detach
329    BPatch::bpatch->unRegisterProcess(getPid());   
330
331    /**
332     * If we attached to the process, then we detach and leave it be,
333     * otherwise we'll terminate it
334     **/
335    if (createdViaAttach) {
336       llproc->detachProcess(true);
337    }else  {
338       if (llproc->isAttached()) {
339         proccontrol_printf("%s[%d]:  about to terminate execution\n", __FILE__, __LINE__);
340         terminateExecutionInt();
341       }
342    }
343
344    delete llproc;
345    llproc = NULL;
346    assert(BPatch::bpatch != NULL);
347 }
348
349
350 /*
351  * BPatch_process::stopExecution
352  *
353  * Puts the thread into the stopped state.
354  */
355 bool BPatch_process::stopExecutionInt()
356 {
357     if (llproc->pause()) {
358         isVisiblyStopped = true;
359         return true;
360     }
361     else
362         return false;
363 }
364
365 /*
366  * BPatch_process::continueExecution
367  *
368  * Puts the thread into the running state.
369  */
370 bool BPatch_process::continueExecutionInt()
371 {
372    getMailbox()->executeCallbacks(FILE__, __LINE__);
373
374    //  maybe executeCallbacks led to the process execution status changing
375    if (!statusIsStopped()) {
376      fprintf(stderr, "%s[%d]:  status change during continue execution, status is now %s\n",
377              FILE__, __LINE__, llproc->getStatusAsString().c_str());
378      isVisiblyStopped = false;
379      return true;
380    }
381
382    //  DON'T let the user continue the process if we have potentially active 
383    //  signal handling going on:
384    while (llproc->sh->activeHandlerForProcess(llproc)) {
385        signal_printf("%s[%d]:  waiting before doing user continue for process %d\n", FILE__, __LINE__, llproc->getPid());
386        llproc->sh->waitForEvent(evtAnyEvent);
387    }
388
389    getMailbox()->executeCallbacks(FILE__, __LINE__);
390
391    if (!statusIsStopped()) {
392      fprintf(stderr, "%s[%d]:  status change during continue execution, status is now %s\n",
393              FILE__, __LINE__, llproc->getStatusAsString().c_str());
394      isVisiblyStopped = false;
395      return true;
396    }
397
398    if (llproc->continueProc()) {
399       setUnreportedStop(false);
400       isVisiblyStopped = false;
401       return true;
402    }
403
404    fprintf(stderr, "%s[%d]:  failed to continueProc, status is %s\n", 
405            FILE__, __LINE__, llproc->getStatusAsString().c_str());
406    return false;
407 }
408
409
410 /*
411  * BPatch_process::terminateExecution
412  *
413  * Kill the thread.
414  */
415 bool BPatch_process::terminateExecutionInt()
416 {
417    proccontrol_printf("%s[%d]:  about to terminate proc\n", FILE__, __LINE__);
418    if (!llproc || !llproc->terminateProc())
419       return false;
420    while (!isTerminated()) {
421        BPatch::bpatch->waitForStatusChange();
422    }
423    
424    return true;
425 }
426
427 /*
428  * BPatch_process::statusIsStopped
429  *
430  * Returns true if the thread is stopped, and false if it is not.
431  */
432 bool BPatch_process::statusIsStopped()
433 {
434    return llproc->status() == stopped;
435 }
436
437 /*
438  * BPatch_process::isStopped
439  *
440  * Returns true if the thread has stopped, and false if it has not.  This may
441  * involve checking for thread events that may have recently changed this
442  * thread's status.  This function also updates the unreportedStop flag if a
443  * stop is detected, in order to indicate that the stop has been reported to
444  * the user.
445  */
446 bool BPatch_process::isStoppedInt()
447 {
448     return isVisiblyStopped;
449
450 #if 0
451
452    assert(BPatch::bpatch);
453    if (statusIsStopped()) {
454       //  if there are signal handler threads that are acting on this process
455       //  that are not idle, we may not really be stopped from the end-user
456       //  perspective (ie a continue might be imminent).
457       if (llproc->sh->activeHandlerForProcess(llproc)) {
458         signal_printf("%s[%d]:  pending events for proc %d, assuming still running\n",
459                       FILE__, __LINE__, llproc->getPid());
460         return false;
461       }
462       setUnreportedStop(false);
463       return true;
464    }
465    
466
467    return false;
468 #endif
469 }
470
471 /*
472  * BPatch_process::stopSignal
473  *
474  * Returns the number of the signal which caused the thread to stop.
475  */
476 int BPatch_process::stopSignalInt()
477 {
478    if (llproc->status() != neonatal && llproc->status() != stopped) {
479       fprintf(stderr, "%s[%d]:  request for stopSignal when process is %s\n",
480               FILE__, __LINE__, llproc->getStatusAsString().c_str());
481       return -1;
482    } else
483       return lastSignal;
484 }
485
486 /*
487  * BPatch_process::statusIsTerminated
488  *
489  * Returns true if the process has terminated, false if it has not.
490  */
491 bool BPatch_process::statusIsTerminated()
492 {
493    if (llproc == NULL) {
494      fprintf(stderr, "%s[%d]:  status is terminated becuase llproc is NULL\n", 
495              FILE__, __LINE__);
496      return true;
497    }
498    return llproc->status() == exited;
499 }
500
501 /*
502  * BPatch_process::isTerminated
503  *
504  * Returns true if the thread has terminated, and false if it has not.  This
505  * may involve checking for thread events that may have recently changed this
506  * thread's status.  This function also updates the unreportedTermination flag
507  * if the program terminated, in order to indicate that the termination has
508  * been reported to the user.
509  */
510 bool BPatch_process::isTerminatedInt()
511 {
512    getMailbox()->executeCallbacks(FILE__, __LINE__);
513    // First see if we've already terminated to avoid 
514    // checking process status too often.
515    if (statusIsTerminated()) {
516       proccontrol_printf("%s[%d]:  about to terminate proc\n", FILE__, __LINE__); 
517       llproc->terminateProc();
518       setUnreportedTermination(false);
519       return true;
520    }
521
522    // Check for status changes.
523    assert(BPatch::bpatch);
524    
525    // Check again
526    if (statusIsTerminated()) {
527       proccontrol_printf("%s[%d]:  about to terminate proc\n", FILE__, __LINE__);
528       llproc->terminateProc();
529       setUnreportedTermination(false);
530       return true;
531    } else {
532       return false;
533    }
534 }
535
536 /*
537  * BPatch_process::terminationStatus
538  *
539  * Indicates how the program exited.  Returns one of NoExit, ExitedNormally,
540  * or ExitedViaSignal.
541  *
542  */
543 BPatch_exitType BPatch_process::terminationStatusInt() {
544    if(exitedNormally)
545       return ExitedNormally;
546    else if(exitedViaSignal)
547       return ExitedViaSignal;   
548    return NoExit;
549 }
550
551 /*
552  * BPatch_process::getExitCode
553  *
554  * Returns exit code of applications
555  *
556  */
557 int BPatch_process::getExitCodeInt() 
558 {
559    return exitCode;
560 }
561
562 /*
563  * BPatch_process::getExitSignal
564  *
565  * Returns signal number that caused application to exit.
566  *
567  */
568 int BPatch_process::getExitSignalInt()
569 {
570    return lastSignal;
571 }
572
573 /*
574  * BPatch_process::detach
575  *
576  * Detach from the thread represented by this object.
577  *
578  * cont         True if the thread should be continued as the result of the
579  *              detach, false if it should not.
580  */
581 bool BPatch_process::detachInt(bool cont)
582 {
583    //__UNLOCK;
584    if (!getAsync()->detachFromProcess(this)) {
585       bperr("%s[%d]:  trouble decoupling async event handler for process %d\n",
586             __FILE__, __LINE__, getPid());
587    }
588   // __LOCK;
589    fprintf(stderr, "%s[%d]:  about to detach process\n", FILE__, __LINE__);
590    detached = llproc->detachProcess(cont);
591    return detached;
592 }
593
594 /*
595  * BPatch_process::isDetaced
596  *
597  * Returns whether dyninstAPI is detached from this mutatee
598  *
599  */
600 bool BPatch_process::isDetachedInt()
601 {
602    return detached;
603 }
604
605 /*
606  * BPatch_process::dumpCore
607  *
608  * Causes the process to dump its state to a file, and optionally to terminate.
609  * Returns true upon success, and false upon failure.
610  *
611  * file         The name of the file to which the state should be written.
612  * terminate    Indicates whether or not the thread should be terminated after
613  *              dumping core.  True indicates that it should, false that is
614  *              should not.
615  */
616 bool BPatch_process::dumpCoreInt(const char *file, bool terminate)
617 {
618    bool had_unreportedStop = unreportedStop;
619    bool was_stopped = isStopped();
620
621    stopExecution();
622
623    bool ret = llproc->dumpCore(file);
624    if (ret && terminate) {
625       fprintf(stderr, "%s[%d]:  about to terminate execution\n", __FILE__, __LINE__);
626       terminateExecutionInt();
627    } else if (was_stopped) {
628         unreportedStop = had_unreportedStop;
629    } else {
630       continueExecutionInt();
631    }
632     
633    return ret;
634 }
635
636 /*
637  * BPatch_process::dumpPatchedImage
638  *
639  * Writes the mutated file back to disk,
640  * in ELF format.
641  */
642 #if defined(os_solaris) || (defined(os_linux) && defined(arch_x86)) || defined(os_aix)
643 char* BPatch_process::dumpPatchedImageInt(const char* file)
644 {
645    bool was_stopped = isStopped();
646    bool had_unreportedStop = unreportedStop;
647    
648    stopExecution();
649    char* ret = llproc->dumpPatchedImage(file);
650    if (was_stopped) 
651       unreportedStop = had_unreportedStop;
652    else 
653       continueExecutionInt();
654
655    return ret;
656    return NULL;
657 }
658 #else
659 char* BPatch_process::dumpPatchedImageInt(const char*)
660 {
661    return NULL;
662 }
663 #endif
664
665 /*
666  * BPatch_process::dumpImage
667  *
668  * Writes the contents of memory into a file.
669  * Returns true upon success, and false upon failure.
670  *
671  * file         The name of the file to which the image should be written.
672  */
673 bool BPatch_process::dumpImageInt(const char *file)
674 {
675 #if defined(os_windows)
676    return false;
677 #else
678    bool was_stopped;
679    bool had_unreportedStop = unreportedStop;
680    if (isStopped()) was_stopped = true;
681    else was_stopped = false;
682
683    stopExecutionInt();
684
685    bool ret = llproc->dumpImage(file);
686    if (was_stopped) 
687       unreportedStop = had_unreportedStop;
688    else 
689       continueExecutionInt();
690
691    return ret;
692 #endif
693 }
694
695 /*
696  * BPatch_process::malloc
697  *
698  * Allocate memory in the thread's address space.
699  *
700  * n    The number of bytes to allocate.
701  *
702  * Returns:
703  *      A pointer to a BPatch_variableExpr representing the memory.
704  *
705  */
706 BPatch_variableExpr *BPatch_process::mallocInt(int n)
707 {
708    assert(BPatch::bpatch != NULL);
709    void *ptr = (void *) llproc->inferiorMalloc(n, dataHeap);
710    if (!ptr) return NULL;
711    return new BPatch_variableExpr(this, ptr, Null_Register, 
712                                   BPatch::bpatch->type_Untyped);
713 }
714
715
716 /*
717  * BPatch_process::malloc
718  *
719  * Allocate memory in the thread's address space for a variable of the given
720  * type.
721  *
722  * type         The type of variable for which to allocate space.
723  *
724  * Returns:
725  *      A pointer to a BPatch_variableExpr representing the memory.
726  *
727  * XXX Should return NULL on failure, but the function which it calls,
728  *     inferiorMalloc, calls exit rather than returning an error, so this
729  *     is not currently possible.
730  */
731 BPatch_variableExpr *BPatch_process::mallocByType(const BPatch_type &type)
732 {
733    assert(BPatch::bpatch != NULL);
734    BPatch_type &t = const_cast<BPatch_type &>(type);
735    void *mem = (void *)llproc->inferiorMalloc(t.getSize(), dataHeap);
736    if (!mem) return NULL;
737    return new BPatch_variableExpr(this, mem, Null_Register, &t);
738 }
739
740
741 /*
742  * BPatch_process::free
743  *
744  * Free memory that was allocated with BPatch_process::malloc.
745  *
746  * ptr          A BPatch_variableExpr representing the memory to free.
747  */
748 bool BPatch_process::freeInt(BPatch_variableExpr &ptr)
749 {
750    llproc->inferiorFree((Address)ptr.getBaseAddr());
751    return true;
752 }
753
754 /*
755  * BPatch_process::getInheritedVariable
756  *
757  * Allows one to retrieve a variable which exists in a child process that 
758  * was inherited from and originally created in the parent process.
759  * Function is invoked on the child BPatch_process (created from a fork in 
760  * the application).
761  *
762  * parentVar   A BPatch_variableExpr created in the parent thread
763  *
764  * Returns:    The corresponding BPatch_variableExpr from the child thread
765  *             or NULL if the variable argument hasn't been malloced
766  *             in a parent process.
767  */
768 BPatch_variableExpr *BPatch_process::getInheritedVariableInt(
769                                                              BPatch_variableExpr &parentVar)
770 {
771    if(! isInferiorAllocated(llproc, (Address)parentVar.getBaseAddr())) {
772       // isn't defined in this process so must not have been defined in a
773       // parent process
774       return NULL;
775    }
776    return new BPatch_variableExpr(this, parentVar.getBaseAddr(), Null_Register,
777                                   const_cast<BPatch_type *>(parentVar.getType()));
778 }
779
780
781 /*
782  * BPatch_process::getInheritedSnippet
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_process (created from a fork in 
787  * the application).
788  *
789  * Allows one to retrieve a snippet which exists in a child process which
790  * was inherited from and originally created in the parent process.
791  * Function is invoked on the child BPatch_process (created from a fork in
792  * the application).
793  *
794  * parentSnippet: A BPatchSnippetHandle created in the parent thread
795  *
796  * Returns:       The corresponding BPatchSnippetHandle from the child thread.
797  *
798  */
799 BPatchSnippetHandle *BPatch_process::getInheritedSnippetInt(BPatchSnippetHandle &parentSnippet)
800 {
801     // a BPatchSnippetHandle has an miniTramp for each point that
802     // the instrumentation is inserted at
803     const BPatch_Vector<miniTramp *> &parent_mtHandles = parentSnippet.mtHandles_;
804
805     BPatchSnippetHandle *childSnippet = new BPatchSnippetHandle(this);
806     for(unsigned i=0; i<parent_mtHandles.size(); i++) {
807         miniTramp *childMT = NULL;
808         if(!getInheritedMiniTramp(parent_mtHandles[i], childMT, llproc)) {
809             fprintf(stderr, "Failed to get inherited mini tramp\n");
810             return NULL;
811         }
812         childSnippet->addMiniTramp(childMT);
813     }
814     return childSnippet;
815 }
816
817 /*
818  * BPatch_process::insertSnippet
819  *
820  * Insert a code snippet at a given instrumentation point.  Upon success,
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_process::insertSnippetInt(const BPatch_snippet &expr, 
828                                                       BPatch_point &point, 
829                                                       BPatch_snippetOrder order)
830 {
831    BPatch_callWhen when;
832    if (point.getPointType() == BPatch_exit)
833       when = BPatch_callAfter;
834    else
835       when = BPatch_callBefore;
836
837    return insertSnippetWhen(expr, point, when, order);
838 }
839
840 /*
841  * BPatch_process::insertSnippet
842  *
843  * Insert a code snippet at a given instrumentation point.  Upon succes,
844  * returns a handle to the created instance of the snippet, which can be used
845  * to delete it.  Otherwise returns NULL.
846  *
847  * expr         The snippet to insert.
848  * point        The point at which to insert it.
849  */
850 // This handles conversion without requiring inst.h in a header file...
851 extern bool BPatchToInternalArgs(BPatch_point *point,
852                                  BPatch_callWhen when,
853                                  BPatch_snippetOrder order,
854                                  callWhen &ipWhen,
855                                  callOrder &ipOrder);
856                            
857
858 BPatchSnippetHandle *BPatch_process::insertSnippetWhen(const BPatch_snippet &expr,
859                                                        BPatch_point &point,
860                                                        BPatch_callWhen when,
861                                                        BPatch_snippetOrder order)
862 {
863   BPatch_Vector<BPatch_point *> points;
864   points.push_back(&point);
865   return insertSnippetAtPointsWhen(expr,
866                                    points,
867                                    when,
868                                    order);
869  
870 }
871
872 /*
873  * BPatch_process::insertSnippet
874  *
875  * Insert a code snippet at each of a list of instrumentation points.  Upon
876  * success, Returns a handle to the created instances of the snippet, which
877  * can be used to delete them (as a unit).  Otherwise returns NULL.
878  *
879  * expr         The snippet to insert.
880  * points       The list of points at which to insert it.
881  */
882 // A lot duplicated from the single-point version. This is unfortunate.
883
884 BPatchSnippetHandle *BPatch_process::insertSnippetAtPointsWhen(const BPatch_snippet &expr,
885                                                                const BPatch_Vector<BPatch_point *> &points,
886                                                                BPatch_callWhen when,
887                                                                BPatch_snippetOrder order)
888 {
889     if (BPatch::bpatch->isTypeChecked()) {
890         assert(expr.ast);
891         if (expr.ast->checkType() == BPatch::bpatch->type_Error) {
892             return false;
893         }
894     }
895     
896     
897     batchInsertionRecord *rec = new batchInsertionRecord;
898     rec->thread_ = NULL;
899     rec->ast_ = expr.ast;
900     rec->trampRecursive_ = BPatch::bpatch->isTrampRecursive();
901
902     BPatchSnippetHandle *ret = new BPatchSnippetHandle(this);
903     rec->handle_ = ret;
904     
905     for (unsigned i = 0; i < points.size(); i++) {
906         BPatch_point *point = points[i];
907         
908 #if defined(os_aix)
909         if(llproc->collectSaveWorldData){
910             // Apparently we have problems with main....
911             // The things I do to not grab the name as a strcopy operation...
912           if (point->getFunction()->lowlevel_func()->symTabName().c_str() == "main") {
913                 rec->trampRecursive_ = true;
914             }
915         }
916
917 #endif
918
919 #if defined(os_aix) || defined(arch_x86_64)
920         // Toss the const; the function _pointer_ doesn't though.
921         BPatch_function *func = (BPatch_function *) point->getFunction();
922         func->calc_liveness(point);
923 #endif 
924         
925         callWhen ipWhen;
926         callOrder ipOrder;
927         
928         if (!BPatchToInternalArgs(point, when, order, ipWhen, ipOrder)) {
929             return NULL;
930         }
931
932         rec->points_.push_back(point->point);
933         rec->when_.push_back(ipWhen);
934         rec->order_ = ipOrder;
935
936         point->recordSnippet(when, order, ret);
937     }
938
939     assert(rec->points_.size() == rec->when_.size());
940
941     // Okey dokey... now see if we just tack it on, or insert now.
942     if (pendingInsertions) {
943         pendingInsertions->push_back(rec);
944     }
945     else {
946         beginInsertionSetInt();
947         pendingInsertions->push_back(rec);
948         // All the insertion work was moved here...
949         finalizeInsertionSetInt(false);
950     }
951     return ret;
952 }
953
954 /*
955  * BPatch_process::insertSnippet
956  *
957  * Insert a code snippet at each of a list of instrumentation points.  Upon
958  * success, Returns a handle to the created instances of the snippet, which
959  * can be used to delete them (as a unit).  Otherwise returns NULL.
960  *
961  * expr         The snippet to insert.
962  * points       The list of points at which to insert it.
963  */
964 BPatchSnippetHandle *BPatch_process::insertSnippetAtPoints(
965                  const BPatch_snippet &expr,
966                  const BPatch_Vector<BPatch_point *> &points,
967                  BPatch_snippetOrder order)
968 {
969     return insertSnippetAtPointsWhen(expr,
970                                      points,
971                                      BPatch_callUnset,
972                                      order);
973 }
974
975
976 /*
977  * BPatch_process::beginInsertionSet
978  * 
979  * Starts a batch insertion set; that is, all calls to insertSnippet until
980  * finalizeInsertionSet are delayed.
981  *
982  */
983
984 void BPatch_process::beginInsertionSetInt() {
985     if (pendingInsertions == NULL)
986         pendingInsertions = new BPatch_Vector<batchInsertionRecord *>;
987     // Nothing else to do...
988 }
989
990 /*
991  * BPatch_process::finalizeInsertionSet
992  * 
993  * Installs all instrumentation specified since the last beginInsertionSet call.
994  *
995  */
996
997 bool BPatch_process::finalizeInsertionSetInt(bool atomic) {
998     // Can't insert code when mutations are not active.
999     if (!mutationsActive)
1000         return false;
1001     
1002     unsigned i, j;
1003
1004     pdvector<miniTramp *> workDone;
1005     bool err = false;
1006
1007     if (pendingInsertions == NULL)
1008         return false;
1009
1010     // Two loops: first addInst, then generate/install/link
1011
1012     for (i = 0; i < pendingInsertions->size(); i++) {
1013         batchInsertionRecord *&bir = (*pendingInsertions)[i];
1014         assert(bir);
1015
1016         // Don't handle thread inst yet...
1017         assert(!bir->thread_);
1018
1019         for (j = 0; j < bir->points_.size(); j++) {
1020             instPoint *point = bir->points_[j];
1021             callWhen when = bir->when_[j];
1022             
1023             miniTramp *mini = point->addInst(bir->ast_,
1024                                              when,
1025                                              bir->order_,
1026                                              bir->trampRecursive_,
1027                                              false);
1028             if (mini) {
1029                 workDone.push_back(mini);
1030                 // Add to snippet handle
1031                 bir->handle_->addMiniTramp(mini);
1032             }
1033             else {
1034                 fprintf(stderr, "ERROR: failed to insert instrumentation: no minitramp\n");
1035                 err = true;
1036                 if (atomic) break;
1037             }
1038         }
1039         if (atomic && err)
1040             break;
1041     }
1042     
1043     if (!atomic || !err) {
1044         // All generation first. Actually, all generation per function...
1045         // but this is close enough.
1046         for (i = 0; i < pendingInsertions->size(); i++) {
1047             batchInsertionRecord *&bir = (*pendingInsertions)[i];
1048             assert(bir);
1049             for (unsigned j = 0; j < bir->points_.size(); j++) {
1050                 instPoint *point = bir->points_[j];
1051                 
1052                 if (!point->generateInst()) {
1053                     fprintf(stderr, "ERROR: failed to insert instrumentation: generate\n");
1054                     err = true;
1055                     if (atomic && err) break;
1056                 }
1057             }
1058             if (atomic && err) break;
1059         }
1060         for (i = 0; i < pendingInsertions->size(); i++) {
1061             batchInsertionRecord *&bir = (*pendingInsertions)[i];
1062             assert(bir);
1063             for (unsigned j = 0; j < bir->points_.size(); j++) {
1064                 instPoint *point = bir->points_[j];
1065                 
1066                 if (!point->installInst()) {
1067                     fprintf(stderr, "ERROR: failed to insert instrumentation: install\n");
1068                     err = true;
1069                 }
1070                 if (!point->linkInst()) {
1071                     err = true;
1072                 }
1073                 if (atomic && err) break;
1074             }
1075             if (atomic && err) break;
1076             else delete bir;
1077         }
1078     }
1079     if (atomic && err) {
1080         // Cleanup...
1081         for (unsigned k = 0; k < workDone.size(); k++) {
1082             workDone[k]->uninstrument();
1083         }
1084         return false;
1085     }
1086
1087     delete pendingInsertions;
1088     pendingInsertions = NULL;
1089     return true;
1090 }
1091
1092 /*
1093  * BPatch_process::deleteSnippet
1094  * 
1095  * Deletes an instance of a snippet.
1096  *
1097  * handle       The handle returned by insertSnippet when the instance to
1098  *              deleted was created.
1099  */
1100 bool BPatch_process::deleteSnippetInt(BPatchSnippetHandle *handle)
1101 {   
1102     if (handle->proc_ == this) {
1103         for (unsigned int i=0; i < handle->mtHandles_.size(); i++)
1104             handle->mtHandles_[i]->uninstrument();
1105         delete handle;
1106         return true;
1107     } 
1108     // Handle isn't to a snippet instance in this process
1109     cerr << "Error: wrong process in deleteSnippet" << endl;     
1110     return false;
1111 }
1112
1113
1114 /*
1115  * BPatch_process::setMutationsActive
1116  *
1117  * Enable or disable the execution of all snippets for the thread.
1118  * 
1119  * activate     If set to true, execution of snippets is enabled.  If false,
1120  *              execution is disabled.
1121  */
1122 #ifdef BPATCH_SET_MUTATIONS_ACTIVE
1123 bool BPatch_process::setMutationsActiveInt(bool activate)
1124 {
1125    // If not activating or deactivating, just return.
1126    if ((activate && mutationsActive) || (!activate && !mutationsActive))
1127       return true;
1128    
1129    if (activate)
1130       llproc->reinstallMutations();
1131    else
1132       llproc->uninstallMutations();
1133    
1134    mutationsActive = activate;
1135    return true;
1136 }
1137 #else
1138 bool BPatch_process::setMutationsActiveInt(bool) { return true; }
1139 #endif
1140
1141 /*
1142  * BPatch_process::replaceFunctionCall
1143  *
1144  * Replace a function call with a call to a different function.  Returns true
1145  * upon success, false upon failure.
1146  * 
1147  * point        The call site that is to be changed.
1148  * newFunc      The function that the call site will now call.
1149  */
1150 bool BPatch_process::replaceFunctionCallInt(BPatch_point &point,
1151                                             BPatch_function &newFunc)
1152 {
1153    // Can't make changes to code when mutations are not active.
1154    if (!mutationsActive)
1155       return false;
1156    assert(point.point && newFunc.lowlevel_func());
1157    return llproc->replaceFunctionCall(point.point, newFunc.lowlevel_func());
1158 }
1159
1160 /*
1161  * BPatch_process::removeFunctionCall
1162  *
1163  * Replace a function call with a NOOP.  Returns true upon success, false upon
1164  * failure.
1165  * 
1166  * point        The call site that is to be NOOPed out.
1167  */
1168 bool BPatch_process::removeFunctionCallInt(BPatch_point &point)
1169 {
1170    // Can't make changes to code when mutations are not active.
1171    if (!mutationsActive)
1172       return false;   
1173    assert(point.point);
1174    return llproc->replaceFunctionCall(point.point, NULL);
1175 }
1176
1177
1178 /*
1179  * BPatch_process::replaceFunction
1180  *
1181  * Replace all calls to function OLDFUNC with calls to NEWFUNC.
1182  * Returns true upon success, false upon failure.
1183  * 
1184  * oldFunc      The function to replace
1185  * newFunc      The replacement function
1186  */
1187 bool BPatch_process::replaceFunctionInt(BPatch_function &oldFunc,
1188                                         BPatch_function &newFunc)
1189 {
1190 #if defined(os_solaris) || defined(os_osf) || defined(os_linux) || \
1191     defined(os_windows) \
1192
1193     assert(oldFunc.lowlevel_func() && newFunc.lowlevel_func());
1194     if (!mutationsActive)
1195         return false;
1196     
1197     // Self replacement is a nop
1198     // We should just test direct equivalence here...
1199     if (oldFunc.lowlevel_func() == newFunc.lowlevel_func()) {
1200         return true;
1201     }
1202
1203    bool old_recursion_flag = BPatch::bpatch->isTrampRecursive();
1204    BPatch::bpatch->setTrampRecursive( true );
1205    
1206    // We replace functions by instrumenting the entry of OLDFUNC with
1207    // a non-linking jump to NEWFUNC.  Calls to OLDFUNC do actually
1208    // transfer to OLDFUNC, but then our jump shunts them to NEWFUNC.
1209    // The non-linking jump ensures that when NEWFUNC returns, it
1210    // returns directly to the caller of OLDFUNC.
1211    BPatch_Vector<BPatch_point *> *pts = oldFunc.findPoint(BPatch_entry);
1212    if (! pts || ! pts->size())
1213       return false;
1214    BPatch_funcJumpExpr fje(newFunc);
1215    BPatchSnippetHandle * result = insertSnippetAtPointsWhen(fje, *pts, BPatch_callBefore);
1216    
1217    BPatch::bpatch->setTrampRecursive( old_recursion_flag );
1218    
1219    return (NULL != result);
1220 #else
1221    char msg[2048];
1222    char buf1[512], buf2[512];
1223    sprintf(msg, "cannot replace func %s with func %s, not implemented",
1224            oldFunc.getName(buf1, 512), newFunc.getName(buf2, 512));
1225     
1226    BPatch_reportError(BPatchSerious, 109, msg);
1227    BPatch_reportError(BPatchSerious, 109,
1228                       "replaceFunction is not implemented on this platform");
1229    return false;
1230 #endif
1231 }
1232
1233 /*
1234  * BPatch_process::oneTimeCode
1235  *
1236  * execute argument <expr> once.
1237  *
1238  */
1239 void *BPatch_process::oneTimeCodeInt(const BPatch_snippet &expr)
1240 {
1241    return oneTimeCodeInternal(expr, NULL, true);
1242 }
1243
1244 /*
1245  * BPatch_process::oneTimeCodeCallbackDispatch
1246  *
1247  * This function is registered with the lower-level code as the callback for
1248  * inferior RPC completion.  It determines what thread the RPC was executed on
1249  * and then calls the API's higher-level callback routine for that thread.
1250  *
1251  * theProc      The process in which the RPC completed.
1252  * userData     This is a value that can be set when we invoke an inferior RPC
1253  *              and which will be returned to us in this callback.
1254  * returnValue  The value returned by the RPC.
1255  */
1256 void BPatch_process::oneTimeCodeCallbackDispatch(process *theProc,
1257                                                  unsigned /* rpcid */, 
1258                                                  void *userData,
1259                                                  void *returnValue)
1260 {
1261    assert(BPatch::bpatch != NULL);
1262    bool need_to_unlock = true;
1263    global_mutex->_Lock(FILE__, __LINE__);
1264    if (global_mutex->depth() > 1) {
1265      global_mutex->_Unlock(FILE__, __LINE__);
1266      need_to_unlock = false;
1267    }
1268
1269    assert(global_mutex->depth());
1270    
1271    OneTimeCodeInfo *info = (OneTimeCodeInfo *)userData;
1272    
1273    BPatch_process *bproc =
1274       BPatch::bpatch->getProcessByPid(theProc->getPid());
1275
1276    assert(bproc != NULL);
1277    assert(info && !info->isCompleted());
1278
1279    info->setReturnValue(returnValue);
1280    info->setCompleted(true);
1281    
1282    if (!info->isSynchronous()) {
1283       pdvector<CallbackBase *> cbs;
1284       getCBManager()->dispenseCallbacksMatching(evtOneTimeCode, cbs);
1285       for (unsigned int i = 0; i < cbs.size(); ++i) {
1286         OneTimeCodeCallback &cb = * ((OneTimeCodeCallback *) cbs[i]);
1287         cb.setTargetThread(TARGET_UI_THREAD);
1288         cb.setSynchronous(false);
1289         cb(bproc->threads[0], info->getUserData(), returnValue);
1290       }
1291
1292       delete info;
1293    }
1294
1295 #ifdef IBM_BPATCH_COMPAT
1296    pdvector<void *> *args2 = new pdvector<void *>;
1297    args2->push_back((void *)bproc);
1298    args2->push_back((void *)userData);
1299    args2->push_back((void *)returnValue);
1300
1301    pdvector<CallbackRecord *> cbs;
1302    if ( getCBManager()->dispenseCallbacksMatching(evtRPCSignal, cbs)) {
1303      for (unsigned int i = 0; i < cbs.size(); ++i) {
1304        if (!getMailbox()->executeOrRegisterCallback(cbs[i]->cb, args, NULL, cbs[i]->target_thread_id, __FILE__, __LINE__)) {
1305          fprintf(stderr, "%s[%d]: error registering callback\n", __FILE__, __LINE__);
1306        }
1307          fprintf(stderr, "%s[%d]:  registered/exec'd cb %p\n", __FILE__, __LINE__, (void*) cbs[i]->cb);
1308      }
1309    }
1310
1311 #endif
1312   if (need_to_unlock)
1313      global_mutex->_Unlock(FILE__, __LINE__);
1314 }
1315
1316 /*
1317  * BPatch_process::oneTimeCodeInternal
1318  *
1319  * Causes a snippet expression to be evaluated once in the mutatee at the next
1320  * available opportunity.  Optionally, Dyninst will call a callback function
1321  * when the snippet has executed in the mutatee, and can wait until the
1322  * snippet has executed to return.
1323  *
1324  * expr         The snippet to evaluate.
1325  * userData     This value is given to the callback function along with the
1326  *              return value for the snippet.  Can be used by the caller to
1327  *              store per-oneTimeCode information.
1328  * synchronous  True means wait until the snippet has executed, false means
1329  *              return immediately.
1330  */
1331 void *BPatch_process::oneTimeCodeInternal(const BPatch_snippet &expr,
1332                                           void *userData,
1333                                           bool synchronous)
1334 {
1335    bool needToResume = false;
1336    if (synchronous && !statusIsStopped()) {
1337       stopExecutionInt();
1338       
1339       if (!statusIsStopped()) {
1340          fprintf(stderr, "%s[%d]:  failed to run oneTimeCodeInternal .. status is %s\n", 
1341                  FILE__, __LINE__, 
1342                  llproc ? llproc->getStatusAsString().c_str() : "unavailable");
1343          return NULL;
1344       }
1345       needToResume = true;
1346    }
1347
1348    OneTimeCodeInfo *info = new OneTimeCodeInfo(synchronous, userData);
1349
1350    llproc->getRpcMgr()->postRPCtoDo(expr.ast,
1351                                     false, 
1352                                     BPatch_process::oneTimeCodeCallbackDispatch,
1353                                     (void *)info,
1354                                     false,
1355                                     NULL, NULL); 
1356     
1357    if (synchronous) {
1358       do {
1359         llproc->getRpcMgr()->launchRPCs(false);
1360         getMailbox()->executeCallbacks(FILE__, __LINE__);
1361         if (info->isCompleted()) break;
1362         llproc->sh->waitForEvent(evtRPCSignal, llproc, NULL /*lwp*/, statusRPCDone);
1363         getMailbox()->executeCallbacks(FILE__, __LINE__);
1364       } while (!info->isCompleted() && !statusIsTerminated());
1365       
1366       void *ret = info->getReturnValue();
1367       delete info;
1368
1369       if (needToResume) {
1370          continueExecutionInt();
1371       }
1372         
1373       return ret;
1374    } else {
1375       llproc->getRpcMgr()->launchRPCs(llproc->status() == running);
1376       return NULL;
1377    }
1378 }
1379
1380 //  BPatch_process::oneTimeCodeAsync
1381 //
1382 //  Have the specified code be executed by the mutatee once.  Don't wait 
1383 //  until done.
1384 bool BPatch_process::oneTimeCodeAsyncInt(const BPatch_snippet &expr, 
1385                                          void *userData)
1386 {
1387    bool ret;
1388    if (!(ret = oneTimeCodeInternal(expr, userData, false))) {
1389      //fprintf(stderr, "%s[%d]:  oneTimeCodeInternal failed\n", FILE__, __LINE__);
1390    }
1391    return ret;
1392 }
1393
1394 /*
1395  * BPatch_process::loadLibrary
1396  *
1397  * Load a dynamically linked library into the address space of the mutatee.
1398  *
1399  * libname      The name of the library to load.
1400  */
1401 #if defined(cap_save_the_world) && defined(BPATCH_LIBRARY)
1402 bool BPatch_process::loadLibraryInt(const char *libname, bool reload)
1403 #else
1404 bool BPatch_process::loadLibraryInt(const char *libname, bool)
1405 #endif
1406 {
1407    stopExecutionInt();
1408    if (!statusIsStopped()) {
1409       fprintf(stderr, "%s[%d]:  Process not stopped in loadLibrary\n", FILE__, __LINE__);
1410       return false;
1411    }
1412    
1413    /**
1414     * Find the DYNINSTloadLibrary function
1415     **/
1416    BPatch_Vector<BPatch_function *> bpfv;
1417    image->findFunction("DYNINSTloadLibrary", bpfv);
1418    if (!bpfv.size()) {
1419       cerr << __FILE__ << ":" << __LINE__ << ": FATAL:  Cannot find Internal"
1420            << "Function DYNINSTloadLibrary" << endl;
1421       return false;
1422    }
1423    if (bpfv.size() > 1) {
1424       pdstring msg = pdstring("Found ") + pdstring(bpfv.size()) + 
1425          pdstring("functions called DYNINSTloadLibrary -- not fatal but weird");
1426       BPatch_reportError(BPatchSerious, 100, msg.c_str());
1427    }
1428    BPatch_function *dlopen_func = bpfv[0]; 
1429    if (dlopen_func == NULL) return false;
1430
1431    /**
1432     * Generate a call to DYNINSTloadLibrary, and then run the generated code.
1433     **/
1434    BPatch_Vector<BPatch_snippet *> args;   
1435    BPatch_constExpr nameArg(libname);
1436    args.push_back(&nameArg);   
1437    BPatch_funcCallExpr call_dlopen(*dlopen_func, args);
1438     
1439    if (!oneTimeCodeInternal(call_dlopen, NULL, true)) {
1440       BPatch_variableExpr *dlerror_str_var = 
1441          image->findVariable("gLoadLibraryErrorString");
1442       assert(NULL != dlerror_str_var);      
1443       char dlerror_str[256];
1444       dlerror_str_var->readValue((void *)dlerror_str, 256);
1445       BPatch_reportError(BPatchSerious, 124, dlerror_str);
1446       return false;
1447    }
1448    BPatch_variableExpr *brk_ptr_var = 
1449       image->findVariable("gBRKptr");
1450    assert(NULL != brk_ptr_var);
1451    void *brk_ptr;
1452    brk_ptr_var->readValue(&brk_ptr, sizeof(void *));
1453
1454 #if defined(cap_save_the_world) && defined(BPATCH_LIBRARY)
1455         if(llproc->collectSaveWorldData && reload){
1456                 llproc->saveWorldloadLibrary(libname, brk_ptr); 
1457         }
1458 #endif
1459    return true;
1460 }
1461
1462 bool BPatch_process::getSourceLinesInt( unsigned long addr, std::vector< LineInformation::LineNoTuple > & lines ) {
1463         unsigned int originalSize = lines.size();
1464
1465         /* Iteratate over the modules, looking for addr in each. */
1466         BPatch_Vector< BPatch_module * > * modules = image->getModules();
1467         for( unsigned int i = 0; i < modules->size(); i++ ) {
1468                 LineInformation & lineInformation = (* modules)[i]->getLineInformation();               
1469                 lineInformation.getSourceLines( addr, lines );
1470                 } /* end iteration over modules */
1471         if( lines.size() != originalSize ) { return true; }
1472         
1473         return false;
1474         } /* end getLineAndFile() */
1475
1476 /*
1477  * BPatch_process::findFunctionByAddr
1478  *
1479  * Returns the function that contains the specified address, or NULL if the
1480  * address is not within a function.
1481  *
1482  * addr         The address to use for the lookup.
1483  */
1484 BPatch_function *BPatch_process::findFunctionByAddrInt(void *addr)
1485 {
1486    int_function *func;
1487    
1488    codeRange *range = llproc->findCodeRangeByAddress((Address) addr);
1489    if (!range)
1490       return NULL;
1491
1492    func = range->is_function();
1493     
1494    if (!func)
1495       return NULL;
1496     
1497    return findOrCreateBPFunc(func, NULL);
1498 }
1499
1500
1501 /* 
1502  *      this function sets a flag in process that 
1503  *      forces the collection of data for saveworld.
1504  */
1505 void BPatch_process::enableDumpPatchedImageInt(){
1506         llproc->collectSaveWorldData=true;
1507 }
1508
1509 void BPatch_process::setExitedViaSignal(int signalnumber) {
1510    exitedViaSignal = true;
1511    lastSignal = signalnumber;
1512 }
1513
1514 void BPatch_process::setExitedNormally() 
1515 {
1516    exitedNormally = true;
1517 }
1518
1519 void BPatch_process::getThreadsInt(BPatch_Vector<BPatch_thread *> &thrds)
1520 {
1521    for (unsigned i=0; i<threads.size(); i++)
1522       thrds.push_back(threads[i]);
1523 }
1524
1525 bool BPatch_process::isMultithreadedInt()
1526 {
1527    return (threads.size() > 1);
1528 }
1529
1530 BPatch_thread *BPatch_process::getThreadInt(dynthread_t tid)
1531 {
1532    for (unsigned i=0; i<threads.size(); i++)
1533       if (threads[i]->getTid() == tid)
1534          return threads[i];
1535    return NULL;
1536 }
1537
1538 BPatch_thread *BPatch_process::getThreadByIndexInt(unsigned index)
1539 {
1540    for (unsigned i=0; i<threads.size(); i++)
1541       if (threads[i]->getBPatchID() == index)
1542          return threads[i];
1543    return NULL;
1544 }
1545
1546 BPatch_function *BPatch_process::findOrCreateBPFunc(int_function* ifunc,
1547                                                     BPatch_module *bpmod)
1548 {
1549   if( func_map->defines(ifunc) ) {
1550     assert( func_map->get(ifunc) != NULL );
1551     return func_map->get(ifunc);
1552   }
1553   
1554   // Find the module that contains the function
1555   if (bpmod == NULL && ifunc->mod() != NULL) {
1556       bpmod = getImage()->findModule(ifunc->mod()->fileName().c_str());
1557   }
1558
1559   // findModule has a tendency to make new function objects... so
1560   // check the map again
1561   if (func_map->defines(ifunc)) {
1562     assert( func_map->get(ifunc) != NULL );
1563     return func_map->get(ifunc);
1564   }
1565
1566   BPatch_function *ret = new BPatch_function(this, ifunc, bpmod);
1567   assert( ret != NULL );
1568   return ret;
1569 }
1570
1571 BPatch_point *BPatch_process::findOrCreateBPPoint(BPatch_function *bpfunc, 
1572                                                   instPoint *ip, 
1573                                                   BPatch_procedureLocation pointType)
1574 {
1575     assert(ip);
1576    if (instp_map->defines(ip)) 
1577       return instp_map->get(ip);
1578
1579    if (bpfunc == NULL) 
1580        bpfunc = findOrCreateBPFunc(ip->func(), NULL);
1581    
1582    BPatch_point *pt = new BPatch_point(this, bpfunc, ip, pointType);
1583
1584    instp_map->add(ip, pt);
1585
1586    return pt;
1587 }
1588
1589 BPatch_function *BPatch_process::createBPFuncCB(process *p, int_function *f)
1590 {
1591    bool found;
1592    BPatch_process *proc = BPatch::bpatch->getProcessByPid(p->getPid(), &found);
1593    assert(found);
1594    return proc->findOrCreateBPFunc(f, NULL);
1595 }
1596
1597 BPatch_point *BPatch_process::createBPPointCB(process *p, int_function *f, 
1598                                               instPoint *ip, int type)
1599 {
1600    bool found;
1601    BPatch_process *proc = BPatch::bpatch->getProcessByPid(p->getPid(), &found);
1602    assert(found);
1603    BPatch_function *func = proc->func_map->get(f);
1604    return proc->findOrCreateBPPoint(func, ip, (BPatch_procedureLocation) type);
1605 }
1606
1607 BPatch_thread *BPatch_process::createOrUpdateBPThread(int lwp, dynthread_t tid, 
1608                                                       unsigned index, 
1609                                                       unsigned long stack_start, 
1610                                                       unsigned long start_addr)
1611 {
1612    //fprintf(stderr, "%s[%d][%s]:  welcome to createOrUpdateBPThread(tid = %lu)\n",
1613    //        FILE__, __LINE__, getThreadStr(getExecThreadID()), tid);
1614    BPatch_thread *thr = NULL;
1615
1616    //Find this thread if it already exists.
1617    for (unsigned i=0; i<threads.size(); i++) 
1618       if (threads[i]->getBPatchID() == index) 
1619       {
1620          thr = threads[i];
1621          break;
1622       }
1623
1624    //Needs creating
1625    if (!thr) 
1626    {
1627       thr = new BPatch_thread(this, index, lwp);
1628       threads.push_back(thr);
1629    }
1630
1631    //Update the non-esential values for the thread
1632    BPatch_function *initial_func = getImage()->findFunction(start_addr);
1633    if (!initial_func) {
1634      //fprintf(stderr, "%s[%d][%s]:  WARNING:  no function at %p found for thread\n",
1635      //        FILE__, __LINE__, getThreadStr(getExecThreadID()), start_addr);
1636    }
1637    thr->updateValues(tid, stack_start, initial_func, lwp);   
1638    return thr;
1639 }
1640
1641 /**
1642  * Called when a delete thread event is read out of the event queue
1643  **/
1644 void BPatch_process::deleteBPThread(BPatch_thread *thrd)
1645 {
1646    if (!thrd->getBPatchID()) 
1647    {
1648       //Don't delete if this is the initial thread.  Some Dyninst programs
1649       // may use the initial BPatch_thread as a handle instead of the 
1650       // BPatch_process, and we don't want to delete that handle out from
1651       // under the users.
1652       return;
1653    }
1654       
1655    thrd->legacy_destructor = false;
1656    delete thrd;      
1657 }
1658
1659 #ifdef IBM_BPATCH_COMPAT
1660 /**
1661  * In IBM's code, this is a wrapper for _BPatch_thread->addSharedObject (linux)
1662  * which is in turn a wrapper for creating a new 
1663  * ibmBpatchElf32Teader(name, addr)
1664  **/
1665 bool BPatch_process::addSharedObjectInt(const char *name, 
1666                                         const unsigned long loadaddr)
1667 {
1668    return loadLibrary(name);
1669 }
1670 #endif
1671
1672
1673 /***************************************************************************
1674  * BPatch_snippetHandle
1675  ***************************************************************************/
1676
1677 /*
1678  * BPatchSnippetHandle::BPatchSnippetHandle
1679  *
1680  * Constructor for BPatchSnippetHandle.  Delete the snippet instance(s)
1681  * associated with the BPatchSnippetHandle.
1682  */
1683 BPatchSnippetHandle::BPatchSnippetHandle(BPatch_process *proc) :
1684     proc_(proc)
1685 {
1686 }
1687
1688 /*
1689  * BPatchSnippetHandle::~BPatchSnippetHandle
1690  *
1691  * Destructor for BPatchSnippetHandle.  Delete the snippet instance(s)
1692  * associated with the BPatchSnippetHandle.
1693  */
1694 void BPatchSnippetHandle::BPatchSnippetHandle_dtor()
1695 {
1696    // don't delete inst instances since they are might have been copied
1697 }
1698
1699 BPatch_function *BPatch_process::get_function(int_function *f) 
1700
1701    if (!func_map->defines(f))
1702       return NULL;
1703    return func_map->get(f); 
1704 }
1705
1706 extern void dyninst_yield();
1707 void BPatch_process::updateThreadInfo()
1708 {
1709    if (!llproc->multithread_capable())
1710       return;
1711    
1712    llproc->recognize_threads(NULL);
1713    
1714    //We want to startup the event handler thread even if there's
1715    // no registered handlers so we can start getting MT events.
1716    if (!getAsync()->startupThread())
1717        return;
1718 }