duran 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +11 -0
  3. data/Rakefile +29 -0
  4. data/VERSION +1 -0
  5. data/client_src/dr_include/dr_api.h +102 -0
  6. data/client_src/dr_include/dr_app.h +92 -0
  7. data/client_src/dr_include/dr_config.h +650 -0
  8. data/client_src/dr_include/dr_defines.h +391 -0
  9. data/client_src/dr_include/dr_events.h +1057 -0
  10. data/client_src/dr_include/dr_ir_instr.h +1214 -0
  11. data/client_src/dr_include/dr_ir_instrlist.h +149 -0
  12. data/client_src/dr_include/dr_ir_macros.h +2426 -0
  13. data/client_src/dr_include/dr_ir_opcodes.h +768 -0
  14. data/client_src/dr_include/dr_ir_opnd.h +1170 -0
  15. data/client_src/dr_include/dr_ir_utils.h +708 -0
  16. data/client_src/dr_include/dr_proc.h +327 -0
  17. data/client_src/dr_include/dr_tools.h +1304 -0
  18. data/client_src/duran.c +57 -0
  19. data/client_src/extconf.rb +28 -0
  20. data/lib/duran.rb +18 -0
  21. data/lib/duran/app.rb +8 -0
  22. data/lib/duran/defines.rb +39 -0
  23. data/lib/duran/events.rb +156 -0
  24. data/lib/duran/ir_opcodes.rb +616 -0
  25. data/lib/duran/ir_opnd.rb +329 -0
  26. data/lib/duran/ir_utils.rb +133 -0
  27. data/lib/duran/proc.rb +49 -0
  28. data/lib/duran/structs.rb +20 -0
  29. data/lib/duran/structs/exception.rb +23 -0
  30. data/lib/duran/structs/fault_fragment_info.rb +34 -0
  31. data/lib/duran/structs/instruction.rb +15 -0
  32. data/lib/duran/structs/machine_context.rb +80 -0
  33. data/lib/duran/structs/memory_info.rb +12 -0
  34. data/lib/duran/structs/module_data.rb +61 -0
  35. data/lib/duran/structs/module_names.rb +24 -0
  36. data/lib/duran/structs/operand.rb +15 -0
  37. data/lib/duran/structs/restore_state_info.rb +30 -0
  38. data/lib/duran/structs/signal_info.rb +41 -0
  39. data/lib/duran/structs/tracedump.rb +50 -0
  40. data/lib/duran/tools.rb +214 -0
  41. metadata +104 -0
