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,1170 @@
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_OPND_H_
34
+ #define _DR_IR_OPND_H_ 1
35
+
36
+ /****************************************************************************
37
+ * OPERAND ROUTINES
38
+ */
39
+ /**
40
+ * @file dr_ir_opnd.h
41
+ * @brief Functions and defines to create and manipulate instruction operands.
42
+ */
43
+
44
+ enum {
45
+ REG_NULL, /**< Sentinel value indicating no register, for address modes. */
46
+ /* 64-bit general purpose */
47
+ REG_RAX, /**< The "rax" register. */
48
+ REG_RCX, /**< The "rcx" register. */
49
+ REG_RDX, /**< The "rdx" register. */
50
+ REG_RBX, /**< The "rbx" register. */
51
+ REG_RSP, /**< The "rsp" register. */
52
+ REG_RBP, /**< The "rbp" register. */
53
+ REG_RSI, /**< The "rsi" register. */
54
+ REG_RDI, /**< The "rdi" register. */
55
+
56
+ REG_R8, /**< The "r8" register. */
57
+ REG_R9, /**< The "r9" register. */
58
+ REG_R10, /**< The "r10" register. */
59
+ REG_R11, /**< The "r11" register. */
60
+ REG_R12, /**< The "r12" register. */
61
+ REG_R13, /**< The "r13" register. */
62
+ REG_R14, /**< The "r14" register. */
63
+ REG_R15, /**< The "r15" register. */
64
+
65
+ /* 32-bit general purpose */
66
+ REG_EAX, /**< The "eax" register. */
67
+ REG_ECX, /**< The "ecx" register. */
68
+ REG_EDX, /**< The "edx" register. */
69
+ REG_EBX, /**< The "ebx" register. */
70
+ REG_ESP, /**< The "esp" register. */
71
+ REG_EBP, /**< The "ebp" register. */
72
+ REG_ESI, /**< The "esi" register. */
73
+ REG_EDI, /**< The "edi" register. */
74
+
75
+ REG_R8D, /**< The "r8d" register. */
76
+ REG_R9D, /**< The "r9d" register. */
77
+ REG_R10D, /**< The "r10d" register. */
78
+ REG_R11D, /**< The "r11d" register. */
79
+ REG_R12D, /**< The "r12d" register. */
80
+ REG_R13D, /**< The "r13d" register. */
81
+ REG_R14D, /**< The "r14d" register. */
82
+ REG_R15D, /**< The "r15d" register. */
83
+
84
+ /* 16-bit general purpose */
85
+ REG_AX, /**< The "ax" register. */
86
+ REG_CX, /**< The "cx" register. */
87
+ REG_DX, /**< The "dx" register. */
88
+ REG_BX, /**< The "bx" register. */
89
+ REG_SP, /**< The "sp" register. */
90
+ REG_BP, /**< The "bp" register. */
91
+ REG_SI, /**< The "si" register. */
92
+ REG_DI, /**< The "di" register. */
93
+
94
+ REG_R8W, /**< The "r8w" register. */
95
+ REG_R9W, /**< The "r9w" register. */
96
+ REG_R10W, /**< The "r10w" register. */
97
+ REG_R11W, /**< The "r11w" register. */
98
+ REG_R12W, /**< The "r12w" register. */
99
+ REG_R13W, /**< The "r13w" register. */
100
+ REG_R14W, /**< The "r14w" register. */
101
+ REG_R15W, /**< The "r15w" register. */
102
+
103
+ /* 8-bit general purpose */
104
+ REG_AL, /**< The "al" register. */
105
+ REG_CL, /**< The "cl" register. */
106
+ REG_DL, /**< The "dl" register. */
107
+ REG_BL, /**< The "bl" register. */
108
+ REG_AH, /**< The "ah" register. */
109
+ REG_CH, /**< The "ch" register. */
110
+ REG_DH, /**< The "dh" register. */
111
+ REG_BH, /**< The "bh" register. */
112
+
113
+ REG_R8L, /**< The "r8l" register. */
114
+ REG_R9L, /**< The "r9l" register. */
115
+ REG_R10L, /**< The "r10l" register. */
116
+ REG_R11L, /**< The "r11l" register. */
117
+ REG_R12L, /**< The "r12l" register. */
118
+ REG_R13L, /**< The "r13l" register. */
119
+ REG_R14L, /**< The "r14l" register. */
120
+ REG_R15L, /**< The "r15l" register. */
121
+
122
+ REG_SPL, /**< The "spl" register. */
123
+ REG_BPL, /**< The "bpl" register. */
124
+ REG_SIL, /**< The "sil" register. */
125
+ REG_DIL, /**< The "dil" register. */
126
+
127
+ /* 64-BIT MMX */
128
+ REG_MM0, /**< The "mm0" register. */
129
+ REG_MM1, /**< The "mm1" register. */
130
+ REG_MM2, /**< The "mm2" register. */
131
+ REG_MM3, /**< The "mm3" register. */
132
+ REG_MM4, /**< The "mm4" register. */
133
+ REG_MM5, /**< The "mm5" register. */
134
+ REG_MM6, /**< The "mm6" register. */
135
+ REG_MM7, /**< The "mm7" register. */
136
+
137
+ /* 128-BIT XMM */
138
+ REG_XMM0, /**< The "xmm0" register. */
139
+ REG_XMM1, /**< The "xmm1" register. */
140
+ REG_XMM2, /**< The "xmm2" register. */
141
+ REG_XMM3, /**< The "xmm3" register. */
142
+ REG_XMM4, /**< The "xmm4" register. */
143
+ REG_XMM5, /**< The "xmm5" register. */
144
+ REG_XMM6, /**< The "xmm6" register. */
145
+ REG_XMM7, /**< The "xmm7" register. */
146
+
147
+ REG_XMM8, /**< The "xmm8" register. */
148
+ REG_XMM9, /**< The "xmm9" register. */
149
+ REG_XMM10, /**< The "xmm10" register. */
150
+ REG_XMM11, /**< The "xmm11" register. */
151
+ REG_XMM12, /**< The "xmm12" register. */
152
+ REG_XMM13, /**< The "xmm13" register. */
153
+ REG_XMM14, /**< The "xmm14" register. */
154
+ REG_XMM15, /**< The "xmm15" register. */
155
+
156
+ /* floating point registers */
157
+ REG_ST0, /**< The "st0" register. */
158
+ REG_ST1, /**< The "st1" register. */
159
+ REG_ST2, /**< The "st2" register. */
160
+ REG_ST3, /**< The "st3" register. */
161
+ REG_ST4, /**< The "st4" register. */
162
+ REG_ST5, /**< The "st5" register. */
163
+ REG_ST6, /**< The "st6" register. */
164
+ REG_ST7, /**< The "st7" register. */
165
+
166
+ /* segments (order from "Sreg" description in Intel manual) */
167
+ SEG_ES, /**< The "es" register. */
168
+ SEG_CS, /**< The "cs" register. */
169
+ SEG_SS, /**< The "ss" register. */
170
+ SEG_DS, /**< The "ds" register. */
171
+ SEG_FS, /**< The "fs" register. */
172
+ SEG_GS, /**< The "gs" register. */
173
+
174
+ /* debug & control registers (privileged access only; 8-15 for future processors) */
175
+ REG_DR0, /**< The "dr0" register. */
176
+ REG_DR1, /**< The "dr1" register. */
177
+ REG_DR2, /**< The "dr2" register. */
178
+ REG_DR3, /**< The "dr3" register. */
179
+ REG_DR4, /**< The "dr4" register. */
180
+ REG_DR5, /**< The "dr5" register. */
181
+ REG_DR6, /**< The "dr6" register. */
182
+ REG_DR7, /**< The "dr7" register. */
183
+
184
+ REG_DR8, /**< The "dr8" register. */
185
+ REG_DR9, /**< The "dr9" register. */
186
+ REG_DR10, /**< The "dr10" register. */
187
+ REG_DR11, /**< The "dr11" register. */
188
+ REG_DR12, /**< The "dr12" register. */
189
+ REG_DR13, /**< The "dr13" register. */
190
+ REG_DR14, /**< The "dr14" register. */
191
+ REG_DR15, /**< The "dr15" register. */
192
+
193
+ /* cr9-cr15 do not yet exist on current x64 hardware */
194
+ REG_CR0, /**< The "cr0" register. */
195
+ REG_CR1, /**< The "cr1" register. */
196
+ REG_CR2, /**< The "cr2" register. */
197
+ REG_CR3, /**< The "cr3" register. */
198
+ REG_CR4, /**< The "cr4" register. */
199
+ REG_CR5, /**< The "cr5" register. */
200
+ REG_CR6, /**< The "cr6" register. */
201
+ REG_CR7, /**< The "cr7" register. */
202
+
203
+ REG_CR8, /**< The "cr8" register. */
204
+ REG_CR9, /**< The "cr9" register. */
205
+ REG_CR10, /**< The "cr10" register. */
206
+ REG_CR11, /**< The "cr11" register. */
207
+ REG_CR12, /**< The "cr12" register. */
208
+ REG_CR13, /**< The "cr13" register. */
209
+ REG_CR14, /**< The "cr14" register. */
210
+ REG_CR15, /**< The "cr15" register. */
211
+
212
+ REG_INVALID, /**< Sentinel value indicating an invalid register. */
213
+ };
214
+ /* we avoid typedef-ing the enum, as its storage size is compiler-specific */
215
+ typedef byte reg_id_t; /* contains a REG_ enum value */
216
+ typedef byte opnd_size_t; /* contains a REG_ or OPSZ_ enum value */
217
+
218
+ /* Platform-independent full-register specifiers */
219
+ #ifdef X64
220
+ # define REG_XAX REG_RAX /**< Platform-independent way to refer to rax/eax. */
221
+ # define REG_XCX REG_RCX /**< Platform-independent way to refer to rcx/ecx. */
222
+ # define REG_XDX REG_RDX /**< Platform-independent way to refer to rdx/edx. */
223
+ # define REG_XBX REG_RBX /**< Platform-independent way to refer to rbx/ebx. */
224
+ # define REG_XSP REG_RSP /**< Platform-independent way to refer to rsp/esp. */
225
+ # define REG_XBP REG_RBP /**< Platform-independent way to refer to rbp/ebp. */
226
+ # define REG_XSI REG_RSI /**< Platform-independent way to refer to rsi/esi. */
227
+ # define REG_XDI REG_RDI /**< Platform-independent way to refer to rdi/edi. */
228
+ #else
229
+ # define REG_XAX REG_EAX /**< Platform-independent way to refer to rax/eax. */
230
+ # define REG_XCX REG_ECX /**< Platform-independent way to refer to rcx/ecx. */
231
+ # define REG_XDX REG_EDX /**< Platform-independent way to refer to rdx/edx. */
232
+ # define REG_XBX REG_EBX /**< Platform-independent way to refer to rbx/ebx. */
233
+ # define REG_XSP REG_ESP /**< Platform-independent way to refer to rsp/esp. */
234
+ # define REG_XBP REG_EBP /**< Platform-independent way to refer to rbp/ebp. */
235
+ # define REG_XSI REG_ESI /**< Platform-independent way to refer to rsi/esi. */
236
+ # define REG_XDI REG_EDI /**< Platform-independent way to refer to rdi/edi. */
237
+ #endif
238
+
239
+
240
+
241
+ #define REG_START_64 REG_RAX /**< Start of 64-bit general register enum values. */
242
+ #define REG_STOP_64 REG_R15 /**< End of 64-bit general register enum values. */
243
+ #define REG_START_32 REG_EAX /**< Start of 32-bit general register enum values. */
244
+ #define REG_STOP_32 REG_R15D /**< End of 32-bit general register enum values. */
245
+ #define REG_START_16 REG_AX /**< Start of 16-bit general register enum values. */
246
+ #define REG_STOP_16 REG_R15W /**< End of 16-bit general register enum values. */
247
+ #define REG_START_8 REG_AL /**< Start of 8-bit general register enum values. */
248
+ #define REG_STOP_8 REG_DIL /**< End of 8-bit general register enum values. */
249
+ #define REG_START_8HL REG_AL /**< Start of 8-bit high-low register enum values. */
250
+ #define REG_STOP_8HL REG_BH /**< End of 8-bit high-low register enum values. */
251
+ #define REG_START_x86_8 REG_AH /**< Start of 8-bit x86-only register enum values. */
252
+ #define REG_STOP_x86_8 REG_BH /**< Stop of 8-bit x86-only register enum values. */
253
+ #define REG_START_x64_8 REG_SPL /**< Start of 8-bit x64-only register enum values. */
254
+ #define REG_STOP_x64_8 REG_DIL /**< Stop of 8-bit x64-only register enum values. */
255
+ #define REG_START_MMX REG_MM0 /**< Start of mmx register enum values. */
256
+ #define REG_STOP_MMX REG_MM7 /**< End of mmx register enum values. */
257
+ #define REG_START_XMM REG_XMM0 /**< Start of xmm register enum values. */
258
+ #define REG_STOP_XMM REG_XMM15 /**< End of xmm register enum values. */
259
+ #define REG_START_FLOAT REG_ST0 /**< Start of floating-point-register enum values. */
260
+ #define REG_STOP_FLOAT REG_ST7 /**< End of floating-point-register enum values. */
261
+ #define REG_START_SEGMENT SEG_ES /**< Start of segment register enum values. */
262
+ #define REG_STOP_SEGMENT SEG_GS /**< End of segment register enum values. */
263
+ #define REG_START_DR REG_DR0 /**< Start of debug register enum values. */
264
+ #define REG_STOP_DR REG_DR15 /**< End of debug register enum values. */
265
+ #define REG_START_CR REG_CR0 /**< Start of control register enum values. */
266
+ #define REG_STOP_CR REG_CR15 /**< End of control register enum values. */
267
+ #define REG_LAST_VALID_ENUM REG_CR15 /**< Last valid register enum value. */
268
+ #define REG_LAST_ENUM REG_INVALID /**< Last register enum value. */
269
+
270
+
271
+ /** Returns an empty operand. */
272
+ opnd_t
273
+ opnd_create_null(void);
274
+
275
+ /** Returns a register operand (\p r must be a REG_ constant). */
276
+ opnd_t
277
+ opnd_create_reg(reg_id_t r);
278
+
279
+ /**
280
+ * Returns an immediate integer operand with value \p i and size
281
+ * \p data_size; \p data_size must be a OPSZ_ constant.
282
+ */
283
+ opnd_t
284
+ opnd_create_immed_int(ptr_int_t i, opnd_size_t data_size);
285
+
286
+ /** Returns an immediate float operand with value \p f. */
287
+ opnd_t
288
+ opnd_create_immed_float(float f);
289
+
290
+ /** Returns a program address operand with value \p pc. */
291
+ opnd_t
292
+ opnd_create_pc(app_pc pc);
293
+
294
+ /**
295
+ * Returns a far program address operand with value \p seg_selector:pc.
296
+ * \p seg_selector is a segment selector, not a SEG_ constant.
297
+ */
298
+ opnd_t
299
+ opnd_create_far_pc(ushort seg_selector, app_pc pc);
300
+
301
+ /** Returns an instr_t pointer address with value \p instr. */
302
+ opnd_t
303
+ opnd_create_instr(instr_t *instr);
304
+
305
+ /**
306
+ * Returns a far instr_t pointer address with value \p seg_selector:instr.
307
+ * \p seg_selector is a segment selector, not a SEG_ constant.
308
+ */
309
+ opnd_t
310
+ opnd_create_far_instr(ushort seg_selector, instr_t *instr);
311
+
312
+ /**
313
+ * Returns a memory reference operand that refers to the address:
314
+ * - disp(base_reg, index_reg, scale)
315
+ *
316
+ * or, in other words,
317
+ * - base_reg + index_reg*scale + disp
318
+ *
319
+ * The operand has data size data_size (must be a OPSZ_ constant).
320
+ * Both \p base_reg and \p index_reg must be REG_ constants.
321
+ * \p scale must be either 1, 2, 4, or 8.
322
+ */
323
+ opnd_t
324
+ opnd_create_base_disp(reg_id_t base_reg, reg_id_t index_reg, int scale, int disp,
325
+ opnd_size_t data_size);
326
+
327
+ /**
328
+ * Returns a memory reference operand that refers to the address:
329
+ * - disp(base_reg, index_reg, scale)
330
+ *
331
+ * or, in other words,
332
+ * - base_reg + index_reg*scale + disp
333
+ *
334
+ * The operand has data size \p data_size (must be a OPSZ_ constant).
335
+ * Both \p base_reg and \p index_reg must be REG_ constants.
336
+ * \p scale must be either 1, 2, 4, or 8.
337
+ * Gives control over encoding optimizations:
338
+ * -# If \p encode_zero_disp, a zero value for disp will not be omitted;
339
+ * -# If \p force_full_disp, a small value for disp will not occupy only one byte.
340
+ * -# If \p disp_short_addr, short (16-bit for 32-bit mode, 32-bit for
341
+ * 64-bit mode) addressing will be used (note that this normally only
342
+ * needs to be specified for an absolute address; otherwise, simply
343
+ * use the desired short registers for base and/or index).
344
+ *
345
+ * (Both of those are false when using opnd_create_base_disp()).
346
+ */
347
+ opnd_t
348
+ opnd_create_base_disp_ex(reg_id_t base_reg, reg_id_t index_reg, int scale,
349
+ int disp, opnd_size_t size,
350
+ bool encode_zero_disp, bool force_full_disp,
351
+ bool disp_short_addr);
352
+
353
+ /**
354
+ * Returns a far memory reference operand that refers to the address:
355
+ * - seg : disp(base_reg, index_reg, scale)
356
+ *
357
+ * or, in other words,
358
+ * - seg : base_reg + index_reg*scale + disp
359
+ *
360
+ * The operand has data size \p data_size (must be a OPSZ_ constant).
361
+ * \p seg must be a SEG_ constant.
362
+ * Both \p base_reg and \p index_reg must be REG_ constants.
363
+ * \p scale must be either 1, 2, 4, or 8.
364
+ */
365
+ opnd_t
366
+ opnd_create_far_base_disp(reg_id_t seg, reg_id_t base_reg, reg_id_t index_reg, int scale,
367
+ int disp, opnd_size_t data_size);
368
+
369
+ /**
370
+ * Returns a far memory reference operand that refers to the address:
371
+ * - seg : disp(base_reg, index_reg, scale)
372
+ *
373
+ * or, in other words,
374
+ * - seg : base_reg + index_reg*scale + disp
375
+ *
376
+ * The operand has data size \p data_size (must be a OPSZ_ constant).
377
+ * \p seg must be a SEG_ constant.
378
+ * Both \p base_reg and \p index_reg must be REG_ constants.
379
+ * scale must be either 1, 2, 4, or 8.
380
+ * Gives control over encoding optimizations:
381
+ * -# If \p encode_zero_disp, a zero value for disp will not be omitted;
382
+ * -# If \p force_full_disp, a small value for disp will not occupy only one byte.
383
+ * -# If \p disp_short_addr, short (16-bit for 32-bit mode, 32-bit for
384
+ * 64-bit mode) addressing will be used (note that this normally only
385
+ * needs to be specified for an absolute address; otherwise, simply
386
+ * use the desired short registers for base and/or index).
387
+ *
388
+ * (Both of those are false when using opnd_create_far_base_disp()).
389
+ */
390
+ opnd_t
391
+ opnd_create_far_base_disp_ex(reg_id_t seg, reg_id_t base_reg, reg_id_t index_reg,
392
+ int scale, int disp, opnd_size_t size,
393
+ bool encode_zero_disp, bool force_full_disp,
394
+ bool disp_short_addr);
395
+
396
+ /**
397
+ * Returns a memory reference operand that refers to the address \p addr.
398
+ * The operand has data size \p data_size (must be a OPSZ_ constant).
399
+ *
400
+ * If \p addr <= 2^32 (which is always true in 32-bit mode), this routine
401
+ * is equivalent to
402
+ * opnd_create_base_disp(REG_NULL, REG_NULL, 0, (int)addr, data_size).
403
+ *
404
+ * Otherwise, this routine creates a separate operand type with an
405
+ * absolute 64-bit memory address. Note that such an operand can only be
406
+ * used as a load or store from or to the rax register.
407
+ */
408
+ opnd_t
409
+ opnd_create_abs_addr(void *addr, opnd_size_t data_size);
410
+
411
+ /**
412
+ * Returns a memory reference operand that refers to the address
413
+ * \p seg: \p addr.
414
+ * The operand has data size \p data_size (must be a OPSZ_ constant).
415
+ *
416
+ * If \p addr <= 2^32 (which is always true in 32-bit mode), this routine
417
+ * is equivalent to
418
+ * opnd_create_far_base_disp(seg, REG_NULL, REG_NULL, 0, (int)addr, data_size).
419
+ *
420
+ * Otherwise, this routine creates a separate operand type with an
421
+ * absolute 64-bit memory address. Note that such an operand can only be
422
+ * used as a load or store from or to the rax register.
423
+ */
424
+ opnd_t
425
+ opnd_create_far_abs_addr(reg_id_t seg, void *addr, opnd_size_t data_size);
426
+ #ifdef X64
427
+
428
+
429
+ /**
430
+ * Returns a memory reference operand that refers to the address \p
431
+ * addr, but will be encoded as a pc-relative address. At emit time,
432
+ * if \p addr is out of reach of a 32-bit signed displacement from the
433
+ * next instruction, encoding will fail.
434
+ *
435
+ * DR guarantees that all of its code caches and heap are within the
436
+ * same 2GB memory region. DR also loads client libraries within
437
+ * 32-bit reachability of its code caches and heap. This means that
438
+ * any static data or code in a client library, or any data allocated
439
+ * using DR's API, is guaranteed to be reachable from code cache code.
440
+ *
441
+ * The operand has data size data_size (must be a OPSZ_ constant).
442
+ *
443
+ * To represent a 32-bit address (i.e., what an address size prefix
444
+ * indicates), simply zero out the top 32 bits of the address before
445
+ * passing it to this routine.
446
+ *
447
+ * \note For 64-bit DR builds only.
448
+ */
449
+ opnd_t
450
+ opnd_create_rel_addr(void *addr, opnd_size_t data_size);
451
+
452
+ /**
453
+ * Returns a memory reference operand that refers to the address \p
454
+ * seg : \p addr, but will be encoded as a pc-relative address. It is
455
+ * up to the caller to ensure that the resulting address is reachable
456
+ * via a 32-bit signed displacement from the next instruction at emit
457
+ * time.
458
+ *
459
+ * DR guarantees that all of its code caches and heap are within the
460
+ * same 2GB memory region. DR also loads client libraries within
461
+ * 32-bit reachability of its code caches and heap. This means that
462
+ * any static data or code in a client library, or any data allocated
463
+ * using DR's API, is guaranteed to be reachable from code cache code.
464
+ *
465
+ * The operand has data size \p data_size (must be a OPSZ_ constant).
466
+ *
467
+ * To represent a 32-bit address (i.e., what an address size prefix
468
+ * indicates), simply zero out the top 32 bits of the address before
469
+ * passing it to this routine.
470
+ *
471
+ * \note For 64-bit DR builds only.
472
+ */
473
+ opnd_t
474
+ opnd_create_far_rel_addr(reg_id_t seg, void *addr, opnd_size_t data_size);
475
+ #endif
476
+
477
+
478
+ /** Returns true iff \p opnd is an empty operand. */
479
+ bool
480
+ opnd_is_null(opnd_t opnd);
481
+
482
+ /** Returns true iff \p opnd is a register operand. */
483
+ bool
484
+ opnd_is_reg(opnd_t opnd);
485
+
486
+ /** Returns true iff \p opnd is an immediate (integer or float) operand. */
487
+ bool
488
+ opnd_is_immed(opnd_t opnd);
489
+
490
+ /** Returns true iff \p opnd is an immediate integer operand. */
491
+ bool
492
+ opnd_is_immed_int(opnd_t opnd);
493
+
494
+ /** Returns true iff \p opnd is an immediate float operand. */
495
+ bool
496
+ opnd_is_immed_float(opnd_t opnd);
497
+
498
+ /** Returns true iff \p opnd is a (near or far) program address operand. */
499
+ bool
500
+ opnd_is_pc(opnd_t opnd);
501
+
502
+ /** Returns true iff \p opnd is a near (i.e., default segment) program address operand. */
503
+ bool
504
+ opnd_is_near_pc(opnd_t opnd);
505
+
506
+ /** Returns true iff \p opnd is a far program address operand. */
507
+ bool
508
+ opnd_is_far_pc(opnd_t opnd);
509
+
510
+ /** Returns true iff \p opnd is a (near or far) instr_t pointer address operand. */
511
+ bool
512
+ opnd_is_instr(opnd_t opnd);
513
+
514
+ /** Returns true iff \p opnd is a near instr_t pointer address operand. */
515
+ bool
516
+ opnd_is_near_instr(opnd_t opnd);
517
+
518
+ /** Returns true iff \p opnd is a far instr_t pointer address operand. */
519
+ bool
520
+ opnd_is_far_instr(opnd_t opnd);
521
+
522
+ /** Returns true iff \p opnd is a (near or far) base+disp memory reference operand. */
523
+ bool
524
+ opnd_is_base_disp(opnd_t opnd);
525
+
526
+ /**
527
+ * Returns true iff \p opnd is a near (i.e., default segment) base+disp memory
528
+ * reference operand.
529
+ */
530
+ bool
531
+ opnd_is_near_base_disp(opnd_t opnd);
532
+
533
+ /** Returns true iff \p opnd is a far base+disp memory reference operand. */
534
+ bool
535
+ opnd_is_far_base_disp(opnd_t opnd);
536
+
537
+ /**
538
+ * Returns true iff \p opnd is a (near or far) absolute address operand.
539
+ * Returns true for both base-disp operands with no base or index and
540
+ * 64-bit non-base-disp absolute address operands.
541
+ */
542
+ bool
543
+ opnd_is_abs_addr(opnd_t opnd);
544
+
545
+ /**
546
+ * Returns true iff \p opnd is a near (i.e., default segment) absolute address operand.
547
+ * Returns true for both base-disp operands with no base or index and
548
+ * 64-bit non-base-disp absolute address operands.
549
+ */
550
+ bool
551
+ opnd_is_near_abs_addr(opnd_t opnd);
552
+
553
+ /**
554
+ * Returns true iff \p opnd is a far absolute address operand.
555
+ * Returns true for both base-disp operands with no base or index and
556
+ * 64-bit non-base-disp absolute address operands.
557
+ */
558
+ bool
559
+ opnd_is_far_abs_addr(opnd_t opnd);
560
+ #ifdef X64
561
+
562
+
563
+ /**
564
+ * Returns true iff \p opnd is a (near or far) pc-relative memory reference operand.
565
+ *
566
+ * \note For 64-bit DR builds only.
567
+ */
568
+ bool
569
+ opnd_is_rel_addr(opnd_t opnd);
570
+
571
+ /**
572
+ * Returns true iff \p opnd is a near (i.e., default segment) pc-relative memory
573
+ * reference operand.
574
+ *
575
+ * \note For 64-bit DR builds only.
576
+ */
577
+ bool
578
+ opnd_is_near_rel_addr(opnd_t opnd);
579
+
580
+ /**
581
+ * Returns true iff \p opnd is a far pc-relative memory reference operand.
582
+ *
583
+ * \note For 64-bit DR builds only.
584
+ */
585
+ bool
586
+ opnd_is_far_rel_addr(opnd_t opnd);
587
+ #endif
588
+
589
+
590
+ /**
591
+ * Returns true iff \p opnd is a (near or far) memory reference operand
592
+ * of any type: base-disp, absolute address, or pc-relative address.
593
+ *
594
+ * \note For 64-bit DR builds only.
595
+ */
596
+ bool
597
+ opnd_is_memory_reference(opnd_t opnd);
598
+
599
+ /**
600
+ * Returns true iff \p opnd is a far memory reference operand
601
+ * of any type: base-disp, absolute address, or pc-relative address.
602
+ */
603
+ bool
604
+ opnd_is_far_memory_reference(opnd_t opnd);
605
+
606
+ /**
607
+ * Returns true iff \p opnd is a near memory reference operand
608
+ * of any type: base-disp, absolute address, or pc-relative address.
609
+ */
610
+ bool
611
+ opnd_is_near_memory_reference(opnd_t opnd);
612
+
613
+ /**
614
+ * Return the data size of \p opnd as a OPSZ_ constant.
615
+ * Assumes \p opnd is a register, immediate integer, or memory reference.
616
+ * If \p opnd is a register returns the result of opnd_reg_get_size()
617
+ * called on the REG_ constant.
618
+ * Returns OPSZ_NA if \p opnd does not have a valid size.
619
+ */
620
+ opnd_size_t
621
+ opnd_get_size(opnd_t opnd);
622
+
623
+ /**
624
+ * Sets the data size of \p opnd.
625
+ * Assumes \p opnd is an immediate integer or a memory reference.
626
+ */
627
+ void
628
+ opnd_set_size(opnd_t *opnd, opnd_size_t newsize);
629
+
630
+ /**
631
+ * Assumes \p opnd is a register operand.
632
+ * Returns the register it refers to (a REG_ constant).
633
+ */
634
+ reg_id_t
635
+ opnd_get_reg(opnd_t opnd);
636
+
637
+ /* Assumes opnd is an immediate integer, returns its value. */
638
+ ptr_int_t
639
+ opnd_get_immed_int(opnd_t opnd);
640
+
641
+ /** Assumes \p opnd is an immediate float, returns its value. */
642
+ float
643
+ opnd_get_immed_float(opnd_t opnd);
644
+
645
+ /** Assumes \p opnd is a (near or far) program address, returns its value. */
646
+ app_pc
647
+ opnd_get_pc(opnd_t opnd);
648
+
649
+ /**
650
+ * Assumes \p opnd is a far program address.
651
+ * Returns \p opnd's segment, a segment selector (not a SEG_ constant).
652
+ */
653
+ ushort
654
+ opnd_get_segment_selector(opnd_t opnd);
655
+
656
+ /** Assumes \p opnd is an instr_t pointer, returns its value. */
657
+ instr_t*
658
+ opnd_get_instr(opnd_t opnd);
659
+
660
+ /**
661
+ * Assumes \p opnd is a (near or far) base+disp memory reference. Returns the base
662
+ * register (a REG_ constant).
663
+ */
664
+ reg_id_t
665
+ opnd_get_base(opnd_t opnd);
666
+
667
+ /**
668
+ * Assumes \p opnd is a (near or far) base+disp memory reference.
669
+ * Returns the displacement.
670
+ */
671
+ int
672
+ opnd_get_disp(opnd_t opnd);
673
+
674
+ /**
675
+ * Assumes \p opnd is a (near or far) base+disp memory reference; returns whether
676
+ * encode_zero_disp has been specified for \p opnd.
677
+ */
678
+ bool
679
+ opnd_is_disp_encode_zero(opnd_t opnd);
680
+
681
+ /**
682
+ * Assumes \p opnd is a (near or far) base+disp memory reference; returns whether
683
+ * force_full_disp has been specified for \p opnd.
684
+ */
685
+ bool
686
+ opnd_is_disp_force_full(opnd_t opnd);
687
+
688
+ /**
689
+ * Assumes \p opnd is a (near or far) base+disp memory reference; returns whether
690
+ * disp_short_addr has been specified for \p opnd.
691
+ */
692
+ bool
693
+ opnd_is_disp_short_addr(opnd_t opnd);
694
+
695
+ /**
696
+ * Assumes \p opnd is a (near or far) base+disp memory reference.
697
+ * Returns the index register (a REG_ constant).
698
+ */
699
+ reg_id_t
700
+ opnd_get_index(opnd_t opnd);
701
+
702
+ /** Assumes \p opnd is a (near or far) base+disp memory reference. Returns the scale. */
703
+ int
704
+ opnd_get_scale(opnd_t opnd);
705
+
706
+ /**
707
+ * Assumes \p opnd is a (near or far) memory reference of any type.
708
+ * Returns \p opnd's segment (a SEG_ constant), or REG_NULL if it is a near
709
+ * memory reference.
710
+ */
711
+ reg_id_t
712
+ opnd_get_segment(opnd_t opnd);
713
+
714
+ /**
715
+ * Assumes \p opnd is a (near or far) absolute or pc-relative memory reference,
716
+ * or a base+disp memory reference with no base or index register.
717
+ * Returns \p opnd's absolute address (which will be pc-relativized on encoding
718
+ * for pc-relative memory references).
719
+ */
720
+ void *
721
+ opnd_get_addr(opnd_t opnd);
722
+
723
+ /**
724
+ * Returns the number of registers referred to by \p opnd. This will only
725
+ * be non-zero for register operands and memory references.
726
+ */
727
+ int
728
+ opnd_num_regs_used(opnd_t opnd);
729
+
730
+ /**
731
+ * Used in conjunction with opnd_num_regs_used(), this routine can be used
732
+ * to iterate through all registers used by \p opnd.
733
+ * The index values begin with 0 and proceed through opnd_num_regs_used(opnd)-1.
734
+ */
735
+ reg_id_t
736
+ opnd_get_reg_used(opnd_t opnd, int index);
737
+
738
+ /**
739
+ * Assumes that \p reg is a REG_ 32-bit register constant.
740
+ * Returns the string name for \p reg.
741
+ */
742
+ const char *
743
+ get_register_name(reg_id_t reg);
744
+
745
+ /**
746
+ * Assumes that \p reg is a REG_ 32-bit register constant.
747
+ * Returns the 16-bit version of \p reg.
748
+ */
749
+ reg_id_t
750
+ reg_32_to_16(reg_id_t reg);
751
+
752
+ /**
753
+ * Assumes that \p reg is a REG_ 32-bit register constant.
754
+ * Returns the 8-bit version of \p reg (the least significant byte:
755
+ * REG_AL instead of REG_AH if passed REG_EAX, e.g.). For 32-bit DR
756
+ * builds, returns REG_NULL if passed REG_ESP, REG_EBP, REG_ESI, or
757
+ * REG_EDI.
758
+ */
759
+ reg_id_t
760
+ reg_32_to_8(reg_id_t reg);
761
+ #ifdef X64
762
+
763
+
764
+ /**
765
+ * Assumes that \p reg is a REG_ 32-bit register constant.
766
+ * Returns the 64-bit version of \p reg.
767
+ *
768
+ * \note For 64-bit DR builds only.
769
+ */
770
+ reg_id_t
771
+ reg_32_to_64(reg_id_t reg);
772
+
773
+ /**
774
+ * Assumes that \p reg is a REG_ 64-bit register constant.
775
+ * Returns the 32-bit version of \p reg.
776
+ *
777
+ * \note For 64-bit DR builds only.
778
+ */
779
+ reg_id_t
780
+ reg_64_to_32(reg_id_t reg);
781
+
782
+ /**
783
+ * Returns true iff \p reg refers to an extended register only available
784
+ * in 64-bit mode and not in 32-bit mode (e.g., R8-R15, XMM8-XMM15, etc.)
785
+ *
786
+ * \note For 64-bit DR builds only.
787
+ */
788
+ bool
789
+ reg_is_extended(reg_id_t reg);
790
+ #endif
791
+
792
+
793
+ /**
794
+ * Assumes that \p reg is a REG_ 32-bit register constant.
795
+ * If \p sz == OPSZ_2, returns the 16-bit version of \p reg.
796
+ * For 64-bit versions of this library, if \p sz == OPSZ_8, returns
797
+ * the 64-bit version of \p reg.
798
+ */
799
+ reg_id_t
800
+ reg_32_to_opsz(reg_id_t reg, opnd_size_t sz);
801
+
802
+ /**
803
+ * Assumes that \p reg is a REG_ register constant.
804
+ * If reg is used as part of the calling convention, returns which
805
+ * parameter ordinal it matches (0-based); otherwise, returns -1.
806
+ */
807
+ int
808
+ reg_parameter_num(reg_id_t reg);
809
+
810
+ /**
811
+ * Assumes that \p reg is a REG_ constant.
812
+ * Returns true iff it refers to a General Purpose Register,
813
+ * i.e., rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, or a subset.
814
+ */
815
+ bool
816
+ reg_is_gpr(reg_id_t reg);
817
+
818
+ /**
819
+ * Assumes that \p reg is a REG_ constant.
820
+ * Returns true iff it refers to a segment (i.e., it's really a SEG_
821
+ * constant).
822
+ */
823
+ bool
824
+ reg_is_segment(reg_id_t reg);
825
+
826
+ /**
827
+ * Assumes that \p reg is a REG_ constant.
828
+ * Returns true iff it refers to an xmm (128-bit SSE/SSE2) register.
829
+ */
830
+ bool
831
+ reg_is_xmm(reg_id_t reg);
832
+
833
+ /**
834
+ * Assumes that \p reg is a REG_ constant.
835
+ * Returns true iff it refers to an mmx (64-bit) register.
836
+ */
837
+ bool
838
+ reg_is_mmx(reg_id_t reg);
839
+
840
+ /**
841
+ * Assumes that \p reg is a REG_ constant.
842
+ * Returns true iff it refers to a floating-point register.
843
+ */
844
+ bool
845
+ reg_is_fp(reg_id_t reg);
846
+
847
+ /**
848
+ * Assumes that \p reg is a REG_ constant.
849
+ * Returns true iff it refers to a 32-bit general-purpose register.
850
+ */
851
+ bool
852
+ reg_is_32bit(reg_id_t reg);
853
+
854
+ /**
855
+ * Returns true iff \p opnd is a register operand that refers to a 32-bit
856
+ * general-purpose register.
857
+ */
858
+ bool
859
+ opnd_is_reg_32bit(opnd_t opnd);
860
+
861
+ /**
862
+ * Assumes that \p reg is a REG_ constant.
863
+ * Returns true iff it refers to a 64-bit general-purpose register.
864
+ */
865
+ bool
866
+ reg_is_64bit(reg_id_t reg);
867
+
868
+ /**
869
+ * Returns true iff \p opnd is a register operand that refers to a 64-bit
870
+ * general-purpose register.
871
+ */
872
+ bool
873
+ opnd_is_reg_64bit(opnd_t opnd);
874
+
875
+ /**
876
+ * Assumes that \p reg is a REG_ constant.
877
+ * Returns true iff it refers to a pointer-sized general-purpose register.
878
+ */
879
+ bool
880
+ reg_is_pointer_sized(reg_id_t reg);
881
+
882
+ /**
883
+ * Assumes that \p reg is a REG_ 32-bit register constant.
884
+ * Returns the pointer-sized version of \p reg.
885
+ */
886
+ reg_id_t
887
+ reg_to_pointer_sized(reg_id_t reg);
888
+
889
+ /**
890
+ * Returns true iff \p opnd is a register operand that refers to a
891
+ * pointer-sized general-purpose register.
892
+ */
893
+ bool
894
+ opnd_is_reg_pointer_sized(opnd_t opnd);
895
+
896
+ /**
897
+ * Assumes that \p r1 and \p r2 are both REG_ constants.
898
+ * Returns true iff \p r1's register overlaps \p r2's register
899
+ * (e.g., if \p r1 == REG_AX and \p r2 == REG_EAX).
900
+ */
901
+ bool
902
+ reg_overlap(reg_id_t r1, reg_id_t r2);
903
+
904
+ /**
905
+ * Assumes that \p reg is a REG_ constant.
906
+ * Returns \p reg's representation as 3 bits in a modrm byte
907
+ * (the 3 bits are the lower-order bits in the return value).
908
+ */
909
+ byte
910
+ reg_get_bits(reg_id_t reg);
911
+
912
+ /**
913
+ * Assumes that \p reg is a REG_ constant.
914
+ * Returns the OPSZ_ constant corresponding to the register size.
915
+ * Returns OPSZ_NA if reg is not a REG_ constant.
916
+ */
917
+ opnd_size_t
918
+ reg_get_size(reg_id_t reg);
919
+
920
+ /**
921
+ * Assumes that \p reg is a REG_ constant.
922
+ * Returns true iff \p opnd refers to reg directly or refers to a register
923
+ * that overlaps \p reg (e.g., REG_AX overlaps REG_EAX).
924
+ */
925
+ bool
926
+ opnd_uses_reg(opnd_t opnd, reg_id_t reg);
927
+
928
+ /** Set the displacement of a memory reference operand \p opnd to \p disp. */
929
+ void
930
+ opnd_set_disp(opnd_t *opnd, int disp);
931
+
932
+ /**
933
+ * Set the displacement and encoding controls of a memory reference operand:
934
+ * - If \p encode_zero_disp, a zero value for \p disp will not be omitted;
935
+ * - If \p force_full_disp, a small value for \p disp will not occupy only one byte.
936
+ * -# If \p disp_short_addr, short (16-bit for 32-bit mode, 32-bit for
937
+ * 64-bit mode) addressing will be used (note that this normally only
938
+ * needs to be specified for an absolute address; otherwise, simply
939
+ * use the desired short registers for base and/or index).
940
+ */
941
+ void
942
+ opnd_set_disp_ex(opnd_t *opnd, int disp, bool encode_zero_disp, bool force_full_disp,
943
+ bool disp_short_addr);
944
+
945
+ /**
946
+ * Assumes that both \p old_reg and \p new_reg are REG_ constants.
947
+ * Replaces all occurrences of \p old_reg in \p *opnd with \p new_reg.
948
+ */
949
+ bool
950
+ opnd_replace_reg(opnd_t *opnd, reg_id_t old_reg, reg_id_t new_reg);
951
+
952
+ /** Returns true iff \p op1 and \p op2 are indistinguishable.
953
+ * If either uses variable operand sizes, the default size is assumed.
954
+ */
955
+ bool
956
+ opnd_same(opnd_t op1,opnd_t op2);
957
+
958
+ /**
959
+ * Returns true iff \p op1 and \p op2 are both memory references and they
960
+ * are indistinguishable, ignoring data size.
961
+ */
962
+ bool
963
+ opnd_same_address(opnd_t op1,opnd_t op2);
964
+
965
+ /**
966
+ * Returns true iff there exists some register that is refered to (directly
967
+ * or overlapping) by both \p op1 and \p op2.
968
+ */
969
+ bool
970
+ opnd_share_reg(opnd_t op1, opnd_t op2);
971
+
972
+ /**
973
+ * Returns true iff \p def, considered as a write, affects \p use.
974
+ * Is conservative, so if both \p def and \p use are memory references,
975
+ * will return true unless it can disambiguate them based on their
976
+ * registers and displacement.
977
+ */
978
+ bool
979
+ opnd_defines_use(opnd_t def, opnd_t use);
980
+
981
+ /**
982
+ * Assumes \p size is a OPSZ_ or a REG_ constant.
983
+ * If \p size is a REG_ constant, first calls reg_get_size(\p size)
984
+ * to get a OPSZ_ constant.
985
+ * Returns the number of bytes the OPSZ_ constant represents.
986
+ */
987
+ uint
988
+ opnd_size_in_bytes(opnd_size_t size);
989
+
990
+ /**
991
+ * Shrinks all 32-bit registers in \p opnd to their 16-bit versions.
992
+ * Also shrinks the size of immediate integers and memory references from
993
+ * OPSZ_4 to OPSZ_2.
994
+ */
995
+ opnd_t
996
+ opnd_shrink_to_16_bits(opnd_t opnd);
997
+ #ifdef X64
998
+
999
+
1000
+ /**
1001
+ * Shrinks all 64-bit registers in \p opnd to their 32-bit versions.
1002
+ * Also shrinks the size of immediate integers and memory references from
1003
+ * OPSZ_8 to OPSZ_4.
1004
+ *
1005
+ * \note For 64-bit DR builds only.
1006
+ */
1007
+ opnd_t
1008
+ opnd_shrink_to_32_bits(opnd_t opnd);
1009
+ #endif
1010
+
1011
+
1012
+ /**
1013
+ * Returns the value of the register \p reg, selected from the passed-in
1014
+ * register values.
1015
+ */
1016
+ reg_t
1017
+ reg_get_value(reg_id_t reg, dr_mcontext_t *mc);
1018
+
1019
+ /**
1020
+ * Sets the register \p reg in the passed in mcontext \p mc to \p value.
1021
+ * \note Current release is limited to setting pointer-sized registers only
1022
+ * (no sub-registers).
1023
+ */
1024
+ void
1025
+ reg_set_value(reg_id_t reg, dr_mcontext_t *mc, reg_t value);
1026
+
1027
+ /**
1028
+ * Returns the effective address of \p opnd, computed using the passed-in
1029
+ * register values. If \p opnd is a far address, ignores that aspect
1030
+ * except for TLS references on Windows (fs: for 32-bit, gs: for 64-bit)
1031
+ * or typical fs: or gs: references on Linux. For far addresses the
1032
+ * calling thread's segment selector is used.
1033
+ */
1034
+ app_pc
1035
+ opnd_compute_address(opnd_t opnd, dr_mcontext_t *mc);
1036
+
1037
+ /* Memory operand sizes (with Intel's corresponding size names noted).
1038
+ * For register operands, the REG_ constants are used, which implicitly
1039
+ * state a size (e.g., REG_CX is 2 bytes).
1040
+ * Use the type opnd_size_t for these values (we avoid typedef-ing the
1041
+ * enum, as its storage size is compiler-specific). opnd_size_t is a
1042
+ * byte, so the largest value here needs to be <= 255.
1043
+ */
1044
+ enum {
1045
+ /* register enum values are used for TYPE_*REG */
1046
+ OPSZ_NA = REG_LAST_ENUM+1, /**< Sentinel value: not a valid size. */ /* = 139 */
1047
+ OPSZ_0, /**< Intel 'm': "sizeless": used for both start addresses
1048
+ * (lea, invlpg) and implicit constants (rol, fldl2e, etc.) */
1049
+ OPSZ_1, /**< Intel 'b': 1 byte */
1050
+ OPSZ_2, /**< Intel 'w': 2 bytes */
1051
+ OPSZ_4, /**< Intel 'd','si': 4 bytes */
1052
+ OPSZ_6, /**< Intel 'p','s': 6 bytes */
1053
+ OPSZ_8, /**< Intel 'q','pi': 8 bytes */
1054
+ OPSZ_10, /**< Intel 's' 64-bit, or double extended precision floating point
1055
+ * (latter used by fld, fstp, fbld, fbstp) */
1056
+ OPSZ_16, /**< Intel 'dq','ps','pd','ss','sd': 16 bytes */
1057
+ OPSZ_14, /**< FPU operating environment with short data size (fldenv, fnstenv) */
1058
+ OPSZ_28, /**< FPU operating environment with normal data size (fldenv, fnstenv) */
1059
+ OPSZ_94, /**< FPU state with short data size (fnsave, frstor) */
1060
+ OPSZ_108, /**< FPU state with normal data size (fnsave, frstor) */
1061
+ OPSZ_512, /**< FPU, MMX, XMM state (fxsave, fxrstor) */
1062
+ /**
1063
+ * The following sizes (OPSZ_*_short*) vary according to the cs segment and the
1064
+ * operand size prefix. This IR assumes that the cs segment is set to the
1065
+ * default operand size. The operand size prefix then functions to shrink the
1066
+ * size. The IR does not explicitly mark the prefix; rather, a shortened size is
1067
+ * requested in the operands themselves, with the IR adding the prefix at encode
1068
+ * time. Normally the fixed sizes above should be used rather than these
1069
+ * variable sizes, which are used internally by the IR and should only be
1070
+ * externally specified when building an operand in order to be flexible and
1071
+ * allow other operands to decide the size for the instruction (the prefix
1072
+ * applies to the entire instruction).
1073
+ */
1074
+ OPSZ_2_short1, /**< Intel 'c': 2/1 bytes ("2/1" means 2 bytes normally, but if
1075
+ * another operand requests a short size then this size can
1076
+ * accomodate by shifting to its short size, which is 1 byte). */
1077
+ OPSZ_4_short2, /**< Intel 'z': 4/2 bytes */
1078
+ OPSZ_4_rex8_short2, /**< Intel 'v': 8/4/2 bytes */
1079
+ OPSZ_4_rex8, /**< Intel 'd/q' (like 'v' but never 2 bytes). */
1080
+ OPSZ_6_irex10_short4, /**< Intel 'p': On Intel processors this is 10/6/4 bytes for
1081
+ * segment selector + address. On AMD processors this is
1082
+ * 6/4 bytes for segment selector + address (rex is ignored). */
1083
+ OPSZ_8_short2, /**< partially resolved 4x8_short2 */
1084
+ OPSZ_8_short4, /**< Intel 'a': pair of 4_short2 (bound) */
1085
+ OPSZ_28_short14, /**< FPU operating env variable data size (fldenv, fnstenv) */
1086
+ OPSZ_108_short94, /**< FPU state with variable data size (fnsave, frstor) */
1087
+ /** Varies by 32-bit versus 64-bit processor mode. */
1088
+ OPSZ_4x8, /**< Full register size with no variation by prefix.
1089
+ * Used for control and debug register moves. */
1090
+ OPSZ_6x10, /**< Intel 's': 6-byte (10-byte for 64-bit mode) table base + limit */
1091
+ /**
1092
+ * Stack operands not only vary by operand size specifications but also
1093
+ * by 32-bit versus 64-bit processor mode.
1094
+ */
1095
+ OPSZ_4x8_short2, /**< Intel 'v'/'d64' for stack operations.
1096
+ * Also 64-bit address-size specified operands, which are
1097
+ * short4 rather than short2 in 64-bit mode (but short2 in
1098
+ * 32-bit mode).
1099
+ * Note that this IR does not distinguish multiple stack
1100
+ * operations; dispatch by opcode must be used:
1101
+ * X2 = far call/far ret
1102
+ * X3 = int/iret
1103
+ * X8 = pusha/popa
1104
+ * X* = enter (dynamically varying amount)
1105
+ * Note that stack operations may also modify the stack
1106
+ * pointer prior to accessing the top of the stack, so
1107
+ * for example "(esp)" may in fact be "4(esp)" depending
1108
+ * on the opcode.
1109
+ */
1110
+ OPSZ_4x8_short2xi8, /**< Intel 'f64': 4_short2 for 32-bit, 8_short2 for 64-bit AMD,
1111
+ * always 8 for 64-bit Intel */
1112
+ OPSZ_4_short2xi4, /**< Intel 'f64': 4_short2 for 32-bit or 64-bit AMD,
1113
+ * always 4 for 64-bit Intel */
1114
+ /**
1115
+ * The following sizes differ based on whether the modrm chooses a
1116
+ * register or memory.
1117
+ */
1118
+ OPSZ_1_reg4, /**< Intel Rd/Mb: zero-extends if reg; used by pextrb */
1119
+ OPSZ_2_reg4, /**< Intel Rd/Mw: zero-extends if reg; used by pextrw */
1120
+ OPSZ_4_reg16, /**< Intel Udq/Md: sub-xmm but we consider that whole xmm;
1121
+ * used by insertps. */
1122
+ OPSZ_LAST,
1123
+ };
1124
+
1125
+ #ifdef X64
1126
+ # define OPSZ_PTR OPSZ_8 /**< Operand size for pointer values. */
1127
+ # define OPSZ_STACK OPSZ_8 /**< Operand size for stack push/pop operand sizes. */
1128
+ #else
1129
+ # define OPSZ_PTR OPSZ_4 /**< Operand size for pointer values. */
1130
+ # define OPSZ_STACK OPSZ_4 /**< Operand size for stack push/pop operand sizes. */
1131
+ #endif
1132
+ #define OPSZ_VARSTACK OPSZ_4x8_short2 /**< Operand size for prefix-varying stack
1133
+ * push/pop operand sizes. */
1134
+ #define OPSZ_REXVARSTACK OPSZ_4_rex8_short2 /* Operand size for prefix/rex-varying
1135
+ * stack push/pop like operand sizes. */
1136
+
1137
+ #define OPSZ_ret OPSZ_4x8_short2xi8 /**< Operand size for ret instruction. */
1138
+ #define OPSZ_call OPSZ_ret /**< Operand size for push portion of call. */
1139
+
1140
+ /* Convenience defines for specific opcodes */
1141
+ #define OPSZ_lea OPSZ_0 /**< Operand size for lea memory reference. */
1142
+ #define OPSZ_invlpg OPSZ_0 /**< Operand size for invlpg memory reference. */
1143
+ #define OPSZ_xlat OPSZ_1 /**< Operand size for xlat memory reference. */
1144
+ #define OPSZ_clflush OPSZ_1 /**< Operand size for clflush memory reference. */
1145
+ #define OPSZ_prefetch OPSZ_1 /**< Operand size for prefetch memory references. */
1146
+ #define OPSZ_lgdt OPSZ_6x10 /**< Operand size for lgdt memory reference. */
1147
+ #define OPSZ_sgdt OPSZ_6x10 /**< Operand size for sgdt memory reference. */
1148
+ #define OPSZ_lidt OPSZ_6x10 /**< Operand size for lidt memory reference. */
1149
+ #define OPSZ_sidt OPSZ_6x10 /**< Operand size for sidt memory reference. */
1150
+ #define OPSZ_bound OPSZ_8_short4 /**< Operand size for bound memory reference. */
1151
+ #define OPSZ_maskmovq OPSZ_8 /**< Operand size for maskmovq memory reference. */
1152
+ #define OPSZ_maskmovdqu OPSZ_16 /**< Operand size for maskmovdqu memory reference. */
1153
+ #define OPSZ_fldenv OPSZ_28_short14 /**< Operand size for fldenv memory reference. */
1154
+ #define OPSZ_fnstenv OPSZ_28_short14 /**< Operand size for fnstenv memory reference. */
1155
+ #define OPSZ_fnsave OPSZ_108_short94 /**< Operand size for fnsave memory reference. */
1156
+ #define OPSZ_frstor OPSZ_108_short94 /**< Operand size for frstor memory reference. */
1157
+ #define OPSZ_fxsave OPSZ_512 /**< Operand size for fxsave memory reference. */
1158
+ #define OPSZ_fxrstor OPSZ_512 /**< Operand size for fxrstor memory reference. */
1159
+
1160
+
1161
+ /**
1162
+ * Prints the operand \p opnd to file \p outfile.
1163
+ * The default is to use AT&T-style syntax, unless the \ref op_syntax_intel
1164
+ * "-syntax_intel" runtime option is specified.
1165
+ */
1166
+ void
1167
+ opnd_disassemble(void *drcontext, opnd_t opnd, file_t outfile);
1168
+
1169
+
1170
+ #endif /* _DR_IR_OPND_H_ */