duran 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,327 @@
|
|
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_PROC_H_
|
34
|
+
#define _DR_PROC_H_ 1
|
35
|
+
|
36
|
+
/****************************************************************************
|
37
|
+
* PROCESSOR-SPECIFIC UTILITY ROUTINES AND CONSTANTS
|
38
|
+
*/
|
39
|
+
/**
|
40
|
+
* @file dr_proc.h
|
41
|
+
* @brief Utility routines for identifying features of the processor.
|
42
|
+
*/
|
43
|
+
|
44
|
+
/* page size is 4K on all DR-supported platforms */
|
45
|
+
#define PAGE_SIZE (4*1024) /**< Size of a page of memory. */
|
46
|
+
|
47
|
+
/**< Convenience macro to align to the start of a page of memory. */
|
48
|
+
#define PAGE_START(x) (((ptr_uint_t)(x)) & ~((PAGE_SIZE)-1))
|
49
|
+
|
50
|
+
/** Constants returned by proc_get_vendor(). */
|
51
|
+
enum {
|
52
|
+
VENDOR_INTEL, /**< proc_get_vendor() processor identification: Intel */
|
53
|
+
VENDOR_AMD, /**< proc_get_vendor() processor identification: AMD */
|
54
|
+
VENDOR_UNKNOWN, /**< proc_get_vendor() processor identification: unknown */
|
55
|
+
};
|
56
|
+
|
57
|
+
/* Family and Model
|
58
|
+
* Intel 486 Family 4
|
59
|
+
* Intel Pentium Family 5
|
60
|
+
* Intel Pentium Pro Family 6, Model 0 and 1
|
61
|
+
* Intel Pentium 2 Family 6, Model 3, 5, and 6
|
62
|
+
* Intel Celeron Family 6, Model 5 and 6
|
63
|
+
* Intel Pentium 3 Family 6, Model 7, 8, 10, 11
|
64
|
+
* Intel Pentium 4 Family 15, Extended 0
|
65
|
+
* Intel Itanium Family 7
|
66
|
+
* Intel Itanium 2 Family 15, Extended 1 and 2
|
67
|
+
* Intel Pentium M Family 6, Model 9 and 13
|
68
|
+
* Intel Core Family 6, Model 14
|
69
|
+
* Intel Core 2 Family 6, Model 15
|
70
|
+
*/
|
71
|
+
|
72
|
+
/* Remember that we add extended family to family as Intel suggests */
|
73
|
+
#define FAMILY_ITANIUM_2_DC 17 /**< proc_get_family() processor family: Itanium 2 DC */
|
74
|
+
#define FAMILY_ITANIUM_2 16 /**< proc_get_family() processor family: Itanium 2 */
|
75
|
+
#define FAMILY_K8L 16 /**< proc_get_family() processor family: AMD K8L */
|
76
|
+
#define FAMILY_K8 15 /**< proc_get_family() processor family: AMD K8 */
|
77
|
+
#define FAMILY_PENTIUM_4 15 /**< proc_get_family() processor family: Pentium 4 */
|
78
|
+
#define FAMILY_ITANIUM 7 /**< proc_get_family() processor family: Itanium */
|
79
|
+
/* Pentium Pro, Pentium II, Pentium III, Athlon, Pentium M, Core, Core 2 */
|
80
|
+
#define FAMILY_CORE_2 6 /**< proc_get_family() processor family: Core 2 */
|
81
|
+
#define FAMILY_CORE 6 /**< proc_get_family() processor family: Core */
|
82
|
+
#define FAMILY_PENTIUM_M 6 /**< proc_get_family() processor family: Pentium M */
|
83
|
+
#define FAMILY_PENTIUM_3 6 /**< proc_get_family() processor family: Pentium 3 */
|
84
|
+
#define FAMILY_PENTIUM_2 6 /**< proc_get_family() processor family: Pentium 2 */
|
85
|
+
#define FAMILY_PENTIUM_PRO 6 /**< proc_get_family() processor family: Pentium Pro */
|
86
|
+
#define FAMILY_ATHLON 6 /**< proc_get_family() processor family: Athlon */
|
87
|
+
/* Pentium (586) */
|
88
|
+
#define FAMILY_PENTIUM 5 /**< proc_get_family() processor family: Pentium */
|
89
|
+
#define FAMILY_K6 5 /**< proc_get_family() processor family: K6 */
|
90
|
+
#define FAMILY_K5 5 /**< proc_get_family() processor family: K5 */
|
91
|
+
/* 486 */
|
92
|
+
#define FAMILY_486 4 /**< proc_get_family() processor family: 486 */
|
93
|
+
|
94
|
+
/* We do not enumerate all models; just relevant ones needed to distinguish
|
95
|
+
* major processors in the same family.
|
96
|
+
*/
|
97
|
+
#define MODEL_PENTIUM_M_1MB 9 /**< proc_get_model() processor model: Pentium M 1MB L2 */
|
98
|
+
#define MODEL_PENTIUM_M 13 /**< proc_get_model() processor model: Pentium M 2MB L2 */
|
99
|
+
#define MODEL_CORE 14 /**< proc_get_model() processor model: Core */
|
100
|
+
#define MODEL_CORE_2 15 /**< proc_get_model() processor model: Core 2 */
|
101
|
+
|
102
|
+
/**
|
103
|
+
* Struct to hold all 4 32-bit feature values returned by cpuid.
|
104
|
+
* Used by proc_get_all_feature_bits().
|
105
|
+
*/
|
106
|
+
typedef struct {
|
107
|
+
uint flags_edx; /**< feature flags stored in edx */
|
108
|
+
uint flags_ecx; /**< feature flags stored in ecx */
|
109
|
+
uint ext_flags_edx; /**< extended feature flags stored in edx */
|
110
|
+
uint ext_flags_ecx; /**< extended feature flags stored in ecx */
|
111
|
+
} features_t;
|
112
|
+
|
113
|
+
/**
|
114
|
+
* Feature bits returned by cpuid. Pass one of these values to proc_has_feature() to
|
115
|
+
* determine whether the underlying processor has the feature.
|
116
|
+
*/
|
117
|
+
typedef enum {
|
118
|
+
/* features returned in edx */
|
119
|
+
FEATURE_FPU = 0, /**< Floating-point unit on chip */
|
120
|
+
FEATURE_VME = 1, /**< Virtual Mode Extension */
|
121
|
+
FEATURE_DE = 2, /**< Debugging Extension */
|
122
|
+
FEATURE_PSE = 3, /**< Page Size Extension */
|
123
|
+
FEATURE_TSC = 4, /**< Time-Stamp Counter */
|
124
|
+
FEATURE_MSR = 5, /**< Model Specific Registers */
|
125
|
+
FEATURE_PAE = 6, /**< Physical Address Extension */
|
126
|
+
FEATURE_MCE = 7, /**< Machine Check Exception */
|
127
|
+
FEATURE_CX8 = 8, /**< CMPXCHG8 Instruction Supported */
|
128
|
+
FEATURE_APIC = 9, /**< On-chip APIC Hardware Supported */
|
129
|
+
FEATURE_SEP = 11, /**< Fast System Call */
|
130
|
+
FEATURE_MTRR = 12, /**< Memory Type Range Registers */
|
131
|
+
FEATURE_PGE = 13, /**< Page Global Enable */
|
132
|
+
FEATURE_MCA = 14, /**< Machine Check Architecture */
|
133
|
+
FEATURE_CMOV = 15, /**< Conditional Move Instruction */
|
134
|
+
FEATURE_PAT = 16, /**< Page Attribute Table */
|
135
|
+
FEATURE_PSE_36 = 17, /**< 36-bit Page Size Extension */
|
136
|
+
FEATURE_PSN = 18, /**< Processor serial # present & enabled */
|
137
|
+
FEATURE_CLFSH = 19, /**< CLFLUSH Instruction supported */
|
138
|
+
FEATURE_DS = 21, /**< Debug Store */
|
139
|
+
FEATURE_ACPI = 22, /**< Thermal monitor & SCC supported */
|
140
|
+
FEATURE_MMX = 23, /**< MMX technology supported */
|
141
|
+
FEATURE_FXSR = 24, /**< Fast FP save and restore */
|
142
|
+
FEATURE_SSE = 25, /**< SSE Extensions supported */
|
143
|
+
FEATURE_SSE2 = 26, /**< SSE2 Extensions supported */
|
144
|
+
FEATURE_SS = 27, /**< Self-snoop */
|
145
|
+
FEATURE_HTT = 28, /**< Hyper-threading Technology */
|
146
|
+
FEATURE_TM = 29, /**< Thermal Monitor supported */
|
147
|
+
FEATURE_IA64 = 30, /**< IA64 Capabilities */
|
148
|
+
FEATURE_PBE = 31, /**< Pending Break Enable */
|
149
|
+
/* features returned in ecx */
|
150
|
+
FEATURE_SSE3 = 0 + 32, /**< SSE3 Extensions supported */
|
151
|
+
FEATURE_MONITOR = 3 + 32, /**< MONITOR/MWAIT instructions supported */
|
152
|
+
FEATURE_DS_CPL = 4 + 32, /**< CPL Qualified Debug Store */
|
153
|
+
FEATURE_VMX = 5 + 32, /**< Virtual Machine Extensions */
|
154
|
+
FEATURE_EST = 7 + 32, /**< Enhanced Speedstep Technology */
|
155
|
+
FEATURE_TM2 = 8 + 32, /**< Thermal Monitor 2 */
|
156
|
+
FEATURE_SSSE3 = 9 + 32, /**< SSSE3 Extensions supported */
|
157
|
+
FEATURE_CID = 10 + 32, /**< Context ID */
|
158
|
+
FEATURE_CX16 = 13 + 32, /**< CMPXCHG16B instruction supported */
|
159
|
+
FEATURE_xPTR = 14 + 32, /**< Send Task Priority Messages */
|
160
|
+
/* extended features returned in edx */
|
161
|
+
FEATURE_SYSCALL = 11 + 64, /**< SYSCALL/SYSRET instructions supported */
|
162
|
+
FEATURE_XD_Bit = 20 + 64, /**< Execution Disable bit */
|
163
|
+
FEATURE_EM64T = 29 + 64, /**< Extended Memory 64 Technology */
|
164
|
+
/* extended features returned in ecx */
|
165
|
+
FEATURE_LAHF = 0 + 96 /**< LAHF/SAHF available in 64-bit mode */
|
166
|
+
} feature_bit_t;
|
167
|
+
|
168
|
+
/**
|
169
|
+
* L1 and L2 cache sizes, used by proc_get_L1_icache_size(),
|
170
|
+
* proc_get_L1_dcache_size(), proc_get_L2_cache_size(), and
|
171
|
+
* proc_get_cache_size_str().
|
172
|
+
*/
|
173
|
+
typedef enum {
|
174
|
+
CACHE_SIZE_8_KB, /**< L1 or L2 cache size of 8 KB. */
|
175
|
+
CACHE_SIZE_16_KB, /**< L1 or L2 cache size of 16 KB. */
|
176
|
+
CACHE_SIZE_32_KB, /**< L1 or L2 cache size of 32 KB. */
|
177
|
+
CACHE_SIZE_64_KB, /**< L1 or L2 cache size of 64 KB. */
|
178
|
+
CACHE_SIZE_128_KB, /**< L1 or L2 cache size of 128 KB. */
|
179
|
+
CACHE_SIZE_256_KB, /**< L1 or L2 cache size of 256 KB. */
|
180
|
+
CACHE_SIZE_512_KB, /**< L1 or L2 cache size of 512 KB. */
|
181
|
+
CACHE_SIZE_1_MB, /**< L1 or L2 cache size of 1 MB. */
|
182
|
+
CACHE_SIZE_2_MB, /**< L1 or L2 cache size of 2 MB. */
|
183
|
+
CACHE_SIZE_UNKNOWN /**< Unknown L1 or L2 cache size. */
|
184
|
+
} cache_size_t;
|
185
|
+
|
186
|
+
|
187
|
+
|
188
|
+
/** Returns the cache line size in bytes of the processor. */
|
189
|
+
size_t
|
190
|
+
proc_get_cache_line_size(void);
|
191
|
+
|
192
|
+
/** Returns true only if \p addr is cache-line-aligned. */
|
193
|
+
bool
|
194
|
+
proc_is_cache_aligned(void *addr);
|
195
|
+
|
196
|
+
/** Returns n >= \p sz such that n is a multiple of the cache line size. */
|
197
|
+
ptr_uint_t
|
198
|
+
proc_bump_to_end_of_cache_line(ptr_uint_t sz);
|
199
|
+
|
200
|
+
/** Returns n <= \p addr such that n is a multiple of the page size. */
|
201
|
+
void *
|
202
|
+
proc_get_containing_page(void *addr);
|
203
|
+
|
204
|
+
/** Returns one of the VENDOR_ constants. */
|
205
|
+
uint
|
206
|
+
proc_get_vendor(void);
|
207
|
+
|
208
|
+
/**
|
209
|
+
* Returns the processor family as given by the cpuid instruction,
|
210
|
+
* adjusted by the extended family as described in the Intel documentation.
|
211
|
+
* The FAMILY_ constants identify important family values.
|
212
|
+
*/
|
213
|
+
uint
|
214
|
+
proc_get_family(void);
|
215
|
+
|
216
|
+
/** Returns the processor type as given by the cpuid instruction. */
|
217
|
+
uint
|
218
|
+
proc_get_type(void);
|
219
|
+
|
220
|
+
/**
|
221
|
+
* Returns the processor model as given by the cpuid instruction,
|
222
|
+
* adjusted by the extended model as described in the Intel documentation.
|
223
|
+
* The MODEL_ constants identify important model values.
|
224
|
+
*/
|
225
|
+
uint
|
226
|
+
proc_get_model(void);
|
227
|
+
|
228
|
+
/** Returns the processor stepping ID. */
|
229
|
+
uint
|
230
|
+
proc_get_stepping(void);
|
231
|
+
|
232
|
+
/** Tests if processor has selected feature. */
|
233
|
+
bool
|
234
|
+
proc_has_feature(feature_bit_t feature);
|
235
|
+
|
236
|
+
/**
|
237
|
+
* Returns all 4 32-bit feature values. Use proc_has_feature to test
|
238
|
+
* for specific features.
|
239
|
+
*/
|
240
|
+
features_t *
|
241
|
+
proc_get_all_feature_bits(void);
|
242
|
+
|
243
|
+
/** Returns the processor brand string as given by the cpuid instruction. */
|
244
|
+
char*
|
245
|
+
proc_get_brand_string(void);
|
246
|
+
|
247
|
+
/** Returns the size of the L1 instruction cache. */
|
248
|
+
cache_size_t
|
249
|
+
proc_get_L1_icache_size(void);
|
250
|
+
|
251
|
+
/** Returns the size of the L1 data cache. */
|
252
|
+
cache_size_t
|
253
|
+
proc_get_L1_dcache_size(void);
|
254
|
+
|
255
|
+
/** Returns the size of the L2 cache. */
|
256
|
+
cache_size_t
|
257
|
+
proc_get_L2_cache_size(void);
|
258
|
+
|
259
|
+
/** Converts a cache_size_t type to a string. */
|
260
|
+
const char*
|
261
|
+
proc_get_cache_size_str(cache_size_t size);
|
262
|
+
|
263
|
+
/**
|
264
|
+
* Returns the size in bytes needed for a buffer for saving the floating point state.
|
265
|
+
*/
|
266
|
+
size_t
|
267
|
+
proc_fpstate_save_size(void);
|
268
|
+
|
269
|
+
/**
|
270
|
+
* Saves the floating point state into the 16-byte-aligned buffer \p buf,
|
271
|
+
* which must be 512 bytes for processors with the FXSR feature, and
|
272
|
+
* 108 bytes for those without (where this routine does not support
|
273
|
+
* 16-bit operand sizing). \note proc_fpstate_save_size() can be used
|
274
|
+
* to determine the particular size needed.
|
275
|
+
*
|
276
|
+
* DR does NOT save the application's floating-point, MMX, or SSE state
|
277
|
+
* on context switches! Thus if a client performs any floating-point
|
278
|
+
* operations in its main routines called by DR, the client must save
|
279
|
+
* and restore the floating-point/MMX/SSE state.
|
280
|
+
* If the client needs to do so inside the code cache the client should implement
|
281
|
+
* that itself.
|
282
|
+
* Returns number of bytes written.
|
283
|
+
*/
|
284
|
+
size_t
|
285
|
+
proc_save_fpstate(byte *buf);
|
286
|
+
|
287
|
+
/**
|
288
|
+
* Restores the floating point state from the 16-byte-aligned buffer
|
289
|
+
* \p buf, which must be 512 bytes for processors with the FXSR feature,
|
290
|
+
* and 108 bytes for those without (where this routine does not
|
291
|
+
* support 16-bit operand sizing). \note proc_fpstate_save_size() can
|
292
|
+
* be used to determine the particular size needed.
|
293
|
+
*/
|
294
|
+
void
|
295
|
+
proc_restore_fpstate(byte *buf);
|
296
|
+
|
297
|
+
|
298
|
+
/**
|
299
|
+
* Inserts into \p ilist prior to \p where meta-instruction(s) to save the
|
300
|
+
* floating point state into the 16-byte-aligned buffer referred to by
|
301
|
+
* \p buf, which must be 512 bytes for processors with the FXSR
|
302
|
+
* feature, and 108 bytes for those without (where this routine does
|
303
|
+
* not support 16-bit operand sizing). \p buf should have size of
|
304
|
+
* OPSZ_512; this routine will automatically adjust it to OPSZ_108 if
|
305
|
+
* necessary. \note proc_fpstate_save_size() can be used to determine
|
306
|
+
* the particular size needed.
|
307
|
+
*/
|
308
|
+
void
|
309
|
+
dr_insert_save_fpstate(void *drcontext, instrlist_t *ilist, instr_t *where,
|
310
|
+
opnd_t buf);
|
311
|
+
|
312
|
+
/**
|
313
|
+
* Inserts into \p ilist prior to \p where meta-instruction(s) to restore the
|
314
|
+
* floating point state from the 16-byte-aligned buffer referred to by
|
315
|
+
* buf, which must be 512 bytes for processors with the FXSR feature,
|
316
|
+
* and 108 bytes for those without (where this routine does not
|
317
|
+
* support 16-bit operand sizing). \p buf should have size of
|
318
|
+
* OPSZ_512; this routine will automatically adjust it to OPSZ_108 if
|
319
|
+
* necessary. \note proc_fpstate_save_size() can be used to determine
|
320
|
+
* the particular size needed.
|
321
|
+
*/
|
322
|
+
void
|
323
|
+
dr_insert_restore_fpstate(void *drcontext, instrlist_t *ilist, instr_t *where,
|
324
|
+
opnd_t buf);
|
325
|
+
|
326
|
+
|
327
|
+
#endif /* _DR_PROC_H_ */
|
@@ -0,0 +1,1304 @@
|
|
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_TOOLS_H_
|
34
|
+
#define _DR_TOOLS_H_ 1
|
35
|
+
|
36
|
+
/**************************************************
|
37
|
+
* MEMORY INFORMATION TYPES
|
38
|
+
*/
|
39
|
+
|
40
|
+
#define DR_MEMPROT_NONE 0x00 /**< No read, write, or execute privileges. */
|
41
|
+
#define DR_MEMPROT_READ 0x01 /**< Read privileges. */
|
42
|
+
#define DR_MEMPROT_WRITE 0x02 /**< Write privileges. */
|
43
|
+
#define DR_MEMPROT_EXEC 0x04 /**< Execute privileges. */
|
44
|
+
|
45
|
+
/**
|
46
|
+
* Flags describing memory used by dr_query_memory_ex().
|
47
|
+
*/
|
48
|
+
typedef enum {
|
49
|
+
DR_MEMTYPE_FREE, /**< No memory is allocated here */
|
50
|
+
DR_MEMTYPE_IMAGE, /**< An executable file is mapped here */
|
51
|
+
DR_MEMTYPE_DATA, /**< Some other data is allocated here */
|
52
|
+
} dr_mem_type_t;
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Describes a memory region. Used by dr_query_memory_ex().
|
56
|
+
*/
|
57
|
+
typedef struct _dr_mem_info_t {
|
58
|
+
/** Starting address of memory region */
|
59
|
+
byte *base_pc;
|
60
|
+
/** Size of region */
|
61
|
+
size_t size;
|
62
|
+
/** Protection of region (DR_MEMPROT_* flags) */
|
63
|
+
uint prot;
|
64
|
+
/** Type of region */
|
65
|
+
dr_mem_type_t type;
|
66
|
+
} dr_mem_info_t;
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
/**************************************************
|
71
|
+
* MODULE INFORMATION TYPES
|
72
|
+
*/
|
73
|
+
|
74
|
+
/**
|
75
|
+
* Type used for dr_get_proc_address(). This can be obtained from the
|
76
|
+
* #_module_data_t structure. It is equivalent to the base address of
|
77
|
+
* the module on both Windows and Linux.
|
78
|
+
*/
|
79
|
+
typedef void * module_handle_t;
|
80
|
+
|
81
|
+
#ifdef WINDOWS
|
82
|
+
|
83
|
+
#define MODULE_FILE_VERSION_INVALID ULLONG_MAX
|
84
|
+
|
85
|
+
/**
|
86
|
+
* Used to hold .rsrc section version number information. This number is usually
|
87
|
+
* presented as p1.p2.p3.p4 by PE parsing tools.
|
88
|
+
*/
|
89
|
+
typedef union _version_number_t {
|
90
|
+
uint64 version; /**< Representation as a 64-bit integer. */
|
91
|
+
struct {
|
92
|
+
uint ms; /**< */
|
93
|
+
uint ls; /**< */
|
94
|
+
} version_uint; /**< Representation as 2 32-bit integers. */
|
95
|
+
struct {
|
96
|
+
ushort p2; /**< */
|
97
|
+
ushort p1; /**< */
|
98
|
+
ushort p4; /**< */
|
99
|
+
ushort p3; /**< */
|
100
|
+
} version_parts; /**< Representation as 4 16-bit integers. */
|
101
|
+
} version_number_t;
|
102
|
+
|
103
|
+
#endif
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Holds the names of a module. This structure contains multiple
|
109
|
+
* fields corresponding to different sources of a module name. Note
|
110
|
+
* that some of these names may not exist for certain modules. It is
|
111
|
+
* highly likely, however, that at least one name is available. Use
|
112
|
+
* dr_module_preferred_name() on the parent _module_data_t to get the
|
113
|
+
* preferred name of the module.
|
114
|
+
*/
|
115
|
+
typedef struct _module_names_t {
|
116
|
+
const char *module_name; /**< On windows this name comes from the PE header exports
|
117
|
+
* section (NULL if the module has no exports section). On
|
118
|
+
* Linux the name will come from the ELF DYNAMIC program
|
119
|
+
* header (NULL if the module has no SONAME entry). */
|
120
|
+
const char *file_name; /**< The file name used to load this module. Note - on Windows
|
121
|
+
* this is not always available. */
|
122
|
+
#ifdef WINDOWS
|
123
|
+
const char *exe_name; /**< If this module is the main executable of this process then
|
124
|
+
* this is the executable name used to launch the process (NULL
|
125
|
+
* for all other modules). */
|
126
|
+
const char *rsrc_name; /**< The internal name given to the module in its resource
|
127
|
+
* section. Will be NULL if the module has no resource section
|
128
|
+
* or doesn't set this field within it. */
|
129
|
+
#else /* LINUX */
|
130
|
+
uint64 inode; /**< The inode of the module file mapped in. */
|
131
|
+
#endif
|
132
|
+
} module_names_t;
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
/**************************************************
|
138
|
+
* TOP-LEVEL ROUTINES
|
139
|
+
*/
|
140
|
+
/**
|
141
|
+
* @file dr_tools.h
|
142
|
+
* @brief Main API routines, including transparency support.
|
143
|
+
*/
|
144
|
+
|
145
|
+
|
146
|
+
/**
|
147
|
+
* Creates a DR context that can be used in a standalone program.
|
148
|
+
* \warning This context cannot be used as the drcontext for a thread
|
149
|
+
* running under DR control! It is only for standalone programs that
|
150
|
+
* wish to use DR as a library of disassembly, etc. routines.
|
151
|
+
*/
|
152
|
+
void *
|
153
|
+
dr_standalone_init(void);
|
154
|
+
|
155
|
+
/**************************************************
|
156
|
+
* UTILITY ROUTINES
|
157
|
+
*/
|
158
|
+
|
159
|
+
#ifdef WINDOWS
|
160
|
+
/**
|
161
|
+
* If \p x is false, displays a message about an assertion failure
|
162
|
+
* (appending \p msg to the message) and then calls dr_abort()
|
163
|
+
*/
|
164
|
+
# define DR_ASSERT_MSG(x, msg) \
|
165
|
+
((void)((!(x)) ? \
|
166
|
+
(dr_messagebox("ASSERT FAILURE: %s:%d: %s (%s)", __FILE__, __LINE__, #x, msg),\
|
167
|
+
dr_abort(), 0) : 0))
|
168
|
+
#else
|
169
|
+
# define DR_ASSERT_MSG(x, msg) \
|
170
|
+
((void)((!(x)) ? \
|
171
|
+
(dr_fprintf(STDERR, "ASSERT FAILURE: %s:%d: %s (%s)", \
|
172
|
+
__FILE__, __LINE__, #x, msg), \
|
173
|
+
dr_abort(), 0) : 0))
|
174
|
+
#endif
|
175
|
+
|
176
|
+
/**
|
177
|
+
* If \p x is false, displays a message about an assertion failure and
|
178
|
+
* then calls dr_abort()
|
179
|
+
*/
|
180
|
+
#define DR_ASSERT(x) DR_ASSERT_MSG(x, "")
|
181
|
+
|
182
|
+
|
183
|
+
|
184
|
+
/** Returns true if all \DynamoRIO caches are thread private. */
|
185
|
+
bool
|
186
|
+
dr_using_all_private_caches(void);
|
187
|
+
|
188
|
+
/**
|
189
|
+
* Returns the client-specific option string specified at client
|
190
|
+
* registration. \p client_id is the client ID passed to dr_init().
|
191
|
+
*/
|
192
|
+
const char *
|
193
|
+
dr_get_options(client_id_t client_id);
|
194
|
+
|
195
|
+
/**
|
196
|
+
* Returns the client library name and path that were originally specified
|
197
|
+
* to load the library. If the resulting string is longer than #MAXIMUM_PATH
|
198
|
+
* it will be truncated. \p client_id is the client ID passed to a client's
|
199
|
+
* dr_init() function.
|
200
|
+
*/
|
201
|
+
const char *
|
202
|
+
dr_get_client_path(client_id_t client_id);
|
203
|
+
|
204
|
+
/** Returns the image name (without path) of the current application. */
|
205
|
+
const char *
|
206
|
+
dr_get_application_name(void);
|
207
|
+
|
208
|
+
/** Returns the process id of the current process. */
|
209
|
+
process_id_t
|
210
|
+
dr_get_process_id(void);
|
211
|
+
|
212
|
+
/**
|
213
|
+
* Returns the process id of the parent of the current process.
|
214
|
+
* \note Linux only.
|
215
|
+
*/
|
216
|
+
process_id_t
|
217
|
+
dr_get_parent_id(void);
|
218
|
+
|
219
|
+
/**
|
220
|
+
* Returns true if this process is a 32-bit process operating on a
|
221
|
+
* 64-bit Windows kernel, known as Windows-On-Windows-64, or WOW64.
|
222
|
+
* Returns false otherwise.
|
223
|
+
*/
|
224
|
+
bool
|
225
|
+
dr_is_wow64(void);
|
226
|
+
|
227
|
+
/** Structure written by dr_get_time() to specify the current time. */
|
228
|
+
typedef struct {
|
229
|
+
uint year; /**< */
|
230
|
+
uint month; /**< */
|
231
|
+
uint day_of_week; /**< */
|
232
|
+
uint day; /**< */
|
233
|
+
uint hour; /**< */
|
234
|
+
uint minute; /**< */
|
235
|
+
uint second; /**< */
|
236
|
+
uint milliseconds; /**< */
|
237
|
+
} dr_time_t;
|
238
|
+
|
239
|
+
|
240
|
+
/** Retrieves the current time. */
|
241
|
+
void
|
242
|
+
dr_get_time(dr_time_t *time);
|
243
|
+
|
244
|
+
/** Aborts the process immediately. */
|
245
|
+
void
|
246
|
+
dr_abort(void);
|
247
|
+
|
248
|
+
/**************************************************
|
249
|
+
* APPLICATION-INDEPENDENT MEMORY ALLOCATION
|
250
|
+
*/
|
251
|
+
|
252
|
+
|
253
|
+
/**
|
254
|
+
* Allocates \p size bytes of memory from DR's memory pool specific to the
|
255
|
+
* thread associated with \p drcontext.
|
256
|
+
*/
|
257
|
+
void *
|
258
|
+
dr_thread_alloc(void *drcontext, size_t size);
|
259
|
+
|
260
|
+
/**
|
261
|
+
* Frees thread-specific memory allocated by dr_thread_alloc().
|
262
|
+
* \p size must be the same as that passed to dr_thread_alloc().
|
263
|
+
*/
|
264
|
+
void
|
265
|
+
dr_thread_free(void *drcontext, void *mem, size_t size);
|
266
|
+
|
267
|
+
/** Allocates \p size bytes of memory from DR's global memory pool. */
|
268
|
+
void *
|
269
|
+
dr_global_alloc(size_t size);
|
270
|
+
|
271
|
+
/**
|
272
|
+
* Frees memory allocated by dr_global_alloc().
|
273
|
+
* \p size must be the same as that passed to dr_global_alloc().
|
274
|
+
*/
|
275
|
+
void
|
276
|
+
dr_global_free(void *mem, size_t size);
|
277
|
+
|
278
|
+
/**
|
279
|
+
* Allocates \p size bytes of memory as a separate allocation from DR's
|
280
|
+
* heap, allowing for separate protection.
|
281
|
+
* The \p prot protection should use the DR_MEMPROT_READ,
|
282
|
+
* DR_MEMPROT_WRITE, and DR_MEMPROT_EXEC bits.
|
283
|
+
* When creating a region to hold dynamically generated code, use
|
284
|
+
* this routine in order to create executable memory.
|
285
|
+
*/
|
286
|
+
void *
|
287
|
+
dr_nonheap_alloc(size_t size, uint prot);
|
288
|
+
|
289
|
+
/**
|
290
|
+
* Frees memory allocated by dr_nonheap_alloc().
|
291
|
+
* \p size must be the same as that passed to dr_nonheap_alloc().
|
292
|
+
*/
|
293
|
+
void
|
294
|
+
dr_nonheap_free(void *mem, size_t size);
|
295
|
+
|
296
|
+
/**
|
297
|
+
* Allocates memory from DR's global memory pool, but mimics the
|
298
|
+
* behavior of malloc. Memory must be freed with __wrap_free(). The
|
299
|
+
* __wrap routines are intended to be used with ld's -wrap option to
|
300
|
+
* replace a client's use of malloc, realloc, and free with internal
|
301
|
+
* versions that allocate memory from DR's private pool. With -wrap,
|
302
|
+
* clients can link to libraries that allocate heap memory without
|
303
|
+
* interfering with application allocations.
|
304
|
+
* \note Currently Linux only.
|
305
|
+
*/
|
306
|
+
void *
|
307
|
+
__wrap_malloc(size_t size);
|
308
|
+
|
309
|
+
/**
|
310
|
+
* Reallocates memory from DR's global memory pool, but mimics the
|
311
|
+
* behavior of realloc. Memory must be freed with __wrap_free(). The
|
312
|
+
* __wrap routines are intended to be used with ld's -wrap option; see
|
313
|
+
* __wrap_malloc() for more information.
|
314
|
+
* \note Currently Linux only.
|
315
|
+
*/
|
316
|
+
void *
|
317
|
+
__wrap_realloc(void *mem, size_t size);
|
318
|
+
|
319
|
+
/**
|
320
|
+
* Frees memory from DR's global memory pool. Memory must have been
|
321
|
+
* allocated with __wrap_malloc(). The __wrap routines are intended to
|
322
|
+
* be used with ld's -wrap option; see __wrap_malloc() for more
|
323
|
+
* information.
|
324
|
+
* \note Currently Linux only.
|
325
|
+
*/
|
326
|
+
void
|
327
|
+
__wrap_free(void *mem);
|
328
|
+
|
329
|
+
/**************************************************
|
330
|
+
* MEMORY QUERY/ACCESS ROUTINES
|
331
|
+
*/
|
332
|
+
|
333
|
+
|
334
|
+
/**
|
335
|
+
* Checks to see that all bytes with addresses in the range [\p pc, \p pc + \p size - 1]
|
336
|
+
* are readable and that reading from that range won't generate an exception (see also
|
337
|
+
* dr_safe_read()).
|
338
|
+
* \note Nothing guarantees that the memory will stay readable for any length of time.
|
339
|
+
*/
|
340
|
+
bool
|
341
|
+
dr_memory_is_readable(const byte *pc, size_t size);
|
342
|
+
|
343
|
+
/**
|
344
|
+
* An os neutral method for querying a memory address. Returns true
|
345
|
+
* iff a memory region containing \p pc is found. If found additional
|
346
|
+
* information about the memory region is returned in the optional out
|
347
|
+
* arguments \p base_pc, \p size, and \p prot where \p base_pc is the
|
348
|
+
* start address of the memory region continaing \p pc, \p size is the
|
349
|
+
* size of said memory region and \p prot is an ORed combination of
|
350
|
+
* DR_MEMPROT_* flags describing its current protection.
|
351
|
+
*
|
352
|
+
* \note To examine only application memory, skip memory for which
|
353
|
+
* dr_memory_is_dr_internal() or dr_memory_is_in_client() returns true.
|
354
|
+
*/
|
355
|
+
bool
|
356
|
+
dr_query_memory(const byte *pc, byte **base_pc, size_t *size, uint *prot);
|
357
|
+
|
358
|
+
/**
|
359
|
+
* Provides additional information beyond dr_query_memory().
|
360
|
+
* Returns true if it was able to obtain information (including about
|
361
|
+
* free regions) and sets the fields of \p info. This routine can be
|
362
|
+
* used to iterate over the entire address space.
|
363
|
+
* Returns false on failure.
|
364
|
+
*
|
365
|
+
* \note To examine only application memory, skip memory for which
|
366
|
+
* dr_memory_is_dr_internal() returns true.
|
367
|
+
*/
|
368
|
+
bool
|
369
|
+
dr_query_memory_ex(const byte *pc, OUT dr_mem_info_t *info);
|
370
|
+
#ifdef WINDOWS
|
371
|
+
|
372
|
+
|
373
|
+
/**
|
374
|
+
* Equivalent to the win32 API function VirtualQuery().
|
375
|
+
* See that routine for a description of
|
376
|
+
* arguments and return values. \note Windows-only.
|
377
|
+
*/
|
378
|
+
size_t
|
379
|
+
dr_virtual_query(const byte *pc, MEMORY_BASIC_INFORMATION *mbi, size_t mbi_size);
|
380
|
+
#endif
|
381
|
+
|
382
|
+
|
383
|
+
/**
|
384
|
+
* Safely reads \p size bytes from address \p base into buffer \p
|
385
|
+
* out_buf. Reading is done without the possibility of an exception
|
386
|
+
* occuring. Optionally returns the actual number of bytes copied
|
387
|
+
* into \p bytes_read. Returns true if successful.
|
388
|
+
*/
|
389
|
+
bool
|
390
|
+
dr_safe_read(const void *base, size_t size, void *out_buf, size_t *bytes_read);
|
391
|
+
|
392
|
+
/**
|
393
|
+
* Safely writes \p size bytes from buffer \p in_buf to address \p
|
394
|
+
* base. Writing is done without the possiblity of an exception
|
395
|
+
* occuring. Optionally returns the actual number of bytes copied
|
396
|
+
* into \p bytes_written. Returns true if successful.
|
397
|
+
*/
|
398
|
+
bool
|
399
|
+
dr_safe_write(void *base, size_t size, const void *in_buf, size_t *bytes_written);
|
400
|
+
|
401
|
+
/**
|
402
|
+
* Modifies the memory protections of the region from \p start through
|
403
|
+
* \p start + \p size. Modification of memory allocated by DR or of
|
404
|
+
* the DR or client libraries themselves is allowed under the
|
405
|
+
* assumption that the client knows what it is doing. Modification of
|
406
|
+
* the ntdll.dll library on Windows is not allowed. Returns true if
|
407
|
+
* successful.
|
408
|
+
*/
|
409
|
+
bool
|
410
|
+
dr_memory_protect(void *base, size_t size, uint new_prot);
|
411
|
+
|
412
|
+
/**
|
413
|
+
* Returns true iff pc is memory allocated by DR for its own
|
414
|
+
* purposes, and would not exist if the application were run
|
415
|
+
* natively.
|
416
|
+
*/
|
417
|
+
bool
|
418
|
+
dr_memory_is_dr_internal(const byte *pc);
|
419
|
+
|
420
|
+
/**
|
421
|
+
* Returns true iff pc is located inside a client library.
|
422
|
+
*/
|
423
|
+
bool
|
424
|
+
dr_memory_is_in_client(const byte *pc);
|
425
|
+
|
426
|
+
/**************************************************
|
427
|
+
* SIMPLE MUTEX SUPPORT
|
428
|
+
*/
|
429
|
+
|
430
|
+
|
431
|
+
/**
|
432
|
+
* Initializes a mutex.
|
433
|
+
*
|
434
|
+
* Warning: there are restrictions on when DR-provided mutexes, and
|
435
|
+
* locks in general, can be held by a client: no lock should be held
|
436
|
+
* while application code is executing in the code cache. Locks can
|
437
|
+
* be used while inside client code reached from clean calls out of
|
438
|
+
* the code cache, but they must be released before returning to the
|
439
|
+
* cache. Failing to follow these restrictions can lead to deadlocks.
|
440
|
+
*/
|
441
|
+
void *
|
442
|
+
dr_mutex_create(void);
|
443
|
+
|
444
|
+
/** Deletes \p mutex. */
|
445
|
+
void
|
446
|
+
dr_mutex_destroy(void *mutex);
|
447
|
+
|
448
|
+
/** Locks \p mutex. Waits until the mutex is successfully held. */
|
449
|
+
void
|
450
|
+
dr_mutex_lock(void *mutex);
|
451
|
+
|
452
|
+
/** Unlocks \p mutex. Asserts that mutex is currently locked. */
|
453
|
+
void
|
454
|
+
dr_mutex_unlock(void *mutex);
|
455
|
+
|
456
|
+
/** Tries once to lock \p mutex, returns whether or not successful. */
|
457
|
+
bool
|
458
|
+
dr_mutex_trylock(void *mutex);
|
459
|
+
/**************************************************
|
460
|
+
* MODULE INFORMATION ROUTINES
|
461
|
+
*/
|
462
|
+
|
463
|
+
/** For dr_module_iterator_* interface */
|
464
|
+
typedef void * dr_module_iterator_t;
|
465
|
+
|
466
|
+
/**
|
467
|
+
* Holds information about a loaded module. \note On Linux the start address can be
|
468
|
+
* cast to an Elf32_Ehdr or Elf64_Ehdr. \note On Windows the start address can be cast to
|
469
|
+
* an IMAGE_DOS_HEADER for use in finding the IMAGE_NT_HEADER and its OptionalHeader.
|
470
|
+
* The OptionalHeader can be used to walk the module sections (among other things).
|
471
|
+
* See WINNT.H. \note When accesing any memory inside the module (including header fields)
|
472
|
+
* user is responsible for guarding against corruption and the possibility of the module
|
473
|
+
* being unmapped.
|
474
|
+
*/
|
475
|
+
struct _module_data_t {
|
476
|
+
union {
|
477
|
+
app_pc start; /**< starting address of this module */
|
478
|
+
module_handle_t handle; /**< module_handle for use with dr_get_proc_address() */
|
479
|
+
} ; /* anonymous union of start address and module handle */
|
480
|
+
app_pc end; /**< ending address of this module */
|
481
|
+
|
482
|
+
app_pc entry_point; /**< entry point for this module as specified in the headers */
|
483
|
+
|
484
|
+
uint flags; /**< Reserved, set to 0 */
|
485
|
+
|
486
|
+
module_names_t names; /**< struct containing name(s) for this module; use
|
487
|
+
* dr_module_preferred_name() to get the preferred name for
|
488
|
+
* this module */
|
489
|
+
|
490
|
+
char *full_path; /**< full path to the file backing this module;
|
491
|
+
* currently not implemented (always NULL): i#138 */
|
492
|
+
|
493
|
+
#ifdef WINDOWS
|
494
|
+
version_number_t file_version; /**< file version number from .rsrc section */
|
495
|
+
version_number_t product_version; /**< product version number from .rsrc section */
|
496
|
+
uint checksum; /**< module checksum from the PE headers */
|
497
|
+
uint timestamp; /**< module timestamp from the PE headers */
|
498
|
+
size_t module_internal_size; /**< module internal size (from PE headers SizeOfImage) */
|
499
|
+
#else
|
500
|
+
/* No Linux specific fields at this time. */
|
501
|
+
#endif
|
502
|
+
};
|
503
|
+
|
504
|
+
|
505
|
+
|
506
|
+
/**
|
507
|
+
* Looks up the module containing \p pc. If a module containing \p pc is found returns
|
508
|
+
* a module_data_t describing that module else returns NULL. Can be used to
|
509
|
+
* obtain a module_handle_t for dr_lookup_module_section().
|
510
|
+
* \note Returned module_data_t must be freed with dr_free_module_data().
|
511
|
+
*/
|
512
|
+
module_data_t *
|
513
|
+
dr_lookup_module(byte *pc);
|
514
|
+
|
515
|
+
/**
|
516
|
+
* Looks up the module with name \p name ignoring case. If an exact name match is found
|
517
|
+
* returns a module_data_t describing that module else returns NULL. User must call
|
518
|
+
* dr_free_module_data() on the returned module_data_t once finished. Can be used to
|
519
|
+
* obtain a module_handle_t for dr_get_proc_address().
|
520
|
+
* \note Returned module_data_t must be freed with dr_free_module_data().
|
521
|
+
*/
|
522
|
+
module_data_t *
|
523
|
+
dr_lookup_module_by_name(const char *name);
|
524
|
+
|
525
|
+
/**
|
526
|
+
* Initialize a new module iterator. The returned module iterator contains a snapshot
|
527
|
+
* of the modules loaded at the time it was created. Use dr_module_iterator_hasnext()
|
528
|
+
* and dr_module_iterator_next() to walk the loaded modules. Call
|
529
|
+
* dr_module_iterator_stop() when finished to release the iterator. \note The iterator
|
530
|
+
* does not prevent modules from being loaded or unloaded while the iterator is being
|
531
|
+
* walked.
|
532
|
+
*/
|
533
|
+
dr_module_iterator_t *
|
534
|
+
dr_module_iterator_start(void);
|
535
|
+
|
536
|
+
/**
|
537
|
+
* Returns true if there is another loaded module in the iterator.
|
538
|
+
*/
|
539
|
+
bool
|
540
|
+
dr_module_iterator_hasnext(dr_module_iterator_t *mi);
|
541
|
+
|
542
|
+
/**
|
543
|
+
* Retrieves the module_data_t for the next loaded module in the iterator. User must call
|
544
|
+
* dr_free_module_data() on the returned module_data_t once finished.
|
545
|
+
* \note Returned module_data_t must be freed with dr_free_module_data().
|
546
|
+
*/
|
547
|
+
module_data_t *
|
548
|
+
dr_module_iterator_next(dr_module_iterator_t *mi);
|
549
|
+
|
550
|
+
/**
|
551
|
+
* User should call this routine to free the module iterator.
|
552
|
+
*/
|
553
|
+
void
|
554
|
+
dr_module_iterator_stop(dr_module_iterator_t *mi);
|
555
|
+
|
556
|
+
/**
|
557
|
+
* Makes a copy of \p data. Copy must be freed with dr_free_module_data().
|
558
|
+
* Useful for making persistent copies of module_data_t's recieved as part of
|
559
|
+
* image load and unload event callbacks.
|
560
|
+
*/
|
561
|
+
module_data_t *
|
562
|
+
dr_copy_module_data(const module_data_t *data);
|
563
|
+
|
564
|
+
/**
|
565
|
+
* Frees a module_data_t returned by dr_module_iterator_next(), dr_lookup_module(),
|
566
|
+
* dr_lookup_module_by_name(), or dr_copy_module_data(). \note Should NOT be used with
|
567
|
+
* a module_data_t obtained as part of a module load or unload event.
|
568
|
+
*/
|
569
|
+
void
|
570
|
+
dr_free_module_data(module_data_t *data);
|
571
|
+
|
572
|
+
/**
|
573
|
+
* Returns the preferred name for the module described by \p data from
|
574
|
+
* \p data->module_names.
|
575
|
+
*/
|
576
|
+
const char *
|
577
|
+
dr_module_preferred_name(const module_data_t *data);
|
578
|
+
#ifdef WINDOWS
|
579
|
+
|
580
|
+
|
581
|
+
/**
|
582
|
+
* Optionally also
|
583
|
+
* returns whether \p pc is within a section within the module in \p section_found and
|
584
|
+
* information about that section in \p section_out. \note Not yet available on Linux.
|
585
|
+
* \note Returned module_data_t must be freed with dr_free_module_data().
|
586
|
+
*/
|
587
|
+
bool
|
588
|
+
dr_lookup_module_section(module_handle_t lib,
|
589
|
+
byte *pc, IMAGE_SECTION_HEADER *section_out);
|
590
|
+
#endif /* WINDOWS */
|
591
|
+
|
592
|
+
|
593
|
+
/**
|
594
|
+
* Returns the entry point of the exported function with the given
|
595
|
+
* name in the module with the given base. Returns NULL on failure.
|
596
|
+
* \note On Linux this ignores symbol preemption by other modules and only
|
597
|
+
* examines the specified module.
|
598
|
+
*/
|
599
|
+
generic_func_t
|
600
|
+
dr_get_proc_address(module_handle_t lib, const char *name);
|
601
|
+
/**************************************************
|
602
|
+
* SYSTEM CALL PROCESSING ROUTINES
|
603
|
+
*/
|
604
|
+
|
605
|
+
|
606
|
+
/**
|
607
|
+
* Usable only from a pre-syscall (dr_register_pre_syscall_event())
|
608
|
+
* event. Returns the value of system call parameter number \p param_num.
|
609
|
+
*/
|
610
|
+
reg_t
|
611
|
+
dr_syscall_get_param(void *drcontext, int param_num);
|
612
|
+
|
613
|
+
/**
|
614
|
+
* Usable only from a pre-syscall (dr_register_pre_syscall_event())
|
615
|
+
* event, or from a post-syscall (dr_register_post_syscall_event())
|
616
|
+
* event when also using dr_syscall_invoke_another(). Sets the value
|
617
|
+
* of system call parameter number \p param_num to \p new_value.
|
618
|
+
*/
|
619
|
+
void
|
620
|
+
dr_syscall_set_param(void *drcontext, int param_num, reg_t new_value);
|
621
|
+
|
622
|
+
/**
|
623
|
+
* Usable only from a post-syscall (dr_register_post_syscall_event())
|
624
|
+
* event. Returns the return value of the system call that will be
|
625
|
+
* presented to the application.
|
626
|
+
*/
|
627
|
+
reg_t
|
628
|
+
dr_syscall_get_result(void *drcontext);
|
629
|
+
|
630
|
+
/**
|
631
|
+
* Usable only from a pre-syscall (dr_register_pre_syscall_event()) or
|
632
|
+
* post-syscall (dr_register_post_syscall_event()) event.
|
633
|
+
* For pre-syscall, should only be used when skipping the system call.
|
634
|
+
* This sets the return value of the system call that the application sees
|
635
|
+
* to \p value.
|
636
|
+
*/
|
637
|
+
void
|
638
|
+
dr_syscall_set_result(void *drcontext, reg_t value);
|
639
|
+
|
640
|
+
/**
|
641
|
+
* Usable only from a pre-syscall (dr_register_pre_syscall_event())
|
642
|
+
* event, or from a post-syscall (dr_register_post_syscall_event())
|
643
|
+
* event when also using dr_syscall_invoke_another(). Sets the system
|
644
|
+
* call number of the system call about to be invoked to \p new_num.
|
645
|
+
*/
|
646
|
+
void
|
647
|
+
dr_syscall_set_sysnum(void *drcontext, int new_num);
|
648
|
+
|
649
|
+
/**
|
650
|
+
* Usable only from a post-syscall (dr_register_post_syscall_event())
|
651
|
+
* event. An additional system call will be invoked immediately,
|
652
|
+
* using the current values of the parameters, which can be set with
|
653
|
+
* dr_syscall_set_param(). The system call to be invoked should be
|
654
|
+
* specified with dr_syscall_set_sysnum().
|
655
|
+
*
|
656
|
+
* Use this routine with caution. Especially on Windows, care must be
|
657
|
+
* taken if the application is expected to continue afterward. When
|
658
|
+
* system call parameters are stored on the stack, modifying them can
|
659
|
+
* result in incorrect application behavior, particularly when setting
|
660
|
+
* more parameters than were present in the original system call,
|
661
|
+
* which will result in corruption of the application stack.
|
662
|
+
*
|
663
|
+
* On Windows, when the first system call is interruptible
|
664
|
+
* (alertable), the additional system call may be delayed.
|
665
|
+
*
|
666
|
+
* DR will set key registers such as r10 for 64-bit or xdx for
|
667
|
+
* sysenter or WOW64 system calls. However, DR will not set ecx for
|
668
|
+
* WOW64; that is up to the client.
|
669
|
+
*/
|
670
|
+
void
|
671
|
+
dr_syscall_invoke_another(void *drcontext);
|
672
|
+
|
673
|
+
/**
|
674
|
+
* Creates a new directory. Fails if the directory already exists
|
675
|
+
* or if it can't be created.
|
676
|
+
*/
|
677
|
+
bool
|
678
|
+
dr_create_dir(const char *fname);
|
679
|
+
#ifdef WINDOWS
|
680
|
+
|
681
|
+
|
682
|
+
/** Checks for the existence of a directory. \note Windows only. */
|
683
|
+
bool
|
684
|
+
dr_directory_exists(const char *fname);
|
685
|
+
|
686
|
+
/** Checks the existence of a file. \note Windows only. */
|
687
|
+
bool
|
688
|
+
dr_file_exists(const char *fname);
|
689
|
+
#endif
|
690
|
+
|
691
|
+
|
692
|
+
/* flags for use with dr_open_file() */
|
693
|
+
/** Open with read access. */
|
694
|
+
#define DR_FILE_READ 0x1
|
695
|
+
/** Open with write access, but do not open if the file already exists. */
|
696
|
+
#define DR_FILE_WRITE_REQUIRE_NEW 0x2
|
697
|
+
/**
|
698
|
+
* Open with write access. If the file already exists, set the file position to the
|
699
|
+
* end of the file.
|
700
|
+
*/
|
701
|
+
#define DR_FILE_WRITE_APPEND 0x4
|
702
|
+
/**
|
703
|
+
* Open with write access. If the file already exists, truncate the
|
704
|
+
* file to zero length.
|
705
|
+
*/
|
706
|
+
#define DR_FILE_WRITE_OVERWRITE 0x8
|
707
|
+
/**
|
708
|
+
* Open with large (>2GB) file support. Only applicable on 32-bit Linux.
|
709
|
+
* \note DR's log files and tracedump files are all created with this flag.
|
710
|
+
*/
|
711
|
+
#define DR_FILE_ALLOW_LARGE 0x10
|
712
|
+
|
713
|
+
|
714
|
+
/**
|
715
|
+
* Opens the file \p fname. On Windows, \p fname must be an absolute path.
|
716
|
+
* If no such file exists then one is created.
|
717
|
+
* The file access mode is set by the \p mode_flags argument which is drawn from
|
718
|
+
* the DR_FILE_* defines ORed together. Returns INVALID_FILE if unsuccessful.
|
719
|
+
*
|
720
|
+
* \note No more then one write mode flag can be specified.
|
721
|
+
*
|
722
|
+
* \note DR does not hide files opened by clients from the
|
723
|
+
* application, to allow clients to open application files and other
|
724
|
+
* forms of interaction. Some applications close all file
|
725
|
+
* descriptors, and clients may want to watch for the close system
|
726
|
+
* call and turn it into a nop (e.g., return -EBADF and not execute it
|
727
|
+
* on Linux) if targeting a client-owned filed.
|
728
|
+
*/
|
729
|
+
file_t
|
730
|
+
dr_open_file(const char *fname, uint mode_flags);
|
731
|
+
|
732
|
+
/** Closes file \p f. */
|
733
|
+
void
|
734
|
+
dr_close_file(file_t f);
|
735
|
+
|
736
|
+
/** Flushes any buffers for file \p f. */
|
737
|
+
void
|
738
|
+
dr_flush_file(file_t f);
|
739
|
+
|
740
|
+
/**
|
741
|
+
* Writes \p count bytes from \p buf to file \p f.
|
742
|
+
* Returns the actual number written.
|
743
|
+
*/
|
744
|
+
ssize_t
|
745
|
+
dr_write_file(file_t f, const void *buf, size_t count);
|
746
|
+
|
747
|
+
/**
|
748
|
+
* Reads up to \p count bytes from file \p f into \p buf.
|
749
|
+
* Returns the actual number read.
|
750
|
+
*/
|
751
|
+
ssize_t
|
752
|
+
dr_read_file(file_t f, void *buf, size_t count);
|
753
|
+
|
754
|
+
/* For use with dr_file_seek(), specifies the origin at which to apply the offset. */
|
755
|
+
#define DR_SEEK_SET 0 /**< start of file */
|
756
|
+
#define DR_SEEK_CUR 1 /**< current file position */
|
757
|
+
#define DR_SEEK_END 2 /**< end of file */
|
758
|
+
|
759
|
+
|
760
|
+
/**
|
761
|
+
* Sets the current file position for file \p f to \p offset bytes
|
762
|
+
* from the specfied origin, where \p origin is one of the DR_SEEK_*
|
763
|
+
* values. Returns true if successful.
|
764
|
+
*/
|
765
|
+
bool
|
766
|
+
dr_file_seek(file_t f, int64 offset, int origin);
|
767
|
+
|
768
|
+
/**
|
769
|
+
* Returns the current position for the file \p f in bytes from the start of the file.
|
770
|
+
* Returns -1 on an error.
|
771
|
+
*/
|
772
|
+
int64
|
773
|
+
dr_file_tell(file_t f);
|
774
|
+
|
775
|
+
/**
|
776
|
+
* Returns a new copy of the file handle \p f.
|
777
|
+
* Returns INVALID_FILE on error.
|
778
|
+
*/
|
779
|
+
file_t
|
780
|
+
dr_dup_file_handle(file_t f);
|
781
|
+
|
782
|
+
/**************************************************
|
783
|
+
* PRINTING
|
784
|
+
*/
|
785
|
+
|
786
|
+
|
787
|
+
/**
|
788
|
+
* Writes to DR's log file for the thread with drcontext \p drcontext if the current
|
789
|
+
* loglevel is >= \p level and the current \p logmask & \p mask != 0.
|
790
|
+
* The mask constants are below.
|
791
|
+
* Logging is disabled for the release build.
|
792
|
+
* If \p drcontext is NULL, writes to the main log file.
|
793
|
+
*/
|
794
|
+
void
|
795
|
+
dr_log(void *drcontext, uint mask, uint level, const char *fmt, ...);
|
796
|
+
|
797
|
+
/* The log mask constants */
|
798
|
+
#define LOG_NONE 0x00000000 /**< Log no data. */
|
799
|
+
#define LOG_STATS 0x00000001 /**< Log per-thread and global statistics. */
|
800
|
+
#define LOG_TOP 0x00000002 /**< Log top-level information. */
|
801
|
+
#define LOG_THREADS 0x00000004 /**< Log data related to threads. */
|
802
|
+
#define LOG_SYSCALLS 0x00000008 /**< Log data related to system calls. */
|
803
|
+
#define LOG_ASYNCH 0x00000010 /**< Log data related to signals/callbacks/etc. */
|
804
|
+
#define LOG_INTERP 0x00000020 /**< Log data related to app interpretation. */
|
805
|
+
#define LOG_EMIT 0x00000040 /**< Log data related to emitting code. */
|
806
|
+
#define LOG_LINKS 0x00000080 /**< Log data related to linking code. */
|
807
|
+
#define LOG_CACHE 0x00000100 /**< Log data related to code cache management. */
|
808
|
+
#define LOG_FRAGMENT 0x00000200 /**< Log data related to app code fragments. */
|
809
|
+
#define LOG_DISPATCH 0x00000400 /**< Log data on every context switch dispatch. */
|
810
|
+
#define LOG_MONITOR 0x00000800 /**< Log data related to trace building. */
|
811
|
+
#define LOG_HEAP 0x00001000 /**< Log data related to memory managment. */
|
812
|
+
#define LOG_VMAREAS 0x00002000 /**< Log data related to address space regions. */
|
813
|
+
#define LOG_SYNCH 0x00004000 /**< Log data related to synchronization. */
|
814
|
+
#define LOG_MEMSTATS 0x00008000 /**< Log data related to memory statistics. */
|
815
|
+
#define LOG_OPTS 0x00010000 /**< Log data related to optimizations. */
|
816
|
+
#define LOG_SIDELINE 0x00020000 /**< Log data related to sideline threads. */
|
817
|
+
#define LOG_SYMBOLS 0x00040000 /**< Log data related to app symbols. */
|
818
|
+
#define LOG_RCT 0x00080000 /**< Log data related to indirect transfers. */
|
819
|
+
#define LOG_NT 0x00100000 /**< Log data related to Windows Native API. */
|
820
|
+
#define LOG_HOT_PATCHING 0x00200000 /**< Log data related to hot patching. */
|
821
|
+
#define LOG_HTABLE 0x00400000 /**< Log data related to hash tables. */
|
822
|
+
#define LOG_MODULEDB 0x00800000 /**< Log data related to the module database. */
|
823
|
+
#define LOG_ALL 0x00ffffff /**< Log all data. */
|
824
|
+
|
825
|
+
|
826
|
+
/**
|
827
|
+
* Returns the log file for the thread with drcontext \p drcontext.
|
828
|
+
* If \p drcontext is NULL, returns the main log file.
|
829
|
+
*/
|
830
|
+
file_t
|
831
|
+
dr_get_logfile(void *drcontext);
|
832
|
+
|
833
|
+
/**
|
834
|
+
* Returns true iff the -stderr_mask runtime option is non-zero, indicating
|
835
|
+
* that the user wants notification messages printed to stderr.
|
836
|
+
*/
|
837
|
+
bool
|
838
|
+
dr_is_notify_on(void);
|
839
|
+
|
840
|
+
/** Returns a handle to stdout. */
|
841
|
+
file_t
|
842
|
+
dr_get_stdout_file(void);
|
843
|
+
|
844
|
+
/** Returns a handle to stderr. */
|
845
|
+
file_t
|
846
|
+
dr_get_stderr_file(void);
|
847
|
+
|
848
|
+
/** Returns a handle to stdin. */
|
849
|
+
file_t
|
850
|
+
dr_get_stdin_file(void);
|
851
|
+
#ifdef WINDOWS
|
852
|
+
|
853
|
+
|
854
|
+
/**
|
855
|
+
* Displays a message in a pop-up window. \note Windows only. \note On Windows Vista
|
856
|
+
* most Windows services are unable to display message boxes.
|
857
|
+
*/
|
858
|
+
void
|
859
|
+
dr_messagebox(const char *fmt, ...);
|
860
|
+
#endif
|
861
|
+
|
862
|
+
|
863
|
+
/**
|
864
|
+
* Stdout printing that won't interfere with the
|
865
|
+
* application's own printing. Currently non-buffered.
|
866
|
+
* \note On Windows, this routine does not support printing floating
|
867
|
+
* point values. Use dr_snprintf() instead.
|
868
|
+
* \note If the data to be printed is large it will be truncated to
|
869
|
+
* an internal buffer size.
|
870
|
+
*/
|
871
|
+
void
|
872
|
+
dr_printf(const char *fmt, ...);
|
873
|
+
|
874
|
+
/**
|
875
|
+
* Printing to a file that won't interfere with the
|
876
|
+
* application's own printing. Currently non-buffered.
|
877
|
+
* \note On Windows, this routine does not support printing floating
|
878
|
+
* point values. Use dr_snprintf() instead.
|
879
|
+
* \note If the data to be printed is large it will be truncated to
|
880
|
+
* an internal buffer size. Use dr_write_file() to print large buffers.
|
881
|
+
* \note On Linux this routine does not check for errors like EINTR. Use
|
882
|
+
* dr_write_file() if that is a concern.
|
883
|
+
*/
|
884
|
+
void
|
885
|
+
dr_fprintf(file_t f, const char *fmt, ...);
|
886
|
+
|
887
|
+
/**
|
888
|
+
* Utility routine to print a formatted message to a string. Will not
|
889
|
+
* print more than max characters. If successful, returns the number
|
890
|
+
* of characters printed, not including the terminating null
|
891
|
+
* character. If the number of characters to write equals max, then
|
892
|
+
* the caller is responsible for supplying a terminating null
|
893
|
+
* character. If the number of characters to write exceeds max, then
|
894
|
+
* max characters are written and -1 is returned. If an error
|
895
|
+
* occurs, a negative value is returned.
|
896
|
+
* \note This routine does not support printing wide characters. On
|
897
|
+
* Windows you can use _snprintf() instead (though _snprintf() does
|
898
|
+
* not support printing floating point values).
|
899
|
+
* \note If the data to be printed is large it will be truncated to
|
900
|
+
* an internal buffer size.
|
901
|
+
*/
|
902
|
+
int
|
903
|
+
dr_snprintf(char *buf, size_t max, const char *fmt, ...);
|
904
|
+
|
905
|
+
/** Prints \p msg followed by the instruction \p instr to file \p f. */
|
906
|
+
void
|
907
|
+
dr_print_instr(void *drcontext, file_t f, instr_t *instr, const char *msg);
|
908
|
+
|
909
|
+
/** Prints \p msg followed by the operand \p opnd to file \p f. */
|
910
|
+
void
|
911
|
+
dr_print_opnd(void *drcontext, file_t f, opnd_t opnd, const char *msg);
|
912
|
+
|
913
|
+
/**************************************************
|
914
|
+
* THREAD SUPPORT
|
915
|
+
*/
|
916
|
+
|
917
|
+
|
918
|
+
/**
|
919
|
+
* Returns the DR context of the current thread.
|
920
|
+
* This routine may return NULL during process exit.
|
921
|
+
*/
|
922
|
+
void *
|
923
|
+
dr_get_current_drcontext(void);
|
924
|
+
|
925
|
+
/** Returns the thread id of the thread with drcontext \p drcontext. */
|
926
|
+
thread_id_t
|
927
|
+
dr_get_thread_id(void *drcontext);
|
928
|
+
|
929
|
+
/**
|
930
|
+
* Returns the user-controlled thread-local-storage field. To
|
931
|
+
* generate an instruction sequence that reads the drcontext field
|
932
|
+
* inline in the code cache, use dr_insert_read_tls_field().
|
933
|
+
*/
|
934
|
+
void *
|
935
|
+
dr_get_tls_field(void *drcontext);
|
936
|
+
|
937
|
+
/**
|
938
|
+
* Sets the user-controlled thread-local-storage field. To
|
939
|
+
* generate an instruction sequence that reads the drcontext field
|
940
|
+
* inline in the code cache, use dr_insert_write_tls_field().
|
941
|
+
*/
|
942
|
+
void
|
943
|
+
dr_set_tls_field(void *drcontext, void *value);
|
944
|
+
|
945
|
+
/**
|
946
|
+
* Allocates \p num_slots contiguous thread-local storage slots that
|
947
|
+
* can be directly accessed via an offset from \p segment_register.
|
948
|
+
* These slots will be initialized to 0 for each new thread.
|
949
|
+
* The slot offsets are [\p offset .. \p offset + (num_slots - 1)].
|
950
|
+
* These slots are disjoint from the #dr_spill_slot_t register spill slots
|
951
|
+
* and the client tls field (dr_get_tls_field()).
|
952
|
+
* Returns whether or not the slots were successfully obtained.
|
953
|
+
*
|
954
|
+
* \note These slots are useful for thread-shared code caches. With
|
955
|
+
* thread-private caches, DR's memory pools are guaranteed to be
|
956
|
+
* reachable via absolute or rip-relative accesses from the code cache
|
957
|
+
* and client libraries.
|
958
|
+
*
|
959
|
+
* \note These slots are a limited resource. On Windows the slots are
|
960
|
+
* shared with the application and reserving even one slot can result
|
961
|
+
* in failure to initialize for certain applications. On Linux they
|
962
|
+
* are more plentiful and transparent but currently DR limits clients
|
963
|
+
* to no more than 64 slots.
|
964
|
+
*/
|
965
|
+
bool
|
966
|
+
dr_raw_tls_calloc(OUT reg_id_t *segment_register,
|
967
|
+
OUT uint *offset,
|
968
|
+
IN uint num_slots,
|
969
|
+
IN uint alignment);
|
970
|
+
|
971
|
+
/**
|
972
|
+
* Frees \p num_slots raw thread-local storage slots starting at
|
973
|
+
* offset \p offset that were allocated with dr_raw_tls_calloc().
|
974
|
+
* Returns whether or not the slots were successfully freed.
|
975
|
+
*/
|
976
|
+
bool
|
977
|
+
dr_raw_tls_cfree(uint offset, uint num_slots);
|
978
|
+
|
979
|
+
/** Current thread gives up its time quantum. */
|
980
|
+
void
|
981
|
+
dr_thread_yield(void);
|
982
|
+
|
983
|
+
/**
|
984
|
+
* Suspends all other threads in the process and returns an array of
|
985
|
+
* contexts in \p drcontexts with one context per successfully suspended
|
986
|
+
* threads. The contexts can be passed to routines like dr_get_thread_id()
|
987
|
+
* or dr_get_mcontext(). However, the contexts may not be modified:
|
988
|
+
* dr_set_mcontext() is not supported. dr_get_mcontext() can be called on
|
989
|
+
* the caller of this routine, unless in a Windows nudge callback.
|
990
|
+
*
|
991
|
+
* The number of successfully suspended threads, which is also the length
|
992
|
+
* of the \p drcontexts array, is returned in \p num_suspended, which is a
|
993
|
+
* required parameter. The number of un-successfully suspended threads, if
|
994
|
+
* any, is returned in the optional parameter \p num_unsuspended. The
|
995
|
+
* calling thread is not considered in either count. DR can fail to
|
996
|
+
* suspend a thread for privilege reasons (e.g., on Windows in a
|
997
|
+
* low-privilege process where another process injected a thread). This
|
998
|
+
* function returns true iff all threads were suspended, in which case \p
|
999
|
+
* num_unsuspended will be 0.
|
1000
|
+
*
|
1001
|
+
* The caller must invoke dr_resume_all_other_threads() in order to resume
|
1002
|
+
* the suspended threads, free the \p drcontexts array, and release
|
1003
|
+
* coarse-grain locks that prevent new threads from being created.
|
1004
|
+
*
|
1005
|
+
* This routine may not be called from any registered event callback other
|
1006
|
+
* than the nudge event. It may be called from clean calls out of the
|
1007
|
+
* cache. This routine may not be called while any locks are held that
|
1008
|
+
* could block a thread processing a registered event callback or cache
|
1009
|
+
* callout.
|
1010
|
+
*
|
1011
|
+
* \note A client wishing to invoke this routine from an event callback can
|
1012
|
+
* queue up a nudge via dr_nudge_client() and invoke this routine from the
|
1013
|
+
* nudge callback.
|
1014
|
+
*/
|
1015
|
+
bool
|
1016
|
+
dr_suspend_all_other_threads(OUT void ***drcontexts,
|
1017
|
+
OUT uint *num_suspended,
|
1018
|
+
OUT uint *num_unsuspended);
|
1019
|
+
|
1020
|
+
/**
|
1021
|
+
* May only be used after invoking dr_suspend_all_other_threads(). This
|
1022
|
+
* routine resumes the threads that were suspended by
|
1023
|
+
* dr_suspend_all_other_threads() and must be passed the same array and
|
1024
|
+
* count of suspended threads that were returned by
|
1025
|
+
* dr_suspend_all_other_threads(). It also frees the \p drcontexts array
|
1026
|
+
* and releases the locks acquired by dr_suspend_all_other_threads(). The
|
1027
|
+
* return value indicates whether all resumption attempts were successful.
|
1028
|
+
*/
|
1029
|
+
bool
|
1030
|
+
dr_resume_all_other_threads(IN void **drcontexts,
|
1031
|
+
IN uint num_suspended);
|
1032
|
+
|
1033
|
+
/****************************************************************************
|
1034
|
+
* ADAPTIVE OPTIMIZATION SUPPORT
|
1035
|
+
*/
|
1036
|
+
|
1037
|
+
|
1038
|
+
/**
|
1039
|
+
* Replaces the fragment with tag \p tag with the instructions in \p
|
1040
|
+
* ilist. This routine is only valid with the -thread_private option;
|
1041
|
+
* it replaces the fragment for the current thread only. After
|
1042
|
+
* replacement, the existing fragment is allowed to complete if
|
1043
|
+
* currently executing. For example, a clean call replacing the
|
1044
|
+
* currently executing fragment will safely return to the existing
|
1045
|
+
* code. Subsequent executions will use the new instructions.
|
1046
|
+
*
|
1047
|
+
* \note The routine takes control of \p ilist and all responsibility
|
1048
|
+
* for deleting it. The client should not keep, use, or reference,
|
1049
|
+
* the instrlist or any of the instrs it contains after passing.
|
1050
|
+
*
|
1051
|
+
* \note This routine supports replacement for the current thread
|
1052
|
+
* only. \p drcontext must be from the current thread and must
|
1053
|
+
* be the drcontext used to create the instruction list.
|
1054
|
+
*
|
1055
|
+
* \return false if the fragment does not exist and true otherwise.
|
1056
|
+
*/
|
1057
|
+
bool
|
1058
|
+
dr_replace_fragment(void *drcontext, void *tag, instrlist_t *ilist);
|
1059
|
+
|
1060
|
+
/**
|
1061
|
+
* Deletes the fragment with tag \p tag. This routine is only valid
|
1062
|
+
* with the -thread_private option; it deletes the fragment in the
|
1063
|
+
* current thread only. After deletion, the existing fragment is
|
1064
|
+
* allowed to complete execution. For example, a clean call deleting
|
1065
|
+
* the currently executing fragment will safely return to the existing
|
1066
|
+
* code. Subsequent executions will cause \DynamoRIO to reconstruct
|
1067
|
+
* the fragment, and therefore call the appropriate fragment-creation
|
1068
|
+
* event hook, if registered.
|
1069
|
+
*
|
1070
|
+
* \note This routine supports deletion for the current thread
|
1071
|
+
* only. \p drcontext must be from the current thread and must
|
1072
|
+
* be the drcontext used to create the instruction list.
|
1073
|
+
*
|
1074
|
+
* \return false if the fragment does not exist and true otherwise.
|
1075
|
+
*/
|
1076
|
+
bool
|
1077
|
+
dr_delete_fragment(void *drcontext, void *tag);
|
1078
|
+
|
1079
|
+
/**
|
1080
|
+
* Flush all fragments containing any code from the region [\p start, \p start + \p size).
|
1081
|
+
* Once this routine returns no execution will occur out of the fragments flushed.
|
1082
|
+
* This routine may only be called during a clean call from the cache or from a nudge
|
1083
|
+
* event handler. It may not be called from any other event callback. No locks can
|
1084
|
+
* held when calling this routine. If called from a clean call, caller can NOT return
|
1085
|
+
* to the cache (the fragment that was called out of may have been flushed even if it
|
1086
|
+
* doesn't apparently overlap the flushed region). Instead the caller must call
|
1087
|
+
* dr_redirect_execution() after this routine to continue execution. Returns true if
|
1088
|
+
* successful.
|
1089
|
+
*
|
1090
|
+
* \note This routine may not be called from any registered event callback other than
|
1091
|
+
* the nudge event; clean calls out of the cache may call this routine.
|
1092
|
+
* \note If called from a clean call, caller must continue execution by calling
|
1093
|
+
* dr_redirect_execution() after this routine, as the fragment containing the callout may
|
1094
|
+
* have been flushed. The context and app_errno to use can be obtained via
|
1095
|
+
* dr_get_mcontext() with the exception of the pc to continue at which must be passed as
|
1096
|
+
* an argument to the callout (see instr_get_app_pc()) or otherwise determined.
|
1097
|
+
* \note This routine may not be called while any locks are held that could block a thread
|
1098
|
+
* processing a registered event callback or cache callout.
|
1099
|
+
* \note dr_delay_flush_region() has fewer restrictions on use, but is less synchronous.
|
1100
|
+
* \note Use \p size == 1 to flush fragments containing the instruction at address
|
1101
|
+
* \p start. A flush of \p size == 0 is not allowed.
|
1102
|
+
* \note As currently implemented, dr_delay_flush_region() with no completion callback
|
1103
|
+
* routine specified can be substantially more performant.
|
1104
|
+
*/
|
1105
|
+
bool
|
1106
|
+
dr_flush_region(app_pc start, size_t size);
|
1107
|
+
|
1108
|
+
/**
|
1109
|
+
* Flush all fragments containing any code from the region [\p start, \p start + \p size).
|
1110
|
+
* Control will not enter a fragment containing code from the region after this returns,
|
1111
|
+
* but a thread already in such a fragment will finish out the fragment. This includes
|
1112
|
+
* the current thread if this is called from a clean call that returns to the cache.
|
1113
|
+
* This routine may only be called during a clean call from the cache or from a nudge
|
1114
|
+
* event handler. It may not be called from any other event callback. No locks can be
|
1115
|
+
* held when calling this routine. Returns true if successful.
|
1116
|
+
*
|
1117
|
+
* \note This routine may not be called from any registered event callback other than
|
1118
|
+
* the nudge event; clean calls out of the cache may call this routine.
|
1119
|
+
* \note This routine may not be called while any locks are held that could block a thread
|
1120
|
+
* processing a registered event callback or cache callout.
|
1121
|
+
* \note dr_delay_flush_region() has fewer restrictions on use, but is less synchronous.
|
1122
|
+
* \note Use \p size == 1 to flush fragments containing the instruction at address
|
1123
|
+
* \p start. A flush of \p size == 0 is not allowed.
|
1124
|
+
* \note This routine is only available with either the -thread_private
|
1125
|
+
* or -enable_full_api options. It is not available when -opt_memory is specified.
|
1126
|
+
*/
|
1127
|
+
bool
|
1128
|
+
dr_unlink_flush_region(app_pc start, size_t size);
|
1129
|
+
|
1130
|
+
/**
|
1131
|
+
* Request a flush of all fragments containing code from the region
|
1132
|
+
* [\p start, \p start + \p size). The flush will be performed at the next safe
|
1133
|
+
* point in time (usually before any new code is added to the cache after this
|
1134
|
+
* routine is called). If \p flush_completion_callback is non-NULL, it will be
|
1135
|
+
* called with the \p flush_id provided to this routine when the flush completes,
|
1136
|
+
* after which no execution will occur out of the fragments flushed. Returns true
|
1137
|
+
* if the flush was successfully queued.
|
1138
|
+
*
|
1139
|
+
* \note dr_flush_region() and dr_unlink_flush_region() can give stronger guarantees on
|
1140
|
+
* when the flush will occur, but have more restrictions on use.
|
1141
|
+
* \note Use \p size == 1 to flush fragments containing the instruction at address
|
1142
|
+
* \p start. A flush of \p size == 0 is not allowed.
|
1143
|
+
* \note As currently implemented there may be a performance penalty for requesting a
|
1144
|
+
* \p flush_completion_callback; for most performant usage set
|
1145
|
+
* \p flush_completion_callback to NULL.
|
1146
|
+
*/
|
1147
|
+
bool
|
1148
|
+
dr_delay_flush_region(app_pc start, size_t size, uint flush_id,
|
1149
|
+
void (*flush_completion_callback) (int flush_id));
|
1150
|
+
|
1151
|
+
/** Returns whether or not there is a fragment in code cache with tag \p tag. */
|
1152
|
+
bool
|
1153
|
+
dr_fragment_exists_at(void *drcontext, void *tag);
|
1154
|
+
|
1155
|
+
/**
|
1156
|
+
* Returns true if a basic block with tag \p tag exists in the code cache.
|
1157
|
+
*/
|
1158
|
+
bool
|
1159
|
+
dr_bb_exists_at(void *drcontext, void *tag);
|
1160
|
+
|
1161
|
+
/**
|
1162
|
+
* Looks up the fragment with tag \p tag.
|
1163
|
+
* If not found, returns 0.
|
1164
|
+
* If found, returns the total size occupied in the cache by the fragment.
|
1165
|
+
*/
|
1166
|
+
uint
|
1167
|
+
dr_fragment_size(void *drcontext, void *tag);
|
1168
|
+
|
1169
|
+
/** Retrieves the application PC of a fragment with tag \p tag. */
|
1170
|
+
app_pc
|
1171
|
+
dr_fragment_app_pc(void *tag);
|
1172
|
+
|
1173
|
+
/****************************************************************************
|
1174
|
+
* CUSTOM TRACE SUPPORT
|
1175
|
+
*/
|
1176
|
+
|
1177
|
+
|
1178
|
+
|
1179
|
+
/**
|
1180
|
+
* Marks the fragment associated with tag \p tag as
|
1181
|
+
* a trace head. The fragment need not exist yet -- once it is
|
1182
|
+
* created it will be marked as a trace head.
|
1183
|
+
*
|
1184
|
+
* DR associates a counter with a trace head and once it
|
1185
|
+
* passes the -hot_threshold parameter, DR begins building
|
1186
|
+
* a trace. Before each fragment is added to the trace, DR
|
1187
|
+
* calls the client's end_trace callback to determine whether
|
1188
|
+
* to end the trace. (The callback will be called both for
|
1189
|
+
* standard DR traces and for client-defined traces.)
|
1190
|
+
*
|
1191
|
+
* \note Some fragments are unsuitable for trace heads. DR will
|
1192
|
+
* ignore attempts to mark such fragments as trace heads and will return
|
1193
|
+
* false. If the client marks a fragment that doesn't exist yet as a trace
|
1194
|
+
* head and DR later determines that the fragment is unsuitable for
|
1195
|
+
* a trace head it will unmark the fragment as a trace head without
|
1196
|
+
* notifying the client.
|
1197
|
+
*
|
1198
|
+
* \note Some fragments' notion of trace heads is dependent on
|
1199
|
+
* which previous block targets them. For these fragments, calling
|
1200
|
+
* this routine will only mark as a trace head for targets from
|
1201
|
+
* the same memory region.
|
1202
|
+
*
|
1203
|
+
* Returns true if the target fragment is marked as a trace head.
|
1204
|
+
*/
|
1205
|
+
bool
|
1206
|
+
dr_mark_trace_head(void *drcontext, void *tag);
|
1207
|
+
|
1208
|
+
/**
|
1209
|
+
* Checks to see if the fragment (or future fragment) with tag \p tag
|
1210
|
+
* is marked as a trace head.
|
1211
|
+
*/
|
1212
|
+
bool
|
1213
|
+
dr_trace_head_at(void *drcontext, void *tag);
|
1214
|
+
|
1215
|
+
/** Checks to see that if there is a trace in the code cache at tag \p tag. */
|
1216
|
+
bool
|
1217
|
+
dr_trace_exists_at(void *drcontext, void *tag);
|
1218
|
+
|
1219
|
+
/****************************************************************************
|
1220
|
+
* BINARY TRACE DUMP FORMAT
|
1221
|
+
*/
|
1222
|
+
|
1223
|
+
/**<pre>
|
1224
|
+
* Binary trace dump format:
|
1225
|
+
* the file starts with a tracedump_file_header_t
|
1226
|
+
* then, for each trace:
|
1227
|
+
struct _tracedump_trace_header
|
1228
|
+
if num_bbs > 0 # tracedump_origins
|
1229
|
+
foreach bb:
|
1230
|
+
app_pc tag;
|
1231
|
+
int bb_code_size;
|
1232
|
+
byte code[bb_code_size];
|
1233
|
+
endif
|
1234
|
+
foreach exit:
|
1235
|
+
struct _tracedump_stub_data
|
1236
|
+
if linkcount_size > 0
|
1237
|
+
linkcount_type_t count; # sizeof == linkcount_size
|
1238
|
+
endif
|
1239
|
+
if separate from body
|
1240
|
+
(i.e., exit_stub < cache_start_pc || exit_stub >= cache_start_pc+code_size):
|
1241
|
+
byte stub_code[15]; # all separate stubs are 15
|
1242
|
+
endif
|
1243
|
+
endfor
|
1244
|
+
byte code[code_size];
|
1245
|
+
* if the -tracedump_threshold option (deprecated) was specified:
|
1246
|
+
int num_below_treshold
|
1247
|
+
linkcount_type_t count_below_threshold
|
1248
|
+
endif
|
1249
|
+
</pre>
|
1250
|
+
*/
|
1251
|
+
typedef struct _tracedump_file_header_t {
|
1252
|
+
int version; /**< The DynamoRIO version that created the file. */
|
1253
|
+
bool x64; /**< Whether a 64-bit DynamoRIO library created the file. */
|
1254
|
+
int linkcount_size; /**< Size of the linkcount (linkcounts are deprecated). */
|
1255
|
+
} tracedump_file_header_t;
|
1256
|
+
|
1257
|
+
/** Header for an individual trace in a binary trace dump file. */
|
1258
|
+
typedef struct _tracedump_trace_header_t {
|
1259
|
+
int frag_id; /**< Identifier for the trace. */
|
1260
|
+
app_pc tag; /**< Application address for start of trace. */
|
1261
|
+
app_pc cache_start_pc; /**< Code cache address of start of trace. */
|
1262
|
+
int entry_offs; /**< Offset into trace of normal entry. */
|
1263
|
+
int num_exits; /**< Number of exits from the trace. */
|
1264
|
+
int code_size; /**< Length of the trace in the code cache. */
|
1265
|
+
uint num_bbs; /**< Number of constituent basic blocks making up the trace. */
|
1266
|
+
bool x64; /**< Whether the trace contains 64-bit code. */
|
1267
|
+
} tracedump_trace_header_t;
|
1268
|
+
|
1269
|
+
/** Size of tag + bb_code_size fields for each bb. */
|
1270
|
+
#define BB_ORIGIN_HEADER_SIZE (sizeof(app_pc)+sizeof(int))
|
1271
|
+
|
1272
|
+
/**< tracedump_stub_data_t.stub_size will not exceed this value. */
|
1273
|
+
#define SEPARATE_STUB_MAX_SIZE IF_X64_ELSE(23, 15)
|
1274
|
+
|
1275
|
+
/** The format of a stub in a trace dump file. */
|
1276
|
+
typedef struct _tracedump_stub_data {
|
1277
|
+
int cti_offs; /**< Offset from the start of the fragment. */
|
1278
|
+
/* stub_pc is an absolute address, since can be separate from body. */
|
1279
|
+
app_pc stub_pc; /**< Code cache address of the stub. */
|
1280
|
+
app_pc target; /**< Target of the stub. */
|
1281
|
+
bool linked; /**< Whether the stub is linked to its target. */
|
1282
|
+
int stub_size; /**< Length of stub_code array */
|
1283
|
+
/****** the rest of the fields are optional and may not be present! ******/
|
1284
|
+
union {
|
1285
|
+
uint count32; /**< 32-bit exit execution count. */
|
1286
|
+
uint64 count64; /**< 64-bit exit execution count. */
|
1287
|
+
} count; /**< Which field is present depends on the first entry in
|
1288
|
+
* the file, which indicates the linkcount size. */
|
1289
|
+
/** Code for exit stubs. Only present if:
|
1290
|
+
* stub_pc < cache_start_pc ||
|
1291
|
+
* stub_pc >= cache_start_pc+code_size).
|
1292
|
+
* The actual size of the array varies and is indicated by the stub_size field.
|
1293
|
+
*/
|
1294
|
+
byte stub_code[1/*variable-sized*/];
|
1295
|
+
} tracedump_stub_data_t;
|
1296
|
+
|
1297
|
+
/** The last offset into tracedump_stub_data_t of always-present fields. */
|
1298
|
+
#define STUB_DATA_FIXED_SIZE (offsetof(tracedump_stub_data_t, count))
|
1299
|
+
|
1300
|
+
/****************************************************************************/
|
1301
|
+
|
1302
|
+
|
1303
|
+
|
1304
|
+
#endif /* _DR_TOOLS_H_ */
|