VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/utils/cpu/cidet.h@ 53563

Last change on this file since 53563 was 53563, checked in by vboxsync, 10 years ago

cidet: More hacking.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 41.0 KB
Line 
1/* $Id: cidet.h 53563 2014-12-18 02:31:37Z vboxsync $ */
2/** @file
3 * CPU Instruction Decoding & Execution Tests - C/C++ Header.
4 */
5
6/*
7 * Copyright (C) 2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28#ifndef ___cidet_h___
29#define ___cidet_h___
30
31#include <iprt/types.h>
32#include <iprt/x86.h>
33
34
35/** @name CIDET - Operand flags.
36 * @{ */
37#define CIDET_OF_FIXED_MASK UINT32_C(0x0000001f) /**< Fixed register/whatever mask. */
38
39#define CIDET_OF_Z_SHIFT 8 /**< Size shift. */
40#define CIDET_OF_Z_MASK UINT32_C(0x00000f00) /**< Size mask. */
41#define CIDET_OF_Z_NONE UINT32_C(0x00000000) /**< Unused zero value. */
42#define CIDET_OF_Z_BYTE UINT32_C(0x00000100) /**< Byte size. */
43#define CIDET_OF_Z_WORD UINT32_C(0x00000200) /**< Word (2 bytes) size. */
44#define CIDET_OF_Z_DWORD UINT32_C(0x00000300) /**< Double word (4 bytes) size. */
45#define CIDET_OF_Z_QWORD UINT32_C(0x00000400) /**< Quad word (8 bytes) size. */
46#define CIDET_OF_Z_TBYTE UINT32_C(0x00000500) /**< Ten byte (10 bytes) size - aka TWORD. */
47#define CIDET_OF_Z_OWORD UINT32_C(0x00000600) /**< Octa word (16 bytes) size - aka DQWORD. */
48#define CIDET_OF_Z_YWORD UINT32_C(0x00000700) /**< Yxx sized, i.e. 32 bytes. */
49#define CIDET_OF_Z_ZWORD UINT32_C(0x00000800) /**< Zxx sized, i.e. 64 bytes. */
50#define CIDET_OF_Z_VAR_WDQ UINT32_C(0x00000900) /**< Variable size depending on size prefix (2, 4, or 8 bytes). */
51#define CIDET_OF_Z_SPECIAL UINT32_C(0x00000f00) /**< Special size, see instruction flags or smth. */
52
53#define CIDET_OF_K_MASK UINT32_C(0x0000f000) /**< Kind of operand. */
54#define CIDET_OF_K_NONE UINT32_C(0x00000000) /**< Unused zero value. */
55#define CIDET_OF_K_GPR UINT32_C(0x00001000) /**< General purpose register. Includes memory when used with CIDET_OF_M_RM. */
56#define CIDET_OF_K_SREG UINT32_C(0x00002000) /**< Segment register. */
57#define CIDET_OF_K_CR UINT32_C(0x00003000) /**< Control register. */
58#define CIDET_OF_K_SSE UINT32_C(0x00004000) /**< SSE register. */
59#define CIDET_OF_K_AVX UINT32_C(0x00005000) /**< AVX register. */
60#define CIDET_OF_K_AVX512 UINT32_C(0x00006000) /**< AVX-512 register. */
61#define CIDET_OF_K_AVXFUTURE UINT32_C(0x00007000) /**< Reserved for future AVX register set. */
62#define CIDET_OF_K_VRX_TST_MASK UINT32_C(0x0000c000) /**< Used for testing for VRX register kind, see CIDET_OF_K_IS_VRX. */
63#define CIDET_OF_K_VRX_TST_RES UINT32_C(0x00004000) /**< Used for testing for VRX register kind, see CIDET_OF_K_IS_VRX. */
64#define CIDET_OF_K_FPU UINT32_C(0x00008000) /**< FPU register. */
65#define CIDET_OF_K_MMX UINT32_C(0x00009000) /**< MMX register. */
66#define CIDET_OF_K_TEST UINT32_C(0x0000a000) /**< Test register. */
67#define CIDET_OF_K_IMM UINT32_C(0x0000d000) /**< Immediate. */
68#define CIDET_OF_K_MEM UINT32_C(0x0000e000) /**< Memory. */
69#define CIDET_OF_K_SPECIAL UINT32_C(0x0000f000) /**< Special. */
70/** Check if @a a_fOp is a general purpose register. */
71#define CIDET_OF_K_IS_GPR(a_fOp) ( ((a_fOp) & CIDET_OF_K_MASK) == CIDET_OF_K_GPR )
72/** Check if @a a_fOp is a XMM (SSE), YMM (AVX), ZMM (AVX-512) or similar register. */
73#define CIDET_OF_K_IS_VRX(a_fOp) ( ((a_fOp) & CIDET_OF_K_VRX_TST_MASK) == CIDET_OF_K_VRX_TST_RES )
74/** Check if @a a_fOp1 and @a a_fOp2 specify the same kind of register,
75 * treating SSE, AVX, AVX-512 and AVX-future as the same kind and ignoring the
76 * special register kind. */
77#define CIDET_OF_K_IS_SAME(a_fOp1, a_fOp2) \
78 ( ((a_fOp1) & CIDET_OF_K_MASK) == ((a_fOp2) & CIDET_OF_K_MASK) \
79 ? ((a_fOp1) & CIDET_OF_K_MASK) != CIDET_OF_K_SPECIAL \
80 : (CIDET_OF_K_IS_VRX(a_fOp1) && CIDET_OF_K_IS_VRX(a_fOp2)) )
81
82#define CIDET_OF_M_RM_ONLY_R UINT32_C(0x00010000)
83#define CIDET_OF_M_RM_ONLY_M UINT32_C(0x00020000)
84#define CIDET_OF_M_RM (CIDET_OF_M_RM_ONLY_R | CIDET_OF_M_RM_ONLY_M)
85#define CIDET_OF_M_REG UINT32_C(0x00040000)
86
87/** The operand defaults to 64-bit width in 64-bit mode, making 32-bit width
88 * inaccessible. */
89#define CIDET_OF_DEFAULT_64BIT UINT32_C(0x40000000)
90/** Operand always uses the ES segment for memory accesses. */
91#define CIDET_OF_ALWAYS_SEG_ES UINT32_C(0x80000000)
92/** @} */
93
94
95/** @name CIDET - Instruction flags.
96 * @{ */
97#define CIDET_IF_MODRM RT_BIT_64(0) /**< ModR/M encoded. */
98#define CIDET_IF_PRIVILEGED RT_BIT_64(1) /**< Privileged. */
99/** @} */
100
101
102/**
103 * Callback function for setting up the input and expected output CPU contexts.
104 *
105 * @returns VBox status.
106 * @retval VINF_EOF when static test data wraps (first entry is returned).
107 * @retval VERR_NO_DATA if @a fInvalid is set and there are no invalid operand
108 * values for this instruction.
109 *
110 * @param pThis The core CIDET state structure. The InCtx
111 * and ExpectedCtx members will be modified.
112 * @param fInvalid When set, get the next invalid operands that will
113 * cause exceptions/faults.
114 */
115typedef int FNCIDETSETUPINOUT(struct CIDETCORE *pThis, bool fInvalid);
116/** Pointer to a FNCIDETSETUPINOUT function. */
117typedef FNCIDETSETUPINOUT *PFNCIDETSETUPINOUT;
118
119
120/**
121 * Instruction test descriptor.
122 */
123typedef struct CIDETINSTR
124{
125 /** The mnemonic (kind of). */
126 const char *pszMnemonic;
127 /** Setup input and outputs. */
128 PFNCIDETSETUPINOUT pfnSetupInOut;
129 /** Number of opcode bytes. */
130 uint8_t cbOpcode;
131 /** Opcode byte(s). */
132 uint8_t abOpcode[3];
133 /** Mandatory prefix (zero if not applicable). */
134 uint8_t bMandatoryPrefix;
135 /** Number of operands. */
136 uint8_t cOperands;
137 /** Operand flags. */
138 uint32_t afOperands[4];
139 /** Flags. */
140 uint64_t fFlags;
141} CIDETINSTR;
142/** Pointer to an instruction test descriptor. */
143typedef CIDETINSTR const *PCCIDETINSTR;
144
145
146/**
147 * CPU Context with a few extra bits for expectations and results.
148 */
149typedef struct CIDETCPUCTX
150{
151 uint64_t rip;
152 uint64_t rfl;
153 uint64_t aGRegs[16];
154 uint16_t aSRegs[6];
155
156 uint16_t tr;
157 uint16_t ldtr;
158 uint64_t cr0;
159 uint64_t cr2;
160 uint64_t cr3;
161 uint64_t cr4;
162 uint64_t cr8;
163 uint64_t dr0;
164 uint64_t dr1;
165 uint64_t dr2;
166 uint64_t dr3;
167 uint64_t dr6;
168 uint64_t dr7;
169
170 uint32_t fIgnoredRFlags; /**< Only for expected result. */
171 uint32_t uXcpt; /**< Exception number. UINT32_MAX if no exception. (Not for input context.) */
172 uint64_t uErr; /**< Exception error code. UINT64_MAX if not applicable. (Not for input context.) */
173
174 bool fTrickyStack; /**< Set if the stack might be bad. May come at the cost of accurate flags (32-bit). */
175
176} CIDETCPUCTX;
177typedef CIDETCPUCTX *PCIDETCPUCTX;
178typedef CIDETCPUCTX const *PCCIDETCPUCTX;
179
180
181/** @name CPU mode + bits + environment.
182 * @{ */
183#define CIDETMODE_BIT_MASK UINT8_C(0x0e) /**< The instruction bit count. Results in byte size when masked. */
184#define CIDETMODE_BIT_16 UINT8_C(0x02) /**< 16-bit instructions. */
185#define CIDETMODE_BIT_32 UINT8_C(0x04) /**< 32-bit instructions. */
186#define CIDETMODE_BIT_64 UINT8_C(0x08) /**< 64-bit instructions. */
187#define CIDETMODE_MODE_MASK UINT8_C(0x70) /**< CPU mode mask. */
188#define CIDETMODE_MODE_RM UINT8_C(0x00) /**< Real mode. */
189#define CIDETMODE_MODE_PE UINT8_C(0x10) /**< Protected mode without paging. */
190#define CIDETMODE_MODE_PP UINT8_C(0x20) /**< Paged protected mode. */
191#define CIDETMODE_MODE_PAE UINT8_C(0x30) /**< PAE protected mode (paged). */
192#define CIDETMODE_MODE_LM UINT8_C(0x40) /**< Long mode (paged). */
193#define CIDETMODE_ENV_MASK UINT8_C(0x81) /**< Execution environment. */
194#define CIDETMODE_ENV_NORMAL UINT8_C(0x01) /**< Normal environment. */
195#define CIDETMODE_ENV_V86 UINT8_C(0x80) /**< V8086 environment. */
196#define CIDETMODE_RM (CIDETMODE_MODE_RM | CIDETMODE_BIT_16 | CIDETMODE_ENV_NORMAL)
197#define CIDETMODE_PE_16 (CIDETMODE_MODE_PE | CIDETMODE_BIT_16 | CIDETMODE_ENV_NORMAL)
198#define CIDETMODE_PE_32 (CIDETMODE_MODE_PE | CIDETMODE_BIT_32 | CIDETMODE_ENV_NORMAL)
199#define CIDETMODE_PE_V86 (CIDETMODE_MODE_PE | CIDETMODE_BIT_16 | CIDETMODE_ENV_V86)
200#define CIDETMODE_PP_16 (CIDETMODE_MODE_PP | CIDETMODE_BIT_16 | CIDETMODE_ENV_NORMAL)
201#define CIDETMODE_PP_32 (CIDETMODE_MODE_PP | CIDETMODE_BIT_32 | CIDETMODE_ENV_NORMAL)
202#define CIDETMODE_PP_V86 (CIDETMODE_MODE_PP | CIDETMODE_BIT_16 | CIDETMODE_ENV_V86)
203#define CIDETMODE_PAE_16 (CIDETMODE_MODE_PAE | CIDETMODE_BIT_16 | CIDETMODE_ENV_NORMAL)
204#define CIDETMODE_PAE_32 (CIDETMODE_MODE_PAE | CIDETMODE_BIT_32 | CIDETMODE_ENV_NORMAL)
205#define CIDETMODE_PAE_V86 (CIDETMODE_MODE_PAE | CIDETMODE_BIT_16 | CIDETMODE_ENV_V86)
206#define CIDETMODE_LM_16 (CIDETMODE_MODE_LM | CIDETMODE_BIT_16 | CIDETMODE_ENV_NORMAL)
207#define CIDETMODE_LM_32 (CIDETMODE_MODE_LM | CIDETMODE_BIT_32 | CIDETMODE_ENV_NORMAL)
208#define CIDETMODE_LM_64 (CIDETMODE_MODE_LM | CIDETMODE_BIT_64 | CIDETMODE_ENV_NORMAL)
209/** Test if @a a_bMode is a 16-bit mode. */
210#define CIDETMODE_IS_16BIT(a_bMode) ( ((a_bMode) & CIDETMODE_BIT_MASK) == CIDETMODE_BIT_16 )
211/** Test if @a a_bMode is a 32-bit mode. */
212#define CIDETMODE_IS_32BIT(a_bMode) ( ((a_bMode) & CIDETMODE_BIT_MASK) == CIDETMODE_BIT_32 )
213/** Test if @a a_bMode is a 64-bit mode. */
214#define CIDETMODE_IS_64BIT(a_bMode) ( ((a_bMode) & CIDETMODE_BIT_MASK) == CIDETMODE_BIT_64 )
215/** Get the instruction bit count. */
216#define CIDETMODE_GET_BIT_COUNT(a_bMode) ( CIDETMODE_GET_BYTE_COUNT(a_bMode) * 8 )
217/** Get the instruction byte count. */
218#define CIDETMODE_GET_BYTE_COUNT(a_bMode) ( (a_bMode) & CIDETMODE_BIT_MASK )
219/** Test if @a a_bMode long mode. */
220#define CIDETMODE_IS_LM(a_bMode) ( ((a_bMode) & CIDETMODE_MODE_MASK) == CIDETMODE_MODE_LM )
221/** Test if @a a_bMode some kind of protected mode. */
222#define CIDETMODE_IS_PROT(a_bMode) ( ((a_bMode) & CIDETMODE_MODE_MASK) >= CIDETMODE_MODE_PE )
223
224/** @} */
225
226
227/** @name Test Configuration Flags.
228 * @{ */
229#define CIDET_TESTCFG_SEG_PRF_CS UINT64_C(0x0000000000000001)
230#define CIDET_TESTCFG_SEG_PRF_SS UINT64_C(0x0000000000000002)
231#define CIDET_TESTCFG_SEG_PRF_DS UINT64_C(0x0000000000000004)
232#define CIDET_TESTCFG_SEG_PRF_ES UINT64_C(0x0000000000000008)
233#define CIDET_TESTCFG_SEG_PRF_FS UINT64_C(0x0000000000000010)
234#define CIDET_TESTCFG_SEG_PRF_GS UINT64_C(0x0000000000000020)
235#define CIDET_TESTCFG_SEG_PRF_MASK UINT64_C(0x000000000000003f)
236/** @} */
237
238/** */
239typedef enum CIDETREG
240{
241 kCidetReg_Gpr_Invalid = 0,
242
243 kCidetReg_Gpr_al,
244 kCidetReg_Gpr_cl,
245 kCidetReg_Gpr_dl,
246 kCidetReg_Gpr_bl,
247 kCidetReg_Gpr_spl,
248 kCidetReg_Gpr_bpl,
249 kCidetReg_Gpr_sil,
250 kCidetReg_Gpr_dil,
251 kCidetReg_Gpr_r8b,
252 kCidetReg_Gpr_r9b,
253 kCidetReg_Gpr_r10b,
254 kCidetReg_Gpr_r11b,
255 kCidetReg_Gpr_r12b,
256 kCidetReg_Gpr_r13b,
257 kCidetReg_Gpr_r14b,
258 kCidetReg_Gpr_r15b,
259 kCidetReg_Gpr_ah,
260 kCidetReg_Gpr_ch,
261 kCidetReg_Gpr_dh,
262 kCidetReg_Gpr_bh,
263#define kCidetReg_Gpr_Byte_First kCidetReg_Gpr_al
264#define kCidetReg_Gpr_Byte_First_Upper kCidetReg_Gpr_ah
265#define kCidetReg_Gpr_Byte_Last kCidetReg_Gpr_bh
266
267 kCidetReg_Gpr_ax,
268 kCidetReg_Gpr_cx,
269 kCidetReg_Gpr_dx,
270 kCidetReg_Gpr_bx,
271 kCidetReg_Gpr_sp,
272 kCidetReg_Gpr_bp,
273 kCidetReg_Gpr_si,
274 kCidetReg_Gpr_di,
275 kCidetReg_Gpr_r8w,
276 kCidetReg_Gpr_r9w,
277 kCidetReg_Gpr_r10w,
278 kCidetReg_Gpr_r11w,
279 kCidetReg_Gpr_r12w,
280 kCidetReg_Gpr_r13w,
281 kCidetReg_Gpr_r14w,
282 kCidetReg_Gpr_r15w,
283#define kCidetReg_Gpr_Word_First kCidetReg_Gpr_ax
284#define kCidetReg_Gpr_Word_Last kCidetReg_Gpr_r15w
285
286 kCidetReg_Gpr_eax,
287 kCidetReg_Gpr_ecx,
288 kCidetReg_Gpr_edx,
289 kCidetReg_Gpr_ebx,
290 kCidetReg_Gpr_esp,
291 kCidetReg_Gpr_ebp,
292 kCidetReg_Gpr_esi,
293 kCidetReg_Gpr_edi,
294 kCidetReg_Gpr_r8d,
295 kCidetReg_Gpr_r9d,
296 kCidetReg_Gpr_r10d,
297 kCidetReg_Gpr_r11d,
298 kCidetReg_Gpr_r12d,
299 kCidetReg_Gpr_r13d,
300 kCidetReg_Gpr_r14d,
301 kCidetReg_Gpr_r15d,
302#define kCidetReg_Gpr_DWord_First kCidetReg_Gpr_eax
303#define kCidetReg_Gpr_DWord_Last kCidetReg_Gpr_r15d
304
305 kCidetReg_Gpr_rax,
306 kCidetReg_Gpr_rcx,
307 kCidetReg_Gpr_rdx,
308 kCidetReg_Gpr_rbx,
309 kCidetReg_Gpr_rsp,
310 kCidetReg_Gpr_rbp,
311 kCidetReg_Gpr_rsi,
312 kCidetReg_Gpr_rdi,
313 kCidetReg_Gpr_r8,
314 kCidetReg_Gpr_r9,
315 kCidetReg_Gpr_r10,
316 kCidetReg_Gpr_r11,
317 kCidetReg_Gpr_r12,
318 kCidetReg_Gpr_r13,
319 kCidetReg_Gpr_r14,
320 kCidetReg_Gpr_r15,
321#define kCidetReg_Gpr_QWord_First kCidetReg_Gpr_rax
322#define kCidetReg_Gpr_QWord_Last kCidetReg_Gpr_r15
323
324 kCidetReg_Seg_es,
325 kCidetReg_Seg_cs,
326 kCidetReg_Seg_ss,
327 kCidetReg_Seg_ds,
328 kCidetReg_Seg_fs,
329 kCidetReg_Seg_gs,
330 kCidetReg_Seg_Inv6,
331 kCidetReg_Seg_Inv7,
332#define kCidetReg_Seg_First kCidetReg_Seg_es
333#define kCidetReg_Seg_Last kCidetReg_Seg_gs
334#define kCidetReg_Seg_Last_Inv kCidetReg_Seg_Inv7
335
336 kCidetReg_Misc_ip,
337 kCidetReg_Misc_eip,
338 kCidetReg_Misc_rip,
339 kCidetReg_Misc_flags,
340 kCidetReg_Misc_eflags,
341 kCidetReg_Misc_rflags,
342 kCidetReg_Misc_tr,
343 kCidetReg_Misc_ldtr,
344 kCidetReg_Misc_gdtr,
345 kCidetReg_Misc_idtr,
346
347 kCidetReg_Ctrl_cr0,
348 kCidetReg_Ctrl_cr1,
349 kCidetReg_Ctrl_cr2,
350 kCidetReg_Ctrl_cr3,
351 kCidetReg_Ctrl_cr4,
352 kCidetReg_Ctrl_cr5,
353 kCidetReg_Ctrl_cr6,
354 kCidetReg_Ctrl_cr7,
355 kCidetReg_Ctrl_cr8,
356 kCidetReg_Ctrl_cr9,
357 kCidetReg_Ctrl_cr10,
358 kCidetReg_Ctrl_cr11,
359 kCidetReg_Ctrl_cr12,
360 kCidetReg_Ctrl_cr13,
361 kCidetReg_Ctrl_cr14,
362 kCidetReg_Ctrl_cr15,
363#define kCidetReg_Ctrl_First kCidetReg_Ctrl_cr0
364#define kCidetReg_Ctrl_Last kCidetReg_Ctrl_cr15
365#define CIDETREG_CTRL_IS_VALID(a_iReg) ( (a_iReg) == kCidetReg_Ctrl_cr0 \
366 && (a_iReg) == kCidetReg_Ctrl_cr2 \
367 && (a_iReg) == kCidetReg_Ctrl_cr3 \
368 && (a_iReg) == kCidetReg_Ctrl_cr4 \
369 && (a_iReg) == kCidetReg_Ctrl_cr8 )
370
371 kCidetReg_Dbg_dr0,
372 kCidetReg_Dbg_dr1,
373 kCidetReg_Dbg_dr2,
374 kCidetReg_Dbg_dr3,
375 kCidetReg_Dbg_dr4,
376 kCidetReg_Dbg_dr5,
377 kCidetReg_Dbg_dr6,
378 kCidetReg_Dbg_dr7,
379 kCidetReg_Dbg_dr8,
380 kCidetReg_Dbg_dr9,
381 kCidetReg_Dbg_dr10,
382 kCidetReg_Dbg_dr11,
383 kCidetReg_Dbg_dr12,
384 kCidetReg_Dbg_dr13,
385 kCidetReg_Dbg_dr14,
386 kCidetReg_Dbg_dr15,
387#define kCidetReg_Dbg_First kCidetReg_Dbg_dr0
388#define kCidetReg_Dbg_Last kCidetReg_Dbg_dr15
389#define CIDETREG_DBG_IS_VALID(a_iReg) ((a_iReg) < kCidetReg_Dbg_dr8 && (a_iReg) >= kCidetReg_Dbg_First)
390
391 kCidetReg_Test_tr0,
392 kCidetReg_Test_tr1,
393 kCidetReg_Test_tr2,
394 kCidetReg_Test_tr3,
395 kCidetReg_Test_tr4,
396 kCidetReg_Test_tr5,
397 kCidetReg_Test_tr6,
398 kCidetReg_Test_tr7,
399 kCidetReg_Test_tr8,
400 kCidetReg_Test_tr9,
401 kCidetReg_Test_tr10,
402 kCidetReg_Test_tr11,
403 kCidetReg_Test_tr12,
404 kCidetReg_Test_tr13,
405 kCidetReg_Test_tr14,
406 kCidetReg_Test_tr15,
407#define kCidetReg_Test_First kCidetReg_Test_tr0
408#define kCidetReg_Test_Last kCidetReg_Test_tr15
409
410 kCidetReg_Fpu_st0,
411 kCidetReg_Fpu_st1,
412 kCidetReg_Fpu_st2,
413 kCidetReg_Fpu_st3,
414 kCidetReg_Fpu_st4,
415 kCidetReg_Fpu_st5,
416 kCidetReg_Fpu_st6,
417 kCidetReg_Fpu_st7,
418#define kCidetReg_Fpu_First kCidetReg_Mmx_st0
419#define kCidetReg_Fpu_Last kCidetReg_Mmx_st7
420
421 kCidetReg_FpuMisc_cs,
422 kCidetReg_FpuMisc_ip,
423 kCidetReg_FpuMisc_ds,
424 kCidetReg_FpuMisc_dp,
425 kCidetReg_FpuMisc_fop,
426 kCidetReg_FpuMisc_ftw,
427 kCidetReg_FpuMisc_fsw,
428 kCidetReg_FpuMisc_fcw,
429 kCidetReg_FpuMisc_mxcsr_mask,
430 kCidetReg_FpuMisc_mxcsr,
431
432 kCidetReg_Mmx_mm0,
433 kCidetReg_Mmx_mm1,
434 kCidetReg_Mmx_mm2,
435 kCidetReg_Mmx_mm3,
436 kCidetReg_Mmx_mm4,
437 kCidetReg_Mmx_mm5,
438 kCidetReg_Mmx_mm6,
439 kCidetReg_Mmx_mm7,
440#define kCidetReg_Mmx_First kCidetReg_Mmx_mm0
441#define kCidetReg_Mmx_Last kCidetReg_Mmx_mm7
442
443 kCidetReg_Sse_xmm0,
444 kCidetReg_Sse_xmm1,
445 kCidetReg_Sse_xmm2,
446 kCidetReg_Sse_xmm3,
447 kCidetReg_Sse_xmm4,
448 kCidetReg_Sse_xmm5,
449 kCidetReg_Sse_xmm6,
450 kCidetReg_Sse_xmm7,
451 kCidetReg_Sse_xmm8,
452 kCidetReg_Sse_xmm9,
453 kCidetReg_Sse_xmm10,
454 kCidetReg_Sse_xmm11,
455 kCidetReg_Sse_xmm12,
456 kCidetReg_Sse_xmm13,
457 kCidetReg_Sse_xmm14,
458 kCidetReg_Sse_xmm15,
459 kCidetReg_Sse_xmm16,
460 kCidetReg_Sse_xmm17,
461 kCidetReg_Sse_xmm18,
462 kCidetReg_Sse_xmm19,
463 kCidetReg_Sse_xmm20,
464 kCidetReg_Sse_xmm21,
465 kCidetReg_Sse_xmm22,
466 kCidetReg_Sse_xmm23,
467 kCidetReg_Sse_xmm24,
468 kCidetReg_Sse_xmm25,
469 kCidetReg_Sse_xmm26,
470 kCidetReg_Sse_xmm27,
471 kCidetReg_Sse_xmm28,
472 kCidetReg_Sse_xmm29,
473 kCidetReg_Sse_xmm30,
474 kCidetReg_Sse_xmm31,
475#define kCidetReg_Sse_First kCidetReg_Mmx_Xmm0
476#define kCidetReg_Sse_Last kCidetReg_Mmx_Xmm15
477#define kCidetReg_Sse_Last_Avx512 kCidetReg_Mmx_Xmm31
478
479 kCidetReg_Avx_Ymm0,
480 kCidetReg_Avx_Ymm1,
481 kCidetReg_Avx_Ymm2,
482 kCidetReg_Avx_Ymm3,
483 kCidetReg_Avx_Ymm4,
484 kCidetReg_Avx_Ymm5,
485 kCidetReg_Avx_Ymm6,
486 kCidetReg_Avx_Ymm7,
487 kCidetReg_Avx_Ymm8,
488 kCidetReg_Avx_Ymm9,
489 kCidetReg_Avx_Ymm10,
490 kCidetReg_Avx_Ymm11,
491 kCidetReg_Avx_Ymm12,
492 kCidetReg_Avx_Ymm13,
493 kCidetReg_Avx_Ymm14,
494 kCidetReg_Avx_Ymm15,
495 kCidetReg_Avx_Ymm16,
496 kCidetReg_Avx_Ymm17,
497 kCidetReg_Avx_Ymm18,
498 kCidetReg_Avx_Ymm19,
499 kCidetReg_Avx_Ymm20,
500 kCidetReg_Avx_Ymm21,
501 kCidetReg_Avx_Ymm22,
502 kCidetReg_Avx_Ymm23,
503 kCidetReg_Avx_Ymm24,
504 kCidetReg_Avx_Ymm25,
505 kCidetReg_Avx_Ymm26,
506 kCidetReg_Avx_Ymm27,
507 kCidetReg_Avx_Ymm28,
508 kCidetReg_Avx_Ymm29,
509 kCidetReg_Avx_Ymm30,
510 kCidetReg_Avx_Ymm31,
511#define kCidetReg_Avx_First kCidetReg_Avx_Ymm0
512#define kCidetReg_Avx_Last kCidetReg_Avx_Ymm15
513#define kCidetReg_Avx_Last_Avx512 kCidetReg_Avx_Ymm31
514
515 kCidetReg_Avx512_Zmm0,
516 kCidetReg_Avx512_Zmm1,
517 kCidetReg_Avx512_Zmm2,
518 kCidetReg_Avx512_Zmm3,
519 kCidetReg_Avx512_Zmm4,
520 kCidetReg_Avx512_Zmm5,
521 kCidetReg_Avx512_Zmm6,
522 kCidetReg_Avx512_Zmm7,
523 kCidetReg_Avx512_Zmm8,
524 kCidetReg_Avx512_Zmm9,
525 kCidetReg_Avx512_Zmm10,
526 kCidetReg_Avx512_Zmm11,
527 kCidetReg_Avx512_Zmm12,
528 kCidetReg_Avx512_Zmm13,
529 kCidetReg_Avx512_Zmm14,
530 kCidetReg_Avx512_Zmm15,
531 kCidetReg_Avx512_Zmm16,
532 kCidetReg_Avx512_Zmm17,
533 kCidetReg_Avx512_Zmm18,
534 kCidetReg_Avx512_Zmm19,
535 kCidetReg_Avx512_Zmm20,
536 kCidetReg_Avx512_Zmm21,
537 kCidetReg_Avx512_Zmm22,
538 kCidetReg_Avx512_Zmm23,
539 kCidetReg_Avx512_Zmm24,
540 kCidetReg_Avx512_Zmm25,
541 kCidetReg_Avx512_Zmm26,
542 kCidetReg_Avx512_Zmm27,
543 kCidetReg_Avx512_Zmm28,
544 kCidetReg_Avx512_Zmm29,
545 kCidetReg_Avx512_Zmm30,
546 kCidetReg_Avx512_Zmm31,
547#define kCidetReg_Avx512_First kCidetReg_Avx512_Zmm0
548#define kCidetReg_Avx512_Last kCidetReg_Avx512_Zmm31
549
550 kCidetReg_End
551} CIDETREG;
552
553
554/** @name CIDETBUF_XXX - buffer flags.
555 * @{ */
556#define CIDETBUF_PROT_MASK UINT32_C(0x0000000f) /**< Page protection mask. */
557#define CIDETBUF_PROT_RWX UINT32_C(0x00000001) /**< Read + write + execute. */
558#define CIDETBUF_PROT_RWNX UINT32_C(0x00000002) /**< Read + write + no execute. */
559#define CIDETBUF_PROT_RX UINT32_C(0x00000003) /**< Read + execute. */
560#define CIDETBUF_PROT_RNX UINT32_C(0x00000004) /**< Read + no execute. */
561#define CIDETBUF_PROT_RWX_1NP UINT32_C(0x00000005) /**< Read + write + execute; 1 page not present. */
562#define CIDETBUF_PROT_RWX_1RWNX UINT32_C(0x00000006) /**< Read + write + execute; 1 page read + write + no execute. */
563#define CIDETBUF_PROT_RWX_1RNX UINT32_C(0x00000007) /**< Read + write + execute; 1 page read + no execute. */
564#define CIDETBUF_PROT_RWX_1RWXS UINT32_C(0x00000008) /**< Read + write + execute; 1 page read + execute + supervisor. */
565
566#define CIDETBUF_LOC_MASK UINT32_C(0x000000f0) /**< Location mask. */
567/** Buffer located at top and start of the 32-bit address space. */
568#define CIDETBUF_LOC_32BIT_WRAP UINT32_C(0x00000010)
569/** Buffer located at the low canonical boundrary (AMD64). */
570#define CIDETBUF_LOC_CANON_LO UINT32_C(0x00000020)
571/** Buffer located at the high canonical boundrary (AMD64). */
572#define CIDETBUF_LOC_CANON_HI UINT32_C(0x00000030)
573
574/** Segment protection mask. */
575#define CIDETBUF_SEG_MASK UINT32_C(0x00000f00)
576#define CIDETBUF_SEG_EO UINT32_C(0x00000100) /**< Execute only */
577#define CIDETBUF_SEG_ER UINT32_C(0x00000200) /**< Execute + read */
578#define CIDETBUF_SEG_EO_CONF UINT32_C(0x00000300) /**< Execute only + conforming. */
579#define CIDETBUF_SEG_ER_CONF UINT32_C(0x00000400) /**< Execute + read + conforming. */
580#define CIDETBUF_SEG_RO UINT32_C(0x00000500) /**< Read only. */
581#define CIDETBUF_SEG_RW UINT32_C(0x00000600) /**< Read + write. */
582#define CIDETBUF_SEG_RO_DOWN UINT32_C(0x00000700) /**< Read only + expand down. */
583#define CIDETBUF_SEG_RW_DOWN UINT32_C(0x00000800) /**< Read + write + expand down. */
584
585#define CIDETBUF_DPL_MASK UINT32_C(0x00003000) /**< DPL mask. */
586#define CIDETBUF_DPL_0 UINT32_C(0x00000000) /**< DPL=0. */
587#define CIDETBUF_DPL_1 UINT32_C(0x00001000) /**< DPL=1. */
588#define CIDETBUF_DPL_2 UINT32_C(0x00002000) /**< DPL=2. */
589#define CIDETBUF_DPL_3 UINT32_C(0x00003000) /**< DPL=3. */
590#define CIDETBUF_DPL_SAME UINT32_C(0x00004000) /**< Same DPL as the execution environment. */
591
592#define CIDETBUF_SEG_LIMIT_BASE_CAP UINT32_C(0x00008000) /**< Capability to change segment limit and base. */
593
594#define CIDETBUF_KIND_DATA UINT32_C(0x00000000) /**< Data buffer. */
595#define CIDETBUF_KIND_CODE UINT32_C(0x80000000) /**< Code buffer. */
596/** Checks if @a a_fFlags describes a code buffer. */
597#define CIDETBUF_IS_CODE(a_fFlags) (((a_fFlags) & CIDETBUF_KIND_CODE) != 0)
598/** Checks if @a a_fFlags describes a data buffer. */
599#define CIDETBUF_IS_DATA(a_fFlags) (((a_fFlags) & CIDETBUF_KIND_CODE) == 0)
600/** @} */
601
602/** Code buffer size. (At least two pages.) */
603#define CIDET_CODE_BUF_SIZE (PAGE_SIZE * 2)
604/** Data buffer size. (At least two pages.) */
605#define CIDET_DATA_BUF_SIZE (PAGE_SIZE * 3)
606
607
608/**
609 * Detailed expected exception.
610 *
611 * This is used to internally in the core to calculate the expected exception
612 * considering all the things that may cause exceptions.
613 */
614typedef enum CIDETEXPECTXCPT
615{
616 kCidetExpectXcpt_Invalid = 0,
617 /** No exception expected. */
618 kCidetExpectXcpt_None,
619
620 /** Page not present. */
621 kCidetExpectXcpt_PageNotPresent,
622 /** Write access to a non-writable page. */
623 kCidetExpectXcpt_PageNotWritable,
624 /** Executable access to a non-executable page. */
625 kCidetExpectXcpt_PageNotExecutable,
626 /** Access to supervisor page from user mode code. */
627 kCidetExpectXcpt_PagePrivileged,
628#define kCidetExpectXcpt_First_PageFault kCidetExpectXcpt_PageNotPresent
629#define kCidetExpectXcpt_Last_PageFault kCidetExpectXcpt_PagePrivileged
630
631 /** Read or write access to an execute only segment. */
632 kCidetExpectXcpt_SegExecuteOnly,
633 /** Write to a read only or execute+read segment. */
634 kCidetExpectXcpt_SegNotWritable,
635 /** Exceeded the limit of a non-stack access. */
636 kCidetExpectXcpt_SegExceededLimit,
637 /** Non-canonical address via any segment other than the stack. */
638 kCidetExpectXcpt_AddrNotCanonical,
639 /** Misaligned 16 or 32 byte SSE or AVX operand. */
640 kCidetExpectXcpt_MisalignedSseAvx,
641 /** Privileged instruction. */
642 kCidetExpectXcpt_PrivilegedInstruction,
643#define kCidetExpectXcpt_First_GeneralProtectionFault kCidetExpectXcpt_SegExecuteOnly
644#define kCidetExpectXcpt_Last_GeneralProtectionFault kCidetExpectXcpt_PrivilegedInstruction
645
646 /** Exceeded the limit of a stack access. */
647 kCidetExpectXcpt_StackExceededLimit,
648 /** Non-canonical stack address. */
649 kCidetExpectXcpt_StackAddrNotCanonical,
650#define kCidetExpectXcpt_First_StackFault kCidetExpectXcpt_StackExceededLimit
651#define kCidetExpectXcpt_Last_StackFault kCidetExpectXcpt_StackAddrNotCanonical
652
653 /** Misaligned memory operand (and alignment checking is in effect) if AC is
654 * enabled (executing in ring-3). */
655 kCidetExpectXcpt_MisalignedIfAcEnabled,
656 /** Misaligned 16 byte memory operand resulting in \#AC if ring-3 and
657 * enable, otherwise \#GP(0). */
658 kCidetExpectXcpt_Misaligned16ByteAcEnabledOrGp,
659#define kCidetExpectXcpt_First_AlignmentCheckFault kCidetExpectXcpt_MisalignedIfAcEnabled
660#define kCidetExpectXcpt_Last_AlignmentCheckFault kCidetExpectXcpt_Misaligned16ByteAcEnabledOrGp
661
662 kCidetExpectXcpt_End
663} CIDETEXPECTXCPT;
664
665
666/**
667 * Buffer configuration.
668 */
669typedef struct CIDETBUFCFG
670{
671 /** The name of this buffer configuration. */
672 const char *pszName;
673 /** The buffer flags (CIDETBUF_XXX) */
674 uint32_t fFlags;
675} CIDETBUFCFG;
676/** Pointer to a constant buffer configuration. */
677typedef CIDETBUFCFG const *PCCIDETBUFCFG;
678
679
680/**
681 * CIDET buffer for code or data.
682 *
683 * ASSUMES page aligned buffers.
684 */
685typedef struct CIDETBUF
686{
687 /** @name Owned & modified by the front end.
688 * @{ */
689 /** Effective buffer address. */
690 uint64_t uEffBufAddr;
691 /** The segment base address. */
692 uint64_t uSegBase;
693 /** The active segment limit (see also cbSegLimit). UINT64_MAX if flat. */
694 uint64_t cbActiveSegLimit;
695 /** This specifies the selector to use if a non-flat segment limit or special
696 * segment flags was requested via pfnSetupBuf. UINT32_MAX if any segment is
697 * selector works. */
698 uint32_t uSeg;
699 /** The off value at the last pfnReinitBuf call. */
700 uint16_t offActive;
701 /** The cb value at the last pfnReinitBuf call. */
702 uint16_t cbActive;
703 /** Prologue (or front fence) size. */
704 uint16_t cbPrologue;
705 /** Epilogue (or tail fence) size. */
706 uint16_t cbEpilogue;
707 /** @} */
708
709 /** @name Set by the core before pfnReinitBuf call.
710 * @{ */
711 /** Pointer to the buffer config. */
712 PCCIDETBUFCFG pCfg;
713 /** The configuration index. */
714 uint32_t idxCfg;
715 /** The offset into the buffer of the data / code. */
716 uint16_t off;
717 /** The number of bytes of data / code. */
718 uint16_t cb;
719 /** The segment limit relative to the start of the buffer (last byte included
720 * in count). UINT16_MAX if maximum segment size should be used. */
721 uint16_t cbSegLimit;
722 /** Desired segment base offset.
723 * This is for checking where the alignment checks are performed. */
724 uint8_t offSegBase;
725
726 /** Set if this buffer is actively being used. */
727 bool fActive : 1;
728 /** The operand index (if data), 7 if not active. */
729 uint8_t idxOp : 3;
730 /** Code: Set if the expected exception is supposed to occur on the
731 * following insturction, not the instruction unter test. */
732 bool fXcptAfterInstruction : 1;
733 /** Set if the instruction will read from the buffer. */
734 bool fRead : 1;
735 /** Set if the instruction will write to the buffer. */
736 bool fWrite : 1;
737 /** The expected exception. */
738 CIDETEXPECTXCPT enmExpectXcpt;
739 /** @} */
740} CIDETBUF;
741/** Pointer to a CIDET buffer for code or data. */
742typedef CIDETBUF *PCIDETBUF;
743
744
745/**
746 * CPU Instruction Decoding & Execution Testing (CIDET) state.
747 */
748typedef struct CIDETCORE
749{
750 /** Magic number (CIDETCORE_MAGIC). */
751 uint32_t u32Magic;
752
753 /** The target CPU mode / environment. */
754 uint8_t bMode;
755 /** The target ring. */
756 uint8_t iRing;
757 /** Unused padding bytes. */
758 uint8_t abPadding1[2];
759
760 /** Test configuration. */
761 uint64_t fTestCfg;
762
763 /** Code buffer configurations to test.
764 * The first buffer must be a normal buffer that does not cause any problems. */
765 PCCIDETBUFCFG paCodeBufConfigs;
766 /** The number of code buffer configurations to test (pafCodeBufConfigs). */
767 uint32_t cCodeBufConfigs;
768 /** The number of data buffer configurations to test (pafDataBufConfigs). */
769 uint32_t cDataBufConfigs;
770 /** Data buffer configurations to test.
771 * The first buffer must be a normal buffer that does not cause any problems. */
772 PCCIDETBUFCFG paDataBufConfigs;
773
774 /** The instruction currently under testing. */
775 PCCIDETINSTR pCurInstr;
776
777 /** Primary data buffer. */
778 CIDETBUF DataBuf;
779 /** Secondary data buffer. */
780 CIDETBUF DataBuf2;
781
782 /** Handle to the random number source. */
783 RTRAND hRand;
784
785 /**
786 * Re-initializes one of the data buffers.
787 *
788 * @returns true on succes, false if the request cannot be satisfied.
789 * @param pThis The core state.
790 * @param pBuf Pointer to the buffer structure.
791 */
792 DECLCALLBACKMEMBER(bool, pfnReInitDataBuf)(struct CIDETCORE *pThis, PCIDETBUF pBuf);
793
794 /**
795 * Copies bytes into the data buffer and sets it up for execution.
796 *
797 * @returns true on succes, false if the request cannot be satisfied.
798 * @param pThis The core state.
799 * @param pBuf Pointer to the buffer structure.
800 * @param pvSrc The source bytes (size and destination offset
801 * given in pfnReinitBuf call).
802 */
803 DECLCALLBACKMEMBER(bool, pfnSetupDataBuf)(struct CIDETCORE *pThis, PCIDETBUF pBuf, void const *pvSrc);
804
805 /**
806 * Compares buffer content after test execution.
807 *
808 * This also checks any fill bytes in the buffer that the front end may
809 * have put up. The front end will double buffer the content of supposedly
810 * inaccessible pages as well as non-existing pages to simplify things for
811 * the core code.
812 *
813 * @returns true if equal, false if not.
814 * @param pThis The core state.
815 * @param pBuf Pointer to the buffer structure.
816 * @param pvExpected Pointer to the expected source bytes (size and
817 * buffer offset given in pfnReinitBuf call).
818 */
819 DECLCALLBACKMEMBER(bool, pfnIsBufEqual)(struct CIDETCORE *pThis, struct CIDETBUF *pBuf, void const *pvExpected);
820
821 /**
822 * Re-initializes the code buffer.
823 *
824 * @returns true on succes, false if the request cannot be satisfied.
825 * @param pThis The core state.
826 * @param pBuf Pointer to the CodeBuf member. The off and cb
827 * members represent what the core wants to
828 * execute.
829 */
830 DECLCALLBACKMEMBER(bool, pfnReInitCodeBuf)(struct CIDETCORE *pThis, PCIDETBUF pBuf);
831
832 /**
833 * Emit code into the code buffer, making everything ready for pfnExecute.
834 *
835 * @returns VBox status code.
836 * @param pThis Pointer to the core structure.
837 * @param pBuf Pointer to the CodeBuf member.
838 * @param pvInstr Pointer to the encoded instruction bytes.
839 */
840 DECLCALLBACKMEMBER(bool, pfnSetupCodeBuf)(struct CIDETCORE *pThis, PCIDETBUF pBuf, void const *pvInstr);
841
842 /**
843 * Executes the code indicated by InCtx, returning the result in ActualCtx.
844 *
845 * @returns true if execute, false if skipped.
846 * @param pThis Pointer to the core structure.
847 */
848 DECLCALLBACKMEMBER(bool, pfnExecute)(struct CIDETCORE *pThis);
849
850 /**
851 * Report a test failure.
852 *
853 * @param pThis Pointer to the core structure.
854 * @param pszFormat Format string containing failure details.
855 * @param va Arguments referenced in @a pszFormat.
856 */
857 DECLCALLBACKMEMBER(void, pfnFailure)(struct CIDETCORE *pThis, const char *pszFormat, va_list va);
858
859 /** Variable that's incremented each time the FNCIDETSETUPINOUT is called
860 * for an instruction. Reset when changing instruction or switching
861 * between valid and invalid inputs. */
862 uint32_t iInOut;
863
864 /** @name Copyied and extracted instruction information.
865 * @{ */
866 /** The flags (CIDET_OF_XXX) for the MODRM.REG operand, 0 if not applicable. */
867 uint32_t fMrmRegOp;
868 /** The flags (CIDET_OF_XXX) for the MODRM.RM operand, 0 if not applicable. */
869 uint32_t fMrmRmOp;
870 /** Instruction flags (CIDETINSTR::fFlags). */
871 uint64_t fInstrFlags;
872 /** Number of operands (CIDETINSTR::cOperands). */
873 uint8_t cOperands;
874 /** Number of memory operands (set by CidetCoreSetupFirstMemoryOperandConfig). */
875 uint8_t cMemoryOperands : 3;
876 /** Set if we're working on a MOD R/M byte. */
877 bool fUsesModRm : 1;
878 /** The index of the MODRM.REG operand, 7 if not applicable. */
879 uint8_t idxMrmRegOp : 3;
880 /** The index of the MODRM.RM operand, 7 if not applicable. */
881 uint8_t idxMrmRmOp : 3;
882 /** Set if the SIB byte uses VEX registers for indexing. */
883 bool fUsesVexIndexRegs : 1;
884 /** @} */
885
886 /** @name Basic encoding knobs, wheels and indicators.
887 * @{ */
888 /** Set if we're working on a SIB byte. */
889 bool fSib : 1;
890 /** Required segment prefix (X86_SREG_XXX), X86_SREG_COUNT if not. */
891 uint8_t uSegPrf : 3;
892 /** The address size prefix. */
893 bool fAddrSizePrf : 1;
894 /** The operand size prefix. */
895 bool fOpSizePrf : 1;
896 /** The REX.W prefix value. */
897 bool fRexW : 1;
898 /** The REX.R prefix value. */
899 bool fRexR : 1;
900 /** The REX.X prefix value. */
901 bool fRexX : 1;
902 /** The REX.B prefix value. */
903 bool fRexB : 1;
904 /** Set if a REX prefix is required with or without flags (for byte regs). */
905 bool fRex : 1;
906 /** Use VEX encoding. */
907 bool fVex : 1;
908 /** Use EVEX encoding. */
909 bool fEvex : 1;
910 /** Indicator: Effective addressing mode in bytes (2, 4, 8). */
911 uint8_t cbAddrMode : 4;
912 /** Indicator: Set if there is an operand accessing memory. */
913 bool fHasMemoryOperand : 1;
914 /** Indicator: Set if a register is used in two or more operands, and one of
915 * them being for addressing. */
916 bool fHasRegCollisionMem : 1;
917 /** Indicator: Helper indicator for tracking SIB.BASE collision. */
918 bool fHasRegCollisionMemBase : 1;
919 /** Indicator: Helper indicator for tracking SIB.INDEX collision. */
920 bool fHasRegCollisionMemIndex : 1;
921 /** Indicator: Set if a register is used directly in more than one operand. */
922 bool fHasRegCollisionDirect : 1;
923
924 /** Indicator: Set if MODRM.REG is the stack register. */
925 bool fHasStackRegInMrmReg : 1;
926 /** Indicator: Set if MODRM.RM or SIB.BASE is the stack register. */
927 bool fHasStackRegInMrmRmBase: 1;
928
929 /** Indicator: High byte-register specified by MODRM.REG. */
930 bool fHasHighByteRegInMrmReg : 1;
931 /** Indicator: High byte-register specified by MODRM.RM. */
932 bool fHasHighByteRegInMrmRm : 1;
933 /** Indicator: Set if REX prefixes are incompatible with the byte-register
934 * specified by MODRM.REG. */
935 bool fNoRexPrefixMrmReg : 1;
936 /** Indicator: Set if REX prefixes are incompatible with the byte-register
937 * specified by MODRM.RM. */
938 bool fNoRexPrefixMrmRm : 1;
939 /** Indicator: fNoRexPrefixMrmReg || fNoRexPrefixMrmMr. */
940 bool fNoRexPrefix : 1;
941 /** The MOD R/M byte we're working on (if fUsesModRm is set). */
942 uint8_t bModRm;
943 /** The SIB/VSIB byte we're working on (if fSib is set). */
944 uint8_t bSib;
945 /** @} */
946
947 /** The effective instruction address. (See InCtx.rip and InCtx.cs for the
948 * rest of the instruction addressing stuff.) */
949 uint64_t uInstrEffAddr;
950
951 /** Operand information, mainly for the FNCIDETSETUPINOUT and similar. */
952 struct
953 {
954 /** The operand flags copied from (CIDETINSTR::afOperands). */
955 uint32_t fFlags;
956 /** The encoded register number, if register, UINT8_MAX if not. */
957 uint8_t iReg;
958 /** The actual operand size (encoded). */
959 uint8_t cb;
960 /** Set if immediate value. */
961 bool fIsImmediate : 1;
962 /** Set if memory access. */
963 bool fIsMem : 1;
964 /** Set if addressing is relative to RIP. */
965 bool fIsRipRelative : 1;
966 /** Set if it's a high byte register. */
967 bool fIsHighByteRegister : 1;
968 /** Size of the disposition, 0 if none. */
969 uint8_t cbMemDisp;
970 /** Base register, UINT8_MAX if not applicable. */
971 uint8_t iMemBaseReg;
972 /** Index register, UINT8_MAX if not applicable. */
973 uint8_t iMemIndexReg;
974 /** Index register, 1 if not applicable. */
975 uint8_t uMemScale;
976 /** Effective segment register, UINT8_MAX if not memory access. */
977 uint8_t iEffSeg;
978 /** Segment offset if memory access. Undefined if not memory access. */
979 uint64_t offSeg;
980 /** The effective address if memory access. */
981 uint64_t uEffAddr;
982 /** Immediate or displacement value. */
983 uint64_t uImmDispValue;
984 /** Base register value, undefined if irrelevant. */
985 uint64_t uMemBaseRegValue;
986 /** Index register value, undefined if irrelevant. */
987 uint64_t uMemIndexRegValue;
988 /** Points to where the input data for this operand should be placed,
989 * when possible. In the fIsMem = true case, it either points directly
990 * to the input buffer or to a temporary one. While in the other case,
991 * it'll point into InCtx when possible. */
992 RTPTRUNION In;
993 /** Points to where the expected output data for this operand should be
994 * stored, when possible. In the fIsMem = false case, it'll point into
995 * ExpectedCtx when possible. */
996 RTPTRUNION Expected;
997 /** Pointer to the data buffer for this operand. */
998 PCIDETBUF pDataBuf;
999 } aOperands[4];
1000
1001 /** Buffer where we assemble the instruction. */
1002 uint8_t abInstr[45];
1003 /** The size of the instruction in abInstr. */
1004 uint8_t cbInstr;
1005 /** Offset of the instruction into the buffer. */
1006 uint16_t offInstr;
1007 /** Current code buffer. */
1008 CIDETBUF CodeBuf;
1009
1010 /** The input context. Initalized by driver and FNCIDETSETUPINOUT. */
1011 CIDETCPUCTX InCtx;
1012 /** The expected output context. */
1013 CIDETCPUCTX ExpectedCtx;
1014 /** The actual output context. */
1015 CIDETCPUCTX ActualCtx;
1016 /** Template input context, initialized when setting the mode. */
1017 CIDETCPUCTX InTemplateCtx;
1018
1019 /** Input and expected output temporary memory buffers. */
1020 uint8_t abBuf[0x2000];
1021
1022} CIDETCORE;
1023/** Pointer to the CIDET core state. */
1024typedef CIDETCORE *PCIDETCORE;
1025
1026/** Magic number for CIDETCORE (Lee Konitz). */
1027#define CIDETCORE_MAGIC UINT32_C(0x19271013)
1028
1029
1030int CidetCoreInit(PCIDETCORE pThis, RTRAND hRand);
1031void CidetCoreDelete(PCIDETCORE pThis);
1032int CidetCoreSetTargetMode(PCIDETCORE pThis, uint8_t bMode);
1033uint32_t CidetCoreGetOperandSize(PCIDETCORE pThis, uint8_t iOp);
1034bool CidetCoreTestInstruction(PCIDETCORE pThis, PCCIDETINSTR pInstr);
1035
1036
1037extern const CIDETINSTR g_aCidetInstructions1[];
1038extern const uint32_t g_cCidetInstructions1;
1039
1040#endif
1041
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette