duran 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.rdoc +11 -0
- data/Rakefile +29 -0
- data/VERSION +1 -0
- data/client_src/dr_include/dr_api.h +102 -0
- data/client_src/dr_include/dr_app.h +92 -0
- data/client_src/dr_include/dr_config.h +650 -0
- data/client_src/dr_include/dr_defines.h +391 -0
- data/client_src/dr_include/dr_events.h +1057 -0
- data/client_src/dr_include/dr_ir_instr.h +1214 -0
- data/client_src/dr_include/dr_ir_instrlist.h +149 -0
- data/client_src/dr_include/dr_ir_macros.h +2426 -0
- data/client_src/dr_include/dr_ir_opcodes.h +768 -0
- data/client_src/dr_include/dr_ir_opnd.h +1170 -0
- data/client_src/dr_include/dr_ir_utils.h +708 -0
- data/client_src/dr_include/dr_proc.h +327 -0
- data/client_src/dr_include/dr_tools.h +1304 -0
- data/client_src/duran.c +57 -0
- data/client_src/extconf.rb +28 -0
- data/lib/duran.rb +18 -0
- data/lib/duran/app.rb +8 -0
- data/lib/duran/defines.rb +39 -0
- data/lib/duran/events.rb +156 -0
- data/lib/duran/ir_opcodes.rb +616 -0
- data/lib/duran/ir_opnd.rb +329 -0
- data/lib/duran/ir_utils.rb +133 -0
- data/lib/duran/proc.rb +49 -0
- data/lib/duran/structs.rb +20 -0
- data/lib/duran/structs/exception.rb +23 -0
- data/lib/duran/structs/fault_fragment_info.rb +34 -0
- data/lib/duran/structs/instruction.rb +15 -0
- data/lib/duran/structs/machine_context.rb +80 -0
- data/lib/duran/structs/memory_info.rb +12 -0
- data/lib/duran/structs/module_data.rb +61 -0
- data/lib/duran/structs/module_names.rb +24 -0
- data/lib/duran/structs/operand.rb +15 -0
- data/lib/duran/structs/restore_state_info.rb +30 -0
- data/lib/duran/structs/signal_info.rb +41 -0
- data/lib/duran/structs/tracedump.rb +50 -0
- data/lib/duran/tools.rb +214 -0
- metadata +104 -0
@@ -0,0 +1,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_ */
|