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