small fixes for my last commit (async events)
[dyninst.git] / dyninstAPI / src / BPatch.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: BPatch.C,v 1.87 2005/02/10 20:39:16 jaw Exp $
43
44 #include <stdio.h>
45 #include <assert.h>
46 #include <signal.h>
47
48 #define BPATCH_FILE
49 #include "common/h/Pair.h"
50 #include "common/h/Vector.h"
51 #include "signalhandler.h"
52 #include "stats.h"
53 #include "BPatch.h"
54 #include "BPatch_typePrivate.h"
55 #include "BPatch_libInfo.h"
56 #include "process.h"
57 #include "BPatch_collections.h"
58 #include "BPatch_asyncEventHandler.h"
59 #include "common/h/timing.h"
60
61 #if defined(i386_unknown_nt4_0) || defined(mips_unknown_ce2_11) //ccw 20 july 2000 : 28 mar 2001
62 #include "nt_signal_emul.h"
63 #endif
64
65 extern bool dyninstAPI_init();
66 extern void loadNativeDemangler();
67
68 BPatch *BPatch::bpatch = NULL;
69
70 //  global stat vars defined in stats.C
71 extern unsigned int trampBytes;
72 extern unsigned int pointsUsed;
73 extern unsigned int insnGenerated;
74 extern unsigned int totalMiniTramps;
75 extern unsigned int ptraceOtherOps;
76 extern unsigned int ptraceOps;
77 extern unsigned int ptraceBytes;
78
79
80 /*
81  * BPatch::BPatch
82  *
83  * Constructor for BPatch.  Performs one-time initialization needed by the
84  * library.
85  */
86 BPatch::BPatch()
87   : info(NULL),
88     errorHandler(NULL),
89     dynLibraryCallback(NULL),
90     typeCheckOn(true),
91     lastError(0),
92     debugParseOn(true),
93     baseTrampDeletionOn(false),
94     trampRecursiveOn(false),
95     forceRelocation_NP(false),
96     autoRelocation_NP(true),
97     delayedParsing_(false),
98     builtInTypes(NULL),
99     stdTypes(NULL),
100     type_Error(NULL),
101     type_Untyped(NULL)
102 {
103     memset(&stats, 0, sizeof(BPatch_stats));
104     extern bool init();
105
106     // Save a pointer to the one-and-only bpatch object.
107     if (bpatch == NULL){
108         bpatch = this;
109 #ifdef mips_unknown_ce2_11 //ccw 10 aug 2000 : 28 mar 2001
110         rDevice = new remoteDevice(); //ccw 8 aug 2000
111 #endif
112         }
113
114     /* XXX else
115      *  (indicate an error somehow)
116      */
117
118     // XXX dyninstAPI_init returns success/failure -- should pass on somehow
119     dyninstAPI_init();
120     initCyclesPerSecond();
121
122     /*
123      * Create the library private info object.
124      */
125     info = new BPatch_libInfo;
126
127     /*
128      * Create the "error" and "untyped" types.
129      */
130     type_Error   = BPatch_type::createFake("<error>");
131     type_Untyped = BPatch_type::createFake("<no type>");
132
133     /*
134      * Initialize hash table of standard types.
135      */
136     BPatch_type *newType;
137     stdTypes = new BPatch_typeCollection;
138     stdTypes->addType(newType = new BPatch_typeScalar(-1, sizeof(int), "int"));
139     newType->decrRefCount();
140     BPatch_type *charType = new BPatch_typeScalar(-2, sizeof(char), "char");
141     stdTypes->addType(charType);
142     stdTypes->addType(newType = new BPatch_typePointer(-3, charType, "char *"));
143     charType->decrRefCount();
144     newType->decrRefCount();
145     BPatch_type *voidType = new BPatch_typeScalar(-11, 0, "void");
146     stdTypes->addType(voidType);
147     stdTypes->addType(newType = new BPatch_typePointer(-4, voidType, "void *"));
148     voidType->decrRefCount();
149     newType->decrRefCount();
150     stdTypes->addType(newType = new BPatch_typeScalar(-12, sizeof(float), "float"));
151     newType->decrRefCount();
152 #if defined(i386_unknown_nt4_0)
153     stdTypes->addType(newType = new BPatch_typeScalar(-31, sizeof(LONGLONG), "long long"));    
154 #else
155     stdTypes->addType(newType = new BPatch_typeScalar(-31, sizeof(long long), "long long"));
156 #endif
157     newType->decrRefCount();
158
159     /*
160      * Initialize hash table of API types.
161      */
162     APITypes = new BPatch_typeCollection;
163
164     /*
165      *  Initialize hash table of Built-in types.
166      *  Negative type numbers defined in the gdb stab-docs
167      */
168      
169     builtInTypes = new BPatch_builtInTypeCollection;
170     
171     // NOTE: integral type  mean twos-complement
172     // -1  int, 32 bit signed integral type
173     // in stab document, size specified in bits, system size is in bytes
174     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-1, 4, "int"));
175     newType->decrRefCount();
176     // -2  char, 8 bit type holding a character. GDB & dbx(AIX) treat as signed
177     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-2, 1, "char"));
178     newType->decrRefCount();
179     // -3  short, 16 bit signed integral type
180     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-3, 2, "short"));
181     newType->decrRefCount();
182     // -4  long, 32/64 bit signed integral type
183     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-4, sizeof(long), "long"));
184     newType->decrRefCount();
185     // -5  unsigned char, 8 bit unsigned integral type
186     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-5, 1, "unsigned char"));
187     newType->decrRefCount();
188     // -6  signed char, 8 bit signed integral type
189     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-6, 1, "signed char"));
190     newType->decrRefCount();
191     // -7  unsigned short, 16 bit unsigned integral type
192     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-7, 2, "unsigned short"));
193     newType->decrRefCount();
194     // -8  unsigned int, 32 bit unsigned integral type
195     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-8, 4, "unsigned int"));
196     newType->decrRefCount();
197     // -9  unsigned, 32 bit unsigned integral type
198     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-9, 4, "unsigned"));
199     newType->decrRefCount();
200     // -10 unsigned long, 32 bit unsigned integral type
201     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-10, sizeof(unsigned long), "unsigned long"));
202     newType->decrRefCount();
203     // -11 void, type indicating the lack of a value
204     //  XXX-size may not be correct jdd 4/22/99
205     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-11, 0, "void"));
206     newType->decrRefCount();
207     // -12 float, IEEE single precision
208     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-12, sizeof(float), "float"));
209     newType->decrRefCount();
210     // -13 double, IEEE double precision
211     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-13, sizeof(double), "double"));
212     newType->decrRefCount();
213     // -14 long double, IEEE double precision, size may increase in future
214     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-14, sizeof(long double), "long double"));
215     newType->decrRefCount();
216     // -15 integer, 32 bit signed integral type
217     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-15, 4, "integer"));
218     newType->decrRefCount();
219     // -16 boolean, 32 bit type. GDB/GCC 0=False, 1=True, all other values
220     //     have unspecified meaning
221     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-16, sizeof(bool), "boolean"));
222     newType->decrRefCount();
223     // -17 short real, IEEE single precision
224     //  XXX-size may not be correct jdd 4/22/99
225     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-17, sizeof(float), "short real"));
226     newType->decrRefCount();
227     // -18 real, IEEE double precision XXX-size may not be correct jdd 4/22/99 
228     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-18, sizeof(double), "real"));
229     newType->decrRefCount();
230     // -19 stringptr XXX- size of void * -- jdd 4/22/99
231     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-19, sizeof(void *), "stringptr"));
232     newType->decrRefCount();
233     // -20 character, 8 bit unsigned character type
234     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-20, 1, "character"));
235     newType->decrRefCount();
236     // -21 logical*1, 8 bit type (Fortran, used for boolean or unsigned int)
237     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-21, 1, "logical*1"));
238     newType->decrRefCount();
239     // -22 logical*2, 16 bit type (Fortran, some for boolean or unsigned int)
240     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-22, 2, "logical*2"));
241     newType->decrRefCount();
242     // -23 logical*4, 32 bit type (Fortran, some for boolean or unsigned int)
243     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-23, 4, "logical*4"));
244     newType->decrRefCount();
245     // -24 logical, 32 bit type (Fortran, some for boolean or unsigned int)
246     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-24, 4, "logical"));
247     newType->decrRefCount();
248     // -25 complex, consists of 2 IEEE single-precision floating point values
249     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-25, sizeof(float)*2, "complex"));
250     newType->decrRefCount();
251     // -26 complex, consists of 2 IEEE double-precision floating point values
252     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-26, sizeof(double)*2, "complex*16"));
253     newType->decrRefCount();
254     // -27 integer*1, 8 bit signed integral type
255     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-27, 1, "integer*1"));
256     newType->decrRefCount();
257     // -28 integer*2, 16 bit signed integral type
258     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-28, 2, "integer*2"));
259     newType->decrRefCount();
260
261 /* Quick hack to make integer*4 compatible with int for Fortran
262    jnb 6/20/01 */
263
264     // This seems questionable - let's try removing that hack - jmo 05/21/04
265     /*
266     builtInTypes->addBuiltInType(newType = new BPatch_type("int",-29,
267                                                  BPatch_built_inType, 4));
268     newType->decrRefCount();
269     */
270     // -29 integer*4, 32 bit signed integral type
271     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-29, 4, "integer*4"));
272     newType->decrRefCount();
273     // -30 wchar, Wide character, 16 bits wide, unsigned (unknown format)
274     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-30, 2, "wchar"));
275     newType->decrRefCount();
276 #ifdef i386_unknown_nt4_0
277     // -31 long long, 64 bit signed integral type
278     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-31, sizeof(LONGLONG), "long long"));
279     newType->decrRefCount();
280     // -32 unsigned long long, 64 bit unsigned integral type
281     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-32, sizeof(ULONGLONG), "unsigned long long"));
282     newType->decrRefCount();
283 #else
284     // -31 long long, 64 bit signed integral type
285     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-31, sizeof(long long), "long long"));
286     newType->decrRefCount();
287     // -32 unsigned long long, 64 bit unsigned integral type
288     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-32, sizeof(unsigned long long), "unsigned long long"));
289     newType->decrRefCount();
290 #endif
291     // -33 logical*8, 64 bit unsigned integral type
292     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-33, 8, "logical*8"));
293     newType->decrRefCount();
294     // -34 integer*8, 64 bit signed integral type
295     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-34, 8, "integer*8"));
296     newType->decrRefCount();
297
298     // default callbacks are null
299     postForkCallback = NULL;
300     preForkCallback = NULL;
301     errorHandler = NULL;
302     dynLibraryCallback = NULL;
303     execCallback = NULL;
304     exitCallback = NULL;
305     oneTimeCodeCallback = NULL;
306
307 #ifdef IBM_BPATCH_COMPAT
308     RPCdoneCallback = NULL;
309 #endif
310
311     loadNativeDemangler();
312
313     eventHandler = new BPatch_asyncEventHandler();
314 #if !defined (os_windows)  && !defined (arch_ia64) && !defined (os_osf) && !defined (os_irix)
315     if (!eventHandler->initialize()) {
316       //  not much else we can do in the ctor, except complain (should we abort?)
317       bperr("%s[%d]:  failed to initialize eventHandler, possibly fatal\n",
318             __FILE__, __LINE__);
319     }
320 #endif
321 }
322
323
324 /*
325  * BPatch::~BPatch
326  *
327  * Destructor for BPatch.  Free allocated memory.
328  */
329 void BPatch::BPatch_dtor()
330 {
331     delete info;
332
333     type_Error->decrRefCount();
334     type_Untyped->decrRefCount();
335
336     delete stdTypes;
337
338     bpatch = NULL;
339 }
340
341 bool BPatch::isTypeCheckedInt()
342 {
343   return typeCheckOn;
344 }
345 void BPatch::setTypeCheckingInt(bool x)
346 {
347   typeCheckOn = x;
348 }
349 bool BPatch::parseDebugInfoInt()
350 {
351   return debugParseOn;
352 }
353 bool BPatch::delayedParsingOnInt()
354 {
355   return delayedParsing_;
356 }
357 void BPatch::setDebugParsingInt(bool x)
358 {
359   debugParseOn = x;
360 }
361 bool BPatch::baseTrampDeletionInt()
362 {
363   return baseTrampDeletionOn;
364 }
365 void BPatch::setBaseTrampDeletionInt(bool x)
366 {
367   baseTrampDeletionOn = x;
368 }
369 bool BPatch::isTrampRecursiveInt()
370 {
371   return trampRecursiveOn;
372 }
373 void BPatch::setTrampRecursiveInt(bool x)
374 {
375   trampRecursiveOn = x;
376 }
377 bool BPatch::hasForcedRelocation_NPInt()
378 {
379   return forceRelocation_NP;
380 }
381 void BPatch::setForcedRelocation_NPInt(bool x)
382 {
383   forceRelocation_NP = x;
384 }
385 bool BPatch::autoRelocationOnInt()
386 {
387   return autoRelocation_NP;
388 }
389 void BPatch::setAutoRelocation_NPInt(bool x)
390 {
391   autoRelocation_NP = x;
392 }
393 void BPatch::setDelayedParsingInt(bool x)
394 {
395   delayedParsing_ = x;
396 }
397
398
399
400
401 /*
402  * BPatch::registerErrorCallbackInt
403  *
404  * Registers a function that is to be called by the library when an error
405  * occurs or when there is status to report.  Returns the address of the
406  * previously registered error callback function.
407  *
408  * function     The function to be called.
409  */
410 BPatchErrorCallback BPatch::registerErrorCallbackInt(BPatchErrorCallback function)
411 {
412     BPatchErrorCallback ret;
413
414     ret = errorHandler;
415     errorHandler = function;
416
417     return ret;
418 }
419
420
421 /*
422  * BPatch::registerPostForkCallback
423  *
424  * Registers a function that is to be called by the library when a new
425  * process has been forked off by an mutatee process.
426  *
427  * function     The function to be called.
428  */
429 BPatchForkCallback BPatch::registerPostForkCallbackInt(BPatchForkCallback func)
430 {
431 #if defined(i386_unknown_nt4_0) 
432   reportError(BPatchWarning, 0,
433               "postfork callbacks not implemented on this platform\n");
434   return NULL;
435 #else
436     BPatchForkCallback ret;
437
438     ret = postForkCallback;
439     postForkCallback = func;
440
441     return ret;
442 #endif
443 }
444
445 /*
446  * BPatch::registerPreForkCallback
447  *
448  * Registers a function that is to be called by the library when a process
449  * is about to fork a new process
450  *
451  * function     The function to be called.
452  */
453 BPatchForkCallback BPatch::registerPreForkCallbackInt(BPatchForkCallback func)
454 {
455 #if defined(i386_unknown_nt4_0)
456     reportError(BPatchWarning, 0,
457         "prefork callbacks not implemented on this platform\n");
458     return NULL;
459 #else
460     BPatchForkCallback ret;
461
462     ret = preForkCallback;
463     preForkCallback = func;
464
465     return ret;
466 #endif
467 }
468
469 /*
470  * BPatch::registerExecCallback
471  *
472  * Registers a function that is to be called by the library when a 
473  * process has just completed an exec* call
474  *
475  * func The function to be called.
476  */
477 BPatchExecCallback BPatch::registerExecCallbackInt(BPatchExecCallback func)
478 {
479
480 #if defined(i386_unknown_nt4_0) 
481     reportError(BPatchWarning, 0,
482         "exec callbacks not implemented on this platform\n");
483     return NULL;
484 #else
485     BPatchExecCallback ret;
486
487     ret = execCallback;
488     execCallback = func;
489
490     return ret;
491 #endif
492 }
493
494 /*
495  * BPatch::registerExecCallback
496  *
497  * Registers a function that is to be called by the library when a 
498  * process has just called the exit system call
499  *
500  * func The function to be called.
501  */
502 BPatchExitCallback BPatch::registerExitCallbackInt(BPatchExitCallback func)
503 {
504     BPatchExitCallback ret;
505
506     ret = exitCallback;
507     exitCallback = func;
508     
509     return ret;
510 }
511
512 /*
513  * BPatch::registerOneTimeCodeCallback
514  *
515  * Registers a function that is to be called by the library when a 
516  * oneTimeCode (inferior RPC) is completed.
517  *
518  * func The function to be called.
519  */
520 BPatchOneTimeCodeCallback BPatch::registerOneTimeCodeCallbackInt(BPatchOneTimeCodeCallback func)
521 {
522     BPatchOneTimeCodeCallback ret;
523
524     ret = oneTimeCodeCallback;
525     oneTimeCodeCallback = func;
526
527     return ret;
528 }
529
530 #ifdef IBM_BPATCH_COMPAT
531 BPatchExitCallback BPatch::registerExitCallbackInt(BPatchThreadEventCallback func)
532 {
533
534     BPatchExitCallback ret;
535
536     ret = exitCallback;
537     exitCallback = (BPatchExitCallback) func;
538
539     return ret;
540
541 }
542 #endif
543
544 /*
545  * BPatch::registerDynLibraryCallback
546  *
547  * Registers a function that is to be called by the library when a dynamically
548  * loaded library is loaded or unloaded by a process under the API's control.
549  * Returns the address of the previously registered callback function.
550  *
551  * function     The function to be called.
552  */
553 BPatchDynLibraryCallback
554 BPatch::registerDynLibraryCallbackInt(BPatchDynLibraryCallback function)
555 {
556     BPatchDynLibraryCallback ret;
557
558     ret = dynLibraryCallback;
559     dynLibraryCallback = function;
560
561     return ret;
562 }
563
564
565 /*
566  * BPatch::getEnglishErrorString
567  *
568  * Returns the descriptive error string for the passed error number.
569  *
570  * number       The number that identifies the error.
571  */
572 const char *BPatch::getEnglishErrorString(int /* number */)
573 {
574     return "%s";
575 }
576
577
578 /*
579  * BPatch::reportError
580  *
581  * Report an error using the callback mechanism.
582  *
583  * severity     The severity level of the error.
584  * number       Identifies the error.
585  * str          A string to pass as the first element of the list of strings
586  *              given to the callback function.
587  */
588 void BPatch::reportError(BPatchErrorLevel severity, int number, const char *str)
589 {
590     assert(bpatch != NULL);
591   
592     // don't log BPatchWarning or BPatchInfo messages as "errors"
593     if ((severity == BPatchFatal) || (severity == BPatchSerious))
594         bpatch->lastError = number;
595
596     if (bpatch->errorHandler != NULL) {
597         bpatch->errorHandler(severity, number, &str);
598     } else if ((severity == BPatchFatal) || (severity == BPatchSerious)){
599         fprintf(stdout, "DYNINST ERROR: %s\n", str);
600         fflush(stdout);
601     }
602 }
603
604
605 /*
606  * BPatch::formatErrorString
607  *
608  * Takes a format string with an error message (obtained from
609  * getEnglishErrorString) and an array of parameters that were passed to an
610  * error callback function, and creates a string with the parameters
611  * substituted into it.
612  *
613  * dst          The address into which the formatted string should be copied.
614  * size         If the formatted string is equal to or longer than this number
615  *              of characters, then it will be truncated to size-1 characters
616  *              and terminated with a nul ('\0').
617  * fmt          The format string (returned by a function such as
618  *              getEnglishErrorString).
619  * params       The array of parameters that were passed to an error callback
620  *              function.
621  */
622 void BPatch::formatErrorString(char *dst, int size,
623                                const char *fmt, const char **params)
624 {
625     int cur_param = 0;
626
627     while (size > 1 && *fmt) {
628         if (*fmt == '%') {
629             if (fmt[1] == '\0') {
630                 break;
631             } else if (fmt[1] == '%') {
632                 *dst++ = '%';
633                 size--;
634             } else if (fmt[1] == 's') {
635                 char *p = const_cast<char *>(params[cur_param++]);
636                 while (size > 1 && *p) {
637                     *dst++ = *p++;
638                     size--;
639                 }
640             } else {
641                 // Illegal specifier
642                 *dst++ = fmt[0];
643                 *dst++ = fmt[1];
644                 size -= 2;
645             }
646             fmt += 2;
647         } else {
648             *dst++ = *fmt++;
649             size--;
650         }
651     }
652     if (size > 0)
653         *dst = '\0';
654 }
655
656
657 /*
658  * BPatch::getThreadByPid
659  *
660  * Given a process ID, this function returns a pointer to the associated
661  * BPatch_thread object (or NULL if there is none).  Since a process may be
662  * registered provisionally with a thread object pointer of NULL, the boolean
663  * pointed to by the parameter "exists" is set to true if the pid exists in
664  * the table of processes, and false if it does not.
665  *
666  * pid          The pid to look up.
667  * exists       A pointer to a boolean to fill in with true if the pid exists
668  *              in the table and false if it does not.  NULL may be passed in
669  *              if this information is not required.
670  */
671 BPatch_thread *BPatch::getThreadByPid(int pid, bool *exists)
672 {
673     if (info->threadsByPid.defines(pid)) {
674         if (exists) *exists = true;
675         return info->threadsByPid[pid];
676     } else {
677         if (exists) *exists = false;
678         return NULL;
679     }
680 }
681
682
683 /*
684  * BPatch::getThreads
685  *
686  * Returns a vector of all threads that are currently defined.  Includes
687  * threads created directly using the library and those created with UNIX fork
688  * or Windows NT spawn system calls.  The caller is responsible for deleting
689  * the vector when it is no longer needed.
690  */
691 BPatch_Vector<BPatch_thread *> *BPatch::getThreadsInt()
692 {
693     BPatch_Vector<BPatch_thread *> *result = new BPatch_Vector<BPatch_thread *>;
694
695     dictionary_hash_iter<int, BPatch_thread *> ti(info->threadsByPid);
696
697     int pid;
698     BPatch_thread *thread;
699
700     while (ti.next(pid, thread))
701         result->push_back(thread);
702
703     return result;
704 }
705
706
707 /*
708  * BPatch::registerProvisionalThread
709  *
710  * Register a new process that is not yet associated with a thread.
711  * (this function is called only by createProcess).
712  *
713  * pid          The pid of the process to register.
714  */
715 void BPatch::registerProvisionalThread(int pid)
716 {
717     assert(!info->threadsByPid.defines(pid));
718     info->threadsByPid[pid] = NULL;
719 }
720
721
722 /*
723  * BPatch::registerForkedThread
724  *
725  * Register a new process that is not yet associated with a thread.
726  * (this function is an upcall when a new process is created).
727  *
728  * parentPid            the pid of the parent process.
729  * childPid             The pid of the process to register.
730  * proc                 lower lever handle to process specific stuff
731  *
732  */
733 void BPatch::registerForkedThread(int parentPid, int childPid, process *proc)
734 {
735     assert(!info->threadsByPid.defines(childPid));
736
737     BPatch_thread *parent = info->threadsByPid[parentPid];
738
739     assert(parent);
740     info->threadsByPid[childPid] = new BPatch_thread(childPid, proc);
741
742 #if !defined (os_osf) && !defined(os_windows) && !defined (arch_ia64) && !defined(os_irix)
743     if (!eventHandler->connectToProcess(info->threadsByPid[childPid])) {
744       bperr("%s[%d]:  eventHandler->connectToProcess failed\n", __FILE__, __LINE__);
745     }
746 #endif
747
748     if (postForkCallback) {
749         postForkCallback(parent, info->threadsByPid[childPid]);
750     }
751     // We don't want to touch the bpatch threads here, as they may have been
752     // deleted in the callback
753     // TODO: figure out if they have and remove them from the info list
754 }
755
756 /*
757  * BPatch::registerForkingThread
758  *
759  * Perform whatever processing is necessary when a thread enters
760  * a fork system call. Previously the preForkCallback was made directly.
761  *
762  * forkingPid   pid of the forking process
763  * proc                 lower lever handle to process specific stuff
764  *
765  */
766 void BPatch::registerForkingThread(int forkingPid, process * /*proc*/)
767 {
768     BPatch_thread *forking = info->threadsByPid[forkingPid];
769     // Wouldn't this be the same as proc->thread?
770     assert(forking);
771
772     if (preForkCallback) {
773         preForkCallback(forking, NULL);
774     }
775 }
776
777
778 /*
779  * BPatch::registerExec
780  *
781  * Register a process that has just done an exec call.
782  *
783  * thread       thread that has just performed the exec
784  *
785  */
786 void BPatch::registerExec(BPatch_thread *thread)
787 {
788     // build a new BPatch_image for this one
789     thread->image = new BPatch_image(thread);
790
791     if (execCallback) {
792        execCallback(thread);
793     }
794 }
795
796 void BPatch::registerNormalExit(BPatch_thread *thread, int exitcode)
797 {
798     thread->setExitCode(exitcode);
799     thread->setExitedNormally();
800     if (exitCallback) {
801         exitCallback(thread, ExitedNormally);
802     }
803 }
804
805 void BPatch::registerSignalExit(BPatch_thread *thread, int signalnum)
806 {
807     thread->setExitedViaSignal(signalnum);
808     if (exitCallback) {
809         exitCallback(thread, ExitedViaSignal);
810     }
811 }
812
813
814
815 /*
816  * BPatch::registerThread
817  *
818  * Register a new BPatch_thread object with the BPatch library (this function
819  * is called only by the constructor for BPatch_thread).
820  *
821  * thread       A pointer to the thread to register.
822  */
823 void BPatch::registerThread(BPatch_thread *thread)
824 {
825     assert(!info->threadsByPid.defines(thread->getPid()) ||
826             info->threadsByPid[thread->getPid()] == NULL);
827     info->threadsByPid[thread->getPid()] = thread;
828 }
829
830
831 /*
832  * BPatch::unRegisterThread
833  *
834  * Remove the BPatch_thread associated with a given pid from the list of
835  * threads being managed by the library.
836  *
837  * pid          The pid of the thread to be removed.
838  */
839 void BPatch::unRegisterThread(int pid)
840 {
841     assert(info->threadsByPid.defines(pid));
842     info->threadsByPid.undef(pid);      
843 }
844
845
846 /*
847  * BPatch::createProcessInt
848  *
849  * Create a process and return a BPatch_thread representing it.
850  * Returns NULL upon failure.
851  *
852  * path         The pathname of the executable for the new process.
853  * argv         A list of the arguments for the new process, terminated by a
854  *              NULL.
855  * envp         A list of values that make up the environment for the new
856  *              process, terminated by a NULL.  If envp is NULL, the new
857  *              new process will inherit the environemnt of the parent.
858  * stdin_fd     file descriptor to use for stdin for the application
859  * stdout_fd    file descriptor to use for stdout for the application
860  * stderr_fd    file descriptor to use for stderr for the application
861
862  */
863 BPatch_thread *BPatch::createProcessInt(const char *path, const char *argv[], const char *envp[],
864                                      int stdin_fd, int stdout_fd, int stderr_fd)
865 {
866     clearError();
867
868     BPatch_thread *ret = 
869         new BPatch_thread(path, const_cast<char **>(argv), const_cast<char **>(envp), 
870                           stdin_fd, stdout_fd, stderr_fd);
871
872     if (!ret->proc ||
873        (ret->proc->status() != stopped) ||
874        !ret->proc->isBootstrappedYet()) {
875         delete ret;
876         reportError(BPatchFatal, 68, "create process failed bootstrap");
877         return NULL;
878     }
879 #if !defined (os_osf) && !defined (os_windows)  && !defined(arch_ia64) && !defined(os_irix)
880     if (!eventHandler->connectToProcess(ret)) {
881       bpfatal("%s[%d]: eventHandler->connectToProcess failed\n", __FILE__, __LINE__);
882       fprintf(stderr,"%s[%d]: eventHandler->connectToProcess failed\n", __FILE__, __LINE__);
883       return NULL;
884     }
885 #endif
886
887     ret->proc->collectSaveWorldData = false;
888     //ccw 23 jan 2002 : this forces the user to call
889     //BPatch_thread::enableDumpPatchedImage() if they want to use the save the world
890     //functionality.
891     return ret;
892 }
893
894
895 /*
896  * BPatch::attachProcess
897  *
898  * Attach to a running process and return a BPatch_thread representing it.
899  * Returns NULL upon failure.
900  *
901  * path         The pathname of the executable for the process.
902  * pid          The id of the process to attach to.
903  */
904 BPatch_thread *BPatch::attachProcessInt(const char *path, int pid)
905 {
906     clearError();
907
908     BPatch_thread *ret = new BPatch_thread(path, pid);
909
910     if (!ret->proc ||
911        (ret->proc->status() != stopped) ||
912        !ret->proc->isBootstrappedYet()) {
913         // It would be considerate to (attempt to) leave the process running
914         // at this point (*before* deleting the BPatch_thread handle for it!),
915         // even though it might be in bad shape after the attempted attach.
916         char msg[256];
917         sprintf(msg,"attachProcess failed: process %d may now be killed!",pid);
918         reportError(BPatchWarning, 26, msg);
919         delete ret;
920         return NULL;
921     }
922 #if !defined (os_osf) && !defined (os_windows) && !defined(os_irix) && !defined (arch_ia64)
923     if (!eventHandler->connectToProcess(ret)) {
924       bperr("%s[%d]:  eventHandler->connectToProcess failed\n", __FILE__, __LINE__);
925       return NULL;
926     }
927 #endif
928     ret->proc->collectSaveWorldData = false;
929     //ccw 31 jan 2003 : this forces the user to call
930     //BPatch_thread::enableDumpPatchedImage() if they want to use the save the world
931     //functionality.
932
933     return ret;
934 }
935
936 /*
937  * BPatch::getThreadEvent
938  *
939  * Checks for changes in any child process, and optionally blocks until such a
940  * change has occurred.  Also performs housekeeping on behalf of Dyninst:
941  * - Launches pending oneTimeCode calls (aka inferior RPCs)
942  * - Updates the process object representing each process for which a
943  *   change is detected.
944  *
945  * The return value is true if a change was detected, otherwise it is false.
946  *
947  * block        Set this parameter to true to block waiting for a change,
948  *              set to false to poll and return immediately, whether or not a
949  *              change occurred.
950  */
951 bool BPatch::getThreadEvent(bool block)
952 {
953     launchDeferredOneTimeCode();
954
955     return getThreadEventOnly(block);
956 }
957
958 /*
959  * BPatch::getThreadEventOnly
960  *
961  * Like getThreadEvent (which actually calls this function), this function
962  * checks for changes in any child process, optionally blocking until such a
963  * change occurs.  It also updates the process objects with information about
964  * such changes.  Unlike getThreadEvent, it does not perform any additional
965  * housekeeping like launching deferred RPCs.
966  *
967  * Returns true if a change was detected, otherwise returns false.
968  *
969  * block        Set this parameter to true to block waiting for a change,
970  *              set to false to poll and return immediately, whether or not a
971  *              change occurred.
972  */
973 bool BPatch::getThreadEventOnly(bool block)
974 {
975    bool result = false;
976
977    // Handles all process (object)-level events.
978    
979    pdvector<procevent *> events;
980    result = getSH()->checkForProcessEvents(&events, -1, block);
981
982    pdvector<procevent *> unhandledEvents = getSH()->handleProcessEvents(events);
983
984    for(unsigned i=0; i < unhandledEvents.size(); i++)
985    {
986        // The only thing we expect to see in here is a SIGSTOP from DYNINSTbreakPoint...
987        procevent *cur_event = unhandledEvents[i];
988        process *proc = cur_event->proc;
989        procSignalWhy_t why   = cur_event->why;
990        procSignalWhat_t what = cur_event->what;
991        
992        bool exists;
993        BPatch_thread *thread = getThreadByPid(proc->getPid(), &exists);
994        if (thread == NULL) {
995            if (exists) {
996                bperr("Warning: event on an existing thread, but can't find thread handle\n");
997            } else {
998                bperr( "Warning - wait returned status of an unknown process (%d)\n",
999                        proc->getPid());
1000            }
1001        }
1002        else { // found a thread
1003 #if !defined(os_windows)
1004            if (didProcReceiveSignal(why)) {
1005                thread->lastSignal = what;
1006 #if defined(os_irix)
1007                unsigned int stop_sig = SIGEMT;
1008 #else
1009                unsigned int stop_sig = SIGSTOP;
1010 #endif
1011                if (what != stop_sig) {
1012                    forwardSigToProcess(*cur_event);
1013                }
1014                else {
1015                    thread->setUnreportedStop(true);
1016                }
1017            }
1018            else {
1019               // bperr( "Unhandled event (why %d, what %d) on process %d\n",
1020               // why, what, proc->getPid());
1021                thread->setUnreportedStop(true);
1022            }
1023            
1024 #else // os_windows
1025            thread->setUnreportedStop(true);
1026 #endif
1027        }
1028        delete unhandledEvents[i];
1029    }
1030
1031    return result;
1032 }
1033
1034
1035 /*
1036  * havePendingEvent
1037  *
1038  * Returns true if any thread has stopped or terminated and that fact hasn't
1039  * been reported to the user of the library.  Otherwise, returns false.
1040  */
1041 bool BPatch::havePendingEvent()
1042 {
1043 #if defined(i386_unknown_nt4_0) || defined(mips_unknown_ce2_11) //ccw 20 july 2001 : 28 mar 2001
1044     // On NT, we need to poll for events as often as possible, so that we can
1045     // handle traps.
1046     if (getThreadEvent(false))
1047         return true;
1048 #endif
1049     
1050     // For now, we'll do it by iterating over the threads and checking them,
1051     // and we'll change it to something more efficient later on.
1052     dictionary_hash_iter<int, BPatch_thread *> ti(info->threadsByPid);
1053     
1054     int pid;
1055     BPatch_thread *thread;
1056     
1057     while (ti.next(pid, thread)) {
1058         if (thread != NULL &&
1059             (thread->pendingUnreportedStop() ||
1060              thread->pendingUnreportedTermination())) {
1061             return true;
1062         }
1063     }
1064     return false;
1065 }
1066
1067
1068 /*
1069  * pollForStatusChange
1070  *
1071  * Checks for unreported changes to the status of any child process, and
1072  * returns true if any are detected.  Returns false otherwise.
1073  *
1074  * This function is declared as a friend of BPatch_thread so that it can use
1075  * the BPatch_thread::getThreadEvent call to check for status changes.
1076  */
1077 bool BPatch::pollForStatusChangeInt()
1078 {
1079     if (havePendingEvent())
1080         return true;
1081   
1082     // No changes were previously detected, so check for new changes
1083     return getThreadEvent(false);
1084 }
1085
1086
1087 /*
1088  * waitForStatusChange
1089  *
1090  * Blocks waiting for a change to occur in the running status of a child
1091  * process.  Returns true upon success, false upon failure.
1092  *
1093  * This function is declared as a friend of BPatch_thread so that it can use
1094  * the BPatch_thread::getThreadEvent call to check for status changes.
1095  */
1096 bool BPatch::waitForStatusChange()
1097 {
1098     if (havePendingEvent()) {
1099         return true;
1100     }
1101     
1102     // No changes were previously detected, so wait for a new change
1103     return getThreadEvent(true);
1104 }
1105
1106 /*
1107  * createEnum
1108  *
1109  * This function is a wrapper for the BPatch_type constructors for API/User
1110  * created types.
1111  *
1112  * It returns a pointer to a BPatch_type that was added to the APITypes
1113  * collection.
1114  */
1115 BPatch_type * BPatch::createEnumInt( const char * name, 
1116                                      BPatch_Vector<char *> elementNames,
1117                                      BPatch_Vector<int> elementIds)
1118 {
1119
1120     if (elementNames.size() != elementIds.size()) {
1121       return NULL;
1122     }
1123
1124     BPatch_fieldListType * newType = new BPatch_typeEnum(name);
1125     if (!newType) return NULL;
1126     
1127     APITypes->addType(newType);
1128
1129     // ADD components to type
1130     for (unsigned int i=0; i < elementNames.size(); i++) {
1131         newType->addField(elementNames[i], elementIds[i]);
1132     }
1133
1134     return(newType);
1135 }
1136
1137
1138 /*
1139  * createEnum
1140  *
1141  * This function is a wrapper for the BPatch_type constructors for API/User
1142  * created types.  The user has left element id specification to us
1143  *
1144  * It returns a pointer to a BPatch_type that was added to the APITypes
1145  * collection.
1146  */
1147 BPatch_type * BPatch::createEnumAutoId( const char * name, 
1148                                         BPatch_Vector<char *> elementNames)
1149 {
1150     BPatch_fieldListType * newType = new BPatch_typeEnum(name);
1151
1152     if (!newType) return NULL;
1153     
1154     APITypes->addType(newType);
1155
1156     // ADD components to type
1157     for (unsigned int i=0; i < elementNames.size(); i++) {
1158         newType->addField(elementNames[i], i);
1159     }
1160
1161     return(newType);
1162 }
1163
1164 /*
1165  * createStructs
1166  *
1167  * This function is a wrapper for the BPatch_type constructors for API/User
1168  * created types.
1169  *
1170  * It returns a pointer to a BPatch_type that was added to the APITypes
1171  * collection.
1172  */
1173
1174 BPatch_type * BPatch::createStructInt( const char * name,
1175                                        BPatch_Vector<char *> fieldNames,
1176                                        BPatch_Vector<BPatch_type *> fieldTypes)
1177 {
1178     unsigned int i;
1179     int offset, size;
1180
1181     offset = size = 0;
1182     if (fieldNames.size() != fieldTypes.size()) {
1183       return NULL;
1184     }
1185
1186     //Compute the size of the struct
1187     for (i=0; i < fieldNames.size(); i++) {
1188         BPatch_type *type = fieldTypes[i];
1189         size = type->getSize();
1190         size += size;
1191     }
1192   
1193     BPatch_fieldListType *newType = new BPatch_typeStruct(name);
1194     if (!newType) return NULL;
1195     
1196     APITypes->addType(newType);
1197
1198     // ADD components to type
1199     size = 0;
1200     for (i=0; i < fieldNames.size(); i++) {
1201         BPatch_type *type = fieldTypes[i];
1202         size = type->getSize();
1203         newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
1204   
1205         // Calculate next offset (in bits) into the struct
1206         offset += (size * 8);
1207     }
1208
1209     return(newType);
1210 }
1211
1212 /*
1213  * createUnions
1214  *
1215  * This function is a wrapper for the BPatch_type constructors for API/User
1216  * created types.
1217  *
1218  * It returns a pointer to a BPatch_type that was added to the APITypes
1219  * collection.
1220  */
1221
1222 BPatch_type * BPatch::createUnionInt( const char * name, 
1223                                       BPatch_Vector<char *> fieldNames,
1224                                       BPatch_Vector<BPatch_type *> fieldTypes)
1225 {
1226     unsigned int i;
1227     int offset, size, newsize;
1228     offset = size = newsize = 0;
1229
1230     if (fieldNames.size() != fieldTypes.size()) {
1231         return NULL;
1232     }
1233
1234     // Compute the size of the union
1235     for (i=0; i < fieldTypes.size(); i++) {
1236         BPatch_type *type = fieldTypes[i];
1237         newsize = type->getSize();
1238         if(size < newsize) size = newsize;
1239     }
1240   
1241     BPatch_fieldListType * newType = new BPatch_typeUnion(name);
1242     if (!newType) return NULL;
1243
1244     APITypes->addType(newType);
1245
1246     // ADD components to type
1247     for (i=0; i < fieldNames.size(); i++) {
1248         BPatch_type *type = fieldTypes[i];
1249         size = type->getSize();
1250         newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
1251     }  
1252     return(newType);
1253 }
1254
1255
1256 /*
1257  * createArray for Arrays and SymTypeRanges
1258  *
1259  * This function is a wrapper for the BPatch_type constructors for API/User
1260  * created types.
1261  *
1262  * It returns a pointer to a BPatch_type that was added to the APITypes
1263  * collection.
1264  */
1265 BPatch_type * BPatch::createArrayInt( const char * name, BPatch_type * ptr,
1266                                       unsigned int low, unsigned int hi)
1267 {
1268
1269     BPatch_type * newType;
1270
1271     if (!ptr) {
1272         return NULL;
1273     } else {
1274         newType = new BPatch_typeArray(ptr, low, hi, name);
1275         if (!newType) return NULL;
1276     }
1277
1278     APITypes->addType(newType);
1279
1280     return newType;
1281 }
1282
1283 /*
1284  * createPointer for BPatch_pointers
1285  *
1286  * This function is a wrapper for the BPatch_type constructors for API/User
1287  * created types.
1288  *
1289  * It returns a pointer to a BPatch_type that was added to the APITypes
1290  * collection.
1291  */
1292 BPatch_type * BPatch::createPointerInt(const char * name, BPatch_type * ptr,
1293                                        int size)
1294 {
1295
1296     BPatch_type * newType = new BPatch_typePointer(ptr, name);
1297     if(!newType) return NULL;
1298
1299     APITypes->addType(newType);
1300   
1301     return newType;
1302 }
1303
1304 /*
1305  * createScalar for scalars with a size and no range
1306  *
1307  * This function is a wrapper for the BPatch_type constructors for API/User
1308  * created types.
1309  *
1310  * It returns a pointer to a BPatch_type that was added to the APITypes
1311  * collection.
1312  */
1313
1314 BPatch_type * BPatch::createScalarInt( const char * name, int size)
1315 {
1316     BPatch_type * newType = new BPatch_typeScalar(size, name);
1317     if (!newType) return NULL;
1318
1319     APITypes->addType(newType);
1320  
1321     return newType;
1322 }
1323
1324 /*
1325  * createType for typedefs
1326  *
1327  * This function is a wrapper for the BPatch_type constructors for API/User
1328  * created types.
1329  *
1330  * It returns a pointer to a BPatch_type that was added to the APITypes
1331  * collection.
1332  */
1333 BPatch_type * BPatch::createTypedefInt( const char * name, BPatch_type * ptr)
1334 {
1335     BPatch_type * newType = new BPatch_typeTypedef(ptr, name);
1336
1337     if (!newType) return NULL;
1338
1339     APITypes->addType(newType);
1340   
1341     return newType;
1342 }
1343
1344 bool BPatch::waitUntilStopped(BPatch_thread *appThread){
1345         while (!appThread->isStopped() && !appThread->isTerminated())
1346                 this->waitForStatusChange();
1347
1348         if (!appThread->isStopped())
1349         {
1350                 cerr << "ERROR : process did not signal mutator via stop"
1351                      << endl;
1352                 return false;
1353         }
1354 #if defined(i386_unknown_nt4_0) || \
1355     defined(mips_unknown_ce2_11)
1356         else if((appThread->stopSignal() != EXCEPTION_BREAKPOINT) && 
1357                 (appThread->stopSignal() != -1))
1358         {
1359                 cerr << "ERROR : process stopped on signal different"
1360                      << " than SIGTRAP" << endl;
1361                 return false;
1362         }
1363 #else
1364         else if ((appThread->stopSignal() != SIGSTOP) &&
1365 #if defined(bug_irix_broken_sigstop)
1366                  (appThread->stopSignal() != SIGEMT) &&
1367 #endif 
1368                  (appThread->stopSignal() != SIGHUP)) {
1369                 cerr << "ERROR :  process stopped on signal "
1370                      << "different than SIGSTOP" << endl;
1371                 return false;
1372         }
1373 #endif
1374         return true;
1375 }
1376
1377 #ifdef IBM_BPATCH_COMPAT
1378
1379 /*
1380  * Register a function to call when an RPC (i.e. oneshot) is done.
1381  *
1382  * dyninst version is a callback that is defined for BPatch_thread
1383  *
1384  */
1385 BPatchThreadEventCallback BPatch::registerRPCTerminationCallbackInt(BPatchThreadEventCallback func)
1386 {
1387     BPatchThreadEventCallback ret;
1388
1389     ret = RPCdoneCallback;
1390     RPCdoneCallback = func;
1391
1392     return ret;
1393 }
1394
1395 void setLogging_NP(BPatchLoggingCallback, int)
1396 {
1397     return;
1398 }
1399
1400 int BPatch::getLastErrorCodeInt()
1401 {
1402   return lastError;
1403 }
1404 BPatchThreadEventCallback BPatch::registerDetachDoneCallbackInt(BPatchThreadEventCallback)
1405 {
1406   return NULL;
1407 }
1408 BPatchThreadEventCallback BPatch::registerSnippetRemovedCallbackInt(BPatchThreadEventCallback)
1409 {
1410   return NULL
1411 }
1412 #endif
1413
1414 /*
1415  * BPatch::launchDeferredOneTimeCode
1416  *
1417  * Launch any deferred oneTimeCode calls (aka inferior RPCs) that might exist,
1418  * if it is now okay to do so.
1419  */
1420 void BPatch::launchDeferredOneTimeCode()
1421 {
1422     for (unsigned int p = 0; p < processVec.size(); p++) {
1423         process *proc = processVec[p];
1424
1425         if (proc == NULL)
1426             continue;
1427         
1428         if (!proc->isAttached() ||
1429             proc->status() == neonatal)
1430             continue;
1431
1432         proc->getRpcMgr()->launchRPCs(proc->status() == running);        
1433     }
1434 }
1435
1436 BPatch_stats &BPatch::getBPatchStatisticsInt()
1437 {
1438   updateStats();
1439   return stats;
1440 }
1441 //  updateStats() -- an internal function called before returning
1442 //  statistics buffer to caller of BPatch_getStatistics(),
1443 //  -- just copies global variable statistics counters into 
1444 //  the buffer which is returned to the user.
1445 void BPatch::updateStats() 
1446 {
1447   stats.pointsUsed = pointsUsed;
1448   stats.totalMiniTramps = totalMiniTramps;
1449   stats.trampBytes = trampBytes;
1450   stats.ptraceOtherOps = ptraceOtherOps;
1451   stats.ptraceOps = ptraceOps;
1452   stats.ptraceBytes = ptraceBytes;
1453   stats.insnGenerated = insnGenerated;
1454 }