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