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