@@ -0,0 +1,391 @@
1
+ /* **********************************************************
2
+ * Copyright (c) 2002-2009 VMware, Inc. All rights reserved.
3
+ * **********************************************************/
4
+
5
+ /*
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ *
9
+ * * Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ *
12
+ * * Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ *
16
+ * * Neither the name of VMware, Inc. nor the names of its contributors may be
17
+ * used to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
24
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
30
+ * DAMAGE.
31
+ */
32
+
33
+ #ifndef _DR_DEFINES_H_
34
+ #define _DR_DEFINES_H_ 1
35
+
36
+ /****************************************************************************
37
+ * GENERAL TYPEDEFS AND DEFINES
38
+ */
39
+
40
+ /**
41
+ * @file dr_defines.h
42
+ * @brief Basic defines and type definitions.
43
+ */
44
+
45
+ /* A client's target operating system and architecture must be specified. */
46
+ #if (!defined(LINUX) && !defined(WINDOWS)) || (defined(LINUX) && defined(WINDOWS))
47
+ # error Target operating system unspecified: must define either WINDOWS xor LINUX
48
+ #endif
49
+
50
+ #if (!defined(X86_64) && !defined(X86_32)) || (defined(X86_64) && defined(X86_32))
51
+ # error Target architecture unspecified: must define either X86_64 xor X86_32
52
+ #endif
53
+
54
+ #if defined(X86_64) && !defined(X64)
55
+ # define X64
56
+ #endif
57
+
58
+ #ifdef WINDOWS
59
+ # define WIN32_LEAN_AND_MEAN
60
+ # include <windows.h>
61
+ # include <winbase.h>
62
+ #else
63
+ # include <stdio.h>
64
+ # include <stdlib.h>
65
+ #endif
66
+
67
+ #ifdef WINDOWS
68
+ /* allow nameless struct/union */
69
+ # pragma warning(disable: 4201)
70
+ #endif
71
+
72
+ #ifdef WINDOWS
73
+ # define DR_EXPORT __declspec(dllexport)
74
+ # define LINK_ONCE __declspec(selectany)
75
+ # define ALIGN_VAR(x) __declspec(align(x))
76
+ # define inline __inline
77
+ # define INLINE_FORCED __forceinline
78
+ #else
79
+ /* We assume gcc is being used. If the client is using -fvisibility
80
+ * (in gcc >= 3.4) to not export symbols by default, setting
81
+ * USE_VISIBILITY_ATTRIBUTES will properly export.
82
+ */
83
+ # ifdef USE_VISIBILITY_ATTRIBUTES
84
+ # define DR_EXPORT __attribute__ ((visibility ("default")))
85
+ # else
86
+ # define DR_EXPORT
87
+ # endif
88
+ # define LINK_ONCE __attribute__ ((weak))
89
+ # define ALIGN_VAR(x) __attribute__ ((aligned (x)))
90
+ # define inline __inline__
91
+ # define INLINE_FORCED inline
92
+ #endif
93
+
94
+ /** Cross-platform maximum file path length. */
95
+ #define MAXIMUM_PATH 260
96
+
97
+
98
+ #ifndef NULL
99
+ # define NULL (0)
100
+ #endif
101
+
102
+ #ifndef __cplusplus
103
+ # ifndef DR_DO_NOT_DEFINE_bool
104
+ typedef int bool;
105
+ # endif
106
+ # define true (1)
107
+ # define false (0)
108
+ #endif
109
+
110
+ #ifndef DR_DO_NOT_DEFINE_uint
111
+ typedef unsigned int uint;
112
+ #endif
113
+ #ifndef DR_DO_NOT_DEFINE_ushort
114
+ typedef unsigned short ushort;
115
+ #endif
116
+ #ifndef DR_DO_NOT_DEFINE_byte
117
+ typedef unsigned char byte;
118
+ #endif
119
+ #ifndef DR_DO_NOT_DEFINE_sbyte
120
+ typedef signed char sbyte;
121
+ #endif
122
+ typedef byte * app_pc;
123
+
124
+ typedef void (*generic_func_t) ();
125
+
126
+ #ifdef WINDOWS
127
+ # ifndef DR_DO_NOT_DEFINE_uint64
128
+ typedef unsigned __int64 uint64;
129
+ # endif
130
+ # ifndef DR_DO_NOT_DEFINE_int64
131
+ typedef __int64 int64;
132
+ # endif
133
+ # ifdef X64
134
+ typedef __int64 ssize_t;
135
+ # else
136
+ typedef int ssize_t;
137
+ # endif
138
+ # define INT64_FORMAT "I64"
139
+ #else /* Linux */
140
+ # ifdef X64
141
+ # ifndef DR_DO_NOT_DEFINE_uint64
142
+ typedef unsigned long int uint64;
143
+ # endif
144
+ # ifndef DR_DO_NOT_DEFINE_int64
145
+ typedef long int int64;
146
+ # endif
147
+ # define INT64_FORMAT "l"
148
+ # else
149
+ # ifndef DR_DO_NOT_DEFINE_uint64
150
+ typedef unsigned long long int uint64;
151
+ # endif
152
+ # ifndef DR_DO_NOT_DEFINE_int64
153
+ typedef long long int int64;
154
+ # endif
155
+ # define INT64_FORMAT "ll"
156
+ # endif
157
+ #endif
158
+
159
+ /* a register value: could be of any type; size is what matters. */
160
+ #ifdef X64
161
+ typedef uint64 reg_t;
162
+ #else
163
+ typedef uint reg_t;
164
+ #endif
165
+ /* integer whose size is based on pointers: ptr diff, mask, etc. */
166
+ typedef reg_t ptr_uint_t;
167
+ #ifdef X64
168
+ typedef int64 ptr_int_t;
169
+ #else
170
+ typedef int ptr_int_t;
171
+ #endif
172
+ /* for memory region sizes, use size_t */
173
+
174
+ #ifdef WINDOWS
175
+ typedef ptr_uint_t thread_id_t;
176
+ typedef ptr_uint_t process_id_t;
177
+ #else /* Linux */
178
+ typedef pid_t thread_id_t;
179
+ typedef pid_t process_id_t;
180
+ #endif
181
+
182
+ #ifdef WINDOWS
183
+ /* since a FILE cannot be used outside of the DLL it was created in,
184
+ * we have to use HANDLE on Windows
185
+ * we hide the distinction behind the file_t type
186
+ */
187
+ typedef HANDLE file_t;
188
+ /** The sentinel value for an invalid file_t. */
189
+ # define INVALID_FILE INVALID_HANDLE_VALUE
190
+ /* dr_get_stdout_file and dr_get_stderr_file return errors as
191
+ * INVALID_HANDLE_VALUE. We leave INVALID_HANDLE_VALUE as is,
192
+ * since it equals INVALID_FILE
193
+ */
194
+ /** The file_t value for standard output. */
195
+ # define STDOUT (dr_get_stdout_file())
196
+ /** The file_t value for standard error. */
197
+ # define STDERR (dr_get_stderr_file())
198
+ /** The file_t value for standard input. */
199
+ # define STDIN (dr_get_stdin_file())
200
+ #endif
201
+
202
+ #ifdef LINUX
203
+ typedef int file_t;
204
+ /** The sentinel value for an invalid file_t. */
205
+ # define INVALID_FILE -1
206
+ /** Allow use of stdout after the application closes it. */
207
+ extern file_t our_stdout;
208
+ /** Allow use of stderr after the application closes it. */
209
+ extern file_t our_stderr;
210
+ /** Allow use of stdin after the application closes it. */
211
+ extern file_t our_stdin;
212
+ /** The file_t value for standard output. */
213
+ # define STDOUT (our_stdout == INVALID_FILE ? stdout->_fileno : our_stdout)
214
+ /** The file_t value for standard error. */
215
+ # define STDERR (our_stderr == INVALID_FILE ? stderr->_fileno : our_stderr)
216
+ /** The file_t value for standard error. */
217
+ # define STDIN (our_stdin == INVALID_FILE ? stdin->_fileno : our_stdin)
218
+ #endif
219
+
220
+ /**
221
+ * ID used to uniquely identify a client. This value is set at
222
+ * client registration and passed to the client in dr_init().
223
+ */
224
+ typedef uint client_id_t;
225
+
226
+ /**
227
+ * Internal structure of opnd_t is below abstraction layer.
228
+ * But compiler needs to know field sizes to copy it around
229
+ */
230
+ typedef struct {
231
+ #ifdef X64
232
+ uint black_box_uint;
233
+ uint64 black_box_uint64;
234
+ #else
235
+ uint black_box_uint[3];
236
+ #endif
237
+ } opnd_t;
238
+
239
+ /**
240
+ * Internal structure of instr_t is below abstraction layer, but we
241
+ * provide its size so that it can be used in stack variables
242
+ * instead of always allocated on the heap.
243
+ */
244
+ typedef struct {
245
+ #ifdef X64
246
+ uint black_box_uint[26];
247
+ #else
248
+ uint black_box_uint[16];
249
+ #endif
250
+ } instr_t;
251
+
252
+ # define IN /* marks input param */
253
+ # define OUT /* marks output param */
254
+ # define INOUT /* marks input+output param */
255
+
256
+
257
+ #ifdef X64
258
+ # define IF_X64(x) x
259
+ # define IF_X64_ELSE(x, y) x
260
+ # define IF_X64_(x) x,
261
+ # define _IF_X64(x) , x
262
+ # define IF_NOT_X64(x)
263
+ # define _IF_NOT_X64(x)
264
+ #else
265
+ # define IF_X64(x)
266
+ # define IF_X64_ELSE(x, y) y
267
+ # define IF_X64_(x)
268
+ # define _IF_X64(x)
269
+ # define IF_NOT_X64(x) x
270
+ # define _IF_NOT_X64(x) , x
271
+ #endif
272
+
273
+ #define UINT64_FORMAT_CODE INT64_FORMAT"u"
274
+ #define INT64_FORMAT_CODE INT64_FORMAT"d"
275
+ #define UINT64_FORMAT_STRING "%"UINT64_FORMAT_CODE
276
+ #define INT64_FORMAT_STRING "%"INT64_FORMAT_CODE
277
+ #define HEX64_FORMAT_STRING "%"INT64_FORMAT"x"
278
+ #define ZHEX64_FORMAT_STRING "%016"INT64_FORMAT"x"
279
+ #define ZHEX32_FORMAT_STRING "%08x"
280
+ #define HEX32_FORMAT_STRING "%x"
281
+ /* Convenience defines for cross-platform printing */
282
+ #ifdef X64
283
+ # define PFMT ZHEX64_FORMAT_STRING
284
+ # define PIFMT HEX64_FORMAT_STRING
285
+ # define SZFMT INT64_FORMAT_STRING
286
+ #else
287
+ # define PFMT ZHEX32_FORMAT_STRING
288
+ # define PIFMT HEX32_FORMAT_STRING
289
+ # define SZFMT "%d"
290
+ #endif
291
+
292
+ #define PFX "0x"PFMT
293
+ #define PIFX "0x"PIFMT
294
+
295
+ /** 128-bit XMM register. */
296
+ typedef union _dr_xmm_t {
297
+ uint64 u64[2]; /**< Representation as 2 64-bit integers. */
298
+ uint u32[4]; /**< Representation as 4 32-bit integers. */
299
+ byte u8[16]; /**< Representation as 8 8-bit integers. */
300
+ reg_t reg[IF_X64_ELSE(2,4)]; /**< Representation as 2 or 4 registers. */
301
+ } dr_xmm_t;
302
+
303
+ #ifdef X64
304
+ # ifdef WINDOWS
305
+ # define NUM_XMM_SLOTS 6 /** Number of xmm reg slots in dr_mcontext_t */ /* xmm0-5 */
306
+ # else
307
+ # define NUM_XMM_SLOTS 16 /** Number of xmm reg slots in dr_mcontext_t */ /* xmm0-15 */
308
+ # endif
309
+ #else
310
+ # define NUM_XMM_SLOTS 8 /** Number of xmm reg slots in dr_mcontext_t */ /* xmm0-7 */
311
+ #endif
312
+
313
+ /**
314
+ * Machine context structure.
315
+ */
316
+ typedef struct _dr_mcontext_t {
317
+ union {
318
+ reg_t xdi; /**< platform-independent name for full rdi/edi register */
319
+ reg_t IF_X64_ELSE(rdi, edi); /**< platform-dependent name for rdi/edi register */
320
+ }; /* anonymous union of alternative names for rdi/edi register */
321
+ union {
322
+ reg_t xsi; /**< platform-independent name for full rsi/esi register */
323
+ reg_t IF_X64_ELSE(rsi, esi); /**< platform-dependent name for rsi/esi register */
324
+ }; /* anonymous union of alternative names for rsi/esi register */
325
+ union {
326
+ reg_t xbp; /**< platform-independent name for full rbp/ebp register */
327
+ reg_t IF_X64_ELSE(rbp, ebp); /**< platform-dependent name for rbp/ebp register */
328
+ }; /* anonymous union of alternative names for rbp/ebp register */
329
+ union {
330
+ reg_t xsp; /**< platform-independent name for full rsp/esp register */
331
+ reg_t IF_X64_ELSE(rsp, esp); /**< platform-dependent name for rsp/esp register */
332
+ }; /* anonymous union of alternative names for rsp/esp register */
333
+ union {
334
+ reg_t xbx; /**< platform-independent name for full rbx/ebx register */
335
+ reg_t IF_X64_ELSE(rbx, ebx); /**< platform-dependent name for rbx/ebx register */
336
+ }; /* anonymous union of alternative names for rbx/ebx register */
337
+ union {
338
+ reg_t xdx; /**< platform-independent name for full rdx/edx register */
339
+ reg_t IF_X64_ELSE(rdx, edx); /**< platform-dependent name for rdx/edx register */
340
+ }; /* anonymous union of alternative names for rdx/edx register */
341
+ union {
342
+ reg_t xcx; /**< platform-independent name for full rcx/ecx register */
343
+ reg_t IF_X64_ELSE(rcx, ecx); /**< platform-dependent name for rcx/ecx register */
344
+ }; /* anonymous union of alternative names for rcx/ecx register */
345
+ union {
346
+ reg_t xax; /**< platform-independent name for full rax/eax register */
347
+ reg_t IF_X64_ELSE(rax, eax); /**< platform-dependent name for rax/eax register */
348
+ }; /* anonymous union of alternative names for rax/eax register */
349
+ #ifdef X64
350
+ reg_t r8; /**< r8 register. \note For 64-bit DR builds only. */
351
+ reg_t r9; /**< r9 register. \note For 64-bit DR builds only. */
352
+ reg_t r10; /**< r10 register. \note For 64-bit DR builds only. */
353
+ reg_t r11; /**< r11 register. \note For 64-bit DR builds only. */
354
+ reg_t r12; /**< r12 register. \note For 64-bit DR builds only. */
355
+ reg_t r13; /**< r13 register. \note For 64-bit DR builds only. */
356
+ reg_t r14; /**< r14 register. \note For 64-bit DR builds only. */
357
+ reg_t r15; /**< r15 register. \note For 64-bit DR builds only. */
358
+ #endif
359
+ /**
360
+ * The SSE registers xmm0-xmm5 (-xmm15 on Linux) are volatile
361
+ * (caller-saved) for 64-bit and WOW64, and are actually zeroed out on
362
+ * Windows system calls. These fields are ignored for 32-bit processes
363
+ * that are not WOW64, or if the underlying processor does not support
364
+ * SSE. Use dr_mcontext_xmm_fields_valid() to determine whether the
365
+ * fields are valid.
366
+ */
367
+ dr_xmm_t xmm[NUM_XMM_SLOTS];
368
+ union {
369
+ reg_t xflags; /**< platform-independent name for full rflags/eflags register */
370
+ reg_t IF_X64_ELSE(rflags, eflags); /**< platform-dependent name for
371
+ rflags/eflags register */
372
+ }; /* anonymous union of alternative names for rflags/eflags register */
373
+ /*
374
+ * Anonymous union of alternative names for the program counter /
375
+ * instruction pointer (eip/rip). This field is not always set or
376
+ * read by all API routines.
377
+ */
378
+ union {
379
+ byte *xip; /**< platform-independent name for full rip/eip register */
380
+ byte *pc; /**< platform-independent alt name for full rip/eip register */
381
+ byte *IF_X64_ELSE(rip, eip); /**< platform-dependent name for rip/eip register */
382
+ };
383
+ } dr_mcontext_t;
384
+
385
+
386
+ typedef struct _instr_list_t instrlist_t;
387
+ typedef struct _module_data_t module_data_t;
388
+
389
+
390
+
391
+ #endif /* _DR_DEFINES_H_ */
@@ -0,0 +1,1057 @@
1
+ /* **********************************************************
2
+ * Copyright (c) 2002-2009 VMware, Inc. All rights reserved.
3
+ * **********************************************************/
4
+
5
+ /*
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ *
9
+ * * Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ *
12
+ * * Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ *
16
+ * * Neither the name of VMware, Inc. nor the names of its contributors may be
17
+ * used to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
24
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
30
+ * DAMAGE.
31
+ */
32
+
33
+ #ifndef _DR_EVENTS_H_
34
+ #define _DR_EVENTS_H_ 1
35
+
36
+
37
+ /**************************************************
38
+ * ROUTINES TO REGISTER EVENT CALLBACKS
39
+ */
40
+ /**
41
+ * @file dr_events.h
42
+ * @brief Event callback registration routines.
43
+ */
44
+
45
+
46
+ /**
47
+ * Registers a callback function for the process exit event. DR calls
48
+ * \p func when the process exits.
49
+ *
50
+ * On Linux, SYS_execve does NOT result in an exit event, but it WILL
51
+ * result in the client library being reloaded and its dr_init()
52
+ * routine being called.
53
+ */
54
+ void
55
+ dr_register_exit_event(void (*func)(void));
56
+
57
+ /**
58
+ * Unregister a callback function for the process exit event.
59
+ * \return true if unregistration is successful and false if it is not
60
+ * (e.g., \p func was not registered).
61
+ */
62
+ bool
63
+ dr_unregister_exit_event(void (*func)(void));
64
+ /**
65
+ * Flags controlling the behavior of basic blocks and traces when emitted
66
+ * into the code cache. For multiple clients, the flags returned by each
67
+ * client are or-ed together.
68
+ */
69
+ typedef enum {
70
+ /** Emit as normal. */
71
+ DR_EMIT_DEFAULT = 0,
72
+ /**
73
+ * Store translation information at emit time rather than calling
74
+ * the basic block or trace event later to recreate the
75
+ * information. Note that even if a standalone basic block has
76
+ * stored translations, if when it is added to a trace it does not
77
+ * request storage (and the trace callback also does not request
78
+ * storage) then the basic block callback may still be called to
79
+ * translate for the trace.
80
+ *
81
+ * \sa #dr_register_bb_event()
82
+ */
83
+ DR_EMIT_STORE_TRANSLATIONS = 0x01,
84
+ } dr_emit_flags_t;
85
+
86
+
87
+ /**
88
+ * Registers a callback function for the basic block event. DR calls
89
+ * \p func before inserting a new basic block into the code cache.
90
+ * When adding a basic block to a new trace, DR calls \p func again
91
+ * with \p for_trace set to true, giving the client the opportunity to
92
+ * keep its same instrumentation in the trace, or to change it. The
93
+ * original basic block's instrumentation is unchanged by whatever
94
+ * action is taken in the \p for_trace call.
95
+ *
96
+ * DR may call \p func again if it needs to translate from code cache
97
+ * addresses back to application addresses, which happens on faulting
98
+ * instructions as well as in certain situations involving suspended
99
+ * threads or forcibly relocated threads. The \p translating
100
+ * parameter distinguishes the two types of calls and is further
101
+ * explained below.
102
+ *
103
+ * - \p drcontext is a pointer to the input program's machine context.
104
+ * Clients should not inspect or modify the context; it is provided as
105
+ * an opaque pointer (i.e., <tt>void *</tt>) to be passed to API
106
+ * routines that require access to this internal data.
107
+ * drcontext is specific to the current thread, but in normal
108
+ * configurations the basic block being created is thread-shared: thus,
109
+ * when allocating data structures with the same lifetime as the
110
+ * basic block, usually global heap (#dr_global_alloc()) is a better
111
+ * choice than heap tied to the thread that happened to first create
112
+ * the basic block (#dr_thread_alloc()). Thread-private heap is fine
113
+ * for temporary structures such as instr_t and instrlist_t.
114
+ *
115
+ * - \p tag is a unique identifier for the basic block fragment.
116
+ * - \p bb is a pointer to the list of instructions that comprise the
117
+ * basic block. Clients can examine, manipulate, or completely
118
+ * replace the instructions in the list.
119
+ *
120
+ * - \p translating indicates whether this callback is for basic block
121
+ * creation (false) or is for address translation (true). This is
122
+ * further explained below.
123
+ *
124
+ * \return a #dr_emit_flags_t flag.
125
+ *
126
+ * The user is free to inspect and modify the block before it
127
+ * executes, but must adhere to the following restrictions:
128
+ * - If there is more than one non-meta branch, only the last can be
129
+ * conditional.
130
+ * - A non-meta conditional branch or direct call must be the final
131
+ * instruction in the block.
132
+ * - There can only be one indirect branch (call, jump, or return) in
133
+ * a basic block, and it must be the final instruction in the
134
+ * block.
135
+ * - The exit control-flow of a block ending in a system call or
136
+ * int instruction cannot be changed, nor can instructions be inserted
137
+ * after the system call or int instruction itself, unless
138
+ * the system call or int instruction is removed entirely.
139
+ * - The number of an interrupt cannot be changed. (Note that the
140
+ * parameter to a system call, normally kept in the eax register, can
141
+ * be freely changed in a basic block: but not in a trace.)
142
+ * - A system call or interrupt instruction can only be added
143
+ * if it satisfies the above constraints: i.e., if it is the final
144
+ * instruction in the block and the only system call or interrupt.
145
+ * - The block's application source code (as indicated by the
146
+ * translation targets, set by #instr_set_translation()) must remain
147
+ * within the original bounds of the block (the one exception to this
148
+ * is that a jump can translate to its target). Otherwise, DR's cache
149
+ * consistency algorithms cannot guarantee to properly invalidate the
150
+ * block if the source application code is modified. To send control
151
+ * to other application code regions, truncate the block and use a
152
+ * direct jump to target the desired address, which will then
153
+ * materialize in the subsequent block, rather than embedding the
154
+ * desired instructions in this block.
155
+ * - There is a limit on the size of a basic block in the code cache.
156
+ * DR performs its own modifications, especially on memory writes for
157
+ * cache consistency of self-modifying (or false sharing) code
158
+ * regions. If an assert fires in debug build indicating a limit was
159
+ * reached, either truncate blocks or use the -max_bb_instrs runtime
160
+ * option to ask DR to make them smaller.
161
+ *
162
+ * To support transparent fault handling, DR must translate a fault in the
163
+ * code cache into a fault at the corresponding application address. DR
164
+ * must also be able to translate when a suspended thread is examined by
165
+ * the application or by DR itself for internal synchronization purposes.
166
+ * If the client is only adding observational instrumentation (i.e., meta
167
+ * instructions: see #instr_set_ok_to_mangle()) (which should not fault) and
168
+ * is not modifying, reordering, or removing application instructions,
169
+ * these details can be ignored. In that case the client should return
170
+ * #DR_EMIT_DEFAULT and set up its basic block callback to be deterministic
171
+ * and idempotent. If the client is performing modifications, then in
172
+ * order for DR to properly translate a code cache address the client must
173
+ * use #instr_set_translation() in the basic block creation callback to set
174
+ * the corresponding application address (the address that should be
175
+ * presented to the application as the faulting address, or the address
176
+ * that should be restarted after a suspend) for each modified instruction
177
+ * and each added non-meta instruction (see #instr_set_ok_to_mangle()).
178
+ *
179
+ * There are two methods for using the translated addresses:
180
+ *
181
+ * -# Return #DR_EMIT_STORE_TRANSLATIONS from the basic block creation
182
+ * callback. DR will then store the translation addresses and use
183
+ * the stored information on a fault. The basic block callback for
184
+ * \p tag will not be called with \p translating set to true. Note
185
+ * that unless #DR_EMIT_STORE_TRANSLATIONS is also returned for \p
186
+ * for_trace calls (or #DR_EMIT_STORE_TRANSLATIONS is returned in
187
+ * the trace callback), each constituent block comprising the trace
188
+ * will need to be re-created with both \p for_trace and \p
189
+ * translating set to true. Storing translations uses additional
190
+ * memory that can be significant: up to 20% in some cases, as it
191
+ * prevents DR from using its simple data structures and forces it
192
+ * to fall back to its complex, corner-case design. This is why DR
193
+ * does not store all translations by default.
194
+ * -# Return #DR_EMIT_DEFAULT from the basic block creation callback.
195
+ * DR will then call the callback again during fault translation
196
+ * with \p translating set to true. All modifications to \p bb
197
+ * that were performed on the creation callback must be repeated on
198
+ * the translating callback. This option is only posible when
199
+ * basic block modifications are deterministic and idempotent, but
200
+ * it saves memory. Naturally, global state changes triggered by
201
+ * block creation should be wrapped in checks for \p translating
202
+ * being false. Even in this case, #instr_set_translation() should
203
+ * be called for non-meta instructions even when \p translating is
204
+ * false, as DR may decide to store the translations at creation
205
+ * time for reasons of its own.
206
+ *
207
+ * Furthermore, if the client's modifications change any part of the
208
+ * machine state besides the program counter, the client should use
209
+ * #dr_register_restore_state_event() or
210
+ * #dr_register_restore_state_ex_event() to restore the registers and
211
+ * application memory to their original application values.
212
+ *
213
+ * For meta instructions that do not reference application memory
214
+ * (i.e., they should not fault), leave the translation field as NULL.
215
+ * A NULL value instructs DR to use the subsequent non-meta
216
+ * instruction's translation as the application address, and to fail
217
+ * when translating the full state. Since the full state will only be
218
+ * needed when relocating a thread (as stated, there will not be a
219
+ * fault here), failure indicates that this is not a valid relocation
220
+ * point, and DR's thread synchronization scheme will use another
221
+ * spot. If the translation field is set to a non-NULL value, the
222
+ * client should be willing to also restore the rest of the machine
223
+ * state at that point (restore spilled registers, etc.) via
224
+ * #dr_register_restore_state_event() or
225
+ * #dr_register_restore_state_ex_event(). This is necessary for meta
226
+ * instructions that reference application memory. DR takes care of
227
+ * such potentially-faulting instructions added by its own API
228
+ * routines (#dr_insert_clean_call() arguments that reference
229
+ * application data, #dr_insert_mbr_instrumentation()'s read of
230
+ * application indirect branch data, etc.)
231
+ *
232
+ * \note In order to present a more straightforward code stream to clients,
233
+ * this release of DR disables several internal optimizations. As a result,
234
+ * some applications may see a performance degradation. Applications making
235
+ * heavy use of system calls are the most likely to be affected.
236
+ * Future releases may allow clients some control over performance versus
237
+ * visibility.
238
+ *
239
+ * \note If multiple clients are present, the instruction list for a
240
+ * basic block passed to earlier-registered clients will contain the
241
+ * instrumentation and modifications put in place by later-registered
242
+ * clients.
243
+ *
244
+ * \note Basic blocks can be deleted due to hitting capacity limits or
245
+ * cache consistency events (when the source application code of a
246
+ * basic block is modified). In that case, the client will see a new
247
+ * basic block callback if the block is then executed again after
248
+ * deletion. The deletion event (#dr_register_delete_event()) will be
249
+ * raised at deletion time.
250
+ *
251
+ * \note If the -thread_private runtime option is specified, clients
252
+ * should expect to see duplicate tags for separate threads, albeit
253
+ * with different dcrcontext values. Additionally, DR employs a
254
+ * cache-sizing algorithm for thread private operation that
255
+ * proactively deletes fragments. Even with thread-shared caches
256
+ * enabled, however, certain situations cause DR to emit
257
+ * thread-private basic blocks (e.g., self-modifying code). In this
258
+ * case, clients should be prepared to see duplicate tags without an
259
+ * intermediate deletion.
260
+ */
261
+ void
262
+ dr_register_bb_event(dr_emit_flags_t (*func)
263
+ (void *drcontext, void *tag, instrlist_t *bb,
264
+ bool for_trace, bool translating));
265
+
266
+ /**
267
+ * Unregister a callback function for the basic block event.
268
+ * \return true if unregistration is successful and false if it is not
269
+ * (e.g., \p func was not registered).
270
+ *
271
+ * \note We do not recommend unregistering for the basic block event
272
+ * unless it aways returned #DR_EMIT_STORE_TRANSLATIONS (including
273
+ * when \p for_trace is true, or if the client has a trace creation
274
+ * callback that returns #DR_EMIT_STORE_TRANSLATIONS). Unregistering
275
+ * can prevent proper state translation on a later fault or other
276
+ * translation event for this basic block or for a trace that includes
277
+ * this basic block. Instead of unregistering, turn the event
278
+ * callback into a nop.
279
+ */
280
+ bool
281
+ dr_unregister_bb_event(dr_emit_flags_t (*func)
282
+ (void *drcontext, void *tag, instrlist_t *bb,
283
+ bool for_trace, bool translating));
284
+
285
+ /**
286
+ * Registers a callback function for the trace event. DR calls \p func
287
+ * before inserting a new trace into the code cache. DR may call \p func
288
+ * again if it needs to translate from code cache addresses back to
289
+ * application addresses, which happens on faulting instructions as well as
290
+ * in certain situations involving suspended threads or forcibly relocated
291
+ * threads. The \p translating parameter distinguishes the two types of
292
+ * calls and behaves identically to the same parameter in the basic
293
+ * block callback: see #dr_register_bb_event() for further details.
294
+ *
295
+ * Traces are not built if the -disable_traces runtime option
296
+ * is specified.
297
+ *
298
+ * - \p drcontext is a pointer to the input program's machine context.
299
+ * Clients should not inspect or modify the context; it is provided as
300
+ * an opaque pointer (i.e., <tt>void *</tt>) to be passed to API
301
+ * routines that require access to this internal data.
302
+ * - \p tag is a unique identifier for the trace fragment.
303
+ * - \p trace is a pointer to the list of instructions that comprise the
304
+ * trace.
305
+ * - \p translating indicates whether this callback is for trace creation
306
+ * (false) or is for fault address recreation (true). This is further
307
+ * explained below.
308
+ *
309
+ * \return a #dr_emit_flags_t flag.
310
+ *
311
+ * The user is free to inspect and modify the trace before it
312
+ * executes, with certain restrictions on introducing control-flow
313
+ * that include those for basic blocks (see dr_register_bb_event()).
314
+ * Additional restrictions unique to traces also apply:
315
+ * - Only one non-meta direct branch that targets the subsequent block
316
+ * in the trace can be present in each block.
317
+ * - Each block must end with a non-meta control transfer.
318
+ * - The parameter to a system call, normally kept in the eax register,
319
+ * cannot be changed.
320
+ * - A system call or interrupt instruction cannot be added.
321
+ *
322
+ * If hitting a size limit due to extensive instrumentation, reduce
323
+ * the -max_trace_bbs option to start with a smaller trace.
324
+ *
325
+ * The basic block restrictions on modifying application source code
326
+ * apply to traces as well. If the user wishes to change which basic
327
+ * blocks comprise the trace, either the
328
+ * #dr_register_end_trace_event() should be used or the \p for_trace
329
+ * basic block callbacks should modify their continuation addresses
330
+ * via direct jumps.
331
+ *
332
+ * All of the comments for #dr_register_bb_event() regarding
333
+ * transparent fault handling and state translation apply to the trace
334
+ * callback as well. Please read those comments carefully.
335
+ *
336
+ * \note As each basic block is added to a new trace, the basic block
337
+ * callback (see #dr_register_bb_event()) is called with its \p
338
+ * for_trace parameter set to true. In order to preserve basic block
339
+ * instrumentation inside of traces, a client need only act
340
+ * identically with respect to the \p for_trace parameter; it can
341
+ * ignore the trace event if its goal is to place instrumentation
342
+ * on all code.
343
+ *
344
+ * \note Certain control flow modifications applied to a basic block
345
+ * can prevent it from becoming part of a trace: e.g., adding
346
+ * additional non-meta control transfers.
347
+ *
348
+ * \note If multiple clients are present, the instruction list for a
349
+ * trace passed to earlier-registered clients will contain the
350
+ * instrumentation and modifications put in place by later-registered
351
+ * clients; similarly for each constituent basic block.
352
+ *
353
+ * \note Traces can be deleted due to hitting capacity limits or cache
354
+ * consistency events (when the source application code of a trace is
355
+ * modified). In that case, the client will see a new trace callback
356
+ * if a new trace containing that code is created again after
357
+ * deletion. The deletion event (#dr_register_delete_event()) will be
358
+ * raised at deletion time.
359
+ */
360
+ void
361
+ dr_register_trace_event(dr_emit_flags_t (*func)
362
+ (void *drcontext, void *tag, instrlist_t *trace,
363
+ bool translating));
364
+
365
+ /**
366
+ * Unregister a callback function for the trace event.
367
+ * \return true if unregistration is successful and false if it is not
368
+ * (e.g., \p func was not registered).
369
+ *
370
+ * \note We do not recommend unregistering for the trace event unless it
371
+ * always returned #DR_EMIT_STORE_TRANSLATIONS, as doing so can prevent
372
+ * proper state translation on a later fault or other translation event.
373
+ * Instead of unregistering, turn the event callback into a nop.
374
+ */
375
+ bool
376
+ dr_unregister_trace_event(dr_emit_flags_t (*func)
377
+ (void *drcontext, void *tag, instrlist_t *trace,
378
+ bool translating));
379
+
380
+ /**
381
+ * DR will call the end trace event if it is registered prior to
382
+ * adding each basic block to a trace being generated. The return
383
+ * value of the event callback should be from the
384
+ * dr_custom_trace_action_t enum.
385
+ *
386
+ * \note DR treats CUSTOM_TRACE_CONTINUE as an advisement only. Certain
387
+ * fragments are not suitable to be included in a trace and if DR runs
388
+ * into one it will end the trace regardless of what the client returns
389
+ * through the event callback.
390
+ */
391
+ typedef enum {
392
+ CUSTOM_TRACE_DR_DECIDES,
393
+ CUSTOM_TRACE_END_NOW,
394
+ CUSTOM_TRACE_CONTINUE
395
+ } dr_custom_trace_action_t;
396
+
397
+
398
+
399
+ /**
400
+ * Registers a callback function for the end-trace event. DR calls \p
401
+ * func before extending a trace with a new basic block. The \p func
402
+ * should return one of the #dr_custom_trace_action_t enum values.
403
+ */
404
+ void
405
+ dr_register_end_trace_event(dr_custom_trace_action_t (*func)
406
+ (void *drcontext, void *tag, void *next_tag));
407
+
408
+ /**
409
+ * Unregister a callback function for the end-trace event.
410
+ * \return true if unregistration is successful and false if it is not
411
+ * (e.g., \p func was not registered).
412
+ */
413
+ bool
414
+ dr_unregister_end_trace_event(dr_custom_trace_action_t (*func)
415
+ (void *drcontext, void *tag, void *next_tag));
416
+
417
+ /**
418
+ * Registers a callback function for the fragment deletion event. DR
419
+ * calls \p func whenever it removes a fragment from the code cache.
420
+ * Due to DR's high-performance non-precise flushing, a fragment
421
+ * can be made inaccessible but not actually freed for some time.
422
+ * A new fragment can thus be created before the deletion event
423
+ * for the old fragment is raised. We recommended using a counter
424
+ * to ignore subsequent deletion events when using per-fragment
425
+ * data structures and duplicate fragments are seen.
426
+ *
427
+ * \note drcontext may be NULL when thread-shared fragments are being
428
+ * deleted during process exit. For this reason, thread-private
429
+ * heap should not be used for data structures intended to be freed
430
+ * at thread-shared fragment deletion.
431
+ */
432
+ void
433
+ dr_register_delete_event(void (*func)(void *drcontext, void *tag));
434
+
435
+ /**
436
+ * Unregister a callback function for the fragment deletion event.
437
+ * \return true if unregistration is successful and false if it is not
438
+ * (e.g., \p func was not registered).
439
+ */
440
+ bool
441
+ dr_unregister_delete_event(void (*func)(void *drcontext, void *tag));
442
+
443
+ /**
444
+ * Registers a callback function for the machine state restoration event.
445
+ * DR calls \p func whenever it needs to translate a code cache machine
446
+ * context from the code cache to its corresponding original application
447
+ * context. DR needs to translate when instructions fault in the cache as
448
+ * well as when a suspended thread is examined or relocated for internal
449
+ * purposes.
450
+ *
451
+ * If a client is only adding instrumentation (meta-code: see
452
+ * #instr_ok_to_mangle()) that does not reference application memory,
453
+ * and is not reordering or removing application instructions, then it
454
+ * need not register for this event. If, however, a client is
455
+ * modifying application code or is adding code that can fault, the
456
+ * client must be capable of restoring the original context.
457
+ *
458
+ * When DR needs to translate a code cache context, DR recreates the
459
+ * faulting instruction's containing fragment, storing translation
460
+ * information along the way, by calling the basic block and/or trace event
461
+ * callbacks with the \p translating parameter set to true. DR uses the
462
+ * recreated code to identify the application instruction (\p mcontext.pc)
463
+ * corresponding to the faulting code cache instruction. If the client
464
+ * asked to store translation information by returning
465
+ * #DR_EMIT_STORE_TRANSLATIONS from the basic block or trace event
466
+ * callback, then this step of re-calling the event callback is skipped and
467
+ * the stored value is used as the application address (\p mcontext.pc).
468
+ *
469
+ * DR then calls the fault state restoration event to allow the client
470
+ * to restore the registers and application memory to their proper
471
+ * values as they would have appeared if the original application code
472
+ * had been executed up to the \p mcontext.pc instruction. Memory
473
+ * should only be restored if the \p restore_memory parameter is true;
474
+ * if it is false, DR may only be querying for the address (\p
475
+ * mcontext.pc) or register state and may not relocate this thread.
476
+ *
477
+ * The \p app_code_consistent parameter indicates whether the original
478
+ * application code containing the instruction being translated is
479
+ * guaranteed to still be in the same state it was when the code was
480
+ * placed in the code cache. This guarantee varies depending on the
481
+ * type of cache consistency being used by DR.
482
+ *
483
+ * The client can update \p mcontext.pc in this callback.
484
+ *
485
+ * \note The passed-in \p drcontext may correspond to a different thread
486
+ * than the thread executing the callback. Do not assume that the
487
+ * executing thread is the target thread.
488
+ */
489
+ void
490
+ dr_register_restore_state_event(void (*func)
491
+ (void *drcontext, void *tag, dr_mcontext_t *mcontext,
492
+ bool restore_memory, bool app_code_consistent));
493
+
494
+ /**
495
+ * Unregister a callback function for the machine state restoration event.
496
+ * \return true if unregistration is successful and false if it is not
497
+ * (e.g., \p func was not registered).
498
+ */
499
+ bool
500
+ dr_unregister_restore_state_event(void (*func)
501
+ (void *drcontext, void *tag, dr_mcontext_t *mcontext,
502
+ bool restore_memory, bool app_code_consistent));
503
+ /**
504
+ * Data structure passed within dr_exception_t, dr_siginfo_t, and
505
+ * dr_restore_state_info_t.
506
+ * Contains information about the code fragment inside the code cache
507
+ * at the exception/signal/translation interruption point.
508
+ */
509
+ typedef struct _dr_fault_fragment_info_t {
510
+ /**
511
+ * The tag of the code fragment inside the code cache at the
512
+ * exception/signal/translation interruption point. NULL for
513
+ * interruption not in the code cache.
514
+ */
515
+ void *tag;
516
+ /**
517
+ * The start address of the code fragment inside the code cache at
518
+ * the exception/signal/translation interruption point. NULL for interruption
519
+ * not in the code cache. Clients are cautioned when examining
520
+ * code cache instructions to not rely on any details of code
521
+ * inserted other than their own.
522
+ */
523
+ byte *cache_start_pc;
524
+ /** Indicates whether the interrupted code fragment is a trace */
525
+ bool is_trace;
526
+ /**
527
+ * Indicates whether the original application code containing the
528
+ * code corresponding to the exception/signal/translation interruption point
529
+ * is guaranteed to still be in the same state it was when the
530
+ * code was placed in the code cache. This guarantee varies
531
+ * depending on the type of cache consistency being used by DR.
532
+ */
533
+ bool app_code_consistent;
534
+ } dr_fault_fragment_info_t;
535
+
536
+ /**
537
+ * Data structure passed to a restore_state_ex event handler (see
538
+ * dr_register_restore_state_ex_event()). Contains the machine
539
+ * context at the translation point and other translation
540
+ * information.
541
+ */
542
+ typedef struct _dr_restore_state_info_t {
543
+ /** The application machine state at the translation point. */
544
+ dr_mcontext_t *mcontext;
545
+ /** Whether raw_mcontext is valid. */
546
+ bool raw_mcontext_valid;
547
+ /**
548
+ * The raw pre-translated machine state at the translation
549
+ * interruption point inside the code cache. Clients are
550
+ * cautioned when examining code cache instructions to not rely on
551
+ * any details of code inserted other than their own.
552
+ */
553
+ dr_mcontext_t raw_mcontext;
554
+ /**
555
+ * Information about the code fragment inside the code cache
556
+ * at the translation interruption point.
557
+ */
558
+ dr_fault_fragment_info_t fragment_info;
559
+ } dr_restore_state_info_t;
560
+
561
+
562
+ /**
563
+ * Registers a callback function for the machine state restoration
564
+ * event with extended information.
565
+ *
566
+ * This event is identical to that for dr_register_restore_state_event()
567
+ * with the following exceptions:
568
+ *
569
+ * - Additional information is provided in the
570
+ * dr_restore_state_info_t structure, including the pre-translation
571
+ * context (containing the address inside the code cache of the
572
+ * translation point) and the starting address of the containing
573
+ * fragment in the code cache. Certain registers may not contain
574
+ * proper application values in \p info->raw_mcontext. Clients are
575
+ * cautioned against relying on any details of code cache layout or
576
+ * register usage beyond instrumentation inserted by the client
577
+ * itself when examining \p info->raw_mcontext.
578
+ *
579
+ * - The callback function returns a boolean indicating the success of
580
+ * the translation. When DR is translating not for a fault but for
581
+ * thread relocation, the \p restore_memory parameter will be false.
582
+ * Such translation can target a meta-instruction that can fault
583
+ * (see instr_set_meta_may_fault()). For that scenario, a client
584
+ * can choose not to translate. Such instructions do not always
585
+ * require full translation for faults, and allowing translation
586
+ * failure removes the requirement that a client must translate at
587
+ * all such instructions. Note, however, that returning false can
588
+ * cause performance degradation as DR must then resume the thread
589
+ * and attempt to re-suspend it at a safer spot. Clients must
590
+ * return true for translation points in application code in order
591
+ * to avoid catastropic failure to suspend, and should thus identify
592
+ * whether translation points are inside their own instrumentation
593
+ * before returning false. Translation for relocation will never
594
+ * occur in meta instructions, so clients only need to look for
595
+ * meta-may-fault instructions. Clients should never return false
596
+ * when \p restore_memory is true.
597
+ */
598
+ void
599
+ dr_register_restore_state_ex_event(bool (*func) (void *drcontext, bool restore_memory,
600
+ dr_restore_state_info_t *info));
601
+
602
+ /**
603
+ * Unregister a callback function for the machine state restoration
604
+ * event with extended ifnormation. \return true if unregistration is
605
+ * successful and false if it is not (e.g., \p func was not
606
+ * registered).
607
+ */
608
+ bool
609
+ dr_unregister_restore_state_ex_event(bool (*func) (void *drcontext, bool restore_memory,
610
+ dr_restore_state_info_t *info));
611
+
612
+ /**
613
+ * Registers a callback function for the thread initialization event.
614
+ * DR calls \p func whenever the application creates a new thread.
615
+ */
616
+ void
617
+ dr_register_thread_init_event(void (*func)(void *drcontext));
618
+
619
+ /**
620
+ * Unregister a callback function for the thread initialization event.
621
+ * \return true if unregistration is successful and false if it is not
622
+ * (e.g., \p func was not registered).
623
+ */
624
+ bool
625
+ dr_unregister_thread_init_event(void (*func)(void *drcontext));
626
+
627
+ /**
628
+ * Registers a callback function for the thread exit event. DR calls
629
+ * \p func whenever an application thread exits.
630
+ */
631
+ void
632
+ dr_register_thread_exit_event(void (*func)(void *drcontext));
633
+
634
+ /**
635
+ * Unregister a callback function for the thread exit event.
636
+ * \return true if unregistration is successful and false if it is not
637
+ * (e.g., \p func was not registered).
638
+ */
639
+ bool
640
+ dr_unregister_thread_exit_event(void (*func)(void *drcontext));
641
+
642
+ /**
643
+ * Registers a callback function for the fork event. DR calls \p func
644
+ * whenever the application forks a new process.
645
+ * \note Valid on Linux only.
646
+ */
647
+ void
648
+ dr_register_fork_init_event(void (*func)(void *drcontext));
649
+
650
+ /**
651
+ * Unregister a callback function for the fork event.
652
+ * \return true if unregistration is successful and false if it is not
653
+ * (e.g., \p func was not registered).
654
+ */
655
+ bool
656
+ dr_unregister_fork_init_event(void (*func)(void *drcontext));
657
+
658
+ /**
659
+ * Registers a callback function for the module load event. DR calls
660
+ * \p func whenever the application loads a module. The \p loaded
661
+ * parameter indicates whether the module is about to be loaded (the
662
+ * normal case) or is already loaded (if the module was already there
663
+ * at the time DR initialized). \note The client should be aware that
664
+ * if the module is being loaded it may not be fully processed by the
665
+ * loader (relocating, rebinding and on Linux segment remapping may
666
+ * have not yet occured). \note The module_data_t \p *info passed
667
+ * to the callback routine is valid only for the duration of the
668
+ * callback and should not be freed; a persistent copy can be made with
669
+ * dr_copy_module_data().
670
+ */
671
+ void
672
+ dr_register_module_load_event(void (*func)(void *drcontext, const module_data_t *info,
673
+ bool loaded));
674
+
675
+ /**
676
+ * Unregister a callback for the module load event.
677
+ * \return true if unregistration is successful and false if it is not
678
+ * (e.g., \p func was not registered).
679
+ */
680
+ bool
681
+ dr_unregister_module_load_event(void (*func)(void *drcontext, const module_data_t *info,
682
+ bool loaded));
683
+
684
+ /**
685
+ * Registers a callback function for the module unload event. DR
686
+ * calls \p func whenever the application unloads a module.
687
+ * \note The module_data_t \p *info passed to
688
+ * the callback routine is valid only for the duration of the callback
689
+ * and should not be freed; a persistent copy can be made with
690
+ * dr_copy_module_data().
691
+ */
692
+ void
693
+ dr_register_module_unload_event(void (*func)(void *drcontext,
694
+ const module_data_t *info));
695
+
696
+ /**
697
+ * Unregister a callback function for the module unload event.
698
+ * \return true if unregistration is successful and false if it is not
699
+ * (e.g., \p func was not registered).
700
+ */
701
+ bool
702
+ dr_unregister_module_unload_event(void (*func)(void *drcontext,
703
+ const module_data_t *info));
704
+ #ifdef WINDOWS
705
+
706
+ /**
707
+ * Data structure passed with an exception event. Contains the
708
+ * machine context and the Win32 exception record.
709
+ */
710
+ typedef struct _dr_exception_t {
711
+ dr_mcontext_t mcontext; /**< Machine context at exception point. */
712
+ EXCEPTION_RECORD *record; /**< Win32 exception record. */
713
+ /**
714
+ * The raw pre-translated machine state at the exception interruption
715
+ * point inside the code cache. Clients are cautioned when examining
716
+ * code cache instructions to not rely on any details of code inserted
717
+ * other than their own.
718
+ */
719
+ ALIGN_VAR(8)/*avoid differences in padding*/
720
+ dr_mcontext_t raw_mcontext;
721
+ /**
722
+ * Information about the code fragment inside the code cache at
723
+ * the exception interruption point.
724
+ */
725
+ dr_fault_fragment_info_t fault_fragment_info;
726
+ } dr_exception_t;
727
+
728
+
729
+ /**
730
+ * Registers a callback function for the exception event. DR calls \p func
731
+ * whenever the application throws an exception. If \p func returns true,
732
+ * the exception is delivered to the application's handler along with any
733
+ * changes made to \p excpt->mcontext. If \p func returns false, the
734
+ * faulting instruction in the code cache is re-executed using \p
735
+ * excpt->raw_mcontext, including any changes made to that structure.
736
+ * Clients are expected to use \p excpt->raw_mcontext when using faults as
737
+ * a mechanism to push rare cases out of an instrumentation fastpath that
738
+ * need to examine instrumentation instructions rather than the translated
739
+ * application state and should normally not examine it for application
740
+ * instruction faults. Certain registers may not contain proper
741
+ * application values in \p excpt->raw_mcontext for exceptions in
742
+ * application instructions. Clients are cautioned against relying on any
743
+ * details of code cache layout or register usage beyond instrumentation
744
+ * inserted by the client itself when examining \p excpt->raw_mcontext.
745
+ *
746
+ * DR raises this event for exceptions outside the code cache that
747
+ * could come from code generated by a client. For such exceptions,
748
+ * mcontext is not translated and is identical to raw_mcontext.
749
+ *
750
+ * To skip the passing of the exception to the application's exception
751
+ * handlers and to send control elsewhere instead, a client can call
752
+ * dr_redirect_execution() from \p func.
753
+ *
754
+ * \note \p excpt->fault_fragment_info data is provided with
755
+ * \p excpt->raw_mcontext. It is valid only if
756
+ * \p excpt->fault_fragment_info.cache_start_pc is not \p NULL.
757
+ * It provides clients information about the code fragment being
758
+ * executed at the exception interruption point. Clients are cautioned
759
+ * against relying on any details of code cache layout or register
760
+ * usage beyond instrumentation inserted by the client itself.
761
+ * \note Only valid on Windows.
762
+ * \note The function is not called for RaiseException.
763
+ */
764
+ void
765
+ dr_register_exception_event(bool (*func)(void *drcontext, dr_exception_t *excpt));
766
+
767
+ /**
768
+ * Unregister a callback function for the exception event.
769
+ * \return true if unregistration is successful and false if it is not
770
+ * (e.g., \p func was not registered).
771
+ */
772
+ bool
773
+ dr_unregister_exception_event(bool (*func)(void *drcontext, dr_exception_t *excpt));
774
+ #endif /* WINDOWS */
775
+
776
+
777
+ /**
778
+ * Registers a callback function for the syscall filter event. DR
779
+ * calls \p func to decide whether to invoke the syscall events for
780
+ * each system call site encountered with a statically-determinable
781
+ * system call number. If \p func returns true, the pre-syscall
782
+ * (dr_register_pre_syscall_event()) and post-syscall
783
+ * (dr_register_post_syscall_event()) events will be invoked.
784
+ * Otherwise, the events may or may not occur, depending on whether DR
785
+ * itself needs to intercept them and whether the system call number
786
+ * is statically determinable. System call number determination can
787
+ * depend on whether the -opt_speed option is enabled. If a system
788
+ * call number is not determinable, the filter event will not be
789
+ * called, but the pre and post events will be called.
790
+ *
791
+ * Intercepting every system call can be detrimental to performance
792
+ * for certain types of applications. Filtering provides for greater
793
+ * performance by letting uninteresting system calls execute without
794
+ * interception overhead.
795
+ */
796
+ void
797
+ dr_register_filter_syscall_event(bool (*func)(void *drcontext, int sysnum));
798
+
799
+ /**
800
+ * Unregister a callback function for the syscall filter event.
801
+ * \return true if unregistration is successful and false if it is not
802
+ * (e.g., \p func was not registered).
803
+ */
804
+ bool
805
+ dr_unregister_filter_syscall_event(bool (*func)(void *drcontext, int sysnum));
806
+
807
+ /**
808
+ * Registers a callback function for the pre-syscall event. DR calls
809
+ * \p func whenever the application is about to invoke a system call,
810
+ * if any client asked for that system call number to be intercepted
811
+ * via the filter event (dr_register_filter_syscall_event()).
812
+ *
813
+ * The application parameters to the system call can be viewed with
814
+ * dr_syscall_get_param() and set with dr_syscall_set_param(). The
815
+ * system call number can also be changed with
816
+ * dr_syscall_set_sysnum().
817
+ *
818
+ * The application's machine state can be accessed and set with
819
+ * dr_get_mcontext() and dr_set_mcontext(). Changing registers in
820
+ * this way overlaps with system call parameter changes on some
821
+ * platforms. On Linux, for SYS_clone, client changes to the ebp/rbp
822
+ * register will be ignored by the clone child.
823
+ *
824
+ * If \p func returns true, the application's system call is invoked
825
+ * normally; if \p func returns false, the system call is skipped. If
826
+ * it is skipped, the return value can be set with
827
+ * dr_syscall_set_result(). If the system call is skipped, there will
828
+ * not be a post-syscall event.
829
+ */
830
+ void
831
+ dr_register_pre_syscall_event(bool (*func)(void *drcontext, int sysnum));
832
+
833
+ /**
834
+ * Unregister a callback function for the pre-syscall event.
835
+ * \return true if unregistration is successful and false if it is not
836
+ * (e.g., \p func was not registered).
837
+ */
838
+ bool
839
+ dr_unregister_pre_syscall_event(bool (*func)(void *drcontext, int sysnum));
840
+
841
+ /**
842
+ * Registers a callback function for the post-syscall event. DR calls
843
+ * \p func whenever the application just finished invoking a system
844
+ * call, if any client asked for that system call number to be
845
+ * intercepted via the filter event
846
+ * (dr_register_filter_syscall_event()) or if DR itself needs to
847
+ * intercept the system call. The result of the system call can be
848
+ * modified with dr_syscall_set_result().
849
+ *
850
+ * System calls that change control flow or terminate the current
851
+ * thread or process typically do not have a post-syscall event.
852
+ * These include SYS_exit, SYS_exit_group, SYS_execve, SYS_sigreturn,
853
+ * and SYS_rt_sigreturn on Linux, and NtTerminateThread,
854
+ * NtTerminateProcess (depending on the parameters), NtCallbackReturn,
855
+ * and NtContinue on Windows.
856
+ *
857
+ * The application's machine state can be accessed and set with
858
+ * dr_get_mcontext() and dr_set_mcontext().
859
+ *
860
+ * Additional system calls may be invoked by calling
861
+ * dr_syscall_invoke_another() prior to returning from the
862
+ * post-syscall event callback. The system call to be invoked should
863
+ * be specified with dr_syscall_set_sysnum(), and its parameters can
864
+ * be set with dr_syscall_set_param().
865
+ */
866
+ void
867
+ dr_register_post_syscall_event(void (*func)(void *drcontext, int sysnum));
868
+
869
+ /**
870
+ * Unregister a callback function for the post-syscall event.
871
+ * \return true if unregistration is successful and false if it is not
872
+ * (e.g., \p func was not registered).
873
+ */
874
+ bool
875
+ dr_unregister_post_syscall_event(void (*func)(void *drcontext, int sysnum));
876
+
877
+ #ifdef LINUX
878
+
879
+ /**
880
+ * Data structure passed with a signal event. Contains the machine
881
+ * context at the signal interruption point and other signal
882
+ * information.
883
+ */
884
+ typedef struct _dr_siginfo_t {
885
+ /** The signal number. */
886
+ int sig;
887
+ /** The context of the thread receiving the signal. */
888
+ void *drcontext;
889
+ /** The application machine state at the signal interruption point. */
890
+ dr_mcontext_t mcontext;
891
+ /**
892
+ * The raw pre-translated machine state at the signal interruption
893
+ * point inside the code cache. NULL for delayable signals. Clients
894
+ * are cautioned when examining code cache instructions to not rely on
895
+ * any details of code inserted other than their own.
896
+ */
897
+ dr_mcontext_t raw_mcontext;
898
+ /** Whether raw_mcontext is valid. */
899
+ bool raw_mcontext_valid;
900
+ /**
901
+ * For SIGBUS and SIGSEGV, the address whose access caused the signal
902
+ * to be raised (as calculated by DR).
903
+ */
904
+ byte *access_address;
905
+ /**
906
+ * Indicates this signal is blocked. DR_SIGNAL_BYPASS is not allowed,
907
+ * and a second event will be sent if the signal is later delivered to
908
+ * the application. Events are only sent for blocked non-delayable signals,
909
+ * not for delayable signals.
910
+ */
911
+ bool blocked;
912
+ /**
913
+ * Information about the code fragment inside the code cache
914
+ * at the signal interruption point.
915
+ */
916
+ dr_fault_fragment_info_t fault_fragment_info;
917
+ } dr_siginfo_t;
918
+
919
+ /**
920
+ * Return value of client signal event callback, determining how DR will
921
+ * proceed with the signal.
922
+ */
923
+ typedef enum {
924
+ /** Deliver signal to the application as normal. */
925
+ DR_SIGNAL_DELIVER,
926
+ /** Suppress signal as though it never happened. */
927
+ DR_SIGNAL_SUPPRESS,
928
+ /**
929
+ * Deliver signal according to the default SIG_DFL action, as would
930
+ * happen if the application had no handler.
931
+ */
932
+ DR_SIGNAL_BYPASS,
933
+ /**
934
+ * Do not deliver the signal. Instead, redirect control to the
935
+ * application state specified in dr_siginfo_t.mcontext.
936
+ */
937
+ DR_SIGNAL_REDIRECT,
938
+ } dr_signal_action_t;
939
+
940
+
941
+ /**
942
+ * Requests that DR call the provided callback function \p func whenever a
943
+ * signal is received by any application thread. The return value of \p
944
+ * func determines whether DR delivers the signal to the application.
945
+ * To redirect execution return DR_SIGNAL_REDIRECT (do not call
946
+ * dr_redirect_execution() from a signal callback). The callback function
947
+ * will be called even if the application has no handler or has registered
948
+ * a SIG_IGN or SIG_DFL handler.
949
+ *
950
+ * Modifications to the fields of \p siginfo->mcontext will be propagated
951
+ * to the application if it has a handler for the signal, if
952
+ * DR_SIGNAL_DELIVER is returned.
953
+ *
954
+ * The \p siginfo->raw_mcontext data is only provided for non-delayable
955
+ * signals (e.g., SIGSEGV) that must be delivered immediately. Whether it
956
+ * is supplied is specified in \p siginfo->raw_mcontext_valid. It is
957
+ * intended for clients using faults as a mechanism to push rare cases out
958
+ * of an instrumentation fastpath that need to examine instrumentation
959
+ * instructions rather than the translated application state. Certain
960
+ * registers may not contain proper application values in \p
961
+ * excpt->raw_mcontext for exceptions in application instructions. Clients
962
+ * are cautioned against relying on any details of code cache layout or
963
+ * register usage beyond instrumentation inserted by the client itself. If
964
+ * DR_SIGNAL_SUPPRESS is returned, \p siginfo->mcontext is ignored and \p
965
+ * siginfo->raw_mcontext is used as the resumption context. The client's
966
+ * changes to \p siginfo->raw_mcontext will take effect.
967
+ *
968
+ * For a delayable signal, DR raises a signal event only when about to
969
+ * deliver the signal to the application. Thus, if the application has
970
+ * blocked a delayable signal, the corresponding signal event will not
971
+ * occur until the application unblocks the signal, even if such a signal
972
+ * is delivered by the kernel. For non-delayable signals, DR will raise a
973
+ * signal event on initial receipt of the signal, with the \p
974
+ * siginfo->blocked field set. Such a blocked signal will have a second
975
+ * event raised when it is delivered to the application (if it is not
976
+ * suppressed by the client, and if there is not already a pending blocked
977
+ * signal, for non-real-time signals).
978
+ *
979
+ * DR raises this event for faults outside the code cache that
980
+ * could come from code generated by a client. For such cases,
981
+ * mcontext is not translated and is identical to raw_mcontext.
982
+ *
983
+ * DR will not raise a signal event for a SIGSEGV or SIGBUS
984
+ * raised by a client code fault rather than the application. Use
985
+ * dr_safe_read() or dr_safe_write() to prevent such faults.
986
+ *
987
+ * \note \p siginfo->fault_fragment_info data is provided
988
+ * with \p siginfo->raw_mcontext. It is valid only if
989
+ * \p siginfo->fault_fragment_info.cache_start_pc is not
990
+ * \p NULL. It provides clients information about the code fragment
991
+ * being executed at the signal interruption point. Clients are
992
+ * cautioned against relying on any details of code cache layout or
993
+ * register usage beyond instrumentation inserted by the client
994
+ * itself.
995
+ *
996
+ * \note Only valid on Linux.
997
+ *
998
+ * \note DR always requests SA_SIGINFO for all signals.
999
+ *
1000
+ * \note This version of DR does not intercept the signals SIGCONT,
1001
+ * SIGSTOP, SIGTSTP, SIGTTIN, or SIGTTOU. Future versions should add
1002
+ * support for these signals.
1003
+ *
1004
+ * \note If the client uses signals for its own communication it should set
1005
+ * a flag to distinguish its own uses of signals from the application's
1006
+ * use. Races where the two are re-ordered should not be problematic.
1007
+ */
1008
+ void
1009
+ dr_register_signal_event(dr_signal_action_t (*func)
1010
+ (void *drcontext, dr_siginfo_t *siginfo));
1011
+
1012
+ /**
1013
+ * Unregister a callback function for the signal event.
1014
+ * \return true if unregistration is successful and false if it is not
1015
+ * (e.g., \p func was not registered).
1016
+ */
1017
+ bool
1018
+ dr_unregister_signal_event(dr_signal_action_t (*func)
1019
+ (void *drcontext, dr_siginfo_t *siginfo));
1020
+ #endif /* LINUX */
1021
+
1022
+
1023
+ /**
1024
+ * Registers a callback function for nudge events. External entities
1025
+ * can nudge a process through the dr_nudge_process() API routine on
1026
+ * Windows or using the \p nudgeunix tool on Linux. DR then calls \p
1027
+ * func whenever the current process receives the nudge. On Windows,
1028
+ * the nudge event is delivered in a new non-application thread.
1029
+ * Callers must specify the target client by passing the client ID
1030
+ * that was provided in dr_init().
1031
+ */
1032
+ void
1033
+ dr_register_nudge_event(void (*func)(void *drcontext, uint64 argument), client_id_t id);
1034
+
1035
+ /**
1036
+ * Unregister a callback function for the nudge event.
1037
+ * \return true if unregistration is successful and false if it is not
1038
+ * (e.g., \p func was not registered).
1039
+ */
1040
+ bool
1041
+ dr_unregister_nudge_event(void (*func)(void *drcontext, uint64 argument), client_id_t id);
1042
+
1043
+ /**
1044
+ * Triggers an asynchronous nudge event in the current process. The callback
1045
+ * function registered with dr_register_nudge_event() will be called with the
1046
+ * supplied \p argument (in a new non-application thread on Windows).
1047
+ *
1048
+ * \note On Linux, the nudge will not be delivered until this thread exits
1049
+ * the code cache. Thus, if this routine is called from a clean call,
1050
+ * dr_redirect_execution() should be used to ensure cache exit.
1051
+ *
1052
+ * \note Not yet supported for 32-bit processes running on 64-bit Windows (WOW64).
1053
+ */
1054
+ bool
1055
+ dr_nudge_client(client_id_t id, uint64 argument);
1056
+
1057
+ #endif /* _DR_EVENTS_H_ */