duran 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +11 -0
  3. data/Rakefile +29 -0
  4. data/VERSION +1 -0
  5. data/client_src/dr_include/dr_api.h +102 -0
  6. data/client_src/dr_include/dr_app.h +92 -0
  7. data/client_src/dr_include/dr_config.h +650 -0
  8. data/client_src/dr_include/dr_defines.h +391 -0
  9. data/client_src/dr_include/dr_events.h +1057 -0
  10. data/client_src/dr_include/dr_ir_instr.h +1214 -0
  11. data/client_src/dr_include/dr_ir_instrlist.h +149 -0
  12. data/client_src/dr_include/dr_ir_macros.h +2426 -0
  13. data/client_src/dr_include/dr_ir_opcodes.h +768 -0
  14. data/client_src/dr_include/dr_ir_opnd.h +1170 -0
  15. data/client_src/dr_include/dr_ir_utils.h +708 -0
  16. data/client_src/dr_include/dr_proc.h +327 -0
  17. data/client_src/dr_include/dr_tools.h +1304 -0
  18. data/client_src/duran.c +57 -0
  19. data/client_src/extconf.rb +28 -0
  20. data/lib/duran.rb +18 -0
  21. data/lib/duran/app.rb +8 -0
  22. data/lib/duran/defines.rb +39 -0
  23. data/lib/duran/events.rb +156 -0
  24. data/lib/duran/ir_opcodes.rb +616 -0
  25. data/lib/duran/ir_opnd.rb +329 -0
  26. data/lib/duran/ir_utils.rb +133 -0
  27. data/lib/duran/proc.rb +49 -0
  28. data/lib/duran/structs.rb +20 -0
  29. data/lib/duran/structs/exception.rb +23 -0
  30. data/lib/duran/structs/fault_fragment_info.rb +34 -0
  31. data/lib/duran/structs/instruction.rb +15 -0
  32. data/lib/duran/structs/machine_context.rb +80 -0
  33. data/lib/duran/structs/memory_info.rb +12 -0
  34. data/lib/duran/structs/module_data.rb +61 -0
  35. data/lib/duran/structs/module_names.rb +24 -0
  36. data/lib/duran/structs/operand.rb +15 -0
  37. data/lib/duran/structs/restore_state_info.rb +30 -0
  38. data/lib/duran/structs/signal_info.rb +41 -0
  39. data/lib/duran/structs/tracedump.rb +50 -0
  40. data/lib/duran/tools.rb +214 -0
  41. metadata +104 -0
