BPatch functions that block are now locked (on a finer grain than the rest of the...
[dyninst.git] / dyninstAPI / src / process.C
1 /*
2  * Copyright (c) 1996-2004 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: process.C,v 1.524 2005/02/25 07:04:46 jaw Exp $
43
44 #include <ctype.h>
45
46 #if defined(i386_unknown_solaris2_5)
47 #include <sys/procfs.h>
48 #endif
49 #include "common/h/headers.h"
50 #include "dyninstAPI/src/function.h"
51 #include "dyninstAPI/src/func-reloc.h"
52 #include "dyninstAPI/src/symtab.h"
53 #include "dyninstAPI/src/dyn_thread.h"
54 #include "dyninstAPI/src/dyn_lwp.h"
55 #include "dyninstAPI/src/signalhandler.h"
56 #include "dyninstAPI/src/process.h"
57 #include "dyninstAPI/src/util.h"
58 #include "dyninstAPI/src/inst.h"
59 #include "dyninstAPI/src/instP.h"
60 #include "dyninstAPI/src/instPoint.h"
61 #include "dyninstAPI/src/dyninstP.h"
62 #include "dyninstAPI/src/os.h"
63 #include "dyninstAPI/src/showerror.h"
64 #include "dyninstAPI/src/dynamiclinking.h"
65 #include "dyninstAPI/src/BPatch_asyncEventHandler.h"
66 // #include "paradynd/src/mdld.h"
67 #include "common/h/Timer.h"
68 #include "common/h/Time.h"
69 #include "common/h/timing.h"
70
71 #include "dyninstAPI/src/rpcMgr.h"
72
73
74 #include "dyninstAPI/h/BPatch.h"
75
76 #if defined(sparc_sun_solaris2_4) \
77  || defined(i386_unknown_linux2_0) \
78  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
79 #include "dyninstAPI/src/writeBackElf.h"
80 #include "dyninstAPI/src/saveSharedLibrary.h" 
81 #elif defined(rs6000_ibm_aix4_1)
82 #include "dyninstAPI/src/writeBackXCOFF.h"
83 #endif
84
85 #include "dyninstAPI/src/syscallNotification.h"
86
87 #if !defined(BPATCH_LIBRARY)
88 #include "rtinst/h/rtinst.h"
89 #include "rtinst/h/trace.h"
90 #include "paradynd/src/perfStream.h"
91 #include "paradynd/src/metricFocusNode.h"
92 #include "paradynd/src/costmetrics.h"
93 #include "paradynd/src/mdld.h"
94 #include "paradynd/src/main.h"
95 #include "paradynd/src/init.h"
96 #include "pdutil/h/pdDebugOstream.h"
97 #include "common/h/int64iostream.h"
98 #endif
99
100 #ifndef BPATCH_LIBRARY
101 #ifdef PAPI
102 #include "paradynd/src/papiMgr.h"
103 #endif
104 #endif
105
106 #ifndef BPATCH_LIBRARY
107 extern void generateRPCpreamble(char *insn, Address &base, process *proc, 
108                                 unsigned offset, int tid, unsigned index);
109 #endif
110
111 #include "common/h/debugOstream.h"
112
113 #include "common/h/Timer.h"
114
115 unsigned enable_pd_attach_detach_debug = 0;
116
117 #if ENABLE_DEBUG_CERR == 1
118 #define attach_cerr if (enable_pd_attach_detach_debug) cerr
119 #else
120 #define attach_cerr if (0) cerr
121 #endif /* ENABLE_DEBUG_CERR == 1 */
122
123 unsigned enable_pd_inferior_rpc_debug = 0;
124
125 #if ENABLE_DEBUG_CERR == 1
126 #define inferiorrpc_cerr if (enable_pd_inferior_rpc_debug) cerr
127 #else
128 #define inferiorrpc_cerr if (0) cerr
129 #endif /* ENABLE_DEBUG_CERR == 1 */
130
131 unsigned enable_pd_shm_sampling_debug = 0;
132
133 #if ENABLE_DEBUG_CERR == 1
134 #define shmsample_cerr if (enable_pd_shm_sampling_debug) cerr
135 #else
136 #define shmsample_cerr if (0) cerr
137 #endif /* ENABLE_DEBUG_CERR == 1 */
138
139 unsigned enable_pd_fork_exec_debug = 0;
140
141 #if ENABLE_DEBUG_CERR == 1
142 #define forkexec_cerr if (enable_pd_fork_exec_debug) cerr
143 #else
144 #define forkexec_cerr if (0) cerr
145 #endif /* ENABLE_DEBUG_CERR == 1 */
146
147 unsigned enable_pd_signal_debug = 0;
148
149 #if ENABLE_DEBUG_CERR == 1
150 #define signal_cerr if (enable_pd_signal_debug) cerr
151 #else
152 #define signal_cerr if (0) cerr
153 #endif /* ENABLE_DEBUG_CERR == 1 */
154
155 unsigned enable_pd_sharedobj_debug = 0;
156
157 #if ENABLE_DEBUG_CERR == 1
158 #define sharedobj_cerr if (enable_pd_sharedobj_debug) cerr
159 #else
160 #define sharedobj_cerr if (0) cerr
161 #endif /* ENABLE_DEBUG_CERR == 1 */
162
163 #ifndef BPATCH_LIBRARY
164
165
166 unsigned enable_pd_metric_debug = 0;
167
168 #if ENABLE_DEBUG_CERR == 1
169 #define metric_cerr if (enable_pd_metric_debug) cerr
170 #else
171 #define metric_cerr if (0) cerr
172 #endif /* ENABLE_DEBUG_CERR == 1 */
173
174 unsigned enable_pd_samplevalue_debug = 0;
175
176 #if ENABLE_DEBUG_CERR == 1
177 #define sampleVal_cerr if (enable_pd_samplevalue_debug) cerr
178 #else
179 #define sampleVal_cerr if (0) cerr
180 #endif /* ENABLE_DEBUG_CERR == 1 */
181
182 unsigned enable_pd_aggregate_debug = 0;
183
184 #if ENABLE_DEBUG_CERR == 1
185 #define agg_cerr if (enable_pd_aggregate_debug) cerr
186 #else
187 #define agg_cerr if (0) cerr
188 #endif /* ENABLE_DEBUG_CERR == 1 */
189
190 #endif
191
192
193
194 #define FREE_WATERMARK (hp->totalFreeMemAvailable/2)
195 #define SIZE_WATERMARK 100
196 static const timeLength MaxWaitingTime(10, timeUnit::sec());
197 static const timeLength MaxDeletingTime(2, timeUnit::sec());
198 unsigned inferiorMemAvailable=0;
199
200 unsigned activeProcesses; // number of active processes
201 pdvector<process*> processVec;
202 pdstring process::programName;
203 pdstring process::pdFlavor;
204
205 #ifndef BPATCH_LIBRARY
206 extern pdstring osName;
207 #endif
208
209 #if defined(i386_unknown_linux2_0) \
210  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
211 extern void cleanupVsysinfo(void *ehd);
212 #endif
213
214 // PARADYND_DEBUG_XXX
215 int pd_debug_infrpc=0;
216 int pd_debug_catchup=0;
217 //
218
219 void printLoadDyninstLibraryError() {
220     cerr << "Paradyn/Dyninst failed to load the runtime library. This is normally caused by " << endl;
221     cerr << "one of the following:" << endl;
222     cerr << "Incorrect DYNINSTAPI_RT_LIB environment variable" << endl;
223     cerr << "Missing RT library" << endl;
224     cerr << "Unavailable dependency of the library" << endl;
225 #if defined(rs6000_ibm_aix4_1)
226     cerr << "   libDyninstText.a must exist in a directory in the LIBPATH environment variable" << endl;
227 #endif
228     cerr << "Please check your environment and try again." << endl;
229 }
230
231
232 void setLibState(libraryState_t &lib, libraryState_t state) {
233     if (lib > state) cerr << "Error: attempting to revert library state" << endl;
234     else lib = state;
235 }
236
237 /* AIX method defined in aix.C; hijacked for IA-64's GP. */
238 #if !defined(rs6000_ibm_aix4_1) \
239  && !defined(ia64_unknown_linux2_4)
240 Address process::getTOCoffsetInfo(Address /*dest */)
241 {
242   Address tmp = 0;
243   assert(0 && "getTOCoffsetInfo not implemented");
244   return tmp; // this is to make the nt compiler happy! - naim
245 }
246 #else
247 Address process::getTOCoffsetInfo(Address dest)
248 {
249   // We have an address, and want to find the module the addr is
250   // contained in. Given the probabilities, we (probably) want
251   // the module dyninst_rt is contained in.
252   // I think this is the right func to use
253
254   if (symbols->findFuncByOffset(dest))
255     return (symbols->getObject()).getTOCoffset();
256   if (shared_objects)
257     for(u_int j=0; j < shared_objects->size(); j++)
258       if (((*shared_objects)[j])->findFuncByAddress(dest))
259 #if ! defined(ia64_unknown_linux2_4)
260         return (((*shared_objects)[j])->getImage()->getObject()).getTOCoffset();
261 #else
262         {
263         /* Entries in the .dynamic section are not relocated. */
264         return (((*shared_objects)[j])->getImage()->getObject()).getTOCoffset() +
265                 ((*shared_objects)[j])->getBaseAddress();
266         }
267 #endif
268   // Serious error! Assert?
269   return 0;
270 }
271
272 #endif
273
274 #if defined(os_linux) && (defined(arch_x86) || defined(arch_x86_64))
275 extern void calcVSyscallFrame(process *p);
276 #endif
277
278 // Windows NT has its own version of the walkStack function in pdwinnt.C
279
280 // Note: stack walks may terminate early. In this case, return what we can.
281 // Relies on the getCallerFrame method in the various <os>.C files
282
283 #if !defined(mips_unknown_ce2_11) && !defined(i386_unknown_nt4_0)
284 bool process::walkStackFromFrame(Frame startFrame,
285                                  pdvector<Frame> &stackWalk)
286 {
287   Address fpOld   = 0;
288   Address fpNew   = 0;
289
290   Frame currentFrame = startFrame;
291   
292   if (!isStopped())
293       return false;
294
295 #ifndef BPATCH_LIBRARY
296   startTimingStackwalk();
297 #endif
298
299 #if defined(os_linux) 
300   Address next_pc = currentFrame.getPC();
301
302   // Do a special check for the vsyscall page.  Silently drop
303   //  the page if it exists.
304 #if defined(arch_ia64)
305   if (next_pc >= 0xffffffffffffe000 && next_pc < 0xfffffffffffff000) {
306     fpOld = currentFrame.getSP();
307     
308     /* Suppress this frame; catch-up doesn't need it, and the user shouldn't see it. */
309     currentFrame = currentFrame.getCallerFrame(); 
310   }
311 #elif defined(arch_x86) || defined(arch_x86_64)
312   calcVSyscallFrame(this);
313   if (next_pc >= getVsyscallStart() && next_pc < getVsyscallEnd()) {
314      currentFrame = currentFrame.getCallerFrame();
315   }
316 #endif
317
318 #endif
319   // Do special check first time for leaf frames
320   // Step through the stack frames
321   while (!currentFrame.isLastFrame()) {
322     
323     // grab the frame pointer
324     fpNew = currentFrame.getFP();
325
326     // Check that we are not moving up the stack
327     // successive frame pointers might be the same (e.g. leaf functions)
328 #if !defined(i386_unknown_linux2_0) \
329  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
330     if (fpOld > fpNew) {
331       
332       // AIX:
333       // There's a signal function in the MPI library that we're not
334       // handling properly. Instead of returning an empty stack,
335       // return what we have.
336       // One thing that makes me feel better: gdb is getting royally
337       // confused as well. This sucks for catchup.
338       
339       #if defined( ia64_unknown_linux2_4 )
340                 /* My single-stepper needs to be able to continue past stackwalking errors. */      
341                 // /* DEBUG */ fprintf( stderr, "Not terminating stackwalk early, even though fpOld (0x%lx) > fpNew (0x%lx).\n", fpOld, fpNew );
342                 // /* DEBUG */ for( unsigned int i = 0; i < stackWalk.size(); i++ ) {
343                 // /* DEBUG */  cerr << stackWalk[i] << endl;
344                 // /* DEBUG */  } 
345                 // /* DEBUG */  cerr << currentFrame << endl; 
346                 // /* DEBUG */ cerr << endl;
347                 break;
348       #else
349         // We should check to see if this early exit is warranted.
350         return false;
351       #endif
352     }
353 #endif
354     fpOld = fpNew;
355     
356     stackWalk.push_back(currentFrame);    
357     currentFrame = currentFrame.getCallerFrame(); 
358   }
359   // Clean up after while loop (push end frame)
360   stackWalk.push_back(currentFrame);
361
362 #ifndef BPATCH_LIBRARY
363   stopTimingStackwalk();
364 #endif
365
366   return true;
367 }
368 #endif
369
370 // Return a vector (possibly with one object) of active frames
371 // in the process
372
373 bool process::getAllActiveFrames(pdvector<Frame> &activeFrames)
374 {
375   Frame active;
376   bool success = true;
377   if (!threads.size()) { // Nothing defined in the thread data structures
378     // So use the process LWP instead (Dyninst)
379     active = getRepresentativeLWP()->getActiveFrame();
380     if (active == Frame()) { // Hrm.. should getActive return a bool?
381       return false;
382     }
383     activeFrames.push_back(active);
384   }
385   else { // Iterate through threads
386     for (unsigned i = 0; i < threads.size(); i++) {
387       active = threads[i]->getActiveFrame();
388       if (active == Frame())
389         success = true;
390       else
391         activeFrames.push_back(active);
392     }
393   }
394   return success;
395 }
396
397 bool process::walkStacks(pdvector<pdvector<Frame> >&stackWalks)
398 {
399   pdvector<Frame> stackWalk;
400   if (!threads.size()) { // Nothing defined in thread data structures
401     if (!getRepresentativeLWP()->walkStack(stackWalk))
402       return false;
403     // Use the walk from the default LWP
404     stackWalks.push_back(stackWalk);
405   }
406   else { // Have threads defined
407     for (unsigned i = 0; i < threads.size(); i++) {
408       if (!threads[i]->walkStack(stackWalk))
409          return false;
410       stackWalks.push_back(stackWalk);
411       stackWalk.resize(0);
412     }
413   }
414   return true;
415 }
416
417
418 static Address alignAddress(Address addr, unsigned align) {
419   Address skew = addr % align;
420   return (skew) ? (((addr/align)+1)*align) : addr;
421 }
422
423 extern "C" int heapItemCmpByAddr(const heapItem **A, const heapItem **B)
424 {
425   heapItem *a = *(heapItem **)const_cast<heapItem **>(A);
426   heapItem *b = *(heapItem **)const_cast<heapItem **>(B);
427
428   if (a->addr < b->addr) {
429       return -1;
430   } else if (a->addr > b->addr) {
431       return 1;
432   } else {
433       return 0;
434   }
435 }
436
437 void process::inferiorFreeCompact(inferiorHeap *hp)
438 {
439   pdvector<heapItem *> &freeList = hp->heapFree;
440   unsigned i, nbuf = freeList.size();
441
442   /* sort buffers by address */
443   VECTOR_SORT(freeList, heapItemCmpByAddr);
444
445   /* combine adjacent buffers */
446   bool needToCompact = false;
447   for (i = 1; i < freeList.size(); i++) {
448       heapItem *h1 = freeList[i-1];
449       heapItem *h2 = freeList[i];
450       assert(h1->length != 0);
451       assert(h1->addr + h1->length <= h2->addr);
452       if (h1->addr + h1->length == h2->addr
453           && h1->type == h2->type) {
454           h2->addr = h1->addr;
455           h2->length = h1->length + h2->length;
456           h1->length = 0;
457           nbuf--;
458           needToCompact = true;
459       }
460   }
461
462   /* remove any absorbed (empty) buffers */ 
463   if (needToCompact) {
464     pdvector<heapItem *> cleanList;
465     unsigned end = freeList.size();
466     for (i = 0; i < end; i++) {
467       heapItem *h1 = freeList[i];
468       if (h1->length != 0) {
469         cleanList.push_back(h1);
470       } else {
471         delete h1;
472       }
473     }
474     assert(cleanList.size() == nbuf);
475     for (i = 0; i < nbuf; i++) {
476       freeList[i] = cleanList[i];
477     }
478     freeList.resize(nbuf);
479     assert(freeList.size() == nbuf);
480   }
481 }
482
483 // Get inferior heaps from every library currently loaded.
484 // This is done at startup by initInferiorHeap().
485 // There's also another one which takes a shared library and
486 // only looks in there for the heaps
487
488 bool process::getInfHeapList(pdvector<heapDescriptor> &infHeaps)
489 {
490   bool foundHeap = false;
491   // First check the program (without shared libs)
492   foundHeap = getInfHeapList(symbols, infHeaps, 0);
493   
494   // Now iterate through shared libs
495   if (shared_objects)
496       for(u_int j=0; j < shared_objects->size(); j++)
497       {
498           if(((*shared_objects)[j]->getImage())){
499               if (getInfHeapList(((*shared_objects)[j])->getImage(), infHeaps, 0))
500                   foundHeap = true;
501               }
502         }
503
504   return foundHeap;
505 }
506
507 bool process::getInfHeapList(const image *theImage, // okay, boring name
508                              pdvector<heapDescriptor> &infHeaps,
509                              Address baseAddr)
510 {
511
512   // First we get the list of symbols we're interested in, then
513   // we go through and add them to the heap list. This is done
514   // for two reasons: first, the symbol address might be off (depends
515   // on the image), and this lets us do some post-processing.
516     bool foundHeap = false;
517     pdvector<Symbol> heapSymbols;
518     // For maximum flexibility the findInternalByPrefix function
519     // returns a list of symbols
520     
521     foundHeap = theImage->findInternalByPrefix(pdstring("DYNINSTstaticHeap"),
522                                                heapSymbols);
523     if (!foundHeap)
524         // Some platforms preface with an underscore
525         foundHeap = theImage->findInternalByPrefix(pdstring("_DYNINSTstaticHeap"),
526                                                    heapSymbols);
527     // The address in the symbol isn't necessarily absolute
528     if (!baseAddr) {
529         // Possible that this call will fail if we're looking for
530         // heaps before this image has been added to the shared objects
531         // list - hence the handed-in parameter.
532         getBaseAddress(theImage, baseAddr);
533     }
534     
535     for (u_int j = 0; j < heapSymbols.size(); j++)
536     {
537         // The string layout is: DYNINSTstaticHeap_size_type_unique
538         // Can't allocate a variable-size array on NT, so malloc
539         // that sucker
540         char *temp_str = (char *)malloc(strlen(heapSymbols[j].name().c_str())+1);
541         strcpy(temp_str, heapSymbols[j].name().c_str());
542         char *garbage_str = strtok(temp_str, "_"); // Don't care about beginning
543         assert(!strcmp("DYNINSTstaticHeap", garbage_str));
544         // Name is as is.
545         // If address is zero, then skip (error condition)
546         if (heapSymbols[j].addr() == 0)
547         {
548             cerr << "Skipping heap " << heapSymbols[j].name().c_str()
549                  << "with address 0" << endl;
550             continue;
551         }
552         // Size needs to be parsed out (second item)
553         // Just to make life difficult, the heap can have an optional
554         // trailing letter (k,K,m,M,g,G) which indicates that it's in
555         // kilobytes, megabytes, or gigabytes. Why gigs? I was bored.
556         char *heap_size_str = strtok(NULL, "_"); // Second element, null-terminated
557         unsigned heap_size = (unsigned) atol(heap_size_str);
558         if (heap_size == 0)
559             /* Zero size or error, either way this makes no sense for a heap */
560         {
561             free(temp_str);
562             continue;
563         }
564         switch (heap_size_str[strlen(heap_size_str)-1])
565         {
566       case 'g':
567       case 'G':
568           heap_size *= 1024;
569       case 'm':
570       case 'M':
571           heap_size *= 1024;
572       case 'k':
573       case 'K':
574           heap_size *= 1024;
575       default:
576           break;
577         }
578         
579         // Type needs to be parsed out. Can someone clean this up?
580         inferiorHeapType heap_type;
581         char *heap_type_str = strtok(NULL, "_");
582         
583         if (!strcmp(heap_type_str, "anyHeap"))
584             heap_type = anyHeap;
585         else if (!strcmp(heap_type_str, "lowmemHeap"))
586             heap_type = lowmemHeap;
587         else if (!strcmp(heap_type_str, "dataHeap"))
588             heap_type = dataHeap;
589         else if (!strcmp(heap_type_str, "textHeap"))
590             heap_type = textHeap;
591         else if (!strcmp(heap_type_str, "uncopiedHeap"))
592             heap_type = uncopiedHeap;
593         else
594         {
595             cerr << "Unknown heap string " << heap_type_str << " read from file!" << endl;
596             free(temp_str);
597             continue;
598         }
599         infHeaps.push_back(heapDescriptor(heapSymbols[j].name(),
600 #ifdef mips_unknown_ce2_11 //ccw 13 apr 2001
601                                           heapSymbols[j].addr(), 
602 #else
603                                           heapSymbols[j].addr()+baseAddr, 
604 #endif
605                                           heap_size, heap_type));
606         free(temp_str);
607     }
608   return foundHeap;
609 }
610
611 /*
612  * Returns true if the address given is within the signal handler function,
613  * otherwise returns false.
614  */
615 bool process::isInSignalHandler(Address addr)
616 {
617 #if defined(os_linux) && (defined(arch_x86) || defined(arch_x86_64))
618   for (unsigned int i = 0; i < signal_restore.size(); i++)
619   {
620     if (addr == signal_restore[i])
621       return true;
622   }
623   return false;
624 #elif defined( os_linux ) && defined( arch_ia64 )
625   assert( 0 );
626 #else
627   if (!signal_handler)
628       return false;
629
630   const image *sig_image = (signal_handler->pdmod())->exec();
631
632   Address sig_addr;
633   if(getBaseAddress(sig_image, sig_addr)){
634     sig_addr += signal_handler->getAddress(this);
635   } else {
636     sig_addr = signal_handler->getAddress(this);
637   }
638
639   if (addr >= sig_addr && addr < sig_addr + signal_handler->get_size())
640     return true;
641   else
642     return false;
643 #endif
644 }
645
646 /*
647  * This function adds an item to the dataUpdates vector
648  * which is used to maintain a list of variables that have
649  * been written by the mutator //ccw 26 nov 2001
650  */
651  
652 #if defined(sparc_sun_solaris2_4) \
653  || defined(i386_unknown_linux2_0) \
654  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
655  || defined(rs6000_ibm_aix4_1)
656
657 void process::saveWorldData( Address address, int size, const void * src ) {
658         if( collectSaveWorldData ) {
659                 dataUpdate *newData = new dataUpdate;
660                 newData->address= address;
661                 newData->size = size;
662                 newData->value = new char[size];
663                 memcpy(newData->value, src, size);
664                 dataUpdates.push_back(newData);
665                 }
666         } /* end saveWorldData() */
667         
668 #else
669
670 void process::saveWorldData( Address, int, const void* ) { ; }    
671
672 #endif
673
674 #if defined(sparc_sun_solaris2_4) \
675  || defined(i386_unknown_linux2_0) \
676  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
677  || defined(rs6000_ibm_aix4_1)
678 /* || defined(rs6000_ibm_aix4_1)*/
679
680 char* process::saveWorldFindDirectory(){
681
682         const char* directoryNameExt = "_dyninstsaved";
683         int dirNo = 0;
684 /* ccw */
685         char cwd[1024];
686         char* directoryName;
687         int lastChar;
688         getcwd(cwd, 1024);
689         lastChar = strlen(cwd);
690
691         if( cwd[lastChar] != '/' && lastChar != 1023){
692                 cwd[lastChar] = '/';
693                 cwd[++lastChar] ='\0';
694         }
695
696         directoryName = new char[strlen(cwd) +
697                         strlen(directoryNameExt) + 3+1+1];
698 /* ccw */
699         sprintf(directoryName,"%s%s%x",cwd, directoryNameExt,dirNo);
700         while(dirNo < 0x1000 && mkdir(directoryName, S_IRWXU) ){
701                  if(errno == EEXIST){
702                          dirNo ++;
703                  }else{
704                          BPatch_reportError(BPatchSerious, 122, "dumpPatchedImage: cannot open directory to store mutated binary. No files saved\n");
705                          delete [] directoryName;
706                          return NULL;
707                  }
708                  sprintf(directoryName, "%s%s%x",cwd,
709                          directoryNameExt,dirNo);
710         }
711         if(dirNo == 0x1000){
712                  BPatch_reportError(BPatchSerious, 122, "dumpPatchedImage: cannot open directory to store mutated binary. No files saved\n");
713                  delete [] directoryName;
714                  return NULL;
715         }
716         return directoryName;
717
718 }
719 #endif
720
721 #if defined(sparc_sun_solaris2_4) \
722  || defined(i386_unknown_linux2_0) \
723  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
724 unsigned int process::saveWorldSaveSharedLibs(int &mutatedSharedObjectsSize, 
725                                  unsigned int &dyninst_SharedLibrariesSize, 
726                                  char* directoryName, unsigned int &count) {
727    shared_object *sh_obj;
728    unsigned int dl_debug_statePltEntry=0;
729 #if defined(sparc_sun_solaris2_4)
730    unsigned int tmp_dlopen;
731 #endif
732    bool dlopenUsed = false;
733    
734    //In the mutated binary we need to catch the dlopen events and adjust the
735    //instrumentation of the shared libraries (and jumps into the shared
736    //libraries) as the base address of the shared libraries different for the
737    //base addresses during the original mutator/mutatee run.
738
739    //the r_debug interface ensures that a change to the dynamic linking
740    //information causes _dl_debug_state to be called.  This is because dlopen
741    //is too small and odd to instrument/breakpoint.  So our code will rely on
742    //this fact. (all these functions are contained in ld-linux.so)
743
744    //Our method: The Procedure Linking Table (.plt) for ld-linux contains an
745    //entry that jumps to a specified address in the .rel.plt table. To call a
746    //function, the compiler generates a jump to the correct .plt entry which
747    //reads its jump value out of the .rel.plt.
748
749    //On the sly, secretly replace the entry in .rel.plt with folgers crystals
750    //and poof, we jump to our own function in RTcommon.c
751    //(dyninst_dl_debug_state) [actually we replace the entry in .rel.plt with
752    //the address of dyninst_dl_debug_state].  To ensure correctness,
753    //dyninst_dl_debug_state contains a call to the real _dl_debug_state
754    //immediately before it returns, thus ensuring any code relying on that
755    //fact that _dl_debug_state is actually run remains happy.
756
757    //It is very important then, that we know the location of the entry in the
758    //.rel.plt table.  We need to record the offset of this entry with respect
759    //to the base address of ld-linux.so (for obvious reasons) This offset is
760    //then sent to RTcommon.c, and here is the slick part, by assigning it to
761    //the 'load address' of the section "dyninstAPI_SharedLibraries," which
762    //contains the shared library/basei address pairs used to fixup the saved
763    //binary. This way when checkElfFile() reads the section the offset will
764    //be there in the section header.
765
766    //neat, eh?  this is how it will work in the future, currently this is not
767    //yet fully implemented and part of the cvs tree.
768
769    //UPDATE: the above is implemented EXCEPT for adjusting the instrumentation
770    //when shared libraries move. currently an error is thrown when a shared
771    //lib is in the wrong place and execution is terminated!
772
773         //I have now added the notion of DirtyCalled to a shared library.
774         //This is a library that contains a function that is called by
775         //instrumentation.  The shared lib may or may not be instrumented itself.
776         //If it is not instrumented (Dirty) then it is NOT saved as a mutated 
777         //shared library.  A flag in dyninstAPI_mutatedSO section that follows
778         //the filename denotes whether the library is Dirty or merely DirtyCalled
779
780    count = 0;
781    for(int i=0;shared_objects && i<(int)shared_objects->size() ; i++) {
782       sh_obj = (*shared_objects)[i];
783       //ccw 24 jul 2003
784       if( (sh_obj->isDirty() || sh_obj->isDirtyCalled()) &&
785                 /* there are some libraries we should not save even if they are marked as mutated*/
786                 NULL==strstr(sh_obj->getName().c_str(),"libdyninstAPI_RT") && 
787                 NULL== strstr(sh_obj->getName().c_str(),"ld-linux.so") && 
788                 NULL==strstr(sh_obj->getName().c_str(),"libc")){ //ccw 6 jul 2003
789          count ++;
790          if(!dlopenUsed && sh_obj->isopenedWithdlopen()){
791             BPatch_reportError(BPatchWarning,123,"dumpPatchedImage: dlopen used by the mutatee, this may cause the mutated binary to fail\n");
792             dlopenUsed = true;
793          }                      
794          //bperr(" %s is DIRTY!\n", sh_obj->getName().c_str());
795         
796
797          if( sh_obj->isDirty()){ 
798             //if the lib is only DirtyCalled dont save it! //ccw 24 jul 2003
799             Address textAddr, textSize;
800             char *newName = new char[strlen(sh_obj->getName().c_str()) + 
801                                      strlen(directoryName) + 1];
802             memcpy(newName, directoryName, strlen(directoryName)+1);
803             const char *file = strrchr(sh_obj->getName().c_str(), '/');
804             strcat(newName, file);
805             
806             saveSharedLibrary *sharedObj =
807                new saveSharedLibrary(sh_obj->getBaseAddress(),
808                                      sh_obj->getName().c_str(), newName);
809             sharedObj->writeLibrary();
810             
811             sharedObj->getTextInfo(textAddr, textSize);
812             
813             char *textSection = new char[textSize];
814             readDataSpace((void*) (textAddr+ sh_obj->getBaseAddress()),
815                           textSize,(void*)textSection, true);
816             
817             sharedObj->saveMutations(textSection);
818             sharedObj->closeLibrary();
819             /*                  
820             //this is for the dlopen problem....
821             if(strstr(sh_obj->getName().c_str(), "ld-linux.so") ){
822             //find the offset of _dl_debug_state in the .plt
823             dl_debug_statePltEntry = 
824             sh_obj->getImage()->getObject().getPltSlot("_dl_debug_state");
825             }
826             */                  
827             delete [] textSection;
828             delete [] newName;
829          }
830          mutatedSharedObjectsSize += strlen(sh_obj->getName().c_str()) +1 ;
831          mutatedSharedObjectsSize += sizeof(int); //a flag to say if this is only DirtyCalled
832       }
833       //this is for the dlopen problem....
834       if(strstr(sh_obj->getName().c_str(), "ld-linux.so") ){
835          //find the offset of _dl_debug_state in the .plt
836          dl_debug_statePltEntry = 
837             sh_obj->getImage()->getObject().getPltSlot("_dl_debug_state");
838       }
839 #if defined(sparc_sun_solaris2_4)
840       
841       if( ((tmp_dlopen = sh_obj->getImage()->getObject().getPltSlot("dlopen")) && !sh_obj->isopenedWithdlopen())){
842          dl_debug_statePltEntry = tmp_dlopen + sh_obj->getBaseAddress();
843       }
844 #endif
845       //this is for the dyninst_SharedLibraries section we need to find out
846       //the length of the names of each of the shared libraries to create the
847       //data buffer for the section
848       
849       dyninst_SharedLibrariesSize += strlen(sh_obj->getName().c_str())+1;
850       //add the size of the address
851       dyninst_SharedLibrariesSize += sizeof(unsigned int);
852    }
853 #if defined(sparc_sun_solaris2_4)
854    if( (tmp_dlopen = getImage()->getObject().getPltSlot("dlopen"))) {
855       dl_debug_statePltEntry = tmp_dlopen;
856    }
857    
858    //dl_debug_statePltEntry = getImage()->getObject().getPltSlot("dlopen");
859 #endif
860    dyninst_SharedLibrariesSize += 1;//for the trailing '\0'
861    
862    return dl_debug_statePltEntry;
863 }
864         
865 char* process::saveWorldCreateSharedLibrariesSection(int dyninst_SharedLibrariesSize){
866         //dyninst_SharedLibraries
867         //the SharedLibraries sections contains a list of all the shared libraries
868         //that have been loaded and the base address for each one.
869         //The format of the sections is:
870         //
871         //sharedlibraryName
872         //baseAddr
873         //...
874         //sharedlibraryName
875         //baseAddr
876         //'\0'
877         
878         char *dyninst_SharedLibrariesData = new char[dyninst_SharedLibrariesSize];
879         char *ptr= dyninst_SharedLibrariesData;
880         int size = shared_objects->size();
881         shared_object *sh_obj;
882
883         for(int i=0;shared_objects && i<size ; i++) {
884                 sh_obj = (*shared_objects)[i];
885
886                 memcpy((void*) ptr, sh_obj->getName().c_str(), strlen(sh_obj->getName().c_str())+1);
887                 //bperr(" %s : ", ptr);
888                 ptr += strlen(sh_obj->getName().c_str())+1;
889
890                 unsigned int baseAddr = sh_obj->getBaseAddress();
891                 memcpy( (void*)ptr, &baseAddr, sizeof(unsigned int));
892                 //bperr(" 0x%x \n", *(unsigned int*) ptr);
893                 ptr += sizeof(unsigned int);
894         }
895         memset( (void*)ptr, '\0' , 1);
896
897         return dyninst_SharedLibrariesData;
898 }
899 #endif
900
901 #if defined(sparc_sun_solaris2_4) \
902  || defined(i386_unknown_linux2_0) \
903  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
904  || defined(rs6000_ibm_aix4_1)
905 void process::saveWorldCreateHighMemSections(
906                         pdvector<imageUpdate*> &compactedHighmemUpdates, 
907                         pdvector<imageUpdate*> &highmem_updates,
908                         void *ptr) {
909
910    unsigned int trampGuardValue;
911    Address guardFlagAddr= trampGuardAddr();
912
913    unsigned int pageSize = getpagesize();
914    unsigned int startPage, stopPage;
915    unsigned int numberUpdates=1;
916    int startIndex, stopIndex;
917    void *data;
918    char name[50];
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    readDataSpace((void*) guardFlagAddr, sizeof(unsigned int),
928                  (void*) &trampGuardValue, true);
929    
930    writeDataSpace((void*)guardFlagAddr, sizeof(unsigned int),
931                   (void*) &numberUpdates);
932
933         saveWorldData((Address) guardFlagAddr,sizeof(unsigned int), &numberUpdates); //ccw 6 jul 2003
934
935
936    for(unsigned int j=0; j<compactedHighmemUpdates.size(); j++) {
937       //the layout of dyninstAPIhighmem_%08x is:
938       //pageData
939       //address of update
940       //size of update
941       // ...
942       //address of update
943       //size of update
944       //number of updates
945
946       startPage = compactedHighmemUpdates[j]->address - 
947                   compactedHighmemUpdates[j]->address % pageSize;
948       stopPage = compactedHighmemUpdates[j]->address + 
949                  compactedHighmemUpdates[j]->size -
950                  (compactedHighmemUpdates[j]->address + 
951                   compactedHighmemUpdates[j]->size) % pageSize;
952
953       numberUpdates = 0;
954       startIndex = -1;
955       stopIndex = -1;
956       
957       for(unsigned index = 0;index < highmem_updates.size(); index++){
958          //here we ignore anything with an address of zero.
959          //these can be safely deleted in writeBackElf
960          if( highmem_updates[index]->address && 
961              startPage <= highmem_updates[index]->address &&
962              highmem_updates[index]->address  < (startPage + pageSize /*compactedHighmemUpdates[j]->sizei*/)){
963             numberUpdates ++;
964             stopIndex = index;
965             if(startIndex == -1){
966                startIndex = index;
967             }
968            //bperr(" HighMemUpdates address 0x%x \n", highmem_updates[index]->address );
969          }
970         //bperr(" high mem updates: 0x%x", highmem_updates[index]->address);
971       }
972       unsigned int dataSize = compactedHighmemUpdates[j]->size + 
973          sizeof(unsigned int) + 
974          (2*(stopIndex - startIndex + 1) /*numberUpdates*/ * sizeof(unsigned int));
975
976         //bperr("DATASIZE: %x : %x + 4 + ( 2*(%x - %x +1) * 4)\n", dataSize, compactedHighmemUpdates[j]->size, stopIndex, startIndex);
977       
978       data = new char[dataSize];
979       
980       //fill in pageData
981       readDataSpace((void*) compactedHighmemUpdates[j]->address, 
982                     compactedHighmemUpdates[j]->size, data, true);
983       
984       unsigned int *dataPtr = 
985          (unsigned int*) ( (char*) data + compactedHighmemUpdates[j]->size);
986
987       //fill in address of update
988       //fill in size of update
989       for(int index = startIndex; index<=stopIndex;index++){ 
990
991          memcpy(dataPtr, &highmem_updates[index]->address,
992                 sizeof(unsigned int));
993          dataPtr ++;
994          memcpy(dataPtr, &highmem_updates[index]->size, sizeof(unsigned int));
995
996          dataPtr++;
997          //bperr("%d J %d ADDRESS: 0x%x SIZE 0x%x\n",index, j,
998          //highmem_updates[index]->address, highmem_updates[index]->size);
999
1000         
1001       }
1002       //fill in number of updates
1003       memcpy(dataPtr, &numberUpdates, sizeof(unsigned int));
1004
1005       //bperr(" NUMBER OF UPDATES 0x%x  %d %x\n\n",numberUpdates,dataSize,dataSize);
1006       sprintf(name,"dyninstAPIhighmem_%08x",j);
1007 #if defined(sparc_sun_solaris2_4) \
1008  || defined(i386_unknown_linux2_0) \
1009  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1010       newFile->addSection(compactedHighmemUpdates[j]->address,data ,dataSize,name,false);
1011 #elif defined(rs6000_ibm_aix4_1)
1012           sprintf(name, "dyH_%03x",j);
1013       newFile->addSection(&(name[0]), compactedHighmemUpdates[j]->address,compactedHighmemUpdates[j]->address,
1014                 dataSize, (char*) data );
1015 #endif
1016       
1017       //lastCompactedUpdateAddress = compactedHighmemUpdates[j]->address+1;
1018       delete [] (char*) data;
1019    }
1020    writeDataSpace((void*)guardFlagAddr, sizeof(unsigned int), 
1021                   (void*)&trampGuardValue);
1022 }
1023
1024 void process::saveWorldCreateDataSections(void* ptr){
1025
1026 #if defined(sparc_sun_solaris2_4) \
1027  || defined(i386_unknown_linux2_0) \
1028  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1029         writeBackElf *newFile = (writeBackElf*) ptr;
1030 #elif defined(rs6000_ibm_aix4_1)
1031         writeBackXCOFF *newFile = (writeBackXCOFF*) ptr;
1032 #endif
1033
1034         char *dataUpdatesData;
1035         int sizeofDataUpdatesData=0;
1036         for(unsigned int m=0;m<dataUpdates.size();m++){
1037                 sizeofDataUpdatesData += (sizeof(int) + sizeof(Address)); //sizeof(size) +sizeof(Address);
1038                 sizeofDataUpdatesData += dataUpdates[m]->size;
1039         }
1040
1041
1042         if(dataUpdates.size() > 0) {
1043                 dataUpdatesData = new char[sizeofDataUpdatesData+(sizeof(int) + sizeof(Address))];
1044                 char* ptr = dataUpdatesData;
1045                 for(unsigned int k=0;k<dataUpdates.size();k++){
1046                         memcpy(ptr, &dataUpdates[k]->size, sizeof(int));
1047                         ptr += sizeof(int);
1048                         memcpy(ptr, &dataUpdates[k]->address, sizeof(Address));
1049                         ptr+=sizeof(Address);
1050                         memcpy(ptr, dataUpdates[k]->value, dataUpdates[k]->size);
1051                         ptr+=dataUpdates[k]->size;
1052                         //bperr(" DATA UPDATE : from: %x to %x , value %x\n", dataUpdates[k]->address,
1053                 //      dataUpdates[k]->address+ dataUpdates[k]->size, (unsigned int) dataUpdates[k]->value);
1054
1055                 }
1056                 *(int*) ptr=0;
1057                 ptr += sizeof(int);
1058                 *(unsigned int*) ptr=0;
1059 #if defined(sparc_sun_solaris2_4) \
1060  || defined(i386_unknown_linux2_0) \
1061  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1062                 newFile->addSection(0/*lastCompactedUpdateAddress*/, dataUpdatesData, 
1063                         sizeofDataUpdatesData + (sizeof(int) + sizeof(Address)), "dyninstAPI_data", false);
1064 #elif defined(rs6000_ibm_aix4_1)
1065                 newFile->addSection("dyn_dat", 0/*lastCompactedUpdateAddress*/,0,
1066                         sizeofDataUpdatesData + (sizeof(int) + sizeof(Address)), (char*) dataUpdatesData);
1067
1068 #endif
1069
1070                 delete [] (char*) dataUpdatesData;
1071         }
1072
1073 }
1074 #endif
1075
1076 #if defined(sparc_sun_solaris2_4) \
1077  || defined(i386_unknown_linux2_0) \
1078  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1079  || defined(rs6000_ibm_aix4_1)
1080
1081 void process::saveWorldAddSharedLibs(void *ptr){ // ccw 14 may 2002 
1082
1083         int dataSize=0;
1084         char *data, *dataptr;
1085 #if defined(sparc_sun_solaris2_4) \
1086  || defined(i386_unknown_linux2_0) \
1087  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1088         writeBackElf *newFile = (writeBackElf*) ptr;
1089 #elif defined(rs6000_ibm_aix4_1)
1090         writeBackXCOFF *newFile = (writeBackXCOFF*) ptr;
1091 #endif
1092
1093         for(unsigned i=0;i<loadLibraryUpdates.size();i++){
1094                 dataSize += loadLibraryUpdates[i].length() + 1;
1095         }
1096         dataSize++;
1097         data = new char[dataSize];
1098         dataptr = data;
1099         /*bperr(" dataSize: %d\n", dataSize);*/
1100
1101         for(unsigned j=0;j<loadLibraryUpdates.size();j++){
1102                 memcpy( dataptr, loadLibraryUpdates[j].c_str(), loadLibraryUpdates[j].length()); 
1103
1104                 /*bperr("SAVING: %s %d\n", dataptr,dataSize);*/
1105                 dataptr += loadLibraryUpdates[j].length();
1106                 *dataptr = '\0';
1107                 dataptr++; 
1108         }
1109         *dataptr = '\0'; //mark the end
1110         if(dataSize > 1){
1111 #if defined(sparc_sun_solaris2_4) \
1112  || defined(i386_unknown_linux2_0) \
1113  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1114                 newFile->addSection(0, data, dataSize, "dyninstAPI_loadLib", false);
1115 #elif  defined(rs6000_ibm_aix4_1)
1116                 newFile->addSection("dyn_lib",0,0, dataSize, data);
1117 #endif
1118         }
1119         delete [] data;
1120 }
1121
1122 #endif
1123
1124
1125 /*
1126  * Given an image, add all static heaps inside it
1127  * (DYNINSTstaticHeap...) to the buffer pool.
1128  */
1129
1130 void process::addInferiorHeap(const image *theImage, Address baseAddr)
1131 {
1132   pdvector<heapDescriptor> infHeaps;
1133   /* Get a list of inferior heaps in the new image */
1134   if (getInfHeapList(theImage, infHeaps, baseAddr))
1135     {
1136       /* Add the vector to the inferior heap structure */
1137         for (u_int j=0; j < infHeaps.size(); j++)
1138         {
1139             heapItem *h = new heapItem (infHeaps[j].addr(), infHeaps[j].size(),
1140                                         infHeaps[j].type(), false);
1141             heap.bufferPool.push_back(h);
1142             heapItem *h2 = new heapItem(h);
1143             heap.heapFree.push_back(h2);
1144         }
1145     }
1146 }
1147
1148
1149 /*
1150  * Called to (re)initialize the static inferior heap structure.
1151  * To incrementally add a static inferior heap (in a dlopen()d module,
1152  * for example), use addInferiorHeap(image *)
1153  */
1154 void process::initInferiorHeap()
1155 {
1156   assert(this->symbols);
1157   inferiorHeap *hp = &heap;
1158   pdvector<heapDescriptor> infHeaps;
1159
1160   // first initialization: add static heaps to pool
1161   if (hp->bufferPool.size() == 0) {
1162     bool err;
1163     Address heapAddr=0;
1164     int staticHeapSize = alignAddress(SYN_INST_BUF_SIZE, 32);
1165
1166     // Get the inferior heap list
1167     getInfHeapList(infHeaps);
1168     
1169     bool lowmemHeapAdded = false;
1170     bool heapAdded = false;
1171     
1172     for (u_int j=0; j < infHeaps.size(); j++)
1173     {
1174         hp->bufferPool.push_back(new heapItem (infHeaps[j].addr(), infHeaps[j].size(),
1175                                                infHeaps[j].type(), false));
1176         heapAdded = true;
1177         if (infHeaps[j].type() == lowmemHeap)
1178             lowmemHeapAdded = true;
1179     }
1180     if (!heapAdded)
1181     {
1182         // No heap added. Check for the old DYNINSTdata heap
1183         unsigned LOWMEM_HEAP_SIZE=(32*1024);
1184         cerr << "No heap found of the form DYNINSTstaticHeap_<size>_<type>_<unique>." << endl;
1185         cerr << "Attempting to use old DYNINSTdata inferior heap..." << endl;
1186         heapAddr = findInternalAddress(pdstring("DYNINSTdata"), true, err);
1187         assert(heapAddr);
1188         hp->bufferPool.push_back(new heapItem(heapAddr, staticHeapSize - LOWMEM_HEAP_SIZE,
1189                                               anyHeap, false));
1190         hp->bufferPool.push_back(new heapItem(heapAddr + staticHeapSize - LOWMEM_HEAP_SIZE,
1191                                               LOWMEM_HEAP_SIZE, lowmemHeap, false));
1192         heapAdded = true; 
1193         lowmemHeapAdded = true;
1194     }
1195     if (!lowmemHeapAdded)
1196     {
1197         // Didn't find the low memory heap. 
1198         // Handle better?
1199         // Yeah, gripe like hell
1200         cerr << "No lowmem heap found (DYNINSTstaticHeap_*_lowmem), inferior RPCs" << endl;
1201         cerr << "will probably fail" << endl;
1202     }
1203     
1204   }
1205   
1206   // (re)initialize everything 
1207   hp->heapActive.clear();
1208   hp->heapFree.resize(0);
1209   hp->disabledList.resize(0);
1210   hp->disabledListTotalMem = 0;
1211   hp->freed = 0;
1212   hp->totalFreeMemAvailable = 0;
1213   
1214   /* add dynamic heap segments to free list */
1215   for (unsigned i = 0; i < hp->bufferPool.size(); i++) {
1216     heapItem *hi = new heapItem(hp->bufferPool[i]);
1217     hi->status = HEAPfree;
1218     hp->heapFree.push_back(hi);
1219     hp->totalFreeMemAvailable += hi->length;     
1220   }
1221   inferiorMemAvailable = hp->totalFreeMemAvailable;
1222 }
1223
1224 bool process::initTrampGuard()
1225 {
1226   // This is slightly funky. Dyninst does not currently support
1227   // multiple threads -- so it uses a single tramp guard flag, 
1228   // which resides in the runtime library. However, this is not
1229   // enough for MT paradyn. So Paradyn overrides this setting as 
1230   // part of its initialization.
1231   // Repeat: OVERRIDDEN LATER FOR PARADYN
1232
1233   const pdstring vrbleName = "DYNINSTtrampGuard";
1234   internalSym sym;
1235   bool flag = findInternalSymbol(vrbleName, true, sym);
1236   assert(flag);
1237   trampGuardAddr_ = sym.getAddr();
1238   return true;
1239 }
1240
1241 // create a new inferior heap that is a copy of src. This is used when a process
1242 // we are tracing forks.
1243 inferiorHeap::inferiorHeap(const inferiorHeap &src):
1244     heapActive(addrHash16)
1245 {
1246     for (unsigned u1 = 0; u1 < src.heapFree.size(); u1++) {
1247       heapFree.push_back(new heapItem(src.heapFree[u1]));
1248     }
1249
1250     pdvector<heapItem *> items = src.heapActive.values();
1251     for (unsigned u2 = 0; u2 < items.size(); u2++) {
1252       heapActive[items[u2]->addr] = new heapItem(items[u2]);
1253     }
1254     
1255     for (unsigned u3 = 0; u3 < src.disabledList.size(); u3++) {
1256       disabledList.push_back(src.disabledList[u3]);
1257     }
1258
1259     for (unsigned u4 = 0; u4 < src.bufferPool.size(); u4++) {
1260       bufferPool.push_back(new heapItem(src.bufferPool[u4]));
1261     }
1262
1263     disabledListTotalMem = src.disabledListTotalMem;
1264     totalFreeMemAvailable = src.totalFreeMemAvailable;
1265     inferiorMemAvailable = totalFreeMemAvailable;
1266     freed = 0;
1267 }
1268
1269 //
1270 // This function will return the index corresponding to the next position
1271 // available in heapFree.
1272 //
1273 int process::findFreeIndex(unsigned size, int type, Address lo, Address hi)
1274 {
1275     // type is a bitmask: match on any bit in the mask
1276   pdvector<heapItem *> &freeList = heap.heapFree;
1277
1278   int best = -1;
1279   for (unsigned i = 0; i < freeList.size(); i++) {
1280       heapItem *h = freeList[i];
1281       // check if free block matches allocation constraints
1282       // Split out to facilitate debugging
1283       if (h->addr >= lo &&
1284           (h->addr + size - 1) <= hi &&
1285           h->length >= size &&
1286           h->type & type) {
1287           if (best == -1)
1288               best = i;
1289           // check for better match
1290           if (h->length < freeList[best]->length) best = i;
1291       }
1292   }
1293   return best;
1294 }  
1295
1296 //
1297 // dynamic inferior heap stuff
1298 //
1299 #if defined(USES_DYNAMIC_INF_HEAP)
1300 #define HEAP_DYN_BUF_SIZE (0x100000)
1301 // "imd_rpc_ret" = Inferior Malloc Dynamic RPC RETurn structure
1302 typedef struct {
1303   bool ready;
1304   void *result;
1305 } imd_rpc_ret;
1306
1307 void process::inferiorMallocCallback(process * /*proc*/, unsigned /* rpc_id */,
1308                                      void *data, void *result)
1309 {
1310   imd_rpc_ret *ret = (imd_rpc_ret *)data;
1311   ret->result = result;
1312   ret->ready = true;
1313 }
1314
1315 void alignUp(int &val, int align)
1316 {
1317   assert(val >= 0);
1318   assert(align >= 0);
1319
1320   if (val % align != 0) {
1321     val = ((val / align) + 1) * align;
1322   }
1323 }
1324
1325 // dynamically allocate a new inferior heap segment using inferiorRPC
1326 void process::inferiorMallocDynamic(int size, Address lo, Address hi)
1327 {
1328    /* 03/07/2001 - Jeffrey Shergalis TODO: This code was placed to prevent
1329     * the infinite recursion on the call to inferiorMallocDynamic,
1330     * unfortunately it makes paradyn break on Irix, temporarily fixed by the
1331     * #if !defined(mips..., but should be properly fixed in the future, just
1332     * no time now
1333     */
1334 #if !defined(mips_sgi_irix6_4)
1335   // Fun (not) case: there's no space for the RPC to execute.
1336   // It'll call inferiorMalloc, which will call inferiorMallocDynamic...
1337   // Avoid this with a static bool.
1338   if (inInferiorMallocDynamic) {
1339       return;
1340   }
1341   inInferiorMallocDynamic = true;
1342 #endif
1343
1344   // word-align buffer size 
1345   // (see "DYNINSTheap_align" in rtinst/src/RTheap-<os>.c)
1346   alignUp(size, 4);
1347   // build AstNode for "DYNINSTos_malloc" call
1348   pdstring callee = "DYNINSTos_malloc";
1349   pdvector<AstNode*> args(3);
1350   args[0] = new AstNode(AstNode::Constant, (void *)(Address)size);
1351   args[1] = new AstNode(AstNode::Constant, (void *)lo);
1352   args[2] = new AstNode(AstNode::Constant, (void *)hi);
1353   AstNode *code = new AstNode(callee, args);
1354   removeAst(args[0]);
1355   removeAst(args[1]);
1356   removeAst(args[2]);
1357
1358   // issue RPC and wait for result
1359   imd_rpc_ret ret = { false, NULL };
1360
1361   /* set lowmem to ensure there is space for inferior malloc */
1362   getRpcMgr()->postRPCtoDo(code, true, // noCost
1363                            &inferiorMallocCallback, &ret, 
1364                            true, // But use reserved memory
1365                            NULL, NULL); // process-wide
1366   bool wasRunning = (status() == running);
1367
1368   do {
1369       getRpcMgr()->launchRPCs(wasRunning);
1370       if(hasExited()) return;
1371       getSH()->checkForAndHandleProcessEvents(false);
1372    } while (!ret.ready); // Loop until callback has fired.
1373
1374    switch ((int)(Address)ret.result) {
1375      case 0:
1376 #ifdef DEBUG
1377         sprintf(errorLine, "DYNINSTos_malloc() failed\n");
1378         logLine(errorLine);
1379 #endif
1380         break;
1381      case -1:
1382         // TODO: assert?
1383         sprintf(errorLine, "DYNINSTos_malloc(): unaligned buffer size\n");
1384         logLine(errorLine);
1385         break;
1386      default:
1387         // add new segment to buffer pool
1388          // FIXME
1389 #if defined(os_aix)
1390          // for save the world...
1391         heapItem *h = new heapItem((Address)ret.result, size, dataHeap, true,
1392                                    HEAPfree);
1393 #else
1394         heapItem *h = new heapItem((Address)ret.result, size, anyHeap, true,
1395                                    HEAPfree);
1396 #endif
1397         heap.bufferPool.push_back(h);
1398         // add new segment to free list
1399         heapItem *h2 = new heapItem(h);
1400         heap.heapFree.push_back(h2);
1401         break;
1402    }
1403    
1404    /* 03/07/2001 - Jeffrey Shergalis
1405     * Part of the above #if !defined(mips... patch for the recursion problem
1406     * TODO: Need a better solution
1407     */
1408 #if !defined(mips_sgi_irix6_4)
1409    inInferiorMallocDynamic = false;
1410 #endif
1411 }
1412 #endif /* USES_DYNAMIC_INF_HEAP */
1413
1414 const Address ADDRESS_LO = ((Address)0);
1415 const Address ADDRESS_HI = ((Address)~((Address)0));
1416 //unsigned int totalSizeAlloc = 0;
1417
1418 Address process::inferiorMalloc(unsigned size, inferiorHeapType type, 
1419                                 Address near_, bool *err)
1420 {
1421    inferiorHeap *hp = &heap;
1422    if (err) *err = false;
1423    assert(size > 0);
1424    
1425    // allocation range
1426    Address lo = ADDRESS_LO; // Should get reset to a more reasonable value
1427    Address hi = ADDRESS_HI; // Should get reset to a more reasonable value
1428    
1429 #if defined(USES_DYNAMIC_INF_HEAP)
1430    inferiorMallocAlign(size); // align size
1431    // Set the lo/hi constraints (if necessary)
1432    inferiorMallocConstraints(near_, lo, hi, type);
1433 #else
1434    /* align to cache line size (32 bytes on SPARC) */
1435    size = (size + 0x1f) & ~0x1f; 
1436 #endif /* USES_DYNAMIC_INF_HEAP */
1437
1438    // find free memory block (7 attempts)
1439    // attempt 0: as is
1440    // attempt 1: deferred free, compact free blocks
1441    // attempt 2: allocate new segment (1 MB, constrained)
1442    // attempt 3: allocate new segment (sized, constrained)
1443    // attempt 4: remove range constraints
1444    // attempt 5: allocate new segment (1 MB, unconstrained)
1445    // attempt 6: allocate new segment (sized, unconstrained)
1446    // attempt 7: deferred free, compact free blocks (why again?)
1447    int freeIndex = -1;
1448    int ntry = 0;
1449    for (ntry = 0; freeIndex == -1; ntry++) {
1450       switch(ntry) {
1451         case 0: // as is
1452            break;
1453 #if defined(USES_DYNAMIC_INF_HEAP)
1454         case 1: // compact free blocks
1455           gcInstrumentation();
1456           inferiorFreeCompact(hp);
1457           break;
1458         case 2: // allocate new segment (1MB, constrained)
1459         inferiorMallocDynamic(HEAP_DYN_BUF_SIZE, lo, hi);
1460            break;
1461         case 3: // allocate new segment (sized, constrained)
1462            inferiorMallocDynamic(size, lo, hi);
1463            break;
1464         case 4: // remove range constraints
1465            lo = ADDRESS_LO;
1466            hi = ADDRESS_HI;
1467            if (err) {
1468               *err = true;
1469            }
1470            break;
1471         case 5: // allocate new segment (1MB, unconstrained)
1472            inferiorMallocDynamic(HEAP_DYN_BUF_SIZE, lo, hi);
1473            break;
1474         case 6: // allocate new segment (sized, unconstrained)
1475            inferiorMallocDynamic(size, lo, hi);
1476            break;
1477         case 7: // deferred free, compact free blocks
1478            inferiorFreeCompact(hp);
1479            break;
1480 #else /* !(USES_DYNAMIC_INF_HEAP) */
1481         case 1: // deferred free, compact free blocks
1482            inferiorFreeCompact(hp);
1483            break;
1484 #endif /* USES_DYNAMIC_INF_HEAP */
1485            
1486         default: // error - out of memory
1487            sprintf(errorLine, "***** Inferior heap overflow: %d bytes "
1488                    "freed, %d bytes requested \n", hp->freed, size);
1489            logLine(errorLine);
1490            showErrorCallback(66, (const char *) errorLine);    
1491 #if defined(BPATCH_LIBRARY)
1492            return(0);
1493 #else
1494            P__exit(-1);
1495 #endif
1496       }
1497       freeIndex = findFreeIndex(size, type, lo, hi);
1498 //      bperr("  type %x",type);
1499    }
1500
1501    // adjust active and free lists
1502    heapItem *h = hp->heapFree[freeIndex];
1503    assert(h);
1504
1505    // remove allocated buffer from free list
1506    if (h->length != size) {
1507       // size mismatch: put remainder of block on free list
1508       heapItem *rem = new heapItem(h);
1509       rem->addr += size;
1510       rem->length -= size;
1511       hp->heapFree[freeIndex] = rem;
1512    } else {
1513       // size match: remove entire block from free list
1514       unsigned last = hp->heapFree.size();
1515       hp->heapFree[freeIndex] = hp->heapFree[last-1];
1516       hp->heapFree.resize(last-1);
1517    }
1518    // add allocated block to active list
1519    h->length = size;
1520    h->status = HEAPallocated;
1521    hp->heapActive[h->addr] = h;
1522    // bookkeeping
1523    hp->totalFreeMemAvailable -= size;
1524    inferiorMemAvailable = hp->totalFreeMemAvailable;
1525    assert(h->addr);
1526    
1527    // ccw: 28 oct 2001
1528    // create imageUpdate here:
1529    // imageUpdate(h->addr,size)
1530    
1531 #ifdef BPATCH_LIBRARY
1532 //      if( h->addr > 0xd0000000){
1533 //              bperr(" \n ALLOCATION: %lx %lx ntry: %d\n", h->addr, size,ntry);
1534 //              fflush(stdout);
1535 //      }
1536 #if defined(sparc_sun_solaris2_4) \
1537  || defined(i386_unknown_linux2_0) \
1538  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1539  || defined(rs6000_ibm_aix4_1)
1540    if(collectSaveWorldData){
1541       
1542 #if defined(sparc_sun_solaris2_4)
1543       if(h->addr < 0xF0000000)
1544 #elif defined(i386_unknown_linux2_0) \
1545    || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1546       if(h->addr < 0x40000000)
1547 #elif defined(rs6000_ibm_aix4_1)
1548         if(h->addr < 0x20000000)
1549 #endif  
1550       {
1551          imageUpdate *imagePatch=new imageUpdate; 
1552          imagePatch->address = h->addr;
1553          imagePatch->size = size;
1554          imageUpdates.push_back(imagePatch);
1555          //totalSizeAlloc += size;
1556          //bperr(" PUSHBACK %x %x --- \n", imagePatch->address, imagePatch->size);              
1557       } else {
1558          //     totalSizeAlloc += size;
1559          //bperr(" HIGHMEM UPDATE %x %x \n", h->addr, size);
1560          imageUpdate *imagePatch=new imageUpdate;
1561          imagePatch->address = h->addr;
1562          imagePatch->size = size;
1563          highmemUpdates.push_back(imagePatch);
1564          //bperr(" PUSHBACK %x %x\n", imagePatch->address, imagePatch->size);
1565       }
1566       //fflush(stdout);
1567    }
1568 #endif
1569 #endif
1570    return(h->addr);
1571 }
1572
1573 /* returns true if memory was allocated for a variable starting at address
1574    "block", otherwise returns false
1575 */
1576 bool isInferiorAllocated(process *p, Address block) {
1577   heapItem *h = NULL;  
1578   inferiorHeap *hp = &p->heap;
1579   return hp->heapActive.find(block, h);
1580 }
1581
1582 void process::inferiorFree(Address block)
1583 {
1584   inferiorHeap *hp = &heap;
1585
1586   // find block on active list
1587   heapItem *h = NULL;  
1588   if (!hp->heapActive.find(block, h)) {
1589     showErrorCallback(96,"Internal error: "
1590         "attempt to free non-defined heap entry.");
1591     return;
1592   }
1593   assert(h);
1594
1595   // Remove from the active list
1596   hp->heapActive.undef(block);
1597
1598   // Add to the free list
1599   h->status = HEAPfree;
1600   hp->heapFree.push_back(h);
1601   hp->totalFreeMemAvailable += h->length;
1602   hp->freed += h->length;
1603   inferiorMemAvailable = hp->totalFreeMemAvailable;
1604 }
1605  
1606
1607 // Cleanup the process object. Delete all sub-objects to ensure we aren't 
1608 // leaking memory and prepare for new versions. Useful when the process exits
1609 // (and the process object is deleted) and when it execs
1610
1611 void process::deleteProcess() {
1612     // A lot of the behavior here is keyed off the current process status....
1613     // if it is exited we'll delete things without performing any operations
1614     // on the process. Otherwise we'll attempt to reverse behavior we've made.
1615
1616   // We may call this function multiple times... once when the process exits,
1617   // once when we delete the process object.
1618   if (status() == deleted) return;
1619     
1620     // If this assert fires check whether we're setting the status vrble correctly
1621     // before calling this function
1622     assert(!isAttached());
1623            
1624     // Get rid of our syscall tracing.
1625     if (tracedSyscalls_) {
1626         delete tracedSyscalls_;
1627         tracedSyscalls_ = NULL;
1628     }
1629     // Delete the base (and minitramp) handles if the process execed or exited
1630     // We keep them around if we detached.
1631     if (status_ != detached) {        
1632         dictionary_hash_iter<const instPoint *, trampTemplate *>baseMap_iter(baseMap);
1633         for (; baseMap_iter; baseMap_iter++) {
1634             // WE ARE NOT DELETING INSTPOINTS as they are shared between processes.
1635             // const instPoint *p = baseMap_iter.currkey();
1636             // delete p;
1637             // Note: we do not remove the base and mini tramps from the codeRange address
1638             // mapping, since we'll clear it later.
1639             trampTemplate *t = baseMap_iter.currval();
1640             delete t;
1641         }
1642 #if defined(arch_ia64)
1643         multiTrampMap.clear();
1644 #endif
1645         // instpoints to base tramps
1646         baseMap.clear();
1647         // Address to instpoint (for arb. instpoints)
1648         instPointMap.clear();
1649         // pdFunctions to bpatch 'parents'
1650         PDFuncToBPFuncMap.clear();
1651         trampTrapMapping.clear();
1652     }
1653     
1654     // Our modifications to the dynamic linker so that we're made aware
1655     // of new shared libraries
1656     if (dyn) {
1657         delete dyn;
1658         dyn = NULL;
1659     }
1660     
1661     // Delete all shared_object objects
1662     if (shared_objects) {
1663         for (unsigned shared_objects_iter = 0;
1664              shared_objects_iter < (*shared_objects).size();
1665              shared_objects_iter++) {
1666           delete (*shared_objects)[shared_objects_iter];
1667         }
1668         // Note: we don't remove the shared objects from the codeRange address
1669         // mapping, as we clear it later.
1670         delete shared_objects;
1671         shared_objects = NULL;
1672         runtime_lib = NULL;
1673     }
1674
1675     // "Delete" the symbols pointer -- refcounting is handled in the image
1676     // class
1677     if (symbols) {
1678       symbols->cleanProcessSpecific(this);
1679       image::removeImage(symbols);
1680       symbols = NULL;
1681     }
1682     
1683     // Clear the codeRange address mapping
1684     if (codeRangesByAddr_) {
1685         delete codeRangesByAddr_;
1686         codeRangesByAddr_ = NULL;
1687     }
1688
1689     // Signal handler
1690 #if !(defined(os_linux) && (defined(arch_x86) || defined(arch_x86_64)))
1691    signal_handler = 0;
1692 #endif
1693
1694    
1695    // pdFunctions should be deleted as part of the image class... when the reference count
1696    // hits 0... this is TODO
1697    delete some_modules; some_modules = NULL;
1698    delete some_functions; some_functions = NULL;
1699    delete all_functions; all_functions = NULL;
1700    delete all_modules; all_modules = NULL;
1701    
1702    if (status_ == exited || status_ == detached) {
1703 // Delete the thread and lwp structures
1704        dictionary_hash_iter<unsigned, dyn_lwp *> lwp_iter(real_lwps);
1705        dyn_lwp *lwp;
1706        unsigned index;
1707        
1708        while (lwp_iter.next(index, lwp)) {
1709            deleteLWP(lwp);
1710        }
1711        real_lwps.clear();
1712        
1713        for (unsigned thr_iter = 0; thr_iter < threads.size(); thr_iter++) {
1714            delete threads[thr_iter];
1715        }
1716        threads.clear();
1717        // Delete the RPC manager
1718        if (theRpcMgr) delete theRpcMgr;
1719        theRpcMgr = NULL;
1720    }
1721
1722    // TODO: thread and lwp cleanup when we exec.
1723
1724    set_status(deleted);
1725 }
1726
1727 //
1728 // cleanup when a process is deleted. Assumed we are detached or the process is exited.
1729 //
1730 process::~process()
1731 {
1732  
1733     // We require explicit detaching if the process still exists.
1734     assert(!isAttached());
1735
1736 #if defined( ia64_unknown_linux2_4 )
1737         if( unwindProcessArg != NULL ) { _UPT_destroy( unwindProcessArg ); }
1738         if( unwindAddressSpace != NULL ) { unw_destroy_addr_space( unwindAddressSpace ); }
1739 #endif
1740     
1741     // Most of the deletion is encapsulated in deleteProcess
1742     deleteProcess();
1743
1744     // We used to delete the particular process, but this created no end of problems
1745     // with people storing pointers into particular indices. We set the pointer to NULL.
1746     for (unsigned lcv=0; lcv < processVec.size(); lcv++) {
1747         if (processVec[lcv] == this) {
1748             processVec[lcv] = NULL;
1749         }        
1750     }
1751
1752 #if defined(i386_unknown_linux2_0) \
1753  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1754     cleanupVsysinfo(getVsyscallData());
1755 #endif
1756
1757 }
1758
1759 unsigned hash_bp(int_function * const &bp ) { return(addrHash4((Address) bp)); }
1760
1761 //
1762 // Process "normal" (non-attach, non-fork) ctor, for when a new process
1763 // is fired up by paradynd itself.
1764 // This ctor. is also used in the case that the application has been fired up
1765 // by another process and stopped just after executing the execv() system call.
1766 // In the "normal" case, the parameter iTraceLink will be a non-negative value which
1767 // corresponds to the pipe descriptor of the trace pipe used between the paradynd
1768 // and the application. In the later case, iTraceLink will be -1. This will be 
1769 // posteriorly used to properly initialize the createdViaAttachToCreated flag. - Ana
1770 //
1771
1772 //removed all ioLink related code for output redirection
1773 process::process(int iPid, image *iImage, int iTraceLink) :
1774   collectSaveWorldData(true),
1775 #if defined(BPATCH_LIBRARY) && defined(rs6000_ibm_aix4_1)
1776  requestTextMiniTramp(0), //ccw 30 jul 2002
1777 #endif
1778   bpatch_thread( NULL ),
1779   baseMap(ipHash),
1780   PDFuncToBPFuncMap(hash_bp),
1781   instPointMap(hash_address),
1782   trampTrapMapping(addrHash4),
1783   suppressCont_(false),
1784   loadLibraryCallbacks_(pdstring::hash),
1785   cached_result(not_cached),
1786   savedRegs(NULL),
1787   pid(iPid), // needed in fastInferiorHeap ctors below
1788 #if !defined(BPATCH_LIBRARY)
1789   previous(0),
1790 #endif
1791 #if defined(i386_unknown_nt4_0) \
1792  || (defined mips_unknown_ce2_11)
1793   windows_termination_requested(false),
1794 #endif
1795   representativeLWP(NULL),
1796 #if ! defined( ia64_unknown_linux2_4 )  
1797   real_lwps(CThash)
1798 #else
1799   real_lwps(CThash),
1800   unwindAddressSpace( NULL ), unwindProcessArg( NULL ),
1801   multiTrampMap(addrHash16)
1802 #endif
1803 {
1804 #if !defined(BPATCH_LIBRARY) //ccw 22 apr 2002 : SPLIT
1805         PARADYNhasBootstrapped = false;
1806 #endif
1807     tracedSyscalls_ = NULL;
1808     codeRangesByAddr_ = NULL;
1809
1810    shared_objects = 0;
1811    invalid_thr_create_msgs = 0;
1812
1813    parentPid = childPid = 0;
1814    dyninstlib_brk_addr = 0;
1815     
1816    main_brk_addr = 0;
1817
1818    nextTrapIsFork = false;
1819    nextTrapIsExec = false;
1820    // Instrumentation points for tracking syscalls
1821    preForkInst = postForkInst = preExecInst = postExecInst = preExitInst = NULL;
1822
1823    LWPstoppedFromForkExit = 0;  
1824
1825    wasRunningWhenAttached_ = false;
1826    bootstrapState = unstarted;
1827
1828    createdViaAttach = false;
1829    createdViaFork = false;
1830    createdViaAttachToCreated = false; 
1831    wasRunningWhenAttached_ = false; // Technically true...
1832
1833 #ifndef BPATCH_LIBRARY
1834    if (iTraceLink == -1 ) createdViaAttachToCreated = true;
1835    // indicates the unique case where paradynd is attached to
1836    // a stopped application just after executing the execv() --Ana
1837 #endif
1838    needToContinueAfterDYNINSTinit = false;  //Wait for press of "RUN" button
1839
1840    symbols = iImage;
1841    // The a.out is a special case... all addresses in it are absolutes,
1842    // but we only want it to occupy the area in our memory map that the
1843    // functions take up. So we insert it at the codeOffset, and then
1844    // _don't_ pass in offsets for recursed function lookups
1845    codeRangesByAddr_ = new codeRangeTree;
1846    addCodeRange(symbols->codeOffset(), symbols);
1847     
1848    mainFunction = NULL; // set in platform dependent function heapIsOk
1849
1850    theRpcMgr = new rpcMgr(this);
1851    set_status(neonatal);
1852    previousSignalAddr_ = 0;
1853    continueAfterNextStop_ = 0;
1854
1855    parent = NULL;
1856    inExec = false;
1857
1858    cumObsCost = 0;
1859    lastObsCostLow = 0;
1860
1861     
1862    dynamiclinking = false;
1863    dyn = new dynamic_linking(this);
1864    runtime_lib = 0;
1865    all_functions = 0;
1866    all_modules = 0;
1867    some_modules = 0;
1868    some_functions = 0;
1869 #if !(defined(os_linux) && (defined(arch_x86) || defined(arch_x86_64)))
1870    signal_handler = 0;
1871 #endif
1872    execed_ = false;
1873
1874    inInferiorMallocDynamic = false;
1875
1876 #if defined(i386_unknown_linux2_0) \
1877  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1878     vsyscall_start_ = 0x0;
1879     vsyscall_end_ = 0x0;
1880     vsyscall_text_ = 0x0;
1881     vsyscall_data_= NULL;
1882 #endif
1883
1884    splitHeaps = false;
1885
1886 #if defined(rs6000_ibm_aix3_2) \
1887  || defined(rs6000_ibm_aix4_1) \
1888  || defined(alpha_dec_osf4_0)
1889    // XXXX - move this to a machine dependant place.
1890
1891    // create a seperate text heap.
1892    //initInferiorHeap(true);
1893    splitHeaps = true;
1894 #endif
1895    traceLink = iTraceLink; // notice that tracelink will be -1 in the unique
1896    // case called "AttachToCreated" - Ana
1897           
1898    bufStart = 0;
1899    bufEnd = 0;
1900    //removed for output redirection
1901    //ioLink = iIoLink;
1902
1903
1904    createRepresentativeLWP();
1905
1906    // attach to the child process (machine-specific implementation)
1907    if (!attach()) { // error check?
1908        status_ = detached;
1909        
1910       pdstring msg = pdstring("Warning: unable to attach to specified process :")
1911          + pdstring(pid);
1912       showErrorCallback(26, msg.c_str());
1913       cerr << "Process: failed attach!" << endl;
1914    }
1915
1916 #ifndef BPATCH_LIBRARY
1917 #ifdef PAPI
1918    if (isPapiInitialized()) {
1919       papi = new papiMgr(this);
1920    }
1921 #endif
1922 #endif
1923
1924    // Set name of RT library.
1925    getDyninstRTLibName();
1926 } // end of normal constructor
1927     
1928
1929 //
1930 // Process "attach" ctor, for when paradynd is attaching to an already-existing
1931 // process. 
1932 //
1933 //
1934 process::process(int iPid, image *iSymbols,
1935                  bool &success) :
1936   collectSaveWorldData(true),
1937 #if defined(BPATCH_LIBRARY) && defined(rs6000_ibm_aix4_1)
1938   requestTextMiniTramp(0), //ccw 30 jul 2002
1939 #endif
1940   bpatch_thread( NULL ),
1941   baseMap(ipHash),
1942   PDFuncToBPFuncMap(hash_bp),
1943   instPointMap(hash_address),
1944   trampTrapMapping(addrHash4),
1945   suppressCont_(false),
1946   loadLibraryCallbacks_(pdstring::hash),
1947   cached_result(not_cached),
1948 #ifndef BPATCH_LIBRARY
1949   PARADYNhasBootstrapped(false),
1950 #endif
1951   savedRegs(NULL),
1952   pid(iPid),
1953 #if !defined(BPATCH_LIBRARY) && defined(i386_unknown_nt4_0)
1954   previous(0), //ccw 8 jun 2002
1955 #endif
1956 #if defined(i386_unknown_nt4_0) \
1957  || (defined mips_unknown_ce2_11)
1958   windows_termination_requested(false),
1959 #endif
1960   representativeLWP(NULL),
1961 #if ! defined( ia64_unknown_linux2_4 )  
1962   real_lwps(CThash)
1963 #else
1964   real_lwps(CThash),
1965   unwindAddressSpace( NULL ), unwindProcessArg( NULL ),
1966   multiTrampMap(addrHash16)
1967 #endif
1968 {
1969     tracedSyscalls_ = NULL;
1970     codeRangesByAddr_ = NULL;
1971
1972     parentPid = childPid = 0;
1973     dyninstlib_brk_addr = 0;
1974     main_brk_addr = 0;
1975     
1976     nextTrapIsFork = false;
1977     nextTrapIsExec = false;
1978
1979     invalid_thr_create_msgs = 0;
1980
1981     createdViaAttach = true;
1982
1983 #if !defined(i386_unknown_nt4_0)
1984     bootstrapState = initialized;
1985 #else
1986     // We need to wait for the CREATE_PROCESS debug event.
1987     // Set to "begun" here, and fix up in the signal loop
1988     bootstrapState = begun;
1989 #endif
1990
1991     createdViaFork = false;
1992     createdViaAttachToCreated = false; 
1993     
1994     symbols = iSymbols;
1995     mainFunction = NULL; // set in platform dependent function heapIsOk
1996     
1997     set_status(neonatal);
1998     previousSignalAddr_ = 0;
1999     continueAfterNextStop_ = 0;
2000
2001     LWPstoppedFromForkExit = 0;
2002
2003     inInferiorMallocDynamic = false;
2004     theRpcMgr = new rpcMgr(this);
2005
2006     parent = NULL;
2007     inExec = false;
2008
2009     // Instrumentation points for tracking syscalls
2010     preForkInst = postForkInst = preExecInst = postExecInst = preExitInst = NULL;
2011     cumObsCost = 0;
2012     lastObsCostLow = 0;
2013
2014     dynamiclinking = false;
2015     dyn = new dynamic_linking(this);
2016     shared_objects = 0;
2017     runtime_lib = 0;
2018     all_functions = 0;
2019     all_modules = 0;
2020     some_modules = 0;
2021     some_functions = 0;
2022 #if !(defined(os_linux) && (defined(arch_x86) || defined(arch_x86_64)))
2023     signal_handler = 0;
2024 #endif
2025     execed_ = false;
2026
2027     splitHeaps = false;
2028 #if defined(rs6000_ibm_aix3_2) \
2029  || defined(rs6000_ibm_aix4_1) \
2030  || defined(alpha_dec_osf4_0)
2031         // XXXX - move this to a machine dependant place.
2032
2033         // create a seperate text heap.
2034         //initInferiorHeap(true);
2035         splitHeaps = true;
2036 #endif
2037
2038 #if defined(i386_unknown_linux2_0) \
2039  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
2040     vsyscall_start_ = 0x0;
2041     vsyscall_end_ = 0x0;
2042     vsyscall_text_ = 0x0;
2043     vsyscall_data_= NULL;
2044 #endif
2045
2046    traceLink = -1; // will be set later, when the appl runs DYNINSTinit
2047    bufStart = 0;
2048    bufEnd = 0;
2049
2050    //removed for output redirection
2051    //ioLink = -1; // (ARGUABLY) NOT YET IMPLEMENTED...MAYBE WHEN WE ATTACH WE DON'T WANT
2052                 // TO REDIRECT STDIO SO WE CAN LEAVE IT AT -1.
2053
2054    // Now the actual attach...the moment we've all been waiting for
2055
2056    attach_cerr << "process attach ctor: about to attach to pid " << getPid() << endl;
2057    createRepresentativeLWP();
2058
2059    // It is assumed that a call to attach() doesn't affect the running status
2060    // of the process.  But, unfortunately, some platforms may barf if the
2061    // running status is anything except paused. (How to deal with this?)
2062    // Note that solaris in particular seems able to attach even if the process
2063    // is running.
2064    if (!attach()) {
2065        status_ = detached;
2066        
2067       pdstring msg = pdstring("Warning: unable to attach to specified process: ")
2068                    + pdstring(pid);
2069       showErrorCallback(26, msg.c_str());
2070       success = false;
2071       return;
2072    }
2073
2074 #if defined(rs6000_ibm_aix3_2) \
2075  || defined(rs6000_ibm_aix4_1)
2076    // Now that we're attached, we can reparse the image with correct
2077    // settings.
2078    // Process is paused 
2079    int status = pid;
2080    fileDescriptor *desc = getExecFileDescriptor(symbols->pathname(), status, false);
2081    if (!desc) {
2082       pdstring msg = pdstring("Warning: unable to parse to specified process: ")
2083                    + pdstring(pid);
2084       showErrorCallback(26, msg.c_str());
2085       success = false;
2086       return;
2087    }
2088
2089    image *theImage = image::parseImage(desc);
2090    if (theImage == NULL) {
2091       pdstring msg = pdstring("Warning: unable to parse to specified process: ")
2092                    + pdstring(pid);
2093       showErrorCallback(26, msg.c_str());
2094       success = false;
2095       return;
2096    }
2097    // this doesn't leak, since the old theImage was deleted. 
2098    symbols = theImage;
2099 #endif
2100
2101    codeRangesByAddr_ = new codeRangeTree;
2102    addCodeRange(symbols->codeOffset(), symbols);
2103
2104    // Record what the process was doing when we attached, for possible
2105    // use later.
2106    wasRunningWhenAttached_ = isRunning_();
2107    if (wasRunningWhenAttached_) 
2108       set_status(running);
2109    else
2110       set_status(stopped);
2111
2112    // Does attach() send a SIGTRAP, a la the initial SIGTRAP sent at the
2113    // end of exec?  It seems that on some platforms it does; on others
2114    // it doesn't.  Ick.  On solaris, it doesn't.
2115
2116    // note: we don't call getSharedObjects() yet; that happens once DYNINSTinit
2117    //       finishes (initSharedObjects)
2118
2119 #ifndef BPATCH_LIBRARY
2120 #ifdef PAPI
2121    if (isPapiInitialized()) {
2122      papi = new papiMgr(this);
2123    }
2124 #endif
2125 #endif
2126
2127    // Set name of RT library.
2128    getDyninstRTLibName();
2129
2130    // Everything worked
2131    success = true;
2132 }
2133
2134 //
2135 // Process "fork" ctor, for when a process which is already being monitored by
2136 // paradynd executes the fork syscall.
2137 //
2138
2139 process::process(const process &parentProc, int iPid, int iTrace_fd) :
2140   collectSaveWorldData(true),
2141 #if defined(BPATCH_LIBRARY) && defined(rs6000_ibm_aix4_1)
2142   requestTextMiniTramp(0), //ccw 30 jul 2002
2143 #endif
2144   baseMap(ipHash), // could change to baseMap(parentProc.baseMap)
2145   PDFuncToBPFuncMap(hash_bp),
2146   instPointMap(hash_address),
2147   trampTrapMapping(parentProc.trampTrapMapping),
2148   suppressCont_(false),
2149   loadLibraryCallbacks_(pdstring::hash),
2150   cached_result(parentProc.cached_result),
2151 #ifndef BPATCH_LIBRARY
2152   PARADYNhasBootstrapped(false),
2153 #endif
2154   savedRegs(NULL),
2155 #if !defined(BPATCH_LIBRARY)
2156   previous(0),
2157 #endif
2158 #if defined(i386_unknown_nt4_0) \
2159  || defined(mips_unknown_ce2_11)
2160   windows_termination_requested(false),
2161 #endif
2162   representativeLWP(NULL),
2163 #if ! defined( ia64_unknown_linux2_4 )  
2164   real_lwps(CThash)  
2165 #else
2166   real_lwps(CThash),
2167   unwindAddressSpace( NULL ), unwindProcessArg( NULL ),
2168   multiTrampMap(addrHash16)
2169 #endif
2170 {
2171
2172     costAddr_ = parentProc.costAddr_;
2173     
2174    // This is the "fork" ctor
2175    bootstrapState = initialized;
2176
2177    invalid_thr_create_msgs = 0;
2178
2179    createdViaAttachToCreated = false;
2180    createdViaFork = true;
2181    createdViaAttach = parentProc.createdViaAttach;
2182    wasRunningWhenAttached_ = true;
2183    needToContinueAfterDYNINSTinit = true;
2184
2185    symbols = parentProc.symbols->clone();
2186
2187    mainFunction = parentProc.mainFunction;
2188
2189    LWPstoppedFromForkExit = 0;
2190
2191    traceLink = iTrace_fd;
2192    bufStart = 0;
2193    bufEnd = 0;
2194
2195    //removed for output redireciton
2196    //ioLink = -1; // when does this get set?
2197
2198    set_status(neonatal); // is neonatal right?
2199    previousSignalAddr_ = 0;
2200    continueAfterNextStop_ = 0;
2201
2202    pid = iPid; 
2203
2204    // Copy over the base tramp data structure
2205    {
2206        dictionary_hash_iter<const instPoint *, trampTemplate *> baseMap_iter(parentProc.baseMap);
2207        trampTemplate *t;
2208        for (; baseMap_iter; baseMap_iter++) {
2209            const instPoint *p = baseMap_iter.currkey();
2210            t = baseMap_iter.currval();
2211            // Also copies internal minitramp lists
2212            baseMap[p] = new trampTemplate(t, this);
2213        }
2214    }
2215
2216    // We don't want to do this... we want to duplicate the behavior
2217    // that created the original tree. As a result, shared objects
2218    // will still be shared, but non-shared ones will be correctly
2219    // duplicated.
2220    //codeRangesByAddr_ = new codeRangeTree(*(parentProc.codeRangesByAddr_));
2221    codeRangesByAddr_ = new codeRangeTree;
2222    // Add the a.out
2223    addCodeRange(symbols->codeOffset(), symbols);
2224    // Clones relocation entries
2225    symbols->updateForFork(this, &parentProc);
2226    // And all shared libs
2227
2228    // make copy of parent's shared_objects vector
2229    shared_objects = NULL;
2230    if (parentProc.shared_objects) {
2231      shared_objects = new pdvector<shared_object*>;
2232      for (unsigned u1 = 0; u1 < parentProc.shared_objects->size(); u1++){
2233        (*shared_objects).push_back(
2234                                    new shared_object(*(*parentProc.shared_objects)[u1], this));
2235      }
2236    }
2237    for (unsigned i = 0; i < shared_objects->size(); i++) {
2238      addCodeRange((*shared_objects)[i]->getBaseAddress() +
2239                   (*shared_objects)[i]->getImage()->codeOffset(),
2240                   (*shared_objects)[i]);
2241      (*shared_objects)[i]->updateForFork(this, &parentProc);
2242    }
2243    // Copy over the system call notifications and reinitialize (if necessary)
2244    tracedSyscalls_ = new syscallNotification(parentProc.tracedSyscalls_, this);
2245
2246    theRpcMgr = new rpcMgr(this);
2247
2248    parent = const_cast<process*>(&parentProc);
2249     
2250    parentPid = childPid = 0;
2251    dyninstlib_brk_addr = 0;
2252
2253    main_brk_addr = 0;
2254    nextTrapIsExec = false;
2255    
2256    //bootstrapState = initialized;
2257    bootstrapState = bootstrapped;
2258
2259    splitHeaps = parentProc.splitHeaps;
2260
2261    heap = inferiorHeap(parentProc.heap);
2262
2263    inExec = false;
2264
2265    cumObsCost = 0;
2266    lastObsCostLow = 0;
2267
2268 #if defined(i386_unknown_linux2_0) \
2269  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
2270     vsyscall_start_ = 0x0;
2271     vsyscall_end_ = 0x0;
2272     vsyscall_text_ = 0x0;
2273     vsyscall_data_= NULL;
2274 #endif
2275
2276    inInferiorMallocDynamic = false;
2277
2278    dynamiclinking = parentProc.dynamiclinking;
2279    dyn = new dynamic_linking(this, parentProc.dyn);
2280    runtime_lib = parentProc.runtime_lib;
2281
2282    all_functions = 0;
2283    if (parentProc.all_functions) {
2284       all_functions = new pdvector<int_function *>;
2285       for (unsigned u2 = 0; u2 < parentProc.all_functions->size(); u2++)
2286          (*all_functions).push_back((*parentProc.all_functions)[u2]);
2287    }
2288
2289    all_modules = 0;
2290    if (parentProc.all_modules) {
2291       all_modules = new pdvector<module *>;
2292       for (unsigned u3 = 0; u3 < parentProc.all_modules->size(); u3++)
2293          (*all_modules).push_back((*parentProc.all_modules)[u3]);
2294    }
2295
2296    some_modules = 0;
2297    if (parentProc.some_modules) {
2298       some_modules = new pdvector<module *>;
2299       for (unsigned u4 = 0; u4 < parentProc.some_modules->size(); u4++)
2300          (*some_modules).push_back((*parentProc.some_modules)[u4]);
2301    }
2302     
2303    some_functions = 0;
2304    if (parentProc.some_functions) {
2305       some_functions = new pdvector<int_function *>;
2306       for (unsigned u5 = 0; u5 < parentProc.some_functions->size(); u5++)
2307          (*some_functions).push_back((*parentProc.some_functions)[u5]);
2308    }
2309
2310 #if defined(os_linux) && (defined(arch_x86) || defined(arch_x86_64))
2311    signal_restore = parentProc.signal_restore;
2312 #else
2313    signal_handler = parentProc.signal_handler;
2314 #endif
2315    execed_ = false;
2316
2317    createRepresentativeLWP();
2318
2319    if (!attach()) {     // moved from ::forkProcess
2320        status_ = detached;
2321       showErrorCallback(69, "Error in fork: cannot attach to child process");
2322       set_status(exited);
2323       return;
2324    }
2325
2326    if(! multithread_capable()) {
2327       // for single thread, add the single thread
2328       assert(parentProc.threads.size() == 1);
2329       dyn_thread *parent_thr = parentProc.threads[0];
2330       dyn_thread *new_thr = new dyn_thread(this, parent_thr);
2331       threads.push_back(new_thr);      
2332    }
2333    // the threads for MT programs are added through later, through function
2334
2335    if( isRunning_() )
2336       set_status(running);
2337    else
2338       set_status(stopped);
2339    // would neonatal be more appropriate?  Nah, we've reached the first trap
2340
2341 #ifndef BPATCH_LIBRARY
2342 #ifdef PAPI
2343    if (isPapiInitialized()) {
2344       papi = new papiMgr(this);
2345    }
2346 #endif
2347 #endif
2348
2349    initTrampGuard();
2350
2351    // Set name of RT library.
2352    getDyninstRTLibName();
2353 }
2354
2355 // #endif
2356
2357 extern bool forkNewProcess(pdstring &file, pdstring dir,
2358                            pdvector<pdstring> *argv, pdvector<pdstring> *envp,
2359                            pdstring inputFile,
2360                            pdstring outputFile, int &traceLink, int &pid,
2361                            int &tid, int &procHandle, int &thrHandle,
2362                            int stdin_fd, int stdout_fd, int stderr_fd);
2363
2364 /*
2365  * Create a new instance of the named process.  Read the symbols and start
2366  *   the program
2367  */
2368 process *ll_createProcess(const pdstring File, pdvector<pdstring> *argv,
2369                           pdvector<pdstring> *envp, const pdstring dir = "",
2370                           int stdin_fd=0, int stdout_fd=1, int stderr_fd=2)
2371 {
2372         // prepend the directory (if any) to the filename,
2373         // unless the filename is an absolute pathname
2374         // 
2375         // The filename is an absolute pathname if it starts with a '/' on UNIX,
2376         // or a letter and colon pair on Windows.
2377     
2378    pdstring file = File;
2379         if( dir.length() > 0 )
2380         {
2381 #if !defined(i386_unknown_nt4_0)
2382                 if( !file.prefixed_by("/") )
2383                 {
2384                         // file does not start  with a '/', so it is a relative pathname
2385                         // we modify it to prepend the given directory
2386                         if( dir.suffixed_by("/") )
2387                         {
2388                                 // the dir already has a trailing '/', so we can
2389                                 // just concatenate them to get an absolute path
2390                                 file = dir + file;
2391                         }
2392                         else
2393                         {
2394                                 // the dir does not have a trailing '/', so we must
2395                                 // add a '/' to get the absolute path
2396                                 file = dir + "/" + file;
2397                         }
2398                 }
2399                 else
2400                 {
2401                         // file starts with a '/', so it is an absolute pathname
2402                         // DO NOT prepend the directory, regardless of what the
2403                         // directory variable holds.
2404                         // nothing to do in this case
2405                 }
2406
2407 #else // !defined(i386_unknown_nt4_0)
2408                 if( (file.length() < 2) ||      // file is too short to be a drive specifier
2409                         !isalpha( file[0] ) ||  // first character in file is not a letter
2410                         (file[1] != ':') )              // second character in file is not a colon
2411                 {
2412                         file = dir + "\\" + file;
2413                 }
2414 #endif // !defined(i386_unknown_nt4_0)
2415         }
2416
2417 #if defined(BPATCH_LIBRARY) && !defined(BPATCH_REDIRECT_IO)
2418     pdstring inputFile;
2419     pdstring outputFile;
2420 #else
2421     // check for I/O redirection in arg list.
2422     pdstring inputFile;
2423     for (unsigned i1=0; i1<argv->size(); i1++) {
2424       if ((*argv)[i1] == "<") {
2425         inputFile = (*argv)[i1+1];
2426         for (unsigned j=i1+2, k=i1; j<argv->size(); j++, k++)
2427           (*argv)[k] = (*argv)[j];
2428         argv->resize(argv->size()-2);
2429       }
2430     }
2431     // TODO -- this assumes no more than 1 of each "<", ">"
2432     pdstring outputFile;
2433     for (unsigned i2=0; i2<argv->size(); i2++) {
2434       if ((*argv)[i2] == ">") {
2435         outputFile = (*argv)[i2+1];
2436         for (unsigned j=i2+2, k=i2; j<argv->size(); j++, k++)
2437           (*argv)[k] = (*argv)[j];
2438         argv->resize(argv->size()-2);
2439       }
2440     }
2441
2442
2443 #endif /* BPATCH_LIBRARY */
2444
2445     int traceLink = -1;
2446     //remove all ioLink related code for output redirection
2447     //int ioLink = stdout_fd;
2448
2449     int pid;
2450     int tid;
2451     // Ignored except on NT (where we modify in forkNewProcess, and ignore the result???)
2452     int procHandle_temp;
2453     int thrHandle_temp;
2454
2455 #ifndef BPATCH_LIBRARY
2456
2457     struct stat file_stat;
2458     int stat_result;
2459
2460     stat_result = stat(file.c_str(), &file_stat);
2461     
2462     if(stat_result == -1) {
2463         pdstring msg = pdstring("Can't read executable file ") + file + (": ") + strerror(errno);
2464         showErrorCallback(68, msg.c_str());
2465         return(NULL);
2466     }
2467
2468 #endif
2469
2470 #if defined (arch_ia64)
2471 //    BPatch::bpatch->eventHandler->stop();
2472 #endif
2473
2474     if (!forkNewProcess(file, dir, argv, envp, inputFile, outputFile,
2475                         traceLink, pid, tid, procHandle_temp, thrHandle_temp,
2476                         stdin_fd, stdout_fd, stderr_fd)) {
2477         // forkNewProcess is responsible for displaying error messages
2478         // Note: if the fork succeeds, but exec fails, forkNew...
2479         // will return true. 
2480         return NULL;
2481     }
2482
2483
2484 #ifdef BPATCH_LIBRARY
2485     // Register the pid with the BPatch library (not yet associated with a
2486     // BPatch_thread object).
2487     assert(BPatch::bpatch != NULL);
2488     BPatch::bpatch->registerProvisionalThread(pid);
2489 #endif
2490
2491 #if defined(i386_unknown_nt4_0)
2492     int status = procHandle_temp;
2493 #else
2494     int status = pid;
2495 #endif // defined(i386_unknown_nt4_0)
2496     
2497     // Get the file descriptor for the executable file
2498     // "true" value is for AIX -- waiting for an initial trap
2499     // it's ignored on other platforms
2500     fileDescriptor *desc = getExecFileDescriptor(file, status, true);
2501     if (!desc) {
2502         cerr << "Failed to find exec descriptor" << endl;
2503         return NULL;
2504     }
2505     // What a hack... getExecFileDescriptor waits for a trap
2506     // signal on AIX and returns the code in status. So we basically
2507     // have a pending TRAP that we need to handle, but not right
2508     // now.
2509 #if defined(rs6000_ibm_aix4_1)
2510     int fileDescSignal = status;
2511 #endif
2512
2513     image *img = image::parseImage(desc);
2514     if (!img) {
2515       // For better error reporting, two failure return values would be
2516       // useful.  One for simple error like because-file-not-because.
2517       // Another for serious errors like found-but-parsing-failed 
2518       //    (internal error; please report to paradyn@cs.wisc.edu)
2519       pdstring msg = pdstring("Unable to parse image: ") + file;
2520       showErrorCallback(68, msg.c_str());
2521       // destroy child process
2522       OS::osKill(pid);
2523       return(NULL);
2524     }
2525
2526     /* parent */
2527     statusLine("initializing process data structures");
2528
2529     process *theProc = new process(pid, img, traceLink);
2530     // change this to a ctor that takes in more args
2531     assert(theProc);
2532
2533     img->defineModules(theProc);
2534
2535 #ifdef mips_unknown_ce2_11 //ccw 27 july 2000 : 29 mar 2001
2536     //the MIPS instruction generator needs the Gp register value to
2537     //correctly calculate the jumps.  In order to get it there it needs
2538     //to be visible in Object-nt, and must be taken from process.
2539     void *cont;
2540     //DebugBreak();
2541     cont = theProc->GetRegisters(thrHandle_temp); //ccw 10 aug 2000 : ADD thrHandle HERE!
2542     img->getObjectNC().set_gp_value(((w32CONTEXT*) cont)->IntGp);
2543 #endif
2544     processVec.push_back(theProc);
2545     activeProcesses++;
2546
2547     // find the signal handler function
2548     theProc->findSignalHandler(); // should this be in the ctor?
2549
2550     // In the ST case, threads[0] (the only one) is effectively
2551     // a pass-through for process operations. In MT, it's the
2552     // main thread of the process and is handled correctly
2553
2554     theProc->createInitialThread();
2555
2556 #if defined(rs6000_ibm_aix3_2) \
2557  || defined(rs6000_ibm_aix4_1)
2558     // XXXX - this is a hack since getExecFileDescriptor needed to wait for
2559     //    the TRAP signal.
2560     // We really need to move most of the above code (esp parse image)
2561     //    to the TRAP signal handler.  The problem is that we don't
2562     //    know the base addresses until we get the load info via ptrace.
2563     //    In general it is even harder, since dynamic libs can be loaded
2564     //    at any time.
2565     procevent ev;
2566     ev.proc = theProc;
2567     ev.why  = procSignalled;
2568     ev.what = fileDescSignal;
2569     ev.info = 0;
2570     getSH()->handleProcessEvent(ev);    
2571 #endif
2572
2573     bool res = theProc->loadDyninstLib();
2574     if(res == false) {
2575         // Error message printout macro
2576         printLoadDyninstLibraryError();
2577         theProc->detachProcess(false);
2578         delete theProc;
2579         return NULL;
2580     }
2581
2582     while (!theProc->reachedBootstrapState(bootstrapped)) {
2583        // We're waiting for something... so wait
2584        // true: block until a signal is received (efficiency)
2585        if(theProc->hasExited()) {
2586            delete theProc;
2587           return NULL;
2588        }
2589
2590        getSH()->checkForAndHandleProcessEvents(true);
2591     }
2592
2593     if(process::IndependentLwpControl())
2594        theProc->independentLwpControlInit();
2595
2596 #if defined (arch_ia64)
2597 //    BPatch::bpatch->eventHandler->resume();
2598 #endif
2599     return theProc;    
2600 }
2601
2602
2603 process *ll_attachProcess(const pdstring &progpath, int pid) 
2604 {
2605   // implementation of dynRPC::attach() (the igen call)
2606   // This is meant to be "the other way" to start a process (competes w/ createProcess)
2607   
2608   // progpath gives the full path name of the executable, which we use ONLY to
2609   // read the symbol table.
2610   
2611   // We try to make progpath optional, since given pid, we should be able to
2612   // calculate it with a clever enough search of the process' PATH, examining
2613   // its argv[0], examining its current directory, etc.  /proc gives us this
2614   // information on solaris...not sure about other platforms...
2615
2616     // No longer take the afterAttach argument. Instead, the process object records
2617     // the state of the process at attach, and the user can read and act on this as
2618     // they please -- bernat, JAN03
2619
2620   attach_cerr << "welcome to attachProcess for pid " << pid << endl;
2621
2622   // QUESTION: When we attach to a process, do we want to redirect its stdout/stderr
2623   //           (like we do when we fork off a new process the 'usual' way)?
2624   //           My first guess would be no.  -ari
2625   //           But although we may ignore the io, we still need the trace stream.
2626   
2627   // When we attach to a process, we don't fork...so this routine is much
2628   // simpler than its "competitor", ll_createProcess() (above).
2629   pdstring fullPathToExecutable = process::tryToFindExecutable(progpath, pid);
2630
2631   if (!fullPathToExecutable.length()) {
2632       return NULL;
2633   }
2634
2635 #if defined(i386_unknown_nt4_0)
2636   int status = (int)INVALID_HANDLE_VALUE;       // indicates we need to obtain a valid handle
2637 #else
2638   int status = pid;
2639 #endif // defined(i386_unknown_nt4_0)
2640
2641   fileDescriptor *desc = getExecFileDescriptor(fullPathToExecutable,
2642                                                status, false);
2643   if (!desc) {
2644       return NULL;
2645   }
2646
2647   image *theImage = image::parseImage(desc);
2648
2649   if (theImage == NULL) {
2650     // two failure return values would be useful here, to differentiate
2651     // file-not-found vs. catastrophic-parse-error.
2652     pdstring msg = pdstring("Unable to parse image: ") + fullPathToExecutable;
2653     showErrorCallback(68, msg.c_str());
2654     return NULL;
2655   }
2656
2657   // NOTE: the actual attach happens in the process "attach" constructor:
2658   bool success=false;
2659   process *theProc = new process(pid, theImage, success);
2660   assert(theProc);
2661
2662   if (!success) {
2663     // XXX Do we need to do something to get rid of theImage, too?
2664     delete theProc;
2665     return NULL;
2666   }
2667
2668   // Note: it used to be that the attach ctor called pause()...not anymore...so
2669   // the process is probably running even as we speak.
2670   
2671   processVec.push_back(theProc);
2672   activeProcesses++;
2673
2674   theProc->createInitialThread();
2675
2676   theImage->defineModules(theProc);
2677
2678   // we now need to dynamically load libdyninstRT.so.1 - naim
2679   if (!theProc->pause()) {
2680     logLine("WARNING: pause failed\n");
2681     assert(0);
2682   }
2683
2684   // find the signal handler function
2685   theProc->findSignalHandler(); // shouldn't this be in the ctor?
2686
2687   if (!theProc->loadDyninstLib()) {
2688       printLoadDyninstLibraryError();
2689       delete theProc;
2690       return NULL;
2691   }
2692
2693   // The process is paused at this point. Run if appropriate.
2694
2695 #if defined(alpha_dec_osf4_0)
2696   // need to perform this after dyninst Heap is present and happy
2697
2698     // Actually, we need to perform this after DYNINSTinit() has
2699     // been invoked in the mutatee.  So, the following line was
2700     // moved to BPatch_thread.C.   RSC 08-26-2002
2701   //theProc->getDyn()->setMappingHooks(theProc);
2702 #endif
2703
2704   return theProc; // successful
2705 }
2706
2707
2708
2709
2710 /***************************************************************************
2711  **** Runtime library initialization code (Dyninst)                     ****
2712  ***************************************************************************/
2713
2714 /*
2715  * Gratuitously large comment. This diagrams the startup flow of 
2716  * messages between the mutator and mutatee. Entry points 
2717  * for create and attach process are both given.
2718  *     Mutator           Signal              Mutatee
2719  * Create:
2720  *     Fork/Exec
2721  *                     <-- Trap              Halted in exec
2722  *     Install trap in main             
2723  *                     <-- Trap              Halted in main
2724  *  Attach: (also paused, not in main)
2725  *     Install call to dlopen/
2726  *     LoadLibrary       
2727  *                     <-- Trap              In library load
2728  *     Set parameters in library
2729  *                     <-- Trap              Finished loading
2730  *     Restore code and leave paused
2731  *     Finalize library
2732  *       If finalizing fails, 
2733  *       init via iRPC
2734  */
2735
2736 /*
2737  * In all cases, the process is left paused at the entry of main
2738  * (create) or where it was (attach). No permanent instrumentation
2739  * is inserted.
2740  */
2741
2742 // Load and initialize the runtime library: returns when the RT lib
2743 // is both loaded and initialized.
2744 // Return val: false=error condition
2745
2746 bool process::loadDyninstLib() {
2747
2748     // Wait for the process to get to an initialized (dlopen exists)
2749     // state
2750     while (!reachedBootstrapState(initialized)) {
2751        if(hasExited()) {
2752            cerr << "Process exited" << endl;
2753            return false;
2754        }
2755        getSH()->checkForAndHandleProcessEvents(true);
2756     }
2757     assert (isStopped());
2758
2759     // We've hit the initialization trap, so load dyninst lib and
2760     // force initialization
2761     pdstring buffer = pdstring("PID=") + pdstring(pid);
2762     buffer += pdstring(", initializing shared objects");       
2763     statusLine(buffer.c_str());
2764
2765     // Perform initialization...
2766     if (!dyn->initialize()) 
2767     {
2768        cerr << "Dyninst was unable to load the dyninst runtime library "
2769             << "into the application.  This may be caused by statically "
2770             << "linked executables, or by having dyninst linked against a "
2771             << "different version of libelf than it was built with." << endl;
2772        return false;
2773     }
2774
2775     // And get the list of all shared objects in the process. More properly,
2776     // get the address of dlopen.
2777     if (!getSharedObjects()) assert (0 && "Failed to get shared objects in initialization");
2778
2779     if (dyninstLibAlreadyLoaded()) {
2780         logLine("ERROR: dyninst library already loaded, we missed initialization!");
2781         assert(0);
2782     }
2783     
2784     if (!getDyninstRTLibName()) return false;
2785     
2786     // Set up a callback to be run when dyninst lib is loaded
2787     // Windows has some odd naming problems, so we only use the root
2788 #if defined(i386_unknown_nt4_0)
2789     char dllFilename[_MAX_FNAME];
2790     _splitpath( dyninstRT_name.c_str(),
2791                 NULL, NULL, dllFilename, NULL);
2792     
2793     registerLoadLibraryCallback(pdstring(dllFilename), dyninstLibLoadCallback, NULL);
2794 #else
2795     registerLoadLibraryCallback(dyninstRT_name, dyninstLibLoadCallback, NULL);
2796 #endif // defined(i386_unknown_nt4_0)
2797     
2798     // Force a call to dlopen(dyninst_lib)
2799     buffer = pdstring("PID=") + pdstring(pid);
2800     buffer += pdstring(", loading dyninst library");       
2801     statusLine(buffer.c_str());
2802     loadDYNINSTlib();
2803     setBootstrapState(loadingRT);
2804     
2805     if (!continueProc()) {
2806         assert(0);
2807     }
2808
2809     // Loop until the dyninst lib is loaded
2810     while (!reachedBootstrapState(loadedRT)) {
2811         if(hasExited()) {
2812             cerr << "Process exited" << endl;
2813             return false;
2814         }
2815         getSH()->checkForAndHandleProcessEvents(true);
2816     }
2817
2818     // We haven't inserted a trap at dlopen yet (as we require the runtime lib for that)
2819     // So re-check all loaded libraries (and add to the list gotten earlier)
2820     // We force a compare even though the PC is not at the correct address.
2821     dyn->set_force_library_check();
2822     handleIfDueToSharedObjectMapping();
2823     dyn->unset_force_library_check();
2824
2825     // Make sure the library was actually loaded
2826     if (!runtime_lib) {
2827         cerr << "Don't have runtime library handle" << endl;
2828         return false;
2829     }
2830     
2831
2832     // Get rid of the callback
2833     unregisterLoadLibraryCallback(dyninstRT_name);
2834
2835     buffer = pdstring("PID=") + pdstring(pid);
2836     buffer += pdstring(", initializing mutator-side structures");
2837     statusLine(buffer.c_str());    
2838
2839     // The following calls depend on the RT library being parsed,
2840     // but not on dyninstInit being run
2841     initInferiorHeap();
2842     // This must be done after the inferior heap is initialized
2843     initTrampGuard();
2844     extern pdvector<sym_data> syms_to_find;
2845     if (!heapIsOk(syms_to_find)) {
2846         bperr( "heap not okay\n");
2847         return false;
2848     }
2849     
2850     // The library is loaded, so do mutator-side initialization
2851     buffer = pdstring("PID=") + pdstring(pid);
2852     buffer += pdstring(", finalizing RT library");
2853     statusLine(buffer.c_str());    
2854     int result = finalizeDyninstLib();
2855
2856     if (!result) {
2857         // For some reason we haven't run dyninstInit successfully.
2858         // Probably because we didn't set parameters before 
2859         // dyninstInit was automatically run. Catchup with
2860         // an inferiorRPC is the best bet.
2861         buffer = pdstring("PID=") + pdstring(pid);
2862         buffer += pdstring(", finalizing library via inferior RPC");
2863         statusLine(buffer.c_str());    
2864         iRPCDyninstInit();
2865         
2866     }
2867     
2868     buffer = pdstring("PID=") + pdstring(pid);
2869     buffer += pdstring(", dyninst RT lib ready");
2870     statusLine(buffer.c_str());    
2871
2872     return true;
2873 }
2874
2875 // Set the shared object mapping for the RT library
2876 bool process::setDyninstLibPtr(shared_object *RTobj) {
2877     assert (!runtime_lib);
2878     
2879     runtime_lib = RTobj;
2880     return true;
2881 }
2882
2883
2884 // Set up the parameters for DYNINSTinit in the RT lib
2885
2886 bool process::setDyninstLibInitParams() {
2887
2888    attach_cerr << "process::setDYNINSTinitArguments()" << endl;
2889
2890    int pid = getpid();
2891    
2892    // Cause: 
2893    // 1 = created
2894    // 2 = forked
2895    // 3 = attached
2896    
2897    int cause;
2898    if (createdViaAttach) {
2899        cause = 3; 
2900    }
2901    else if (createdViaFork) {
2902        cause = 2;
2903    }
2904    
2905    else 
2906        cause = 1;
2907    
2908    // Now we write these variables into the following global vrbles
2909    // in the dyninst library:
2910    // libdyninstAPI_RT_init_localCause
2911    // libdyninstAPI_RT_init_localPid
2912
2913    Symbol causeSym;
2914    if (!getSymbolInfo("libdyninstAPI_RT_init_localCause", causeSym))
2915        if (!getSymbolInfo("_libdyninstAPI_RT_init_localCause", causeSym))
2916            assert(0 && "Could not find symbol libdyninstAPI_RT_init_localCause");
2917    assert(causeSym.type() != Symbol::PDST_FUNCTION);
2918    writeDataSpace((void*)causeSym.addr(), sizeof(int), (void *)&cause);
2919    
2920    Symbol pidSym;
2921    if (!getSymbolInfo("libdyninstAPI_RT_init_localPid", pidSym))
2922        if (!getSymbolInfo("_libdyninstAPI_RT_init_localPid", pidSym))
2923            assert(0 && "Could not find symbol libdyninstAPI_RT_init_localPid");
2924    assert(pidSym.type() != Symbol::PDST_FUNCTION);
2925    writeDataSpace((void*)pidSym.addr(), sizeof(int), (void *)&pid);
2926    
2927    attach_cerr << "process::installBootstrapInst() complete" << endl;
2928    
2929    return true;
2930 }
2931
2932 // Callback for the above
2933 void process::dyninstLibLoadCallback(process *p, pdstring /*ignored*/, shared_object *libobj, void * /*ignored*/) {
2934     p->setDyninstLibPtr(libobj);
2935     p->setDyninstLibInitParams();
2936 }
2937
2938 // Call DYNINSTinit via an inferiorRPC
2939 bool process::iRPCDyninstInit() {
2940     // Duplicates the parameter code in setDyninstLibInitParams()
2941     int cause;
2942     int pid = getpid();
2943
2944     if (createdViaAttach)
2945         cause = 3;
2946     else if (createdViaFork)
2947         cause = 2;
2948     else 
2949         cause = 1;
2950
2951     pdvector<AstNode*> the_args(2);
2952     the_args[0] = new AstNode(AstNode::Constant, (void*)(Address)cause);
2953     the_args[1] = new AstNode(AstNode::Constant, (void*)(Address)pid);
2954     AstNode *dynInit = new AstNode("DYNINSTinit", the_args);
2955     removeAst(the_args[0]); removeAst(the_args[1]);
2956     getRpcMgr()->postRPCtoDo(dynInit,
2957                              true, // Don't update cost
2958                              process::DYNINSTinitCompletionCallback,
2959                              NULL, // No user data
2960                              true, // Use reserved memory
2961                              NULL, NULL);// No particular thread or LWP
2962
2963     // We loop until dyninst init has run (check via the callback)
2964     while (!reachedBootstrapState(bootstrapped)) {
2965         getRpcMgr()->launchRPCs(false); // false: not running
2966         if(hasExited())
2967            return false;
2968         getSH()->checkForAndHandleProcessEvents(true);
2969     }
2970     return true;
2971 }
2972
2973 bool process::attach() {
2974    dictionary_hash_iter<unsigned, dyn_lwp *> lwp_iter(real_lwps);
2975    dyn_lwp *lwp;
2976    unsigned index;
2977    assert(getRepresentativeLWP());  // we expect this to be defined
2978    // Though on linux, if process found to be MT, there will be no
2979    // representativeLWP since there is no lwp which controls the entire
2980    // process for MT linux.
2981
2982    if(! getRepresentativeLWP()->attach())
2983       return false;
2984
2985    while (lwp_iter.next(index, lwp)) {
2986       if (!lwp->attach()) {
2987          deleteLWP(lwp);
2988          return false;
2989       }
2990    }
2991    return setProcessFlags();
2992 }
2993
2994 void process::DYNINSTinitCompletionCallback(process* theProc,
2995                                             unsigned /* rpc_id */,
2996                                             void* /*userData*/, // user data
2997                                             void* /*ret*/) // return value from DYNINSTinit
2998 {
2999     theProc->finalizeDyninstLib();
3000 }
3001
3002 // Callback: finish mutator-side processing for dyninst lib
3003
3004 bool process::finalizeDyninstLib() {
3005     assert (isStopped());
3006    if (reachedBootstrapState(bootstrapped)) {
3007        return true;
3008    }
3009
3010    DYNINST_bootstrapStruct bs_record;
3011    if (!extractBootstrapStruct(&bs_record))
3012       assert(false);
3013
3014    // Read the structure; if event 0 then it's undefined! (not yet written)
3015    if (bs_record.event == 0){
3016        return false;
3017    }
3018
3019    // Now that we have the dyninst library loaded, insert the hooks to dlopen/dlclose
3020    // (which may require the dyninst library)
3021
3022    // Set breakpoints to detect (un)loaded libraries
3023    if (!dyn->installTracing()) assert (0 && "Failed to install library mapping hooks");
3024     
3025    assert(bs_record.event == 1 || bs_record.event == 2 || bs_record.event==3);
3026
3027    bool calledFromFork = (bs_record.event == 2);
3028    bool calledFromAttach = (bs_record.event == 3);
3029
3030    // Get the address of the observed cost slot
3031    internalSym obsCostSym;
3032    bool foundCostAddr = findInternalSymbol("DYNINSTobsCostLow", true, obsCostSym);
3033    assert(foundCostAddr);
3034    costAddr_ = obsCostSym.getAddr();
3035    assert(costAddr_);
3036
3037    if (!calledFromFork) {
3038
3039        // Install initial instrumentation requests
3040        pdstring str=pdstring("PID=") + pdstring(bs_record.pid) + ", installing default (DYNINST) inst...";
3041        statusLine(str.c_str());
3042        
3043        extern pdvector<instMapping*> initialRequests; // init.C
3044
3045        // Install any global instrumentation requests
3046        installInstrRequests(initialRequests);
3047
3048        // Install process-specific instrumentation requests
3049        installInstrRequests(tracingRequests);
3050        
3051        // Install our system call tracing
3052        tracedSyscalls_ = new syscallNotification(this);
3053
3054        //#ifdef i386_unknown_linux2_0
3055        //if(pdFlavor != "mpi") {
3056        //#endif
3057           // TODO: prefork and pre-exit should depend on whether a callback is defined
3058           if (!tracedSyscalls_->installPreFork()) 
3059              cerr << "Warning: failed pre-fork notification setup" << endl;
3060           if (!tracedSyscalls_->installPostFork()) 
3061              cerr << "Warning: failed post-fork notification setup" << endl;
3062           if (!tracedSyscalls_->installPreExec()) 
3063              cerr << "Warning: failed pre-exec notification setup" << endl;
3064           if (!tracedSyscalls_->installPostExec()) 
3065              cerr << "Warning: failed post-exec notification setup" << endl;
3066           if (!tracedSyscalls_->installPreExit()) 
3067              cerr << "Warning: failed pre-exit notification setup" << endl;
3068           //#ifdef i386_unknown_linux2_0
3069           //}
3070           //#endif
3071    }
3072    else { // called from a forking process
3073        process *parentProcess = process::findProcess(bs_record.ppid);
3074        if (parentProcess) {
3075            if (parentProcess->status() == stopped) {
3076                if (!parentProcess->continueProc())
3077                    assert(false);
3078            }
3079            else
3080                parentProcess->continueAfterNextStop();
3081        }
3082        
3083    }
3084    
3085    if (!calledFromAttach) {
3086        pdstring str=pdstring("PID=") + pdstring(bs_record.pid) + ", dyninst ready.";
3087        statusLine(str.c_str());
3088    }
3089
3090    // Ready to rock
3091    setBootstrapState(bootstrapped);
3092    
3093    if (wasExeced()) {
3094        BPatch::bpatch->registerExec(bpatch_thread);
3095    }
3096    
3097    return true;
3098 }
3099
3100 dyn_thread *process::STdyn_thread() { 
3101    assert(! multithread_capable());
3102    assert(threads.size()>0);
3103    return threads[0];
3104 }
3105
3106 /*
3107  * This function is needed in the unique case where we want to 
3108  * attach to an application which has been previously stopped
3109  * in the exec() system call as in the normal case (createProcess).
3110  * In this particular case, the SIGTRAP due to the exec() has been 
3111  * previously caught by another process, therefore we should taking into
3112  * account this issue in the necessary platforms. 
3113  * Basically, is an hybrid case between addprocess() and attachProcess().
3114  * 
3115  */
3116
3117 bool AttachToCreatedProcess(int pid,const pdstring &progpath)
3118 {
3119
3120
3121     int traceLink = -1;
3122
3123     pdstring fullPathToExecutable = process::tryToFindExecutable(progpath, pid);
3124     
3125     if (!fullPathToExecutable.length()) {
3126       return false;
3127     }  
3128
3129 #ifdef BPATCH_LIBRARY
3130     // Register the pid with the BPatch library (not yet associated with a
3131     // BPatch_thread object).
3132     assert(BPatch::bpatch != NULL);
3133     BPatch::bpatch->registerProvisionalThread(pid);
3134 #endif
3135
3136     int status = pid;
3137     
3138     // Get the file descriptor for the executable file
3139     // "true" value is for AIX -- waiting for an initial trap
3140     // it's ignored on other platforms
3141     fileDescriptor *desc = 
3142         getExecFileDescriptor(fullPathToExecutable, status, true);
3143     // What a hack... getExecFileDescriptor waits for a trap
3144     // signal on AIX and returns the code in status. So we basically
3145     // have a pending TRAP that we need to handle, but not right
3146     // now.
3147 #if defined(rs6000_ibm_aix4_1)
3148     int fileDescSignal = status;
3149 #endif 
3150
3151     if (!desc) {
3152       return false;
3153     }
3154
3155 #ifndef BPATCH_LIBRARY
3156
3157 // We bump up batch mode here; the matching bump-down occurs after 
3158 // shared objects are processed (after receiving the SIGSTOP indicating
3159 // the end of running DYNINSTinit; more specifically, 
3160 // finalizeDyninstInit(). Prevents a diabolical w/w deadlock on 
3161 // solaris --ari
3162     tp->resourceBatchMode(true);
3163
3164 #endif
3165
3166     image *img = image::parseImage(desc);
3167
3168     if (img==NULL) {
3169
3170         // For better error reporting, two failure return values would be
3171         // useful.  One for simple error like because-file-not-because.
3172         // Another for serious errors like found-but-parsing-failed 
3173         //    (internal error; please report to paradyn@cs.wisc.edu)
3174
3175         pdstring msg = pdstring("Unable to parse image: ") + fullPathToExecutable;
3176         showErrorCallback(68, msg.c_str());
3177         // destroy child process
3178         OS::osKill(pid);
3179         return(false);
3180     }
3181
3182     /* parent */
3183     statusLine("initializing process data structures");
3184
3185     // The same process ctro. is used as in the "normal" case but
3186     // here, traceLink is -1 instead of a positive value.
3187     process *ret = new process(pid, img, traceLink);
3188
3189     assert(ret);
3190
3191     img->defineModules(ret);
3192
3193 #ifdef mips_unknown_ce2_11 //ccw 27 july 2000 : 29 mar 2001
3194
3195     //the MIPS instruction generator needs the Gp register value to
3196     //correctly calculate the jumps.  In order to get it there it needs
3197     //to be visible in Object-nt, and must be taken from process.
3198     void *cont;
3199     //DebugBreak();
3200     //ccw 10 aug 2000 : ADD thrHandle HERE
3201     
3202     cont = ret->GetRegisters(thrHandle_temp);
3203
3204     img->getObjectNC().set_gp_value(((w32CONTEXT*) cont)->IntGp);
3205 #endif
3206
3207     processVec.push_back(ret);
3208     activeProcesses++;
3209
3210 #ifndef BPATCH_LIBRARY
3211     if (!costMetric::addProcessToAll(ret)) {
3212         assert(false);
3213     }
3214 #endif
3215
3216     // find the signal handler function
3217     ret->findSignalHandler(); // should this be in the ctor?
3218
3219     // initializing vector of threads - thread[0] is really the 
3220     // same process
3221
3222     ret->createInitialThread();
3223
3224     // initializing hash table for threads. This table maps threads to
3225     // positions in the superTable - naim 4/14/97
3226
3227 #if defined(rs6000_ibm_aix3_2) \
3228  || defined(rs6000_ibm_aix4_1)
3229     // XXXX - this is a hack since getExecFileDescriptor needed to wait for
3230     //        the TRAP signal.
3231     // We really need to move most of the above code (esp parse image)
3232     // to the TRAP signal handler.  The problem is that we don't
3233     // know the base addresses until we get the load info via ptrace.
3234     // In general it is even harder, since dynamic libs can be loaded
3235     // at any time.
3236     procevent ev;
3237     ev.proc = ret;
3238     ev.why  = procSignalled;
3239     ev.what = fileDescSignal;
3240     ev.info = 0;
3241     getSH()->handleProcessEvent(ev);
3242 #endif
3243     
3244     return(true);
3245
3246 } // end of AttachToCreatedProcess
3247
3248
3249 #if !defined(BPATCH_LIBRARY)
3250 void process::processCost(unsigned obsCostLow,
3251                           timeStamp wallTime,
3252                           timeStamp processTime) {
3253   // wallTime and processTime should compare to DYNINSTgetWallTime() and
3254   // DYNINSTgetCPUtime().
3255
3256   // check for overflow, add to running total, convert cycles to seconds, and
3257   // report.  Member vrbles of class process: lastObsCostLow and cumObsCost
3258   // (the latter a 64-bit value).
3259
3260   // code to handle overflow used to be in rtinst; we borrow it pretty much
3261   // verbatim. (see rtinst/RTposix.c)
3262   if (obsCostLow < lastObsCostLow) {
3263     // we have a wraparound
3264     cumObsCost += ((unsigned)0xffffffff - lastObsCostLow) + obsCostLow + 1;
3265   }
3266   else
3267     cumObsCost += (obsCostLow - lastObsCostLow);
3268   
3269   lastObsCostLow = obsCostLow;
3270   //  sampleVal_cerr << "processCost- cumObsCost: " << cumObsCost << "\n"; 
3271   timeLength observedCost(cumObsCost, getCyclesPerSecond());
3272   // timeUnit tu = getCyclesPerSecond(); // just used to print out
3273   //  sampleVal_cerr << "processCost: cyclesPerSecond=" << tu
3274   //             << "; cum obs cost=" << observedCost << "\n";
3275   
3276   // Notice how most of the rest of this is copied from processCost() of
3277   // metric.C.  Be sure to keep the two "in sync"!
3278
3279   extern costMetric *totalPredictedCost; // init.C
3280   extern costMetric *observed_cost;      // init.C
3281   
3282   const timeStamp lastProcessTime = 
3283     totalPredictedCost->getLastSampleProcessTime(this);
3284   //  sampleVal_cerr << "processCost- lastProcessTime: " <<lastProcessTime << "\n";
3285   // find the portion of uninstrumented time for this interval
3286   timeLength userPredCost = timeLength::sec() + getCurrentPredictedCost();
3287   //  sampleVal_cerr << "processCost- userPredCost: " << userPredCost << "\n";
3288   const double unInstTime = (processTime - lastProcessTime) / userPredCost; 
3289   //  sampleVal_cerr << "processCost- unInstTime: " << unInstTime << "\n";
3290   // update predicted cost
3291   // note: currentPredictedCost is the same for all processes
3292   //       this should be changed to be computed on a per process basis
3293   pdSample newPredCost = totalPredictedCost->getCumulativeValue(this);
3294   //  sampleVal_cerr << "processCost- newPredCost: " << newPredCost << "\n";
3295   timeLength tempPredCost = getCurrentPredictedCost() * unInstTime;
3296   //  sampleVal_cerr << "processCost- tempPredCost: " << tempPredCost << "\n";
3297   newPredCost += pdSample(tempPredCost.getI(timeUnit::ns()));
3298   //  sampleVal_cerr << "processCost- tempPredCost: " << newPredCost << "\n";
3299   totalPredictedCost->updateValue(this, wallTime, newPredCost, processTime);
3300   // update observed cost
3301   pdSample sObsCost(observedCost);
3302   observed_cost->updateValue(this, wallTime, sObsCost, processTime);
3303 }
3304 #endif
3305         
3306 // If true is passed for ignore_if_mt_not_set, then an error won't be
3307 // initiated if we're unable to determine if the program is multi-threaded.
3308 // We are unable to determine this if the daemon hasn't yet figured out what
3309 // libraries are linked against the application.  Currently, we identify an
3310 // application as being multi-threaded if it is linked against a thread
3311 // library (eg. libpthreads.a on AIX).  There are cases where we are querying
3312 // whether the app is multi-threaded, but it can't be determined yet but it
3313 // also isn't necessary to know.
3314 #if defined( BPATCH_LIBRARY ) || defined( ia64_unknown_linux2_4 )
3315 bool process::multithread_capable(bool) { return false; }
3316 #else
3317 bool process::multithread_capable(bool ignore_if_mt_not_set)
3318 {
3319    if(cached_result != not_cached) {
3320       if(cached_result == cached_mt_true) {
3321          return true;
3322       } else {
3323          assert(cached_result == cached_mt_false);
3324          return false;
3325       }
3326    }
3327
3328    if(!symbols || !shared_objects) {
3329       if(! ignore_if_mt_not_set) {
3330          cerr << "   can't query MT state, assert\n";
3331          assert(false);
3332       }
3333       return false;
3334    }
3335
3336    if(findModule("libthread.so.1") ||  // Solaris
3337       findModule("libpthreads.a")  ||  // AIX
3338       findModule("libpthread.so.0"))   // Linux
3339    {
3340       cached_result = cached_mt_true;
3341       return true;
3342    } else {
3343       cached_result = cached_mt_false;
3344       return false;
3345    }
3346 }
3347 #endif
3348
3349 dyn_lwp *process::query_for_stopped_lwp() {
3350    dyn_lwp *foundLWP = NULL;
3351    dictionary_hash_iter<unsigned, dyn_lwp *> lwp_iter(real_lwps);
3352    dyn_lwp *lwp;
3353    unsigned index;
3354
3355    if(IndependentLwpControl()) {
3356       while (lwp_iter.next(index, lwp)) {
3357          if(lwp->status() == stopped || lwp->status() == neonatal) {
3358             foundLWP = lwp;
3359             break;
3360          }
3361       }
3362       if(foundLWP == NULL  &&  getRepresentativeLWP() != NULL)
3363          if(getRepresentativeLWP()->status() == stopped ||
3364             getRepresentativeLWP()->status() == neonatal)
3365             foundLWP = getRepresentativeLWP();
3366    } else {
3367       if(this->status() == stopped || this->status() == neonatal) {
3368          foundLWP = getRepresentativeLWP();
3369       }
3370    }
3371
3372    return foundLWP;
3373 }
3374
3375 // first searches for stopped lwp and if not found explicitly stops an lwp
3376 dyn_lwp *process::stop_an_lwp(bool *wasRunning) {
3377    dictionary_hash_iter<unsigned, dyn_lwp *> lwp_iter(real_lwps);
3378    dyn_lwp *lwp;
3379    dyn_lwp *stopped_lwp = NULL;
3380    unsigned index;
3381
3382    if(IndependentLwpControl()) {
3383       while(lwp_iter.next(index, lwp)) {
3384          if(lwp->status() == stopped) {
3385             stopped_lwp = lwp;
3386             *wasRunning = false;
3387             break;
3388          }
3389          if(lwp->pauseLWP()) {
3390             stopped_lwp = lwp;
3391             *wasRunning = true;
3392             break;
3393          }
3394       }
3395       if(stopped_lwp == NULL) {
3396          if(getRepresentativeLWP()->status() == stopped) {
3397             *wasRunning = false;
3398          } else {
3399             getRepresentativeLWP()->pauseLWP();
3400             *wasRunning = true;
3401          }
3402          stopped_lwp = getRepresentativeLWP();
3403       }
3404    } else {
3405       if(getRepresentativeLWP()->status() == stopped)
3406          *wasRunning = false;
3407       else {
3408          getRepresentativeLWP()->pauseLWP();
3409          *wasRunning = true;
3410       }
3411       stopped_lwp = getRepresentativeLWP();
3412    }
3413
3414    return stopped_lwp;
3415 }
3416
3417 bool process::terminateProc() {
3418    if(status() == exited) {
3419      // "Sure, we terminated it... really!"
3420      return true;
3421    }
3422    terminateProcStatus_t retVal = terminateProc_();
3423
3424    switch (retVal) {
3425    case terminateSucceeded:
3426      // handle the kill signal on the process, which will dispatch exit callback
3427      getSH()->checkForAndHandleProcessEvents(true);
3428      return true;
3429      break;
3430    case alreadyTerminated:
3431      // don't try to consume a signal (since we can't), 
3432      // just set process status to exited
3433      set_status(exited);
3434      return true;
3435      break;
3436    case terminateFailed:
3437      return false;
3438      break;
3439
3440    }
3441    assert (0 && "Can't be reached");
3442    return false;
3443 }
3444
3445 /*
3446  * Copy data from controller process to the named process.
3447  */
3448 bool process::writeDataSpace(void *inTracedProcess, unsigned size,
3449                              const void *inSelf) {
3450    bool needToCont = false;
3451
3452    if (!isAttached()) return false;
3453
3454    dyn_lwp *stopped_lwp = query_for_stopped_lwp();
3455    if(stopped_lwp == NULL) {
3456       stopped_lwp = stop_an_lwp(&needToCont);
3457       if(stopped_lwp == NULL) {
3458          pdstring msg =
3459             pdstring("System error: unable to write to process data "
3460                      "space (WDS): couldn't stop an lwp\n");
3461          showErrorCallback(38, msg);
3462          return false;
3463       }
3464    }
3465    
3466    bool res = stopped_lwp->writeDataSpace(inTracedProcess, size, inSelf);
3467    if (!res) {
3468       pdstring msg = pdstring("System error: unable to write to process data "
3469                               "space (WDS):") + pdstring(strerror(errno));
3470       showErrorCallback(38, msg);
3471       return false;
3472    }
3473
3474    if(needToCont) {
3475       return stopped_lwp->continueLWP();
3476    }
3477    return true;
3478 }
3479
3480 bool process::readDataSpace(const void *inTracedProcess, unsigned size,
3481                             void *inSelf, bool displayErrMsg) {
3482    bool needToCont = false;
3483
3484    if (!isAttached()) return false;
3485
3486    dyn_lwp *stopped_lwp = query_for_stopped_lwp();
3487    if(stopped_lwp == NULL) {
3488       stopped_lwp = stop_an_lwp(&needToCont);
3489       if(stopped_lwp == NULL) {
3490          pdstring msg =
3491             pdstring("System error: unable to read to process data "
3492                      "space: couldn't stop an lwp\n");
3493          showErrorCallback(38, msg);
3494          return false;
3495       }
3496    }
3497
3498    bool res = stopped_lwp->readDataSpace(inTracedProcess, size, inSelf);
3499    if (!res) {
3500       if (displayErrMsg) {
3501          sprintf(errorLine, "System error: "
3502                  "<>unable to read %d@%s from process data space: %s (pid=%d)",
3503                  size, Address_str((Address)inTracedProcess), 
3504                  strerror(errno), getPid());
3505          pdstring msg(errorLine);
3506          showErrorCallback(38, msg);
3507       }
3508       return false;
3509    }
3510
3511    if (needToCont) {
3512       return stopped_lwp->continueLWP();
3513    }
3514
3515    return true;
3516 }
3517
3518 bool process::writeTextWord(caddr_t inTracedProcess, int data) {
3519    bool needToCont = false;
3520
3521    if (!isAttached()) return false;
3522
3523    dyn_lwp *stopped_lwp = query_for_stopped_lwp();
3524    if(stopped_lwp == NULL) {
3525       stopped_lwp = stop_an_lwp(&needToCont);
3526       if(stopped_lwp == NULL) {
3527          pdstring msg =
3528             pdstring("System error: unable to write word to process text "
3529                      "space: couldn't stop an lwp\n");
3530          showErrorCallback(38, msg);
3531          return false;
3532       }
3533    }
3534
3535 #ifdef BPATCH_SET_MUTATIONS_ACTIVE
3536   if (!isAddrInHeap((Address)inTracedProcess)) {
3537     if (!saveOriginalInstructions((Address)inTracedProcess, sizeof(int)))
3538         return false;
3539     afterMutationList.insertTail((Address)inTracedProcess, sizeof(int), &data);
3540   }
3541 #endif
3542
3543   bool res = stopped_lwp->writeTextWord(inTracedProcess, data);
3544   if (!res) {
3545      pdstring msg = pdstring("System error: unable to write word to process "
3546                              "text space:") + pdstring(strerror(errno));
3547      showErrorCallback(38, msg);
3548      return false;
3549   }
3550
3551   if(needToCont) {
3552      return stopped_lwp->continueLWP();
3553   }
3554   return true;
3555 }
3556
3557 bool process::writeTextSpace(void *inTracedProcess, u_int amount, 
3558                              const void *inSelf) {
3559    bool needToCont = false;
3560
3561    if (!isAttached()) return false;
3562    dyn_lwp *stopped_lwp = query_for_stopped_lwp();
3563    if(stopped_lwp == NULL) {
3564       stopped_lwp = stop_an_lwp(&needToCont);
3565       if(stopped_lwp == NULL) {
3566          pdstring msg =
3567             pdstring("System error: unable to write to process text "
3568                      "space (WTS): couldn't stop an lwp\n");
3569          showErrorCallback(38, msg);
3570          return false;
3571       }
3572    }
3573
3574 #ifdef BPATCH_SET_MUTATIONS_ACTIVE
3575   if (!isAddrInHeap((Address)inTracedProcess)) {
3576     if (!saveOriginalInstructions((Address)inTracedProcess, amount))
3577         return false;
3578     afterMutationList.insertTail((Address)inTracedProcess, amount, inSelf);
3579   }
3580 #endif
3581
3582   bool res = stopped_lwp->writeTextSpace(inTracedProcess, amount, inSelf);
3583
3584   if (!res) {
3585      pdstring msg = pdstring("System error: unable to write to process text "
3586                              "space (WTS):") + pdstring(strerror(errno));
3587      showErrorCallback(38, msg);
3588      return false;
3589   }
3590   
3591   if(needToCont) {
3592      return stopped_lwp->continueLWP();
3593   }
3594   return true;
3595 }
3596
3597 // InsrucIter uses readTextSpace
3598 //#ifdef BPATCH_SET_MUTATIONS_ACTIVE
3599 bool process::readTextSpace(const void *inTracedProcess, u_int amount,
3600                             const void *inSelf)
3601 {
3602    bool needToCont = false;
3603
3604    if (!isAttached()) return false;
3605
3606    dyn_lwp *stopped_lwp = query_for_stopped_lwp();
3607    if(stopped_lwp == NULL) {
3608       stopped_lwp = stop_an_lwp(&needToCont);
3609       if(stopped_lwp == NULL) {
3610          pdstring msg =
3611             pdstring("System error: unable to read to process text "
3612                      "space: couldn't stop an lwp\n");
3613          showErrorCallback(39, msg);
3614          return false;
3615       }
3616    }
3617
3618    bool res = stopped_lwp->readTextSpace(const_cast<void*>(inTracedProcess),
3619                                          amount, inSelf);
3620
3621    if (!res) {
3622       sprintf(errorLine, "System error: "
3623               "<>unable to read %d@%s from process text space: %s (pid=%d)",
3624               amount, Address_str((Address)inTracedProcess), 
3625               strerror(errno), getPid());
3626       pdstring msg(errorLine);
3627       showErrorCallback(38, msg);
3628       return false;
3629    }
3630
3631    if (needToCont) {
3632       return stopped_lwp->continueLWP();
3633    }
3634
3635    return true;
3636 }
3637 //#endif /* BPATCH_SET_MUTATIONS_ACTIVE */
3638
3639 void process::clearProcessEvents() {
3640    // first coded for Solaris, trying it out on other platforms
3641
3642    // Make sure process isn't already stopped from an event. If it is,
3643    // handle the event.  An example where this happens is if the process is
3644    // stopped at a trap that signals the end of an rpc.  The loop is because
3645    // there are actually 2 successive traps at the end of an rpc.
3646    bool gotEvent = false;
3647    do {
3648       pdvector<procevent *> foundEvents;
3649       int timeout = 0;
3650       gotEvent = getSH()->checkForProcessEvents(&foundEvents, getPid(), timeout);
3651       getSH()->handleProcessEvents(foundEvents);
3652    } while(gotEvent == true);  // keep checking if we handled an event
3653 }
3654
3655 void process::set_status(processState st) {
3656    // update the process status
3657    status_ = st;
3658
3659    pdvector<dyn_thread *>::iterator iter = threads.begin();
3660    
3661    dyn_lwp *proclwp = getRepresentativeLWP();
3662    if(proclwp) proclwp->internal_lwp_set_status___(st);
3663    
3664    while(iter != threads.end()) {
3665       dyn_thread *thr = *(iter);
3666       dyn_lwp *lwp = thr->get_lwp();
3667       assert(lwp);
3668       lwp->internal_lwp_set_status___(st);
3669       iter++;
3670    }
3671 }
3672
3673 void process::set_lwp_status(dyn_lwp *whichLWP, processState lwp_st) {
3674    // any lwp status = stopped, means proc status = stopped
3675
3676    assert(whichLWP != NULL);
3677
3678    // update the process status
3679    if(lwp_st == stopped)
3680       status_ = stopped;
3681
3682    whichLWP->internal_lwp_set_status___(lwp_st);
3683
3684    if(IndependentLwpControl()) {
3685       // all lwp status = running, means proc status = running
3686       bool stopped_lwp_exists = false;
3687       pdvector<dyn_thread *>::iterator iter = threads.begin();
3688       if(lwp_st == running) {
3689          while(iter != threads.end()) {
3690             dyn_thread *thr = *(iter);
3691             dyn_lwp *lwp = thr->get_lwp();
3692             assert(lwp);
3693             if(lwp->status() == stopped)
3694                stopped_lwp_exists = true;
3695             iter++;
3696          }
3697       }
3698       if(!stopped_lwp_exists && lwp_st==running)
3699          status_ = running;
3700    } else {
3701       // if can't do independent lwp control, should only be able to set
3702       // lwp status for representative lwp
3703       assert(whichLWP == getRepresentativeLWP());
3704       set_status(lwp_st);  // sets process status and all lwp statuses
3705    }
3706 }
3707
3708 void process::clearCachedRegister() {
3709    pdvector<dyn_thread *>::iterator iter = threads.begin();
3710