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