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