BPatch functions that block are now locked (on a finer grain than the rest of the...
[dyninst.git] / dyninstAPI / h / BPatch_thread.h
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 #ifndef _BPatch_thread_h_
43 #define _BPatch_thread_h_
44
45 #include <stdio.h>
46
47 /*
48  * The following is a kludge so that the functions that refer to signals (such
49  * as BPatch_thread::stopSignal) can emulate the Unix behavior on Windows NT.
50  */
51 #include <signal.h>
52 #ifndef SIGTRAP
53 #define SIGTRAP         5
54 #endif
55
56 #include "BPatch_dll.h"
57 #include "BPatch_Vector.h"
58 #include "BPatch_image.h"
59 #include "BPatch_snippet.h"
60 #include "BPatch_eventLock.h"
61
62 class process;
63 class miniTrampHandle;
64 class BPatch;
65 class BPatch_thread;
66 typedef enum {
67   BPatch_nullEvent,
68   BPatch_newConnectionEvent,
69   BPatch_internalShutDownEvent,
70   BPatch_threadCreateEvent,
71   BPatch_threadStartEvent,
72   BPatch_threadStopEvent,
73   BPatch_threadDestroyEvent,
74   BPatch_dynamicCallEvent
75 } BPatch_asyncEventType;
76
77
78
79 // BPatch_callWhen is defined in BPatch_point.h
80
81 /*
82  * Used to specify whether a snippet should be installed before other snippets
83  * that have previously been inserted at the same point, or after.
84  */
85 typedef enum {
86     BPatch_firstSnippet,
87     BPatch_lastSnippet
88 } BPatch_snippetOrder;
89
90
91 /*
92  * Contains information about the code that was inserted by an earlier call to
93  * Bpatch_thread::insertSnippet.
94  */
95 #ifdef DYNINST_CLASS_NAME
96 #undef DYNINST_CLASS_NAME
97 #endif
98 #define DYNINST_CLASS_NAME BPatchSnippetHandle
99
100 class BPATCH_DLL_EXPORT BPatchSnippetHandle : public BPatch_eventLock {
101     friend class BPatch_thread;
102     friend class BPatch_point;
103 private:
104     BPatch_Vector<miniTrampHandle *> mtHandles;
105       
106     process *proc;
107
108     BPatchSnippetHandle(process *_proc) : proc(_proc) {};
109
110     void add(miniTrampHandle *pointInstance);
111     void getMiniTrampHandles(BPatch_Vector<miniTrampHandle *> *save_mtHandles) {
112       for(unsigned i=0; i<mtHandles.size(); i++)
113         (*save_mtHandles).push_back(mtHandles[i]);
114     }
115
116 public:
117     API_EXPORT_DTOR(_dtor, (),
118     ~,BPatchSnippetHandle,());
119 };
120
121 /*
122  * The following types are used by BPatch_thread::getCallStack()
123  */
124
125 // Stack frame types
126 typedef enum {
127     BPatch_frameNormal,
128     BPatch_frameSignal,
129     BPatch_frameTrampoline
130 } BPatch_frameType;
131
132 typedef enum {
133    NoExit,
134    ExitedNormally,
135    ExitedViaSignal
136 } BPatch_exitType;
137
138 #ifdef DYNINST_CLASS_NAME
139 #undef DYNINST_CLASS_NAME
140 #endif
141 #define DYNINST_CLASS_NAME BPatch_frame
142
143 // Contains information about a stack frame (used by
144 class BPATCH_DLL_EXPORT BPatch_frame : public BPatch_eventLock{
145     friend class BPatch_thread;
146     friend class BPatch_Vector<BPatch_frame>;
147     BPatch_thread *thread;
148
149     void *pc;
150     void *fp;
151     bool isSignalFrame;
152     bool isTrampoline;
153     BPatch_frame() : thread(NULL), pc(NULL), fp(NULL), 
154                      isSignalFrame(false), isTrampoline(false) {};
155     BPatch_frame(BPatch_thread *_thread, void *_pc, void *_fp, 
156                  bool isf = false, bool istr = false ) :
157         thread(_thread), pc(_pc), fp(_fp), isSignalFrame(isf), isTrampoline(istr) {};
158
159 public:
160     //  BPatch_frame::getFrameType
161     //  Returns type of frame: BPatch_frameNormal for a stack frame for a function,
162     //  BPatch_frameSignal for the stack frame created when a signal is delivered,
163     //  or BPatch_frameTrampoline for a stack frame created by internal Dyninst 
164     //  instrumentation.
165     API_EXPORT(Int, (),
166
167     BPatch_frameType,getFrameType,());
168
169     //  BPatch_frame::getPC
170     //  Returns:  value of program counter
171     API_EXPORT(Int, (),
172
173     void *,getPC,()); 
174
175     //  BPatch_frame::getFP
176     API_EXPORT(Int, (),
177
178     void *,getFP,()); 
179
180     //  BPatch_frame::findFunction
181     //  Returns:  the function corresponding to this stack frame, NULL if there is none
182     API_EXPORT(Int, (),
183
184     BPatch_function *,findFunction,());
185    
186     // The following are planned but no yet implemented:
187     // int getSignalNumber();
188     // BPatch_point *findPoint();
189 };
190
191 typedef void (*BPatchThreadEventCallback)(BPatch_thread *thr, unsigned long thread_id);
192
193 /*
194  * Represents a thread of execution.
195  */
196 #ifdef DYNINST_CLASS_NAME
197 #undef DYNINST_CLASS_NAME
198 #endif
199 #define DYNINST_CLASS_NAME BPatch_thread
200
201 class BPATCH_DLL_EXPORT BPatch_thread : public BPatch_eventLock {
202     friend class BPatch;
203     friend class BPatch_image;
204     friend class BPatch_function;
205     friend class BPatch_frame;
206     friend class process;
207     friend bool pollForStatusChange();
208     friend class BPatch_asyncEventHandler;
209     friend class ThreadLibrary;
210
211     process *proc;
212     BPatch_image *image;
213
214     int lastSignal;
215     int exitCode;
216     int exitSignal;
217     bool exitedNormally;
218     bool exitedViaSignal;
219     bool mutationsActive;
220     bool createdViaAttach;
221     bool detached;
222
223     bool unreportedStop;
224     bool unreportedTermination;
225
226     //pdvector<pdpair<BPatchDynamicCallSiteCallback, Address> > dynsiteCallbacks;
227     //bool registerDynamicCallSiteCB(BPatchDynamicCallSiteCallback,
228     //                               BPatch_point *);
229     //BPatchDynamicCallSiteCallback getCallback(Address);
230
231     void setUnreportedStop(bool new_value) {unreportedStop = new_value;}
232     void setUnreportedTermination(bool new_value) {unreportedTermination = new_value;}
233
234     void setExitedNormally() {exitedNormally = true;}
235     void setExitedViaSignal(int signalnumber) {
236            exitedViaSignal = true;
237            lastSignal = signalnumber;
238     }
239
240     void setExitCode(int exitcode) { exitCode = exitcode; }
241     void setExitSignal(int exitsignal) { exitSignal = exitsignal; }
242
243     bool pendingUnreportedStop() { return unreportedStop;}
244     bool pendingUnreportedTermination() { return unreportedTermination; }
245
246     bool statusIsStopped();
247     bool statusIsTerminated();
248
249     static void oneTimeCodeCallbackDispatch(process *theProc,
250                                             unsigned /* rpcid */, 
251                                             void *userData,
252                                             void *returnValue);
253
254     void *oneTimeCodeInternal(const BPatch_snippet &expr,
255                               void *userData,
256                               bool synchronous);
257
258     protected:
259     // for creating a process
260     BPatch_thread(const char *path, char *argv[], char *envp[] = NULL, 
261                   int stdin_fd = 0, int stdout_fd = 1, int stderr_fd = 2);
262     // for attaching
263     BPatch_thread(const char *path, int pid);   
264
265     // for forking
266     BPatch_thread(int childPid, process *proc);
267
268     public:
269
270     // DO NOT USE
271     // this function should go away as soon as Paradyn links against Dyninst
272     process *lowlevel_process() { return proc; }
273
274     // DO NOT USE
275     // this function should go away as soon as Paradyn links against Dyninst
276     process *PDSEP_process() { return proc; }
277
278   
279     //  BPatch_thread::~BPatch_thread
280     //
281     //  Destructor
282     API_EXPORT_DTOR(_dtor, (),
283     ~,BPatch_thread,());
284
285     //  BPatch_thread::getImage
286     //
287     //  Obtain BPatch_image associated with this BPatch_thread
288
289     API_EXPORT(Int, (),
290     BPatch_image *,getImage,());
291     
292     //  BPatch_thread::getPid
293     //  
294     //  Get  id of mutatee process
295
296     API_EXPORT(Int, (),
297     int,getPid,());
298
299     //  BPatch_thread::stopExecution
300     //  
301     //  Stop the mutatee process
302
303     API_EXPORT(Int, (),
304     bool,stopExecution,());
305
306     //  BPatch_thread::continueExecution
307     //  
308     //  Resume execution of mutatee process
309
310     API_EXPORT(Int, (),
311     bool,continueExecution,());
312
313     //  BPatch_thread::terminateExecution
314     //  
315     //  Terminate mutatee process
316
317     API_EXPORT(Int, (),
318     bool,terminateExecution,());
319
320     //  BPatch_thread::isStopped
321     //  
322     //  Returns true if mutatee process is currently stopped
323
324     API_EXPORT(Int, (),
325     bool,isStopped,());
326
327     //  BPatch_thread::stopSignal
328     //  
329     //  Returns signal number of signal that stopped mutatee process
330
331     API_EXPORT(Int, (),
332     int,stopSignal,());
333
334     //  BPatch_thread::isTerminated
335     //  
336     //  Returns true if mutatee process is terminated
337
338     API_EXPORT(Int, (),
339     bool,isTerminated,());
340
341     //  BPatch_thread::terminationStatus
342     //  
343     //  Returns information on how mutatee process was terminated
344
345     API_EXPORT(Int, (),
346     BPatch_exitType,terminationStatus,());
347
348     //  BPatch_thread::getExitCode
349     //  
350     //  Returns integer exit code of (exited) mutatee process
351
352     API_EXPORT(Int, (),
353     int,getExitCode,());
354
355     //  BPatch_thread::getExitSignal
356     //  
357     //  Returns integer signal number of signal that caused mutatee to exit
358
359     API_EXPORT(Int, (),
360     int,getExitSignal,());
361
362     //  BPatch_thread::detach
363     //  
364     //  Detach from the mutatee process, optionally leaving it running
365
366     API_EXPORT(Int, (cont),
367     bool,detach,(bool cont));
368
369     //  BPatch_thread::isDetached
370     //  
371     //  Returns true if DyninstAPI is detached from this mutatee
372
373     API_EXPORT(Int, (),
374     bool,isDetached,());
375
376     //  BPatch_thread::dumpCore
377     //  
378     //  Produce a core dump file <file> for the mutatee process
379
380     API_EXPORT(Int, (file, terminate),
381     bool,dumpCore,(const char *file, bool terminate));
382
383     //  BPatch_thread::dumpImage
384     //  
385     //  Write contents of memory to <file>
386
387     API_EXPORT(Int, (file),
388     bool,dumpImage,(const char *file));
389
390     //  BPatch_thread::dumpPatchedImage
391     //  
392     //  Write executable image of mutatee, including runtime modifications, to <file>
393
394     API_EXPORT(Int, (file),
395     char *,dumpPatchedImage,(const char* file));
396
397     //  BPatch_thread::malloc
398     //  
399     //  Allocate memory for a new variable in the mutatee process
400
401     API_EXPORT(Int, (n),
402     BPatch_variableExpr *,malloc,(int n));
403
404     //  BPatch_thread::malloc
405     //  
406     //  Allocate memory for a new variable in the mutatee process
407
408     API_EXPORT(ByType, (type),
409     BPatch_variableExpr *,malloc,(const BPatch_type &type));
410
411     //  BPatch_thread::free
412     //  
413     //  Free memory allocated by Dyninst in the mutatee process
414
415     API_EXPORT(Int, (ptr),
416     bool,free,(BPatch_variableExpr &ptr));
417
418     //  BPatch_thread::getInheritedVariable
419     //  
420     //  
421
422     API_EXPORT(Int, (pVar),
423     BPatch_variableExpr *,getInheritedVariable,(BPatch_variableExpr &pVar));
424
425     //  BPatch_thread::getInheritedSnippet
426     //  
427     //  
428
429     API_EXPORT(Int, (parentSnippet),
430     BPatchSnippetHandle *,getInheritedSnippet,(BPatchSnippetHandle &parentSnippet));
431
432     //  BPatch_thread::insertSnippet
433     //  
434     //  Insert new code into the mutatee
435
436     API_EXPORT(Int, (expr, point, order),
437     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr, BPatch_point &point,
438                                          BPatch_snippetOrder order = BPatch_firstSnippet));
439
440     //  BPatch_thread::insertSnippet
441     //  
442     //  Insert new code into the mutatee, specifying "when" (before/after point)
443
444     API_EXPORT(When, (expr, point, when, order),
445     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr, BPatch_point &point,
446                                          BPatch_callWhen when,
447                                          BPatch_snippetOrder order = BPatch_firstSnippet));
448
449     //  BPatch_thread::insertSnippet
450     //  
451     //  Insert new code into the mutatee at multiple points
452
453     API_EXPORT(AtPoints, (expr, points, order),
454     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr,
455                                          const BPatch_Vector<BPatch_point *> &points,
456                                          BPatch_snippetOrder order = BPatch_firstSnippet));
457
458     //  BPatch_thread::insertSnippet
459     //  
460     //  Insert new code into the mutatee at multiple points, specifying "when"
461
462     API_EXPORT(AtPointsWhen, (expr, points, when, order),
463     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr,
464                                          const BPatch_Vector<BPatch_point *> &points,
465                                          BPatch_callWhen when,
466                                          BPatch_snippetOrder order = BPatch_firstSnippet));
467     
468     //  BPatch_thread::deleteSnippet
469     //  
470     //  Remove instrumentation from the mutatee process
471
472     API_EXPORT(Int, (handle),
473     bool,deleteSnippet,(BPatchSnippetHandle *handle));
474
475     //  BPatch_thread::setMutationsActive
476     //  
477     //  Turn on/off instrumentation
478
479     API_EXPORT(Int, (activate),
480     bool,setMutationsActive,(bool activate));
481
482     //  BPatch_thread::replaceFunctionCall
483     //  
484     //  Replace function call at one point with another
485
486     API_EXPORT(Int, (point, newFunc),
487     bool,replaceFunctionCall,(BPatch_point &point, BPatch_function &newFunc));
488
489     //  BPatch_thread::removeFunctionCall
490     //  
491     //  Remove function call at one point 
492
493     API_EXPORT(Int, (point),
494     bool,removeFunctionCall,(BPatch_point &point));
495
496     //  BPatch_thread::replaceFunction
497     //  
498     //  Replace all calls to a function with calls to another
499
500     API_EXPORT(Int, (oldFunc, newFunc),
501     bool,replaceFunction,(BPatch_function &oldFunc, BPatch_function &newFunc));
502
503     //  BPatch_thread::oneTimeCode
504     //  
505     //  Have the specified code be executed by the mutatee once.  Wait until done.
506
507     API_EXPORT(Int, (expr),
508     void *,oneTimeCode,(const BPatch_snippet &expr));
509
510     //  BPatch_thread::oneTimeCodeAsync
511     //  
512     //  Have the specified code be executed by the mutatee once.  Dont wait until done.
513
514     API_EXPORT(Int, (expr, userData),
515     bool,oneTimeCodeAsync,(const BPatch_snippet &expr, void *userData = NULL));
516
517     //  BPatch_thread::loadLibrary
518     //  
519     //  Load a shared library into the mutatee's address space
520     //
521     //  the reload argument is used by save the world to determine
522     //  if this library should be reloaded by the mutated binary
523     //  when it starts up. this is up to the user because loading
524     //  an extra shared library could hide access to the 'correct'
525     //  function by redefining a function  
526
527     API_EXPORT(Int, (libname, reload),
528     bool,loadLibrary,(const char *libname, bool reload = false));
529
530     //  BPatch_thread::getLineAndFile
531     //  
532     //  Method that retrieves the line number and file name corresponding 
533     //  to an address
534
535     API_EXPORT(Int, (addr, lineNo, fileName, length),
536     bool,getLineAndFile,(unsigned long addr, unsigned short& lineNo,
537                          char *fileName, int length));
538
539     //  BPatch_thread::findFunctionByAddr
540     //  
541     //  Returns the function containing an address
542
543     API_EXPORT(Int, (addr),
544     BPatch_function *,findFunctionByAddr,(void *addr));
545
546     //  BPatch_thread::getCallStack
547     //  
548     //  Returns a vector of BPatch_frame, representing the current call stack
549
550     API_EXPORT(Int, (stack),
551     bool,getCallStack,(BPatch_Vector<BPatch_frame>& stack));
552
553     //  BPatch_thread::enableDumpPatchedImage
554     //  
555     //  
556
557     API_EXPORT_V(Int, (),
558     void,enableDumpPatchedImage,());
559
560     //  BPatch_thread::registerThreadEventCallback
561     //  
562     //  Specifies a user defined function to call when a thread event of
563     //  <type> occurs
564     //  
565     //  relevant event types:  BPatch_threadCreateEvent, BPatch_threadStartEvent
566     //                         BPatch_threadStopEvent, BPatch_threadDestroyEvent 
567     //  BPatchThreadEventCallback is:
568     //  void (*BPatchThreadEventCallback)(BPatch_thread *thr, int thread_id);
569
570     API_EXPORT(Int, (type,cb),
571     bool,registerThreadEventCallback,(BPatch_asyncEventType type, 
572                                       BPatchThreadEventCallback cb));
573
574     API_EXPORT(Int, (type,cb),
575     bool,removeThreadEventCallback,(BPatch_asyncEventType type,
576                                     BPatchThreadEventCallback cb));
577
578     //  BPatch_thread::registerThreadEventCallback
579     //
580     //  Specifies a user defined function to execute in the mutatee when a 
581     //  thread event of <type> occurs.
582     //  Typically function will be loaded into mutatee in a user defined 
583     //  shared library (see loadLibrary()).
584     //  The function <cb> _must_ have the following prototype:
585     //    void user_cb(int thread_id);
586     //  XXX  This will change.
587
588     API_EXPORT(MutateeSide, (type,cb),
589     bool,registerThreadEventCallback,(BPatch_asyncEventType type,
590                                       BPatch_function *cb));
591
592     API_EXPORT(MutateeSide, (type,cb),
593     bool,removeThreadEventCallback,(BPatch_asyncEventType type,
594                                     BPatch_function *cb));
595
596
597 #ifdef IBM_BPATCH_COMPAT
598
599     API_EXPORT(Int, (),
600     bool,isThreaded,());
601
602     API_EXPORT(Int, (name, loadaddr),
603     bool,addSharedObject,(const char *name, const unsigned long loadaddr));
604 #endif
605
606 };
607
608 #endif /* BPatch_thread_h_ */