1 /*
2 prefix.h
3 
4 diStorm3 - Powerful disassembler for X86/AMD64
5 http://ragestorm.net/distorm/
6 distorm at gmail dot com
7 Copyright (C) 2003-2012 Gil Dabah
8 
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program.  If not, see <http://www.gnu.org/licenses/>
21 */
22 
23 
24 #ifndef PREFIX_H
25 #define PREFIX_H
26 
27 #include "config.h"
28 #include "decoder.h"
29 
30 
31 /* Specifies the type of the extension prefix, such as: REX, 2 bytes VEX, 3 bytes VEX. */
32 typedef enum {PET_NONE = 0, PET_REX, PET_VEX2BYTES, PET_VEX3BYTES} _PrefixExtType;
33 
34 /* Specifies an index into a table of prefixes by their type. */
35 typedef enum {PFXIDX_NONE = -1, PFXIDX_REX, PFXIDX_LOREP, PFXIDX_SEG, PFXIDX_OP_SIZE, PFXIDX_ADRS, PFXIDX_MAX} _PrefixIndexer;
36 
37 /*
38 * This holds the prefixes state for the current instruction we decode.
39 * decodedPrefixes includes all specific prefixes that the instruction got.
40 * start is a pointer to the first prefix to take into account.
41 * last is a pointer to the last byte we scanned.
42 * Other pointers are used to keep track of prefixes positions and help us know if they appeared already and where.
43 */
44 typedef struct {
45 	_iflags decodedPrefixes, usedPrefixes;
46 	const uint8_t *start, *last, *vexPos, *rexPos;
47 	_PrefixExtType prefixExtType;
48 	uint16_t unusedPrefixesMask;
49 	/* Indicates whether the operand size prefix (0x66) was used as a mandatory prefix. */
50 	int isOpSizeMandatory;
51 	/* If VEX prefix is used, store the VEX.vvvv field. */
52 	unsigned int vexV;
53 	/* The fields B/X/R/W/L of REX and VEX are stored together in this byte. */
54 	unsigned int vrex;
55 
56 	/* !! Make sure pfxIndexer is LAST! Otherwise memset won't work well with it. !! */
57 
58 	/* Holds the offset to the prefix byte by its type. */
59 	int pfxIndexer[PFXIDX_MAX];
60 } _PrefixState;
61 
62 /*
63 * Intel supports 6 types of prefixes, whereas AMD supports 5 types (lock is seperated from rep/nz).
64 * REX is the fifth prefix type, this time I'm based on AMD64.
65 * VEX is the 6th, though it can't be repeated.
66 */
67 #define MAX_PREFIXES (5)
68 
69 int prefixes_is_valid(unsigned int ch, _DecodeType dt);
70 void prefixes_ignore(_PrefixState* ps, _PrefixIndexer pi);
71 void prefixes_ignore_all(_PrefixState* ps);
72 uint16_t prefixes_set_unused_mask(_PrefixState* ps);
73 void prefixes_decode(const uint8_t* code, int codeLen, _PrefixState* ps, _DecodeType dt);
74 void prefixes_use_segment(_iflags defaultSeg, _PrefixState* ps, _DecodeType dt, _DInst* di);
75 
76 #endif /* PREFIX_H */
77