These are the windows fixes that I previously alluded to, combined with
[dyninst.git] / dyninstAPI / src / process.C
1 /*
2  * Copyright (c) 1996-2006 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: process.C,v 1.717 2008/05/09 00:25:38 jaw Exp $
43
44 #include <ctype.h>
45
46 #if defined(i386_unknown_solaris2_5)
47 #include <sys/procfs.h>
48 #endif
49
50 #include <set>
51 #include <string>
52
53 #include <stdio.h>
54
55 #include "common/h/headers.h"
56 #include "dyninstAPI/src/function.h"
57 #include "symtabAPI/h/Symtab.h"
58 //#include "dyninstAPI/src/func-reloc.h"
59 #include "dyninstAPI/src/baseTramp.h"
60 #include "dyninstAPI/src/miniTramp.h"
61 #include "dyninstAPI/src/symtab.h"
62 #include "dyninstAPI/src/dyn_thread.h"
63 #include "dyninstAPI/src/dyn_lwp.h"
64 #include "dyninstAPI/src/signalhandler.h"
65 #include "dyninstAPI/src/signalgenerator.h"
66 #include "dyninstAPI/src/mailbox.h"
67 #include "dyninstAPI/src/EventHandler.h"
68 #include "dyninstAPI/src/process.h"
69 #include "dyninstAPI/src/util.h"
70 #include "dyninstAPI/src/inst.h"
71 #include "dyninstAPI/src/instP.h"
72 #include "dyninstAPI/src/instPoint.h"
73 #include "dyninstAPI/src/os.h"
74 #include "dyninstAPI/src/debug.h"
75 #include "dyninstAPI/src/dynamiclinking.h"
76 #include "dyninstAPI/src/BPatch_asyncEventHandler.h"
77 #include "dyninstAPI/src/debuggerinterface.h"
78 #include "dyninstAPI_RT/h/dyninstAPI_RT.h"
79 #include "dyninstAPI/src/InstrucIter.h"
80 #include "dyninstAPI/src/ast.h"
81
82 // #include "paradynd/src/mdld.h"
83 #include "common/h/Timer.h"
84 #include "common/h/Time.h"
85 #include "common/h/timing.h"
86
87 #include "dyninstAPI/src/rpcMgr.h"
88
89 #include "mapped_module.h"
90 #include "mapped_object.h"
91
92 #include "dyninstAPI/h/BPatch.h"
93
94 #if defined(sparc_sun_solaris2_4) \
95  || defined(i386_unknown_linux2_0) \
96  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
97 #include "dyninstAPI/src/writeBackElf.h"
98 #include "dyninstAPI/src/saveSharedLibrary.h" 
99 #elif defined(rs6000_ibm_aix4_1)
100 #include "dyninstAPI/src/writeBackXCOFF.h"
101 #endif
102
103 #include "dyninstAPI/src/syscallNotification.h"
104
105 #include "common/h/debugOstream.h"
106
107 #include "common/h/Timer.h"
108
109 #include "dyninstAPI_RT/h/dyninstAPI_RT.h"
110 using namespace Dyninst;
111
112 #define P_offsetof(s, m) (Address) &(((s *) NULL)->m)
113
114 #define FREE_WATERMARK (hp->totalFreeMemAvailable/2)
115 #define SIZE_WATERMARK 100
116 static const timeLength MaxWaitingTime(10, timeUnit::sec());
117 static const timeLength MaxDeletingTime(2, timeUnit::sec());
118
119 unsigned activeProcesses; // number of active processes
120 pdvector<process*> processVec;
121
122 #if defined(i386_unknown_linux2_0) \
123  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
124 extern void cleanupVsysinfo(void *ehd);
125 #endif
126
127 pdvector<instMapping*> initialRequests;
128
129 void printLoadDyninstLibraryError() {
130     cerr << "Paradyn/Dyninst failed to load the runtime library. This is normally caused by " << endl;
131     cerr << "one of the following:" << endl;
132     cerr << "Incorrect DYNINSTAPI_RT_LIB environment variable" << endl;
133     cerr << "Missing RT library" << endl;
134     cerr << "Unavailable dependency of the library" << endl;
135 #if defined(rs6000_ibm_aix4_1)
136     cerr << "   libDyninstText.a must exist in a directory in the LIBPATH environment variable" << endl;
137 #endif
138     cerr << "Please check your environment and try again." << endl;
139 }
140
141 /* AIX method defined in aix.C; hijacked for IA-64's GP. */
142 #if !defined(arch_power) \
143  && !defined(ia64_unknown_linux2_4)
144 Address process::getTOCoffsetInfo(Address /*dest */)
145 {
146   Address tmp = 0;
147   assert(0 && "getTOCoffsetInfo not implemented");
148   return tmp; // this is to make the nt compiler happy! - naim
149 }
150 #else
151 Address process::getTOCoffsetInfo(Address dest)
152 {
153    // Linux-power-32 bit: return 0 here, as it doesn't use the TOC.
154    // Linux-power-64 does. Lovely. 
155 #if defined(arch_power) && defined(os_linux)
156    if (getAddressWidth() == 4)
157       return 0;
158 #endif
159
160     // We have an address, and want to find the module the addr is
161     // contained in. Given the probabilities, we (probably) want
162     // the module dyninst_rt is contained in.
163     // I think this is the right func to use
164     
165     // Find out which object we're in (by addr).
166     codeRange *range = NULL;
167     textRanges_.find(dest, range);
168     if (!range)  // Try data?
169         dataRanges_.find(dest, range);
170     if (!range)
171         return 0;
172     mapped_object *mobj = range->is_mapped_object();
173     if (!mobj) {
174         mappedObjData *tmp = dynamic_cast<mappedObjData *>(range);
175         if (tmp)
176             mobj = tmp->obj;
177     }
178     // Very odd case if this is not defined.
179     assert(mobj);
180     Address TOCOffset = mobj->parse_img()->getObject()->getTOCoffset(); 
181     if (!TOCOffset)
182        return 0;
183     return TOCOffset + mobj->dataBase();
184
185 }
186
187 Address process::getTOCoffsetInfo(int_function *func) {
188
189 #if defined(arch_power) && defined(os_linux)
190    // See comment above.
191    if (getAddressWidth() == 4)
192       return 0;
193 #endif
194
195     mapped_object *mobj = func->obj();
196
197     return mobj->parse_img()->getObject()->getTOCoffset() + mobj->dataBase();
198 }
199
200 #endif
201
202 #if defined(os_linux) && (defined(arch_x86) || defined(arch_x86_64))
203 extern void calcVSyscallFrame(process *p);
204 #endif
205
206 // Note: stack walks may terminate early. In this case, return what we can.
207 // Relies on the getCallerFrame method in the various <os>.C files
208 #if !defined(os_linux)
209 Frame process::preStackWalkInit(Frame startFrame) {
210     return startFrame;
211 }
212 #endif
213
214 bool process::walkStackFromFrame(Frame startFrame,
215                                  pdvector<Frame> &stackWalk)
216 {
217 #if !defined( arch_x86) && !defined(arch_x86_64)
218   Address fpOld   = 0;
219 #endif
220   if (!isStopped())
221       return false;
222
223   Frame currentFrame = preStackWalkInit(startFrame);
224
225   while (!currentFrame.isLastFrame()) {
226
227 #if !defined( arch_x86) && !defined(arch_x86_64)
228     // Check that we are not moving up the stack.  Not relevant on x86,
229     // since the frame pointer may be used for data.
230     // successive frame pointers might be the same (e.g. leaf functions)
231     if (fpOld > currentFrame.getFP())
232         return false;
233     fpOld = currentFrame.getFP();
234 #endif
235
236     stackWalk.push_back(currentFrame);
237     currentFrame = currentFrame.getCallerFrame();
238   }
239   if (currentFrame.getProc() != NULL)
240       stackWalk.push_back(currentFrame);
241
242   return true;
243 }
244
245 FILE *debugfd = NULL;
246
247 // Return a vector (possibly with one object) of active frames
248 // in the process
249
250 bool process::getAllActiveFrames(pdvector<Frame> &activeFrames)
251 {
252   Frame active;
253   bool success = true;
254   if (!threads.size()) { // Nothing defined in the thread data structures
255     // So use the process LWP instead (Dyninst)
256     active = getRepresentativeLWP()->getActiveFrame();
257     if (active == Frame()) { // Hrm.. should getActive return a bool?
258       return false;
259     }
260     activeFrames.push_back(active);
261   }
262   else { // Iterate through threads
263     for (unsigned i = 0; i < threads.size(); i++) {
264       active = threads[i]->getActiveFrame();
265       if (active == Frame()) {
266         success = true;
267       }
268       else {
269         activeFrames.push_back(active);
270       }
271     }
272   }
273   return success;
274 }
275
276 bool process::walkStacks(pdvector<pdvector<Frame> >&stackWalks)
277 {
278         bool needToContinue = false;
279         bool retval = true;
280         
281         if (!isStopped()) {
282                 needToContinue = true;
283                 pause();
284         }
285         
286         pdvector<Frame> stackWalk;
287         if (!threads.size()) { // Nothing defined in thread data structures
288         if (!getRepresentativeLWP()->walkStack(stackWalk)) {
289                         retval = false;
290                 }
291         else {
292                         // Use the walk from the default LWP
293                 stackWalks.push_back(stackWalk);
294                 }
295         }
296         else { // Have threads defined
297         for (unsigned i = 0; i < threads.size(); i++) {
298                 if (!threads[i]->walkStack(stackWalk)) {
299                                 retval = false;
300                         }
301                 else {
302                                 stackWalks.push_back(stackWalk);
303                         stackWalk.clear();
304                         }
305         }
306         }
307         if (needToContinue)
308                 continueProc();
309                 
310         return retval;
311 }
312
313 // Search an object for heapage
314
315 bool process::getInfHeapList(const mapped_object *obj,
316                              pdvector<heapDescriptor> &infHeaps)
317 {
318
319     pdvector<mapped_object::foundHeapDesc> foundHeaps;
320     obj->getInferiorHeaps(foundHeaps);
321
322     for (u_int j = 0; j < foundHeaps.size(); j++)
323     {
324         // The string layout is: DYNINSTstaticHeap_size_type_unique
325         // Can't allocate a variable-size array on NT, so malloc
326         // that sucker
327         char *temp_str = (char *)malloc(strlen(foundHeaps[j].name.c_str())+1);
328         strcpy(temp_str, foundHeaps[j].name.c_str());
329         char *garbage_str = strtok(temp_str, "_"); // Don't care about beginning
330         assert(!strcmp("DYNINSTstaticHeap", garbage_str));
331         // Name is as is.
332         // If address is zero, then skip (error condition)
333         if (foundHeaps[j].addr == 0)
334         {
335             cerr << "Skipping heap " << foundHeaps[j].name.c_str()
336                  << "with address 0" << endl;
337             continue;
338         }
339         // Size needs to be parsed out (second item)
340         // Just to make life difficult, the heap can have an optional
341         // trailing letter (k,K,m,M,g,G) which indicates that it's in
342         // kilobytes, megabytes, or gigabytes. Why gigs? I was bored.
343         char *heap_size_str = strtok(NULL, "_"); // Second element, null-terminated
344         unsigned heap_size = (unsigned) atol(heap_size_str);
345         if (heap_size == 0)
346             /* Zero size or error, either way this makes no sense for a heap */
347         {
348             free(temp_str);
349             continue;
350         }
351         switch (heap_size_str[strlen(heap_size_str)-1])
352         {
353       case 'g':
354       case 'G':
355           heap_size *= 1024;
356       case 'm':
357       case 'M':
358           heap_size *= 1024;
359       case 'k':
360       case 'K':
361           heap_size *= 1024;
362       default:
363           break;
364         }
365         
366         // Type needs to be parsed out. Can someone clean this up?
367         inferiorHeapType heap_type;
368         char *heap_type_str = strtok(NULL, "_");
369         
370         if (!strcmp(heap_type_str, "anyHeap"))
371             heap_type = anyHeap;
372         else if (!strcmp(heap_type_str, "lowmemHeap"))
373             heap_type = lowmemHeap;
374         else if (!strcmp(heap_type_str, "dataHeap"))
375             heap_type = dataHeap;
376         else if (!strcmp(heap_type_str, "textHeap"))
377             heap_type = textHeap;
378         else if (!strcmp(heap_type_str, "uncopiedHeap"))
379             heap_type = uncopiedHeap;
380         else
381         {
382             cerr << "Unknown heap string " << heap_type_str << " read from file!" << endl;
383             free(temp_str);
384             continue;
385         }
386         infHeaps.push_back(heapDescriptor(foundHeaps[j].name.c_str(),
387                                           foundHeaps[j].addr, 
388                                           heap_size, heap_type));
389         free(temp_str);
390     }
391   return foundHeaps.size() > 0;
392 }
393
394 /*
395  * Returns true if the address given is within the signal handler function,
396  * otherwise returns false.
397  */
398 bool process::isInSignalHandler(Address addr)
399 {
400 #if defined(arch_ia64)
401     // We handle this elsewhere
402     return false;
403 #endif
404     codeRange *range;
405     if (signalHandlerLocations_.find(addr, range))
406         return true;
407     return false;
408 }
409
410 /*
411  * This function adds an item to the dataUpdates vector
412  * which is used to maintain a list of variables that have
413  * been written by the mutator //ccw 26 nov 2001
414  */
415  
416 #if defined(sparc_sun_solaris2_4) \
417  || defined(i386_unknown_linux2_0) \
418  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
419  || defined(rs6000_ibm_aix4_1)
420
421 void process::saveWorldData( Address address, int size, const void * src ) {
422         if( collectSaveWorldData ) {
423                 dataUpdate *newData = new dataUpdate;
424                 newData->address= address;
425                 newData->size = size;
426                 newData->value = new char[size];
427                 memcpy(newData->value, src, size);
428                 dataUpdates.push_back(newData);
429                 }
430         } /* end saveWorldData() */
431         
432 #else
433
434 void process::saveWorldData( Address, int, const void* ) { ; }    
435
436 #endif
437
438 #if defined (cap_save_the_world) 
439
440 #if defined(sparc_sun_solaris2_4) \
441  || defined(i386_unknown_linux2_0) \
442  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
443  || defined(rs6000_ibm_aix4_1)
444 /* || defined(rs6000_ibm_aix4_1)*/
445
446 char* process::saveWorldFindDirectory(){
447
448         const char* directoryNameExt = "_dyninstsaved";
449         int dirNo = 0;
450 /* ccw */
451         char cwd[1024];
452         char* directoryName;
453         int lastChar;
454         getcwd(cwd, 1024);
455         lastChar = strlen(cwd);
456
457         if( cwd[lastChar] != '/' && lastChar != 1023){
458                 cwd[lastChar] = '/';
459                 cwd[++lastChar] ='\0';
460         }
461
462         directoryName = new char[strlen(cwd) +
463                         strlen(directoryNameExt) + 3+1+1];
464 /* ccw */
465         sprintf(directoryName,"%s%s%x",cwd, directoryNameExt,dirNo);
466         while(dirNo < 0x1000 && mkdir(directoryName, S_IRWXU) ){
467                  if(errno == EEXIST){
468                          dirNo ++;
469                  }else{
470                          BPatch_reportError(BPatchSerious, 122, "dumpPatchedImage: cannot open directory to store mutated binary. No files saved\n");
471                          delete [] directoryName;
472                          return NULL;
473                  }
474                  sprintf(directoryName, "%s%s%x",cwd,
475                          directoryNameExt,dirNo);
476         }
477         if(dirNo == 0x1000){
478                  BPatch_reportError(BPatchSerious, 122, "dumpPatchedImage: cannot open directory to store mutated binary. No files saved\n");
479                  delete [] directoryName;
480                  return NULL;
481         }
482         return directoryName;
483
484 }
485 #endif
486 #endif
487
488 #if defined (cap_save_the_world)
489 #if defined(sparc_sun_solaris2_4) \
490  || defined(i386_unknown_linux2_0) \
491  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
492
493
494 char *process::saveWorldFindNewSharedLibraryName(string originalLibNameFullPath, char* dirName){
495         const char *originalLibName = originalLibNameFullPath.c_str();
496         unsigned int index=0;
497
498         unsigned int nextIndex = 0;
499         for(nextIndex = 0; nextIndex < originalLibNameFullPath.length() ;nextIndex++){
500                 if(originalLibName[nextIndex] == '/'){
501                         index = nextIndex +1;
502                 }
503         }
504
505         string oldLibName = originalLibNameFullPath.substr(index,originalLibNameFullPath.length());
506         char* newLibName = new char[strlen(dirName) + oldLibName.length()+1];
507         memcpy(newLibName,dirName,strlen(dirName)+1);
508         newLibName =strcat(newLibName, oldLibName.c_str());
509
510         return newLibName;
511
512         
513 }
514
515
516
517 unsigned int process::saveWorldSaveSharedLibs(int &mutatedSharedObjectsSize, 
518                                  unsigned int &dyninst_SharedLibrariesSize, 
519                                  char* directoryName, unsigned int &count) {
520
521    unsigned int dl_debug_statePltEntry=0;
522 #if defined(sparc_sun_solaris2_4)
523    unsigned int tmp_dlopen;
524 #endif
525    bool dlopenUsed = false;
526    
527    //In the mutated binary we need to catch the dlopen events and adjust the
528    //instrumentation of the shared libraries (and jumps into the shared
529    //libraries) as the base address of the shared libraries different for the
530    //base addresses during the original mutator/mutatee run.
531
532    //the r_debug interface ensures that a change to the dynamic linking
533    //information causes _dl_debug_state to be called.  This is because dlopen
534    //is too small and odd to instrument/breakpoint.  So our code will rely on
535    //this fact. (all these functions are contained in ld-linux.so)
536
537    //Our method: The Procedure Linking Table (.plt) for ld-linux contains an
538    //entry that jumps to a specified address in the .rel.plt table. To call a
539    //function, the compiler generates a jump to the correct .plt entry which
540    //reads its jump value out of the .rel.plt.
541
542    //On the sly, secretly replace the entry in .rel.plt with folgers crystals
543    //and poof, we jump to our own function in RTcommon.c
544    //(dyninst_dl_debug_state) [actually we replace the entry in .rel.plt with
545    //the address of dyninst_dl_debug_state].  To ensure correctness,
546    //dyninst_dl_debug_state contains a call to the real _dl_debug_state
547    //immediately before it returns, thus ensuring any code relying on that
548    //fact that _dl_debug_state is actually run remains happy.
549
550    //It is very important then, that we know the location of the entry in the
551    //.rel.plt table.  We need to record the offset of this entry with respect
552    //to the base address of ld-linux.so (for obvious reasons) This offset is
553    //then sent to RTcommon.c, and here is the slick part, by assigning it to
554    //the 'load address' of the section "dyninstAPI_SharedLibraries," which
555    //contains the shared library/basei address pairs used to fixup the saved
556    //binary. This way when checkElfFile() reads the section the offset will
557    //be there in the section header.
558
559    //neat, eh?  this is how it will work in the future, currently this is not
560    //yet fully implemented and part of the cvs tree.
561
562    //UPDATE: the above is implemented EXCEPT for adjusting the instrumentation
563    //when shared libraries move. currently an error is thrown when a shared
564    //lib is in the wrong place and execution is terminated!
565
566         //I have now added the notion of DirtyCalled to a shared library.
567         //This is a library that contains a function that is called by
568         //instrumentation.  The shared lib may or may not be instrumented itself.
569         //If it is not instrumented (Dirty) then it is NOT saved as a mutated 
570         //shared library.  A flag in dyninstAPI_mutatedSO section that follows
571         //the filename denotes whether the library is Dirty or merely DirtyCalled
572
573    count = 0;
574    for (unsigned i = 1; i < mapped_objects.size(); i++) {
575      // We start at 1 because 0 is the a.out
576      mapped_object *sh_obj = mapped_objects[i];
577
578       //ccw 24 jul 2003
579       if( (sh_obj->isDirty() || sh_obj->isDirtyCalled()) &&
580                 /* there are some libraries we should not save even if they are marked as mutated*/
581                 NULL==strstr(sh_obj->fileName().c_str(),"libdyninstAPI_RT") && 
582                 NULL== strstr(sh_obj->fileName().c_str(),"ld-linux.so") && 
583                 NULL==strstr(sh_obj->fileName().c_str(),"libc")){ //ccw 6 jul 2003
584          count ++;
585          if(!dlopenUsed && sh_obj->isopenedWithdlopen()){
586             BPatch_reportError(BPatchWarning,123,"dumpPatchedImage: dlopen used by the mutatee, this may cause the mutated binary to fail\n");
587             dlopenUsed = true;
588          }                      
589          //bperr(" %s is DIRTY!\n", sh_obj->fileName().c_str());
590         
591
592          if( sh_obj->isDirty()){ 
593                         //fprintf(stderr," SAVING SHARED LIB: %s\n", sh_obj->fileName().c_str());
594             //if the lib is only DirtyCalled dont save it! //ccw 24 jul 2003
595             Address textAddr, textSize;
596             char *newName = saveWorldFindNewSharedLibraryName(sh_obj->fileName(),directoryName);
597
598                 /*      what i need to do:
599                         open the ORIGINAL shared lib --> sh_obj->fileName()
600                         read the text section out.
601                         reapply the instrumentation code
602                         save this new, instrumented text section back to the NEW DLDUMPED file in the _dyninstSaved# dir --> newName
603                 */               
604
605             saveSharedLibrary *sharedObj =
606                new saveSharedLibrary(sh_obj->getBaseAddress(),
607                                      sh_obj->fullName().c_str(), newName);
608
609                 sharedObj->openBothLibraries();
610             
611                 sharedObj->getTextInfo(textAddr, textSize);
612                 char* textSection ;//= sharedObj->getTextSection(); /* get the text section from the ORIGINAL library */
613                 textSection = new char[textSize]; //ccw 14 dec 2005
614
615                 if(textSection){
616
617                         //applyMutationsToTextSection(textSection, textAddr, textSize);
618
619                         readDataSpace((void*)textAddr, textSize, (void*)textSection, true); //ccw 14 dec 2005
620                         sharedObj->saveMutations(textSection);
621                         sharedObj->closeNewLibrary();
622                         delete [] textSection;
623                 }else{
624                         char msg[strlen(sh_obj->fileName().c_str())+100];
625                         sprintf(msg,"dumpPatchedImage: could not retreive .text section for %s\n",sh_obj->fileName().c_str());
626                         BPatch_reportError(BPatchWarning,123,msg);
627                         sharedObj->closeNewLibrary();
628                 }
629                 //sharedObj->closeOriginalLibrary();
630                 delete sharedObj;
631                 delete [] newName;
632          }
633          mutatedSharedObjectsSize += strlen(sh_obj->fileName().c_str()) +1 ;
634          mutatedSharedObjectsSize += sizeof(int); //a flag to say if this is only DirtyCalled
635       }
636       //this is for the dlopen problem...
637       if(strstr(sh_obj->fileName().c_str(), "ld-linux.so") ){
638          //find the offset of _dl_debug_state in the .plt
639          Symtab *obj = sh_obj->parse_img()->getObject();
640          vector<relocationEntry> fbt;
641          obj->getFuncBindingTable(fbt);
642          dl_debug_statePltEntry = 0;
643          for(unsigned i=0; i<fbt.size();i++)
644          {
645                 if(fbt[i].name() == "_dl_debug_state")
646                         dl_debug_statePltEntry = fbt[i].rel_addr();
647          }
648       }
649 #if defined(sparc_sun_solaris2_4)
650       relocationEntry re;
651       tmp_dlopen = 0;
652       vector<relocationEntry> fbt;
653       sh_obj->parse_img()->getObject()->getFuncBindingTable(fbt);
654       for( unsigned int i = 0; i < fbt.size(); i++ )
655       {
656         if("dlopen" == fbt[i].name())
657                 tmp_dlopen =  fbt[i].rel_addr();
658       }
659       
660       if( tmp_dlopen && (!sh_obj->isopenedWithdlopen()))
661       {
662          dl_debug_statePltEntry = tmp_dlopen + sh_obj->getBaseAddress();
663       }
664 #endif
665       //this is for the dyninst_SharedLibraries section we need to find out
666       //the length of the names of each of the shared libraries to create the
667       //data buffer for the section
668       
669       dyninst_SharedLibrariesSize += strlen(sh_obj->fileName().c_str())+1;
670       //add the size of the address
671       dyninst_SharedLibrariesSize += sizeof(unsigned int);
672    }
673 #if defined(sparc_sun_solaris2_4)
674    if(tmp_dlopen) {
675        dl_debug_statePltEntry = tmp_dlopen;
676    }
677    
678    //dl_debug_statePltEntry = parse_img()->getObject()->getPltSlot("dlopen");
679 #endif
680    dyninst_SharedLibrariesSize += 1;//for the trailing '\0'
681    
682    return dl_debug_statePltEntry;
683 }
684         
685 bool process::applyMutationsToTextSection(char* /*textSection*/, unsigned /*textAddr*/, 
686                                           unsigned /*textSize*/)
687 {
688     // Uhh... what does this do?
689 #if 0
690         mutationRecord *mr = afterMutationList.getHead();
691
692         while (mr != NULL) {
693             if( mr->addr >= textAddr && mr->addr < (textAddr+textSize)){
694                 memcpy(&(textSection[mr->addr-textAddr]), mr->data, mr->size);
695             }
696             mr = mr->next;
697         }
698         return true;
699 #endif
700    return true;
701 }
702
703 char* process::saveWorldCreateSharedLibrariesSection(int dyninst_SharedLibrariesSize){
704         //dyninst_SharedLibraries
705         //the SharedLibraries sections contains a list of all the shared libraries
706         //that have been loaded and the base address for each one.
707         //The format of the sections is:
708         //
709         //sharedlibraryName
710         //baseAddr
711         //...
712         //sharedlibraryName
713         //baseAddr
714         //'\0'
715         
716         char *dyninst_SharedLibrariesData = new char[dyninst_SharedLibrariesSize];
717         char *ptr= dyninst_SharedLibrariesData;
718         //int size = mapped_objects->size() - 1; // a.out is included as well
719         mapped_object *sh_obj;
720
721         for(unsigned i=1; i < mapped_objects.size(); i++) {
722           sh_obj = mapped_objects[i];
723
724                 memcpy((void*) ptr, sh_obj->fileName().c_str(), strlen(sh_obj->fileName().c_str())+1);
725                 //fprintf(stderr,"loaded shared libs %s : ", ptr);
726                 ptr += strlen(sh_obj->fileName().c_str())+1;
727
728                 unsigned int baseAddr = sh_obj->getBaseAddress();
729                 /*      LINUX PROBLEM. in the link_map structure the map->l_addr field is NOT
730                         the load address of the dynamic object, as the documentation says.  It is the
731                         RELOCATED address of the object. If the object was not relocated then the
732                         value is ZERO.
733
734                         So, on LINUX we check the address of the dynamic section, map->l_ld, which is
735                         correct.
736                 */
737 #if defined(i386_unknown_linux2_0) || defined(x86_64_unknown_linux2_4)
738                 Symbol info;
739                 std::string dynamicSection = "_DYNAMIC";
740                 sh_obj->getSymbolInfo(dynamicSection,info);
741                 baseAddr = sh_obj->getBaseAddress() + info.getAddr();
742                 //fprintf(stderr," %s DYNAMIC ADDR: %x\n",sh_obj->fileName().c_str(), baseAddr);
743 #endif
744
745                 memcpy( (void*)ptr, &baseAddr, sizeof(unsigned int));
746                 //fprintf(stderr," 0x%x \n", *(unsigned int*) ptr);
747                 ptr += sizeof(unsigned int);
748         }
749         memset( (void*)ptr, '\0' , 1);
750
751         return dyninst_SharedLibrariesData;
752 }
753 #endif
754 #endif
755
756 #if defined (cap_save_the_world)
757 #if defined(sparc_sun_solaris2_4) \
758  || defined(i386_unknown_linux2_0) \
759  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
760  || defined(rs6000_ibm_aix4_1)
761 void process::saveWorldCreateHighMemSections(
762                         pdvector<imageUpdate*> &compactedHighmemUpdates, 
763                         pdvector<imageUpdate*> &highmem_updates,
764                         void *ptr) {
765
766    Address guardFlagAddr= trampGuardBase();
767
768    unsigned int pageSize = getpagesize();
769    unsigned int startPage, stopPage;
770    unsigned int numberUpdates=1;
771    int startIndex, stopIndex;
772    char *data;
773    char name[50];
774 #if defined(sparc_sun_solaris2_4) \
775  || defined(i386_unknown_linux2_0) \
776  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
777         writeBackElf *newFile = (writeBackElf*) ptr;
778 #elif defined(rs6000_ibm_aix4_1)
779         writeBackXCOFF *newFile = (writeBackXCOFF*) ptr;
780
781 #endif
782
783 #if 0
784    unsigned int trampGuardValue;
785         bool err ;
786 //#if !defined(rs6000_ibm_aix4_1)
787
788         /*fprintf(stderr,"guardFlagAddr %x\n",guardFlagAddr);*/
789 //      readDataSpace((void*) guardFlagAddr, sizeof(unsigned int),
790 //                (void*) &trampGuardValue, true);
791    
792
793         for(int i=0;i< max_number_of_threads;i++){
794                 err = writeDataSpace((void*) &( ((int *)guardFlagAddr)[i]), sizeof(unsigned int),
795                   (void*) &numberUpdates);
796                 if (!err) fprintf(stderr, "%s[%d][%s]:  writeDataSpace failed\n", FILE__, __LINE__, getThreadStr(getExecThreadID()));
797                         assert(err);
798
799                 saveWorldData( (Address) &( ((int *)guardFlagAddr)[i]),sizeof(unsigned int), &numberUpdates); //ccw 7 jul 2003
800         }
801 #endif
802
803       sprintf(name,"dyninstAPItrampguard");
804
805         data = new char[sizeof(max_number_of_threads)*max_number_of_threads];
806         memcpy(data, &max_number_of_threads,sizeof(max_number_of_threads));
807         //fprintf(stderr,"WRITING: max_number_of_threads %d\n",max_number_of_threads);
808         //ccw 14 dec 2005
809 #if defined(sparc_sun_solaris2_4) \
810  || defined(i386_unknown_linux2_0) \
811  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
812       newFile->addSection(guardFlagAddr,data,sizeof(max_number_of_threads),name,false);
813 #elif defined(rs6000_ibm_aix4_1)
814         sprintf(name,"trampg");
815         //fprintf(stderr," trampg 0x%x\n",guardFlagAddr);
816         newFile->addSection(name,guardFlagAddr,guardFlagAddr,sizeof(unsigned int) *max_number_of_threads,data);
817         //newFile->setDataEnd(guardFlagAddr+sizeof(unsigned int) *max_number_of_threads);
818 #endif
819         delete []data;
820
821                 
822 #if  defined(i386_unknown_linux2_0) \
823  || defined(x86_64_unknown_linux2_4) \
824  || defined(sparc_sun_solaris2_4)
825
826 #if defined(sparc_sun_solaris2_4)
827         if( imageUpdates.size() == 0 ){
828 #endif
829         //fprintf(stderr,"LOADING trampgu 0x%x\n",guardFlagAddr);
830         data = new char[sizeof(unsigned int) * max_number_of_threads];
831         memset(data,1,sizeof(unsigned int) * max_number_of_threads);            
832         newFile->addSection(guardFlagAddr,data,sizeof(unsigned int) * max_number_of_threads,"dyninstAPI_1",false);
833         delete []data;
834 #if defined(sparc_sun_solaris2_4)
835         }
836 #endif
837 #endif
838
839    for(unsigned int j=0; j<compactedHighmemUpdates.size(); j++) {
840       //the layout of dyninstAPIhighmem_%08x is:
841       //pageData
842       //address of update
843       //size of update
844       // ...
845       //address of update
846       //size of update
847       //number of updates
848
849       startPage = compactedHighmemUpdates[j]->address - 
850                   compactedHighmemUpdates[j]->address % pageSize;
851       stopPage = compactedHighmemUpdates[j]->address + 
852                  compactedHighmemUpdates[j]->size -
853                  (compactedHighmemUpdates[j]->address + 
854                   compactedHighmemUpdates[j]->size) % pageSize;
855
856       numberUpdates = 0;
857       startIndex = -1;
858       stopIndex = -1;
859       
860       for(unsigned index = 0;index < highmem_updates.size(); index++){
861          //here we ignore anything with an address of zero.
862          //these can be safely deleted in writeBackElf
863          if( highmem_updates[index]->address && 
864              startPage <= highmem_updates[index]->address &&
865              highmem_updates[index]->address  < (startPage + pageSize /*compactedHighmemUpdates[j]->sizei*/)){
866             numberUpdates ++;
867             stopIndex = index;
868             if(startIndex == -1){
869                startIndex = index;
870             }
871            //bperr(" HighMemUpdates address 0x%x \n", highmem_updates[index]->address );
872          }
873         //bperr(" high mem updates: 0x%x", highmem_updates[index]->address);
874       }
875       unsigned int dataSize = compactedHighmemUpdates[j]->size + 
876          sizeof(unsigned int) + 
877          (2*(stopIndex - startIndex + 1) /*numberUpdates*/ * sizeof(unsigned int));
878
879         //bperr("DATASIZE: %x : %x + 4 + ( 2*(%x - %x +1) * 4)\n", dataSize, compactedHighmemUpdates[j]->size, stopIndex, startIndex);
880       
881       data = new char[dataSize];
882       
883       //fill in pageData
884       readDataSpace((void*) compactedHighmemUpdates[j]->address, 
885                     compactedHighmemUpdates[j]->size, data, true);
886       
887       unsigned int *dataPtr = 
888          (unsigned int*) ( (char*) data + compactedHighmemUpdates[j]->size);
889
890       //fill in address of update
891       //fill in size of update
892       for(int index = startIndex; index<=stopIndex;index++){ 
893
894          memcpy(dataPtr, &highmem_updates[index]->address,
895                 sizeof(unsigned int));
896          dataPtr ++;
897          memcpy(dataPtr, &highmem_updates[index]->size, sizeof(unsigned int));
898
899          dataPtr++;
900          //bperr("%d J %d ADDRESS: 0x%x SIZE 0x%x\n",index, j,
901          //highmem_updates[index]->address, highmem_updates[index]->size);
902
903         
904       }
905       //fill in number of updates
906       memcpy(dataPtr, &numberUpdates, sizeof(unsigned int));
907
908       //bperr(" NUMBER OF UPDATES 0x%x  %d %x\n\n",numberUpdates,dataSize,dataSize);
909       sprintf(name,"dyninstAPIhighmem_%08x",j);
910 #if defined(sparc_sun_solaris2_4) \
911  || defined(i386_unknown_linux2_0) \
912  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
913       newFile->addSection(compactedHighmemUpdates[j]->address,data ,dataSize,name,false);
914 #elif defined(rs6000_ibm_aix4_1)
915           sprintf(name, "dyH_%03x",j);
916       newFile->addSection(&(name[0]), compactedHighmemUpdates[j]->address,compactedHighmemUpdates[j]->address,
917                 dataSize, (char*) data );
918
919 #endif
920       
921       //lastCompactedUpdateAddress = compactedHighmemUpdates[j]->address+1;
922       delete [] (char*) data;
923    }
924 #if 0
925    err = writeDataSpace((void*)guardFlagAddr, sizeof(unsigned int), 
926                   (void*)&trampGuardValue);
927    if (!err) fprintf(stderr, "%s[%d][%s]:  writeDataSpace failed\n", FILE__, __LINE__, getThreadStr(getExecThreadID()));
928         assert(err);
929 #endif 
930 }
931
932 void process::saveWorldCreateDataSections(void* ptr){
933
934 #if defined(sparc_sun_solaris2_4) \
935  || defined(i386_unknown_linux2_0) \
936  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
937         writeBackElf *newFile = (writeBackElf*) ptr;
938 #elif defined(rs6000_ibm_aix4_1)
939         writeBackXCOFF *newFile = (writeBackXCOFF*) ptr;
940 #endif
941
942         char *dataUpdatesData;
943         int sizeofDataUpdatesData=0;
944         for(unsigned int m=0;m<dataUpdates.size();m++){
945                 sizeofDataUpdatesData += (sizeof(int) + sizeof(Address)); //sizeof(size) +sizeof(Address);
946                 sizeofDataUpdatesData += dataUpdates[m]->size;
947         }
948
949
950         if(dataUpdates.size() > 0) {
951                 dataUpdatesData = new char[sizeofDataUpdatesData+(sizeof(int) + sizeof(Address))];
952                 char* ptr = dataUpdatesData;
953                 for(unsigned int k=0;k<dataUpdates.size();k++){
954                         memcpy(ptr, &dataUpdates[k]->size, sizeof(int));
955                         ptr += sizeof(int);
956                         memcpy(ptr, &dataUpdates[k]->address, sizeof(Address));
957                         ptr+=sizeof(Address);
958                         memcpy(ptr, dataUpdates[k]->value, dataUpdates[k]->size);
959                         ptr+=dataUpdates[k]->size;
960                         /*fprintf(stderr," DATA UPDATE : from: %x to %x , value %x\n", dataUpdates[k]->address, dataUpdates[k]->address+ dataUpdates[k]->size, (unsigned int) dataUpdates[k]->value);*/
961
962                 }
963                 *(int*) ptr=0;
964                 ptr += sizeof(int);
965                 *(unsigned int*) ptr=0;
966 #if defined(sparc_sun_solaris2_4) \
967  || defined(i386_unknown_linux2_0) \
968  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
969                 newFile->addSection(0/*lastCompactedUpdateAddress*/, dataUpdatesData, 
970                         sizeofDataUpdatesData + (sizeof(int) + sizeof(Address)), "dyninstAPI_data", false);
971 #elif defined(rs6000_ibm_aix4_1)
972                 newFile->addSection("dyn_dat", 0/*lastCompactedUpdateAddress*/,0,
973                         sizeofDataUpdatesData + (sizeof(int) + sizeof(Address)), (char*) dataUpdatesData);
974
975 #endif
976
977                 delete [] (char*) dataUpdatesData;
978         }
979
980 }
981 #endif
982 #endif
983
984 #if defined (cap_save_the_world)
985 #if defined(sparc_sun_solaris2_4) \
986  || defined(i386_unknown_linux2_0) \
987  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
988  || defined(rs6000_ibm_aix4_1)
989
990 void process::saveWorldAddSharedLibs(void *ptr){ // ccw 14 may 2002 
991
992         int dataSize=0;
993         char *data, *dataptr;
994 #if defined(sparc_sun_solaris2_4) \
995  || defined(i386_unknown_linux2_0) \
996  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
997         writeBackElf *newFile = (writeBackElf*) ptr;
998 #elif defined(rs6000_ibm_aix4_1)
999         writeBackXCOFF *newFile = (writeBackXCOFF*) ptr;
1000 #endif
1001
1002         for(unsigned i=0;i<loadLibraryUpdates.size();i++){
1003                 dataSize += loadLibraryUpdates[i].length() + 1 + sizeof(void *);
1004         }
1005         dataSize++;
1006         data = new char[dataSize];
1007         dataptr = data;
1008         /*bperr(" dataSize: %d\n", dataSize);*/
1009
1010         for(unsigned j=0;j<loadLibraryUpdates.size();j++){
1011                 memcpy( dataptr, loadLibraryUpdates[j].c_str(), loadLibraryUpdates[j].length()); 
1012
1013                 /*bperr("SAVING: %s %d\n", dataptr,dataSize);*/
1014                 dataptr += loadLibraryUpdates[j].length();
1015                 *dataptr = '\0';
1016                 dataptr++;
1017                 void *tmp_brk = loadLibraryBRKs[j];
1018                 memcpy( dataptr, &tmp_brk, sizeof(void *));
1019                 dataptr += sizeof(void *);
1020         }
1021         *dataptr = '\0'; //mark the end
1022         if(dataSize > 1){
1023 #if defined(sparc_sun_solaris2_4) \
1024  || defined(i386_unknown_linux2_0) \
1025  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1026                 newFile->addSection(0, data, dataSize, "dyninstAPI_loadLib", false);
1027 #elif  defined(rs6000_ibm_aix4_1)
1028                 newFile->addSection("dyn_lib",0,0, dataSize, data);
1029 #endif
1030         }
1031         delete [] data;
1032 }
1033
1034 #endif
1035 #endif
1036
1037 /*
1038  * Given an image, add all static heaps inside it
1039  * (DYNINSTstaticHeap...) to the buffer pool.
1040  */
1041
1042 void process::addInferiorHeap(const mapped_object *obj)
1043 {
1044   pdvector<heapDescriptor> infHeaps;
1045   /* Get a list of inferior heaps in the new image */
1046   if (getInfHeapList(obj, infHeaps))
1047     {
1048       /* Add the vector to the inferior heap structure */
1049         for (u_int j=0; j < infHeaps.size(); j++)
1050         {
1051 #ifdef DEBUG
1052             fprintf(stderr, "Adding heap at 0x%x to 0x%x, name %s\n",
1053                     infHeaps[j].addr(),
1054                     infHeaps[j].addr() + infHeaps[j].size(),
1055                     infHeaps[j].name().c_str());
1056 #endif
1057 #if defined(os_aix)
1058             // MT: I've seen problems writing into a "found" heap that
1059             // is in the application heap (IE a dlopen'ed
1060             // library). Since we don't have any problems getting
1061             // memory there, I'm skipping any heap that is in 0x2.....
1062             
1063             if ((infHeaps[j].addr() > 0x20000000) &&
1064                 (infHeaps[j].addr() < 0xd0000000) &&
1065                 (infHeaps[j].type() == uncopiedHeap))
1066                 continue;
1067 #endif            
1068
1069             heapItem *h = new heapItem (infHeaps[j].addr(), infHeaps[j].size(),
1070                                         infHeaps[j].type(), false);
1071
1072             infmalloc_printf("%s[%d]: Adding heap from 0x%lx - 0x%lx (%d bytes, type %d) from mapped object %s\n",
1073                              FILE__, __LINE__, 
1074                              infHeaps[j].addr(),
1075                              infHeaps[j].addr() + infHeaps[j].size(),
1076                              infHeaps[j].size(),
1077                              infHeaps[j].type(),
1078                              obj->fileName().c_str());
1079                              
1080             addHeap(h);
1081         }
1082     }
1083   
1084 }
1085
1086
1087 /*
1088  * Called to (re)initialize the static inferior heap structure.
1089  * To incrementally add a static inferior heap (in a dlopen()d module,
1090  * for example), use addInferiorHeap(image *)
1091  */
1092 void process::initInferiorHeap()
1093 {
1094     initializeHeap();
1095
1096     // first initialization: add static heaps to pool
1097     for (unsigned i = 0; i < mapped_objects.size(); i++) {
1098         addInferiorHeap(mapped_objects[i]);
1099     }
1100 }
1101
1102 bool process::initTrampGuard()
1103 {
1104   // This is slightly funky. Dyninst does not currently support
1105   // multiple threads -- so it uses a single tramp guard flag, 
1106   // which resides in the runtime library. However, this is not
1107   // enough for MT paradyn. So Paradyn overrides this setting as 
1108   // part of its initialization.
1109     const std::string vrbleName = "DYNINST_tramp_guards";
1110     pdvector<int_variable *> vars;
1111     if (!findVarsByAll(vrbleName, vars)) 
1112     {
1113         fprintf(stderr, "ERROR: failed to initialize tramp guards!\n");
1114         return false;
1115     }
1116     assert(vars.size() == 1);
1117
1118     if (getAddressWidth() == 4) {
1119         // Don't write directly into trampGuardBase_ as a buffer,
1120         //   in case we're on a big endian architechture.
1121         uint32_t value;
1122         readDataSpace((void *)vars[0]->getAddress(), 4, &value, true);
1123         trampGuardBase_ = value;
1124
1125     } else if (getAddressWidth() == 8) {
1126         readDataSpace((void *)vars[0]->getAddress(), 8, &trampGuardBase_, true);
1127
1128     } else assert(0 && "Incompatible mutatee address width");
1129
1130     return true;
1131 }
1132
1133
1134 //
1135 // dynamic inferior heap stuff
1136 //
1137 #if defined(cap_dynamic_heap)
1138 #define HEAP_DYN_BUF_SIZE (0x100000)
1139 // "imd_rpc_ret" = Inferior Malloc Dynamic RPC RETurn structure
1140 typedef struct {
1141   bool ready;
1142   void *result;
1143 } imd_rpc_ret;
1144
1145 bool inferiorMallocCallbackFlag = false;
1146 int process::inferiorMallocCallback(process * /*p proc*/, unsigned /* rpc_id */,
1147                                      void *data, void *result)
1148 {
1149   global_mutex->_Lock(FILE__, __LINE__);
1150   inferiorrpc_printf("%s[%d]:  inside inferior malloc callback\n", FILE__, __LINE__);
1151   imd_rpc_ret *ret = (imd_rpc_ret *)data;
1152   ret->result = result;
1153   ret->ready = true;
1154   inferiorMallocCallbackFlag = true;
1155   global_mutex->_Unlock(FILE__, __LINE__);
1156   return 0;
1157 }
1158
1159 void alignUp(int &val, int align)
1160 {
1161   assert(val >= 0);
1162   assert(align >= 0);
1163
1164   if (val % align != 0) {
1165     val = ((val / align) + 1) * align;
1166   }
1167 }
1168
1169 // dynamically allocate a new inferior heap segment using inferiorRPC
1170 void process::inferiorMallocDynamic(int size, Address lo, Address hi)
1171 {
1172    /* 03/07/2001 - Jeffrey Shergalis TODO: This code was placed to prevent
1173     * the infinite recursion on the call to inferiorMallocDynamic,
1174     * unfortunately it makes paradyn break on Irix, temporarily fixed by the
1175     * #if !defined(mips..., but should be properly fixed in the future, just
1176     * no time now
1177     */
1178    inferiorrpc_printf("%s[%d]:  welcome to inferiorMallocDynamic\n", FILE__, __LINE__);
1179 #if !defined(mips_sgi_irix6_4)
1180   // Fun (not) case: there's no space for the RPC to execute.
1181   // It'll call inferiorMalloc, which will call inferiorMallocDynamic...
1182   // Avoid this with a static bool.
1183   if (inInferiorMallocDynamic) {
1184       fprintf(stderr, "%s[%d]:  recursion guard\n", FILE__, __LINE__);
1185       return;
1186   }
1187   inInferiorMallocDynamic = true;
1188 #endif
1189
1190   // word-align buffer size 
1191   // (see "DYNINSTheap_align" in rtinst/src/RTheap-<os>.c)
1192   alignUp(size, 4);
1193   // build AstNode for "DYNINSTos_malloc" call
1194   std::string callee = "DYNINSTos_malloc";
1195   pdvector<AstNodePtr> args(3);
1196   args[0] = AstNode::operandNode(AstNode::Constant, (void *)(Address)size);
1197   args[1] = AstNode::operandNode(AstNode::Constant, (void *)lo);
1198   args[2] = AstNode::operandNode(AstNode::Constant, (void *)hi);
1199   AstNodePtr code = AstNode::funcCallNode(callee, args);
1200
1201   // issue RPC and wait for result
1202   imd_rpc_ret ret = { false, NULL };
1203
1204   bool wasRunning = (status() == running);
1205  
1206   /* set lowmem to ensure there is space for inferior malloc */
1207   getRpcMgr()->postRPCtoDo(code, true, // noCost
1208                            &inferiorMallocCallback, &ret, 
1209                            wasRunning, // run when finished?
1210                            true, // But use reserved memory
1211                            NULL, NULL); // process-wide
1212
1213   // Specify that we want to wait for a RPCDone event
1214   eventType res = evtUndefined;
1215
1216   inferiorMallocCallbackFlag = false;
1217   inferiorrpc_printf("%s[%d]:  waiting for rpc completion\n", FILE__, __LINE__);
1218   // Aggravation....
1219   // We need to override the BPatch paused behavior; we may be BPatch-paused,
1220   // but we _really_ need to run the process here.
1221
1222   processRunState_t oldState = sh->overrideSyncContinueState(ignoreRequest);
1223
1224   do {
1225       bool rpcNeedsContinue = false;
1226       getRpcMgr()->launchRPCs(rpcNeedsContinue,
1227                               wasRunning);
1228       if( rpcNeedsContinue ) { continueProc(); }
1229       
1230       getMailbox()->executeCallbacks(FILE__, __LINE__);
1231       
1232       if(hasExited()) {
1233           fprintf(stderr, "%s[%d]:  BAD NEWS, process has exited\n", FILE__, __LINE__);
1234           return;
1235       }
1236       if (inferiorMallocCallbackFlag) {
1237           break;
1238       }
1239       
1240       inferiorrpc_printf("%s[%d][%s]:  before wait for RPCDone, status == running is %s\n", 
1241                          FILE__, __LINE__, getThreadStr(getExecThreadID()), 
1242                          status() == running ? "true" : "false");
1243       
1244       res = sh->waitForEvent(evtRPCSignal, this, NULL /*lwp*/, statusRPCDone);
1245       getMailbox()->executeCallbacks(FILE__, __LINE__);
1246       /* If, as we used to, we loop while res != evtRPCSignal, we could
1247          be kicked out of the loop by some other (random) RPC completing,
1248          rather than the malloc() call, and we'll fail based on the random
1249          garbage in the return structure that the callback hasn't filled in yet. */
1250   } while( ! inferiorMallocCallbackFlag );
1251   
1252   sh->overrideSyncContinueState(oldState);
1253   inferiorMallocCallbackFlag = false;
1254
1255    switch ((int)(Address)ret.result) {
1256      case 0:
1257 #ifdef DEBUG
1258         sprintf(errorLine, "DYNINSTos_malloc() failed\n");
1259         logLine(errorLine);
1260 #endif
1261         break;
1262      case -1:
1263         // TODO: assert?
1264         sprintf(errorLine, "DYNINSTos_malloc(): unaligned buffer size\n");
1265         logLine(errorLine);
1266         break;
1267      default:
1268         // add new segment to buffer pool
1269          // FIXME
1270 #if defined(os_aix)
1271          // for save the world...
1272         heapItem *h = new heapItem((Address)ret.result, size, dataHeap, true,
1273                                    HEAPfree);
1274 #else
1275         heapItem *h = new heapItem((Address)ret.result, size, anyHeap, true,
1276                                    HEAPfree);
1277 #endif
1278
1279         addHeap(h);
1280         break;
1281    }
1282    
1283    /* 03/07/2001 - Jeffrey Shergalis
1284     * Part of the above #if !defined(mips... patch for the recursion problem
1285     * TODO: Need a better solution
1286     */
1287 #if !defined(mips_sgi_irix6_4)
1288    inInferiorMallocDynamic = false;
1289 #endif
1290 }
1291 #endif 
1292
1293 const Address ADDRESS_LO = ((Address)0);
1294 const Address ADDRESS_HI = ((Address)~((Address)0));
1295 //unsigned int totalSizeAlloc = 0;
1296
1297 Address process::inferiorMalloc(unsigned size, inferiorHeapType type, 
1298                                 Address near_, bool *err)
1299 {
1300     Address ret = 0;
1301
1302    if (err) *err = false;
1303    assert(size > 0);
1304    
1305
1306    // allocation range
1307    Address lo = ADDRESS_LO; // Should get reset to a more reasonable value
1308    Address hi = ADDRESS_HI; // Should get reset to a more reasonable value
1309    
1310 #if defined(cap_dynamic_heap)
1311    inferiorMallocAlign(size); // align size
1312    // Set the lo/hi constraints (if necessary)
1313    inferiorMallocConstraints(near_, lo, hi, type);
1314 #else
1315    /* align to cache line size (32 bytes on SPARC) */
1316    size = (size + 0x1f) & ~0x1f; 
1317 #endif
1318
1319    infmalloc_printf("%s[%d]: inferiorMalloc entered; size %d, type %d, near 0x%lx (0x%lx to 0x%lx)\n",
1320                     FILE__, __LINE__, size, type, near_, lo, hi);
1321
1322    // find free memory block (7 attempts)
1323    // attempt 0: as is
1324    // attempt 1: deferred free, compact free blocks
1325    // attempt 2: allocate new segment (1 MB, constrained)
1326    // attempt 3: allocate new segment (sized, constrained)
1327    // attempt 4: remove range constraints
1328    // attempt 5: allocate new segment (1 MB, unconstrained)
1329    // attempt 6: allocate new segment (sized, unconstrained)
1330    // attempt 7: deferred free, compact free blocks (why again?)
1331    int freeIndex = -1;
1332    int ntry = 0;
1333    for (ntry = 0; freeIndex == -1; ntry++) {
1334       switch(ntry) {
1335         case 0: // as is
1336            break;
1337 #if defined(cap_dynamic_heap)
1338         case 1: // compact free blocks
1339             infmalloc_printf("%s[%d]: garbage collecting and compacting\n",
1340                              FILE__, __LINE__);
1341             gcInstrumentation();
1342             inferiorFreeCompact();
1343           break;
1344         case 2: // allocate new segment (1MB, constrained)
1345             infmalloc_printf("%s[%d]: inferiorMallocDynamic for %d (0x%x) bytes between 0x%lx - 0x%lx\n",
1346                              FILE__, __LINE__, HEAP_DYN_BUF_SIZE, lo, hi);
1347             inferiorMallocDynamic(HEAP_DYN_BUF_SIZE, lo, hi);
1348             break;
1349         case 3: // allocate new segment (sized, constrained)
1350             infmalloc_printf("%s[%d]: inferiorMallocDynamic for %d (0x%x) bytes between 0x%lx - 0x%lx\n",
1351                              FILE__, __LINE__, size, lo, hi);
1352            inferiorMallocDynamic(size, lo, hi);
1353            break;
1354         case 4: // remove range constraints
1355             infmalloc_printf("%s[%d]: inferiorMalloc: removing range constraints\n",
1356                              FILE__, __LINE__);
1357            lo = ADDRESS_LO;
1358            hi = ADDRESS_HI;
1359            if (err) {
1360               fprintf(stderr, "%s[%d]: ERROR!\n", FILE__, __LINE__);
1361               *err = true;
1362            }
1363            break;
1364         case 5: // allocate new segment (1MB, unconstrained)
1365             infmalloc_printf("%s[%d]: inferiorMallocDynamic for %d (0x%x) bytes between 0x%lx - 0x%lx\n",
1366                              FILE__, __LINE__, HEAP_DYN_BUF_SIZE, lo, hi);
1367            inferiorMallocDynamic(HEAP_DYN_BUF_SIZE, lo, hi);
1368            break;
1369         case 6: // allocate new segment (sized, unconstrained)
1370             infmalloc_printf("%s[%d]: inferiorMallocDynamic for %d (0x%x) bytes between 0x%lx - 0x%lx\n",
1371                              FILE__, __LINE__, size, lo, hi);
1372            inferiorMallocDynamic(size, lo, hi);
1373            break;
1374         case 7: // deferred free, compact free blocks
1375             infmalloc_printf("%s[%d]: inferiorMalloc: recompacting\n", FILE__, __LINE__);
1376             inferiorFreeCompact();
1377            break;
1378 #else /* !(cap_dynamic_heap) */
1379       case 1: // deferred free, compact free blocks
1380           gcInstrumentation();
1381           inferiorFreeCompact();
1382           break;
1383 #endif /* cap_dynamic_heap */
1384            
1385         default: // error - out of memory
1386            return(0);
1387       }
1388       ret = inferiorMallocInternal(size, lo, hi, type);
1389       if (ret) break;
1390    }
1391    infmalloc_printf("%s[%d]: inferiorMalloc, returning address 0x%lx\n", FILE__, __LINE__, ret);
1392    return ret;
1393 }
1394
1395 // Cleanup the process object. Delete all sub-objects to ensure we aren't 
1396 // leaking memory and prepare for new versions. Useful when the process exits
1397 // (and the process object is deleted) and when it execs
1398
1399 void process::deleteProcess() 
1400 {
1401   assert(this);
1402
1403   // A lot of the behavior here is keyed off the current process status....
1404   // if it is exited we'll delete things without performing any operations
1405   // on the process. Otherwise we'll attempt to reverse behavior we've made.
1406     // For platforms that don't like repeated use of for (unsigned i...)
1407     unsigned iter = 0;
1408
1409   // We may call this function multiple times... once when the process exits,
1410   // once when we delete the process object.
1411   if (status() == deleted) {
1412       return;
1413   }
1414
1415   // If this assert fires check whether we're setting the status vrble correctly
1416   // before calling this function
1417   assert(!isAttached() || !reachedBootstrapState(bootstrapped_bs) || execing());
1418
1419   // Cancel the BPatch layer's control of anything below this point
1420   if (sh) {
1421       sh->overrideSyncContinueState(ignoreRequest);
1422       sh->clearCachedLocations();
1423   }
1424
1425
1426   for (iter = 0; iter < deleted_objects.size(); iter++)
1427       delete deleted_objects[iter];
1428   deleted_objects.clear();
1429
1430   runtime_lib = NULL;
1431
1432   // Signal handlers...
1433   signalHandlerLocations_.clear();
1434
1435   // creationMechanism_ remains untouched
1436   // stateWhenAttached_ remains untouched
1437   main_function = NULL;
1438   thread_index_function = NULL;
1439
1440   if (dyn) {
1441       delete dyn;
1442       dyn = NULL;
1443   }
1444
1445   // Delete the thread and lwp structures
1446   dictionary_hash_iter<unsigned, dyn_lwp *> lwp_iter(real_lwps);
1447   dyn_lwp *lwp;
1448   unsigned index;
1449   
1450   // This differs on exec; we need to kill all but the representative LWP
1451   // Duplicate code for ease of reading
1452
1453   if (execing()) {
1454       while (lwp_iter.next(index, lwp)) {
1455           if (process::IndependentLwpControl() &&
1456               (index == (unsigned)getPid())) {
1457               // Keep this around instead of nuking it -- this is our
1458               // handle to the "real" LWP
1459               representativeLWP = lwp;
1460           }
1461           else
1462               delete lwp;
1463       }
1464       real_lwps.clear();
1465       
1466       // DO NOT DELETE THE REPRESENTATIVE LWP
1467
1468   }
1469   else { 
1470       while (lwp_iter.next(index, lwp)) {
1471           deleteLWP(lwp);
1472       }
1473       real_lwps.clear();
1474       
1475       if (representativeLWP) {
1476           delete representativeLWP;
1477           representativeLWP = NULL;
1478       }
1479   }
1480
1481   // Blow away dyn_lwp's that we delayed delete'ing
1482   for (unsigned lwp_ndx = 0; lwp_ndx < lwps_to_delete.size(); lwp_ndx++) {
1483       delete lwps_to_delete[lwp_ndx];
1484   }
1485   lwps_to_delete.clear();
1486   
1487   // Blow away threads; we'll recreate later
1488   for (unsigned thr_iter = 0; thr_iter < threads.size(); thr_iter++) {
1489       delete threads[thr_iter];
1490   }
1491   threads.clear();
1492
1493
1494   deferredContinueProc = false;
1495   previousSignalAddr_ = 0;
1496   continueAfterNextStop_ = false;
1497   
1498   // Don't touch exec; statically allocated anyway.
1499
1500   if (theRpcMgr) {
1501       delete theRpcMgr;
1502   }
1503   theRpcMgr = NULL;
1504
1505   // Skipping saveTheWorld; don't know what to do with it.
1506
1507   dyninstlib_brk_addr = 0;
1508   main_brk_addr = 0;
1509
1510   deleteAddressSpace();
1511
1512   inInferiorMallocDynamic = false;
1513
1514   // Get rid of our syscall tracing.
1515   if (tracedSyscalls_) {
1516       delete tracedSyscalls_;
1517       tracedSyscalls_ = NULL;
1518   }
1519
1520   for (iter = 0; iter < syscallTraps_.size(); iter++) { 
1521       if(syscallTraps_[iter] != NULL)
1522           delete syscallTraps_[iter];
1523   }
1524   syscallTraps_.clear();
1525
1526   trapMapping.clearTrapMappings();
1527
1528   for (iter = 0; iter < tracingRequests.size(); iter++) {
1529       if(tracingRequests[iter] != NULL)
1530           delete tracingRequests[iter];
1531   }
1532   tracingRequests.clear();
1533
1534   // By definition, these are dangling.
1535   for (iter = 0; iter < pendingGCInstrumentation.size(); iter++) {
1536       if(pendingGCInstrumentation[iter] != NULL)
1537           delete pendingGCInstrumentation[iter];
1538   }
1539   pendingGCInstrumentation.clear();
1540
1541 #if defined(os_linux)
1542   vsyscall_start_ = 0;
1543   vsyscall_end_ = 0;
1544   vsyscall_text_ = 0;
1545   vsyscall_data_ = 0;
1546 #endif
1547
1548   set_status(deleted);
1549   
1550 }
1551
1552 //
1553 // cleanup when a process is deleted. Assumed we are detached or the process is exited.
1554 //
1555 process::~process()
1556 {
1557     // Failed creation... nothing is here yet
1558     if (!reachedBootstrapState(initialized_bs)) {
1559         if (sh) SignalGeneratorCommon::stopSignalGenerator(sh);
1560         sh = NULL;
1561         return;
1562     }
1563
1564     // We require explicit detaching if the process still exists.
1565     // On the other hand, if it never started...
1566     if (reachedBootstrapState(bootstrapped_bs)) {
1567         assert(!isAttached());
1568     }
1569
1570 #if defined( ia64_unknown_linux2_4 )
1571         upaIterator iter = unwindProcessArgs.begin();
1572         for( ; iter != unwindProcessArgs.end(); ++iter ) {
1573                 void * unwindProcessArg = * iter;
1574                 if( unwindProcessArg != NULL ) { getDBI()->UPTdestroy( unwindProcessArg ); }
1575                 }
1576         if( unwindAddressSpace != NULL ) { getDBI()->destroyUnwindAddressSpace( unwindAddressSpace ); }
1577 #endif
1578     
1579     // Most of the deletion is encapsulated in deleteProcess
1580     deleteProcess();
1581
1582     /*
1583       // Removed; if we're detached (or the proc exited) this trick won't work anyway. 
1584       // And when the process dies the signal generator will clean itself up.
1585
1586     if (sh) {
1587       signal_printf("%s[%d]:  removing signal handler for process\n", FILE__, __LINE__);
1588       SignalGeneratorCommon::stopSignalGenerator(sh);
1589     }
1590     */
1591
1592     // We used to delete the particular process, but this created no end of problems
1593     // with people storing pointers into particular indices. We set the pointer to NULL.
1594     for (unsigned lcv=0; lcv < processVec.size(); lcv++) {
1595         if (processVec[lcv] == this) {
1596             processVec[lcv] = NULL;
1597         }        
1598     }
1599
1600     if (sh) {
1601         // Set this to TRUE before setting proc to null so that it knows to go away...
1602         sh->stop_request = true;
1603         sh->proc = NULL;
1604     }
1605
1606 #if defined(i386_unknown_linux2_0) \
1607  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1608     cleanupVsysinfo(getVsyscallData());
1609 #endif
1610
1611 }
1612
1613 // Default process class constructor. This handles both create,
1614 // attach, and attachToCreated cases. We then call an auxiliary
1615 // function (which can return an error value) to handle specific
1616 // cases.
1617 process::process(SignalGenerator *sh_) :
1618     cached_result(not_cached), // MOVE ME
1619     parent(NULL),
1620     sh(sh_),
1621     runtime_lib(NULL),
1622     creationMechanism_(unknown_cm),
1623     stateWhenAttached_(unknown_ps),
1624     main_function(NULL),
1625     thread_index_function(NULL),
1626     lastForkingThread(NULL),
1627     dyn(NULL),
1628     interpreter_name_(NULL),
1629     interpreter_base_(0x0),
1630     representativeLWP(NULL),
1631     real_lwps(CThash),
1632     max_number_of_threads(MAX_THREADS),
1633     thread_structs_base(0),
1634     deferredContinueProc(false),
1635     previousSignalAddr_(0),
1636     continueAfterNextStop_(false),
1637     status_(neonatal),
1638     exiting_(false),
1639     nextTrapIsExec(false),
1640     inExec_(false),
1641     theRpcMgr(NULL),
1642     collectSaveWorldData(true),
1643     requestTextMiniTramp(false),
1644     traceLink(0),
1645     bootstrapState(unstarted_bs),
1646     suppress_bpatch_callbacks_(false),
1647     loadDyninstLibAddr(0),
1648 #if defined(os_windows)
1649     main_breaks(addrHash4),
1650 #endif
1651     savedRegs(NULL),
1652     dyninstlib_brk_addr(0),
1653     main_brk_addr(0),
1654     systemPrelinkCommand(NULL),
1655 #if defined(os_windows)
1656     processHandle_(INVALID_HANDLE_VALUE),
1657     mainFileHandle_(INVALID_HANDLE_VALUE),
1658 #endif
1659     inInferiorMallocDynamic(false),
1660     tracedSyscalls_(NULL),
1661     traceSysCalls_(false),
1662     traceState_(noTracing_ts),
1663     libcstartmain_brk_addr(0)
1664 #if defined(arch_ia64)
1665     , unwindAddressSpace( NULL )
1666     , unwindProcessArgs( addrHash )
1667 #endif
1668 #if defined(os_linux)
1669     , vsys_status_(vsys_unknown)
1670     , vsyscall_start_(0)
1671     , vsyscall_end_(0)
1672     , vsyscall_text_(0)
1673     , vsyscall_data_(NULL)
1674     , auxv_parser(NULL)
1675 #endif
1676 {
1677     // Let's try to profile memory usage
1678 #if defined(PROFILE_MEM_USAGE)
1679    void *mem_usage = sbrk(0);
1680    fprintf(stderr, "Process creation: sbrk %p\n", mem_usage);
1681 #endif
1682
1683     theRpcMgr = new rpcMgr(this);    
1684     dyn = new dynamic_linking(this);
1685 }
1686
1687 //
1688 // Process "normal" (non-attach, non-fork) ctor equivalent, for when a
1689 // new process is fired up by paradynd itself.  This ctor. is also
1690 // used in the case that the application has been fired up by another
1691 // process and stopped just after executing the execv() system call.
1692 // In the "normal" case, the parameter iTraceLink will be a
1693 // non-negative value which corresponds to the pipe descriptor of the
1694 // trace pipe used between the paradynd and the application. In the
1695 // later case, iTraceLink will be -1. This will be posteriorly used to
1696 // properly initialize the createdViaAttachToCreated flag. - Ana
1697 //
1698
1699
1700 bool process::setupCreated(int iTraceLink) 
1701 {
1702     traceLink = iTraceLink; // notice that tracelink will be -1 in the unique
1703     // case called "AttachToCreated" - Ana 
1704     // PARADYN ONLY
1705
1706     creationMechanism_ = created_cm;
1707     
1708     // Post-setup state variables
1709     stateWhenAttached_ = stopped; 
1710     
1711     startup_printf("%s[%d]: Creation method: attaching to process\n", FILE__, __LINE__);
1712     // attach to the child process (machine-specific implementation)
1713     if (!attach()) { // error check?
1714         status_ = detached;
1715          fprintf(stderr, "%s[%d] attach failing here\n", FILE__, __LINE__);
1716          std::string msg = std::string("Warning: unable to attach to specified process :")
1717             + utos(getPid());
1718         showErrorCallback(26, msg.c_str());
1719         return false;
1720     }
1721     startup_printf("%s[%d]: Creation method: returning\n", FILE__, __LINE__);
1722     return true;
1723 }
1724     
1725
1726 // Attach version of the above: no trace pipe, but we assume that
1727 // main() has been reached and passed. Someday we could unify the two
1728 // if someone has a good way of saying "has main been reached".
1729 bool process::setupAttached() 
1730 {
1731     creationMechanism_ = attached_cm;
1732     // We're post-main... run the bootstrapState forward
1733
1734 #if !defined(os_windows)
1735     bootstrapState = initialized_bs;
1736 #else
1737     // We need to wait for the CREATE_PROCESS debug event.
1738     // Set to "begun" here, and fix up in the signal loop
1739     bootstrapState = attached_bs;
1740 #endif
1741
1742    traceLink = -1; // will be set later, when the appl runs DYNINSTinit
1743
1744    startup_printf("Attach method: attaching to process\n");
1745
1746    // It is assumed that a call to attach() doesn't affect the running status
1747    // of the process.  But, unfortunately, some platforms may barf if the
1748    // running status is anything except paused. (How to deal with this?)
1749    // Note that solaris in particular seems able to attach even if the process
1750    // is running.
1751    if (!attach()) {
1752        status_ = detached;
1753        
1754          fprintf(stderr, "%s[%d] attach failing here\n", FILE__, __LINE__);
1755       std::string msg = std::string("Warning: unable to attach to specified process: ")
1756                    + utos(getPid());
1757       showErrorCallback(26, msg.c_str());
1758       return false;
1759    }
1760
1761    startup_printf("%s[%d]: attached, getting current process state\n", FILE__, __LINE__);
1762
1763    // Record what the process was doing when we attached, for possible
1764    // use later.
1765    if (isRunning_()) {
1766        startup_printf("%s[%d]: process running when attached, pausing...\n", FILE__, __LINE__);
1767        stateWhenAttached_ = running; 
1768        set_status(running);
1769        if (!pause())
1770            return false;
1771    }
1772    else {
1773        startup_printf("%s[%d]: attached to previously paused process\n", FILE__, __LINE__);
1774        stateWhenAttached_ = stopped;
1775        set_status(stopped);
1776    }
1777    startup_printf("%s[%d]: setupAttached returning true\n",FILE__, __LINE__);
1778
1779    assert(status() == stopped);
1780    return true;
1781 }
1782
1783 int HACKSTATUS = 0;
1784
1785 bool process::prepareExec(fileDescriptor &desc) 
1786 {
1787     ///////////////////////////// CONSTRUCTION STAGE ///////////////////////////
1788     // For all intents and purposes: a new id.
1789     // However, we don't want to make a new object since all sorts
1790     // of people have a pointer to this object. We could index by PID,
1791     // which would allow us to swap out processes; but hey.
1792
1793     // We should be attached to the process
1794
1795     // setupExec must get us to the point of putting a trap at the
1796     // beginning of main. We then continue. We might get called again,
1797     // or we might go into loading the dyninst lib; impossible to
1798     // tell.
1799     //
1800
1801 #if defined(os_aix) && defined(cap_proc)
1802     // AIX oddly detaches from the process... fix that here
1803     // Actually, it looks like only the as FD is closed (probably because
1804     // the file it refers to is gone). Reopen.
1805    getRepresentativeLWP()->reopen_fds();
1806 #endif
1807 #if defined(os_linux)
1808    if (auxv_parser) {
1809       auxv_parser->deleteAuxvParser();
1810       auxv_parser = NULL;
1811    }
1812 #endif
1813
1814     // Revert the bootstrap state
1815     bootstrapState = attached_bs;
1816
1817     // First, duplicate constructor.
1818
1819     assert(theRpcMgr == NULL);
1820     assert(dyn == NULL);
1821     theRpcMgr = new rpcMgr(this);
1822
1823     dictionary_hash<unsigned, dyn_lwp *>::iterator lwp_iter = real_lwps.begin();
1824     for (; lwp_iter != real_lwps.end(); lwp_iter++) 
1825        theRpcMgr->addLWP(*lwp_iter);
1826     if (representativeLWP)
1827        theRpcMgr->addLWP(representativeLWP);
1828
1829     dyn = new dynamic_linking(this);
1830
1831     startup_printf("%s[%d]: exec exit, setting a.out to %s:%s\n",
1832                    FILE__, __LINE__, desc.file().c_str(), desc.member().c_str());
1833
1834     if (!setAOut(desc)) {
1835         return false;
1836     }
1837
1838     // Probably not going to find anything (as we haven't loaded the
1839     // RT lib yet, and that's where most of the space is). However,
1840     // any shared object added after this point will have infHeaps
1841     // auto-added.
1842     startup_printf("Initializing vector heap\n");
1843     initInferiorHeap();
1844
1845     // Now from setupGeneral...
1846     createInitialThread();
1847
1848     // Status: stopped.
1849     set_status(stopped, true, true); // Revert and ignore
1850
1851     // Annoying; most of our initialization code is in unix.C, and it
1852     // knows how to get us to main. Problem is, it triggers on a trap...
1853     // and guess what we just consumed. So replicate it manually.
1854     setBootstrapState(begun_bs);
1855     insertTrapAtEntryPointOfMain();
1856
1857     return true;
1858 }
1859
1860 bool process::finishExec() {
1861     startup_printf("%s[%d]:  about to load DyninstLib\n", FILE__, __LINE__);
1862     bool res = loadDyninstLib();
1863     if (!res)
1864         return false;
1865     
1866     getMailbox()->executeCallbacks(FILE__, __LINE__);
1867     while(!reachedBootstrapState(bootstrapped_bs)) {
1868         // We're waiting for something... so wait
1869         // true: block until a signal is received (efficiency)
1870         if(hasExited()) {
1871             return false;
1872         }
1873         sh->waitForEvent(evtProcessInitDone);
1874         getMailbox()->executeCallbacks(FILE__, __LINE__);
1875     }
1876     
1877     if(process::IndependentLwpControl())
1878         independentLwpControlInit();
1879     
1880     set_status(stopped); // was 'exited'
1881     
1882     inExec_ = false;
1883     BPatch::bpatch->registerExecExit(this);
1884
1885     sh->continueProcessAsync();
1886
1887     return true;
1888 }
1889
1890 bool process::setupFork() 
1891 {
1892     assert(parent);
1893     assert(parent->status() == stopped);
1894
1895     // Do stuff....
1896
1897     // Copy: 
1898     //   all mapped objects
1899     //   dynamic object tracer
1900     //   all threads
1901     //   all lwps
1902     //   rpc manager
1903     //   all vector heaps
1904     //   all defined instPoints
1905     //   all multiTramps
1906     //    ... and baseTramps, relocatedInstructions, trampEnds, miniTramps
1907     //   installed instrumentation
1908     //    ... including system call handling
1909     //   process state
1910     //   
1911
1912     copyAddressSpace(parent);
1913
1914     assert(mapped_objects.size() == parent->mapped_objects.size());
1915
1916     for (unsigned i = 0; i < mapped_objects.size(); i++) {        
1917         if ((parent->mapped_objects[i]->fileName() == dyninstRT_name.c_str()) ||
1918             (parent->mapped_objects[i]->fullName() == dyninstRT_name.c_str()))
1919             runtime_lib = mapped_objects[i];
1920     }
1921
1922     // And the main func and dyninst RT lib
1923     if (!setMainFunction())
1924         return false;
1925     if (parent->runtime_lib) {
1926         // This should be set by now...
1927         assert(runtime_lib);
1928     }
1929     
1930     /////////////////////////
1931     // Threads & LWPs
1932     /////////////////////////
1933
1934     if(process::IndependentLwpControl())
1935         independentLwpControlInit();
1936
1937     /////////////////////////
1938     // RPC manager
1939     /////////////////////////
1940     
1941     theRpcMgr = new rpcMgr(parent->theRpcMgr, this);
1942     assert(theRpcMgr);
1943
1944     /////////////////////////
1945     // Find new threads
1946     /////////////////////////    
1947
1948     recognize_threads(parent);
1949
1950     // Tag the garbage collection list...
1951     for (unsigned ii = 0; ii < parent->pendingGCInstrumentation.size(); ii++) {
1952         // TODO. For now we'll just "leak"
1953     }
1954
1955     // Now that we have instPoints, we can create the (possibly) instrumentation-
1956     // based tracing code
1957
1958     /////////////////////////
1959     // Dynamic tracer
1960     /////////////////////////
1961
1962     dyn = new dynamic_linking(parent->dyn, this);
1963     assert(dyn);
1964
1965     /////////////////////////
1966     // Syscall tracer
1967     /////////////////////////
1968
1969     tracedSyscalls_ = new syscallNotification(parent->tracedSyscalls_, this);
1970
1971     // Copy signal handlers
1972
1973     pdvector<codeRange *> sigHandlers;
1974     parent->signalHandlerLocations_.elements(sigHandlers);
1975     for (unsigned iii = 0; iii < sigHandlers.size(); iii++) {
1976         signal_handler_location *oldSig = dynamic_cast<signal_handler_location *>(sigHandlers[iii]);
1977         assert(oldSig);
1978         signal_handler_location *newSig = new signal_handler_location(*oldSig);
1979         signalHandlerLocations_.insert(newSig);
1980     }
1981
1982
1983 #if defined(os_aix)
1984     // AIX doesn't copy memory past the ends of text segments, so we
1985     // do it manually here
1986     copyDanglingMemory(const_cast<process *>(parent));
1987 #endif
1988
1989     /////////////////////////
1990     // Process vector
1991     /////////////////////////
1992
1993     processVec.push_back(this);
1994     activeProcesses++;
1995     return true;
1996 }
1997
1998
1999 unsigned process::getAddressWidth() const { 
2000     if (mapped_objects.size() > 0)
2001         return mapped_objects[0]->parse_img()->getObject()->getAddressWidth(); 
2002     // We can call this before we've attached.. 
2003     return 4;
2004 }
2005
2006 bool process::setAOut(fileDescriptor &desc) 
2007 {
2008    startup_printf("%s[%d]:  enter setAOut\n", FILE__, __LINE__);
2009     assert(reachedBootstrapState(attached_bs));
2010     assert(mapped_objects.size() == 0);
2011     mapped_object *aout = mapped_object::createMappedObject(desc, this);
2012     if (!aout) {
2013        startup_printf("%s[%d]:  fail setAOut\n", FILE__, __LINE__);
2014         return false;
2015     }
2016     
2017     mapped_objects.push_back(aout);
2018    startup_printf("%s[%d]:  setAOut: adding range\n", FILE__, __LINE__);
2019     addOrigRange(aout);
2020
2021    startup_printf("%s[%d]:  setAOut: finding signal handler\n", FILE__, __LINE__);
2022     findSignalHandler(aout);
2023
2024     // Find main
2025    startup_printf("%s[%d]:  leave setAOut/setting main\n", FILE__, __LINE__);
2026     return setMainFunction();
2027 }
2028
2029 // Here's the list of functions to look for:
2030 #define NUMBER_OF_MAIN_POSSIBILITIES 7
2031 char main_function_names[NUMBER_OF_MAIN_POSSIBILITIES][20] = {
2032     "main",
2033     "DYNINST_pltMain",
2034     "_main",
2035     "WinMain",
2036     "_WinMain",
2037     "wWinMain",
2038     "_wWinMain"};
2039
2040 bool process::setMainFunction() 
2041 {
2042     assert(!main_function);
2043     
2044     for (unsigned i = 0; i < NUMBER_OF_MAIN_POSSIBILITIES; i++) {
2045         main_function = findOnlyOneFunction(main_function_names[i]);
2046         if (main_function) break;
2047     }
2048
2049     return true;
2050 }
2051
2052 bool process::setupGeneral() 
2053 {
2054     // Need to have a.out at this point
2055     assert(mapped_objects.size() > 0);
2056
2057     if (reachedBootstrapState(bootstrapped_bs)) 
2058         return true;
2059     // We should be paused; be sure.
2060     pause();
2061     
2062     // In the ST case, threads[0] (the only one) is effectively
2063     // a pass-through for process operations. In MT, it's the
2064     // main thread of the process and is handled correctly
2065
2066     startup_printf("Creating initial thread...\n");
2067
2068     createInitialThread();
2069
2070     // Probably not going to find anything (as we haven't loaded the
2071     // RT lib yet, and that's where most of the space is). However,
2072     // any shared object added after this point will have infHeaps
2073     // auto-added.
2074     startup_printf("Initializing vector heap\n");
2075     initInferiorHeap();
2076
2077     startup_printf("%s[%d]: Loading DYNINST lib...\n", FILE__, __LINE__);
2078     // TODO: loadDyninstLib actually embeds a lot of startup material;
2079     // should move it up to this function to make things more obvious.
2080     bool res = loadDyninstLib();
2081     if(res == false) {
2082         startup_printf("%s[%d]: ERROR: failed to load DYNINST lib\n", FILE__, __LINE__);
2083         return false;
2084     }
2085     startup_printf("%s[%d]: Waiting for bootstrapped state...\n", FILE__, __LINE__);
2086     while (!reachedBootstrapState(bootstrapped_bs)) {
2087        // We're waiting for something... so wait
2088        // true: block until a signal is received (efficiency)
2089        if(hasExited()) {
2090            return false;
2091        }
2092        startup_printf("Checking for process event...\n");
2093        sh->waitForEvent(evtProcessInitDone);
2094        getMailbox()->executeCallbacks(FILE__, __LINE__);
2095     }
2096
2097     if(process::IndependentLwpControl())
2098         independentLwpControlInit();
2099
2100    return true;
2101 }
2102
2103 //
2104 // Process "fork" ctor, for when a process which is already being monitored by
2105 // paradynd executes the fork syscall.
2106 //
2107 // Needs to strictly duplicate all process information; this is a _lot_ of work.
2108
2109 process::process(process *parentProc, SignalGenerator *sg_, int childTrace_fd) : 
2110     cached_result(parentProc->cached_result), // MOVE ME
2111     parent(parentProc),
2112     sh(sg_),
2113     runtime_lib(NULL), // Set later
2114     dyninstRT_name(parentProc->dyninstRT_name),
2115     creationMechanism_(parentProc->creationMechanism_),
2116     stateWhenAttached_(parentProc->stateWhenAttached_),
2117     main_function(NULL), // Set later
2118     thread_index_function(NULL),
2119     dyn(NULL),  // Set later
2120     interpreter_name_(NULL),
2121     interpreter_base_(0x0),
2122     representativeLWP(NULL), // Set later
2123     real_lwps(CThash),
2124     max_number_of_threads(parentProc->max_number_of_threads),
2125     thread_structs_base(parentProc->thread_structs_base),
2126     deferredContinueProc(parentProc->deferredContinueProc),
2127     previousSignalAddr_(parentProc->previousSignalAddr_),
2128     continueAfterNextStop_(parentProc->continueAfterNextStop_),
2129     status_(parentProc->status_),
2130     exiting_(parentProc->exiting_),
2131     nextTrapIsExec(parentProc->nextTrapIsExec),
2132     inExec_(parentProc->inExec_),
2133     theRpcMgr(NULL), // Set later
2134     collectSaveWorldData(parentProc->collectSaveWorldData),
2135     requestTextMiniTramp(parentProc->requestTextMiniTramp),
2136     traceLink(childTrace_fd),
2137     bootstrapState(parentProc->bootstrapState),
2138     suppress_bpatch_callbacks_(parentProc->suppress_bpatch_callbacks_),
2139     loadDyninstLibAddr(0),
2140 #if defined(os_windows)
2141     main_breaks(addrHash4),
2142 #endif
2143     savedRegs(NULL), // Later
2144     dyninstlib_brk_addr(parentProc->dyninstlib_brk_addr),
2145     main_brk_addr(parentProc->main_brk_addr),
2146     systemPrelinkCommand(NULL),
2147     inInferiorMallocDynamic(parentProc->inInferiorMallocDynamic),
2148     tracedSyscalls_(NULL),  // Later
2149     traceSysCalls_(parentProc->getTraceSysCalls()),
2150     traceState_(parentProc->getTraceState()),
2151     libcstartmain_brk_addr(parentProc->getlibcstartmain_brk_addr())
2152 #if defined(arch_ia64)
2153     , unwindAddressSpace( NULL )
2154     , unwindProcessArgs( addrHash )
2155 #endif
2156 #if defined(os_linux)
2157     , vsyscall_start_(parentProc->vsyscall_start_)
2158     , vsyscall_end_(parentProc->vsyscall_end_)
2159     , vsyscall_text_(parentProc->vsyscall_text_)
2160     , vsyscall_data_(parentProc->vsyscall_data_)
2161     , auxv_parser(NULL)
2162 #endif
2163 {
2164 }
2165
2166 static void cleanupBPatchHandle(int pid)
2167 {
2168    BPatch::bpatch->unRegisterProcess(pid, NULL);
2169 }
2170
2171
2172 /*
2173  * Create a new instance of the named process.  Read the symbols and start
2174  *   the program
2175  */
2176 process *ll_createProcess(const std::string File, pdvector<std::string> *argv,
2177                           pdvector<std::string> *envp, const std::string dir = "",
2178                           int stdin_fd=0, int stdout_fd=1, int stderr_fd=2)
2179 {
2180
2181         // prepend the directory (if any) to the filename,
2182         // unless the filename is an absolute pathname
2183         // 
2184         // The filename is an absolute pathname if it starts with a '/' on UNIX,
2185         // or a letter and colon pair on Windows.
2186
2187   startup_cerr << "Creating process " << File << " in directory " << dir << endl;
2188
2189   if (argv) {
2190     startup_cerr << "Arguments: (" << argv->size() << ")" << endl;
2191     for (unsigned a = 0; a < argv->size(); a++)
2192       startup_cerr << "   " << a << ": " << (*argv)[a] << endl;
2193   }
2194   if (envp) {
2195     startup_cerr << "Environment: (" << envp->size() << ")" << endl;
2196     for (unsigned e = 0; e < envp->size(); e++)
2197       startup_cerr << "   " << e << ": " << (*envp)[e] << endl;
2198   }
2199   startup_printf("Stdin: %d, stdout: %d, stderr: %d\n", stdin_fd, stdout_fd, stderr_fd);
2200
2201   //    int traceLink = -1; // set by forkNewProcess, below.
2202
2203   //    int pid = -1;
2204   //    int tid;
2205
2206     // NT
2207     //    int thrHandle_temp;
2208
2209     process *theProc = SignalGeneratorCommon::newProcess(File, dir,
2210                                                                     argv, envp,
2211                                                                     stdin_fd, stdout_fd, 
2212                                                                     stderr_fd);
2213
2214    if (!theProc || !theProc->sh) {
2215        startup_printf("%s[%d]: For new process... failed (theProc %p, SH %p)\n", FILE__, __LINE__,
2216                       theProc, theProc ? theProc->sh : NULL);
2217        getMailbox()->executeCallbacks(FILE__, __LINE__);
2218        return NULL;
2219    }
2220
2221     startup_printf( "%s[%d]:  Fork new process... succeeded",FILE__, __LINE__);
2222
2223     // Register the pid with the BPatch library (not yet associated with a
2224     // BPatch_thread object).
2225     assert(BPatch::bpatch != NULL);
2226     BPatch::bpatch->registerProvisionalThread(theProc->sh->getPid());
2227
2228     theProc->set_status(running);
2229
2230     // We need to add this as soon as possible, since a _lot_ of things
2231     // do lookups.
2232     processVec.push_back(theProc);
2233     activeProcesses++;
2234
2235     statusLine("initializing process data structures");
2236
2237     if (!theProc->setupGeneral()) {
2238         startup_printf("[%s:%u] - Couldn't setupGeneral\n", FILE__, __LINE__);
2239         if (theProc->sh)
2240         cleanupBPatchHandle(theProc->sh->getPid());
2241         processVec.pop_back();
2242         delete theProc;
2243         return NULL;
2244     }
2245
2246     // Let's try to profile memory usage
2247 #if defined(PROFILE_MEM_USAGE)
2248    void *mem_usage = sbrk(0);
2249    fprintf(stderr, "Post process: sbrk %p\n", mem_usage);
2250 #endif
2251
2252    assert(theProc->reachedBootstrapState(bootstrapped_bs));
2253    startup_printf("%s[%d]:  process state: %s\n\n\n\n", FILE__, __LINE__, theProc->getBootstrapStateAsString().c_str());
2254    return theProc;    
2255 }
2256
2257
2258 process *ll_attachProcess(const std::string &progpath, int pid, void *container_proc_) 
2259 {
2260   // implementation of dynRPC::attach() (the igen call)
2261   // This is meant to be "the other way" to start a process (competes w/ createProcess)
2262   
2263   // progpath gives the full path name of the executable, which we use ONLY to
2264   // read the symbol table.
2265   
2266   // We try to make progpath optional, since given pid, we should be able to
2267   // calculate it with a clever enough search of the process' PATH, examining
2268   // its argv[0], examining its current directory, etc.  /proc gives us this
2269   // information on solaris...not sure about other platforms...
2270
2271     // No longer take the afterAttach argument. Instead, the process object records
2272     // the state of the process at attach, and the user can read and act on this as
2273     // they please -- bernat, JAN03
2274
2275   startup_cerr << "welcome to attachProcess for pid " << pid << endl;
2276   startup_cerr << "Given program path: " << progpath << endl;
2277
2278   // QUESTION: When we attach to a process, do we want to redirect its stdout/stderr
2279   //           (like we do when we fork off a new process the 'usual' way)?
2280   //           My first guess would be no.  -ari
2281   //           But although we may ignore the io, we still need the trace stream.
2282   
2283   // When we attach to a process, we don't fork...so this routine is much
2284   // simpler than its "competitor", ll_createProcess() (above).
2285   std::string fullPathToExecutable = process::tryToFindExecutable(progpath, pid);
2286
2287   if (!fullPathToExecutable.length()) {
2288       return NULL;
2289   }
2290
2291   process *theProc = SignalGeneratorCommon::newProcess(fullPathToExecutable, pid);
2292   if (!theProc || !theProc->sh) {
2293        startup_printf("%s[%d]: Fork new process... failed\n", FILE__, __LINE__);
2294     getMailbox()->executeCallbacks(FILE__, __LINE__);
2295     return NULL;
2296   }
2297   theProc->set_up_ptr(container_proc_);
2298
2299   // Add this as we can't do _anything_ without a process to look up.
2300   processVec.push_back(theProc);
2301   activeProcesses++;
2302
2303   if (!theProc->setupGeneral()) {
2304         processVec.pop_back();
2305       delete theProc;
2306       return NULL;
2307   }
2308
2309   return theProc; // successful
2310 }
2311
2312 /***************************************************************************
2313  **** Runtime library initialization code (Dyninst)                     ****
2314  ***************************************************************************/
2315
2316 /*
2317  * Gratuitously large comment. This diagrams the startup flow of 
2318  * messages between the mutator and mutatee. Entry points 
2319  * for create and attach process are both given.
2320  *     Mutator           Signal              Mutatee
2321  * Create:
2322  *     Fork/Exec
2323  *                     <-- Trap              Halted in exec
2324  *     Install trap in main             
2325  *                     <-- Trap              Halted in main
2326  *  Attach: (also paused, not in main)
2327  *     Install call to dlopen/
2328  *     LoadLibrary       
2329  *                     <-- Trap              In library load
2330  *     Set parameters in library
2331  *                     <-- Trap              Finished loading
2332  *     Restore code and leave paused
2333  *     Finalize library
2334  *       If finalizing fails, 
2335  *       init via iRPC
2336  *
2337  * Note: we've actually stopped trying to trap the library, since
2338  * setting arguments via inferior RPC is just as easy and a _lot_
2339  * cleaner.
2340  */
2341
2342 /*
2343  * In all cases, the process is left paused at the entry of main
2344  * (create) or where it was (attach). No permanent instrumentation
2345  * is inserted.
2346  */
2347
2348 // Load and initialize the runtime library: returns when the RT lib
2349 // is both loaded and initialized.
2350 // Return val: false=error condition
2351
2352 bool process::loadDyninstLib() {
2353    startup_printf("%s[%d]: Entry to loadDyninstLib\n", FILE__, __LINE__);
2354    // Wait for the process to get to an initialized (dlopen exists)
2355    // state
2356 #if !defined(os_windows)    
2357    if (!reachedBootstrapState(initialized_bs) && wasCreatedViaAttach())
2358    {
2359       insertTrapAtEntryPointOfMain();
2360       continueProc();
2361    }
2362 #endif
2363    while (!reachedBootstrapState(libcLoaded_bs)) {
2364       startup_printf("%s[%d]: Waiting for process to load libc or reach "
2365                      "initialized state...\n", FILE__, __LINE__);
2366       if(hasExited()) {
2367 #if defined(os_linux)
2368          bperr("The process exited during startup.  This is likely due to one " 
2369                "of two reasons:\n"
2370                "A). The application is mis-built and unable to load.  Try " 
2371                "running the application outside of Dyninst and see if it " 
2372                "loads properly.\n"
2373                "B). libdyninstAPI_RT is mis-built.  Try loading the library " 
2374                "into another application and see if it reports any errors.  "
2375                "Ubuntu users - You may need to rebuild the RT library "
2376                "with the DISABLE_STACK_PROT line enabled in " 
2377                "core/make.config.local");
2378 #endif
2379          startup_printf("%s[%d] Program exited early, never reached " 
2380                         "initialized state\n", FILE__, __LINE__);
2381          startup_printf("Error is likely due to the application or RT " 
2382                         "library having missing symbols or dependencies\n");
2383          return false;
2384       }
2385       getMailbox()->executeCallbacks(FILE__, __LINE__);
2386       pdvector<eventType> evts;
2387       evts.push_back(evtProcessAttach); 
2388       evts.push_back(evtProcessInit); 
2389       evts.push_back(evtLibcLoaded);
2390       evts.push_back(evtProcessExit); 
2391       if (reachedBootstrapState(libcLoaded_bs)) break;
2392       sh->waitForOneOf(evts);
2393       getMailbox()->executeCallbacks(FILE__, __LINE__);
2394    }
2395    startup_printf("%s[%d]: Ready to initialize dynamic linking tracer\n", 
2396                   FILE__, __LINE__);
2397
2398    // We've hit the initialization trap, so load dyninst lib and
2399    // force initialization
2400    std::string buffer = std::string("PID=") + utos(getPid());
2401    buffer += std::string(", initializing shared objects");       
2402    statusLine(buffer.c_str());
2403
2404    // Perform initialization...
2405    if (!dyn->initialize()) 
2406    {
2407       cerr << "Dyninst was unable to load the dyninst runtime library "
2408            << "into the application.  This may be caused by statically "
2409            << "linked executables, or by having dyninst linked against a "
2410            << "different version of libelf than it was built with." << endl;
2411       return false;
2412    }
2413    startup_printf("Initialized dynamic linking tracer\n");
2414
2415    if (!getDyninstRTLibName()) {
2416       startup_printf("Failed to get Dyninst RT lib name\n");
2417       return false;
2418    }
2419    startup_printf("%s[%d]: Got Dyninst RT libname: %s\n", FILE__, __LINE__,
2420                   dyninstRT_name.c_str());
2421
2422    // if tracing system calls then put a breakpoint at __libc_start_main
2423    if (getTraceState() >= instrumentLibc_ts) {
2424
2425       // instrument libc
2426       instrumentLibcStartMain();
2427
2428       // wait for process to reach initialized bootstrap state 
2429       while (!reachedBootstrapState(initialized_bs)) {
2430          startup_printf("%s[%d]: Waiting for process to reach initialized state...\n", 
2431                         FILE__, __LINE__);
2432          if(hasExited()) {
2433             return false;
2434          }
2435          getMailbox()->executeCallbacks(FILE__, __LINE__);
2436          pdvector<eventType> evts;
2437          evts.push_back(evtProcessAttach); 
2438          evts.push_back(evtProcessInit); 
2439          evts.push_back(evtProcessExit); 
2440          if (reachedBootstrapState(initialized_bs)) break;
2441          sh->waitForOneOf(evts);
2442          getMailbox()->executeCallbacks(FILE__, __LINE__);
2443       }
2444    }
2445
2446    // And get the list of all shared objects in the process. More properly,
2447    // get the address of dlopen.
2448    if (!processSharedObjects()) {
2449       startup_printf("Failed to get initial shared objects\n");
2450       return false;
2451    }
2452
2453    startup_printf("Processed initial shared objects:\n");
2454
2455    for (unsigned debug_iter = 1; debug_iter < mapped_objects.size(); debug_iter++)
2456       startup_printf("%d: %s\n", debug_iter, 
2457                      mapped_objects[debug_iter]->debugString().c_str());
2458
2459    startup_printf("----\n");
2460
2461    if (dyninstLibAlreadyLoaded()) {
2462       // LD_PRELOAD worked or we are attaching for the second time
2463       // or app was linked with RTlib
2464       setBootstrapState(loadedRT_bs);
2465       if (main_brk_addr) {
2466          //The trap at the entry of is usually cleaned when we handle a RT
2467          // library load.  Since that's not going to happen, clean it manually.
2468          handleTrapAtEntryPointOfMain(getInitialLwp());
2469       }
2470    }
2471    else {
2472       // Force a call to dlopen(dyninst_lib)
2473       buffer = std::string("PID=") + utos(getPid());
2474       buffer += std::string(", loading dyninst library");       
2475       statusLine(buffer.c_str());
2476        
2477       startup_printf("%s[%d]: Starting load of Dyninst library...\n",
2478                      FILE__, __LINE__);
2479       if (!loadDYNINSTlib()) {
2480          fprintf(stderr, "%s[%d]:  FIXME:  loadDYNINSTlib failed\n", FILE__, __LINE__);
2481       }
2482       startup_printf("%s[%d]: Think we have Dyninst RT lib set up...\n", FILE__, __LINE__);
2483        
2484       setBootstrapState(loadingRT_bs);
2485
2486       if (!sh->continueProcessAsync()) {
2487          assert(0);
2488       }
2489        
2490       // Loop until the dyninst lib is loaded
2491       while (!reachedBootstrapState(loadedRT_bs)) {
2492          if(hasExited()) {
2493             startup_printf("Odd, process exited while waiting for "
2494                            "Dyninst RT lib load\n");
2495             return false;
2496          }
2497           
2498          sh->waitForEvent(evtProcessLoadedRT);
2499       }
2500       getMailbox()->executeCallbacks(FILE__, __LINE__);
2501
2502       // We haven't inserted a trap at dlopen yet (as we require the
2503       // runtime lib for that) So re-check all loaded libraries (and
2504       // add to the list gotten earlier) We force a compare even
2505       // though the PC is not at the correct address.
2506       dyn->set_force_library_check();
2507       EventRecord load_rt_event;
2508       load_rt_event.proc = this;
2509       load_rt_event.lwp = NULL;
2510       load_rt_event.type = evtLoadLibrary;
2511       load_rt_event.what = SHAREDOBJECT_ADDED;
2512       if (!handleChangeInSharedObjectMapping(load_rt_event)) {
2513          fprintf(stderr, "%s[%d]:  handleChangeInSharedObjectMapping "
2514                  "failed!\n", FILE__, __LINE__);
2515       }
2516       dyn->unset_force_library_check();
2517
2518       // Make sure the library was actually loaded
2519       if (!runtime_lib) {
2520          fprintf(stderr, "%s[%d]:  Don't have runtime library handle\n",
2521                  FILE__, __LINE__);
2522          return false;
2523       }
2524    }    
2525    buffer = std::string("PID=") + utos(getPid());
2526    buffer += std::string(", initializing mutator-side structures");
2527    statusLine(buffer.c_str());    
2528
2529    // The library is loaded, so do mutator-side initialization
2530    buffer = std::string("PID=") + utos(getPid());
2531    buffer += std::string(", finalizing RT library");
2532    statusLine(buffer.c_str());    
2533    startup_printf("%s[%d]: (%d) finalizing dyninst RT library\n", FILE__, __LINE__, getPid());
2534
2535    if (!finalizeDyninstLib())
2536       startup_printf("%s[%d]:  failed to finalize dyninst lib\n", FILE__, __LINE__);
2537       //fprintf(stderr, "%s[%d]:  failed to finalize dyninst lib\n", FILE__, __LINE__);
2538
2539    if (!reachedBootstrapState(bootstrapped_bs)) {
2540       // For some reason we haven't run dyninstInit successfully.
2541       // Probably because we didn't set parameters before 
2542       // dyninstInit was automatically run. Catchup with
2543       // an inferiorRPC is the best bet.
2544       buffer = std::string("PID=") + utos(getPid());
2545       buffer += std::string(", finalizing library via inferior RPC");
2546       statusLine(buffer.c_str());    
2547       iRPCDyninstInit();        
2548    }
2549
2550    buffer = std::string("PID=") + utos(getPid());
2551    buffer += std::string(", dyninst RT lib ready");
2552    statusLine(buffer.c_str());    
2553
2554    return true;
2555 }
2556
2557
2558 // Set the shared object mapping for the RT library
2559 bool process::setDyninstLibPtr(mapped_object *RTobj) 
2560 {
2561     assert (!runtime_lib);
2562     runtime_lib = RTobj;
2563     return true;
2564 }
2565
2566
2567 // Set up the parameters for DYNINSTinit in the RT lib
2568
2569 bool process::setDyninstLibInitParams() 
2570 {
2571    startup_cerr << "process::setDYNINSTinitArguments()" << endl;
2572
2573    int pid = getpid();
2574    
2575    // Cause: 
2576    // 1 = created
2577    // 2 = forked
2578    // 3 = attached
2579    
2580    int cause;
2581    switch (creationMechanism_) {
2582    case created_cm:
2583        cause = 1;
2584        break;
2585    case attached_cm:
2586        cause = 3;
2587        break;
2588    case attachedToCreated_cm:
2589        // Uhhh....
2590        cause = 3;
2591        break;
2592    default:
2593        assert(0);
2594        break;
2595    }
2596    
2597    // Now we write these variables into the following global vrbles
2598    // in the dyninst library:
2599    // libdyninstAPI_RT_init_localCause
2600    // libdyninstAPI_RT_init_localPid
2601
2602    pdvector<int_variable *> vars;
2603
2604    if (!findVarsByAll("libdyninstAPI_RT_init_localCause",
2605                       vars,
2606                       dyninstRT_name))
2607        if (!findVarsByAll("_libdyninstAPI_RT_init_localCause",
2608                           vars))
2609           if (!findVarsByAll("libdyninstAPI_RT_init_localCause",
2610                               vars))
2611
2612            assert(0 && "Could not find necessary internal variable");
2613    assert(vars.size() == 1);
2614    if (!writeDataSpace((void*)vars[0]->getAddress(), sizeof(int), (void *)&cause))
2615      fprintf(stderr, "%s[%d]:  writeDataSpace failed\n", FILE__, __LINE__);
2616    vars.clear();
2617
2618    if (!findVarsByAll("libdyninstAPI_RT_init_localPid", vars))
2619        if (!findVarsByAll("_libdyninstAPI_RT_init_localPid", vars))
2620            assert(0 && "Could not find necessary internal variable");
2621    assert(vars.size() == 1);
2622    if (!writeDataSpace((void*)vars[0]->getAddress(), sizeof(int), (void *)&pid))
2623      fprintf(stderr, "%s[%d]:  writeDataSpace failed\n", FILE__, __LINE__);
2624    vars.clear();   
2625
2626    if (!findVarsByAll("libdyninstAPI_RT_init_maxthreads", vars))
2627        if (!findVarsByAll("_libdyninstAPI_RT_init_maxthreads", vars))
2628            assert(0 && "Could not find necessary internal variable");
2629    assert(vars.size() == 1);
2630    if (!writeDataSpace((void*)vars[0]->getAddress(), sizeof(int), (void *) &max_number_of_threads))
2631      fprintf(stderr, "%s[%d]:  writeDataSpace failed\n", FILE__, __LINE__);
2632    vars.clear();   
2633
2634    extern int dyn_debug_rtlib;
2635    if (!findVarsByAll("libdyninstAPI_RT_init_debug_flag", vars))
2636        if (!findVarsByAll("_libdyninstAPI_RT_init_debug_flag", vars))
2637            assert(0 && "Could not find necessary internal variable");
2638    assert(vars.size() == 1);
2639    if (!writeDataSpace((void*)vars[0]->getAddress(), sizeof(int), (void *) &dyn_debug_rtlib))
2640      fprintf(stderr, "%s[%d]:  writeDataSpace failed\n", FILE__, __LINE__);
2641    vars.clear();   
2642    if (dyn_debug_rtlib) {
2643       fprintf(stderr, "%s[%d]:  set var in RTlib for debug...\n", FILE__, __LINE__);
2644    }
2645
2646    startup_cerr << "process::installBootstrapInst() complete" << endl;   
2647    return true;
2648 }
2649
2650 // Call DYNINSTinit via an inferiorRPC
2651 bool process::iRPCDyninstInit() 
2652 {
2653     startup_printf("%s[%d]: Running DYNINSTinit via irpc\n", FILE__, __LINE__);
2654     // Duplicates the parameter code in setDyninstLibInitParams()
2655     int pid = getpid();
2656     int maxthreads = maxNumberOfThreads();
2657     extern int dyn_debug_rtlib;
2658
2659     int cause = 0;
2660     switch (creationMechanism_) {
2661     case created_cm:
2662         cause = 1;
2663         break;
2664     case attached_cm:
2665         cause = 3;
2666         break;
2667     case attachedToCreated_cm:
2668         // Uhhh....
2669         cause = 3;
2670         break;
2671     default:
2672         assert(0);
2673         break;
2674    }
2675
2676     pdvector<AstNodePtr> the_args(4);
2677     the_args[0] = AstNode::operandNode(AstNode::Constant, (void*)(Address)cause);
2678     the_args[1] = AstNode::operandNode(AstNode::Constant, (void*)(Address)pid);
2679     the_args[2] = AstNode::operandNode(AstNode::Constant, (void*)(Address)maxthreads);
2680     the_args[3] = AstNode::operandNode(AstNode::Constant, (void*)(Address)dyn_debug_rtlib);
2681     AstNodePtr dynInit = AstNode::funcCallNode("DYNINSTinit", the_args);
2682     getRpcMgr()->postRPCtoDo(dynInit,
2683                              true, // Don't update cost
2684                              process::DYNINSTinitCompletionCallback,
2685                              NULL, // No user data
2686                              false, // Don't run when done
2687                              true, // Use reserved memory
2688                              NULL, NULL);// No particular thread or LWP
2689
2690     startup_printf("%s[%d][%s]:  posted RPC\n", FILE__, __LINE__, getThreadStr(getExecThreadID()));
2691     // We loop until dyninst init has run (check via the callback)
2692      inferiorrpc_printf("%s[%d]:  waiting for rpc completion\n", FILE__, __LINE__);
2693
2694      bool rpcNeedsContinue = false;
2695      getRpcMgr()->launchRPCs(rpcNeedsContinue,
2696                              false); // false: not running
2697      assert(rpcNeedsContinue);
2698      continueProc();
2699
2700     while (!reachedBootstrapState(bootstrapped_bs)) {
2701     startup_printf("%s[%d][%s]:  waiting for RPC completion\n", FILE__, __LINE__, getThreadStr(getExecThreadID()));
2702         if (hasExited()) {
2703             fprintf(stderr, "%s[%d][%s]:  unexpected exit\n", FILE__, __LINE__, getThreadStr(getExecThreadID()));
2704            return false;
2705         }
2706         getMailbox()->executeCallbacks(FILE__, __LINE__);
2707         // This needs to be before after _anything_ that can give up the global lock.
2708         if (reachedBootstrapState(bootstrapped_bs)) break;
2709
2710         //sh->waitForEvent(evtRPCSignal, this, NULL /*lwp*/, statusRPCDone);
2711         sh->waitForEvent(evtAnyEvent, this, NULL /*lwp*/);
2712         getMailbox()->executeCallbacks(FILE__, __LINE__);
2713     }
2714     startup_printf("%s[%d][%s]:  bootstrapped\n", FILE__, __LINE__, getThreadStr(getExecThreadID()));
2715     startup_printf("%s[%u]: - Ran DYNINSTinit via irpc\n", FILE__, __LINE__);
2716     return true;
2717 }
2718
2719 bool process::attach() 
2720 {
2721    dictionary_hash_iter<unsigned, dyn_lwp *> lwp_iter(real_lwps);
2722    dyn_lwp *lwp;
2723    unsigned index;
2724    assert(getRepresentativeLWP());  // we expect this to be defined
2725    // Though on linux, if process found to be MT, there will be no
2726    // representativeLWP since there is no lwp which controls the entire
2727    // process for MT linux.
2728
2729    startup_printf("[%d]: attaching to representative LWP\n", getPid());
2730
2731    if( !getRepresentativeLWP()->attach()) {
2732       startup_printf("%s[%d]:  failed to attach to rep lwp\n", FILE__, __LINE__);
2733       return false;
2734    }
2735
2736    while (lwp_iter.next(index, lwp)) {
2737        startup_printf("[%d]: attaching to LWP %d\n", getPid(), index);
2738
2739       if (!lwp->attach()) {
2740          deleteLWP(lwp);
2741          return false;
2742       }
2743    }
2744    // Fork calls attach() but is probably past this; silencing warning
2745    if (!reachedBootstrapState(attached_bs))
2746        setBootstrapState(attached_bs);
2747    signal_printf("%s[%d]: calling signalActiveProcess from attach\n",
2748                  FILE__, __LINE__);
2749    //sh->signalActiveProcess();
2750    startup_printf("[%d]: setting process flags\n", getPid());
2751    return setProcessFlags();
2752 }
2753
2754
2755 // Callback: finish mutator-side processing for dyninst lib
2756
2757 bool process::finalizeDyninstLib() 
2758 {
2759    startup_printf("%s[%d]:  isAttached() = %s\n", FILE__, __LINE__, isAttached() ? "true" : "false");
2760    startup_printf("%s[%d]: %s\n", FILE__, __LINE__, getStatusAsString().c_str());
2761    
2762     assert (isStopped());
2763     if (reachedBootstrapState(bootstrapped_bs)) {
2764         return true;
2765     }
2766
2767    DYNINST_bootstrapStruct bs_record;
2768    if (!extractBootstrapStruct(&bs_record))
2769       assert(false);
2770
2771    // Read the structure; if event 0 then it's undefined! (not yet written)
2772    if (bs_record.event == 0)
2773    {
2774        startup_printf("%s[%d]: - bs_record.event is undefined\n", FILE__, __LINE__);
2775        return false;
2776    }
2777
2778    // Now that we have the dyninst library loaded, insert the hooks to dlopen/dlclose
2779    // (which may require the dyninst library)
2780
2781    assert(bs_record.event == 1 || bs_record.event == 2 || bs_record.event==3);
2782
2783    bool calledFromFork = (bs_record.event == 2);
2784    bool calledFromAttach = (bs_record.event == 3);
2785
2786    pdvector<int_variable *> obsCostVec;
2787    if (!findVarsByAll("DYNINSTobsCostLow", obsCostVec))
2788        assert(0);
2789    assert(obsCostVec.size() == 1);
2790
2791    costAddr_ = obsCostVec[0]->getAddress();
2792
2793    assert(costAddr_);
2794
2795    // Set breakpoints to detect (un)loaded libraries
2796    // Do this after the observed cost is set, in case we use instrumentation
2797    if (!dyn->installTracing()) assert (0 && "Failed to install library mapping hooks");
2798
2799    if (!calledFromFork) {
2800
2801        // Install initial instrumentation requests
2802        std::string str=std::string("PID=") + utos(bs_record.pid) + ", installing default (DYNINST) inst...";
2803        statusLine(str.c_str());
2804        
2805        extern pdvector<instMapping*> initialRequests; // init.C
2806
2807        // Install any global instrumentation requests
2808        installInstrRequests(initialRequests);
2809
2810        // Install process-specific instrumentation requests
2811        installInstrRequests(tracingRequests);
2812        
2813        // Install our system call tracing
2814        tracedSyscalls_ = new syscallNotification(this);
2815
2816        //#ifdef i386_unknown_linux2_0
2817        //if(pdFlavor != "mpi") {
2818        //#endif
2819           // TODO: prefork and pre-exit should depend on whether a callback is defined
2820           if (!tracedSyscalls_->installPreFork()) 
2821              cerr << "Warning: failed pre-fork notification setup" << endl;
2822           if (!tracedSyscalls_->installPostFork()) 
2823              cerr << "Warning: failed post-fork notification setup" << endl;
2824           if (!tracedSyscalls_->installPreExec()) 
2825              cerr << "Warning: failed pre-exec notification setup" << endl;
2826           if (!tracedSyscalls_->installPostExec()) 
2827              cerr << "Warning: failed post-exec notification setup" << endl;
2828           if (!tracedSyscalls_->installPreExit()) 
2829              cerr << "Warning: failed pre-exit notification setup" << endl;
2830           if (!tracedSyscalls_->installPreLwpExit()) 
2831              cerr << "Warning: failed pre-lwp-exit notification setup" << endl;
2832           //#ifdef i386_unknown_linux2_0
2833           //}
2834           //#endif
2835    }
2836    else { // called from a forking process
2837        process *parentProcess = process::findProcess(bs_record.ppid);
2838        if (parentProcess) {
2839            if (parentProcess->status() == stopped) {
2840                if (!parentProcess->continueProc())
2841                    assert(false);
2842            }
2843            else
2844                parentProcess->continueAfterNextStop();
2845        }
2846        
2847    }
2848
2849    startup_printf("Initializing tramp guard\n");
2850    if (!initTrampGuard())
2851       assert(0);
2852
2853 #if defined(cap_threads)
2854    if (multithread_capable())
2855    {
2856       initMT();
2857    }
2858 #endif
2859
2860    if (!calledFromAttach) {
2861        std::string str=std::string("PID=") + utos(bs_record.pid) + ", dyninst ready.";
2862        statusLine(str.c_str());
2863    }
2864
2865    startup_printf("%s[%d]:  bootstrap done\n", FILE__, __LINE__);
2866    // Ready to rock
2867    setBootstrapState(bootstrapped_bs);
2868    sh->signalEvent(evtProcessInitDone);
2869
2870    return true;
2871 }
2872
2873 void finalizeDyninstLibWrapper(process *p) 
2874 {
2875   global_mutex->_Lock(FILE__, __LINE__);
2876   p->finalizeDyninstLib();
2877   global_mutex->_Unlock(FILE__, __LINE__);
2878 }
2879
2880 int process::DYNINSTinitCompletionCallback(process* theProc,
2881                                             unsigned /* rpc_id */,
2882                                             void* /*userData*/, // user data
2883                                             void* /*ret*/) // return value from DYNINSTinit
2884 {
2885     //global_mutex->_Lock(FILE__, __LINE__);
2886     startup_printf("%s[%d]:  about to finalize Dyninst Lib\n", FILE__, __LINE__);
2887     theProc->finalizeDyninstLib();
2888     //FinalizeRTLibCallback *cbp = new FinalizeRTLibCallback(finalizeDyninstLibWrapper);
2889     //FinalizeRTLibCallback &cb = *cbp;
2890     //cb.setSynchronous(false);
2891     //cb(theProc);
2892     //global_mutex->_Unlock(FILE__, __LINE__);
2893     return 0;
2894 }
2895
2896 dyn_thread *process::STdyn_thread() { 
2897    assert(! multithread_capable());
2898    assert(threads.size()>0);
2899    return threads[0];
2900 }
2901
2902
2903 // If true is passed for ignore_if_mt_not_set, then an error won't be
2904 // initiated if we're unable to determine if the program is multi-threaded.
2905 // We are unable to determine this if the daemon hasn't yet figured out what
2906 // libraries are linked against the application.  Currently, we identify an
2907 // application as being multi-threaded if it is linked against a thread
2908 // library (eg. libpthreads.a on AIX).  There are cases where we are querying
2909 // whether the app is multi-threaded, but it can't be determined yet but it
2910 // also isn't necessary to know.
2911 bool process::multithread_capable(bool ignore_if_mt_not_set)
2912 {
2913 #if !defined(cap_threads)
2914    return false;
2915 #endif
2916
2917 #if defined(os_windows)
2918    return true;
2919 #endif
2920
2921    if(cached_result != not_cached) {
2922        if(cached_result == cached_mt_true) {
2923            return true;
2924        } else {
2925            assert(cached_result == cached_mt_false);
2926            return false;
2927        }
2928    }
2929    
2930    if(mapped_objects.size() <= 1) {
2931        if(! ignore_if_mt_not_set) {
2932            cerr << "   can't query MT state, assert\n";
2933            assert(false);
2934        }
2935        return false;
2936    }
2937
2938    if(findObject("libthread.so*", true) ||  // Solaris
2939       findObject("libpthreads.*", true)  ||  // AIX
2940       findObject("libpthread.so*", true))   // Linux
2941    {
2942        cached_result = cached_mt_true;
2943        return true;
2944    } else {
2945        cached_result = cached_mt_false;
2946        return false;
2947    }
2948 }
2949
2950 void process::updateThreadIndex(dyn_thread *thread, int index) {
2951     assert(thread->get_index() == -1 && index != -1);
2952     thread->update_index(index);
2953     getRpcMgr()->addThread(thread);
2954 }
2955
2956 void process::addThread(dyn_thread *thread)
2957 {
2958    if (thread->get_index() != -1) {
2959      getRpcMgr()->addThread(thread);
2960    }
2961    threads.push_back(thread);
2962 }
2963
2964 bool process::multithread_ready(bool ignore_if_mt_not_set) {
2965     if (thread_index_function != NULL)
2966         return true;
2967     if (!multithread_capable(ignore_if_mt_not_set))
2968         return false;
2969     if (!reachedBootstrapState(loadedRT_bs))
2970         return false;
2971
2972     thread_index_function = findOnlyOneFunction("DYNINSTthreadIndex");
2973
2974     return thread_index_function != NULL;
2975 }
2976
2977 dyn_lwp *process::query_for_stopped_lwp() 
2978 {
2979    dyn_lwp *foundLWP = NULL;
2980    dictionary_hash_iter<unsigned, dyn_lwp *> lwp_iter(real_lwps);
2981    dyn_lwp *lwp, *backup_lwp = NULL;
2982    unsigned index;
2983
2984    if(IndependentLwpControl()) {
2985       while (lwp_iter.next(index, lwp)) {
2986          if (lwp->status() == stopped || lwp->status() == neonatal)
2987          {
2988             if (lwp->isDoingAttach_) {
2989                backup_lwp = lwp;
2990                continue;
2991             }
2992             foundLWP = lwp;
2993             break;
2994          }
2995       }
2996       if (!foundLWP && backup_lwp) {
2997          foundLWP = backup_lwp;
2998       }
2999      
3000       if(foundLWP == NULL  &&  getRepresentativeLWP() != NULL) {
3001          if(getRepresentativeLWP()->status() == stopped ||
3002             getRepresentativeLWP()->status() == neonatal)
3003             foundLWP = getRepresentativeLWP();
3004       }
3005    } else {
3006       if(this->status() == stopped || this->status() == neonatal) {
3007          foundLWP = getRepresentativeLWP();
3008       }
3009    }
3010
3011    return foundLWP;
3012 }
3013
3014 dyn_lwp *process::query_for_running_lwp() 
3015 {
3016    dyn_lwp *foundLWP = NULL;
3017    dictionary_hash_iter<unsigned, dyn_lwp *> lwp_iter(real_lwps);
3018    dyn_lwp *lwp;
3019    unsigned index;
3020
3021    if(IndependentLwpControl()) {
3022       while (lwp_iter.next(index, lwp)) {
3023          if (!lwp) continue;
3024          if(lwp->status() == running || lwp->status() == neonatal) {
3025             foundLWP = lwp;
3026             break;
3027          }
3028       }
3029       if(foundLWP == NULL  &&  getRepresentativeLWP() != NULL) {
3030          if(getRepresentativeLWP()->status() == running ||
3031             getRepresentativeLWP()->status() == neonatal)
3032             foundLWP = getRepresentativeLWP();
3033       }
3034    } else {
3035       if(this->status() == running || this->status() == neonatal) {
3036          foundLWP = getRepresentativeLWP();
3037       }
3038    }
3039
3040    return foundLWP;
3041 }
3042
3043 // first searches for stopped lwp and if not found explicitly stops an lwp
3044 dyn_lwp *process::stop_an_lwp(bool *wasRunning) 
3045 {
3046    dictionary_hash_iter<unsigned, dyn_lwp *> lwp_iter(real_lwps);
3047    dyn_lwp *lwp;
3048    dyn_lwp *stopped_lwp = NULL;
3049    unsigned index;
3050    if (!isAttached()) {
3051      fprintf(stderr, "%s[%d]:  cannot stop_an_lwp, process not attached\n", 
3052              FILE__, __LINE__);
3053      return NULL;
3054    }
3055
3056    if(IndependentLwpControl()) {
3057       while (lwp_iter.next(index, lwp)) {
3058          if (lwp->status() == exited) 
3059             continue;
3060          if (lwp->status() == stopped) {
3061              stopped_lwp = lwp;
3062              if (wasRunning)
3063                  *wasRunning = false;
3064              break;
3065          }
3066          if (lwp->pauseLWP()) {
3067              if (lwp->status() != stopped) 
3068                  continue;
3069             stopped_lwp = lwp;
3070             if (wasRunning)
3071                 *wasRunning = true;
3072             break;
3073          }
3074       }
3075       if(stopped_lwp == NULL) {
3076          if (!getRepresentativeLWP()) return NULL;
3077          if(getRepresentativeLWP()->status() == stopped) {
3078              if (wasRunning)
3079                  *wasRunning = false;
3080          } else {
3081             getRepresentativeLWP()->pauseLWP();
3082             if (wasRunning)
3083                 *wasRunning = true;
3084          }
3085          stopped_lwp = getRepresentativeLWP();
3086       }
3087    } else {
3088        // We whole-process pause....
3089       if(status() == stopped)
3090           if (wasRunning)
3091               *wasRunning = false;
3092       else {
3093           if (wasRunning)
3094               *wasRunning = true;
3095       }
3096
3097       processRunState_t oldState = sh->overrideSyncContinueState(stopRequest);
3098       sh->pauseProcessBlocking();
3099       sh->overrideSyncContinueState(oldState);
3100       stopped_lwp = getRepresentativeLWP();
3101    }
3102
3103    if (!stopped_lwp) {
3104      fprintf(stderr, "%s[%d][%s]:  stop_an_lwp failing\n", FILE__, __LINE__, getThreadStr(getExecThreadID()));
3105    }
3106    return stopped_lwp;
3107 }
3108
3109 bool process::terminateProc() 
3110 {
3111     if(status() == exited || status() == deleted) {
3112         return true;
3113     }
3114     if (status() == detached || !sh->isRunning()) {
3115         set_status(exited);
3116         return true;
3117     }
3118     terminateProcStatus_t retVal = terminateProc_();
3119     switch (retVal) {
3120     case terminateSucceeded: {
3121      // handle the kill signal on the process, which will dispatch exit callback
3122       signal_printf("%s[%d][%s]:  before waitForEvent(evtProcessExit)\n", 
3123               FILE__, __LINE__, getThreadStr(getExecThreadID()));
3124
3125       // Let it run so we can see it die...      
3126       set_status(running);
3127
3128       if (getExecThreadID() != sh->getThreadID()) {
3129           signal_printf("%s[%d][%s]:  signalling active process from termination\n", 
3130                         FILE__, __LINE__, getThreadStr(getExecThreadID()));
3131           sh->signalActiveProcess();
3132       }
3133       sh->waitForEvent(evtProcessExit);
3134       if (status() != deleted)
3135           set_status(exited);
3136       return true;
3137      }
3138      break;
3139    case alreadyTerminated:
3140      // don't try to consume a signal (since we can't), 
3141      // just set process status to exited
3142      set_status(exited);
3143      return true;
3144      break;
3145    case terminateFailed:
3146        set_status(exited);
3147      return false;
3148      break;
3149
3150    }
3151    assert (0 && "Can't be reached");
3152    return false;
3153 }
3154
3155 void process::writeDebugDataSpace(void *inTracedProcess, u_int amount, 
3156                                   const void *inSelf)
3157 {
3158   static unsigned write_no = 0;
3159
3160   if (!dyn_debug_write)
3161     return;
3162   write_printf("char ");
3163 #if defined(arch_x86_64)
3164   if (getAddressWidth() == 4)
3165     write_printf("x86_");
3166   else
3167     write_printf("amd64_");
3168 #elif defined(arch_x86)
3169   write_printf("x86_");
3170 #elif defined(arch_ia64)
3171   write_printf("ia64_");
3172 #elif defined(arch_power)
3173   write_printf("power_");
3174 #elif defined(arch_sparc)
3175   write_printf("sparc_");
3176 #else
3177   write_printf("unknown_");
3178 #endif
3179   write_printf("%lx_%d_%u[] = {", inTracedProcess, getPid(), write_no++);
3180
3181   const unsigned char *buffer = (const unsigned char *) inSelf;
3182   for (unsigned i=0; i < amount-1; i++) {
3183     if (amount && !(amount % 10))
3184       write_printf("\n");
3185     write_printf("0x%hhx, ", buffer[i]);
3186   }
3187   if (amount)
3188     write_printf("0x%hhx", buffer[amount-1]);
3189   write_printf(" };\n", buffer[amount-1]);
3190 }
3191
3192 /*
3193  * Copy data from controller process to the named process.
3194  */
3195 bool process::writeDataSpace(void *inTracedProcess, unsigned size,
3196                              const void *inSelf) 
3197 {
3198    bool needToCont = false;
3199
3200    if (!isAttached()) return false;
3201
3202    dyn_lwp *stopped_lwp = query_for_stopped_lwp();
3203    if(stopped_lwp == NULL) {
3204       stopped_lwp = stop_an_lwp(&needToCont);
3205       if(stopped_lwp == NULL) {
3206          std::string msg =
3207             std::string("System error: unable to write to process data "
3208                      "space (WDS): couldn't stop an lwp\n");
3209          fprintf(stderr, "%s[%d]:  stop_an_lwp failed\n", FILE__, __LINE__);
3210          showErrorCallback(38, msg);
3211          return false;
3212       }
3213    }
3214    
3215    bool res = stopped_lwp->writeDataSpace(inTracedProcess, size, inSelf);
3216    if (!res) {
3217        fprintf(stderr, "%s[%d]: WDS failure - %d bytes from %p to %p, lwp %p\n",
3218                FILE__, __LINE__, size, inSelf, inTracedProcess, stopped_lwp);
3219        std::string msg = std::string("System error: unable to write to process data "
3220                                "space (WDS):") + std::string(strerror(errno));
3221        showErrorCallback(38, msg);
3222        return false;
3223    }
3224
3225    if (dyn_debug_write)
3226      writeDebugDataSpace(inTracedProcess, size, inSelf);
3227
3228    if(needToCont) {
3229       return stopped_lwp->continueLWP();
3230    }
3231    return true;
3232 }
3233
3234 bool process::readDataSpace(const void *inTracedProcess, unsigned size,
3235                             void *inSelf, bool displayErrMsg) 
3236 {
3237    bool needToCont = false;
3238
3239    if (!isAttached()) {
3240       fprintf(stderr, "%s[%d][%s]:  readDataSpace() failing, not attached\n",
3241             FILE__, __LINE__, getThreadStr(getExecThreadID()));
3242       return false;
3243    }
3244
3245    dyn_lwp *stopped_lwp = query_for_stopped_lwp();
3246    if(stopped_lwp == NULL) {
3247       stopped_lwp = stop_an_lwp(&needToCont);
3248       if (stopped_lwp == NULL) {
3249          std::string msg =
3250             std::string("System error: unable to read to process data "
3251                   "space: couldn't stop an lwp\n");
3252          fprintf(stderr, "%s[%d]:  stop_an_lwp failed\n", FILE__, __LINE__);
3253          showErrorCallback(38, msg);
3254          return false;
3255       }
3256    }
3257
3258    errno = 0;
3259    bool res = stopped_lwp->readDataSpace(inTracedProcess, size, inSelf);
3260    if (!res) {
3261       if (displayErrMsg) {
3262          sprintf(errorLine, "System error: "
3263                "<>unable to read %d@%s from process data space: %s (pid=%d)",
3264                size, Address_str((Address)inTracedProcess), 
3265                strerror(errno), getPid());
3266          fprintf(stderr, "%s[%d]: Failed to read %d from %p: LWP %d\n", 
3267                FILE__, __LINE__, size, inTracedProcess, stopped_lwp->get_lwp_id());
3268
3269          std::string msg(errorLine);
3270          showErrorCallback(38, msg);
3271       }
3272    }
3273
3274    if (needToCont) {
3275       stopped_lwp->continueLWP();
3276    }
3277
3278    return res;
3279 }
3280
3281 bool process::writeTextWord(caddr_t inTracedProcess, int data) {
3282    bool needToCont = false;
3283
3284    if (!isAttached()) return false;
3285
3286    dyn_lwp *stopped_lwp = query_for_stopped_lwp();
3287    if(stopped_lwp == NULL) {
3288       stopped_lwp = stop_an_lwp(&needToCont);
3289       if(stopped_lwp == NULL) {
3290          std::string msg =
3291             std::string("System error: unable to write word to process text "
3292                      "space: couldn't stop an lwp\n");
3293          fprintf(stderr, "%s[%d]:  stop_an_lwp failed\n", FILE__, __LINE__);
3294          showErrorCallback(38, msg);
3295          return false;
3296       }
3297    }
3298
3299   bool res = stopped_lwp->writeTextWord(inTracedProcess, data);
3300   if (!res) {
3301      std::string msg = std::string("System error: unable to write word to process "
3302                              "text space:") + std::string(strerror(errno));
3303          fprintf(stderr, "%s[%d]:  writeDataSpace failed\n", FILE__, __LINE__);
3304      showErrorCallback(38, msg);
3305      return false;
3306   }
3307
3308   if (dyn_debug_write)
3309      writeDebugDataSpace(inTracedProcess, sizeof(int), &data);
3310
3311   if(needToCont) {
3312      return stopped_lwp->continueLWP();
3313   }
3314   return true;
3315 }
3316
3317 bool process::writeTextSpace(void *inTracedProcess, u_int amount, 
3318                              const void *inSelf) 
3319 {
3320    assert(inTracedProcess);
3321    bool needToCont = false;
3322
3323    /*
3324    fprintf(stderr, "writeTextSpace to %p to %p, %d\n",
3325            inTracedProcess,
3326            (char *)inTracedProcess + amount, amount);
3327    */
3328
3329    if (!isAttached()) return false;
3330    dyn_lwp *stopped_lwp = query_for_stopped_lwp();
3331    if(stopped_lwp == NULL) {
3332       stopped_lwp = stop_an_lwp(&needToCont);
3333       if(stopped_lwp == NULL) {
3334          std::string msg =
3335             std::string("System error: unable to write to process text "
3336                      "space (WTS): couldn't stop an lwp\n");
3337          fprintf(stderr, "%s[%d]:  stop_an_lwp failed\n", FILE__, __LINE__);
3338          showErrorCallback(38, msg);
3339          return false;
3340       }
3341    }
3342
3343   bool res = stopped_lwp->writeTextSpace(inTracedProcess, amount, inSelf);
3344
3345   if (!res) {
3346      std::string msg = std::string("System error: unable to write to process text "
3347                              "space (WTS):") + std::string(strerror(errno));
3348          fprintf(stderr, "%s[%d]:  writeTextSpace failed\n", FILE__, __LINE__);
3349      showErrorCallback(38, msg);
3350      return false;
3351   }
3352
3353    if (dyn_debug_write)
3354      writeDebugDataSpace(inTracedProcess, amount, inSelf);
3355   
3356   if(needToCont) {
3357      return stopped_lwp->continueLWP();
3358   }
3359   return true;
3360 }
3361
3362 // InsrucIter uses readTextSpace
3363 bool process::readTextSpace(const void *inTracedProcess, u_int amount,
3364                             const void *inSelf)
3365 {
3366    bool needToCont = false;
3367
3368    if (!isAttached()) return false;
3369
3370    dyn_lwp *stopped_lwp = query_for_stopped_lwp();
3371    if(stopped_lwp == NULL) {
3372       stopped_lwp = stop_an_lwp(&needToCont);
3373       if(stopped_lwp == NULL) {
3374          std::string msg =
3375             std::string("System error: unable to read to process text "
3376                      "space: couldn't stop an lwp\n");
3377          showErrorCallback(39, msg);
3378          return false;
3379       }
3380    }
3381
3382    bool res = stopped_lwp->readTextSpace(const_cast<void*>(inTracedProcess),
3383                                          amount, inSelf);
3384
3385    if (!res) {
3386       sprintf(errorLine, "System error: "
3387               "<>unable to read %d@%s from process text space: %s (pid=%d)",
3388               amount, Address_str((Address)inTracedProcess), 
3389               strerror(errno), getPid());
3390       std::string msg(errorLine);
3391       showErrorCallback(38, msg);
3392       fprintf(stderr, "%s[%d]:  readTextSpace failed\n", FILE__, __LINE__);
3393
3394       return false;
3395    }
3396
3397    if (needToCont) {
3398       return stopped_lwp->continueLWP();
3399    }
3400
3401    return true;
3402 }
3403
3404 void process::set_status(processState st,
3405                          bool global_st /* = true */,
3406                          bool override /* = false */) 
3407 {
3408     // There's a state machine:
3409     // neonatal
3410     // running <-> stopped
3411     // detached
3412     // deleted
3413     // exited
3414     // Make sure we never regress on that...
3415
3416     if (override) {
3417         status_ = st;
3418     } 
3419     else {
3420         switch (status_) {
3421         case neonatal:
3422             status_ = st;
3423             break;
3424         case running:
3425         case stopped:
3426             if (st == neonatal) {
3427                 fprintf(stderr, "%s[%d]: REGRESSION OF STATUS: %s to %s\n",
3428                         FILE__, __LINE__, processStateAsString(status_), 
3429                         processStateAsString(st));
3430             }
3431             else
3432                 status_ = st;
3433             break;
3434         case detached:
3435             if ((st == neonatal) ||
3436                 (st == running) ||
3437                 (st == stopped)) {
3438                 fprintf(stderr, "%s[%d]: REGRESSION OF STATUS: %s to %s\n",
3439                         FILE__, __LINE__, processStateAsString(status_), 
3440                         processStateAsString(st));
3441             }
3442             else
3443                 status_ = st;
3444             break;
3445         case exited:
3446             if ((st == neonatal) ||
3447                 (st == running) ||
3448                 (st == stopped) ||
3449                 (st == detached)) {
3450                 fprintf(stderr, "%s[%d]: REGRESSION OF STATUS: %s to %s\n",
3451                         FILE__, __LINE__, processStateAsString(status_), 
3452                         processStateAsString(st));
3453             }
3454             else
3455                 status_ = st;
3456             break;
3457         case deleted:
3458             if ((st == neonatal) ||
3459                 (st == running) ||
3460                 (st == stopped) ||
3461                 (st == detached) ||
3462                 (st == exited)) {
3463                 fprintf(stderr, "%s[%d]: REGRESSION OF STATUS: %s to %s\n",
3464                         FILE__, __LINE__, processStateAsString(status_), 
3465                         processStateAsString(st));
3466             }
3467             else
3468                 status_ = st;
3469             break;
3470         default:
3471             // ???
3472             assert(0);
3473             break;
3474         };
3475     }
3476
3477     if (!global_st) return;
3478
3479    proccontrol_printf("[%s:%u] - Setting everyone to state %s\n",
3480                       FILE__, __LINE__, 
3481                       processStateAsString(status_));
3482
3483    pdvector<dyn_thread *>::iterator iter = threads.begin();
3484    
3485    dyn_lwp *proclwp = getRepresentativeLWP();
3486    if(proclwp) proclwp->internal_lwp_set_status___(status_);
3487    
3488    while(iter != threads.end()) {
3489       dyn_thread *thr = *(iter);
3490       dyn_lwp *lwp = thr->get_lwp();
3491       assert(lwp);
3492       lwp->internal_lwp_set_status___(status_);
3493       iter++;
3494    }
3495 }
3496
3497 void process::set_lwp_status(dyn_lwp *whichLWP, processState lwp_st) 
3498 {
3499    // any lwp status = stopped, means proc status = stopped
3500
3501    assert(whichLWP != NULL);
3502
3503    // update the process status
3504    if(lwp_st == stopped) {
3505      set_status(stopped, false);
3506    }
3507
3508    proccontrol_printf("[%s:%u] - Setting %d to state %s (%d)\n",
3509                       FILE__, __LINE__, whichLWP->get_lwp_id(),
3510                       lwp_st == running ? "running" : 
3511                       lwp_st == stopped ? "stopped" : 
3512                       lwp_st == exited ? "exited" : "other",
3513                       lwp_st);
3514    whichLWP->internal_lwp_set_status___(lwp_st);
3515
3516    if(IndependentLwpControl()) {
3517       // all lwp status = running, means proc status = running
3518       bool stopped_lwp_exists = false;
3519       pdvector<dyn_thread *>::iterator iter = threads.begin();
3520       if(lwp_st == running) {
3521          while(iter != threads.end()) {
3522             dyn_thread *thr = *(iter);
3523             dyn_lwp *lwp = thr->get_lwp();
3524             assert(lwp);
3525             if(lwp->status() == stopped)
3526                stopped_lwp_exists = true;
3527             iter++;
3528          }
3529       }
3530       if(!stopped_lwp_exists && lwp_st==running) {
3531         set_status(running, false);
3532       }
3533    } else {
3534       // if can't do independent lwp control, should only be able to set
3535       // lwp status for representative lwp
3536       assert(whichLWP == getRepresentativeLWP());
3537       set_status(lwp_st);  // sets process status and all lwp statuses
3538    }
3539 }
3540
3541 bool process::pause() {
3542   bool result;
3543
3544
3545   if (!isAttached()) { 
3546     bperr( "Warning: pause attempted on non-attached process\n");
3547     return false;
3548   }
3549       
3550    // The only remaining combination is: status==running but haven't yet
3551    // reached first break.  We never want to pause before reaching the first
3552    // break (trap, actually).  But should we be returning true or false in
3553    // this case?
3554
3555   if(! reachedBootstrapState(initialized_bs)) {
3556      return true;
3557   }
3558
3559    // Let's try having stopped mean all lwps stopped and running mean
3560    // atleast one lwp running.
3561    
3562    if (status_ == neonatal) {
3563       return true;
3564    }
3565
3566    signal_printf("%s[%d]: stopping process\n", FILE__, __LINE__);
3567
3568    result = stop_();
3569    if (!result) {
3570        bperr ("Warning: low-level paused failed, process is not paused\n");
3571        fprintf(stderr, "%s[%d]:  pause() failing here\n", FILE__, __LINE__);
3572      return false;
3573    }
3574    set_status(stopped, false);
3575
3576    signal_printf("%s[%d]: process stopped\n", FILE__, __LINE__);
3577
3578    return true;
3579 }
3580
3581 //process::stop_ is only different on linux
3582 #if !defined(os_linux) && !defined(os_windows)
3583 bool process::stop_(bool waitUntilStop)
3584 {
3585    if (status_ == stopped) {
3586        return true;
3587    }
3588
3589    assert(status_ == running);      
3590
3591    bool res = getRepresentativeLWP()->pauseLWP(waitUntilStop);
3592    if (!res) {
3593       sprintf(errorLine,
3594               "warn : in process::pause, pause_ unable to pause process\n");
3595       logLine(errorLine);
3596       return false;
3597    }
3598    return true;
3599 }
3600 #endif
3601
3602 // There also exists the possibility of objects having been both
3603 // loaded and unloaded (especially at startup) in which case the
3604 // options for ev.type and ev.what are inadequate, but it doesn't
3605 // really matter since both library loads and unloads are processed by
3606 // the same event handler
3607 bool process::decodeIfDueToSharedObjectMapping(EventRecord &ev)
3608 {
3609    if(!dyn) { 
3610        fprintf(stderr, "%s[%d]:  no dyn objects, failing ...\n", FILE__, __LINE__);
3611        return false;
3612    }
3613
3614    u_int change_type = 0;
3615    if (!dyn->decodeIfDueToSharedObjectMapping(ev,change_type))
3616      return false;
3617
3618    ev.what = change_type;
3619    switch(change_type) {
3620      case SHAREDOBJECT_ADDED:
3621         ev.type = evtLoadLibrary;
3622         signal_printf("%s[%d]:  ADDED\n", FILE__, __LINE__);
3623         return true;
3624      case SHAREDOBJECT_REMOVED:
3625         ev.type = evtUnloadLibrary;
3626         signal_printf("%s[%d]:  REMOVED\n", FILE__, __LINE__);
3627         return true;
3628      case SHAREDOBJECT_NOCHANGE:
3629         signal_printf("%s[%d]:  NOCHANGE\n", FILE__, __LINE__);
3630         ev.type = evtLoadLibrary;
3631         return true;
3632      default:
3633        fprintf(stderr, "%s[%d]:  WEIRD ERROR, decodeIfDueToSharedObjectMapping"
3634                "must be broken\n", FILE__, __LINE__);
3635    };
3636    return false;
3637 }
3638
3639 /* Uses dynamiclinking::handleIfDueToSharedObjectMapping to figure out
3640  * what objects were loaded / removed and to create mapped_objects for
3641  * them.  If an object was loaded we add it using addASharedObject.
3642  * If one was removed, we call removeASharedObject, which currently
3643  * doesn't do much.
3644  */
3645 bool process::handleChangeInSharedObjectMapping(EventRecord &ev)
3646 {
3647    pdvector<mapped_object *> changed_objs;
3648    pdvector<bool> is_new_object;
3649    if(!dyn) { 
3650        fprintf(stderr, "%s[%d]:  no dyn objects, failing ...\n", FILE__, __LINE__);
3651        return false;