duran 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +11 -0
- data/Rakefile +29 -0
- data/VERSION +1 -0
- data/client_src/dr_include/dr_api.h +102 -0
- data/client_src/dr_include/dr_app.h +92 -0
- data/client_src/dr_include/dr_config.h +650 -0
- data/client_src/dr_include/dr_defines.h +391 -0
- data/client_src/dr_include/dr_events.h +1057 -0
- data/client_src/dr_include/dr_ir_instr.h +1214 -0
- data/client_src/dr_include/dr_ir_instrlist.h +149 -0
- data/client_src/dr_include/dr_ir_macros.h +2426 -0
- data/client_src/dr_include/dr_ir_opcodes.h +768 -0
- data/client_src/dr_include/dr_ir_opnd.h +1170 -0
- data/client_src/dr_include/dr_ir_utils.h +708 -0
- data/client_src/dr_include/dr_proc.h +327 -0
- data/client_src/dr_include/dr_tools.h +1304 -0
- data/client_src/duran.c +57 -0
- data/client_src/extconf.rb +28 -0
- data/lib/duran.rb +18 -0
- data/lib/duran/app.rb +8 -0
- data/lib/duran/defines.rb +39 -0
- data/lib/duran/events.rb +156 -0
- data/lib/duran/ir_opcodes.rb +616 -0
- data/lib/duran/ir_opnd.rb +329 -0
- data/lib/duran/ir_utils.rb +133 -0
- data/lib/duran/proc.rb +49 -0
- data/lib/duran/structs.rb +20 -0
- data/lib/duran/structs/exception.rb +23 -0
- data/lib/duran/structs/fault_fragment_info.rb +34 -0
- data/lib/duran/structs/instruction.rb +15 -0
- data/lib/duran/structs/machine_context.rb +80 -0
- data/lib/duran/structs/memory_info.rb +12 -0
- data/lib/duran/structs/module_data.rb +61 -0
- data/lib/duran/structs/module_names.rb +24 -0
- data/lib/duran/structs/operand.rb +15 -0
- data/lib/duran/structs/restore_state_info.rb +30 -0
- data/lib/duran/structs/signal_info.rb +41 -0
- data/lib/duran/structs/tracedump.rb +50 -0
- data/lib/duran/tools.rb +214 -0
- 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_ */
|