@@ -0,0 +1,708 @@
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_IR_UTILS_H_
34
+ #define _DR_IR_UTILS_H_ 1
35
+
36
+ #ifdef X64
37
+
38
+
39
+ /**
40
+ * The decode and encode routines use a per-thread persistent flag that
41
+ * indicates whether to treat code as 32-bit (x86) or 64-bit (x64). This
42
+ * routine sets that flag to the indicated value and returns the old value. Be
43
+ * sure to restore the old value prior to any further application execution to
44
+ * avoid problems in mis-interpreting application code.
45
+ *
46
+ * \note For 64-bit DR builds only.
47
+ */
48
+ bool
49
+ set_x86_mode(void *drcontext, bool x86);
50
+
51
+ /**
52
+ * The decode and encode routines use a per-thread persistent flag that
53
+ * indicates whether to treat code as 32-bit (x86) or 64-bit (x64). This
54
+ * routine returns the value of that flag.
55
+ *
56
+ * \note For 64-bit DR builds only.
57
+ */
58
+ bool
59
+ get_x86_mode(void *drcontext);
60
+ #endif
61
+
62
+
63
+ /**************************************************
64
+ * CODE TRANSFORMATION UTILITIES
65
+ */
66
+ /**
67
+ * @file dr_ir_utils.h
68
+ * @brief Code transformation utilities.
69
+ */
70
+
71
+ /**
72
+ * An enum of spill slots to use with dr_save_reg(), dr_restore_reg(),
73
+ * dr_save_arith_flags(), dr_restore_arith_flags() and
74
+ * dr_insert_mbr_instrumentation(). Values stored in spill slots remain
75
+ * valid only until the next non-meta (i.e. application) instruction. Spill slots
76
+ * can be accessed/modifed during clean calls and restore_state_events (see
77
+ * dr_register_restore_state_event()) with dr_read_saved_reg() and
78
+ * dr_write_saved_reg().
79
+ *
80
+ * Spill slots <= dr_max_opnd_accessible_spill_slot() can be directly accessed
81
+ * from client inserted instructions with dr_reg_spill_slot_opnd().
82
+ *
83
+ * \note Some spill slots may be faster to access than others. Currently spill
84
+ * slots 1-3 are significantly faster to access than the others when running
85
+ * without -thread_private. When running with -thread_private all spill slots
86
+ * are expected to have similar performance. This is subject to change in future
87
+ * releases, but clients may assume that smaller numbered spill slots are faster
88
+ * or the same cost to access as larger numbered spill slots.
89
+ *
90
+ * \note The number of spill slots may change in future releases.
91
+ */
92
+ typedef enum {
93
+ SPILL_SLOT_1 = 0, /** spill slot for register save/restore routines */
94
+ SPILL_SLOT_2 = 1, /** spill slot for register save/restore routines */
95
+ SPILL_SLOT_3 = 2, /** spill slot for register save/restore routines */
96
+ SPILL_SLOT_4 = 3, /** spill slot for register save/restore routines */
97
+ SPILL_SLOT_5 = 4, /** spill slot for register save/restore routines */
98
+ SPILL_SLOT_6 = 5, /** spill slot for register save/restore routines */
99
+ SPILL_SLOT_7 = 6, /** spill slot for register save/restore routines */
100
+ SPILL_SLOT_8 = 7, /** spill slot for register save/restore routines */
101
+ SPILL_SLOT_9 = 8, /** spill slot for register save/restore routines */
102
+ #ifdef X64
103
+ SPILL_SLOT_10 = 9, /** spill slot for register save/restore routines
104
+ * \note x64 only */
105
+ SPILL_SLOT_11 = 10, /** spill slot for register save/restore routines
106
+ * \note x64 only */
107
+ SPILL_SLOT_12 = 11, /** spill slot for register save/restore routines
108
+ * \note x64 only */
109
+ SPILL_SLOT_13 = 12, /** spill slot for register save/restore routines
110
+ * \note x64 only */
111
+ SPILL_SLOT_14 = 13, /** spill slot for register save/restore routines
112
+ * \note x64 only */
113
+ SPILL_SLOT_15 = 14, /** spill slot for register save/restore routines
114
+ * \note x64 only */
115
+ SPILL_SLOT_16 = 15, /** spill slot for register save/restore routines
116
+ * \note x64 only */
117
+ SPILL_SLOT_17 = 16, /** spill slot for register save/restore routines
118
+ * \note x64 only */
119
+ SPILL_SLOT_MAX = SPILL_SLOT_17 /** Enum value of the last register save/restore
120
+ * spill slot. */
121
+ #else
122
+ SPILL_SLOT_MAX = SPILL_SLOT_9 /** Enum value of the last register save/restore
123
+ * spill slot. */
124
+ #endif
125
+ } dr_spill_slot_t;
126
+
127
+
128
+ /**
129
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to save the
130
+ * register \p reg in the spill slot \p slot. See dr_restore_reg(). Use
131
+ * dr_read_saved_reg() and dr_write_saved_reg() to access spill slots from clean
132
+ * calls and restore_state_events (see dr_register_restore_state_event()).
133
+ * \note The stored value remains available only until the next non-meta (i.e.
134
+ * application) instruction. Use dr_insert_write_tls_field() and
135
+ * dr_insert_read_tls_field() for a persistent (but more costly to access)
136
+ * thread-local-storage location. See also dr_raw_tls_calloc().
137
+ */
138
+ void
139
+ dr_save_reg(void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg,
140
+ dr_spill_slot_t slot);
141
+
142
+ /**
143
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to restore the
144
+ * register \p reg from the spill slot \p slot. See dr_save_reg() for notes on
145
+ * lifetime and alternative access to spill slots.
146
+ */
147
+ void
148
+ dr_restore_reg(void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg,
149
+ dr_spill_slot_t slot);
150
+
151
+ /**
152
+ * Returns the largest dr_spill_slot_t that can be accessed with an opnd_t from
153
+ * dr_reg_spill_slot_opnd().
154
+ */
155
+ dr_spill_slot_t
156
+ dr_max_opnd_accessible_spill_slot(void);
157
+
158
+ /**
159
+ * Returns an opnd_t that directly accesses the spill slot \p slot. Only slots
160
+ * <= dr_max_opnd_accessible_spill_slot() can be used with this routine.
161
+ * \note \p slot must be <= dr_max_opnd_accessible_spill_slot()
162
+ */
163
+ opnd_t
164
+ dr_reg_spill_slot_opnd(void *drcontext, dr_spill_slot_t slot);
165
+
166
+ /**
167
+ * Can be used from a clean call or a restore_state_event (see
168
+ * dr_register_restore_state_event()) to see the value saved in spill slot
169
+ * \p slot by dr_save_reg().
170
+ */
171
+ reg_t
172
+ dr_read_saved_reg(void *drcontext, dr_spill_slot_t slot);
173
+
174
+ /**
175
+ * Can be used from a clean call to modify the value saved in the spill slot
176
+ * \p slot by dr_save_reg() such that a later dr_restore_reg() will see the
177
+ * new value.
178
+ *
179
+ * \note This routine should only be used during a clean call out of the
180
+ * cache. Use at any other time could corrupt application or \DynamoRIO
181
+ * state.
182
+ */
183
+ void
184
+ dr_write_saved_reg(void *drcontext, dr_spill_slot_t slot, reg_t value);
185
+
186
+ /**
187
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to save the 6
188
+ * arithmetic flags into xax after first saving xax to the spill slot \p slot.
189
+ * This is equivalent to dr_save_reg() of xax to \p slot followed by lahf and
190
+ * seto al instructions. See dr_restore_arith_flags().
191
+ *
192
+ * \note At completion of the inserted instructions the saved flags are in the
193
+ * xax register. The xax register should not be modified after using this
194
+ * routine unless it is first saved (and later restored prior to
195
+ * using dr_restore_arith_flags()).
196
+ */
197
+ void
198
+ dr_save_arith_flags(void *drcontext, instrlist_t *ilist, instr_t *where,
199
+ dr_spill_slot_t slot);
200
+
201
+ /**
202
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to restore the 6
203
+ * arithmetic flags, assuming they were saved using dr_save_arith_flags() with
204
+ * slot \p slot and that xax holds the same value it did after the save.
205
+ */
206
+ void
207
+ dr_restore_arith_flags(void *drcontext, instrlist_t *ilist, instr_t *where,
208
+ dr_spill_slot_t slot);
209
+
210
+ /**
211
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to read into the
212
+ * general-purpose full-size register \p reg from the user-controlled drcontext
213
+ * field for this thread. Reads from the same field as dr_get_tls_field().
214
+ */
215
+ void
216
+ dr_insert_read_tls_field(void *drcontext, instrlist_t *ilist, instr_t *where,
217
+ reg_id_t reg);
218
+
219
+ /**
220
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to write the
221
+ * general-purpose full-size register \p reg to the user-controlled drcontext field
222
+ * for this thread. Writes to the same field as dr_set_tls_field().
223
+ */
224
+ void
225
+ dr_insert_write_tls_field(void *drcontext, instrlist_t *ilist, instr_t *where,
226
+ reg_id_t reg);
227
+
228
+ /** Inserts \p instr as a non-application instruction into \p ilist prior to \p where. */
229
+ void
230
+ instrlist_meta_preinsert(instrlist_t *ilist, instr_t *where, instr_t *instr);
231
+
232
+ /** Inserts \p instr as a non-application instruction into \p ilist after \p where. */
233
+ void
234
+ instrlist_meta_postinsert(instrlist_t *ilist, instr_t *where, instr_t *instr);
235
+
236
+ /** Inserts \p instr as a non-application instruction onto the end of \p ilist */
237
+ void
238
+ instrlist_meta_append(instrlist_t *ilist, instr_t *instr);
239
+
240
+ /**
241
+ * Inserts \p instr as a non-application instruction that can fault (see
242
+ * instr_set_meta_may_fault()) into \p ilist prior to \p where.
243
+ */
244
+ void
245
+ instrlist_meta_fault_preinsert(instrlist_t *ilist, instr_t *where, instr_t *instr);
246
+
247
+ /**
248
+ * Inserts \p instr as a non-application instruction that can fault (see
249
+ * instr_set_meta_may_fault()) into \p ilist after \p where.
250
+ */
251
+ void
252
+ instrlist_meta_fault_postinsert(instrlist_t *ilist, instr_t *where, instr_t *instr);
253
+
254
+ /**
255
+ * Inserts \p instr as a non-application instruction that can fault (see
256
+ * instr_set_meta_may_fault()) onto the end of \p ilist.
257
+ */
258
+ void
259
+ instrlist_meta_fault_append(instrlist_t *ilist, instr_t *instr);
260
+
261
+ /**
262
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to save state
263
+ * for a call, switch to this thread's DR stack, set up the passed-in
264
+ * parameters, make a call to \p callee, clean up the parameters, and
265
+ * then restore the saved state.
266
+ *
267
+ * The callee must use the standard C calling convention that matches the
268
+ * underlying 32-bit or 64-bit binary interface convention ("cdecl"). Other
269
+ * calling conventions, such as "fastcall" and "stdcall", are not supported.
270
+ *
271
+ * Stores the application state information on the DR stack, where it can
272
+ * be accessed from \c callee using dr_get_mcontext() and modified using
273
+ * dr_set_mcontext().
274
+ *
275
+ * If \p save_fpstate is true, preserves the fp/mmx/sse state on the DR stack.
276
+ * Note that it is relatively expensive to save this state (on the
277
+ * order of 200 cycles) and that it typically takes 512 bytes to store
278
+ * it (see proc_fpstate_save_size()).
279
+ *
280
+ * DR does support translating a fault in an argument (e.g., an
281
+ * argument that references application memory); such a fault will be
282
+ * treated as an application exception.
283
+ *
284
+ * \note The stack used to save state and call \p callee is limited to
285
+ * 20KB by default; this can be changed with the -stack_size DR runtime
286
+ * parameter. This stack cannot be used to store state that persists
287
+ * beyond \c callee's return point.
288
+ *
289
+ * \note This routine only supports passing arguments that are
290
+ * integers or pointers of a size equal to the register size: i.e., no
291
+ * floating-point, multimedia, or aggregate data types.
292
+ * The routine also supports immediate integers that are smaller than
293
+ * the register size, and for 64-bit mode registers or memory references that
294
+ * are OPSZ_4.
295
+ *
296
+ * \note For 64-bit mode, passing arguments that use calling
297
+ * convention registers (for Windows, RCX, RDX, R8, R9; for Linux,
298
+ * RDI, RSI, RDX, RCX, R8 and R9) are supported but may incur
299
+ * additional stack usage.
300
+ *
301
+ * \note For 64-bit mode, if a 32-bit immediate integer is specified as an
302
+ * argument and it has its top bit set, we assume it is intended to be
303
+ * sign-extended to 64-bits; otherwise we zero-extend it.
304
+ *
305
+ * \note For 64-bit mode, variable-sized argument operands may not work
306
+ * properly.
307
+ *
308
+ * \note Arguments that reference sub-register portions of REG_XSP are
309
+ * not supported (full REG_XSP is supported).
310
+ */
311
+ void
312
+ dr_insert_clean_call(void *drcontext, instrlist_t *ilist, instr_t *where,
313
+ void *callee, bool save_fpstate, uint num_args, ...);
314
+
315
+ /**
316
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to set
317
+ * up the passed-in parameters, make a call to \p callee, and clean up
318
+ * the parameters.
319
+ *
320
+ * The callee must use the standard C calling convention that matches the
321
+ * underlying 32-bit or 64-bit binary interface convention ("cdecl"). Other
322
+ * calling conventions, such as "fastcall" and "stdcall", are not supported.
323
+ *
324
+ * This routine uses the existing stack. In 64-bit mode, this routine assumes
325
+ * that the stack pointer is currently 16-byte aligned.
326
+ *
327
+ * The application state is NOT saved or restored (use dr_prepare_for_call()
328
+ * and dr_cleanup_after_call(), or replace this routine with dr_insert_clean_call()).
329
+ * The parameter set-up may write to registers if the calling convention so
330
+ * dictates. The registers are NOT saved beforehand (to do so, use
331
+ * dr_insert_clean_call()).
332
+ *
333
+ * It is up to the caller of this routine to preserve caller-saved registers.
334
+ *
335
+ * DR does not support translating a fault in an argument. For fault
336
+ * transparency, the client must perform the translation (see
337
+ * #dr_register_restore_state_event()), or use
338
+ * #dr_insert_clean_call().
339
+ *
340
+ * \note This routine only supports passing arguments that are
341
+ * integers or pointers of a size equal to the register size: i.e., no
342
+ * floating-point, multimedia, or aggregate data types.
343
+ * The routine also supports immediate integers that are smaller than
344
+ * the register size, and for 64-bit mode registers or memory references that
345
+ * are OPSZ_4.
346
+ *
347
+ * \note For 64-bit mode, passing arguments that use calling
348
+ * convention registers (for Windows, RCX, RDX, R8, R9; for Linux,
349
+ * RDI, RSI, RDX, RCX, R8 and R9) are supported but may incur
350
+ * additional stack usage.
351
+ *
352
+ * \note For 64-bit mode, if a 32-bit immediate integer is specified as an
353
+ * argument and it has its top bit set, we assume it is intended to be
354
+ * sign-extended to 64-bits; otherwise we zero-extend it.
355
+ *
356
+ * \note For 64-bit mode, variable-sized argument operands may not work
357
+ * properly.
358
+ *
359
+ * \note Arguments that reference REG_XSP are not supported in 64-bit mode.
360
+ */
361
+ void
362
+ dr_insert_call(void *drcontext, instrlist_t *ilist, instr_t *where,
363
+ void *callee, uint num_args, ...);
364
+
365
+ /**
366
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to save state for a call.
367
+ * Stores the application state information on the DR stack.
368
+ * Returns the size of the data stored on the DR stack (in case the caller
369
+ * needs to align the stack pointer).
370
+ *
371
+ * \warning This routine does NOT save the fp/mmx/sse state: to do that the
372
+ * instrumentation routine should call proc_save_fpstate() to save and
373
+ * then proc_restore_fpstate() to restore (or use dr_insert_clean_call()).
374
+ *
375
+ * \note The preparation modifies the REG_XSP and REG_XAX registers
376
+ * (after saving them). Use dr_insert_clean_call() instead if an
377
+ * argument to the subsequent call that references REG_XAX is
378
+ * desired.
379
+ *
380
+ * \note The stack used to save the state is limited to
381
+ * 20KB by default; this can be changed with the -stack_size DR runtime
382
+ * parameter. This stack cannot be used to store state that persists
383
+ * beyond a single clean call, code cache execution, or probe callback
384
+ * function execution.
385
+ */
386
+ uint
387
+ dr_prepare_for_call(void *drcontext, instrlist_t *ilist, instr_t *instr);
388
+
389
+ /**
390
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to restore state
391
+ * after a call.
392
+ */
393
+ void
394
+ dr_cleanup_after_call(void *drcontext, instrlist_t *ilist, instr_t *where,
395
+ uint sizeof_param_area);
396
+
397
+ /**
398
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to save the current
399
+ * esp and switch to this thread's DR stack.
400
+ * \note The DR stack is limited to 20KB by default; this can be changed with
401
+ * the -stack_size DR runtime parameter. This stack cannot be used to store
402
+ * state that persists beyond a single clean call, code cache execution,
403
+ * or probe callback function execution.
404
+ */
405
+ void
406
+ dr_swap_to_clean_stack(void *drcontext, instrlist_t *ilist, instr_t *where);
407
+
408
+ /**
409
+ * Inserts into \p ilist prior to \p where meta-instruction(s) to restore into
410
+ * esp the value saved by dr_swap_to_dr_stack().
411
+ */
412
+ void
413
+ dr_restore_app_stack(void *drcontext, instrlist_t *ilist, instr_t *where);
414
+
415
+ /**
416
+ * Assumes that \p instr is a near call.
417
+ * Inserts into \p ilist prior to \p instr instruction(s) to call callee passing
418
+ * two arguments:
419
+ * -# address of call instruction (caller)
420
+ * -# target address of call (callee)
421
+ */
422
+ void
423
+ dr_insert_call_instrumentation(void *drcontext, instrlist_t *ilist,
424
+ instr_t *instr, void *callee);
425
+
426
+ /**
427
+ * Assumes that \p instr is an indirect branch.
428
+ * Inserts into \p ilist prior to \p instr instruction(s) to call callee passing
429
+ * two arguments:
430
+ * -# address of branch instruction
431
+ * -# target address of branch
432
+ * \note Only the address portion of a far indirect branch is considered.
433
+ * \note \p scratch_slot must be <= dr_max_opnd_accessible_spill_slot(). \p scratch_slot
434
+ * is used internally to this routine and will be clobbered.
435
+ */
436
+ void
437
+ dr_insert_mbr_instrumentation(void *drcontext, instrlist_t *ilist,
438
+ instr_t *instr, void *callee, dr_spill_slot_t scratch_slot);
439
+
440
+ /**
441
+ * Assumes that \p instr is a conditional branch
442
+ * Inserts into \p ilist prior to \p instr instruction(s) to call callee passing
443
+ * three arguments:
444
+ * -# address of branch instruction
445
+ * -# target address of branch
446
+ * -# 0 if the branch is not taken, 1 if it is taken
447
+ */
448
+ void
449
+ dr_insert_cbr_instrumentation(void *drcontext, instrlist_t *ilist,
450
+ instr_t *instr, void *callee);
451
+
452
+ /**
453
+ * Assumes that \p instr is a direct, near, unconditional branch.
454
+ * Inserts into \p ilist prior to \p instr instruction(s) to call callee passing
455
+ * two arguments:
456
+ * -# address of branch instruction
457
+ * -# target address of branch
458
+ *
459
+ * \warning Basic block eliding is controlled by -max_elide_jmp. If that
460
+ * option is set to non-zero, ubrs may never be seen.
461
+ */
462
+ void
463
+ dr_insert_ubr_instrumentation(void *drcontext, instrlist_t *ilist,
464
+ instr_t *instr, void *callee);
465
+
466
+ /**
467
+ * Returns true if the xmm0 through xmm5 for Windows, or xmm0 through
468
+ * xmm15 for Linux, fields in dr_mcontext_t are valid for this process
469
+ * (i.e., whether this process is 64-bit or WOW64, and the processor
470
+ * supports SSE).
471
+ */
472
+ bool
473
+ dr_mcontext_xmm_fields_valid(void);
474
+
475
+ /**
476
+ * Copies the current application machine context to \p context.
477
+ * This routine may only be called from:
478
+ * - A clean call invoked by dr_insert_clean_call() or dr_prepare_for_call()
479
+ * - A pre- or post-syscall event (dr_register_pre_syscall_event(),
480
+ * dr_register_post_syscall_event())
481
+ * - Basic block or trace creation events (dr_register_bb_event(),
482
+ * dr_register_trace_event()), but for basic block creation only when the
483
+ * basic block callback parameters \p for_trace and \p translating are
484
+ * false, and for trace creation only when \p translating is false.
485
+ * - A nudge callback (dr_register_nudge_event()) on Linux.
486
+ * (On Windows nudges happen in separate dedicated threads.)
487
+ *
488
+ * Does NOT copy the pc field. If \p app_errno is non-NULL copies the
489
+ * saved application error code (value of GetLastError() on Windows; ignored
490
+ * on Linux) to \p app_errno.
491
+ *
492
+ * \note NUM_XMM_SLOTS in the dr_mcontext_t.xmm array are filled in, but
493
+ * only if dr_mcontext_fields_valid() returns true.
494
+ * \note The context is the context saved at the dr_insert_clean_call() or
495
+ * dr_prepare_for_call() points. It does not correct for any registers saved
496
+ * with dr_save_reg(). To access registers saved with dr_save_reg() from a
497
+ * clean call use dr_read_saved_reg().
498
+ */
499
+ void
500
+ dr_get_mcontext(void *drcontext, dr_mcontext_t *context, int *app_errno);
501
+
502
+ /**
503
+ * Sets the application machine context to \p context.
504
+ * This routine may only be called from:
505
+ * - A clean call invoked by dr_insert_clean_call() or dr_prepare_for_call()
506
+ * - A pre- or post-syscall event (dr_register_pre_syscall_event(),
507
+ * dr_register_post_syscall_event())
508
+ * dr_register_thread_exit_event())
509
+ * - Basic block or trace creation events (dr_register_bb_event(),
510
+ * dr_register_trace_event()), but for basic block creation only when the
511
+ * basic block callback parameters \p for_trace and \p translating are
512
+ * false, and for trace creation only when \p translating is false.
513
+ *
514
+ * Ignores the pc field. If \p app_errno is non-NULL sets the
515
+ * application error code (value of GetLastError() on Windows; ignored
516
+ * on Linux) to be restored as well.
517
+ *
518
+ * \note The xmm0 through xmm5 fields are only set for 64-bit or WOW64
519
+ * processes where the underlying processor supports SSE. For
520
+ * dr_insert_clean_call() that requested \p save_fpstate, the xmm0
521
+ * through xmm5 values set here override that saved state.
522
+ * Use dr_mcontext_xmm_fields_valid() to determine whether the fields are valid.
523
+ */
524
+ void
525
+ dr_set_mcontext(void *drcontext, dr_mcontext_t *context, const int *app_errno);
526
+
527
+ /**
528
+ * Immediately resumes application execution from a clean call out of the cache (see
529
+ * dr_insert_clean_call() or dr_prepare_for_call()) or an exception event with the
530
+ * state specified in \p mcontext (including pc, and including the xmm0 through xmm5
531
+ * values if dr_mcontext_xmm_fields_valid() returns true) and the application error
532
+ * code (value of GetLastError() on Windows; ignored on Linux) specified by \p app_errno.
533
+ *
534
+ * \note dr_get_mcontext() can be used to get the register state (except pc) and the
535
+ * \p app_errno value saved in dr_insert_clean_call() or dr_prepare_for_call()
536
+ * \note If floating point state was saved by dr_prepare_for_call() or
537
+ * dr_insert_clean_call() it is not restored (other than xmm0 through xmm5, if
538
+ * dr_mcontext_xmm_fields_valid()). The caller should instead manually save and
539
+ * restore the floating point state with proc_save_fpstate() and proc_restore_fpstate()
540
+ * if necessary.
541
+ * \note If the caller wishes to set any other state (such as xmm registers that are
542
+ * not part of the mcontext) they may do so by just setting that state in the current
543
+ * thread before making this call.
544
+ * \note This routine may only be called from a clean call from the cache. It can not be
545
+ * called from any registered event callback.
546
+ * \note This routine doesn't return.
547
+ */
548
+ void
549
+ dr_redirect_execution(dr_mcontext_t *mcontext, int app_errno);
550
+
551
+ /***************************************************************************
552
+ * DECODE / DISASSEMBLY ROUTINES
553
+ */
554
+
555
+
556
+ /**
557
+ * Calculates the size, in bytes, of the memory read or write of
558
+ * the instr at \p pc. If the instruction is a repeating string instruction,
559
+ * considers only one iteration.
560
+ * Returns the pc of the following instruction.
561
+ * If the instruction at \p pc does not reference memory, or is invalid,
562
+ * returns NULL.
563
+ */
564
+ app_pc
565
+ decode_memory_reference_size(void *drcontext, app_pc pc, uint *size_in_bytes);
566
+
567
+ /**
568
+ * Decodes only enough of the instruction at address \p pc to determine
569
+ * its eflags usage, which is returned in \p usage as EFLAGS_ constants
570
+ * or'ed together.
571
+ * Returns the address of the next byte after the decoded instruction.
572
+ * Returns NULL on decoding an invalid instruction.
573
+ */
574
+ byte *
575
+ decode_eflags_usage(void *drcontext, byte *pc, uint *usage);
576
+
577
+ /**
578
+ * Decodes the instruction at address \p pc into \p instr, filling in the
579
+ * instruction's opcode, eflags usage, prefixes, and operands.
580
+ * The instruction's raw bits are set to valid and pointed at \p pc
581
+ * (xref instr_get_raw_bits()).
582
+ * Assumes that \p instr is already initialized, but uses the x86/x64 mode
583
+ * for the thread \p dcontext rather than that set in instr.
584
+ * If caller is re-using same instr_t struct over multiple decodings,
585
+ * caller should call instr_reset() or instr_reuse().
586
+ * Returns the address of the next byte after the decoded instruction.
587
+ * Returns NULL on decoding an invalid instr and sets opcode to OP_INVALID.
588
+ */
589
+ byte *
590
+ decode(void *drcontext, byte *pc, instr_t *instr);
591
+
592
+ /**
593
+ * Decodes the instruction at address \p copy_pc into \p instr as though
594
+ * it were located at address \p orig_pc. Any pc-relative operands have
595
+ * their values calculated as though the instruction were actually at
596
+ * \p orig_pc, though that address is never de-referenced.
597
+ * The instruction's raw bits are not valid, but its translation field
598
+ * (see instr_get_translation()) is set to \p orig_pc.
599
+ * The instruction's opcode, eflags usage, prefixes, and operands are
600
+ * all filled in.
601
+ * Assumes that \p instr is already initialized, but uses the x86/x64 mode
602
+ * for the thread \p dcontext rather than that set in instr.
603
+ * If caller is re-using same instr_t struct over multiple decodings,
604
+ * caller should call instr_reset() or instr_reuse().
605
+ * Returns the address of the next byte after the decoded instruction
606
+ * copy at \p copy_pc.
607
+ * Returns NULL on decoding an invalid instr and sets opcode to OP_INVALID.
608
+ */
609
+ byte *
610
+ decode_from_copy(void *drcontext, byte *copy_pc, byte *orig_pc, instr_t *instr);
611
+
612
+ /**
613
+ * Client routine to decode instructions at an arbitrary app address,
614
+ * following all the rules that DynamoRIO follows internally for
615
+ * terminating basic blocks. Note that DynamoRIO does not validate
616
+ * that \p start_pc is actually the first instruction of a basic block.
617
+ * \note Caller is reponsible for freeing the list and its instrs!
618
+ */
619
+ instrlist_t *
620
+ decode_as_bb(void *drcontext, byte *start_pc);
621
+
622
+ /**
623
+ * Decodes the trace with tag \p tag, and returns an instrlist_t of
624
+ * the instructions comprising that fragment. If \p tag is not a
625
+ * valid tag for an existing trace, the routine returns NULL. Clients
626
+ * can use dr_trace_exists_at() to determine whether the trace exists.
627
+ * \note Unlike the instruction list presented by the trace event, the
628
+ * list here does not include any existing client modifications. If
629
+ * client-modified instructions are needed, it is the responsibility
630
+ * of the client to record or recreate that list itself.
631
+ * \note This routine does not support decoding thread-private traces
632
+ * created by other than the calling thread.
633
+ */
634
+ instrlist_t *
635
+ decode_trace(void *drcontext, void *tag);
636
+
637
+ /**
638
+ * Given an OP_ constant, returns the first byte of its opcode when
639
+ * encoded as an IA-32 instruction.
640
+ */
641
+ byte
642
+ decode_first_opcode_byte(int opcode);
643
+
644
+ /** Given an OP_ constant, returns the string name of its opcode. */
645
+ const char *
646
+ decode_opcode_name(int opcode);
647
+
648
+ /**
649
+ * Decodes only enough of the instruction at address \p pc to determine its size.
650
+ * Returns that size.
651
+ * If \p num_prefixes is non-NULL, returns the number of prefix bytes.
652
+ * If \p rip_rel_pos is non-NULL, returns the offset into the instruction
653
+ * of a rip-relative addressing displacement (for data only: ignores
654
+ * control-transfer relative addressing), or 0 if none.
655
+ * May return 0 size for certain invalid instructions.
656
+ */
657
+ int
658
+ decode_sizeof(void *drcontext, byte *pc, int *num_prefixes
659
+ _IF_X64(uint *rip_rel_pos));
660
+
661
+ /**
662
+ * Decodes only enough of the instruction at address \p pc to determine its size.
663
+ * Returns the address of the byte following the instruction.
664
+ * Returns NULL on decoding an invalid instruction.
665
+ */
666
+ byte *
667
+ decode_next_pc(void *drcontext, byte *pc);
668
+
669
+
670
+ /**
671
+ * Decodes and then prints the instruction at address \p pc to file \p outfile.
672
+ * The default is to use AT&T-style syntax, unless the \ref op_syntax_intel
673
+ * "-syntax_intel" runtime option is specified.
674
+ * Returns the address of the subsequent instruction, or NULL if the instruction
675
+ * at \p pc is invalid.
676
+ */
677
+ byte *
678
+ disassemble(void *drcontext, byte *pc, file_t outfile);
679
+
680
+ /**
681
+ * Decodes and then prints the instruction at address \p pc to file \p outfile.
682
+ * Prior to the instruction the address is printed if \p show_pc and the raw
683
+ * bytes are printed if \p show_bytes.
684
+ * The default is to use AT&T-style syntax, unless the \ref op_syntax_intel
685
+ * "-syntax_intel" runtime option is specified.
686
+ * Returns the address of the subsequent instruction, or NULL if the instruction
687
+ * at \p pc is invalid.
688
+ */
689
+ byte *
690
+ disassemble_with_info(void *drcontext, byte *pc, file_t outfile,
691
+ bool show_pc, bool show_bytes);
692
+
693
+ /**
694
+ * Decodes the instruction at address \p copy_pc as though
695
+ * it were located at address \p orig_pc, and then prints the
696
+ * instruction to file \p outfile.
697
+ * Prior to the instruction the address \p orig_pc is printed if \p show_pc and the raw
698
+ * bytes are printed if \p show_bytes.
699
+ * The default is to use AT&T-style syntax, unless the \ref op_syntax_intel
700
+ * "-syntax_intel" runtime option is specified.
701
+ * Returns the address of the subsequent instruction after the copy at
702
+ * \p copy_pc, or NULL if the instruction at \p copy_pc is invalid.
703
+ */
704
+ byte *
705
+ disassemble_from_copy(void *drcontext, byte *copy_pc, byte *orig_pc,
706
+ file_t outfile, bool show_pc, bool show_bytes);
707
+
708
+ #endif /* _DR_IR_UTILS_H_ */