This commit enables arbitrary instrumentation points at the last instruction
[dyninst.git] / dyninstAPI / h / BPatch_thread.h
1 /*
2  * Copyright (c) 1996 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
61 class process;
62 class miniTrampHandle;
63 class BPatch;
64 class BPatch_thread;
65
66 // BPatch_callWhen is defined in BPatch_point.h
67
68 /*
69  * Used to specify whether a snippet should be installed before other snippets
70  * that have previously been inserted at the same point, or after.
71  */
72 typedef enum {
73     BPatch_firstSnippet,
74     BPatch_lastSnippet
75 } BPatch_snippetOrder;
76
77
78 /*
79  * Contains information about the code that was inserted by an earlier call to
80  * Bpatch_thread::insertSnippet.
81  */
82 class BPATCH_DLL_EXPORT BPatchSnippetHandle {
83     friend class BPatch_thread;
84 private:
85     BPatch_Vector<miniTrampHandle *> mtHandles;
86       
87 public:
88     process *proc;
89
90     BPatchSnippetHandle(process *_proc) : proc(_proc) {};
91     ~BPatchSnippetHandle();
92
93     void add(miniTrampHandle *pointInstance);
94     void getMiniTrampHandles(BPatch_Vector<miniTrampHandle *> *save_mtHandles) {
95       for(unsigned i=0; i<mtHandles.size(); i++)
96         (*save_mtHandles).push_back(mtHandles[i]);
97     }
98 };
99
100 /*
101  * The following types are used by BPatch_thread::getCallStack()
102  */
103
104 // Stack frame types
105 typedef enum {
106     BPatch_frameNormal,
107     BPatch_frameSignal,
108     BPatch_frameTrampoline
109 } BPatch_frameType;
110
111 // Contains information about a stack frame (used by
112 class BPATCH_DLL_EXPORT BPatch_frame {
113     BPatch_thread *thread;
114
115     void *pc;
116     void *fp;
117 public:
118     BPatch_frame() : thread(NULL), pc(NULL), fp(NULL) {};
119     BPatch_frame(BPatch_thread *_thread, void *_pc, void *_fp) :
120         thread(_thread), pc(_pc), fp(_fp) {};
121
122     BPatch_frameType getFrameType();
123
124     void *getPC() { return pc; };
125     void *getFP() { return fp; };
126
127     BPatch_function *findFunction();
128    
129     // The following are planned but no yet implemented:
130     // int getSignalNumber();
131     // BPatch_point *findPoint();
132 };
133
134 /*
135  * Represents a thread of execution.
136  */
137 class BPATCH_DLL_EXPORT BPatch_thread {
138     friend class BPatch;
139     friend class BPatch_image;
140     friend class BPatch_function;
141     friend class BPatch_frame;
142     friend class process;
143     friend bool pollForStatusChange();
144
145     process             *proc;
146     BPatch_image        *image;
147     int                 lastSignal;
148     int                 exitCode;
149     bool                mutationsActive;
150     bool                createdViaAttach;
151     bool                detached;
152
153     bool                unreportedStop;
154     bool                unreportedTermination;
155
156     void                setUnreportedStop(bool new_value)
157                                 { unreportedStop = new_value; }
158     void                setUnreportedTermination(bool new_value)
159                                 { unreportedTermination = new_value; }
160
161     bool                pendingUnreportedStop()
162                                 { return unreportedStop; }
163     bool                pendingUnreportedTermination()
164                                 { return unreportedTermination; }
165
166     bool                statusIsStopped();
167     bool                statusIsTerminated();
168
169     static void         oneTimeCodeCallbackDispatch(process *theProc,
170                                                     void *userData,
171                                                     void *returnValue);
172
173     void                *oneTimeCodeInternal(const BPatch_snippet &expr,
174                                              void *userData,
175                                              bool synchronous);
176
177 protected:
178     // for creating a process
179     BPatch_thread(const char *path, char *argv[], char *envp[] = NULL, 
180                   int stdin_fd = 0, int stdout_fd = 1, int stderr_fd = 2);
181     // for attaching
182     BPatch_thread(const char *path, int pid);   
183
184     // for forking
185     BPatch_thread(int childPid, process *proc);
186
187 public:
188     ~BPatch_thread();
189
190     BPatch_image *getImage() { return image; }
191
192     int         getPid();
193
194     bool        stopExecution();
195     bool        continueExecution();
196     bool        terminateExecution();
197
198     bool        isStopped();
199     int         stopSignal();
200     bool        isTerminated();
201     int         terminationStatus();
202
203     void        detach(bool cont);
204
205     bool        dumpCore(const char *file, bool terminate);
206     bool        dumpImage(const char *file);
207     char*       dumpPatchedImage(const char* file);//ccw 28 oct 2001
208
209     BPatch_variableExpr *malloc(int n);
210     BPatch_variableExpr *malloc(const BPatch_type &type);
211     void        free(const BPatch_variableExpr &ptr);
212     BPatch_variableExpr *getInheritedVariable(const BPatch_variableExpr &pVar);
213     BPatchSnippetHandle *getInheritedSnippet(
214                                           BPatchSnippetHandle &parentSnippet);
215
216
217     // to provide backward compatiblity 
218     BPatchSnippetHandle *insertSnippet(
219                             const BPatch_snippet &expr,
220                             BPatch_point &point,
221                             BPatch_snippetOrder order = BPatch_firstSnippet);
222
223     BPatchSnippetHandle *insertSnippet(
224                             const BPatch_snippet &expr,
225                             BPatch_point &point,
226                             BPatch_callWhen when,
227                             BPatch_snippetOrder order = BPatch_firstSnippet);
228
229     BPatchSnippetHandle *insertSnippet(
230                             const BPatch_snippet &expr,
231                             const BPatch_Vector<BPatch_point *> &points,
232                             BPatch_snippetOrder order = BPatch_firstSnippet);
233
234     BPatchSnippetHandle *insertSnippet(
235                             const BPatch_snippet &expr,
236                             const BPatch_Vector<BPatch_point *> &points,
237                             BPatch_callWhen when,
238                             BPatch_snippetOrder order = BPatch_firstSnippet);
239
240     bool        deleteSnippet(BPatchSnippetHandle *handle);
241
242     void        setMutationsActive(bool activate);
243
244     bool        replaceFunctionCall(BPatch_point &point,
245                                     BPatch_function &newFunc);
246     bool        removeFunctionCall(BPatch_point &point);
247     bool        replaceFunction(BPatch_function &oldFunc,
248                                 BPatch_function &newFunc);
249
250     void        oneTimeCode(const BPatch_snippet &expr) {
251                         oneTimeCodeInternal(expr, NULL, true);
252                     };
253
254     void        oneTimeCodeAsync(const BPatch_snippet &expr, void *userData = NULL) {
255                         oneTimeCodeInternal(expr, userData, false);
256                     };
257
258         //the reload argument is used by save the world to determine
259         //if this library should be reloaded by the mutated binary
260         //when it starts up. this is up to the user because loading
261         //an extra shared library could hide access to the 'correct'
262         //function by redefining a function  
263     bool loadLibrary(const char *libname, bool reload = false); 
264
265     //method that retrieves the line number and file name corresponding 
266     //to an address
267     bool getLineAndFile(unsigned long addr,unsigned short& lineNo,
268                         char* fileName,int length);
269     //returns the function containing an address
270     BPatch_function *findFunctionByAddr(void *addr);
271
272     void getCallStack(BPatch_Vector<BPatch_frame>& stack);
273
274         void startSaveWorld();//ccw 23 jan 2002
275 #ifdef IBM_BPATCH_COMPAT
276     bool isThreaded() { return false; }
277     bool addSharedObject(const char *name, const unsigned long loadaddr);
278 #endif
279
280 };
281
282 #endif /* BPatch_thread_h_ */