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.
Files changed (41) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +11 -0
  3. data/Rakefile +29 -0
  4. data/VERSION +1 -0
  5. data/client_src/dr_include/dr_api.h +102 -0
  6. data/client_src/dr_include/dr_app.h +92 -0
  7. data/client_src/dr_include/dr_config.h +650 -0
  8. data/client_src/dr_include/dr_defines.h +391 -0
  9. data/client_src/dr_include/dr_events.h +1057 -0
  10. data/client_src/dr_include/dr_ir_instr.h +1214 -0
  11. data/client_src/dr_include/dr_ir_instrlist.h +149 -0
  12. data/client_src/dr_include/dr_ir_macros.h +2426 -0
  13. data/client_src/dr_include/dr_ir_opcodes.h +768 -0
  14. data/client_src/dr_include/dr_ir_opnd.h +1170 -0
  15. data/client_src/dr_include/dr_ir_utils.h +708 -0
  16. data/client_src/dr_include/dr_proc.h +327 -0
  17. data/client_src/dr_include/dr_tools.h +1304 -0
  18. data/client_src/duran.c +57 -0
  19. data/client_src/extconf.rb +28 -0
  20. data/lib/duran.rb +18 -0
  21. data/lib/duran/app.rb +8 -0
  22. data/lib/duran/defines.rb +39 -0
  23. data/lib/duran/events.rb +156 -0
  24. data/lib/duran/ir_opcodes.rb +616 -0
  25. data/lib/duran/ir_opnd.rb +329 -0
  26. data/lib/duran/ir_utils.rb +133 -0
  27. data/lib/duran/proc.rb +49 -0
  28. data/lib/duran/structs.rb +20 -0
  29. data/lib/duran/structs/exception.rb +23 -0
  30. data/lib/duran/structs/fault_fragment_info.rb +34 -0
  31. data/lib/duran/structs/instruction.rb +15 -0
  32. data/lib/duran/structs/machine_context.rb +80 -0
  33. data/lib/duran/structs/memory_info.rb +12 -0
  34. data/lib/duran/structs/module_data.rb +61 -0
  35. data/lib/duran/structs/module_names.rb +24 -0
  36. data/lib/duran/structs/operand.rb +15 -0
  37. data/lib/duran/structs/restore_state_info.rb +30 -0
  38. data/lib/duran/structs/signal_info.rb +41 -0
  39. data/lib/duran/structs/tracedump.rb +50 -0
  40. data/lib/duran/tools.rb +214 -0
  41. metadata +104 -0
@@ -0,0 +1,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_ */