extended parseThat to use new addressSpace abstraction
[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 process;
161     friend class SignalHandler;
162     friend int handleSignal(EventRecord &ev);
163     friend void threadDeleteWrapper(BPatch_process *, BPatch_thread *); 
164     friend bool pollForStatusChange();
165     friend class AsyncThreadEventCallback;
166     friend class AstNode; // AST needs to translate instPoint to
167                       // BPatch_point via instp_map
168     friend class AstOperatorNode;
169     friend class AstMemoryNode;
170     friend class rpcMgr;
171
172     public:
173     void PDSEP_updateObservedCostAddr(unsigned long a);
174     private:
175
176     //References to lower level objects
177     process *llproc;
178
179     BPatch_Vector<BPatch_thread *> threads;
180
181     // Due to interactions of internal events and signal handling,
182     // we need to keep an internal variable of whether the user
183     // should observe us as stopped. This is set by internal 
184     // code if a "stop" is a real stop. 
185     bool isVisiblyStopped;
186     bool isAttemptingAStop;
187
188     int lastSignal;
189     int exitCode;
190     int exitSignal;
191     bool exitedNormally;
192     bool exitedViaSignal;
193     bool mutationsActive;
194     bool createdViaAttach;
195     bool detached;
196
197     bool unreportedStop;
198     bool unreportedTermination;
199
200     // BPatch-level; once the callbacks are sent by the llproc, we're terminated
201     // Used because callbacks go (and can clean up user code) before the low-level process
202     // sets flags.
203     bool terminated; 
204
205     //When an async RPC is posted on a stopped process we post it, but haven't 
206     // yet launched it.  The next process level continue should start the RPC 
207     // going.  unstarteRPC is true if we have a posted but not launced RPC.
208     bool unstartedRPC;
209
210     void setUnreportedStop(bool new_value) { unreportedStop = new_value; }
211     void setUnreportedTermination(bool new_value) {unreportedTermination = new_value;}
212
213     void setExitedNormally();
214     void setExitedViaSignal(int signalnumber);
215
216     void setExitCode(int exitcode) { exitCode = exitcode; }
217     void setExitSignal(int exitsignal) { exitSignal = exitsignal; }
218
219     bool pendingUnreportedStop() { return unreportedStop;}
220     bool pendingUnreportedTermination() { return unreportedTermination; }
221
222     bool statusIsStopped();
223     bool statusIsTerminated();
224
225     bool getType();
226     AddressSpace * getAS();
227     bool getTerminated() {return terminated;}
228     bool getMutationsActive() {return mutationsActive;}
229
230     int activeOneTimeCodes_;
231     bool resumeAfterCompleted_;
232
233     static int oneTimeCodeCallbackDispatch(process *theProc,
234                                            unsigned /* rpcid */, 
235                                            void *userData,
236                                            void *returnValue);
237
238     void *oneTimeCodeInternal(const BPatch_snippet &expr,
239                               BPatch_thread *thread, // == NULL if proc-wide
240                               void *userData,
241                               BPatchOneTimeCodeCallback cb = NULL,
242                               bool synchronous = true, bool *err = NULL);
243
244     void oneTimeCodeCompleted(bool isSynchronous);
245
246     protected:
247     // for creating a process
248     BPatch_process(const char *path, const char *argv[], const char **envp = NULL, 
249                   int stdin_fd = 0, int stdout_fd = 1, int stderr_fd = 2);
250     // for attaching
251     BPatch_process(const char *path, int pid);  
252
253     // for forking
254     BPatch_process(process *proc);
255
256     // Create a new thread in this proc
257     BPatch_thread *createOrUpdateBPThread(int lwp, dynthread_t tid, unsigned index, 
258                                           unsigned long stack_start, 
259                                           unsigned long start_addr);
260     BPatch_thread *handleThreadCreate(unsigned index, int lwpid, dynthread_t threadid, 
261                             unsigned long stack_top, unsigned long start_pc, process *proc = NULL);
262     void deleteBPThread(BPatch_thread *thrd);
263
264     // These callbacks are triggered by lower-level code and forward
265     // calls up to the findOrCreate functions.
266     static BPatch_function *createBPFuncCB(AddressSpace *p, int_function *f);
267     static BPatch_point *createBPPointCB(AddressSpace *p, int_function *f,
268                                          instPoint *ip, int type);
269     void updateThreadInfo();
270
271         
272     public:
273
274     // DO NOT USE
275     // this function should go away as soon as Paradyn links against Dyninst
276     process *lowlevel_process() { return llproc; }
277
278     // DO NOT USE
279     // this function should go away as soon as Paradyn links against Dyninst
280     BPatch_function *get_function(int_function *f);
281
282     // DO NOT USE
283     // This is an internal debugging function
284     API_EXPORT_V(Int, (), 
285     void, debugSuicide,());
286
287   
288     //  BPatch_process::~BPatch_process
289     //
290     //  Destructor
291     API_EXPORT_DTOR(_dtor, (),
292     ~,BPatch_process,());
293
294        
295     //  BPatch_process::getPid
296     //  
297     //  Get  id of mutatee process
298
299     API_EXPORT(Int, (),
300     int,getPid,());
301
302         // BPatch_process::getAddressWidth
303         //
304         // Get the address width (4 or 8) of the process
305
306     API_EXPORT(Int, (),
307     int,getAddressWidth,());
308
309     //  BPatch_process::stopExecution
310     //  
311     //  Stop the mutatee process
312
313     API_EXPORT(Int, (),
314     bool,stopExecution,());
315
316     //  BPatch_process::continueExecution
317     //  
318     //  Resume execution of mutatee process
319
320     API_EXPORT(Int, (),
321     bool,continueExecution,());
322
323     //  BPatch_process::terminateExecution
324     //  
325     //  Terminate mutatee process
326
327     API_EXPORT(Int, (),
328     bool,terminateExecution,());
329
330     //  BPatch_process::isStopped
331     //  
332     //  Returns true if mutatee process is currently stopped
333
334     API_EXPORT(Int, (),
335     bool,isStopped,());
336
337     //  BPatch_process::stopSignal
338     //  
339     //  Returns signal number of signal that stopped mutatee process
340
341     API_EXPORT(Int, (),
342     int,stopSignal,());
343
344     //  BPatch_process::isTerminated
345     //  
346     //  Returns true if mutatee process is terminated
347
348     API_EXPORT(Int, (),
349     bool,isTerminated,());
350
351     //  BPatch_process::terminationStatus
352     //  
353     //  Returns information on how mutatee process was terminated
354
355     API_EXPORT(Int, (),
356     BPatch_exitType,terminationStatus,());
357
358     //  BPatch_process::getExitCode
359     //  
360     //  Returns integer exit code of (exited) mutatee process
361
362     API_EXPORT(Int, (),
363     int,getExitCode,());
364
365     //  BPatch_process::getExitSignal
366     //  
367     //  Returns integer signal number of signal that caused mutatee to exit
368
369     API_EXPORT(Int, (),
370     int,getExitSignal,());
371
372     //  BPatch_process::detach
373     //  
374     //  Detach from the mutatee process, optionally leaving it running
375
376     API_EXPORT(Int, (),
377     bool,wasRunningWhenAttached,());
378
379     //  BPatch_process::detach
380     //  
381     //  Detach from the mutatee process, optionally leaving it running
382
383     API_EXPORT(Int, (cont),
384     bool,detach,(bool cont));
385
386     //  BPatch_process::isDetached
387     //  
388     //  Returns true if DyninstAPI is detached from this mutatee
389
390     API_EXPORT(Int, (),
391     bool,isDetached,());
392
393     //  BPatch_process::getThreads
394     //
395     //  Fills a vector with the BPatch_thread objects that belong to
396     //  this process
397     API_EXPORT_V(Int, (thrds),
398     void, getThreads, (BPatch_Vector<BPatch_thread *> &thrds));
399
400     //  BPatch_prOcess::isMultithreaded
401     //
402     //  Returns true if this process has more than one thread
403     API_EXPORT(Int, (),
404     bool, isMultithreaded, ());
405
406     //  BPatch_prOcess::isMultithreadCapable
407     //
408     //  Returns true if this process is linked against a thread library
409     //  (and thus might be multithreaded)
410     API_EXPORT(Int, (),
411     bool, isMultithreadCapable, ());
412
413     //  BPatch_process::getThread
414     //
415     //  Returns one of this process's threads, given a tid
416     API_EXPORT(Int, (tid),
417     BPatch_thread *, getThread, (dynthread_t tid));
418
419     //  BPatch_process::getThread
420     //
421     //  Returns one of this process's threads, given an index
422     API_EXPORT(Int, (index),
423     BPatch_thread *, getThreadByIndex, (unsigned index));
424
425     //  BPatch_process::dumpCore
426     //  
427     //  Produce a core dump file <file> for the mutatee process
428
429     API_EXPORT(Int, (file, terminate),
430     bool,dumpCore,(const char *file, bool terminate));
431
432     //  BPatch_process::dumpImage
433     //  
434     //  Write contents of memory to <file>
435
436     API_EXPORT(Int, (file),
437     bool,dumpImage,(const char *file));
438
439     //  BPatch_process::dumpPatchedImage
440     //  
441     //  Write executable image of mutatee, including runtime modifications, to <file>
442
443     API_EXPORT(Int, (file),
444     char *,dumpPatchedImage,(const char* file));
445
446
447     //  BPatch_process::getInheritedVariable
448     //  
449     //  
450
451     API_EXPORT(Int, (pVar),
452     BPatch_variableExpr *,getInheritedVariable,(BPatch_variableExpr &pVar));
453
454     //  BPatch_process::getInheritedSnippet
455     //  
456     //  
457
458     API_EXPORT(Int, (parentSnippet),
459     BPatchSnippetHandle *,getInheritedSnippet,(BPatchSnippetHandle &parentSnippet));
460
461     //  BPatch_process::insertSnippet
462     //  
463     //  Insert new code into the mutatee
464
465     API_EXPORT(Int, (expr, point, order),
466     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr, BPatch_point &point,
467                                            BPatch_snippetOrder order = BPatch_firstSnippet));
468
469     //BPatch_process::insertSnippet
470       
471     //Insert new code into the mutatee, specifying "when" (before/after point)
472
473     API_EXPORT(When, (expr, point, when, order),
474     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr, BPatch_point &point,
475                                      BPatch_callWhen when,
476                                        BPatch_snippetOrder order = BPatch_firstSnippet));
477
478     //BPatch_process::insertSnippet
479       
480     //Insert new code into the mutatee at multiple points
481
482     API_EXPORT(AtPoints, (expr, points, order),
483     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr,
484                                    const BPatch_Vector<BPatch_point *> &points,
485                                        BPatch_snippetOrder order = BPatch_firstSnippet));
486
487       // BPatch_process::insertSnippet
488       
489       //Insert new code into the mutatee at multiple points, specifying "when"
490
491     API_EXPORT(AtPointsWhen, (expr, points, when, order),
492     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr,
493                                          const BPatch_Vector<BPatch_point *> &points,
494                                          BPatch_callWhen when,
495                                          BPatch_snippetOrder order = BPatch_firstSnippet));
496
497
498
499         //  BPatch_binaryEdit::beginInsertionSet()
500     //
501     //  Start the batch insertion of multiple points; all calls to insertSnippet*
502     //  after this call will not actually instrument until finalizeInsertionSet is
503     //  called
504
505     API_EXPORT_V(Int, (),
506                  void, beginInsertionSet, ());
507
508
509     //BPatch_process::finalizeInsertionSet()
510     
511         // Finalizes all instrumentation logically added since a call to beginInsertionSet.
512     //  Returns true if all instrumentation was successfully inserted; otherwise, none
513     //  was. Individual instrumentation can be manipulated via the BPatchSnippetHandles
514     //  returned from individual calls to insertSnippet.
515     //
516     //  atomic: if true, all instrumentation will be removed if any fails to go in.
517     //  modified: if provided, and set to true by finalizeInsertionSet, additional
518     //            steps were taken to make the installation work, such as modifying
519     //            process state.  Note that such steps will be taken whether or not
520     //            a variable is provided.
521
522     API_EXPORT(Int, (atomic, modified),
523                bool, finalizeInsertionSet, (bool atomic, bool *modified = NULL));
524                                        
525     
526     API_EXPORT(Int, (atomic, modified, catchup_handles),
527                bool, finalizeInsertionSetWithCatchup, (bool atomic, bool *modified,
528                                             BPatch_Vector<BPatch_catchupInfo> &catchup_handles));
529    
530     
531     //  BPatch_process::setMutationsActive
532     //  
533     //  Turn on/off instrumentation
534
535     API_EXPORT(Int, (activate),
536     bool,setMutationsActive,(bool activate));
537
538     //  BPatch_process::oneTimeCode
539     //  
540     //  Have the specified code be executed by the mutatee once.  Wait until done.
541
542     API_EXPORT(Int, (expr, err),
543     void *,oneTimeCode,(const BPatch_snippet &expr, bool *err = NULL));
544
545     //  BPatch_process::oneTimeCodeAsync
546     //  
547     //  Have the specified code be executed by the mutatee once.  Dont wait until done.
548
549     API_EXPORT(Int, (expr, userData, cb),
550     bool,oneTimeCodeAsync,(const BPatch_snippet &expr, void *userData = NULL,
551                            BPatchOneTimeCodeCallback cb = NULL));
552                            
553
554     //  BPatch_process::loadLibrary
555     //  
556     //  Load a shared library into the mutatee's address space
557     //
558     //  the reload argument is used by save the world to determine
559     //  if this library should be reloaded by the mutated binary
560     //  when it starts up. this is up to the user because loading
561     //  an extra shared library could hide access to the 'correct'
562     //  function by redefining a function  
563
564     API_EXPORT(Int, (libname, reload),
565     bool,loadLibrary,(const char *libname, bool reload = false));
566
567     //  BPatch_process::enableDumpPatchedImage
568     //  
569     //  
570     API_EXPORT_V(Int, (),
571     void,enableDumpPatchedImage,());
572
573 #ifdef IBM_BPATCH_COMPAT
574     API_EXPORT(Int, (name, loadaddr),
575     bool,addSharedObject,(const char *name, const unsigned long loadaddr));
576 #endif
577
578 };
579
580 #endif /* BPatch_process_h_ */