Expose endianness from Elf_X.
[dyninst.git] / dyninstAPI / src / BPatch_process.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #define BPATCH_FILE
32
33 #include <string>
34
35 #include "inst.h"
36 #include "instP.h"
37 #include "instPoint.h"
38 #include "function.h" // func_instance
39 #include "codeRange.h"
40 #include "dynProcess.h"
41 #include "dynThread.h"
42 #include "pcEventHandler.h"
43 #include "os.h"
44
45 #include "mapped_module.h"
46 #include "mapped_object.h"
47
48 #include "BPatch_libInfo.h"
49 #include "BPatch.h"
50 #include "BPatch_point.h"
51 #include "BPatch_thread.h"
52 #include "BPatch_function.h"
53 #include "BPatch_basicBlock.h"
54 #include "BPatch_module.h"
55 #include "hybridAnalysis.h"
56 #include "BPatch_private.h"
57 #include "parseAPI/h/CFG.h"
58 #include "ast.h"
59 #include "debug.h"
60 #include "MemoryEmulator/memEmulator.h"
61 #include <boost/tuple/tuple.hpp>
62
63 #include "PatchMgr.h"
64 #include "PatchModifier.h"
65 #include "Command.h"
66 #include "Relocation/DynAddrSpace.h"
67 #include "Relocation/DynPointMaker.h"
68 #include "Relocation/DynObject.h"
69
70 #include "Point.h"
71
72 using namespace Dyninst;
73 using namespace Dyninst::SymtabAPI;
74 using PatchAPI::DynObject;
75 using PatchAPI::DynAddrSpace;
76 using PatchAPI::PatchMgr;
77 using PatchAPI::Patcher;
78
79 int BPatch_process::getAddressWidth(){
80         return llproc->getAddressWidth();
81 }
82
83 /*
84  * BPatch_process::getPid
85  *
86  * Return the process ID of the thread associated with this object.
87  */
88 int BPatch_process::getPid()
89 {
90    return llproc ? llproc->getPid() : -1;
91 }
92
93 /*
94  * BPatch_process::BPatch_process
95  *
96  * Starts a new process and associates it with the BPatch_process being
97  * constructed.  The new process is placed into a stopped state before
98  * executing any code.
99  *
100  * path         Pathname of the executable to start.
101  * argv         A list of pointers to character strings which are the
102  *              arguments for the new process, terminated by a NULL pointer.
103  * envp         A list of pointers to character strings which are the
104  *              environment variables for the new process, terminated by a
105  *              NULL pointer.  If NULL, the default environment will be used.
106  */
107 BPatch_process::BPatch_process(const char *path, const char *argv[],
108                                BPatch_hybridMode mode, const char **envp,
109                                int stdin_fd, int stdout_fd, int stderr_fd)
110    : llproc(NULL), lastSignal(-1), exitCode(-1), exitSignal(-1),
111      exitedNormally(false), exitedViaSignal(false), mutationsActive(true), 
112      createdViaAttach(false), detached(false), 
113      terminated(false), reportedExit(false),
114      hybridAnalysis_(NULL)
115 {
116    image = NULL;
117    pendingInsertions = NULL;
118
119    pdvector<std::string> argv_vec;
120    pdvector<std::string> envp_vec;
121    // Contruct a vector out of the contents of argv
122    if (argv) {
123       for(int i = 0; argv[i] != NULL; i++)
124          argv_vec.push_back(argv[i]);
125    }
126
127    // Construct a vector out of the contents of envp
128    if(envp) {
129       for(int i = 0; envp[i] != NULL; ++i)
130          envp_vec.push_back(envp[i]);
131    }
132
133    std::string directoryName = "";
134
135  #if !defined(os_windows)
136    // this fixes a problem on linux and alpha platforms where pathless
137    // filenames are searched for either in a standard, predefined path, or
138    // in $PATH by execvp.  thus paths that should resolve to "./" are
139    // missed.  Note that the previous use of getcwd() here for the alpha
140    // platform was dangerous since this is an API and we don't know where
141    // the user's code will leave the cwd pointing.
142
143    if (NULL == strchr(path, '/')) {
144       const char *pathenv = getenv("PATH");
145       char *pathenv_copy = strdup(pathenv);
146       char *ptrptr;
147       char *nextpath = strtok_r(pathenv_copy, ":", &ptrptr);
148       while (nextpath) {
149          struct stat statbuf;
150
151          char *fullpath = new char[strlen(nextpath)+strlen(path)+2];
152          strcpy(fullpath,nextpath);
153          strcat(fullpath,"/");
154          strcat(fullpath,path);
155
156          if (!stat(fullpath,&statbuf)) {
157             directoryName = nextpath;
158             delete[] fullpath;
159             break;
160          }
161          delete[] fullpath;
162          nextpath = strtok_r(NULL,":", &ptrptr);
163       }
164       ::free(pathenv_copy);
165
166       if (nextpath == NULL) {
167          const char *dotslash = "./";
168          directoryName = dotslash;
169       }
170    }
171 #endif
172
173    /*
174     * Set directoryName if a current working directory can be found in
175     * the new process' environment (and override any previous settings).
176     */
177    if (envp) {
178        for (int i = 0; envp[i] != NULL; ++i) {
179            if (strncmp(envp[i], "PWD=", 4) == 0) {
180                directoryName = envp[i] + 4;
181                break;
182            }
183        }
184    }
185
186    std::string spath(path);
187    llproc = PCProcess::createProcess(spath, argv_vec, mode, envp_vec,
188                                      directoryName, 
189                                      stdin_fd, stdout_fd, stderr_fd);
190    if (llproc == NULL) {
191       BPatch_reportError(BPatchFatal, 68,
192            "Dyninst was unable to create the specified process");
193       return;
194    }
195
196    startup_cerr << "Registering function callback..." << endl;
197    llproc->registerFunctionCallback(createBPFuncCB);
198
199
200    startup_cerr << "Registering instPoint callback..." << endl;
201    llproc->registerInstPointCallback(createBPPointCB);
202    llproc->set_up_ptr(this);
203
204    assert(BPatch::bpatch != NULL);
205    startup_cerr << "Registering process..." << endl;
206    BPatch::bpatch->registerProcess(this);
207
208    // Create an initial thread
209    startup_cerr << "Getting initial thread..." << endl;
210    PCThread *thr = llproc->getInitialThread();
211    BPatch_thread *initial_thread = new BPatch_thread(this, thr);
212    threads.push_back(initial_thread);
213
214    startup_cerr << "Creating new BPatch_image..." << endl;
215    image = new BPatch_image(this);
216
217    assert(llproc->isBootstrapped());
218
219    assert(BPatch_heuristicMode != llproc->getHybridMode());
220    if ( BPatch_normalMode != mode ) {
221        BPatch::bpatch->setInstrStackFrames(true);
222        hybridAnalysis_ = new HybridAnalysis(llproc->getHybridMode(),this);
223    }
224
225    // Let's try to profile memory usage
226 #if defined(PROFILE_MEM_USAGE)
227    void *mem_usage = sbrk(0);
228    fprintf(stderr, "Post BPatch_process: sbrk %p\n", mem_usage);
229 #endif
230
231    startup_cerr << "BPatch_process::BPatch_process, completed." << endl;
232 }
233
234 #if defined(os_linux)
235 /* Particular linux kernels running dyninst in particular patterns
236    (namely, with a single process having spawned the mutator and the
237    mutatee) are susceptible to a kernel bug that will cause a panic
238    if the mutator exits before the mutatee. See the comment above
239    class ForkNewProcessCallback : public DBICallbackBase in
240    debuggerinterface.h for details.
241 */
242 bool LinuxConsideredHarmful(pid_t pid) // PUSH
243 {
244     int major, minor, sub, subsub; // version numbers
245     pid_t my_ppid, my_pid, mutatee_ppid = 0;
246     FILE *fd;
247     char buf[1024];
248     char filename[64];
249
250     get_linux_version(major,minor,sub,subsub);
251
252     if( major == 2 && minor == 6 &&
253         (sub < 11 || (sub == 11 && subsub <= 11)) )
254     {
255         my_ppid = getppid();
256         my_pid = getpid();
257         // If anybody knows a better way to get the parent pid, be my
258         // guest to change this.
259         snprintf(filename, 64, "/proc/%d/status", pid);
260         fd = fopen(filename, "r");
261         if (!fd) {
262             startup_printf("Failed to open %s, assuming no linux kernel bug\n",
263                             filename);
264             return false;
265         }
266         while (fgets(buf, 1024, fd)) {
267             if (strncmp(buf, "PPid", 4) == 0) {
268                 sscanf(buf, "%*s %d", &mutatee_ppid);
269                 break;
270             }
271         }
272         fclose(fd);
273
274         if(my_ppid == mutatee_ppid ||
275            my_pid == mutatee_ppid)
276             return true;
277     }
278
279     return false;
280 }
281 #endif
282 /*
283  * BPatch_process::BPatch_process
284  *
285  * Constructs a new BPatch_process and associates it with a running process.
286  * Stops execution of the process.
287  *
288  * path         Pathname of the executable file for the process.
289  * pid          Process ID of the target process.
290  */
291 BPatch_process::BPatch_process
292 (const char *path, int pid, BPatch_hybridMode mode)
293    : llproc(NULL), lastSignal(-1), exitCode(-1), exitSignal(-1),
294      exitedNormally(false), exitedViaSignal(false), mutationsActive(true), 
295      createdViaAttach(true), detached(false), 
296      terminated(false), reportedExit(false),
297      hybridAnalysis_(NULL)
298 {
299    image = NULL;
300    pendingInsertions = NULL;
301
302 #if defined(os_linux)
303     /* We need to test whether we are in kernel 2.6.9 - 2.6.11.11 (inclusive).
304        If so, and if the mutatee's parent and our parent are one and the same,
305        we are exposing the user to a potential kernel panic.
306     */
307     startup_printf("Checking for potential Linux kernel bug...\n");
308     if(LinuxConsideredHarmful(pid))
309     {
310         fprintf(stderr,
311             "\nWARNING: You are running a Linux kernel between 2.6.9 and \n"
312             "2.6.11.11 (inclusive). Executing Dyninst under this kernel \n"
313             "may exercise a bug in the Linux kernel and lead to a panic \n"
314             "under some conditions. We STRONGLY suggest that you upgrade \n"
315             "your kernel to 2.6.11.12 or higher.\n\n");
316     }
317 #endif
318
319    assert(BPatch::bpatch != NULL);
320
321     startup_printf("%s[%d]:  creating new BPatch_image...\n", FILE__, __LINE__);
322    image = new BPatch_image(this);
323     startup_printf("%s[%d]:  created new BPatch_image...\n", FILE__, __LINE__);
324    std::string spath = path ? std::string(path) : std::string();
325     startup_printf("%s[%d]:  attaching to process %s/%d\n", FILE__, __LINE__,
326           path ? path : "no_path", pid);
327
328    llproc = PCProcess::attachProcess(spath, pid, mode);
329    if (!llproc) {
330       BPatch_reportError(BPatchFatal, 68, "Dyninst was unable to attach to the specified process");
331       BPatch::bpatch->unRegisterProcess(pid, this);
332
333       return;
334    }
335
336    BPatch::bpatch->registerProcess(this, pid);
337    startup_printf("%s[%d]:  attached to process %s/%d\n", FILE__, __LINE__, path ? path : 
338             "no_path", pid);
339
340    // Create the initial threads
341    pdvector<PCThread *> llthreads;
342    llproc->getThreads(llthreads);
343    for (pdvector<PCThread *>::iterator i = llthreads.begin();
344            i != llthreads.end(); ++i)
345    {
346       BPatch_thread *thrd = new BPatch_thread(this, *i);
347       threads.push_back(thrd);
348    }
349
350    llproc->registerFunctionCallback(createBPFuncCB);
351    llproc->registerInstPointCallback(createBPPointCB);
352    llproc->set_up_ptr(this);
353
354    assert(llproc->isBootstrapped());
355    assert(llproc->isStopped());
356
357    assert(BPatch_heuristicMode != llproc->getHybridMode());
358    if ( BPatch_normalMode != mode ) {
359        hybridAnalysis_ = new HybridAnalysis(llproc->getHybridMode(),this);
360    }
361 }
362
363 /*
364  * BPatch_process::BPatch_process
365  *
366  * Constructs a new BPatch_process and associates it with a forked process.
367  *
368  * parentPid          Pathname of the executable file for the process.
369  * childPid           Process ID of the target process.
370  */
371 BPatch_process::BPatch_process(PCProcess *nProc)
372    : llproc(nProc), lastSignal(-1), exitCode(-1), exitSignal(-1),
373      exitedNormally(false), exitedViaSignal(false), mutationsActive(true),
374      createdViaAttach(true), detached(false),
375      terminated(false),
376      reportedExit(false), hybridAnalysis_(NULL)
377 {
378    // Add this object to the list of threads
379    assert(BPatch::bpatch != NULL);
380    image = NULL;
381    pendingInsertions = NULL;
382
383    BPatch::bpatch->registerProcess(this);
384
385    // Create the initial threads
386    pdvector<PCThread *> llthreads;
387    llproc->getThreads(llthreads);
388    for (pdvector<PCThread *>::iterator i = llthreads.begin();
389            i != llthreads.end(); ++i)
390    {
391       BPatch_thread *thrd = new BPatch_thread(this, *i);
392       threads.push_back(thrd);
393    }
394
395    llproc->registerFunctionCallback(createBPFuncCB);
396    llproc->registerInstPointCallback(createBPPointCB);
397    llproc->set_up_ptr(this);
398
399    image = new BPatch_image(this);
400 }
401
402 /*
403  * BPatch_process::~BPatch_process
404  *
405  * Destructor for BPatch_process.
406  */
407 BPatch_process::~BPatch_process()
408 {
409    if( llproc ) {
410        //  unRegister process before doing detach
411        BPatch::bpatch->unRegisterProcess(getPid(), this);   
412
413        /**
414         * If we attached to the process, then we detach and leave it be,
415         * otherwise we'll terminate it
416         **/
417
418        if (createdViaAttach) 
419        {
420            llproc->detachProcess(true);
421        }
422        else  
423        {
424            if (llproc->isAttached()) {
425                terminateExecution();
426            }
427        }
428        delete llproc;
429        llproc = NULL;
430    }
431
432    for (int i=threads.size()-1; i>=0; i--) {
433        delete threads[i];
434    }
435
436    if (image) delete image;
437
438    image = NULL;
439
440    if (pendingInsertions)
441    {
442        for (unsigned f = 0; f < pendingInsertions->size(); f++)
443            {
444            delete (*pendingInsertions)[f];
445        }
446
447        delete pendingInsertions;
448        pendingInsertions = NULL;
449    }
450
451    if (NULL != hybridAnalysis_) {
452        delete hybridAnalysis_;
453    }
454
455    assert(BPatch::bpatch != NULL);
456 }
457
458 /*
459  * BPatch_process::triggerInitialThreadEvents
460  *
461  * Events and callbacks shouldn't be delivered from a constructor so after a
462  * BPatch_process is constructed, this should be called.
463  */
464 void BPatch_process::triggerInitialThreadEvents() {
465     // For compatibility, only do this for multithread capable processes
466     if( llproc->multithread_capable() ) {
467         for (BPatch_Vector<BPatch_thread *>::iterator i = threads.begin();
468                 i != threads.end(); ++i) 
469         {
470             BPatch::bpatch->registerThreadCreate(this, *i);
471         }
472     }
473 }
474
475 /*
476  * BPatch_process::stopExecution
477  *
478  * Puts the thread into the stopped state.
479  */
480 bool BPatch_process::stopExecution() 
481 {
482     if( NULL == llproc ) return false;
483
484     // The user has already indicated they would like the process stopped
485     if( llproc->getDesiredProcessState() == PCProcess::ps_stopped ) return true;
486
487     llproc->setDesiredProcessState(PCProcess::ps_stopped);
488     return llproc->stopProcess();
489 }
490
491 /*
492  * BPatch_process::continueExecution
493  *
494  * Puts the thread into the running state.
495  */
496 bool BPatch_process::continueExecution() 
497 {
498     if( NULL == llproc ) return false;
499     if( !llproc->isBootstrapped() ) return false;
500
501     // The user has already indicated they would like the process running
502     if( llproc->getDesiredProcessState() == PCProcess::ps_running ) return true;
503
504     llproc->setDesiredProcessState(PCProcess::ps_running);
505
506     return llproc->continueProcess();
507 }
508
509 /*
510  * BPatch_process::terminateExecution
511  *
512  * Kill the thread.
513  */
514 bool BPatch_process::terminateExecution() 
515 {
516     if( NULL == llproc ) return false;
517
518     if( isTerminated() ) return true;
519
520     proccontrol_printf("%s[%d]:  about to terminate proc\n", FILE__, __LINE__);
521     return llproc->terminateProcess();
522 }
523
524 /*
525  * BPatch_process::isStopped
526  *
527  * Returns true if the thread has stopped, and false if it has not.  
528  */
529 bool BPatch_process::isStopped()
530 {
531     if( llproc == NULL ) return true;
532
533     // The state visible to the user is different than the state
534     // maintained by ProcControlAPI because processes remain in
535     // a stopped state while doing event handling -- the user 
536     // shouldn't see the process in a stopped state in this
537     // case
538     //
539     // The following list is all cases where the user should see
540     // the process stopped:
541     // 1) BPatch_process::stopExecution is invoked
542     // 2) A snippet breakpoint occurs
543     // 3) The mutatee is delivered a stop signal
544
545     return llproc->getDesiredProcessState() == PCProcess::ps_stopped;
546 }
547
548 /*
549  * BPatch_process::stopSignal
550  *
551  * Returns the number of the signal which caused the thread to stop.
552  */
553 int BPatch_process::stopSignal()
554 {
555     if (!isStopped()) {
556         BPatch::reportError(BPatchWarning, 0, 
557                 "Request for stopSignal when process is not stopped");
558         return -1;
559     }
560     return lastSignal;
561 }
562
563 /*
564  * BPatch_process::statusIsTerminated
565  *
566  * Returns true if the process has terminated, false if it has not.
567  */
568 bool BPatch_process::statusIsTerminated()
569 {
570    if (llproc == NULL) return true;
571    return llproc->isTerminated();
572 }
573
574 /*
575  * BPatch_process::isTerminated
576  *
577  * Returns true if the thread has terminated, and false if it has not.  This
578  * may involve checking for thread events that may have recently changed this
579  * thread's status.  
580  */
581 bool BPatch_process::isTerminated()
582 {
583     if( NULL == llproc ) return true;
584
585     if( exitedNormally || exitedViaSignal ) return true;
586
587     return llproc->isTerminated();
588 }
589
590 /*
591  * BPatch_process::terminationStatus
592  *
593  * Indicates how the program exited.  Returns one of NoExit, ExitedNormally,
594  * or ExitedViaSignal.
595  *
596  */
597 BPatch_exitType BPatch_process::terminationStatus() {
598    if(exitedNormally)
599       return ExitedNormally;
600    else if(exitedViaSignal)
601       return ExitedViaSignal;
602    return NoExit;
603 }
604
605 /*
606  * BPatch_process::getExitCode
607  *
608  * Returns exit code of applications
609  *
610  */
611 int BPatch_process::getExitCode()
612 {
613    return exitCode;
614 }
615
616 /*
617  * BPatch_process::getExitSignal
618  *
619  * Returns signal number that caused application to exit.
620  *
621  */
622 int BPatch_process::getExitSignal()
623 {
624    return lastSignal;
625 }
626
627 bool BPatch_process::wasRunningWhenAttached()
628 {
629   if (!llproc) return false;
630   return llproc->wasRunningWhenAttached();
631 }
632
633 /*
634  * BPatch_process::detach
635  *
636  * Detach from the thread represented by this object.
637  *
638  * cont         True if the thread should be continued as the result of the
639  *              detach, false if it should not.
640  */
641 bool BPatch_process::detach(bool cont)
642 {
643    if (image)
644       image->removeAllModules();
645    detached = llproc->detachProcess(cont);
646    BPatch::bpatch->unRegisterProcess(getPid(), this);
647    return detached;
648 }
649
650 /*
651  * BPatch_process::isDetached
652  *
653  * Returns whether dyninstAPI is detached from this mutatee
654  *
655  */
656 bool BPatch_process::isDetached()
657 {
658    return detached;
659 }
660
661 /*
662  * BPatch_process::dumpCore
663  *
664  * Causes the process to dump its state to a file, and optionally to terminate.
665  * Returns true upon success, and false upon failure.
666  *
667  * file         The name of the file to which the state should be written.
668  * terminate    Indicates whether or not the thread should be terminated after
669  *              dumping core.  True indicates that it should, false that is
670  *              should not.
671  */
672 bool BPatch_process::dumpCore(const char *file, bool terminate)
673 {
674    bool was_stopped = isStopped();
675
676    stopExecution();
677
678    bool ret = llproc->dumpCore(file);
679    if (ret && terminate) {
680       terminateExecution();
681    } else if (!was_stopped) {
682       continueExecution();
683    }
684
685    return ret;
686 }
687
688 /*
689  * BPatch_process::dumpImage
690  *
691  * Writes the contents of memory into a file.
692  * Returns true upon success, and false upon failure.
693  *
694  * file         The name of the file to which the image should be written.
695  */
696 bool BPatch_process::dumpImage(const char *file)
697 {
698 #if defined(os_windows) 
699    return false;
700 #else
701    bool was_stopped = isStopped();
702
703    stopExecution();
704
705    bool ret = llproc->dumpImage(file);
706    if (!was_stopped) continueExecution();
707
708    return ret;
709 #endif
710 }
711
712 /*
713  * BPatch_process::getInheritedVariable
714  *
715  * Allows one to retrieve a variable which exists in a child process that
716  * was inherited from and originally created in the parent process.
717  * Function is invoked on the child BPatch_process (created from a fork in
718  * the application).
719  *
720  * parentVar   A BPatch_variableExpr created in the parent thread
721  *
722  * Returns:    The corresponding BPatch_variableExpr from the child thread
723  *             or NULL if the variable argument hasn't been malloced
724  *             in a parent process.
725  */
726 BPatch_variableExpr *BPatch_process::getInheritedVariable(
727                                                              BPatch_variableExpr &parentVar)
728 {
729    if(! llproc->isInferiorAllocated((Address)parentVar.getBaseAddr())) {
730       // isn't defined in this process so must not have been defined in a
731       // parent process
732       return NULL;
733    }
734
735    return new BPatch_variableExpr(this, llproc, parentVar.getBaseAddr(), Null_Register,
736                                   const_cast<BPatch_type *>(parentVar.getType()));
737 }
738
739
740 /*
741  * BPatch_process::getInheritedSnippet
742  *
743  * Allows one to retrieve a snippet which exists in a child process which
744  * was inherited from and originally created in the parent process.
745  * Function is invoked on the child BPatch_process (created from a fork in
746  * the application).
747  *
748  * Allows one to retrieve a snippet which exists in a child process which
749  * was inherited from and originally created in the parent process.
750  * Function is invoked on the child BPatch_process (created from a fork in
751  * the application).
752  *
753  * parentSnippet: A BPatchSnippetHandle created in the parent thread
754  *
755  * Returns:       The corresponding BPatchSnippetHandle from the child thread.
756  *
757  */
758
759 BPatchSnippetHandle *BPatch_process::getInheritedSnippet(BPatchSnippetHandle &parentSnippet)
760 {
761     // a BPatchSnippetHandle has an miniTramp for each point that
762     // the instrumentation is inserted at
763    const BPatch_Vector<Dyninst::PatchAPI::Instance::Ptr> &instances = parentSnippet.instances_;
764
765    BPatchSnippetHandle *childSnippet = new BPatchSnippetHandle(this);
766    for(unsigned i=0; i<instances.size(); i++) {
767       Dyninst::PatchAPI::Instance::Ptr child = getChildInstance(instances[0], llproc);
768       if (child) childSnippet->addInstance(child);
769    }
770    return childSnippet;
771 }
772
773 /*
774  * BPatch_addressSpace::beginInsertionSet
775  *
776  * Starts a batch insertion set; that is, all calls to insertSnippet until
777  * finalizeInsertionSet are delayed.
778  *
779  */
780
781 void BPatch_process::beginInsertionSet()
782 {
783     if (pendingInsertions == NULL)
784         pendingInsertions = new BPatch_Vector<batchInsertionRecord *>;
785     // Nothing else to do...
786 }
787
788
789 /*
790  * BPatch_process::finalizeInsertionSet
791  *
792  * Installs all instrumentation specified since the last beginInsertionSet call.
793  *
794  * modified gets set as a result of the catchup/fixup logic and is helpful in
795  * interpreting a false return value...  if finalizeInsertionSet returns false,
796  * but modified comes back true, then something horrible happened, because, if
797  * we go thru the trouble to modify the process state to make everything work
798  * then the function really should work.
799  */
800 bool BPatch_process::finalizeInsertionSet(bool, bool *)
801 {
802
803    if (statusIsTerminated()) return false;
804
805
806   // Can't insert code when mutations are not active.
807   bool shouldContinue = false;
808   if (!mutationsActive) {
809     return false;
810   }
811   
812   if ( ! isStopped() ) {
813     shouldContinue = true;
814     stopExecution();
815   }
816
817   /* PatchAPI stuffs */
818   bool ret = AddressSpace::patch(llproc);
819   /* End of PatchAPI stuffs */
820
821   llproc->trapMapping.flush();
822
823   if (shouldContinue)
824     continueExecution();
825
826   if (pendingInsertions) {
827     delete pendingInsertions;
828     pendingInsertions = NULL;
829   }
830
831   return ret;
832 }
833
834
835 bool BPatch_process::finalizeInsertionSetWithCatchup(bool, bool *,
836                                                         BPatch_Vector<BPatch_catchupInfo> &)
837 {
838    return false;
839 }
840
841 /*
842  * BPatch_process::oneTimeCode
843  *
844  * execute argument <expr> once.
845  *
846  */
847 void *BPatch_process::oneTimeCode(const BPatch_snippet &expr, bool *err)
848 {
849     if( !isStopped() ) {
850         BPatch_reportError(BPatchWarning, 0,
851                 "oneTimeCode failing because process is not stopped");
852         if( err ) *err = true;
853         return NULL;
854     }
855
856     return oneTimeCodeInternal(expr, NULL, NULL, NULL, true, err, true);
857 }
858
859 /*
860  * BPatch_process::oneTimeCodeCallbackDispatch
861  *
862  * theProc      The process in which the RPC completed.
863  * userData     This is a value that can be set when we invoke an inferior RPC
864  * returnValue  The value returned by the RPC.
865  */
866 int BPatch_process::oneTimeCodeCallbackDispatch(PCProcess *theProc,
867                                                  unsigned /* rpcid */, 
868                                                  void *userData,
869                                                  void *returnValue)
870 {
871     // Don't care what the process state is...
872     int retval = RPC_LEAVE_AS_IS;
873
874     assert(BPatch::bpatch != NULL);
875
876     OneTimeCodeInfo *info = (OneTimeCodeInfo *)userData;
877
878     BPatch_process *bproc =
879     BPatch::bpatch->getProcessByPid(theProc->getPid());
880
881     assert(bproc != NULL);
882
883     assert(info && !info->isCompleted());
884
885     info->setReturnValue(returnValue);
886     info->setCompleted(true);
887
888     if (!info->isSynchronous()) {
889         // Do the callback specific to this OneTimeCode, if set
890         BPatchOneTimeCodeCallback specificCB = info->getCallback();
891         if( specificCB ) {
892             (*specificCB)(bproc->threads[0], info->getUserData(), returnValue);
893         }
894
895         // Do the registered callback
896         BPatchOneTimeCodeCallback cb = BPatch::bpatch->oneTimeCodeCallback;
897         if( cb ) {
898             (*cb)(bproc->threads[0], info->getUserData(), returnValue);
899         }
900
901         // This is the case if the user requested a stop in a callback
902         if (bproc->isStopped()) retval = RPC_STOP_WHEN_DONE;
903         else retval = RPC_RUN_WHEN_DONE;
904
905         delete info;
906     }
907
908     return retval;
909 }
910
911 /*
912  * BPatch_process::oneTimeCodeInternal
913  *
914  * Causes a snippet expression to be evaluated once in the mutatee at the next
915  * available opportunity.  Optionally, Dyninst will call a callback function
916  * when the snippet has executed in the mutatee, and can wait until the
917  * snippet has executed to return.
918  *
919  * expr         The snippet to evaluate.
920  * userData     This value is given to the callback function along with the
921  *              return value for the snippet.  Can be used by the caller to
922  *              store per-oneTimeCode information.
923  * synchronous  True means wait until the snippet has executed, false means
924  *              return immediately.
925  */
926 void *BPatch_process::oneTimeCodeInternal(const BPatch_snippet &expr,
927                                           BPatch_thread *thread,
928                                           void *userData,
929                                           BPatchOneTimeCodeCallback cb,
930                                           bool synchronous,
931                                           bool *err,
932                                           bool userRPC)
933 {
934     if( statusIsTerminated() ) { 
935         BPatch_reportError(BPatchWarning, 0,
936                 "oneTimeCode failing because process has already exited");
937         if( err ) *err = true;
938         return NULL;
939     }
940
941     proccontrol_printf("%s[%d]: UI top of oneTimeCode...\n", FILE__, __LINE__);
942
943     OneTimeCodeInfo *info = new OneTimeCodeInfo(synchronous, userData, cb,
944             (thread) ? thread->getBPatchID() : 0);
945
946     if( !llproc->postIRPC(expr.ast_wrapper, 
947             (void *)info,
948             !isStopped(), 
949             (thread ? thread->llthread : NULL),
950             synchronous,
951             NULL, // the result will be passed to the callback 
952             userRPC) )
953     {
954         BPatch_reportError(BPatchWarning, 0,
955                     "failed to continue process to run oneTimeCode");
956         if( err ) *err = true;
957         delete info;
958         return NULL;
959     }
960
961     if( !synchronous ) return NULL;
962
963     assert( info->isCompleted() );
964
965     void *ret = info->getReturnValue();
966
967     proccontrol_printf("%s[%d]: RPC completed, process status %s\n",
968                        FILE__, __LINE__, isStopped() ? "stopped" : "running");
969
970     if (err) *err = false;
971     delete info;
972     return ret;
973 }
974
975 //  BPatch_process::oneTimeCodeAsync
976 //
977 //  Have the specified code be executed by the mutatee once.  Don't wait
978 //  until done.
979 bool BPatch_process::oneTimeCodeAsync(const BPatch_snippet &expr,
980                                          void *userData, BPatchOneTimeCodeCallback cb)
981 {
982    bool err = false;
983    oneTimeCodeInternal(expr, NULL, userData,  cb, false, &err, true);
984
985    if( err ) return false;
986    return true;
987 }
988
989 /*
990  * BPatch_process::loadLibrary
991  *
992  * Load a dynamically linked library into the address space of the mutatee.
993  *
994  * libname      The name of the library to load.
995  */
996 BPatch_object *BPatch_process::loadLibrary(const char *libname, bool)
997 {
998    if (!libname) {
999       fprintf(stderr, "[%s:%u] - loadLibrary called with NULL library name\n",
1000               __FILE__, __LINE__);
1001       return NULL;
1002    }
1003
1004    bool wasStopped = isStopped();
1005    if( !wasStopped ) {
1006        if (!stopExecution()) {
1007           BPatch_reportError(BPatchWarning, 0, 
1008                   "Failed to stop process for loadLibrary");
1009           return NULL;
1010        }
1011    }
1012
1013    BPatch_object *object = NULL;
1014    do {
1015
1016       /**
1017        * Find the DYNINSTloadLibrary function
1018        **/
1019       BPatch_Vector<BPatch_function *> bpfv;
1020       image->findFunction("DYNINSTloadLibrary", bpfv);
1021       if (!bpfv.size()) {
1022          cerr << __FILE__ << ":" << __LINE__ << ": FATAL:  Cannot find Internal"
1023               << "Function DYNINSTloadLibrary" << endl;
1024          break;
1025       }
1026       if (bpfv.size() > 1) {
1027          std::string msg = std::string("Found ") + utos(bpfv.size()) +
1028             std::string("functions called DYNINSTloadLibrary -- not fatal but weird");
1029          BPatch_reportError(BPatchSerious, 100, msg.c_str());
1030       }
1031       BPatch_function *dlopen_func = bpfv[0];
1032       if (dlopen_func == NULL)
1033         break;
1034
1035       /**
1036        * Generate a call to DYNINSTloadLibrary, and then run the generated code.
1037        **/
1038       BPatch_Vector<BPatch_snippet *> args;
1039       BPatch_constExpr nameArg(libname);
1040       args.push_back(&nameArg);
1041       BPatch_funcCallExpr call_dlopen(*dlopen_func, args);
1042
1043       if (!oneTimeCodeInternal(call_dlopen, NULL, NULL, NULL, true)) {
1044          BPatch_variableExpr *dlerror_str_var =
1045             image->findVariable("gLoadLibraryErrorString");
1046          assert(NULL != dlerror_str_var);
1047          char dlerror_str[256];
1048          dlerror_str_var->readValue((void *)dlerror_str, 256);
1049          BPatch_reportError(BPatchSerious, 124, dlerror_str);
1050          break;
1051       }
1052       /* Find the new mapped_object, map it to a BPatch_module, and return it */
1053
1054       mapped_object* plib = llproc->findObject(libname);
1055       if (!plib) {
1056         std::string wildcard(libname);
1057         wildcard += "*";
1058         plib = llproc->findObject(wildcard, true);
1059       }
1060       if (!plib) {
1061          // Best effort; take the latest added mapped_object
1062          plib = llproc->mappedObjects().back();
1063       }
1064
1065       dynamic_cast<DynAddrSpace*>(llproc->mgr()->as())->loadLibrary(plib);
1066       object = getImage()->findOrCreateObject(plib);
1067
1068    } while (0);
1069
1070    if( !wasStopped ) {
1071        if( !continueExecution() ) {
1072            BPatch_reportError(BPatchWarning, 0,
1073                    "Failed to continue process for loadLibrary");
1074        }
1075    }
1076
1077    return object;
1078 }
1079
1080
1081 void BPatch_process::enableDumpPatchedImage(){
1082     // deprecated; saveTheWorld is dead. Do nothing for now; kill later.
1083 }
1084
1085 void BPatch_process::setExitedViaSignal(int signalnumber)
1086 {
1087    exitedViaSignal = true;
1088    lastSignal = signalnumber;
1089 }
1090
1091 void BPatch_process::setExitedNormally()
1092 {
1093    exitedNormally = true;
1094 }
1095
1096 void BPatch_process::getThreads(BPatch_Vector<BPatch_thread *> &thrds)
1097 {
1098    for (unsigned i=0; i<threads.size(); i++)
1099       thrds.push_back(threads[i]);
1100 }
1101
1102 bool BPatch_process::isMultithreaded()
1103 {
1104    return (threads.size() > 1);
1105 }
1106
1107 bool BPatch_process::isMultithreadCapable()
1108 {
1109    if (!llproc) return false;
1110    return llproc->multithread_capable();
1111 }
1112
1113 BPatch_thread *BPatch_process::getThread(dynthread_t tid)
1114 {
1115    for (unsigned i=0; i<threads.size(); i++)
1116       if (threads[i]->getTid() == tid)
1117          return threads[i];
1118    return NULL;
1119 }
1120
1121 BPatch_thread *BPatch_process::getThreadByIndex(unsigned index)
1122 {
1123    for (unsigned i=0; i<threads.size(); i++)
1124       if (threads[i]->getBPatchID() == index)
1125          return threads[i];
1126    return NULL;
1127 }
1128
1129 processType BPatch_process::getType()
1130 {
1131   return TRADITIONAL_PROCESS;
1132 }
1133
1134 void BPatch_process::getAS(std::vector<AddressSpace *> &as)
1135 {
1136    as.push_back(static_cast<AddressSpace*>(llproc));
1137 }
1138
1139 /**
1140  * Removes the BPatch_thread from this process' collection of
1141  * threads
1142  **/
1143 void BPatch_process::deleteBPThread(BPatch_thread *thrd)
1144 {
1145    if (!thrd || !thrd->getBPatchID())
1146    {
1147       //Don't delete if this is the initial thread.  Some Dyninst programs
1148       // may use the initial BPatch_thread as a handle instead of the
1149       // BPatch_process, and we don't want to delete that handle out from
1150       // under the users.
1151       return;
1152    }
1153
1154 #if !defined(USE_DEPRECATED_BPATCH_VECTOR)
1155    // STL vectors don't have item erase. We use iterators instead...
1156    threads.erase(std::find(threads.begin(),
1157                                  threads.end(),
1158                                  thrd));
1159 #else
1160    for (unsigned i=0; i< threads.size(); i++) {
1161       if (threads[i] == thrd) {
1162          threads.erase(i);
1163          break;
1164       }
1165    }
1166 #endif
1167
1168    llproc->removeThread(thrd->getTid());
1169
1170    // We allow users to maintain pointers to exited threads
1171    // If this changes, the memory can be free'd here
1172    // delete thrd;
1173 }
1174
1175 #ifdef IBM_BPATCH_COMPAT
1176 /**
1177  * In IBM's code, this is a wrapper for _BPatch_thread->addSharedObject (linux)
1178  * which is in turn a wrapper for creating a new
1179  * ibmBpatchElf32Teader(name, addr)
1180  **/
1181 bool BPatch_process::addSharedObject(const char *name,
1182                                         const unsigned long loadaddr)
1183 {
1184    return loadLibrary(name);
1185 }
1186 #endif
1187
1188 /**
1189  * This function continues a stopped process, letting it execute in single step mode,
1190  * and printing the current instruction as it executes.
1191  **/
1192
1193 void BPatch_process::debugSuicide()
1194 {
1195     llproc->debugSuicide();
1196 }
1197
1198 void BPatch_process::triggerThreadCreate(PCThread *thread) {
1199   BPatch_thread *newthr = BPatch_thread::createNewThread(this, thread);
1200   threads.push_back(newthr);
1201   BPatch::bpatch->registerThreadCreate(this, newthr);
1202 }
1203
1204 /* BPatch::triggerStopThread
1205  *
1206  * Causes the execution of a callback in the mutator that was
1207  * triggered for the evtStopThread event. As BPatch_stopThreadExpr
1208  * snippets allow a different callback to be triggered for each
1209  * snippet instance, the cb_ID is used to find the right callback to
1210  * trigger. This code had to be in a BPatch-level class so that we
1211  * could utilize the findOrCreateBPFunc and findOrCreateBPPoint
1212  * functions.
1213  *
1214  * @intPoint: the instPoint at which the event occurred, will be
1215  *    wrapped in a BPatch_point and sent to the callback as a parameter
1216  * @intFunc: the function in which the event occurred, will be wrapped
1217  *    in a BPatch_function and sent to the callback as a parameter
1218  * @proc: the process is needed for the creation of BPatch level objects
1219  * @cb_ID: helps us identify the correct call
1220  * @retVal: the return value of a parameter snippet that gets passed
1221  *    down in the stopThread snippet and evaluated.
1222  *
1223  * Return Value: Will always be true if code unless an error occurs, a
1224  *    callback is triggered for every stopThread snippet instance.
1225  */
1226 bool BPatch_process::triggerStopThread(instPoint *intPoint,
1227          func_instance *intFunc, int cb_ID, void *retVal)
1228 {
1229     // find the BPatch_point corresponding to the instrumentation point
1230     BPatch_function *bpFunc = findOrCreateBPFunc(intFunc, NULL);
1231     BPatch_procedureLocation bpPointType =
1232         BPatch_point::convertInstPointType_t(intPoint->type());
1233     BPatch_point *bpPoint = findOrCreateBPPoint(bpFunc, intPoint, bpPointType);
1234     if (!bpPoint) {
1235         return false;
1236     }
1237
1238     // Trigger all the callbacks matching this snippet
1239     for(unsigned int i = 0; i < BPatch::bpatch->stopThreadCallbacks.size(); ++i) {
1240         BPatchStopThreadCallback curCallback = BPatch::bpatch->stopThreadCallbacks[i];
1241         if( cb_ID == BPatch::bpatch->info->getStopThreadCallbackID((Address)curCallback) ) {
1242             (*curCallback)(bpPoint, retVal);
1243         }
1244     }
1245
1246    return true;
1247 }
1248
1249
1250 /* BPatch::triggerSignalHandlerCB
1251  *
1252  * Grabs BPatch level objects for the instPoint and enclosing function
1253  * and triggers any registered callbacks for this signal/exception
1254  *
1255  * @intPoint: the instPoint at which the event occurred, will be
1256  * wrapped in a BPatch_point and sent to the callback as a parameter
1257  * @intFunc: the function in which the event occurred, will be
1258  * wrapped in a BPatch_function and sent to the callback as a parameter
1259  *
1260  * Return Value: true if a matching callback was found and no error occurred
1261  *
1262  */
1263 bool BPatch_process::triggerSignalHandlerCB(instPoint *intPoint,
1264         func_instance *intFunc, long signum, BPatch_Vector<Address> *handlers)
1265 {
1266     // find the BPatch_point corresponding to the exception-raising instruction
1267     BPatch_function *bpFunc = findOrCreateBPFunc(intFunc, NULL);
1268     BPatch_procedureLocation bpPointType =
1269         BPatch_point::convertInstPointType_t(intPoint->type());
1270     BPatch_point *bpPoint = findOrCreateBPPoint(bpFunc, intPoint, bpPointType);
1271     if (!bpPoint) { return false; }
1272
1273     // Do the callback
1274     InternalSignalHandlerCallback cb = BPatch::bpatch->signalHandlerCallback;
1275     if( cb ) {
1276         (*cb)(bpPoint, signum, *handlers);
1277         return true;
1278     }
1279
1280     return false;
1281 }
1282
1283 /* BPatch::triggerCodeOverwriteCB
1284  *
1285  * Grabs BPatch level objects for the instPoint and enclosing function
1286  * and triggers a registered callback if there is one
1287  *
1288  * @intPoint: the instPoint at which the event occurred, will be
1289  * wrapped in a BPatch_point and sent to the callback as a parameter
1290  *
1291  * Return Value: true if a matching callback was found and no error occurred
1292  */
1293 bool BPatch_process::triggerCodeOverwriteCB(instPoint *faultPoint,
1294                                             Address faultTarget)
1295 {
1296     BPatch_function *bpFunc = findOrCreateBPFunc
1297         (faultPoint->func(),NULL);
1298     assert(bpFunc);
1299     BPatch_point *bpPoint = findOrCreateBPPoint(
1300         bpFunc,
1301         faultPoint,
1302         BPatch_point::convertInstPointType_t(faultPoint->type()));
1303
1304     // Do the callback
1305     InternalCodeOverwriteCallback cb = BPatch::bpatch->codeOverwriteCallback;
1306     if( cb ) {
1307         (*cb)(bpPoint, faultTarget);
1308         return true;
1309     }
1310
1311     return false;
1312 }
1313
1314 /* This is a Windows only function that sets the user-space
1315  * debuggerPresent flag to 0 or 1, 0 meaning that the process is not
1316  * being debugged.  The debugging process will still have debug
1317  * access, but system calls that ask if the process is being debugged
1318  * will say that it is not because they merely return the value of the
1319  * user-space beingDebugged flag.
1320  */
1321 bool BPatch_process::hideDebugger()
1322 {
1323     // do non-instrumentation related hiding
1324     bool retval = llproc->hideDebugger();
1325
1326     // disable API calls //
1327     vector<pair<BPatch_function *,BPatch_function *> > disabledFuncs;
1328     BPatch_module *user = image->findModule("user32.dll",true);
1329     BPatch_module *kern = image->findModule("*kernel32.dll",true);
1330
1331     if (user) {
1332         // BlockInput
1333         using namespace SymtabAPI;
1334         vector<BPatch_function*> funcs;
1335         user->findFunction(
1336             "BlockInput",
1337             funcs, false, false, false, true);
1338         assert (funcs.size());
1339         BPatch_module *rtlib = this->image->findOrCreateModule(
1340             (*llproc->runtime_lib.begin())->getModules().front());
1341         vector<BPatch_function*> repfuncs;
1342         rtlib->findFunction("DYNINST_FakeBlockInput", repfuncs, false);
1343         assert(!repfuncs.empty());
1344         replaceFunction(*funcs[0],*repfuncs[0]);
1345         disabledFuncs.push_back(pair<BPatch_function*,BPatch_function*>(
1346                                 funcs[0],repfuncs[0]));
1347     }
1348
1349     if (kern) {
1350         // SuspendThread
1351         // KEVINTODO: condition the function replacement on its thread ID parameter matching a Dyninst thread
1352         using namespace SymtabAPI;
1353         vector<BPatch_function*> funcs;
1354         kern->findFunction(
1355             "SuspendThread",
1356             funcs, false, false, false, true);
1357         assert (funcs.size());
1358         BPatch_module *rtlib = this->image->findOrCreateModule(
1359             (*llproc->runtime_lib.begin())->getModules().front());
1360         vector<BPatch_function*> repfuncs;
1361         rtlib->findFunction("DYNINST_FakeSuspendThread", repfuncs, false);
1362         assert(!repfuncs.empty());
1363         replaceFunction(*funcs[0],*repfuncs[0]);
1364         disabledFuncs.push_back(pair<BPatch_function*,BPatch_function*>(
1365                                 funcs[0],repfuncs[0]));
1366     }
1367
1368     if (kern) {
1369         // getTickCount
1370         using namespace SymtabAPI;
1371         vector<BPatch_function*> funcs;
1372         kern->findFunction(
1373             "GetTickCount",
1374             funcs, false, false, false, true);
1375         if (!funcs.empty()) {
1376                         BPatch_module *rtlib = this->image->findOrCreateModule(
1377                                 (*llproc->runtime_lib.begin())->getModules().front());
1378                         vector<BPatch_function*> repfuncs;
1379                         rtlib->findFunction("DYNINST_FakeTickCount", repfuncs, false);
1380                         assert(!repfuncs.empty());
1381                         replaceFunction(*funcs[0],*repfuncs[0]);
1382                         disabledFuncs.push_back(pair<BPatch_function*,BPatch_function*>(
1383                                                                         funcs[0],repfuncs[0]));
1384                 }
1385     }
1386
1387     if (kern) {
1388         // getSystemTime
1389         using namespace SymtabAPI;
1390         vector<BPatch_function*> funcs;
1391         kern->findFunction(
1392             "GetSystemTime",
1393             funcs, false, false, false, true);
1394         assert (!funcs.empty());
1395         BPatch_module *rtlib = this->image->findOrCreateModule(
1396             (*llproc->runtime_lib.begin())->getModules().front());
1397         vector<BPatch_function*> repfuncs;
1398         rtlib->findFunction("DYNINST_FakeGetSystemTime", repfuncs, false);
1399         assert(!repfuncs.empty());
1400         replaceFunction(*funcs[0],*repfuncs[0]);
1401         disabledFuncs.push_back(pair<BPatch_function*,BPatch_function*>(
1402                                 funcs[0],repfuncs[0]));
1403     }
1404
1405     if (kern) {
1406         // CheckRemoteDebuggerPresent
1407         vector<BPatch_function*> funcs;
1408         kern->findFunction(
1409             "CheckRemoteDebuggerPresent",
1410             funcs, false, false, true);
1411         assert (funcs.size());
1412         BPatch_module *rtlib = this->image->findOrCreateModule(
1413             (*llproc->runtime_lib.begin())->getModules().front());
1414         vector<BPatch_function*> repfuncs;
1415         rtlib->findFunction("DYNINST_FakeCheckRemoteDebuggerPresent", repfuncs, false);
1416         assert(!repfuncs.empty());
1417         replaceFunction(*funcs[0],*repfuncs[0]);
1418         disabledFuncs.push_back(pair<BPatch_function*,BPatch_function*>(
1419                                 funcs[0],repfuncs[0]));
1420     }
1421
1422     if (kern && user) {
1423         // OutputDebugStringA
1424         vector<BPatch_function*> funcs;
1425         kern->findFunction("OutputDebugStringA",
1426             funcs, false, false, true);
1427         assert(funcs.size());
1428         vector<BPatch_function*> sle_funcs;
1429         user->findFunction("SetLastErrorEx", sle_funcs,
1430                            false, false, true, true);
1431         assert(!sle_funcs.empty());
1432         vector<BPatch_snippet*> args;
1433         BPatch_constExpr lasterr(1);
1434         args.push_back(&lasterr);
1435         args.push_back(&lasterr); // need a second parameter, but it goes unused by windows
1436         BPatch_funcCallExpr callSLE (*(sle_funcs[0]), args);
1437         vector<BPatch_point*> *exitPoints = sle_funcs[0]->findPoint(BPatch_exit);
1438         beginInsertionSet();
1439         for (unsigned i=0; i < exitPoints->size(); i++) {
1440             insertSnippet( callSLE, *((*exitPoints)[i]) );
1441         }
1442     }
1443
1444     if (NULL != hybridAnalysis_) {
1445         hybridAnalysis_->addReplacedFuncs(disabledFuncs);
1446     }
1447     finalizeInsertionSet(false);
1448
1449     if (!user || !kern) {
1450         retval = false;
1451     }
1452     return retval;
1453 }
1454
1455 bool BPatch_process::setMemoryAccessRights(Address start, size_t size, Dyninst::ProcControlAPI::Process::mem_perm rights) {
1456     bool wasStopped = isStopped();
1457     if( !wasStopped ) {
1458         if (!stopExecution()) {
1459             BPatch_reportError(BPatchWarning, 0,
1460                                "Failed to stop process for setMemoryAccessRights");
1461             return false;
1462         }
1463     }
1464
1465     int result = llproc->setMemoryAccessRights(start, size, rights);
1466
1467     if( !wasStopped ) {
1468         if( !continueExecution() ) {
1469             BPatch_reportError(BPatchWarning, 0,
1470                     "Failed to continue process for setMemoryAccessRights");
1471             return false;
1472         }
1473     }
1474
1475     return (result != -1);
1476 }
1477
1478 unsigned char * BPatch_process::makeShadowPage(Dyninst::Address pageAddr)
1479 {
1480     unsigned pagesize = llproc->getMemoryPageSize();
1481     pageAddr = (pageAddr / pagesize) * pagesize;
1482
1483     Address shadowAddr = pageAddr;
1484     if (llproc->isMemoryEmulated()) {
1485         bool valid = false;
1486         boost::tie(valid, shadowAddr) = llproc->getMemEm()->translate(pageAddr);
1487         assert(valid);
1488     }
1489
1490     unsigned char* buf = (unsigned char*) ::malloc(pagesize);
1491     llproc->readDataSpace((void*)shadowAddr, pagesize, buf, true);
1492     return buf;
1493 }
1494
1495 // is the first instruction: [00 00] add byte ptr ds:[eax],al ? 
1496 static bool hasWeirdEntryBytes(func_instance *func)
1497 {
1498     using namespace SymtabAPI;
1499     Symtab *sym = func->obj()->parse_img()->getObject();
1500     if (sym->findEnclosingRegion(func->addr())
1501         !=
1502         sym->findEnclosingRegion(func->addr()+1))
1503     {
1504         return false;
1505     }
1506     unsigned short ebytes;
1507     memcpy(&ebytes,func->obj()->getPtrToInstruction(func->addr()),2);
1508
1509     if (0 == ebytes) {
1510         mal_printf("funct at %lx hasWeirdEntryBytes, 0x0000\n", func->addr());
1511         return true;
1512     }
1513     return false;
1514 }
1515
1516 void BPatch_process::overwriteAnalysisUpdate
1517     ( std::map<Dyninst::Address,unsigned char*>& owPages, //input
1518       std::vector<std::pair<Dyninst::Address,int> >& deadBlocks, //output
1519       std::vector<BPatch_function*>& owFuncs, //output: overwritten & modified
1520       std::set<BPatch_function *> &monitorFuncs, // output: those that call overwritten or modified funcs
1521       bool &changedPages, bool &changedCode) //output
1522 {
1523     //1.  get the overwritten blocks and regions
1524     std::list<std::pair<Address,Address> > owRegions;
1525     std::list<block_instance *> owBBIs;
1526     llproc->getOverwrittenBlocks(owPages, owRegions, owBBIs);
1527     changedPages = ! owRegions.empty();
1528     changedCode = ! owBBIs.empty();
1529
1530     if ( !changedCode ) {
1531         // update the mapped data for the overwritten ranges
1532         llproc->updateCodeBytes(owRegions);
1533         return;
1534     }
1535
1536     /*2. remove dead code from the analysis */
1537
1538     // identify the dead code (see getDeadCode for its parameter definitions)
1539     std::set<block_instance*> delBlocks; 
1540     std::map<func_instance*,set<block_instance*> > elimMap; 
1541     std::list<func_instance*> deadFuncs; 
1542     std::map<func_instance*,block_instance*> newFuncEntries; 
1543     llproc->getDeadCode(owBBIs,delBlocks,elimMap,deadFuncs,newFuncEntries);
1544
1545     // remove instrumentation from affected funcs
1546     beginInsertionSet();
1547     for(std::map<func_instance*,set<block_instance*> >::iterator fIter = elimMap.begin();
1548         fIter != elimMap.end();
1549         fIter++)
1550     {
1551         BPatch_function *bpfunc = findOrCreateBPFunc(fIter->first,NULL);
1552         //hybridAnalysis_->removeInstrumentation(bpfunc,false,false);
1553         bpfunc->removeInstrumentation(false);
1554     }
1555
1556     //remove instrumentation from dead functions
1557     for(std::list<func_instance*>::iterator fit = deadFuncs.begin();
1558         fit != deadFuncs.end();
1559         fit++)
1560     {
1561         // remove instrumentation
1562         findOrCreateBPFunc(*fit,NULL)->removeInstrumentation(true);
1563     }
1564
1565     finalizeInsertionSet(false);
1566
1567     // update the mapped data for the overwritten ranges
1568     llproc->updateCodeBytes(owRegions);
1569
1570     // create stub edge set which is: all edges such that:
1571     //     e->trg() in owBBIs and
1572     //     while e->src() in delBlocks choose stub from among e->src()->sources()
1573     std::map<func_instance*,vector<edgeStub> > stubs =
1574        llproc->getStubs(owBBIs,delBlocks,deadFuncs);
1575
1576     // get stubs for dead funcs
1577     map<Address,vector<block_instance*> > deadFuncCallers;
1578     for(std::list<func_instance*>::iterator fit = deadFuncs.begin();
1579         fit != deadFuncs.end();
1580         fit++)
1581     {
1582        if ((*fit)->getLiveCallerBlocks(delBlocks, deadFuncs, deadFuncCallers) &&
1583            ((*fit)->ifunc()->hasWeirdInsns() || hasWeirdEntryBytes(*fit))) 
1584        {
1585           // don't reparse the function if it's likely a garbage function, 
1586           // but mark the caller point as unresolved so we'll re-parse
1587           // if we actually call into the garbage func
1588           Address funcAddr = (*fit)->addr();
1589           vector<block_instance*>::iterator sit = deadFuncCallers[funcAddr].begin();
1590           for ( ; sit != deadFuncCallers[funcAddr].end(); sit++) {
1591              (*sit)->llb()->setUnresolvedCF(true);
1592              vector<func_instance*> cfuncs;
1593              (*sit)->getFuncs(std::back_inserter(cfuncs));
1594              for (unsigned i=0; i < cfuncs.size(); i++) {
1595                 cfuncs[i]->ifunc()->setPrevBlocksUnresolvedCF(0); // force rebuild of unresolved list
1596                 cfuncs[i]->preCallPoint(*sit, true); // create point
1597                 monitorFuncs.insert(findOrCreateBPFunc(cfuncs[i], NULL));
1598              }
1599           }
1600           deadFuncCallers.erase(deadFuncCallers.find(funcAddr));
1601        }
1602     }
1603
1604     // set new entry points for functions with NewF blocks, the active blocks
1605     // in newFuncEntries serve as suggested entry points, but will not be 
1606     // chosen if there are other blocks in the function with no incoming edges
1607     for (map<func_instance*,block_instance*>::iterator nit = newFuncEntries.begin();
1608          nit != newFuncEntries.end();
1609          nit++)
1610     {
1611         nit->first->setNewEntry(nit->second,delBlocks);
1612     }
1613     
1614     // delete delBlocks and set new function entry points, if necessary
1615     vector<PatchBlock*> delVector;
1616     for(set<block_instance*>::reverse_iterator bit = delBlocks.rbegin(); 
1617         bit != delBlocks.rend();
1618         bit++)
1619     {
1620         mal_printf("Deleting block [%lx %lx)\n", (*bit)->start(),(*bit)->end());
1621         deadBlocks.push_back(pair<Address,int>((*bit)->start(),(*bit)->size()));
1622         delVector.push_back(*bit);
1623     }
1624     if (!delVector.empty() && ! PatchAPI::PatchModifier::remove(delVector,true)) {
1625         assert(0);
1626     }
1627     mal_printf("Done deleting blocks\n"); 
1628     // delete completely dead functions // 
1629
1630     // save deadFunc block addresses in deadBlocks
1631     for(std::list<func_instance*>::iterator fit = deadFuncs.begin();
1632         fit != deadFuncs.end();
1633         fit++)
1634     {
1635         const PatchFunction::Blockset& deadBs = (*fit)->blocks();
1636         PatchFunction::Blockset::const_iterator bIter= deadBs.begin();
1637         for (; bIter != deadBs.end(); bIter++) {
1638             deadBlocks.push_back(pair<Address,int>((*bIter)->start(),
1639                                                    (*bIter)->size()));
1640         }
1641     }
1642
1643     // now actually delete the dead functions and redirect call edges to sink 
1644     // block (if there already is an edge to the sink block, redirect 
1645     // doesn't duplicate the edge)
1646     for(std::list<func_instance*>::iterator fit = deadFuncs.begin();
1647         fit != deadFuncs.end();
1648         fit++)
1649     {
1650         const PatchBlock::edgelist & srcs = (*fit)->entry()->sources();
1651         vector<PatchEdge*> srcVec; // can't operate off edgelist, since we'll be deleting edges
1652         srcVec.insert(srcVec.end(), srcs.begin(), srcs.end());
1653         for (vector<PatchEdge*>::const_iterator sit = srcVec.begin();
1654              sit != srcVec.end();
1655              sit++)
1656         {
1657            if ((*sit)->type() == ParseAPI::CALL) {
1658               PatchAPI::PatchModifier::redirect(*sit, NULL);
1659            }
1660         }
1661
1662         if (false == PatchAPI::PatchModifier::remove(*fit)) {
1663             assert(0);
1664         }
1665     }
1666     mal_printf("Done deleting functions\n");
1667
1668
1669     // set up data structures for re-parsing dead functions from stubs
1670     map<mapped_object*,vector<edgeStub> > dfstubs;
1671     for (map<Address, vector<block_instance*> >::iterator sit = deadFuncCallers.begin();
1672          sit != deadFuncCallers.end();
1673          sit++)
1674     {
1675        for (vector<block_instance*>::iterator bit = sit->second.begin();
1676             bit != sit->second.end();
1677             bit++) 
1678        {
1679           // re-instate call edges to the function
1680           dfstubs[(*bit)->obj()].push_back(edgeStub(*bit,
1681                                                     sit->first,
1682                                                     ParseAPI::CALL));
1683        }
1684    }
1685
1686     // re-parse the functions
1687     for (map<mapped_object*,vector<edgeStub> >::iterator mit= dfstubs.begin();
1688          mit != dfstubs.end(); mit++)
1689     {
1690         mit->first->setCodeBytesUpdated(false);
1691         if (mit->first->parseNewEdges(mit->second)) {
1692             // add functions to output vector
1693             for (unsigned fidx=0; fidx < mit->second.size(); fidx++) {
1694                BPatch_function *bpfunc = findFunctionByEntry(mit->second[fidx].trg);
1695                if (bpfunc) {
1696                   owFuncs.push_back(bpfunc);
1697                } else {
1698                   // couldn't reparse
1699                   mal_printf("WARNING: Couldn't re-parse an overwritten "
1700                              "function at %lx %s[%d]\n", mit->second[fidx].trg, 
1701                              FILE__,__LINE__);
1702                }
1703             }
1704         } else {
1705             mal_printf("ERROR: Couldn't re-parse overwritten "
1706                        "functions %s[%d]\n", FILE__,__LINE__);
1707         }
1708     }
1709
1710     //3. parse new code, one overwritten function at a time
1711     for(std::map<func_instance*,set<block_instance*> >::iterator
1712         fit = elimMap.begin();
1713         fit != elimMap.end();
1714         fit++)
1715     {
1716         // parse new edges in the function
1717        if (!stubs[fit->first].empty()) {
1718           fit->first->obj()->parseNewEdges(stubs[fit->first]);
1719        } else {
1720           // stubs may have been shared with another function and parsed in 
1721           // the other function's context.  
1722           mal_printf("WARNING: didn't have any stub edges for overwritten "
1723                      "func %lx\n", fit->first->addr());
1724           //KEVINTEST: we used to wind up here with deleted functions, hopefully we do not anymore
1725        }
1726         // add curFunc to owFuncs, and clear the function's BPatch_flowGraph
1727         BPatch_function *bpfunc = findOrCreateBPFunc(fit->first,NULL);
1728         bpfunc->removeCFG();
1729         owFuncs.push_back(bpfunc);
1730     }
1731
1732     // do a consistency check
1733     for(std::map<func_instance*,set<block_instance*> >::iterator 
1734         fit = elimMap.begin();
1735         fit != elimMap.end();
1736         fit++) 
1737     {
1738         assert(fit->first->consistency());
1739     }
1740 }
1741
1742 /* Protect analyzed code without protecting relocated code in the
1743  * runtime library and for now only protect code in the aOut,
1744  * also don't protect code that hasn't been analyzed
1745  */
1746 bool BPatch_process::protectAnalyzedCode()
1747 {
1748     bool ret = true;
1749     BPatch_Vector<BPatch_module *> *bpMods = image->getModules();
1750     for (unsigned midx=0; midx < bpMods->size(); midx++) {
1751        if (!(*bpMods)[midx]->setAnalyzedCodeWriteable(false)) {
1752            ret = false;
1753        }
1754     }
1755     return ret;
1756 }