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