mods/additions largely under the USE_STL_VECTOR and IBM_BPATCH_COMPAT flags
[dyninst.git] / dyninstAPI / src / BPatch.C
1 /*
2  * Copyright (c) 1996 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: BPatch.C,v 1.45 2002/03/19 22:57:20 jaw Exp $
43
44 #include <stdio.h>
45 #include <assert.h>
46 #include <signal.h>
47
48 #define BPATCH_FILE
49 #include "BPatch.h"
50 #include "BPatch_libInfo.h"
51 #include "process.h"
52 #include "BPatch_collections.h"
53 #include "common/h/timing.h"
54
55 #if defined(i386_unknown_nt4_0) || defined(mips_unknown_ce2_11) //ccw 20 july 2000 : 28 mar 2001
56 #include "nt_signal_emul.h"
57 #endif
58
59 extern bool dyninstAPI_init();
60 extern int handleSigChild(int pid, int status);
61
62
63 BPatch *BPatch::bpatch = NULL;
64
65 /*
66  * BPatch::BPatch
67  *
68  * Constructor for BPatch.  Performs one-time initialization needed by the
69  * library.
70  */
71 BPatch::BPatch()
72   : info(NULL),
73     errorHandler(NULL),
74     dynLibraryCallback(NULL),
75     typeCheckOn(true),
76     lastError(0),
77     debugParseOn(true),
78     baseTrampDeletionOn(false),
79     trampRecursiveOn(false),
80     forceRelocation_NP(false),
81     builtInTypes(NULL),
82     stdTypes(NULL),
83     type_Error(NULL),
84     type_Untyped(NULL)
85 {
86     extern bool init();
87
88     // Save a pointer to the one-and-only bpatch object.
89     if (bpatch == NULL){
90         bpatch = this;
91 #ifdef mips_unknown_ce2_11 //ccw 10 aug 2000 : 28 mar 2001
92         rDevice = new remoteDevice(); //ccw 8 aug 2000
93 #endif
94         }
95
96     /* XXX else
97      *  (indicate an error somehow)
98      */
99
100     // XXX dyninstAPI_init returns success/failure -- should pass on somehow
101     dyninstAPI_init();
102     initCyclesPerSecond();
103
104     /*
105      * Create the library private info object.
106      */
107     info = new BPatch_libInfo;
108
109     /*
110      * Create the "error" and "untyped" types.
111      */
112     type_Error   = new BPatch_type("<error>", true);
113     type_Untyped = new BPatch_type("<no type>", true);
114
115     /*
116      * Initialize hash table of standard types.
117      */
118     stdTypes = new BPatch_typeCollection;
119     stdTypes->addType(new BPatch_type("int",-1, BPatch_dataScalar, sizeof(int)));
120     stdTypes->addType(new BPatch_type("char *",-3, BPatch_dataScalar, sizeof(char*)));
121     BPatch_type *voidType = new BPatch_type("void",-11, BPatch_dataScalar, 0);
122     stdTypes->addType(voidType);
123     stdTypes->addType(new BPatch_type("void *",-4, BPatch_dataPointer, voidType));
124     stdTypes->addType(new BPatch_type("float",-12, BPatch_dataScalar, sizeof(float)));
125 #if !defined(i386_unknown_nt4_0)
126     stdTypes->addType(new BPatch_type("long long",-31, BPatch_dataScalar, sizeof(long long int)));
127 #endif
128
129     /*
130      * Initialize hash table of API types.
131      */
132     APITypes = new BPatch_typeCollection;
133
134     /*
135      *  Initialize hash table of Built-in types.
136      *  Negative type numbers defined in the gdb stab-docs
137      */
138      
139     builtInTypes = new BPatch_builtInTypeCollection;
140     
141     // NOTE: integral type  mean twos-complement
142     // -1  int, 32 bit signed integral type
143     // in stab document, size specified in bits, system size is in bytes
144     builtInTypes->addBuiltInType(new BPatch_type("int",-1, BPatch_dataBuilt_inType,
145                                                  4));
146     // -2  char, 8 bit type holding a character. GDB & dbx(AIX) treat as signed
147     builtInTypes->addBuiltInType(new BPatch_type("char",-2,
148                                                  BPatch_dataBuilt_inType, 1));
149     // -3  short, 16 bit signed integral type
150     builtInTypes->addBuiltInType(new BPatch_type("short",-3,
151                                                  BPatch_dataBuilt_inType, 2));
152     // -4  long, 32/64 bit signed integral type
153     builtInTypes->addBuiltInType(new BPatch_type("long",-4,
154                                                  BPatch_dataBuilt_inType, 
155                                                  sizeof(long)));
156     // -5  unsigned char, 8 bit unsigned integral type
157     builtInTypes->addBuiltInType(new BPatch_type("unsigned char",-5,
158                                                  BPatch_dataBuilt_inType, 1));
159     // -6  signed char, 8 bit signed integral type
160     builtInTypes->addBuiltInType(new BPatch_type("signed char",-6,
161                                                  BPatch_dataBuilt_inType, 1));
162     // -7  unsigned short, 16 bit unsigned integral type
163     builtInTypes->addBuiltInType(new BPatch_type("unsigned short",-7,
164                                                  BPatch_dataBuilt_inType, 2));
165     // -8  unsigned int, 32 bit unsigned integral type
166     builtInTypes->addBuiltInType(new BPatch_type("unsigned int",-8,
167                                                  BPatch_dataBuilt_inType, 4));
168     // -9  unsigned, 32 bit unsigned integral type
169     builtInTypes->addBuiltInType(new BPatch_type("unsigned",-9,
170                                                  BPatch_dataBuilt_inType,4));
171     // -10 unsigned long, 32 bit unsigned integral type
172     builtInTypes->addBuiltInType(new BPatch_type("unsigned long",-10,
173                                                  BPatch_dataBuilt_inType, 
174                                                  sizeof(unsigned long)));
175     // -11 void, type indicating the lack of a value
176     //  XXX-size may not be correct jdd 4/22/99
177     builtInTypes->addBuiltInType(new BPatch_type("void",-11,
178                                                  BPatch_dataBuilt_inType,
179                                                  0));
180     // -12 float, IEEE single precision
181     builtInTypes->addBuiltInType(new BPatch_type("float",-12,
182                                                  BPatch_dataBuilt_inType,
183                                                  sizeof(float)));
184     // -13 double, IEEE double precision
185     builtInTypes->addBuiltInType(new BPatch_type("double",-13,
186                                                  BPatch_dataBuilt_inType,
187                                                  sizeof(double)));
188     // -14 long double, IEEE double precision, size may increase in future
189     builtInTypes->addBuiltInType(new BPatch_type("long double",-14,
190                                                  BPatch_dataBuilt_inType,
191                                                  sizeof(long double)));
192     // -15 integer, 32 bit signed integral type
193     builtInTypes->addBuiltInType(new BPatch_type("integer",-15,
194                                                  BPatch_dataBuilt_inType, 4));
195     // -16 boolean, 32 bit type. GDB/GCC 0=False, 1=True, all other values
196     //     have unspecified meaning
197     builtInTypes->addBuiltInType(new BPatch_type("boolean",-16,
198                                                  BPatch_dataBuilt_inType, 4));
199     // -17 short real, IEEE single precision
200     //  XXX-size may not be correct jdd 4/22/99
201     builtInTypes->addBuiltInType(new BPatch_type("short real",-17,
202                                                  BPatch_dataBuilt_inType,
203                                                  sizeof(float)));
204     // -18 real, IEEE double precision XXX-size may not be correct jdd 4/22/99 
205     builtInTypes->addBuiltInType(new BPatch_type("real",-18,
206                                                  BPatch_dataBuilt_inType,
207                                                  sizeof(double)));
208     // -19 stringptr XXX- size of void * -- jdd 4/22/99
209     builtInTypes->addBuiltInType(new BPatch_type("stringptr",-19,
210                                                  BPatch_dataBuilt_inType,
211                                                  sizeof(void *)));
212     // -20 character, 8 bit unsigned character type
213     builtInTypes->addBuiltInType(new BPatch_type("character",-20,
214                                                  BPatch_dataBuilt_inType, 1));
215     // -21 logical*1, 8 bit type (Fortran, used for boolean or unsigned int)
216     builtInTypes->addBuiltInType(new BPatch_type("logical*1",-21,
217                                                  BPatch_dataBuilt_inType, 1));
218     // -22 logical*2, 16 bit type (Fortran, some for boolean or unsigned int)
219     builtInTypes->addBuiltInType(new BPatch_type("logical*2",-22,
220                                                  BPatch_dataBuilt_inType, 2));
221     // -23 logical*4, 32 bit type (Fortran, some for boolean or unsigned int)
222     builtInTypes->addBuiltInType(new BPatch_type("logical*4",-23,
223                                                  BPatch_dataBuilt_inType, 4));
224     // -24 logical, 32 bit type (Fortran, some for boolean or unsigned int)
225     builtInTypes->addBuiltInType(new BPatch_type("logical",-24,
226                                                  BPatch_dataBuilt_inType, 4));
227     // -25 complex, consists of 2 IEEE single-precision floating point values
228     builtInTypes->addBuiltInType(new BPatch_type("complex",-25,
229                                                  BPatch_dataBuilt_inType,
230                                                  (sizeof(float)*2)));
231     // -26 complex, consists of 2 IEEE double-precision floating point values
232     builtInTypes->addBuiltInType(new BPatch_type("complex",-26,
233                                                  BPatch_dataBuilt_inType,
234                                                  (sizeof(double)*2)));
235     // -27 integer*1, 8 bit signed integral type
236     builtInTypes->addBuiltInType(new BPatch_type("integer*1",-27,
237                                                  BPatch_dataBuilt_inType, 1));
238     // -28 integer*2, 16 bit signed integral type
239     builtInTypes->addBuiltInType(new BPatch_type("integer*2",-28,
240                                                  BPatch_dataBuilt_inType, 2));
241
242 /* Quick hack to make integer*4 compatible with int for Fortran
243    jnb 6/20/01 */
244
245     builtInTypes->addBuiltInType(new BPatch_type("int",-29,
246                                                  BPatch_built_inType, 4));
247 /*    // -29 integer*4, 32 bit signed integral type
248     builtInTypes->addBuiltInType(new BPatch_type("integer*4",-29,
249                                                  BPatch_built_inType, 4)); */
250
251     // -30 wchar, Wide character, 16 bits wide, unsigned (unknown format)
252     builtInTypes->addBuiltInType(new BPatch_type("wchar",-30,
253                                                  BPatch_dataBuilt_inType, 2));
254     // -31 long long, 64 bit signed integral type
255     builtInTypes->addBuiltInType(new BPatch_type("long long",-31,
256                                                  BPatch_dataBuilt_inType, 8));
257     // -32 unsigned long long, 64 bit unsigned integral type
258     builtInTypes->addBuiltInType(new BPatch_type("unsigned long long", -32,
259                                                  BPatch_dataBuilt_inType, 8));
260     // -33 logical*8, 64 bit unsigned integral type
261     builtInTypes->addBuiltInType(new BPatch_type("logical*8",-33,
262                                                  BPatch_dataBuilt_inType, 8));
263     // -34 integer*8, 64 bit signed integral type
264     builtInTypes->addBuiltInType(new BPatch_type("integer*8",-34,
265                                                  BPatch_dataBuilt_inType, 8));
266
267     // default callbacks are null
268     postForkCallback = NULL;
269     preForkCallback = NULL;
270     errorHandler = NULL;
271     dynLibraryCallback = NULL;
272     execCallback = NULL;
273     exitCallback = NULL;
274
275 #ifdef DETACH_ON_THE_FLY
276     // Register handler for notification from detached inferiors
277     extern void initDetachOnTheFly();
278     initDetachOnTheFly();
279 #endif
280 }
281
282
283 /*
284  * BPatch::~BPatch
285  *
286  * Destructor for BPatch.  Free allocated memory.
287  */
288 BPatch::~BPatch()
289 {
290     delete info;
291
292     delete type_Error;
293     delete type_Untyped;
294
295     delete stdTypes;
296
297     bpatch = NULL;
298 }
299
300
301 /*
302  * BPatch::registerErrorCallback
303  *
304  * Registers a function that is to be called by the library when an error
305  * occurs or when there is status to report.  Returns the address of the
306  * previously registered error callback function.
307  *
308  * function     The function to be called.
309  */
310 BPatchErrorCallback BPatch::registerErrorCallback(BPatchErrorCallback function)
311 {
312     BPatchErrorCallback ret;
313
314     ret = errorHandler;
315     errorHandler = function;
316
317     return ret;
318 }
319
320
321 /*
322  * BPatch::registerPostForkCallback
323  *
324  * Registers a function that is to be called by the library when a new
325  * process has been forked off by an mutatee process.
326  *
327  * function     The function to be called.
328  */
329 BPatchForkCallback BPatch::registerPostForkCallback(BPatchForkCallback func)
330 {
331
332 #if !defined(sparc_sun_solaris2_4) && \
333     !defined(i386_unknown_solaris2_5) && \
334     !defined(alpha_dec_osf4_0) && \
335     !defined(mips_sgi_irix6_4)
336
337   reportError(BPatchWarning, 0,
338               "postfork callbacks not implemented on this platform\n");
339   return NULL;
340 #else
341     BPatchForkCallback ret;
342
343     ret = postForkCallback;
344     postForkCallback = func;
345
346     return ret;
347 #endif
348 }
349
350 /*
351  * BPatch::registerPreForkCallback
352  *
353  * Registers a function that is to be called by the library when a process
354  * is about to fork a new process
355  *
356  * function     The function to be called.
357  */
358 BPatchForkCallback BPatch::registerPreForkCallback(BPatchForkCallback func)
359 {
360 #if !defined(sparc_sun_solaris2_4) && \
361     !defined(i386_unknown_solaris2_5) &&\
362     !defined(alpha_dec_osf4_0) && \
363     !defined(mips_sgi_irix6_4)
364     reportError(BPatchWarning, 0,
365         "prefork callbacks not implemented on this platform\n");
366     return NULL;
367 #else
368     BPatchForkCallback ret;
369
370     ret = preForkCallback;
371     preForkCallback = func;
372
373     return ret;
374 #endif
375 }
376
377 /*
378  * BPatch::registerExecCallback
379  *
380  * Registers a function that is to be called by the library when a 
381  * process has just completed an exec* call
382  *
383  * func The function to be called.
384  */
385 BPatchExecCallback BPatch::registerExecCallback(BPatchExecCallback func)
386 {
387
388 #if !defined(sparc_sun_solaris2_4) && \
389     !defined(i386_unknown_solaris2_5) &&\
390     !defined(alpha_dec_osf4_0) && \
391     !defined(mips_sgi_irix6_4)
392     reportError(BPatchWarning, 0,
393         "exec callbacks not implemented on this platform\n");
394     return NULL;
395 #else
396     BPatchExecCallback ret;
397
398     ret = execCallback;
399     execCallback = func;
400
401     return ret;
402 #endif
403 }
404
405 /*
406  * BPatch::registerExecCallback
407  *
408  * Registers a function that is to be called by the library when a 
409  * process has just called the exit system call
410  *
411  * func The function to be called.
412  */
413 BPatchExitCallback BPatch::registerExitCallback(BPatchExitCallback func)
414 {
415
416 #if !defined(sparc_sun_solaris2_4) && \
417     !defined(i386_unknown_solaris2_5) &&\
418     !defined(alpha_dec_osf4_0) && \
419     !defined(mips_sgi_irix6_4)
420     reportError(BPatchWarning, 0,
421         "exit callbacks not implemented on this platform\n");
422     return NULL;
423 #else
424     BPatchExitCallback ret;
425
426     ret = exitCallback;
427     exitCallback = func;
428
429     return ret;
430 #endif
431 }
432
433 #ifdef IBM_BPATCH_COMPAT
434 BPatchExitCallback BPatch::registerExitCallback(BPatchThreadEventCallback func)
435 {
436
437     BPatchExitCallback ret;
438
439     ret = exitCallback;
440     exitCallback = (BPatchExitCallback) func;
441
442     return ret;
443
444 }
445 #endif
446
447 /*
448  * BPatch::registerDynLibraryCallback
449  *
450  * Registers a function that is to be called by the library when a dynamically
451  * loaded library is loaded or unloaded by a process under the API's control.
452  * Returns the address of the previously registered callback function.
453  *
454  * function     The function to be called.
455  */
456 BPatchDynLibraryCallback
457 BPatch::registerDynLibraryCallback(BPatchDynLibraryCallback function)
458 {
459     BPatchDynLibraryCallback ret;
460
461     ret = dynLibraryCallback;
462     dynLibraryCallback = function;
463
464     return ret;
465 }
466
467
468 /*
469  * BPatch::getEnglishErrorString
470  *
471  * Returns the descriptive error string for the passed error number.
472  *
473  * number       The number that identifies the error.
474  */
475 const char *BPatch::getEnglishErrorString(int /* number */)
476 {
477     return "%s";
478 }
479
480
481 /*
482  * BPatch::reportError
483  *
484  * Report an error using the callback mechanism.
485  *
486  * severity     The severity level of the error.
487  * number       Identifies the error.
488  * str          A string to pass as the first element of the list of strings
489  *              given to the callback function.
490  */
491 void BPatch::reportError(BPatchErrorLevel severity, int number, const char *str)
492 {
493     assert(bpatch != NULL);
494   
495     // don't log BPatchWarning or BPatchInfo messages as "errors"
496     if ((severity == BPatchFatal) || (severity == BPatchSerious))
497         bpatch->lastError = number;
498
499     if (bpatch->errorHandler != NULL) {
500         bpatch->errorHandler(severity, number, &str);
501     } else if ((severity == BPatchFatal) || (severity == BPatchSerious)){
502         fprintf(stdout, "DYNINST ERROR: %s\n", str);
503         fflush(stdout);
504     }
505 }
506
507
508 /*
509  * BPatch::formatErrorString
510  *
511  * Takes a format string with an error message (obtained from
512  * getEnglishErrorString) and an array of parameters that were passed to an
513  * error callback function, and creates a string with the parameters
514  * substituted into it.
515  *
516  * dst          The address into which the formatted string should be copied.
517  * size         If the formatted string is equal to or longer than this number
518  *              of characters, then it will be truncated to size-1 characters
519  *              and terminated with a nul ('\0').
520  * fmt          The format string (returned by a function such as
521  *              getEnglishErrorString).
522  * params       The array of parameters that were passed to an error callback
523  *              function.
524  */
525 void BPatch::formatErrorString(char *dst, int size,
526                                const char *fmt, const char **params)
527 {
528     int cur_param = 0;
529
530     while (size > 1 && *fmt) {
531         if (*fmt == '%') {
532             if (fmt[1] == '\0') {
533                 break;
534             } else if (fmt[1] == '%') {
535                 *dst++ = '%';
536                 size--;
537             } else if (fmt[1] == 's') {
538                 char *p = const_cast<char *>(params[cur_param++]);
539                 while (size > 1 && *p) {
540                     *dst++ = *p++;
541                     size--;
542                 }
543             } else {
544                 // Illegal specifier
545                 *dst++ = fmt[0];
546                 *dst++ = fmt[1];
547                 size -= 2;
548             }
549             fmt += 2;
550         } else {
551             *dst++ = *fmt++;
552             size--;
553         }
554     }
555     if (size > 0)
556         *dst = '\0';
557 }
558
559
560 /*
561  * BPatch::getThreadByPid
562  *
563  * Given a process ID, this function returns a pointer to the associated
564  * BPatch_thread object (or NULL if there is none).  Since a process may be
565  * registered provisionally with a thread object pointer of NULL, the boolean
566  * pointed to by the parameter "exists" is set to true if the pid exists in
567  * the table of processes, and false if it does not.
568  *
569  * pid          The pid to look up.
570  * exists       A pointer to a boolean to fill in with true if the pid exists
571  *              in the table and false if it does not.  NULL may be passed in
572  *              if this information is not required.
573  */
574 BPatch_thread *BPatch::getThreadByPid(int pid, bool *exists)
575 {
576     if (info->threadsByPid.defines(pid)) {
577         if (exists) *exists = true;
578         return info->threadsByPid[pid];
579     } else {
580         if (exists) *exists = false;
581         return NULL;
582     }
583 }
584
585
586 /*
587  * BPatch::getThreads
588  *
589  * Returns a vector of all threads that are currently defined.  Includes
590  * threads created directly using the library and those created with UNIX fork
591  * or Windows NT spawn system calls.  The caller is responsible for deleting
592  * the vector when it is no longer needed.
593  */
594 BPatch_Vector<BPatch_thread *> *BPatch::getThreads()
595 {
596     BPatch_Vector<BPatch_thread *> *result = new BPatch_Vector<BPatch_thread *>;
597
598     dictionary_hash_iter<int, BPatch_thread *> ti(info->threadsByPid);
599
600     int pid;
601     BPatch_thread *thread;
602
603     while (ti.next(pid, thread))
604         result->push_back(thread);
605
606     return result;
607 }
608
609
610 /*
611  * BPatch::registerProvisionalThread
612  *
613  * Register a new process that is not yet associated with a thread.
614  * (this function is called only by createProcess).
615  *
616  * pid          The pid of the process to register.
617  */
618 void BPatch::registerProvisionalThread(int pid)
619 {
620     assert(!info->threadsByPid.defines(pid));
621     info->threadsByPid[pid] = NULL;
622 }
623
624
625 /*
626  * BPatch::registerForkedThread
627  *
628  * Register a new process that is not yet associated with a thread.
629  * (this function is an upcall when a new process is created).
630  *
631  * parentPid            the pid of the parent process.
632  * childPid             The pid of the process to register.
633  * proc                 lower lever handle to process specific stuff
634  *
635  */
636 void BPatch::registerForkedThread(int parentPid, int childPid, process *proc)
637 {
638     assert(!info->threadsByPid.defines(childPid));
639
640     BPatch_thread *parent = info->threadsByPid[parentPid];
641
642     assert(parent);
643     info->threadsByPid[childPid] = new BPatch_thread(childPid, proc);
644
645     if (postForkCallback) {
646         postForkCallback(parent, info->threadsByPid[childPid]);
647     }
648 }
649
650
651 /*
652  * BPatch::registerExec
653  *
654  * Register a process that has just done an exec call.
655  *
656  * thread       thread that has just performed the exec
657  *
658  */
659 void BPatch::registerExec(BPatch_thread *thread)
660 {
661     // build a new BPatch_image for this one
662     thread->image = new BPatch_image(thread->proc);
663
664     if (execCallback) {
665         execCallback(thread);
666     }
667 }
668
669
670 /*
671  * BPatch::registerExit
672  *
673  * Register a process that has just done an exit call.
674  *
675  * thread       thread that has just performed the exec
676  * code         the exit status code
677  *
678  */
679 void BPatch::registerExit(BPatch_thread *thread, int code)
680 {
681     if (exitCallback) {
682         exitCallback(thread, code);
683     }
684 }
685
686
687 /*
688  * BPatch::registerThread
689  *
690  * Register a new BPatch_thread object with the BPatch library (this function
691  * is called only by the constructor for BPatch_thread).
692  *
693  * thread       A pointer to the thread to register.
694  */
695 void BPatch::registerThread(BPatch_thread *thread)
696 {
697     assert(!info->threadsByPid.defines(thread->getPid()) ||
698             info->threadsByPid[thread->getPid()] == NULL);
699     info->threadsByPid[thread->getPid()] = thread;
700 }
701
702
703 /*
704  * BPatch::unRegisterThread
705  *
706  * Remove the BPatch_thread associated with a given pid from the list of
707  * threads being managed by the library.
708  *
709  * pid          The pid of the thread to be removed.
710  */
711 void BPatch::unRegisterThread(int pid)
712 {
713     assert(info->threadsByPid.defines(pid));
714     info->threadsByPid.undef(pid);      
715 }
716
717
718 /*
719  * BPatch::createProcess
720  *
721  * Create a process and return a BPatch_thread representing it.
722  * Returns NULL upon failure.
723  *
724  * path         The pathname of the executable for the new process.
725  * argv         A list of the arguments for the new process, terminated by a
726  *              NULL.
727  * envp         A list of values that make up the environment for the new
728  *              process, terminated by a NULL.  If envp is NULL, the new
729  *              new process will inherit the environemnt of the parent.
730  * stdin_fd     file descriptor to use for stdin for the application
731  * stdout_fd    file descriptor to use for stdout for the application
732  * stderr_fd    file descriptor to use for stderr for the application
733
734  */
735 BPatch_thread *BPatch::createProcess(char *path, char *argv[], 
736         char *envp[], int stdin_fd, int stdout_fd, int stderr_fd)
737 {
738     clearError();
739
740     BPatch_thread *ret = 
741         new BPatch_thread(path, argv, envp, stdin_fd, stdout_fd, stderr_fd);
742
743     if (!ret->proc ||
744        (ret->proc->status() != stopped) ||
745        !ret->proc->isBootstrappedYet()) {
746         delete ret;
747         return NULL;
748     }
749         ret->proc->collectSaveWorldData = false;//ccw 23 jan 2002 : this forces the user
750                 // to call BPatch_thread::startSaveWorld() if they want to use the
751                 // save the world functionality.  
752
753     return ret;
754 }
755
756
757 /*
758  * BPatch::attachProcess
759  *
760  * Attach to a running process and return a BPatch_thread representing it.
761  * Returns NULL upon failure.
762  *
763  * path         The pathname of the executable for the process.
764  * pid          The id of the process to attach to.
765  */
766 BPatch_thread *BPatch::attachProcess(char *path, int pid)
767 {
768     clearError();
769
770     BPatch_thread *ret = new BPatch_thread(path, pid);
771
772     if (!ret->proc ||
773        (ret->proc->status() != stopped) ||
774        !ret->proc->isBootstrappedYet()) {
775         // It would be considerate to (attempt to) leave the process running
776         // at this point (*before* deleting the BPatch_thread handle for it!),
777         // even though it might be in bad shape after the attempted attach.
778         char msg[256];
779         sprintf(msg,"attachProcess failed: process %d may now be killed!",pid);
780         reportError(BPatchWarning, 26, msg);
781         delete ret;
782         return NULL;
783     }
784
785     return ret;
786 }
787
788
789 /*
790  * getThreadEvent
791  *
792  * Checks for changes in any child process, and optionally blocks until such a
793  * change has occurred.  Also updates the process object representing each
794  * process for which a change is detected.  The return value is true if a
795  * change was detected, otherwise it is false.
796  *
797  * block        Set this parameter to true to block waiting for a change,
798  *              set to false to poll and return immediately, whether or not a
799  *              change occurred.
800  */
801 bool BPatch::getThreadEvent(bool block)
802 {
803     bool        result = false;
804     int         pid, status;
805
806     // while ((pid = process::waitProcs(&status, block)) > 0) {
807     if ((pid = process::waitProcs(&status, block)) > 0) {
808         // There's been a change in a child process
809         result = true;
810         // Since we found something, we don't want to block anymore
811         block = false;
812
813         bool exists;
814         BPatch_thread *thread = getThreadByPid(pid, &exists);
815         if (thread == NULL) {
816             if (exists) {
817                 if (WIFSIGNALED(status) || WIFEXITED(status))
818                     unRegisterThread(pid);
819             } else {
820                 fprintf(stderr, "Warning - wait returned status of an unknown process (%d)\n", pid);
821             }
822         }
823         if (thread != NULL) {
824             if (WIFSTOPPED(status)) {
825                 thread->lastSignal = WSTOPSIG(status);
826                 thread->setUnreportedStop(true);
827             } else if (WIFSIGNALED(status)) {
828                 thread->lastSignal = WTERMSIG(status);
829                 thread->setUnreportedTermination(true);
830             } else if (WIFEXITED(status)) {
831 #if !defined(i386_unknown_nt4_0) && !defined(mips_unknown_ce2_11) //ccw 20 july 2000 : 28 mar 2001
832                 thread->proc->exitCode_ = WEXITSTATUS(status);
833 #endif
834                 thread->exitCode = thread->proc->exitCode();
835                 thread->lastSignal = 0; /* XXX Make into some constant */
836                 thread->setUnreportedTermination(true);
837             }
838         }
839 #if !(defined i386_unknown_nt4_0) && !(defined mips_unknown_ce2_11) //ccw 20 july 2000 : 28 mar 2001
840         handleSigChild(pid, status);
841 #ifdef notdef
842         if (thread->lastSignal == SIGSTOP) {
843             // need to continue process after initial sigstop
844             // thread->continueExecution();
845             printf("BPatch past handleSigChild for SIGSTOP\n");
846             if (thread->proc->wasCreatedViaFork()) {
847                 printf("marking forked process stopped\n");
848                 thread->proc->status_ = stopped;
849                 // thread->lastSignal = SIGSTOP;
850                 // thread->setUnreportedStop(true);
851                 // thread->proc->continueProc();
852             }
853         }
854 #endif
855 #endif
856     }
857
858     return result;
859 }
860
861
862 /*
863  * havePendingEvent
864  *
865  * Returns true if any thread has stopped or terminated and that fact hasn't
866  * been reported to the user of the library.  Otherwise, returns false.
867  */
868 bool BPatch::havePendingEvent()
869 {
870 #if defined(i386_unknown_nt4_0) || defined(mips_unknown_ce2_11) //ccw 20 july 2001 : 28 mar 2001
871     // On NT, we need to poll for events as often as possible, so that we can
872     // handle traps.
873     if (getThreadEvent(false))
874         return true;
875 #endif
876
877     // For now, we'll do it by iterating over the threads and checking them,
878     // and we'll change it to something more efficient later on.
879     dictionary_hash_iter<int, BPatch_thread *> ti(info->threadsByPid);
880
881     int pid;
882     BPatch_thread *thread;
883
884     while (ti.next(pid, thread)) {
885         if (thread != NULL &&
886             (thread->pendingUnreportedStop() ||
887              thread->pendingUnreportedTermination())) {
888             return true;
889         }
890     }
891
892     return false;
893 }
894
895
896 /*
897  * pollForStatusChange
898  *
899  * Checks for unreported changes to the status of any child process, and
900  * returns true if any are detected.  Returns false otherwise.
901  *
902  * This function is declared as a friend of BPatch_thread so that it can use
903  * the BPatch_thread::getThreadEvent call to check for status changes.
904  */
905 bool BPatch::pollForStatusChange()
906 {
907     if (havePendingEvent())
908         return true;
909   
910     // No changes were previously detected, so check for new changes
911     return getThreadEvent(false);
912 }
913
914
915 /*
916  * waitForStatusChange
917  *
918  * Blocks waiting for a change to occur in the running status of a child
919  * process.  Returns true upon success, false upon failure.
920  *
921  * This function is declared as a friend of BPatch_thread so that it can use
922  * the BPatch_thread::getThreadEvent call to check for status changes.
923  */
924 bool BPatch::waitForStatusChange()
925 {
926     if (havePendingEvent())
927         return true;
928
929     // No changes were previously detected, so wait for a new change
930     return getThreadEvent(true);
931 }
932
933 /*
934  * createEnum
935  *
936  * This function is a wrapper for the BPatch_type constructors for API/User
937  * created types.
938  *
939  * It returns a pointer to a BPatch_type that was added to the APITypes
940  * collection.
941  */
942 BPatch_type * BPatch::createEnum( const char * name, 
943                                   BPatch_Vector<char *> elementNames,
944                                   BPatch_Vector<int> elementIds)
945 {
946
947     if (elementNames.size() != elementIds.size()) {
948       return NULL;
949     }
950
951     BPatch_type * newType = new BPatch_type( name, BPatch_dataEnumerated );
952     if (!newType) return NULL;
953     
954     APITypes->addType(newType);
955
956     // ADD components to type
957     for (unsigned int i=0; i < elementNames.size(); i++) {
958         newType->addField(elementNames[i], BPatch_dataScalar, elementIds[i]);
959     }
960
961     return(newType);
962 }
963
964
965 /*
966  * createEnum
967  *
968  * This function is a wrapper for the BPatch_type constructors for API/User
969  * created types.  The user has left element id specification to us
970  *
971  * It returns a pointer to a BPatch_type that was added to the APITypes
972  * collection.
973  */
974 BPatch_type * BPatch::createEnum( const char * name, 
975                                   BPatch_Vector<char *> elementNames)
976 {
977     BPatch_type * newType = new BPatch_type( name, BPatch_dataEnumerated );
978
979     if (!newType) return NULL;
980     
981     APITypes->addType(newType);
982
983     // ADD components to type
984     for (unsigned int i=0; i < elementNames.size(); i++) {
985         newType->addField(elementNames[i], BPatch_dataScalar, i);
986     }
987
988     return(newType);
989 }
990
991 /*
992  * createStructs
993  *
994  * This function is a wrapper for the BPatch_type constructors for API/User
995  * created types.
996  *
997  * It returns a pointer to a BPatch_type that was added to the APITypes
998  * collection.
999  */
1000
1001 BPatch_type * BPatch::createStruct( const char * name,
1002                                     BPatch_Vector<char *> fieldNames,
1003                                     BPatch_Vector<BPatch_type *> fieldTypes)
1004 {
1005     unsigned int i;
1006     int offset, size;
1007
1008     offset = size = 0;
1009     if (fieldNames.size() != fieldTypes.size()) {
1010       return NULL;
1011     }
1012
1013     //Compute the size of the struct
1014     for (i=0; i < fieldNames.size(); i++) {
1015         BPatch_type *type = fieldTypes[i];
1016         size = type->getSize();
1017         size += size;
1018     }
1019   
1020     BPatch_type *newType = new BPatch_type(name, BPatch_dataStructure, size);
1021     if (!newType) return NULL;
1022     
1023     APITypes->addType(newType);
1024
1025     // ADD components to type
1026     size = 0;
1027     for (i=0; i < fieldNames.size(); i++) {
1028         BPatch_type *type = fieldTypes[i];
1029         size = type->getSize();
1030         newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
1031   
1032         // Calculate next offset (in bits) into the struct
1033         offset += (size * 8);
1034     }
1035
1036     return(newType);
1037 }
1038
1039 /*
1040  * createUnions
1041  *
1042  * This function is a wrapper for the BPatch_type constructors for API/User
1043  * created types.
1044  *
1045  * It returns a pointer to a BPatch_type that was added to the APITypes
1046  * collection.
1047  */
1048
1049 BPatch_type * BPatch::createUnion( const char * name, 
1050                                    BPatch_Vector<char *> fieldNames,
1051                                    BPatch_Vector<BPatch_type *> fieldTypes)
1052 {
1053     unsigned int i;
1054     int offset, size, newsize;
1055     offset = size = newsize = 0;
1056
1057     if (fieldNames.size() != fieldTypes.size()) {
1058         return NULL;
1059     }
1060
1061     // Compute the size of the union
1062     for (i=0; i < fieldTypes.size(); i++) {
1063         BPatch_type *type = fieldTypes[i];
1064         newsize = type->getSize();
1065         if(size < newsize) size = newsize;
1066     }
1067   
1068     BPatch_type * newType = new BPatch_type(name, BPatch_dataUnion, size);
1069     if (!newType) return NULL;
1070
1071     APITypes->addType(newType);
1072
1073     // ADD components to type
1074     for (i=0; i < fieldNames.size(); i++) {
1075         BPatch_type *type = fieldTypes[i];
1076         size = type->getSize();
1077         newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
1078     }  
1079     return(newType);
1080 }
1081
1082
1083 /*
1084  * createArray for Arrays and SymTypeRanges
1085  *
1086  * This function is a wrapper for the BPatch_type constructors for API/User
1087  * created types.
1088  *
1089  * It returns a pointer to a BPatch_type that was added to the APITypes
1090  * collection.
1091  */
1092 BPatch_type * BPatch::createArray( const char * name, BPatch_type * ptr,
1093                                    unsigned int low, unsigned int hi)
1094 {
1095
1096     BPatch_type * newType;
1097
1098     if (!ptr) {
1099         return NULL;
1100     } else {
1101         newType = new BPatch_type(name, BPatch_dataArray , ptr, low, hi);
1102         if (!newType) return NULL;
1103     }
1104
1105     APITypes->addType(newType);
1106
1107     return newType;
1108 }
1109
1110 /*
1111  * createPointer for BPatch_pointers
1112  *
1113  * This function is a wrapper for the BPatch_type constructors for API/User
1114  * created types.
1115  *
1116  * It returns a pointer to a BPatch_type that was added to the APITypes
1117  * collection.
1118  */
1119 BPatch_type * BPatch::createPointer(const char * name, BPatch_type * ptr,
1120                                     int size)
1121 {
1122
1123     BPatch_type * newType = new BPatch_type(name, ptr, size);
1124     if(!newType) return NULL;
1125
1126     APITypes->addType(newType);
1127   
1128     return newType;
1129 }
1130
1131 /*
1132  * createScalar for scalars with a size and no range
1133  *
1134  * This function is a wrapper for the BPatch_type constructors for API/User
1135  * created types.
1136  *
1137  * It returns a pointer to a BPatch_type that was added to the APITypes
1138  * collection.
1139  */
1140
1141 BPatch_type * BPatch::createScalar( const char * name, int size)
1142 {
1143     BPatch_type * newType = new BPatch_type(name, BPatch_dataScalar, size);
1144     if (!newType) return NULL;
1145
1146     APITypes->addType(newType);
1147  
1148     return newType;
1149 }
1150
1151 /*
1152  * createType for typedefs
1153  *
1154  * This function is a wrapper for the BPatch_type constructors for API/User
1155  * created types.
1156  *
1157  * It returns a pointer to a BPatch_type that was added to the APITypes
1158  * collection.
1159  */
1160 BPatch_type * BPatch::createTypedef( const char * name, BPatch_type * ptr)
1161 {
1162     BPatch_type * newType = new BPatch_type(name, ptr);
1163
1164     if (!newType) return NULL;
1165
1166     APITypes->addType(newType);
1167   
1168     return newType;
1169 }
1170
1171 bool BPatch::waitUntilStopped(BPatch_thread *appThread){
1172         while (!appThread->isStopped() && !appThread->isTerminated())
1173                 this->waitForStatusChange();
1174
1175         if (!appThread->isStopped())
1176         {
1177                 cerr << "ERROR : process did not signal mutator via stop"
1178                      << endl;
1179                 return false;
1180         }
1181 #if defined(i386_unknown_nt4_0) || \
1182     defined(mips_unknown_ce2_11)
1183         else if((appThread->stopSignal() != SIGTRAP) && 
1184                 (appThread->stopSignal() != -1))
1185         {
1186                 cerr << "ERROR : process stopped on signal different"
1187                      << " than SIGTRAP" << endl;
1188                 return false;
1189         }
1190 #else
1191 #ifdef DETACH_ON_THE_FLY
1192         else if ((appThread->stopSignal() != SIGSTOP) &&
1193                  (appThread->stopSignal() != SIGHUP) &&
1194                  (appThread->stopSignal() != SIGILL)) {
1195 #else
1196         else if ((appThread->stopSignal() != SIGSTOP) &&
1197 #ifdef USE_IRIX_FIXES
1198                  (appThread->stopSignal() != SIGEMT) &&
1199 #endif /* USE_IRIX_FIXES */
1200                  (appThread->stopSignal() != SIGHUP)) {
1201 #endif /* DETACH_ON_THE_FLY */
1202                 cerr << "ERROR :  process stopped on signal "
1203                      << "different than SIGSTOP" << endl;
1204                 return false;
1205         }
1206 #endif
1207         return true;
1208 }
1209
1210 #ifdef IBM_BPATCH_COMPAT
1211
1212 /*
1213  * Register a function to call when an RPC (i.e. oneshot) is done.
1214  *
1215  * dyninst version is a callback that is defined for BPatch_thread
1216  *
1217  */
1218 BPatchThreadEventCallback BPatch::registerRPCTerminationCallback(BPatchThreadEventCallback func)
1219 {
1220     BPatchThreadEventCallback ret;
1221
1222     ret = RPCdoneCallback;
1223     RPCdoneCallback = func;
1224
1225     return ret;
1226 }
1227
1228 void setLogging_NP(BPatchLoggingCallback, int)
1229 {
1230     return;
1231 }
1232
1233 #endif