Problem 1:
[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.112 2006/02/14 23:50:15 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 "process.h"
56 #include "BPatch_libInfo.h"
57 #include "BPatch_collections.h"
58 #include "BPatch_thread.h"
59 #include "BPatch_asyncEventHandler.h"
60 #include "callbacks.h"
61 #include "common/h/timing.h"
62 #include "showerror.h"
63
64 #if defined(i386_unknown_nt4_0) || defined(mips_unknown_ce2_11) //ccw 20 july 2000 : 28 mar 2001
65 #include "nt_signal_emul.h"
66 #endif
67
68 extern void loadNativeDemangler();
69
70 BPatch *BPatch::bpatch = NULL;
71
72 //  global stat vars defined in stats.C
73 extern unsigned int trampBytes;
74 extern unsigned int pointsUsed;
75 extern unsigned int insnGenerated;
76 extern unsigned int totalMiniTramps;
77 extern unsigned int ptraceOtherOps;
78 extern unsigned int ptraceOps;
79 extern unsigned int ptraceBytes;
80
81 extern BPatch_asyncEventHandler *global_async_event_handler;
82 void defaultErrorFunc(BPatchErrorLevel level, int num, const char **params);
83
84 extern void dyninst_yield();
85
86 /*
87  * BPatch::BPatch
88  *
89  * Constructor for BPatch.  Performs one-time initialization needed by the
90  * library.
91  */
92 BPatch::BPatch()
93   : info(NULL),
94     typeCheckOn(true),
95     lastError(0),
96     debugParseOn(true),
97     baseTrampDeletionOn(false),
98     trampRecursiveOn(false),
99     forceRelocation_NP(false),
100     autoRelocation_NP(true),
101     trampMergeOn(false),
102     asyncActive(false),
103     delayedParsing_(false),
104     systemPrelinkCommand(NULL),
105     mutateeStatusChange(false),
106     builtInTypes(NULL),
107     stdTypes(NULL),
108     type_Error(NULL),
109     type_Untyped(NULL)
110 {
111     if (!global_mutex) {
112       global_mutex = new eventLock();
113       extern bool mutex_created;
114       mutex_created = true;
115     }
116
117     global_mutex->_Lock(FILE__, __LINE__);
118     memset(&stats, 0, sizeof(BPatch_stats));
119     extern bool init();
120
121     // Save a pointer to the one-and-only bpatch object.
122     if (bpatch == NULL){
123        bpatch = this;
124     }
125     
126     initDefaultPointFrequencyTable();
127     BPatch::bpatch->registerErrorCallback(defaultErrorFunc);
128     bpinfo("installed default error reporting function");
129     initCyclesPerSecond();
130     
131     init_debug();
132
133     /*
134      * Create the list of processes.
135      */
136     info = new BPatch_libInfo();
137
138     /*
139      * Create the "error" and "untyped" types.
140      */
141     type_Error   = BPatch_type::createFake("<error>");
142     type_Untyped = BPatch_type::createFake("<no type>");
143
144     /*
145      * Initialize hash table of standard types.
146      */
147     BPatch_type *newType;
148     stdTypes = BPatch_typeCollection::getGlobalTypeCollection();
149     stdTypes->addType(newType = new BPatch_typeScalar(-1, sizeof(int), "int"));
150     newType->decrRefCount();
151     BPatch_type *charType = new BPatch_typeScalar(-2, sizeof(char), "char");
152     stdTypes->addType(charType);
153     stdTypes->addType(newType = new BPatch_typePointer(-3, charType, "char *"));
154     charType->decrRefCount();
155     newType->decrRefCount();
156     BPatch_type *voidType = new BPatch_typeScalar(-11, 0, "void");
157     stdTypes->addType(voidType);
158     stdTypes->addType(newType = new BPatch_typePointer(-4, voidType, "void *"));
159     voidType->decrRefCount();
160     newType->decrRefCount();
161     stdTypes->addType(newType = new BPatch_typeScalar(-12, sizeof(float), "float"));
162     newType->decrRefCount();
163 #if defined(i386_unknown_nt4_0)
164     stdTypes->addType(newType = new BPatch_typeScalar(-31, sizeof(LONGLONG), "long long"));    
165 #else
166     stdTypes->addType(newType = new BPatch_typeScalar(-31, sizeof(long long), "long long"));
167 #endif
168     newType->decrRefCount();
169
170     /*
171      * Initialize hash table of API types.
172      */
173     APITypes = BPatch_typeCollection::getGlobalTypeCollection();
174
175     /*
176      *  Initialize hash table of Built-in types.
177      *  Negative type numbers defined in the gdb stab-docs
178      */
179      
180     builtInTypes = new BPatch_builtInTypeCollection;
181     
182     // NOTE: integral type  mean twos-complement
183     // -1  int, 32 bit signed integral type
184     // in stab document, size specified in bits, system size is in bytes
185     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-1, 4, "int"));
186     newType->decrRefCount();
187     // -2  char, 8 bit type holding a character. GDB & dbx(AIX) treat as signed
188     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-2, 1, "char"));
189     newType->decrRefCount();
190     // -3  short, 16 bit signed integral type
191     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-3, 2, "short"));
192     newType->decrRefCount();
193     // -4  long, 32/64 bit signed integral type
194     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-4, sizeof(long), "long"));
195     newType->decrRefCount();
196     // -5  unsigned char, 8 bit unsigned integral type
197     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-5, 1, "unsigned char"));
198     newType->decrRefCount();
199     // -6  signed char, 8 bit signed integral type
200     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-6, 1, "signed char"));
201     newType->decrRefCount();
202     // -7  unsigned short, 16 bit unsigned integral type
203     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-7, 2, "unsigned short"));
204     newType->decrRefCount();
205     // -8  unsigned int, 32 bit unsigned integral type
206     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-8, 4, "unsigned int"));
207     newType->decrRefCount();
208     // -9  unsigned, 32 bit unsigned integral type
209     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-9, 4, "unsigned"));
210     newType->decrRefCount();
211     // -10 unsigned long, 32 bit unsigned integral type
212     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-10, sizeof(unsigned long), "unsigned long"));
213     newType->decrRefCount();
214     // -11 void, type indicating the lack of a value
215     //  XXX-size may not be correct jdd 4/22/99
216     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-11, 0, "void"));
217     newType->decrRefCount();
218     // -12 float, IEEE single precision
219     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-12, sizeof(float), "float"));
220     newType->decrRefCount();
221     // -13 double, IEEE double precision
222     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-13, sizeof(double), "double"));
223     newType->decrRefCount();
224     // -14 long double, IEEE double precision, size may increase in future
225     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-14, sizeof(long double), "long double"));
226     newType->decrRefCount();
227     // -15 integer, 32 bit signed integral type
228     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-15, 4, "integer"));
229     newType->decrRefCount();
230     // -16 boolean, 32 bit type. GDB/GCC 0=False, 1=True, all other values
231     //     have unspecified meaning
232     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-16, sizeof(bool), "boolean"));
233     newType->decrRefCount();
234     // -17 short real, IEEE single precision
235     //  XXX-size may not be correct jdd 4/22/99
236     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-17, sizeof(float), "short real"));
237     newType->decrRefCount();
238     // -18 real, IEEE double precision XXX-size may not be correct jdd 4/22/99 
239     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-18, sizeof(double), "real"));
240     newType->decrRefCount();
241     // -19 stringptr XXX- size of void * -- jdd 4/22/99
242     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-19, sizeof(void *), "stringptr"));
243     newType->decrRefCount();
244     // -20 character, 8 bit unsigned character type
245     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-20, 1, "character"));
246     newType->decrRefCount();
247     // -21 logical*1, 8 bit type (Fortran, used for boolean or unsigned int)
248     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-21, 1, "logical*1"));
249     newType->decrRefCount();
250     // -22 logical*2, 16 bit type (Fortran, some for boolean or unsigned int)
251     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-22, 2, "logical*2"));
252     newType->decrRefCount();
253     // -23 logical*4, 32 bit type (Fortran, some for boolean or unsigned int)
254     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-23, 4, "logical*4"));
255     newType->decrRefCount();
256     // -24 logical, 32 bit type (Fortran, some for boolean or unsigned int)
257     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-24, 4, "logical"));
258     newType->decrRefCount();
259     // -25 complex, consists of 2 IEEE single-precision floating point values
260     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-25, sizeof(float)*2, "complex"));
261     newType->decrRefCount();
262     // -26 complex, consists of 2 IEEE double-precision floating point values
263     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-26, sizeof(double)*2, "complex*16"));
264     newType->decrRefCount();
265     // -27 integer*1, 8 bit signed integral type
266     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-27, 1, "integer*1"));
267     newType->decrRefCount();
268     // -28 integer*2, 16 bit signed integral type
269     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-28, 2, "integer*2"));
270     newType->decrRefCount();
271
272 /* Quick hack to make integer*4 compatible with int for Fortran
273    jnb 6/20/01 */
274
275     // This seems questionable - let's try removing that hack - jmo 05/21/04
276     /*
277     builtInTypes->addBuiltInType(newType = new BPatch_type("int",-29,
278                                                  BPatch_built_inType, 4));
279     newType->decrRefCount();
280     */
281     // -29 integer*4, 32 bit signed integral type
282     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-29, 4, "integer*4"));
283     newType->decrRefCount();
284     // -30 wchar, Wide character, 16 bits wide, unsigned (unknown format)
285     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-30, 2, "wchar"));
286     newType->decrRefCount();
287 #ifdef i386_unknown_nt4_0
288     // -31 long long, 64 bit signed integral type
289     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-31, sizeof(LONGLONG), "long long"));
290     newType->decrRefCount();
291     // -32 unsigned long long, 64 bit unsigned integral type
292     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-32, sizeof(ULONGLONG), "unsigned long long"));
293     newType->decrRefCount();
294 #else
295     // -31 long long, 64 bit signed integral type
296     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-31, sizeof(long long), "long long"));
297     newType->decrRefCount();
298     // -32 unsigned long long, 64 bit unsigned integral type
299     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-32, sizeof(unsigned long long), "unsigned long long"));
300     newType->decrRefCount();
301 #endif
302     // -33 logical*8, 64 bit unsigned integral type
303     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-33, 8, "logical*8"));
304     newType->decrRefCount();
305     // -34 integer*8, 64 bit signed integral type
306     builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-34, 8, "integer*8"));
307     newType->decrRefCount();
308
309     loadNativeDemangler();
310
311     global_async_event_handler = new BPatch_asyncEventHandler();
312 #if defined(cap_async_events)
313     if (!global_async_event_handler->initialize()) {
314       //  not much else we can do in the ctor, except complain (should we abort?)
315       bperr("%s[%d]:  failed to initialize asyncEventHandler, possibly fatal\n",
316             __FILE__, __LINE__);
317     }
318 #endif
319     global_mutex->_Unlock(FILE__, __LINE__);
320 }
321
322
323 /*
324  * BPatch::~BPatch
325  *
326  * Destructor for BPatch.  Free allocated memory.
327  */
328 void BPatch::BPatch_dtor()
329 {
330     delete info;
331
332     type_Error->decrRefCount();
333     type_Untyped->decrRefCount();
334
335     if (stdTypes)
336         BPatch_typeCollection::freeTypeCollection(stdTypes);
337     if (APITypes)
338         BPatch_typeCollection::freeTypeCollection(APITypes);
339
340
341     if(systemPrelinkCommand){
342         delete [] systemPrelinkCommand;
343     }
344     bpatch = NULL;
345 }
346
347 char * BPatch::getPrelinkCommandInt(){
348         return systemPrelinkCommand;
349 }
350
351 void BPatch::setPrelinkCommandInt(char *command){
352
353         if(systemPrelinkCommand){
354                 delete [] systemPrelinkCommand;
355         }
356         systemPrelinkCommand = new char[strlen(command)+1];
357         memcpy(systemPrelinkCommand, command, strlen(command)+1);
358 }
359
360 bool BPatch::isTypeCheckedInt()
361 {
362   return typeCheckOn;
363 }
364 void BPatch::setTypeCheckingInt(bool x)
365 {
366   typeCheckOn = x;
367 }
368 bool BPatch::parseDebugInfoInt()
369 {
370   return debugParseOn;
371 }
372 bool BPatch::delayedParsingOnInt()
373 {
374   return delayedParsing_;
375 }
376 void BPatch::setDebugParsingInt(bool x)
377 {
378   debugParseOn = x;
379 }
380 bool BPatch::baseTrampDeletionInt()
381 {
382   return baseTrampDeletionOn;
383 }
384 void BPatch::setBaseTrampDeletionInt(bool x)
385 {
386   baseTrampDeletionOn = x;
387 }
388 bool BPatch::isTrampRecursiveInt()
389 {
390   return trampRecursiveOn;
391 }
392 void BPatch::setTrampRecursiveInt(bool x)
393 {
394   trampRecursiveOn = x;
395 }
396 bool BPatch::hasForcedRelocation_NPInt()
397 {
398   return forceRelocation_NP;
399 }
400 void BPatch::setForcedRelocation_NPInt(bool x)
401 {
402   forceRelocation_NP = x;
403 }
404 bool BPatch::autoRelocationOnInt()
405 {
406   return autoRelocation_NP;
407 }
408 void BPatch::setAutoRelocation_NPInt(bool x)
409 {
410   autoRelocation_NP = x;
411 }
412 void BPatch::setDelayedParsingInt(bool x)
413 {
414   delayedParsing_ = x;
415 }
416 bool BPatch::isMergeTrampInt()
417 {
418   return trampMergeOn;
419 }
420 void BPatch::setMergeTrampInt(bool x)
421 {
422   trampMergeOn = x; 
423 }
424
425
426
427
428 /*
429  * BPatch::registerErrorCallbackInt
430  *
431  * Registers a function that is to be called by the library when an error
432  * occurs or when there is status to report.  Returns the address of the
433  * previously registered error callback function.
434  *
435  * function     The function to be called.
436  */
437
438
439 BPatchErrorCallback BPatch::registerErrorCallbackInt(BPatchErrorCallback function)
440 {
441     BPatchErrorCallback ret = NULL;
442     ErrorCallback *cb = new ErrorCallback(function);
443
444     pdvector<CallbackBase *> cbs;
445     getCBManager()->removeCallbacks(evtError, cbs);
446     getCBManager()->registerCallback(evtError, cb);
447     if (cbs.size()) {
448       mailbox_printf("%s[%d]:  removed %d error cbs\n", FILE__, __LINE__, cbs.size());
449       ErrorCallback *ercb = (ErrorCallback *) cbs[0];
450       ret = ercb->getFunc();
451     }
452
453     return ret;
454 }
455
456
457 /*
458  * BPatch::registerPostForkCallback
459  *
460  * Registers a function that is to be called by the library when a new
461  * process has been forked off by an mutatee process.
462  *
463  * function     The function to be called.
464  */
465 BPatchForkCallback BPatch::registerPostForkCallbackInt(BPatchForkCallback func)
466 {
467 #if defined(i386_unknown_nt4_0) 
468   reportError(BPatchWarning, 0,
469               "postfork callbacks not implemented on this platform\n");
470   return NULL;
471 #else
472     BPatchForkCallback ret = NULL;
473     ForkCallback *cb = new ForkCallback(func);
474
475     pdvector<CallbackBase *> cbs;
476     getCBManager()->removeCallbacks(evtPostFork, cbs);
477     getCBManager()->registerCallback(evtPostFork, cb);
478
479     if (cbs.size()) {
480       ForkCallback *fcb = (ForkCallback *) cbs[0];
481       ret =  fcb->getFunc();
482     }
483
484     return ret;
485 #endif
486 }
487
488 /*
489  * BPatch::registerPreForkCallback
490  *
491  * Registers a function that is to be called by the library when a process
492  * is about to fork a new process
493  *
494  * function     The function to be called.
495  */
496 BPatchForkCallback BPatch::registerPreForkCallbackInt(BPatchForkCallback func)
497 {
498 #if defined(i386_unknown_nt4_0)
499     reportError(BPatchWarning, 0,
500         "prefork callbacks not implemented on this platform\n");
501     return NULL;
502 #else
503     BPatchForkCallback ret = NULL;
504     ForkCallback *cb = new ForkCallback(func);
505
506     pdvector<CallbackBase *> cbs;
507     getCBManager()->removeCallbacks(evtPreFork, cbs);
508     getCBManager()->registerCallback(evtPreFork, cb);
509     if (cbs.size()) {
510       ForkCallback *fcb = (ForkCallback *) cbs[0];
511       ret =  fcb->getFunc();
512     }
513
514     return ret;
515 #endif
516 }
517
518 /*
519  * BPatch::registerExecCallback
520  *
521  * Registers a function that is to be called by the library when a 
522  * process has just completed an exec* call
523  *
524  * func The function to be called.
525  */
526 BPatchExecCallback BPatch::registerExecCallbackInt(BPatchExecCallback func)
527 {
528
529 #if defined(i386_unknown_nt4_0) 
530     reportError(BPatchWarning, 0,
531         "exec callbacks not implemented on this platform\n");
532     return NULL;
533 #else
534     BPatchExecCallback ret = NULL;
535
536     pdvector<CallbackBase *> cbs;
537     ExecCallback *cb = new ExecCallback(func);
538     getCBManager()->removeCallbacks(evtExec, cbs);
539     getCBManager()->registerCallback(evtExec, cb);
540     if (cbs.size()) {
541       ExecCallback *fcb = (ExecCallback *) cbs[0];
542       ret =  fcb->getFunc();
543     }
544
545     return ret;
546
547 #endif
548 }
549
550 /*
551  * BPatch::registerExitCallback
552  *
553  * Registers a function that is to be called by the library when a 
554  * process has just called the exit system call
555  *
556  * func The function to be called.
557  */
558 BPatchExitCallback BPatch::registerExitCallbackInt(BPatchExitCallback func)
559 {
560     BPatchExitCallback ret = NULL;
561     ExitCallback *cb = new ExitCallback(func);
562
563     pdvector<CallbackBase *> cbs;
564     getCBManager()->removeCallbacks(evtProcessExit, cbs);
565     getCBManager()->registerCallback(evtProcessExit, cb);
566     if (cbs.size()) {
567       ExitCallback *fcb = (ExitCallback *) cbs[0];
568       ret =  fcb->getFunc();
569     }
570
571     return ret;
572 }
573
574 /*
575  * BPatch::registerOneTimeCodeCallback
576  *
577  * Registers a function that is to be called by the library when a 
578  * oneTimeCode (inferior RPC) is completed.
579  *
580  * func The function to be called.
581  */
582 BPatchOneTimeCodeCallback BPatch::registerOneTimeCodeCallbackInt(BPatchOneTimeCodeCallback func)
583 {
584     BPatchOneTimeCodeCallback ret = NULL;
585     OneTimeCodeCallback *cb = new OneTimeCodeCallback(func);
586
587     pdvector<CallbackBase *> cbs;
588     getCBManager()->removeCallbacks(evtOneTimeCode, cbs);
589     getCBManager()->registerCallback(evtOneTimeCode, cb);
590     if (cbs.size()) {
591       OneTimeCodeCallback *fcb = (OneTimeCodeCallback *) cbs[0];
592       ret =  fcb->getFunc();
593     }
594
595     return ret;
596 }
597
598 #ifdef IBM_BPATCH_COMPAT
599 BPatchExitCallback BPatch::registerExitCallbackDPCL(BPatchThreadEventCallback func)
600 {
601
602     BPatchExitCallback ret = NULL;
603
604     ExitCallback *cb = new ExitCallback(func);
605     pdvector<CallbackBase *> cbs;
606     getCBManager()->removeCallbacks(evtProcessExit, cbs);
607     getCBManager()->registerCallback(evtProcessExit, cb);
608     if (cbs.size()) {
609       ExitCallback *fcb = (ExitCallback *) cbs[0];
610       ret =  fcb->getFunc();
611     }
612
613     return ret;
614 }
615 #endif
616
617 /*
618  * BPatch::registerDynLibraryCallback
619  *
620  * Registers a function that is to be called by the library when a dynamically
621  * loaded library is loaded or unloaded by a process under the API's control.
622  * Returns the address of the previously registered callback function.
623  *
624  * function     The function to be called.
625  */
626 BPatchDynLibraryCallback
627 BPatch::registerDynLibraryCallbackInt(BPatchDynLibraryCallback function)
628 {
629
630     BPatchDynLibraryCallback ret = NULL;
631     DynLibraryCallback *cb = new DynLibraryCallback(function);
632
633     pdvector<CallbackBase *> cbs;
634     getCBManager()->removeCallbacks(evtLoadLibrary, cbs);
635     getCBManager()->registerCallback(evtLoadLibrary, cb);
636     if (cbs.size()) {
637       DynLibraryCallback *fcb = (DynLibraryCallback *) cbs[0];
638       ret =  fcb->getFunc();
639     }
640
641     return ret;
642 }
643
644
645 /*
646  * BPatch::getEnglishErrorString
647  *
648  * Returns the descriptive error string for the passed error number.
649  *
650  * number       The number that identifies the error.
651  */
652 const char *BPatch::getEnglishErrorString(int /* number */)
653 {
654     return "%s";
655 }
656
657
658 /*
659  * BPatch::reportError
660  *
661  * Report an error using the callback mechanism.
662  *
663  * severity     The severity level of the error.
664  * number       Identifies the error.
665  * str          A string to pass as the first element of the list of strings
666  *              given to the callback function.
667  */
668 void BPatch::reportError(BPatchErrorLevel severity, int number, const char *str)
669 {
670     assert(bpatch != NULL);
671     assert(global_mutex);
672     assert(global_mutex->depth());
673     // don't log BPatchWarning or BPatchInfo messages as "errors"
674     if ((severity == BPatchFatal) || (severity == BPatchSerious))
675         bpatch->lastError = number;
676
677     pdvector<CallbackBase *> cbs;
678     if (! getCBManager()->dispenseCallbacksMatching(evtError, cbs)) {
679       fprintf(stdout, "%s[%d]:  DYNINST ERROR:\n %s\n", FILE__, __LINE__, str);
680       fflush(stdout);
681       return; 
682     }
683
684     for (unsigned int i = 0; i < cbs.size(); ++i) {
685       ErrorCallback &cb = *((ErrorCallback *) cbs[i]);
686       cb(severity, number, str); 
687     }
688 }
689
690
691 /*
692  * BPatch::formatErrorString
693  *
694  * Takes a format string with an error message (obtained from
695  * getEnglishErrorString) and an array of parameters that were passed to an
696  * error callback function, and creates a string with the parameters
697  * substituted into it.
698  *
699  * dst          The address into which the formatted string should be copied.
700  * size         If the formatted string is equal to or longer than this number
701  *              of characters, then it will be truncated to size-1 characters
702  *              and terminated with a nul ('\0').
703  * fmt          The format string (returned by a function such as
704  *              getEnglishErrorString).
705  * params       The array of parameters that were passed to an error callback
706  *              function.
707  */
708 void BPatch::formatErrorString(char *dst, int size,
709                                const char *fmt, const char **params)
710 {
711     int cur_param = 0;
712
713     while (size > 1 && *fmt) {
714         if (*fmt == '%') {
715             if (fmt[1] == '\0') {
716                 break;
717             } else if (fmt[1] == '%') {
718                 *dst++ = '%';
719                 size--;
720             } else if (fmt[1] == 's') {
721                 char *p = const_cast<char *>(params[cur_param++]);
722                 while (size > 1 && *p) {
723                     *dst++ = *p++;
724                     size--;
725                 }
726             } else {
727                 // Illegal specifier
728                 *dst++ = fmt[0];
729                 *dst++ = fmt[1];
730                 size -= 2;
731             }
732             fmt += 2;
733         } else {
734             *dst++ = *fmt++;
735             size--;
736         }
737     }
738     if (size > 0)
739         *dst = '\0';
740 }
741
742 static char *lvl_str(BPatchErrorLevel lvl)
743 {
744   switch(lvl) {
745     case BPatchFatal: return "--FATAL--";
746     case BPatchSerious: return "--SERIOUS--";
747     case BPatchWarning: return "--WARN--";
748     case BPatchInfo: return "--INFO--";
749   };
750   return "BAD ERR CODE";
751 }
752
753 void defaultErrorFunc(BPatchErrorLevel level, int num, const char **params)
754 {
755     char line[256];
756
757     if ((level == BPatchWarning) || (level == BPatchInfo)) {
758          // ignore low level errors/warnings in the default reporter
759          return;
760     }
761
762     const char *msg = BPatch::bpatch->getEnglishErrorString(num);
763     BPatch::bpatch->formatErrorString(line, sizeof(line), msg, params);
764
765     if (num != -1) {
766        fprintf(stderr,"%s #%d: %s\n", lvl_str(level),num, line);
767     }
768 }
769
770
771 /*
772  * BPatch::getThreadByPid
773  *
774  * Given a process ID, this function returns a pointer to the associated
775  * BPatch_thread object (or NULL if there is none).  Since a process may be
776  * registered provisionally with a thread object pointer of NULL, the boolean
777  * pointed to by the parameter "exists" is set to true if the pid exists in
778  * the table of processes, and false if it does not.
779  *
780  * pid          The pid to look up.
781  * exists       A pointer to a boolean to fill in with true if the pid exists
782  *              in the table and false if it does not.  NULL may be passed in
783  *              if this information is not required.
784  */
785 BPatch_process *BPatch::getProcessByPid(int pid, bool *exists)
786 {
787     if (info->procsByPid.defines(pid)) {
788         if (exists) *exists = true;
789         BPatch_process *proc = info->procsByPid[pid];
790         return proc;
791     } else {
792         if (exists) *exists = false;
793         return NULL;
794     }
795 }
796
797 BPatch_thread *BPatch::getThreadByPid(int pid, bool *exists)
798 {
799    BPatch_process *p = getProcessByPid(pid, exists);
800    if (!exists)
801       return NULL;
802    assert(p->threads.size() > 0);
803    return p->threads[0];
804 }
805
806
807 /*
808  * BPatch::getThreads
809  *
810  * Returns a vector of all threads that are currently defined.  Includes
811  * threads created directly using the library and those created with UNIX fork
812  * or Windows NT spawn system calls.  The caller is responsible for deleting
813  * the vector when it is no longer needed.
814  */
815 BPatch_Vector<BPatch_thread *> *BPatch::getThreadsInt()
816 {
817     BPatch_Vector<BPatch_thread *> *result = new BPatch_Vector<BPatch_thread *>;
818
819     dictionary_hash_iter<int, BPatch_process *> ti(info->procsByPid);
820
821     int pid;
822     BPatch_process *proc;
823
824     while (ti.next(pid, proc))
825     {
826        assert(proc);
827        assert(proc->threads.size() > 0);
828        result->push_back(proc->threads[0]);
829     }
830
831     return result;
832 }
833
834
835 /*
836  * BPatch::registerProvisionalThread
837  *
838  * Register a new process that is not yet associated with a thread.
839  * (this function is called only by createProcess).
840  *
841  * pid          The pid of the process to register.
842  */
843 void BPatch::registerProvisionalThread(int pid)
844 {
845     assert(!info->procsByPid.defines(pid));
846     info->procsByPid[pid] = NULL;
847 }
848
849
850 /*
851  * BPatch::registerForkedProcess
852  *
853  * Register a new process that is not yet associated with a thread.
854  * (this function is an upcall when a new process is created).
855  *
856  * parentPid            the pid of the parent process.
857  * childPid             The pid of the process to register.
858  * proc                 lower lever handle to process specific stuff
859  *
860  */
861 void BPatch::registerForkedProcess(process *parentProc, process *childProc)
862 {
863     int parentPid = parentProc->getPid();
864     int childPid = childProc->getPid();
865
866     forkexec_printf("BPatch: registering fork, parent %d, child %d\n",
867                     parentPid, childPid);
868     assert(getProcessByPid(childPid) == NULL);
869     
870     BPatch_process *parent = getProcessByPid(parentPid);
871     assert(parent);
872     parent->isVisiblyStopped = true;
873     
874     assert(parent);
875     BPatch_process *child = new BPatch_process(childProc);
876     
877 #if defined(cap_async_events)
878     if (!getAsync()->connectToProcess(child)) {
879         bperr("%s[%d]:  asyncEventHandler->connectToProcess failed\n", __FILE__, __LINE__);
880     }
881     else 
882         asyncActive = true;
883 #endif
884     forkexec_printf("Successfully connected socket to child\n");
885     
886     
887     pdvector<CallbackBase *> cbs;
888     getCBManager()->dispenseCallbacksMatching(evtPostFork,cbs);
889     
890     for (unsigned int i = 0; i < cbs.size(); ++i) {
891         assert( cbs[i] );
892         ForkCallback &cb = *((ForkCallback *) cbs[i]);
893         cb(parent->threads[0], child->threads[0]);
894     }
895
896     // Re-lookup the process pointers as they may have been deleted.
897     continueIfExists(parentPid);
898     continueIfExists(childPid);
899
900     forkexec_printf("BPatch: finished registering fork, parent %d, child %d\n",
901                     parentPid, childPid);
902 }
903
904 /*
905  * BPatch::registerForkingThread
906  *
907  * Perform whatever processing is necessary when a thread enters
908  * a fork system call. Previously the preForkCallback was made directly.
909  *
910  * forkingPid   pid of the forking process
911  * proc                 lower lever handle to process specific stuff
912  *
913  */
914 void BPatch::registerForkingProcess(int forkingPid, process * /*proc*/)
915 {
916     BPatch_process *forking = getProcessByPid(forkingPid);
917     assert(forking);
918     forking->isVisiblyStopped = true;
919
920     pdvector<CallbackBase *> cbs;
921     getCBManager()->dispenseCallbacksMatching(evtPreFork,cbs);
922     for (unsigned int i = 0; i < cbs.size(); ++i) {
923         assert(cbs[i]);
924         ForkCallback &cb = *((ForkCallback *) cbs[i]);
925         cb(forking->threads[0], NULL);
926     }
927
928     // Re-lookup since we made callbacks
929     continueIfExists(forkingPid);
930 }
931
932
933 /*
934  * BPatch::registerExecEntry
935  *
936  * Register a process that has just entered exec
937  *
938  * Currently doesn't do anything, as there is no "just before exec"
939  * callback in the API.
940  */
941
942 void BPatch::registerExecEntry(process *p, char *) {
943     continueIfExists(p->getPid());
944 }    
945
946 /*
947  * BPatch::registerExecExit
948  *
949  * Register a process that has just done an exec call.
950  *
951  * thread       thread that has just performed the exec
952  *
953  */
954
955 void BPatch::registerExecExit(process *proc)
956 {
957     int execPid = proc->getPid();
958     BPatch_process *process = getProcessByPid(execPid);
959     assert(process);
960     process->isVisiblyStopped = true;
961
962    // build a new BPatch_image for this one
963    if (process->image)
964        delete process->image;
965    process->image = new BPatch_image(process);
966    
967     pdvector<CallbackBase *> cbs;
968     getCBManager()->dispenseCallbacksMatching(evtExec,cbs);
969     for (unsigned int i = 0; i < cbs.size(); ++i) {
970         ExecCallback &cb = *((ExecCallback *) cbs[i]);
971         cb(process->threads[0]);
972     }
973     continueIfExists(execPid);
974
975 }
976
977 void BPatch::registerNormalExit(process *proc, int exitcode)
978 {
979    if (!proc)
980       return;
981
982    int pid = proc->getPid();
983
984    BPatch_process *process = getProcessByPid(pid);
985    BPatch_thread *thrd = process->getThreadByIndex(0);
986    process->isVisiblyStopped = true;
987
988    if (!process)
989      return;
990
991    process->setExitCode(exitcode);
992    process->setExitedNormally();
993    process->setUnreportedTermination(true);
994
995    pdvector<CallbackBase *> cbs;
996
997
998
999    getCBManager()->dispenseCallbacksMatching(evtThreadExit,cbs);
1000    for (unsigned int i = 0; i < cbs.size(); ++i) {
1001      AsyncThreadEventCallback &cb = *((AsyncThreadEventCallback *) cbs[i]);
1002      cb(process, thrd);
1003    }
1004
1005    cbs.clear();
1006    getCBManager()->dispenseCallbacksMatching(evtProcessExit,cbs);
1007    for (unsigned int i = 0; i < cbs.size(); ++i) {
1008      ExitCallback &cb = *((ExitCallback *) cbs[i]);
1009      signal_printf("%s[%d]:  about to register/wait for exit callback\n", FILE__, __LINE__);
1010      cb(process->threads[0], ExitedNormally);
1011      signal_printf("%s[%d]:  exit callback done\n", FILE__, __LINE__);
1012    }
1013
1014    continueIfExists(pid);
1015
1016 }
1017
1018 void BPatch::registerSignalExit(process *proc, int signalnum)
1019 {
1020    if (!proc)
1021       return;
1022
1023    int pid = proc->getPid();
1024
1025    BPatch_process *bpprocess = getProcessByPid(pid);
1026    if (!bpprocess) {
1027        // Error during startup can cause this -- we have a partially
1028        // constructed process object, but it was never registered with
1029        // bpatch
1030        return;
1031    }
1032    assert(bpprocess);
1033    bpprocess->setExitedViaSignal(signalnum);
1034    bpprocess->setUnreportedTermination(true);
1035    bpprocess->isVisiblyStopped = true;
1036
1037   pdvector<CallbackBase *> cbs;
1038    getCBManager()->dispenseCallbacksMatching(evtThreadExit,cbs);
1039    for (unsigned int i = 0; i < cbs.size(); ++i) {
1040      AsyncThreadEventCallback &cb = * ((AsyncThreadEventCallback *) cbs[i]);
1041      cb(bpprocess, NULL);
1042    }
1043
1044    cbs.clear();
1045    getCBManager()->dispenseCallbacksMatching(evtProcessExit,cbs);
1046    for (unsigned int i = 0; i < cbs.size(); ++i) {
1047      ExitCallback &cb = * ((ExitCallback *) cbs[i]);
1048      cb(bpprocess->threads[0], ExitedViaSignal);
1049    }
1050
1051    // We need to clean this up... but the user still has pointers
1052    // into this code. Ugh.
1053    // Do not continue at this point; process is already gone.
1054
1055 }
1056
1057
1058
1059 /*
1060  * BPatch::registerProcess
1061  *
1062  * Register a new BPatch_process object with the BPatch library (this function
1063  * is called only by the constructor for BPatch_process).
1064  *
1065  * process      A pointer to the process to register.
1066  */
1067 void BPatch::registerProcess(BPatch_process *process, int pid)
1068 {
1069    if (!pid)
1070       pid = process->getPid();
1071
1072    assert(!info->procsByPid.defines(pid) || !info->procsByPid[pid]);
1073    info->procsByPid[pid] = process;
1074 }
1075
1076
1077 /*
1078  * BPatch::unRegisterProcess
1079  *
1080  * Remove the BPatch_thread associated with a given pid from the list of
1081  * threads being managed by the library.
1082  *
1083  * pid          The pid of the thread to be removed.
1084  */
1085 void BPatch::unRegisterProcess(int pid)
1086 {
1087     if (!info->procsByPid.defines(pid)) {
1088        fprintf(stderr, "%s[%d]:  ERROR, no process %d defined in procsByPid\n", FILE__,  __LINE__, pid);
1089        dictionary_hash_iter<int, BPatch_process *> iter(info->procsByPid);
1090        BPatch_process *p;
1091        int pid;
1092        while (iter.next(pid, p)) {
1093          fprintf(stderr, "%s[%d]:  have process %d\n", FILE__, __LINE__, pid);
1094        }
1095     }
1096     assert(info->procsByPid.defines(pid));
1097     info->procsByPid.undef(pid);        
1098     assert(!info->procsByPid.defines(pid));
1099 }
1100
1101
1102 /*
1103  * BPatch::processCreateInt
1104  *
1105  * Create a process and return a BPatch_process representing it.
1106  * Returns NULL upon failure.
1107  *
1108  * path         The pathname of the executable for the new process.
1109  * argv         A list of the arguments for the new process, terminated by a
1110  *              NULL.
1111  * envp         A list of values that make up the environment for the new
1112  *              process, terminated by a NULL.  If envp is NULL, the new
1113  *              new process will inherit the environemnt of the parent.
1114  * stdin_fd     file descriptor to use for stdin for the application
1115  * stdout_fd    file descriptor to use for stdout for the application
1116  * stderr_fd    file descriptor to use for stderr for the application
1117
1118  */
1119 BPatch_process *BPatch::processCreateInt(const char *path, const char *argv[], 
1120                                          const char **envp, int stdin_fd, 
1121                                          int stdout_fd, int stderr_fd)
1122 {
1123     clearError();
1124
1125     if( path == NULL ) { return NULL; }
1126
1127     BPatch_process *ret = 
1128        new BPatch_process(path, argv, 
1129                           envp, 
1130                           stdin_fd, stdout_fd, stderr_fd);
1131     
1132     if (!ret->llproc ||
1133         (ret->llproc->status() != stopped) ||
1134         !ret->llproc->isBootstrappedYet()) 
1135     { 
1136        ret->BPatch_process_dtor();
1137        delete ret;
1138        reportError(BPatchFatal, 68, "create process failed bootstrap");
1139        return NULL;
1140     }
1141
1142     //ccw 23 jan 2002 : this forces the user to call
1143     //BPatch_thread::enableDumpPatchedImage() if they want to use the save the world
1144     //functionality.
1145     ret->llproc->collectSaveWorldData = false;
1146     ret->updateThreadInfo();
1147
1148 #if defined(cap_async_events)
1149     async_printf("%s[%d]:  about to connect to process\n", FILE__, __LINE__);
1150     if (!getAsync()->connectToProcess(ret)) {
1151        bpfatal("%s[%d]: asyncEventHandler->connectToProcess failed\n", __FILE__, __LINE__);
1152        fprintf(stderr,"%s[%d]: asyncEventHandler->connectToProcess failed\n", __FILE__, __LINE__);
1153        return NULL;
1154     }
1155     asyncActive = true;
1156 #endif
1157     
1158
1159     return ret;
1160 }
1161
1162 /*
1163  * BPatch::createProcess
1164  * This function is deprecated, see processCreate
1165  */
1166 BPatch_thread *BPatch::createProcessInt(const char *path, const char *argv[], 
1167                                          const char **envp, int stdin_fd, 
1168                                          int stdout_fd, int stderr_fd)
1169 {
1170    BPatch_process *ret = processCreateInt(path, argv, envp, stdin_fd, 
1171                                           stdout_fd, stderr_fd);
1172    if (!ret)
1173       return NULL;
1174
1175    assert(ret->threads.size() > 0);
1176    return ret->threads[0];
1177 }
1178
1179 /*
1180  * BPatch::processAttach
1181  *
1182  * Attach to a running process and return a BPatch_thread representing it.
1183  * Returns NULL upon failure.
1184  *
1185  * path         The pathname of the executable for the process.
1186  * pid          The id of the process to attach to.
1187  */
1188 BPatch_process *BPatch::processAttachInt(const char *path, int pid)
1189 {
1190    clearError();
1191    
1192    BPatch_process *ret = new BPatch_process(path, pid);
1193
1194    if (!ret->llproc ||
1195        (ret->llproc->status() != stopped) ||
1196        !ret->llproc->isBootstrappedYet()) {
1197       // It would be considerate to (attempt to) leave the process running
1198       // at this point (*before* deleting the BPatch_thread handle for it!),
1199       // even though it might be in bad shape after the attempted attach.
1200       char msg[256];
1201       sprintf(msg,"attachProcess failed: process %d may now be killed!",pid);
1202       reportError(BPatchWarning, 26, msg);
1203       delete ret;
1204       return NULL;
1205    }
1206 #if !defined (os_osf) && !defined (os_windows) && !defined(os_irix)  && !defined(arch_ia64)
1207    if (!getAsync()->connectToProcess(ret)) {
1208       bperr("%s[%d]:  asyncEventHandler->connectToProcess failed\n", __FILE__, __LINE__);
1209       return NULL;
1210    } 
1211    asyncActive = true;
1212 #endif
1213     //ccw 31 jan 2003 : this forces the user to call
1214     //BPatch_thread::enableDumpPatchedImage() if they want to use the save the world
1215     //functionality.
1216    ret->llproc->collectSaveWorldData = false;
1217    ret->updateThreadInfo();
1218
1219    return ret;
1220 }
1221
1222 /*
1223  * BPatch::attachProcess
1224  * This function is deprecated, see processAttach
1225  */
1226 BPatch_thread *BPatch::attachProcessInt(const char *path, int pid)
1227 {
1228    BPatch_process *proc = processAttachInt(path, pid);
1229    if (!proc)
1230       return NULL;
1231    
1232    assert(proc->threads.size() > 0);
1233    return proc->threads[0];
1234 }
1235
1236 /*
1237  * pollForStatusChange
1238  *
1239  * Checks for unreported changes to the status of any child process, and
1240  * returns true if any are detected.  Returns false otherwise.
1241  *
1242  * This function is declared as a friend of BPatch_thread so that it can use
1243  * the BPatch_thread::getThreadEvent call to check for status changes.
1244  */
1245 bool BPatch::pollForStatusChangeInt()
1246 {
1247   getMailbox()->executeCallbacks(FILE__, __LINE__);
1248     
1249     if (mutateeStatusChange) {
1250         mutateeStatusChange = false;
1251         return true;
1252     }
1253     return false;
1254 }
1255
1256
1257 /*
1258  * waitForStatusChange
1259  *
1260  * Blocks waiting for a change to occur in the running status of a child
1261  * process.  Returns true upon success, false upon failure.
1262  *
1263  * This function is declared as a friend of BPatch_thread so that it can use
1264  * the BPatch_thread::getThreadEvent call to check for status changes.
1265  */
1266 bool BPatch::waitForStatusChangeInt()
1267 {
1268
1269   getMailbox()->executeCallbacks(FILE__, __LINE__);
1270
1271   if (mutateeStatusChange) {
1272     mutateeStatusChange = false;
1273     return true;
1274   }
1275
1276   SignalGenerator *sh = NULL;
1277
1278   //  find a signal handler (in an active process)
1279   extern pdvector<process *> processVec;
1280   if (!processVec.size()) return false;
1281   for (unsigned int i = 0; i < processVec.size(); ++i) {
1282     if (processVec[i] && processVec[i]->status() != deleted) {
1283       sh = processVec[i]->sh;
1284       break;
1285     }
1286   } 
1287   if (!sh) {
1288     fprintf(stderr, "%s[%d]:  cannot find an event generator to wait for!\n", FILE__, __LINE__);
1289     return false;
1290   }
1291   eventType evt;
1292   do {
1293    pdvector<eventType> evts;
1294    evts.push_back(evtProcessStop);
1295    evts.push_back(evtProcessExit);
1296    evts.push_back(evtThreadCreate);
1297    evts.push_back(evtThreadExit);
1298    waitingForStatusChange = true;
1299    getMailbox()->executeCallbacks(FILE__, __LINE__);
1300    if (mutateeStatusChange) break;
1301    evt = SignalGeneratorCommon::globalWaitForOneOf(evts);
1302   } while ((    evt != evtProcessStop ) 
1303             && (evt != evtProcessExit)
1304             && (evt != evtThreadExit)
1305             && (evt != evtThreadCreate));
1306
1307   waitingForStatusChange = false;
1308
1309   if (mutateeStatusChange) {
1310     mutateeStatusChange = false;
1311     return true;
1312   }
1313   //  we waited for a change, but didn't get it
1314   fprintf(stderr, "%s[%d]:  Error in status change reporting\n", __FILE__, __LINE__);
1315   return false;
1316 }
1317
1318 /*
1319  * createEnum
1320  *
1321  * This function is a wrapper for the BPatch_type constructors for API/User
1322  * created types.
1323  *
1324  * It returns a pointer to a BPatch_type that was added to the APITypes
1325  * collection.
1326  */
1327 BPatch_type * BPatch::createEnumInt( const char * name, 
1328                                      BPatch_Vector<char *> elementNames,
1329                                      BPatch_Vector<int> elementIds)
1330 {
1331
1332     if (elementNames.size() != elementIds.size()) {
1333       return NULL;
1334     }
1335
1336     BPatch_fieldListType * newType = new BPatch_typeEnum(name);
1337     if (!newType) return NULL;
1338     
1339     APITypes->addType(newType);
1340
1341     // ADD components to type
1342     for (unsigned int i=0; i < elementNames.size(); i++) {
1343         newType->addField(elementNames[i], elementIds[i]);
1344     }
1345
1346     return(newType);
1347 }
1348
1349
1350 /*
1351  * createEnum
1352  *
1353  * This function is a wrapper for the BPatch_type constructors for API/User
1354  * created types.  The user has left element id specification to us
1355  *
1356  * It returns a pointer to a BPatch_type that was added to the APITypes
1357  * collection.
1358  */
1359 BPatch_type * BPatch::createEnumAutoId( const char * name, 
1360                                         BPatch_Vector<char *> elementNames)
1361 {
1362     BPatch_fieldListType * newType = new BPatch_typeEnum(name);
1363
1364     if (!newType) return NULL;
1365     
1366     APITypes->addType(newType);
1367
1368     // ADD components to type
1369     for (unsigned int i=0; i < elementNames.size(); i++) {
1370         newType->addField(elementNames[i], i);
1371     }
1372
1373     return(newType);
1374 }
1375
1376 /*
1377  * createStructs
1378  *
1379  * This function is a wrapper for the BPatch_type constructors for API/User
1380  * created types.
1381  *
1382  * It returns a pointer to a BPatch_type that was added to the APITypes
1383  * collection.
1384  */
1385
1386 BPatch_type * BPatch::createStructInt( const char * name,
1387                                        BPatch_Vector<char *> fieldNames,
1388                                        BPatch_Vector<BPatch_type *> fieldTypes)
1389 {
1390     unsigned int i;
1391     int offset, size;
1392
1393     offset = size = 0;
1394     if (fieldNames.size() != fieldTypes.size()) {
1395       return NULL;
1396     }
1397
1398     //Compute the size of the struct
1399     for (i=0; i < fieldNames.size(); i++) {
1400         BPatch_type *type = fieldTypes[i];
1401         size = type->getSize();
1402         size += size;
1403     }
1404   
1405     BPatch_fieldListType *newType = new BPatch_typeStruct(name);
1406     if (!newType) return NULL;
1407     
1408     APITypes->addType(newType);
1409
1410     // ADD components to type
1411     size = 0;
1412     for (i=0; i < fieldNames.size(); i++) {
1413         BPatch_type *type = fieldTypes[i];
1414         size = type->getSize();
1415         newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
1416   
1417         // Calculate next offset (in bits) into the struct
1418         offset += (size * 8);
1419     }
1420
1421     return(newType);
1422 }
1423
1424 /*
1425  * createUnions
1426  *
1427  * This function is a wrapper for the BPatch_type constructors for API/User
1428  * created types.
1429  *
1430  * It returns a pointer to a BPatch_type that was added to the APITypes
1431  * collection.
1432  */
1433
1434 BPatch_type * BPatch::createUnionInt( const char * name, 
1435                                       BPatch_Vector<char *> fieldNames,
1436                                       BPatch_Vector<BPatch_type *> fieldTypes)
1437 {
1438     unsigned int i;
1439     int offset, size, newsize;
1440     offset = size = newsize = 0;
1441
1442     if (fieldNames.size() != fieldTypes.size()) {
1443         return NULL;
1444     }
1445
1446     // Compute the size of the union
1447     for (i=0; i < fieldTypes.size(); i++) {
1448         BPatch_type *type = fieldTypes[i];
1449         newsize = type->getSize();
1450         if(size < newsize) size = newsize;
1451     }
1452   
1453     BPatch_fieldListType * newType = new BPatch_typeUnion(name);
1454     if (!newType) return NULL;
1455
1456     APITypes->addType(newType);
1457
1458     // ADD components to type
1459     for (i=0; i < fieldNames.size(); i++) {
1460         BPatch_type *type = fieldTypes[i];
1461         size = type->getSize();
1462         newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
1463     }  
1464     return(newType);
1465 }
1466
1467
1468 /*
1469  * createArray for Arrays and SymTypeRanges
1470  *
1471  * This function is a wrapper for the BPatch_type constructors for API/User
1472  * created types.
1473  *
1474  * It returns a pointer to a BPatch_type that was added to the APITypes
1475  * collection.
1476  */
1477 BPatch_type * BPatch::createArrayInt( const char * name, BPatch_type * ptr,
1478                                       unsigned int low, unsigned int hi)
1479 {
1480
1481     BPatch_type * newType;
1482
1483     if (!ptr) {
1484         return NULL;
1485     } else {
1486         newType = new BPatch_typeArray(ptr, low, hi, name);
1487         if (!newType) return NULL;
1488     }
1489
1490     APITypes->addType(newType);
1491
1492     return newType;
1493 }
1494
1495 /*
1496  * createPointer for BPatch_pointers
1497  *
1498  * This function is a wrapper for the BPatch_type constructors for API/User
1499  * created types.
1500  *
1501  * It returns a pointer to a BPatch_type that was added to the APITypes
1502  * collection.
1503  */
1504 BPatch_type * BPatch::createPointerInt(const char * name, BPatch_type * ptr,
1505                                        int /*size*/)
1506 {
1507
1508     BPatch_type * newType = new BPatch_typePointer(ptr, name);
1509     if(!newType) return NULL;
1510
1511     APITypes->addType(newType);
1512   
1513     return newType;
1514 }
1515
1516 /*
1517  * createScalar for scalars with a size and no range
1518  *
1519  * This function is a wrapper for the BPatch_type constructors for API/User
1520  * created types.
1521  *
1522  * It returns a pointer to a BPatch_type that was added to the APITypes
1523  * collection.
1524  */
1525
1526 BPatch_type * BPatch::createScalarInt( const char * name, int size)
1527 {
1528     BPatch_type * newType = new BPatch_typeScalar(size, name);
1529     if (!newType) return NULL;
1530
1531     APITypes->addType(newType);
1532  
1533     return newType;
1534 }
1535
1536 /*
1537  * createType for typedefs
1538  *
1539  * This function is a wrapper for the BPatch_type constructors for API/User
1540  * created types.
1541  *
1542  * It returns a pointer to a BPatch_type that was added to the APITypes
1543  * collection.
1544  */
1545 BPatch_type * BPatch::createTypedefInt( const char * name, BPatch_type * ptr)
1546 {
1547     BPatch_type * newType = new BPatch_typeTypedef(ptr, name);
1548
1549     if (!newType) return NULL;
1550
1551     APITypes->addType(newType);
1552   
1553     return newType;
1554 }
1555
1556 bool BPatch::waitUntilStoppedInt(BPatch_thread *appThread){
1557
1558    bool ret = false;
1559
1560    while (1) {
1561      __LOCK;
1562      if (!appThread->isStopped() && !appThread->isTerminated()) {
1563        __UNLOCK;
1564        this->waitForStatusChange();
1565      }
1566      else {
1567        __UNLOCK;
1568        break;
1569      }
1570    }
1571
1572    __LOCK;
1573
1574         if (!appThread->isStopped())
1575         {
1576                 cerr << "ERROR : process did not signal mutator via stop"
1577                      << endl;
1578                 ret = false;
1579                 goto done;
1580         }
1581 #if defined(i386_unknown_nt4_0) || \
1582     defined(mips_unknown_ce2_11)
1583         else if((appThread->stopSignal() != EXCEPTION_BREAKPOINT) && 
1584                 (appThread->stopSignal() != -1))
1585         {
1586                 cerr << "ERROR : process stopped on signal different"
1587                      << " than SIGTRAP" << endl;
1588                 ret =  false;
1589                 goto done;
1590         }
1591 #else
1592         else if ((appThread->stopSignal() != SIGSTOP) &&
1593 #if defined(bug_irix_broken_sigstop)
1594                  (appThread->stopSignal() != SIGEMT) &&
1595 #endif 
1596                  (appThread->stopSignal() != SIGHUP)) {
1597                 cerr << "ERROR :  process stopped on signal "
1598                      << "different than SIGSTOP" << endl;
1599                 ret =  false;
1600                 goto done;
1601         }
1602 #endif
1603
1604   done:
1605    __UNLOCK;
1606
1607   return ret;
1608 }
1609
1610 #ifdef IBM_BPATCH_COMPAT
1611
1612 /*
1613  * Register a function to call when an RPC (i.e. oneshot) is done.
1614  *
1615  * dyninst version is a callback that is defined for BPatch_thread
1616  *
1617  */
1618 BPatchThreadEventCallback BPatch::registerRPCTerminationCallbackInt(BPatchThreadEventCallback func)
1619 {
1620     BPatchThreadEventCallback ret;
1621
1622     ret = RPCdoneCallback;
1623     RPCdoneCallback = func;
1624
1625     return ret;
1626 }
1627
1628 void setLogging_NP(BPatchLoggingCallback, int)
1629 {
1630     return;
1631 }
1632
1633 int BPatch::getLastErrorCodeInt()
1634 {
1635   return lastError;
1636 }
1637 BPatchThreadEventCallback BPatch::registerDetachDoneCallbackInt(BPatchThreadEventCallback)
1638 {
1639   return NULL;
1640 }
1641 BPatchThreadEventCallback BPatch::registerSnippetRemovedCallbackInt(BPatchThreadEventCallback)
1642 {
1643   return NULL;
1644 }
1645 BPatchThreadEventCallback BPatch::registerSignalCallbackInt(BPatchThreadEventCallback, int signum)
1646 {
1647   fprintf(stderr, "%s[%d]:  WARNING:  registerSignalCallback is not implemented yet\n", __FILE__, __LINE__);
1648   return NULL;
1649 }
1650
1651 #endif
1652
1653
1654 BPatch_stats &BPatch::getBPatchStatisticsInt()
1655 {
1656   updateStats();
1657   return stats;
1658 }
1659 //  updateStats() -- an internal function called before returning
1660 //  statistics buffer to caller of BPatch_getStatistics(),
1661 //  -- just copies global variable statistics counters into 
1662 //  the buffer which is returned to the user.
1663 void BPatch::updateStats() 
1664 {
1665   stats.pointsUsed = pointsUsed;
1666   stats.totalMiniTramps = totalMiniTramps;
1667   stats.trampBytes = trampBytes;
1668   stats.ptraceOtherOps = ptraceOtherOps;
1669   stats.ptraceOps = ptraceOps;
1670   stats.ptraceBytes = ptraceBytes;
1671   stats.insnGenerated = insnGenerated;
1672 }
1673
1674 bool BPatch::registerThreadEventCallbackInt(BPatch_asyncEventType type,
1675                                             BPatchAsyncThreadEventCallback func)
1676 {
1677     
1678     eventType evt;
1679     switch (type) {
1680       case BPatch_threadCreateEvent: evt = evtThreadCreate; break;
1681       case BPatch_threadDestroyEvent: evt = evtThreadExit; break;
1682       default:
1683         fprintf(stderr, "%s[%d]:  Cannot register callback for type %s\n",
1684                FILE__, __LINE__, asyncEventType2Str(type));
1685         return false; 
1686     };
1687
1688     pdvector<CallbackBase *> cbs;
1689     AsyncThreadEventCallback *cb = new AsyncThreadEventCallback(func);
1690     getCBManager()->removeCallbacks(evt, cbs);
1691     bool ret = getCBManager()->registerCallback(evt, cb);
1692
1693     return ret;
1694 }
1695
1696 bool BPatch::removeThreadEventCallbackInt(BPatch_asyncEventType type,
1697                                           BPatchAsyncThreadEventCallback cb)
1698 {
1699     eventType evt;
1700     switch (type) {
1701       case BPatch_threadCreateEvent: evt = evtThreadCreate; break;
1702       case BPatch_threadDestroyEvent: evt = evtThreadExit; break;
1703       default:
1704         fprintf(stderr, "%s[%d]:  Cannot remove callback for type %s\n",
1705                FILE__, __LINE__, asyncEventType2Str(type));
1706         return false; 
1707     };
1708
1709     pdvector<CallbackBase *> cbs;
1710     if (!getCBManager()->removeCallbacks(evt, cbs)) {
1711         fprintf(stderr, "%s[%d]:  Cannot remove callback for type %s, not found\n",
1712                FILE__, __LINE__, asyncEventType2Str(type));
1713         return false;
1714     }
1715
1716     //  See if supplied function was in the set of removed functions
1717     bool ret = false;
1718     for (int i = cbs.size() -1; i >= 0; i--) {
1719       AsyncThreadEventCallback *test = (AsyncThreadEventCallback *)cbs[i];
1720       if (test->getFunc() == cb) {
1721         //  found it, destroy it
1722         cbs.erase(i,i);
1723         ret = true;
1724         delete test;
1725       } 
1726     }
1727
1728     //  we deleted any found target functions, put the others back.
1729     for (unsigned int i = 0; i < cbs.size(); ++i) 
1730        if (!getCBManager()->registerCallback(evt, cbs[i]))
1731           ret = false;
1732
1733     return ret;
1734 }
1735
1736 bool BPatch::registerUserEventCallbackInt(BPatchUserEventCallback func)
1737 {
1738   pdvector<CallbackBase *> cbs;
1739   UserEventCallback *cb = new UserEventCallback(func);
1740   bool ret = getCBManager()->registerCallback(evtUserEvent, cb);
1741
1742   return ret;
1743 }
1744
1745 bool BPatch::removeUserEventCallbackInt(BPatchUserEventCallback cb)
1746 {
1747     bool ret = false;
1748     pdvector<CallbackBase *> cbs;
1749     if (!getCBManager()->removeCallbacks(evtUserEvent, cbs)) {
1750         fprintf(stderr, "%s[%d]:  Cannot remove callback evtUserEvent, not found\n",
1751                FILE__, __LINE__);
1752         return false;
1753     }
1754
1755     //  See if supplied function was in the set of removed functions
1756     for (int i = cbs.size() -1; i >= 0; i--) {
1757       UserEventCallback *test = (UserEventCallback *)cbs[i];
1758       if (test->getFunc() == cb) {
1759         //  found it, destroy it
1760         cbs.erase(i,i);
1761         ret = true;
1762         delete test;
1763       } 
1764     }
1765
1766     //  we deleted any found target functions, put the others back.
1767     for (unsigned int i = 0; i < cbs.size(); ++i) 
1768        if (!getCBManager()->registerCallback(evtUserEvent, cbs[i]))
1769           ret = false;
1770
1771     return ret;
1772 }
1773
1774
1775
1776 void BPatch::continueIfExists(int pid) {
1777     BPatch_process *proc = getProcessByPid(pid);
1778     if (proc) proc->continueExecution();
1779 }