These are the windows fixes that I previously alluded to, combined with
[dyninst.git] / dyninstAPI / h / BPatch_process.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_process_h_
43 #define _BPatch_process_h_
44
45 #include "BPatch_snippet.h"
46 #include "BPatch_dll.h"
47 #include "BPatch_Vector.h"
48 #include "BPatch_image.h"
49 #include "BPatch_eventLock.h"
50 #include "BPatch_point.h"
51 #include "BPatch_addressSpace.h"
52
53 #include "BPatch_callbacks.h"
54
55 #include <vector>
56
57 #include <stdio.h>
58 #include <signal.h>
59
60 class process;
61 class AddressSpace;
62 class dyn_thread;
63 class miniTrampHandle;
64 class miniTramp;
65 class BPatch;
66 class BPatch_thread;
67 class BPatch_process;
68 class BPatch_funcMap;
69 class BPatch_instpMap;
70 class int_function;
71 class rpcMgr;
72 struct batchInsertionRecord;
73
74 typedef enum {
75   BPatch_nullEvent,
76   BPatch_newConnectionEvent,
77   BPatch_internalShutDownEvent,
78   BPatch_threadCreateEvent,
79   BPatch_threadDestroyEvent,
80   BPatch_dynamicCallEvent,
81   BPatch_userEvent,
82   BPatch_errorEvent,
83   BPatch_dynLibraryEvent,
84   BPatch_preForkEvent,
85   BPatch_postForkEvent,
86   BPatch_execEvent,
87   BPatch_exitEvent,
88   BPatch_signalEvent,
89   BPatch_oneTimeCodeEvent
90 } BPatch_asyncEventType;
91
92 typedef long dynthread_t;
93
94
95 typedef struct {
96   BPatch_snippet snip;
97   BPatchSnippetHandle *sh;
98   BPatch_thread *thread;
99 } BPatch_catchupInfo;
100
101 class EventRecord;
102 class OneTimeCodeCallback;
103 /*
104  * class OneTimeCodeInfo
105  *
106  * This is used by the oneTimeCode (inferiorRPC) mechanism to keep per-RPC
107  * information.
108  */
109 class OneTimeCodeInfo {
110    bool synchronous;
111    bool completed;
112    void *userData;
113    OneTimeCodeCallback *cb;
114    void *returnValue;
115    unsigned thrID;
116 public:
117    OneTimeCodeInfo(bool _synchronous, void *_userData, OneTimeCodeCallback *_cb, unsigned _thrID) :
118       synchronous(_synchronous), completed(false), userData(_userData), cb(_cb),
119       thrID(_thrID) { };
120
121    bool isSynchronous() { return synchronous; }
122
123    bool isCompleted() const { return completed; }
124    void setCompleted(bool _completed) { completed = _completed; }
125
126    void *getUserData() { return userData; }
127
128    void setReturnValue(void *_returnValue) { returnValue = _returnValue; }
129    void *getReturnValue() { return returnValue; }
130
131    unsigned getThreadID() { return thrID; }
132
133    OneTimeCodeCallback *getCallback() { return cb;}
134    
135 };
136
137
138 /*
139  * Represents a process
140  */
141 #ifdef DYNINST_CLASS_NAME
142 #undef DYNINST_CLASS_NAME
143 #endif
144 #define DYNINST_CLASS_NAME BPatch_process
145 class BPATCH_DLL_EXPORT BPatch_process : public BPatch_addressSpace {
146     friend class BPatch;
147     friend class BPatch_image;
148     friend class BPatch_function;
149     friend class BPatch_frame;
150     friend class BPatch_thread;
151     friend class BPatch_asyncEventHandler;
152     friend class BPatch_module;
153     friend class BPatch_basicBlock;
154     friend class BPatch_flowGraph;
155     friend class BPatch_loopTreeNode;
156     friend class BPatch_point;
157     friend class BPatch_funcCallExpr;
158     friend class BPatch_eventMailbox;
159     friend class BPatch_instruction;
160     friend class BPatch_addressSpace;
161     friend class process;
162     friend class SignalHandler;
163     friend int handleSignal(EventRecord &ev);
164     friend void threadDeleteWrapper(BPatch_process *, BPatch_thread *); 
165     friend bool pollForStatusChange();
166     friend class AsyncThreadEventCallback;
167     friend class AstNode; // AST needs to translate instPoint to
168                       // BPatch_point via instp_map
169     friend class AstOperatorNode;
170     friend class AstMemoryNode;
171     friend class rpcMgr;
172     friend class EventRecord;
173     friend bool handleThreadCreate(BPatch_process *, EventRecord &, unsigned, int, dynthread_t, unsigned long, unsigned long);
174
175     public:
176     void PDSEP_updateObservedCostAddr(unsigned long a);
177     private:
178
179     //References to lower level objects
180     process *llproc;
181
182     BPatch_Vector<BPatch_thread *> threads;
183
184     // Due to interactions of internal events and signal handling,
185     // we need to keep an internal variable of whether the user
186     // should observe us as stopped. This is set by internal 
187     // code if a "stop" is a real stop. 
188     bool isVisiblyStopped;
189     bool isAttemptingAStop;
190
191     int lastSignal;
192     int exitCode;
193     int exitSignal;
194     bool exitedNormally;
195     bool exitedViaSignal;
196     bool mutationsActive;
197     bool createdViaAttach;
198     bool detached;
199
200     bool unreportedStop;
201     bool unreportedTermination;
202
203     // BPatch-level; once the callbacks are sent by the llproc, we're terminated
204     // Used because callbacks go (and can clean up user code) before the low-level process
205     // sets flags.
206     bool terminated; 
207     bool reportedExit;
208
209     //When an async RPC is posted on a stopped process we post it, but haven't 
210     // yet launched it.  The next process level continue should start the RPC 
211     // going.  unstarteRPC is true if we have a posted but not launced RPC.
212     bool unstartedRPC;
213
214     void setUnreportedStop(bool new_value) { unreportedStop = new_value; }
215     void setUnreportedTermination(bool new_value) {unreportedTermination = new_value;}
216
217     void setExitedNormally();
218     void setExitedViaSignal(int signalnumber);
219
220     void setExitCode(int exitcode) { exitCode = exitcode; }
221     void setExitSignal(int exitsignal) { exitSignal = exitsignal; }
222
223     bool pendingUnreportedStop() { return unreportedStop;}
224     bool pendingUnreportedTermination() { return unreportedTermination; }
225
226     bool statusIsStopped();
227     bool statusIsTerminated();
228
229     bool getType();
230     AddressSpace * getAS();
231     bool getTerminated() {return terminated;}
232     bool getMutationsActive() {return mutationsActive;}
233
234     int activeOneTimeCodes_;
235     bool resumeAfterCompleted_;
236
237     static int oneTimeCodeCallbackDispatch(process *theProc,
238                                            unsigned /* rpcid */, 
239                                            void *userData,
240                                            void *returnValue);
241
242     void *oneTimeCodeInternal(const BPatch_snippet &expr,
243                               BPatch_thread *thread, // == NULL if proc-wide
244                               void *userData,
245                               BPatchOneTimeCodeCallback cb = NULL,
246                               bool synchronous = true, bool *err = NULL);
247
248     void oneTimeCodeCompleted(bool isSynchronous);
249
250     protected:
251     // for creating a process
252     BPatch_process(const char *path, const char *argv[], const char **envp = NULL, 
253                   int stdin_fd = 0, int stdout_fd = 1, int stderr_fd = 2);
254     // for attaching
255     BPatch_process(const char *path, int pid);  
256
257     // for forking
258     BPatch_process(process *proc);
259
260     // Create a new thread in this proc
261     BPatch_thread *createOrUpdateBPThread(int lwp, dynthread_t tid, unsigned index, 
262                                           unsigned long stack_start, 
263                                           unsigned long start_addr);
264     BPatch_thread *handleThreadCreate(unsigned index, int lwpid, dynthread_t threadid, 
265                             unsigned long stack_top, unsigned long start_pc, process *proc = NULL);
266     void deleteBPThread(BPatch_thread *thrd);
267
268     void updateThreadInfo();
269
270         
271     public:
272
273     // DO NOT USE
274     // this function should go away as soon as Paradyn links against Dyninst
275     process *lowlevel_process() { return llproc; }
276     // DO NOT USE
277     // this function should go away as soon as Paradyn links against Dyninst
278     BPatch_function *get_function(int_function *f);
279
280     // DO NOT USE
281     // These internal funcs trigger callbacks registered to matching events
282     bool triggerStopThread(instPoint *intPoint, int_function *intFunc, 
283                             int cb_ID, void *retVal);
284     bool triggerSignalHandlerCB(instPoint *point, int_function *func, long signum, 
285                                BPatch_Vector<Dyninst::Address> *handlers); 
286
287     // DO NOT USE
288     // This is an internal debugging function
289     API_EXPORT_V(Int, (), 
290     void, debugSuicide,());
291
292   
293     //  BPatch_process::~BPatch_process
294     //
295     //  Destructor
296     API_EXPORT_DTOR(_dtor, (),
297     ~,BPatch_process,());
298
299        
300     //  BPatch_process::getPid
301     //  
302     //  Get  id of mutatee process
303
304     API_EXPORT(Int, (),
305     int,getPid,());
306
307         // BPatch_process::getAddressWidth
308         //
309         // Get the address width (4 or 8) of the process
310
311     API_EXPORT(Int, (),
312     int,getAddressWidth,());
313
314     //  BPatch_process::stopExecution
315     //  
316     //  Stop the mutatee process
317
318     API_EXPORT(Int, (),
319     bool,stopExecution,());
320
321     //  BPatch_process::continueExecution
322     //  
323     //  Resume execution of mutatee process
324
325     API_EXPORT(Int, (),
326     bool,continueExecution,());
327
328     //  BPatch_process::terminateExecution
329     //  
330     //  Terminate mutatee process
331
332     API_EXPORT(Int, (),
333     bool,terminateExecution,());
334
335     //  BPatch_process::isStopped
336     //  
337     //  Returns true if mutatee process is currently stopped
338
339     API_EXPORT(Int, (),
340     bool,isStopped,());
341
342     //  BPatch_process::stopSignal
343     //  
344     //  Returns signal number of signal that stopped mutatee process
345
346     API_EXPORT(Int, (),
347     int,stopSignal,());
348
349     //  BPatch_process::isTerminated
350     //  
351     //  Returns true if mutatee process is terminated
352
353     API_EXPORT(Int, (),
354     bool,isTerminated,());
355
356     //  BPatch_process::terminationStatus
357     //  
358     //  Returns information on how mutatee process was terminated
359
360     API_EXPORT(Int, (),
361     BPatch_exitType,terminationStatus,());
362
363     //  BPatch_process::getExitCode
364     //  
365     //  Returns integer exit code of (exited) mutatee process
366
367     API_EXPORT(Int, (),
368     int,getExitCode,());
369
370     //  BPatch_process::getExitSignal
371     //  
372     //  Returns integer signal number of signal that caused mutatee to exit
373
374     API_EXPORT(Int, (),
375     int,getExitSignal,());
376
377     //  BPatch_process::detach
378     //  
379     //  Detach from the mutatee process, optionally leaving it running
380
381     API_EXPORT(Int, (),
382     bool,wasRunningWhenAttached,());
383
384     //  BPatch_process::detach
385     //  
386     //  Detach from the mutatee process, optionally leaving it running
387
388     API_EXPORT(Int, (cont),
389     bool,detach,(bool cont));
390
391     //  BPatch_process::isDetached
392     //  
393     //  Returns true if DyninstAPI is detached from this mutatee
394
395     API_EXPORT(Int, (),
396     bool,isDetached,());
397
398     //  BPatch_process::getThreads
399     //
400     //  Fills a vector with the BPatch_thread objects that belong to
401     //  this process
402     API_EXPORT_V(Int, (thrds),
403     void, getThreads, (BPatch_Vector<BPatch_thread *> &thrds));
404
405     //  BPatch_prOcess::isMultithreaded
406     //
407     //  Returns true if this process has more than one thread
408     API_EXPORT(Int, (),
409     bool, isMultithreaded, ());
410
411     //  BPatch_prOcess::isMultithreadCapable
412     //
413     //  Returns true if this process is linked against a thread library
414     //  (and thus might be multithreaded)
415     API_EXPORT(Int, (),
416     bool, isMultithreadCapable, ());
417
418     //  BPatch_process::getThread
419     //
420     //  Returns one of this process's threads, given a tid
421     API_EXPORT(Int, (tid),
422     BPatch_thread *, getThread, (dynthread_t tid));
423
424     //  BPatch_process::getThread
425     //
426     //  Returns one of this process's threads, given an index
427     API_EXPORT(Int, (index),
428     BPatch_thread *, getThreadByIndex, (unsigned index));
429
430     //  BPatch_process::dumpCore
431     //  
432     //  Produce a core dump file <file> for the mutatee process
433
434     API_EXPORT(Int, (file, terminate),
435     bool,dumpCore,(const char *file, bool terminate));
436
437     //  BPatch_process::dumpImage
438     //  
439     //  Write contents of memory to <file>
440
441     API_EXPORT(Int, (file),
442     bool,dumpImage,(const char *file));
443
444     //  BPatch_process::dumpPatchedImage
445     //  
446     //  Write executable image of mutatee, including runtime modifications, to <file>
447
448     API_EXPORT(Int, (file),
449     char *,dumpPatchedImage,(const char* file));
450
451
452     //  BPatch_process::getInheritedVariable
453     //  
454     //  
455
456     API_EXPORT(Int, (pVar),
457     BPatch_variableExpr *,getInheritedVariable,(BPatch_variableExpr &pVar));
458
459     //  BPatch_process::getInheritedSnippet
460     //  
461     //  
462
463     API_EXPORT(Int, (parentSnippet),
464     BPatchSnippetHandle *,getInheritedSnippet,(BPatchSnippetHandle &parentSnippet));
465
466
467         //  BPatch_binaryEdit::beginInsertionSet()
468     //
469     //  Start the batch insertion of multiple points; all calls to insertSnippet*
470     //  after this call will not actually instrument until finalizeInsertionSet is
471     //  called
472
473     API_EXPORT_V(Int, (),
474                  void, beginInsertionSet, ());
475
476
477     //BPatch_process::finalizeInsertionSet()
478     
479         // Finalizes all instrumentation logically added since a call to beginInsertionSet.
480     //  Returns true if all instrumentation was successfully inserted; otherwise, none
481     //  was. Individual instrumentation can be manipulated via the BPatchSnippetHandles
482     //  returned from individual calls to insertSnippet.
483     //
484     //  atomic: if true, all instrumentation will be removed if any fails to go in.
485     //  modified: if provided, and set to true by finalizeInsertionSet, additional
486     //            steps were taken to make the installation work, such as modifying
487     //            process state.  Note that such steps will be taken whether or not
488     //            a variable is provided.
489
490     API_EXPORT(Int, (atomic, modified),
491                bool, finalizeInsertionSet, (bool atomic, bool *modified = NULL));
492                                        
493     
494     API_EXPORT(Int, (atomic, modified, catchup_handles),
495                bool, finalizeInsertionSetWithCatchup, (bool atomic, bool *modified,
496                                             BPatch_Vector<BPatch_catchupInfo> &catchup_handles));
497    
498     
499     //  BPatch_process::setMutationsActive
500     //  
501     //  Turn on/off instrumentation
502
503     API_EXPORT(Int, (activate),
504     bool,setMutationsActive,(bool activate));
505
506     //  BPatch_process::oneTimeCode
507     //  
508     //  Have the specified code be executed by the mutatee once.  Wait until done.
509
510     API_EXPORT(Int, (expr, err),
511     void *,oneTimeCode,(const BPatch_snippet &expr, bool *err = NULL));
512
513     //  BPatch_process::oneTimeCodeAsync
514     //  
515     //  Have the specified code be executed by the mutatee once.  Dont wait until done.
516
517     API_EXPORT(Int, (expr, userData, cb),
518     bool,oneTimeCodeAsync,(const BPatch_snippet &expr, void *userData = NULL,
519                            BPatchOneTimeCodeCallback cb = NULL));
520                            
521
522     //  BPatch_process::loadLibrary
523     //  
524     //  Load a shared library into the mutatee's address space
525     //
526     //  the reload argument is used by save the world to determine
527     //  if this library should be reloaded by the mutated binary
528     //  when it starts up. this is up to the user because loading
529     //  an extra shared library could hide access to the 'correct'
530     //  function by redefining a function  
531
532     API_EXPORT(Int, (libname, reload),
533     bool,loadLibrary,(const char *libname, bool reload = false));
534
535     // BPatch_process::setBeingDebuggedFlag
536     //
537     // This is a Windows only function that sets the user-space
538     // debuggerPresent flag to 0 or 1, 0 meaning that the process is not
539     // being debugged.  The debugging process will still have debug
540     // access, but system calls that ask if the process is being debugged
541     // will say that it is not because they merely return the value of the
542     // user-space beingDebugged flag. 
543     API_EXPORT(Int, (debuggerPresent),
544     bool,setBeingDebuggedFlag,(bool debuggerPresent));
545
546     //  BPatch_process::enableDumpPatchedImage
547     //  
548     //  
549     API_EXPORT_V(Int, (),
550     void,enableDumpPatchedImage,());
551
552 #ifdef IBM_BPATCH_COMPAT
553     API_EXPORT(Int, (name, loadaddr),
554     bool,addSharedObject,(const char *name, const unsigned long loadaddr));
555 #endif
556
557 };
558
559 #endif /* BPatch_process_h_ */