1 /****************************  disasm.h   **********************************
2 * Author:        Agner Fog
3 * Date created:  2007-02-21
4 * Last modified: 2014-12-06
5 * Project:       objconv
6 * Module:        disasm.h
7 * Description:
8 * Header file for disassembler
9 *
10 * Copyright 2007-2014 GNU General Public License http://www.gnu.org/licenses
11 *****************************************************************************/
12 #ifndef DISASM_H
13 #define DISASM_H
14 
15 // Define tabulator positions for output
16 #define AsmTab1  8                     // Column for opcode
17 #define AsmTab2  16                    // Column for first operand
18 #define AsmTab3  56                    // Column for comment
19 
20 #define ReplaceIllegalChars 0          // 1 if you want to replace illegal characters in symbol names
21 
22 
23 // Structure for defining x86 opcode maps
24 struct SOpcodeDef {
25    const char * Name;                  // opcode name
26    uint32_t InstructionSet;              // mmx, sse, 3dnow, x64, etc.
27    uint32_t AllowedPrefixes;             // prefixes allowed for this opcode
28    uint16_t InstructionFormat;           // opcode type, number of operands
29    uint16_t Destination;                 // type and size of destination operand
30    uint16_t Source1;                     // type and size of 1. source operand
31    uint16_t Source2;                     // type and size of 2. source operand
32    uint16_t Source3;                     // type and size of 3. source operand
33    uint16_t EVEX;                        // options for interpreting EVEX prefix, may be used for 4. source operand otherwise (unused)
34    uint16_t MVEX;                        // options for interpreting MVEX prefix: swizzle, convert, mask options
35    uint16_t TableLink;                   // this entry is a link to another map
36    uint16_t Options;                     // miscellaneous options
37 };
38 
39 /****************     Constants for opcode definition     **********************
40 I have deliberately not assigned names to these constants because this would
41 make the tables in opcodes.cpp wery broad with many constant names OR'ed together.
42 It would be almost impossible to align the columns in a readable way.
43 Sorry that you have to look up the constants here.
44 
45 The following tables define the possible values for each field in SOpcodeDef:
46 
47 Name:
48 -----
49 Opcode mnemonic
50 
51 InstructionSet:
52 (Some values can be OR'ed):
53 ---------------------------
54 0:       8086
55 1:       80186
56 2:       80286
57 3:       80386
58 4:       80486, cpuid
59 5:       Pentium
60 6:       Pentium Pro, cmov, fcomi
61 7:       MMX
62 8:       Pentium II
63 0x11:    SSE
64 0x12:    SSE2
65 0x13:    SSE3
66 0x14:    Suppl. SSE3
67 0x15:    SSE4.1
68 0x16:    SSE4.2
69 0x17:    AES
70 0x18:    CLMUL
71 0x19:    AVX
72 0x1A:    FMA3
73 0x1C:    AVX2
74 0x1D:    BMI1, BMI2, ADX, RDRAND, RDSEED, INVPCID, SMAP, PRFCHW, F16C, Transactional Synchronization
75 0x20:    AVX512F,BW,DQ,VL
76 0x21:    AVX512PF,ER,CD
77 0x22:    SHA,TBD
78 0x23:    AVX512IFMA,VBMI
79 0x24:    AVX512_4FMAPS, ..
80 
81 0x80:    MIC Knights Corner
82 0x100:   8087
83 0x101:   80387
84 0x800:   Privileged instruction
85 0x1001:  AMD 3DNow
86 0x1002:  AMD 3DNow extension
87 0x1004:  AMD SSE4a or AMD virtualization
88 0x1005:  AMD XOP
89 0x1006:  AMD FMA4
90 0x1007:  AMD TBM
91 0x2001;  VIA
92 
93 0x4000:  Only available in 64 bit mode
94 0x8000:  Not  available in 64 bit mode
95 0x10000: Proposed instruction code, preliminary specification
96 0x20000: Proposed instruction code never implemented, preliminary specification later changed
97 
98 AllowedPrefixes:
99 (Values can be OR'ed):
100 ----------------------
101 0:       No prefix allowed other than possibly segment and address size prefixes if there is a mod/reg/rm byte
102 1:       Address size prefix allowed, even if no mod/reg/rm byte
103 2:       This is a stack operation. Address size prefix will truncate the stack pointer. Make warning if address size prefix or operand size prefix
104 4:       Segment prefix allowed, even if no mod/reg/rm byte
105 8:       Branch prediction hint prefix allowed (on Pentium 4) or BND prefix allowed
106 0x10:    LOCK prefix allowed
107 0x20:    REP prefix allowed
108 0x40:    REPE/REPNE prefix allowed
109 0x80:    This is a jump operation. 66 prefix will truncate EIP. Make warning if 66 prefix in 32 bit mode. 66 prefix not allowed in 64 bit mode.
110 0x100:   66 prefix determines integer operand size
111 0x200:   66 prefix allowed for other purpose. Typical meanings are:
112          * indicates packed integer xmm vs. mmx,
113          * indicates packed double precision xmm (pd) vs. packed single (ps)
114          * always required
115 0x400:   F3 prefix allowed for other purpose. Typical = scalar single precision xmm (ss)
116 0x800:   F2 prefix allowed for other purpose. Typical = scalar double precision xmm (sd)
117 0xC40:   F2 and F3 prefix allowed for XACQUIRE and XRELEASE
118 0xE00:   none/66/F2/F3 prefix indicate ps/pd/sd/ss vector
119 
120 0x1000:  REX.W prefix determines integer g.p. operand size or fp precision or swaps operands or other purpose
121 0x2000:  REX.W prefix allowed but unnecessary
122 0x3000:  REX.W prefix determines integer (vector) operand size d/q or ps/pd
123 0x4000:  VEX.W prefix determines integer (vector) operand size b/w
124 0x5000:  VEX.W and 66 prefix determines integer operand size b/w/d/q (mask instructions. B = 66W0, W = _W0, D = 66W1, Q = _W1)
125 0x7000:  REX.W prefix swaps last two operands (AMD)
126 0x8000:  Instruction not allowed without 66/F2/F3 prefix as specified by previous bits
127 
128 0x10000: VEX or XOP prefix allowed
129 0x20000: VEX or EVEX or XOP prefix required
130 0x40000: VEX.L prefix allowed
131 0x80000: VEX.vvvv prefix allowed
132 
133 0x100000:VEX.L prefix required
134 0x200000:VEX.L prefix allowed only if pp bits < 2
135 0x400000:MVEX prefix allowed
136 0x800000:EVEX prefix allowed
137 
138 InstructionFormat:
139 (Values can be OR'ed):
140 ----------------------
141 0:      Illegal opcode.
142 1:      No mod/reg/rm byte. Operands are implicit
143 2:      No mod/reg/rm byte. No operands (other than possibly immediate operand)
144 3:      No mod/reg/rm byte. Register operand indicated by bits 0-2
145 4:      Has VEX or EVEX prefix and no mod/reg/rm byte, Register operand, if any, indicated by VEX.v
146 0x10:   Has mod/reg/rm byte and possibly a SIB byte
147 0x11:   Has mod/reg/rm byte and one register/memory operand
148 0x12:   Has mod/reg/rm byte, a register destination operand and a register/memory source operand
149 0x13:   Has mod/reg/rm byte, a register/memory destination operand and a register source operand
150 0x14:   Has mod/reg/rm byte and AMD DREX byte. One destination and two source operands and possibly an immediate byte operand (AMD SSE5 instructions never implemened)
151 0x15:   Has mod/reg/rm byte and AMD DREX byte. One destination and three source operands. One of the source operands is equal to the destination operand (AMD SSE5 instructions never implemened)
152 0x18:   Has VEX or EVEX prefix and 2 operands. (NDD) Dest = VEX.v, src = rm, opcode extension in r bits. Src omitted if no VEX prefix.
153 0x19:   Has VEX or EVEX prefix and 3 operands. (NDS) Dest = r,  src1 = VEX.v, src2 = rm. Src1 omitted if no VEX prefix. May swap src1 and src2 if VEX.W = 0
154 0x1A:   Has VEX prefix and 3 operands. Dest = rm, src1 = VEX.v, src2 = r
155 0x1B:   Has VEX prefix and 3 operands. Dest = r,  src1 = rm, src2 = VEX.v.
156 0x1C:   Has VEX prefix and 4 operands. Dest = r,  src1 = VEX.v, src2 = rm, src3 = bits 4-7 of immediate byte. May swap src2 and src3 if VEX.W
157 0x1D:   Has VEX prefix and 4 operands. Dest = r,  src1 = bits 4-7 of immediate byte, src2 = rm, src3 = VEX.v. May swap src2 and src3 if VEX.W
158 0x1E:   Has VEX prefix VSIB and 2 or 3 operands. Dest = r or rm, src1 = rm or r, src2 = VEX.v or k register or none. VSIB byte required (rm operand & 0xF00 = index register size, rm operand & 0xFF = operand size)
159 0x20:   Has 2 bytes immediate operand (ret i) or 1 + 1 bytes (insrtq)
160 0x40:   Has 1 byte immediate operand or short jump
161 0x60:   Has 2 + 1 = 3 bytes immediate operand (enter)
162 0x80:   Has 2 or 4 bytes immediate operand or near jump
163 0x100:  Has a 2, 4 or 8 bytes immediate operand
164 0x200:  Has a 2+2 or 4+2 far direct jump operand
165 0x400:  Has a 2, 4 or 8 bytes direct memory operand
166 0x800:  Has a far indirect memory operand, dword, fword or tbyte
167 0x2000: Opcode reserved for future extensions
168 0x4000: Undocumented opcode or illegal (undocumented if name specified, otherwise illegal or unknown)
169 0x8000: This is a prefix, not an opcode
170 0x8001: This is a segment prefix
171 
172 Destination and Source operand types,
173 used by SOpcodeDef::Destination, SOpcodeDef::Source, and CDisassembler::s.Operands[].
174 Many of the bit values can be OR'ed. If an instruction has two source operands, then
175 the values for these two operands are OR'ed (e.g. imul eax,ebx,9; shrd eax,ebx,cl).
176 -------------------------------------------------------------------------------------
177 0:      No explicit operand
178 1:      8  bit integer
179 2:      16 bit integer
180 3:      32 bit integer
181 4:      64 bit integer
182 5:      80 bit integer memory
183 6:      integer memory, other size
184 7:      48 bit memory
185 8:      16 or 32 bit integer, depending on 66 prefix
186 9:      16, 32 or 64 bit integer, depending on 66 or REX.W prefix. (8 bit in some cases as indicated by AllowedPrefixes)
187 0x0A:   16, 32 or 64 bit integer, default size = address size (REX.W not needed)
188 0x0B:   16, 32 or 64 bit near indirect pointer (jump)
189 0x0C:   16, 32 or 64 bit near indirect pointer (call)
190 0x0D:   16+16, 32+16 or 64+16 bits far indirect pointer (jump or call)
191 
192 0x11:   8  bit constant, unsigned
193 0x12:   16 bit constant, unsigned
194 0x13:   32 bit constant, unsigned
195 0x18:   16 or 32 bit constant, unsigned
196 0x19:   16, 32 or 64 bit constant, unsigned
197 0x21:   8  bit constant, signed
198 0x22:   16 bit constant, signed
199 0x23:   32 bit constant, signed
200 0x28:   16 or 32 bit constant, signed
201 0x29:   16, 32 or 64 bit constant, signed
202 0x31:   8  bit constant, hexadecimal
203 0x32:   16 bit constant, hexadecimal
204 0x33:   32 bit constant, hexadecimal
205 0x34:   64 bit constant, hexadecimal
206 0x38:   16 or 32 bit constant, hexadecimal
207 0x39:   16, 32 or 64 bit constant, hexadecimal
208 
209 0x40:   float x87, unknown size or register only
210 0x43:   32 bit float x87, single precision
211 0x44:   64 bit float x87, double precision
212 0x45:   80 bit float x87, long double precision
213 0x48:   float SSE, unknown size
214 0x4A:   16 bit float, half precision
215 0x4B:   32 bit float SSE,  single precision (ss) or packed (ps)
216 0x4C:   64 bit float SSE2, double precision (sd) or packed (pd)
217 0x4F:   XMM float. Size depends on prefix: none = ps, 66 = pd, F2 = sd, F3 = ss; or VEX.W bit = sd/pd
218 0x50:   Full vector, aligned
219 0x51:   Full vector, unaligned
220 
221 0x81:   Short jump destination, 8 bits
222 0x82:   Near jump destination, 16 or 32 bits, depending on operand size
223 0x83:   Near call destination, 16 or 32 bits, depending on operand size
224 0x84:   Far jump destination, 16+16 or 32+16 bits, depending on operand size
225 0x85:   Far call destination, 16+16 or 32+16 bits, depending on operand size
226 0x91:   segment register
227 0x92:   control register
228 0x93:   debug register
229 0x94:   test register (obsolete or undocumented)
230 0x95:   k0 - k7 mask register. 16 bits if memory operand, 32-64 bits if register
231 0x96:   (reserved for future mask register > 16 bits)
232 0x98:   bnd0 - bnd3 bounds register
233 
234 0xa1:   al
235 0xa2:   ax
236 0xa3:   eax
237 0xa4:   rax
238 0xa8:   ax or eax
239 0xa9:   ax, eax or rax
240 0xae:   xmm0
241 0xaf:   st(0)
242 0xb1:   1
243 0xb2:   dx
244 0xb3:   cl
245 0xc0:   [bx], [ebx] or [rbx]
246 0xc1:   [si], [esi] or [rsi]
247 0xc2:   es:[di], es:[edi] or [rdi]
248 
249 // The following values can be added to specify vectors
250 0x100:  Vector MMX or XMM or YMM or ZMM, depending on 66 prefix and VEX.L prefix and EVEX.LL prefix
251 0x200:  Vector XMM, YMM or ZMM, depending on VEX.L prefix and EVEX.LL prefix
252 0x300:  Vector MMX (8  bytes)
253 0x400:  Vector XMM (16 bytes)
254 0x500:  Vector YMM (32 bytes)
255 0x600:  Vector ZMM (64 bytes)
256 0x700:  Future ??? (128 bytes)
257 0xF00:  Vector half the size defined by VEX.L prefix and EVEX.LL prefix. Minimum size = 8 bytes for memory, xmm for register
258 
259 // The following values can be added to specify operand type
260 0x1000: Must be register, memory operand not allowed
261 0x2000: Must be memory, register operand not allowed
262 
263 // The following bit values apply to CDisassembler::s.Operands[] only:
264 0x10000:    Direct memory operand without mod/reg/rm byte
265 0x20000:    Register operand indicated by last bits of opcode and B bit
266 0x30000:    Register or memory operand indicated by mod and rm bits of mod/reg/rm byte and B,X bits
267 0x40000:    Register operand indicated by reg bits of mod/reg/rm byte and R bit
268 0x50000:    Register operand indicated by dest bits of DREX byte
269 0x60000:    Register operand indicated by VEX.vvvv bits
270 0x70000:    Register operand indicated by bits 4-7 of immediate operand
271 0x80000:    (Register operand indicated by bits 0-3 of immediate operand. unused, reserved for future use)
272 0x100000:   Immediate operand using immediate field or first part of it
273 0x200000:   Immediate operand using second part of immediate field
274 0x1000000:  Is code
275 0x2000000:  Is supposed to be code, but dubious
276 0x4000000:  Is data
277 
278 // The following bit values applies only to symbol types originating from object file
279 0x40000000: Gnu indirect function (CPU dispatcher)
280 0x80000000: Symbol is a segment (in COFF file symbol table)
281 
282 EVEX:
283 --------
284 This field indicates the meaning of the z, L'L, b and aaa bits of an EVEX prefix.
285 (The EVEX field may also be used in the future for indicating an extra operand
286 if it is not needed for its current purpose).
287 
288 Bit 0-3 indicate meaning of L'L, b field:
289   0x01  broadcast allowed for memory operand, LL indicate vector length
290   0x02  SAE allowed for register operands, no rounding control, LL indicate vector length
291   0x06  rounding control and SAE allowed for register operands
292   0x08  Scalar. LL ignored
293 
294 Bit 4-7 indicate mask use in aaa/kkk field
295   0x00  no masking. aaa must be zero
296   0x10  allow masking, not zeroing
297   0x20  allow masking  and zeroing
298   0x50  allow masking, not zeroing. aaa must be nonzero
299   0x80  mask is modified by instruction
300 
301 Bit 12-15 indicate offset multiplier
302   0x0000 Multiplier corresponds to memory operand size
303   0x1000 Multiplier corresponds to vector element size
304   0x2200 Multiplier corresponds to half the size of the largest vector operand
305   0x2400 Multiplier corresponds to 1/4 of the size of the largest vector operand
306   0x2600 Multiplier corresponds to 1/8 of the size of the largest vector operand
307 
308 
309 MVEX:
310 --------
311 This field indicates the meaning of the sss, e and kkk bits of an MVEX prefix.
312 (The MVEX field may also be used in the future for indicating an extra operand
313 if it is not needed for its current purpose).
314 Bit 0-4 indicate meaning of sss field:
315     0. none, sss must be 0
316     1. sss ignored or used only for sae, offset multiplier defined, vector size defined
317     2. sss ignored or used only for sae, offset multiplier defined, vector size not defined by sss
318     3. reserved for future use
319     4. Sf32. 32-bit float operand. permutation if register, broadcast or conversion if memory operand
320     5. Sf64. 64-bit float operand. permutation if register, broadcast if memory operand
321     6. Si32. 32-bit integer operand. permutation if register, broadcast or conversion if memory operand
322     7. Si64. 64-bit integer operand. permutation if register, broadcast if memory operand
323     8. Uf32. 32-bit float memory operand. Up conversion from smaller integer or float operand
324     9. Uf64. 64-bit float memory operand. Currently no conversion supported
325   0xA. Ui32. 32-bit integer memory operand. Up conversion from smaller integer operand
326   0xB. Ui64. 64-bit integer memory operand. Currently no conversion supported
327   0xC. Df32. 32-bit float memory operand. Down conversion to smaller integer or float operand
328   0xD. Df64. 64-bit float memory operand. Currently no conversion supported
329   0xE. Di32. 32-bit integer memory operand. Down conversion to smaller integer operand
330   0xF. Di64. 64-bit integer memory operand. Currently no conversion supported
331  0x10. Uf32, broadcast * 4, vbroadcastf32x4
332  0x11. Uf64, broadcast * 4, vbroadcastf64x4
333  0x12. Ui32, broadcast * 4, vbroadcasti32x4
334  0x13. Ui64, broadcast * 4, vbroadcasti64x4
335  0x14. Si32, half size, vcvtdq2pd, vcvtudq2pd
336  0x15. Sf32, half size, vcvtps2pd
337  0x16. Sf32, without register swizzle and limited broadcast, vfmadd233ps
338 Bit 6-7 indicate offset multiplier
339   0x00  No broadcast. Multiplier corresponds to conversion
340   0x40  Broadcast, gather and scatter instructions. Multiplier corresponds to element size before conversion
341 Bit 8-10 indicate alternative meaning of sss field for register operand when E bit is 1:
342   0x000. E bit not allowed for register operand
343   0x100. sss specifies rounding mode
344   0x200. high s bit indicates suppress all exceptions {sae}
345   0x300. sss specifies rounding mode and sae
346   0x400. no rounding and no sae. sss bits ignored when E = 1
347 Bit 11  ignore E bit
348   0x000. The E bit means cache eviction hint
349   0x800. The E bit is ignored for memory operands or has a different meaning
350 Bit 12-13 indicate meaning of kkk field
351   0x0000. kkk bits unused, must be 0
352   0x1000. kkk bits specify register used for masked operation
353   0x2000. kkk bits specify mask register as destination operand
354   0x3000. kkk bits specify mask register used both for masked operation and as destination operand
355 The multiplier for single-byte address offsets is derived from the meaning of the sss field.
356 
357 TableLink:
358 ----------
359 Used for linking to another opcode table when more than one opcode begins
360 with the same bytes or when different specifications are needed in different
361 cases. When TableLink is nonzero then InstructionSet is an index into
362 OpcodeTables pointing to a subtable. The subtable is indexed according to
363 the criterion defined by TableLink.
364 
365 0:      No link to other table
366 1:      Use following byte as index into next table (256 entries)
367 2:      Use reg field of mod/reg/rm byte as index into next table (8 entries)
368 3:      Use mod < 3 vs. mod == 3 as index (0: memory operand, 1: register operand)
369 4:      Use mod and reg fields of mod/reg/rm byte as index into next table,
370         first 8 entries indexed by reg for mod < 3, next 8 entries indexed by reg for mod = 3.
371 5:      Use rm bits of mod/reg/rm byte as index into next table (8 entries)
372 6:      Use immediate byte after any operands as index into next table. Note: Instruction format must be specified
373 7:      Use mode as index into next table (0: 16 bits, 1: 32 bits, 2: 64 bits)
374 8:      Use operand size as index into next table (0: 16 bits, 1: 32 bits, 2: 64 bits)
375 9:      Use prefixes as index into next table (0: none, 1: 66, 2: F2, 3: F3)
376 0x0A:   Use address size as index into next table (0: 16 bits, 1: 32 bits, 2: 64 bits)
377 0x0B:   Use VEX prefix and VEX.L bits as index into next table (0: VEX absent, 1: VEX.L=0, 2: VEX.L=1, 3:MVEX or EVEX.LL=2, 4: EVEX.LL=3)
378 0x0C:   Use VEX.W bit as index into next table (0: VEX.W=0, 1: VEX.W=1)
379 0x0D:   Use vector size by VEX.L bits as index into next table (0: VEX.L=0, 1: VEX.L=1, 2:MVEX or EVEX.LL=2, 3: EVEX.LL=3)
380 0x0E:   Use VEX prefix type as index into next table. (0: 2- or 3-bytes VEX or none, 1: 4-bytes EVEX or MVEX)
381 0x0F:   Use MVEX.E bit as index into next table. (0: MVEX.E = 0 or no MVEX, 1: MVEX.E = 1)
382 0x10:   Use assembly language dialect as index into next table (0: MASM, 1: NASM/YASM, 2: GAS)
383 0x11:   Use VEX prefix type as index into next table. (0: none, 1: VEX prefix, 2: EVEX prefix, 3: MVEX prefix)
384 
385 Options:
386 (Values can be OR'ed):
387 ----------------------
388 1:      Append suffix for operand size or type to opcode name (prefix 0x100: b/w/d/q, 0xE00: ps/pd/ss/sd, 0x1000: s/d, 0x3000: d/q, 0x4000: b/w)
389 2:      Prepend 'v' to opcode name if VEX prefix present
390 4:      Does not change destination register
391 8:      Can change registers other than explicit destination register (includes call etc.)
392 0x10:   Unconditional jump. Next instruction will not be executed unless there is a jump to it.
393 0x20:   Code prefixes explicitly. Assembler cannot code prefixes on this instruction
394 0x40:   Instruction may be used as NOP or filler
395 0x80:   Shorter version of instruction exists for certain operand values
396 0x100:  Aligned. Memory operand must be aligned, even if VEX prefixed
397 0x200:  Unaligned. Unaligned memory operand always allowed.
398 0x400:  Opcode name differs if 64 bits
399 0x800:  Do not write size specifier on memory operand
400 0x1000: Append alternative suffix to opcode name (prefix 0x3000: "32"/"64")
401 
402 */
403 
404 // Structure for opcode swizzle table entries indicating meaning of EVEX.sss bits
405 struct SwizSpec {
406     uint32_t memop;       // memory operand type
407     uint32_t memopsize;   // memory operand size = byte offset multiplier = required alignment
408     uint32_t elementsize; // memory operand size for broadcast, gather and scatter instructions
409     const char * name;  // name of permutation, conversion or rounding
410 };
411 
412 
413 // Define data structures and classes used by class CDisassembler:
414 
415 // Structure for properties of a single opcode during disassembly
416 struct SOpcodeProp {
417    SOpcodeDef const * OpcodeDef;                 // Points to entry in opcode map
418    uint8_t  Prefixes[8];                           // Stores the last prefix encountered in each category
419    uint8_t  Conflicts[8];                          // Counts prefix conflicts as different prefixes in the same category
420    uint32_t Warnings1;                             // Warnings about conditions that could be intentional and suboptimal code
421    uint32_t Warnings2;                             // Warnings about possible misinterpretation
422    uint32_t Errors;                                // Errors that will prevent execution or are unlikely to be intentional
423    uint32_t AddressSize;                           // Address size: 16, 32 or 64
424    uint32_t OperandSize;                           // Operand size: 16, 32 or 64
425    uint32_t MaxNumOperands;                        // Number of opcode table operands to check
426    uint32_t Mod;                                   // mod bits of mod/reg/rm byte
427    uint32_t Reg;                                   // reg bits of mod/reg/rm byte
428    uint32_t RM;                                    // r/m bits of mod/reg/rm byte
429    uint32_t MFlags;                                // Memory operand type: 1=has memory operand, 2=has mod/reg/rm byte, 4=has SIB byte, 8=has VEX or DREX byte, 0x100=is rip-relative
430    uint32_t BaseReg;                               // Base  register + 1. (0 if none)
431    uint32_t IndexReg;                              // Index register + 1. (0 if none)
432    uint32_t Scale;                                 // Scale factor = 2^Scale
433    uint32_t Vreg;                                  // ~VEX.vvvv or AMD DREX byte
434    uint32_t Kreg;                                  // EVEX.aaa = MVEX.kkk mask register
435    uint32_t Esss;                                  // EVEX.zLLb = MVEX.Esss option bits
436    SwizSpec const * SwizRecord;                  // Selected entry in MVEX table for MVEX code
437    uint32_t OffsetMultiplier;                      // Multiplier for 1-byte offset calculated from EVEX or obtained from MVEX.sss and table lookup
438    uint32_t Operands[5];                           // Operand types for destination, source, immediate
439    uint32_t OpcodeStart1;                          // Index to first opcode byte, after prefixes
440    uint32_t OpcodeStart2;                          // Index to last opcode byte, after 0F, 0F 38, etc., before mod/reg/rm byte and operands
441    uint32_t AddressField;                          // Beginning of address/displacement field
442    uint32_t AddressFieldSize;                      // Size of address/displacement field
443    uint32_t AddressRelocation;                     // Relocation pointing to address field
444    uint32_t ImmediateField;                        // Beginning of immediate operand or jump address field
445    uint32_t ImmediateFieldSize;                    // Size of immediate operand or jump address field
446    uint32_t ImmediateRelocation;                   // Relocation pointing to immediate operand or jump address field
447    const char * OpComment;                       // Additional comment for opcode
ResetSOpcodeProp448    void   Reset() {                              // Set everything to zero
449       memset(this, 0, sizeof(*this));}
450 };
451 // The meaning of each bit in s.Warnings and s.Errors is given in
452 // AsmErrorTexts and AsmWarningTexts in the beginning of disasm.cpp
453 
454 // Prefix categories used by s.Prefixes[category]
455 // 0: Segment prefix (26, 2E, 36, 3E, 64, 65)
456 // 1: Address size prefix (67)
457 // 2: Lock prefix (F0)
458 // 3: Repeat prefix (F2, F3) or VEX prefix (C4, C5) or EVEX, MVEX (62) or XOP (8F)
459 // 4: Operand size prefix (66, REX.W)
460 // 5: Operand type prefix (66, F2, F3)
461 // 6: VEX prefix: bit 5: VEX.L (vector length), bit 0-4: VEX.mmmmm
462 //    MVEX: bit 5 = 0, bit 6 = 1. EVEX: bit 5 = 1, bit 6 = 1
463 // 7: Rex prefix (40 - 4F), VEX.W,R,X,B, DREX.W,R,X,B
464 //    bit 0: B = extension of mod/rm or base or opcode
465 //    bit 1: X = extension of index register
466 //    bit 2: R = extension of reg bits
467 //    bit 3: W = 64 bit operand size, or swap operands or other use of VEX.W
468 //    bit 4: 2-bytes VEX prefix
469 //    bit 5: 3 or 4-bytes VEX prefix
470 //    bit 6: REX prefix
471 //    bit 7: XOP prefix or DREX byte (AMD only)
472 // Note that the 66 and REX.W prefixes belong to two categories. The interpretation
473 // is determined by AllowedPrefixes in SOpcodeDef
474 
475 // Structure for tracing register values etc.
476 // See CDisassembler::UpdateTracer() in disasm.cpp for an explanation
477 struct SATracer {
478    uint8_t  Regist[16];                            // Defines the type of information contained in each g.p. register
479    uint32_t Value[16];                             // Meaning depends on the value of Regist[i]
ResetSATracer480    void Reset() {                                // Set to zero
481       *(uint64_t*)Regist = 0; *(uint64_t*)(Regist+8) = 0;
482    }
483 };
484 
485 // Structure for defining section
486 struct SASection {
487    uint8_t * Start;                                // Point to start of binary data
488    uint32_t  SectionAddress;                       // Address of section (image relative)
489    uint32_t  InitSize;                             // Size of initialized data in section
490    uint32_t  TotalSize;                            // Size of initialized and uninitialized data in section
491    uint32_t  Type;                                 // 0 = unknown, 1 = code,
492                                                  // 2 = data, 3 = uninitialized data only, 4 = constant data,
493                                                  // 0x10 = debug info, 0x11 = exception info.
494                                                  // 0x800 = segment group
495                                                  // 0x1000 = communal section
496    uint32_t  Align;                                // Alignment = 1 << Align
497    uint32_t  WordSize;                             // Word size, 16, 32, 64
498    uint32_t  Name;                                 // Name, as index into CDisassembler::NameBuffer
499    int32_t   Group;                                // Group that the segment is member of. 0 = none, -2 = flat, > 0 = defined group
500 };
501 
502 // Structure for defining relocation or cross-reference
503 struct SARelocation {
504    int32_t   Section;                              // Section of relocation source
505    uint32_t  Offset;                               // Offset of relocation source into section
506    uint32_t  Type;                                 // Relocation types:
507    // 0 = unknown, 1 = direct, 2 = self-relative, 4 = image-relative,
508    // 8 = segment relative, 0x10 = relative to arbitrary ref. point,
509    // 0x21 = direct, has already been relocated to image base (executable files only)
510    // 0x41 = direct, make entry in procedure linkage table. Ignore addend (executable files only)
511    // 0x81 = direct to Gnu indirect function PLT entry
512    // 0x100 = segment address/descriptor, 0x200 = segment of symbol,
513    // 0x400 = segment:offset far
514    // 0x1001 = reference to GOT entry relative to GOT. 0x1002 = self-relative reference to GOT or GOT-entry
515    // 0x2002 = self-relative to PLT
516    uint32_t  Size;                                 // 1 = byte, 2 = word, 4 = dword, 6 = fword, 8 = qword
517    int32_t   Addend;                               // Addend to add to target address,
518                                                  // including distance from source to instruction pointer in self-relative addresses,
519                                                  // not including inline addend.
520    uint32_t  TargetOldIndex;                       // Old symbol table index of target
521    uint32_t  RefOldIndex;                          // Old symbol table index of reference point if Type = 8, 0x10, 0x200
522    int operator < (const SARelocation & y) const{// Operator for sorting relocation table by source address
523       return Section < y.Section || (Section == y.Section && Offset < y.Offset);}
524 };
525 
526 // Structure for indicating where a function begins and ends
527 struct SFunctionRecord {
528    int32_t  Section;                               // Section containing function
529    uint32_t Start;                                 // Offset of function start
530    uint32_t End;                                   // Offset of function end
531    uint32_t Scope;                                 // Scope of function. 0 = inaccessible, 1 = function local, 2 = file local, 4 = public, 8 = weak public, 0x10 = communal, 0x20 = external
532                                                  // 0x10000 means End not known, extend it when you pass End
533    uint32_t OldSymbolIndex;                        // Old symbol table index
534    int operator < (const SFunctionRecord & y) const{// Operator for sorting function table by source address
535       return Section < y.Section || (Section == y.Section && Start < y.Start);}
536 };
537 
538 // Structure for defining symbol
539 struct SASymbol {
540    int32_t   Section;                              // Section number. 0 = external, -1 = absolute symbol, -16 = section to be found from image-relative offset
541    uint32_t  Offset;                               // Offset into section. (Value for absolute symbol)
542    uint32_t  Size;                                 // Number of bytes used by symbol or function. 0 = unknown
543    uint32_t  Type;                                 // Use values listed above for SOpcodeDef operands. 0 = unknown type
544    uint32_t  Name;                                 // Name, as index into CDisassembler::SymbolNameBuffer. 0 = no name yet
545    uint32_t  DLLName;                              // Name of DLL if symbol imported by dynamic linking
546    uint32_t  Scope;                                // 0 = inaccessible, 1 = function local, 2 = file local, 4 = public, 8 = weak public, 0x10 = communal, 0x20 = external, 0x100 = has been written
547    uint32_t  OldIndex;                             // Index in original symbol table. Used for tracking relocation entries
ResetSASymbol548    void    Reset() {                             // Set everything to zero
549       memset(this, 0, sizeof(*this));}
550    int operator < (const SASymbol & y) const {   // Operator for sorting symbol table
551       return Section < y.Section || (Section == y.Section && Offset < y.Offset);}
552 };
553 
554 // Define class CSymbolTable
555 class CSymbolTable {
556 public:
557    CSymbolTable();                               // Constructor
558    uint32_t AddSymbol(int32_t Section, uint32_t Offset,// Add a symbol from original file
559       uint32_t Size, uint32_t Type, uint32_t Scope,
560       uint32_t OldIndex, const char * Name, const char * DLLName = 0);
561    uint32_t NewSymbol(int32_t Section, uint32_t Offset, uint32_t Scope); // Add symbol to list
562    uint32_t NewSymbol(SASymbol & sym);             // Add symbol to list
563    void AssignNames();                           // Assign names to symbols that do not have a name
564    uint32_t FindByAddress(int32_t Section, uint32_t Offset, uint32_t * Last, uint32_t * NextAfter = 0); // Find symbols by address
565    uint32_t FindByAddress(int32_t Section, uint32_t Offset); // Find symbols by address
566    uint32_t Old2NewIndex(uint32_t OldIndex);         // Translate old symbol index to new index
567    SASymbol & operator [](uint32_t NewIndex) {     // Access symbol by new index
568       return List[NewIndex];}
569    const char * HasName(uint32_t symo);            // Ask if symbol has a name, input = old index, output = name or 0
570    const char * GetName(uint32_t symi);            // Get symbol name by new index. (Assign a name if none)
571    const char * GetNameO(uint32_t symo);           // Get symbol name by old index. (Assign a name if none)
572    const char * GetDLLName(uint32_t symi);         // Get import DLL name
573    void   AssignName(uint32_t symi, const char *name); // Give symbol a specific name
GetLimit()574    uint32_t GetLimit() {return OldNum;}            // Get highest old symbol number + 1
GetNumEntries()575    uint32_t GetNumEntries() {return List.GetNumEntries();}// Get highest new symbol number + 1
576 protected:
577    CSList<SASymbol> List;                        // List of symbols, sorted by address
578    CMemoryBuffer    SymbolNameBuffer;            // String buffer for names of symbols
579    CSList<uint32_t>   TranslateOldIndex;           // Table to translate old symbol index to new symbol index
580    void UpdateIndex();                           // Update TranslateOldIndex
581    uint32_t OldNum;                                // = 1 + max OldIndex
582    uint32_t NewNum;                                // Number of entries in List
583    uint32_t UnnamedNum;                            // Number of unnamed symbols
584 public:
585    const char * UnnamedSymbolsPrefix;            // Prefix for names of unnamed symbols
586    const char * UnnamedSymFormat;                // Format string for giving names to unnamed symbols
587    const char * ImportTablePrefix;               // Prefix for pointers in import table
588 };
589 
590 
591 // Define class CDisassembler
592 
593 // Instructions for use:
594 // The calling program must first define the imagebase, if any, by calling
595 // Init. Define all sections by calls to AddSection.
596 // Then define all symbols and relocations or cross-references by calls to
597 // AddSymbol and AddRelocation.
598 // Then call Go().
599 // Go() and its subfunctions will sort Symbols and Relocations, add all
600 // nameless symbols to its symbol table and give them names, assign types
601 // to all symbols as good as possible from the available information, and
602 // find where each function begins and ends. Then it will disassemble the
603 // code and fill OutFile with the disassembly.
604 
605 class CDisassembler {
606 public:
607    CDisassembler();                              // Constructor. Initializes tables etc.
608    void Go();                                    // Do the disassembly
609    void Init(uint32_t ExeType, int64_t ImageBase);   // Define file type and imagebase if executable file
610                                                  // ExeType: 0 = object, 1 = position independent shared object, 2 = executable file
611                                                  // Set ExeType = 2 if addresses have been relocated to a nonzero image base and there is no base relocation table.
612    void AddSection(                              // Define section to be disassembled
613       uint8_t * Buffer,                            // Buffer containing raw data
614       uint32_t  InitSize,                          // Size of initialized data in section
615       uint32_t  TotalSize,                         // Size of initialized and uninitialized data in section
616       uint32_t  SectionAddress,                    // Start address of section (image relative)
617       uint32_t  Type,                              // 0 = unknown, 1 = code, 2 = data, 3 = uninitialized data, 4 = constant data
618       uint32_t  Align,                             // Alignment = 1 << Align
619       uint32_t  WordSize,                          // Segment word size: 16, 32 or 64
620       const char * Name,                         // Name of section
621       uint32_t  NameLength = 0);                   // Length of name if not zero terminated
622    uint32_t AddSymbol(                             // Define symbol for disassembler
623       int32_t   Section,                           // Section number (1-based). 0 = external, -1 = absolute, -16 = Offset contains image-relative address
624       uint32_t  Offset,                            // Offset into section. (Value for absolute symbol)
625       uint32_t  Size,                              // Number of bytes used by symbol or function. 0 = unknown
626       uint32_t  Type,                              // Symbol type. Use values listed above for SOpcodeDef operands. 0 = unknown type
627       uint32_t  Scope,                             // 1 = function local, 2 = file local, 4 = public, 8 = weak public, 0x10 = communal, 0x20 = external
628       uint32_t  OldIndex,                          // Unique identifier used in relocation entries. Value must be > 0 and limited because an array is created with this as index.
629                                                  // A value will be assigned and returned if 0.
630       const char * Name,                         // Name of symbol. Zero-terminated ASCII string. A name will be assigned if 0.
631       const char * DLLName = 0);                 // Name of DLL if imported dynamically
632    void AddRelocation(                           // Define relocation or cross-reference for disassembler
633       int32_t   Section,                           // Section of relocation source:
634                                                  // Sections (and groups) are numbered in the order they are defined, starting at 1
635                                                  // 0 = none or external, -1 = absolute symbol
636                                                  // -16 = Offset contains image-relative address
637       uint32_t  Offset,                            // Offset of relocation source into section
638       int32_t   Addend,                            // Addend to add to target address,
639                                                  // including distance from source to instruction pointer in self-relative addresses,
640                                                  // not including inline addend.
641       uint32_t  Type,                              // see above at SARelocation for definition of relocation types
642       uint32_t  Size,                              // 1 = byte, 2 = word, 4 = dword, 8 = qword
643       uint32_t  TargetIndex,                       // Symbol index of target
644       uint32_t  ReferenceIndex = 0);               // Symbol index of reference point if Type 0x10, Segment index if Type = 8 or 0x200
645    int32_t AddSectionGroup(                        // Define section group (from OMF file)
646       const char * Name,                         // Name of group
647       int32_t MemberSegment);                      // Group member. Repeat for multiple members. 0 if none.
648    static void CountInstructions();              // Count total number of instructions defined in opcodes.cpp
649    const char * CommentSeparator;                // "; " or "# " Start of comment string
650    const char * HereOperator;                    // "$" or "." indicating current position
651    CTextFileBuffer   OutFile;                    // Output file
652 protected:
653    CSymbolTable Symbols;                         // Table of symbols
654    CSList<SASection> Sections;                   // List of sections. First is 0
655    CSList<SARelocation> Relocations;             // List of cross references. First is 0
656    CMemoryBuffer NameBuffer;                     // String buffer for names of sections. First is 0.
657    CSList<SFunctionRecord> FunctionList;         // List of functions
658    int64_t   ImageBase;                            // Image base for executable files
659    uint32_t  ExeType;                              // File type: 0 = object, 1 = position independent shared object, 2 = executable
660    uint32_t  RelocationsInSource;                  // Number of relocations in source file
661 
662    // Code parser: The following members are used for parsing
663    // an opcode and identifying its components
664    uint8_t * Buffer;                               // Point to start of binary data
665    SOpcodeProp s;                                // Properties of current opcode
666    SATracer t;                                   // Trace of register contents
667    uint32_t  Pass;                                 // 1 = pass 1, 2-3 = pass 1 repeated, 0x10 = pass 2, 0x100 = repetition requested
668    uint32_t  SectionEnd;                           // End of current section
669    uint32_t  WordSize;                             // Segment word size: 16, 32, 64
670    uint32_t  Section;                              // Current section/segment
671    uint32_t  SectionAddress;                       // Address of beginning of this section
672    uint32_t  SectionType;                          // 0 = unknown, 1 = code, 2 = data, 3 = uninitialized data, 4 = constant data
673    uint32_t  CodeMode;                             // 1 if current position contains code, 2 if dubiuos, 4 if data
674    uint32_t  IFunction;                            // Index into FunctionList
675    uint32_t  FunctionEnd;                          // End address of current function (pass 2)
676    uint32_t  LabelBegin;                           // Address of nearest preceding label
677    uint32_t  LabelEnd;                             // Address of next label
678    uint32_t  LabelInaccessible;                    // Address of inaccessible code
679    uint32_t  IBegin;                               // Begin of current instruction
680    uint32_t  IEnd;                                 // End of current instruction
681    uint32_t  DataType;                             // Type of current data
682    uint32_t  DataSize;                             // Size of current data
683    uint32_t  FlagPrevious;                         // 1: previous instruction was a NOP.
684                                                  // 2: previous instruction was unconditional jump. 6: instruction was ud2
685                                                  // 0x100: previous data aligned by 16
686                                                  // 0x200: previous data aligned by 32
687    uint8_t   InstructionSetMax;                    // Highest instruction set encountered
688    uint8_t   InstructionSetAMDMAX;                 // Highest AMD-specific instruction set encountered
689    uint16_t  InstructionSetOR;                     // Bitwise OR of all instruction sets encountered
690    uint16_t  Opcodei;                              // Map number and index in opcodes.cpp
691    uint16_t  OpcodeOptions;                        // Option flags for opcode
692    uint16_t  PreviousOpcodei;                      // Opcode for previous instruction
693    uint16_t  PreviousOpcodeOptions;                // Option flags for previous instruction
694    uint32_t  CountErrors;                          // Number of errors since last label
695    uint32_t  Syntax;                               // Assembly syntax dialect: 1: MASM/TASM, 2: NASM/YASM, 4: GAS
696    uint32_t  MasmOptions;                          // Options needed for MASM: 1: dotname, 2: fs used, 4: gs used
697                                                  // 0x100: 16 bit segments, 0x200: 32 bit segments, 0x400: 64 bit segments
698    uint32_t  NamesChanged;                         // Symbol names containing invalid characters changed
699    int32_t   Assumes[6];                           // Assumed value of segment register es, cs, ss, ds, fs, gs. See CDisassembler::WriteSectionName for values
700    void    Pass1();                              // Pass 1: Find symbols types and unnamed symbols
701    void    Pass2();                              // Pass 2: Write output file
702    int     NextFunction2();                      // Loop through function blocks in pass 2. Return 0 if finished
703    int     NextLabel();                          // Loop through labels. (Pass 2)
704    int     NextInstruction1();                   // Go to next instruction. Return 0 if none. (Pass 1)
705    int     NextInstruction2();                   // Go to next instruction. Return 0 if none. (Pass 2)
706    void    ParseInstruction();                   // Parse one opcode
707    void    ScanPrefixes();                       // Scan prefixes
708    void    StorePrefix(uint32_t Category, uint8_t Byte);// Store prefix according to category
709    void    FindMapEntry();                       // Find entry in opcode maps
710    void    FindOperands();                       // Interpret mod/reg/rm and SIB bytes and find operand fields
711    void    FindOperandTypes();                   // Determine the types of each operand
712    void    FindBroadcast();                      // Find broadcast and offset multiplier for EVEX code
713    void    SwizTableLookup();                    // Find swizzle table entry for MVEX code
714    void    FindLabels();                         // Find any labels at current position and next
715    void    CheckForMisplacedLabel();             // Remove any label placed inside function
716    void    FindRelocations();                    // Find any relocation sources in this instruction
717    void    FindWarnings();                       // Find any reasons for warnings in code
718    void    FindErrors();                         // Find any errors in code
719    void    FindInstructionSet();                 // Update instruction set
720    void    CheckForNops();                       // Check if warnings are caused by multi-byte NOP
721    void    UpdateSymbols();                      // Find unnamed symbols, determine symbol types, update symbol list, call CheckJumpTarget if jump/call
722    void    UpdateTracer();                       // Trace register values
723    void    MarkCodeAsDubious();                  // Remember that this may be data in a code segment
724    void    CheckRelocationTarget(uint32_t IRel, uint32_t TargetType, uint32_t TargetSize);// Update relocation record and its target
725    void    CheckJumpTarget(uint32_t symi);         // Extend range of current function to jump target, if needed
726    void    FollowJumpTable(uint32_t symi, uint32_t RelType);// Check jump/call table and its targets
727    uint32_t  MakeMissingRelocation(int32_t Section, uint32_t Offset, uint32_t RelType, uint32_t TargetType, uint32_t TargetScope, uint32_t SourceSize = 0, uint32_t RefPoint = 0); // Make a relocation and its target symbol from inline address
728    void    CheckImportSymbol(uint32_t symi);       // Check for indirect jump to import table entry
729    void    CheckForFunctionBegin();              // Check if function begins at current position
730    void    CheckForFunctionEnd();                // Check if function ends at current position
731    void    CheckLabel();                         // Check if a label is needed before instruction
732    void    InitialErrorCheck();                  // Check for illegal relocations table entries
733    void    FinalErrorCheck();                    // Check for illegal entries in symbol table and relocations table
734    void    CheckNamesValid();                    // Fix invalid characters in symbol and section names
735    void    FixRelocationTargetAddresses();       // Find missing relocation target addresses
736    int     TranslateAbsAddress(int64_t Addr, int32_t &Sect, uint32_t &Offset); // Translate absolute virtual address to section and offset
737    void    WriteFileBegin();                     // Write begin of file
738    void    WriteFileBeginMASM();                 // Write MASM-specific file init
739    void    WriteFileBeginYASM();                 // Write YASM-specific file init
740    void    WriteFileBeginGASM();                 // Write  GAS-specific file init
741    void    WriteFileEnd();                       // Write end of file
742    void    WriteSegmentBegin();                  // Write begin of segment
743    void    WriteSegmentBeginMASM();              // Write begin of segment, MASM syntax
744    void    WriteSegmentBeginYASM();              // Write begin of segment, YASM syntax
745    void    WriteSegmentBeginGASM();              // Write begin of segment, GAS  syntax
746    void    WriteSegmentEnd();                    // Write end of segment
747    void    WritePublicsAndExternalsMASM();       // Write public and external symbol definitions, MASM syntax
748    void    WritePublicsAndExternalsYASMGASM();   // Write public and external symbol definitions, YASM and GAS syntax
749    void    WriteFunctionBegin();                 // Write begin of function
750    void    WriteFunctionBeginMASM(uint32_t symi, uint32_t scope);// Write begin of function, MASM syntax
751    void    WriteFunctionBeginYASM(uint32_t symi, uint32_t scope);// Write begin of function, YASM syntax
752    void    WriteFunctionBeginGASM(uint32_t symi, uint32_t scope);// Write begin of function, GAS  syntax
753    void    WriteFunctionEnd();                   // Write end of function
754    void    WriteFunctionEndMASM(uint32_t symi);    // Write end of function, MASM syntax
755    void    WriteFunctionEndYASM(uint32_t symi);    // Write end of function, YASM syntax
756    void    WriteFunctionEndGASM(uint32_t symi);    // Write end of function, GAS  syntax
757    void    WriteCodeLabel(uint32_t symi);          // Write private or public code label
758    void    WriteCodeLabelMASM(uint32_t symi, uint32_t scope);// Write private or public code label, MASM syntax
759    void    WriteCodeLabelYASM(uint32_t symi, uint32_t scope);// Write private or public code label, MASM syntax
760    void    WriteCodeLabelGASM(uint32_t symi, uint32_t scope);// Write private or public code label, MASM syntax
761    int     WriteFillers();                       // Check if code is a series of NOPs or other fillers. If so then write it as such
762    void    WriteAlign(uint32_t a);                 // Write alignment directive
763    void    WriteErrorsAndWarnings();             // Write errors and warnings, if any
764    void    WriteAssume();                        // Write assume directive for segment register
765    void    WriteInstruction();                   // Write instruction and operands
766    void    WriteCodeComment();                   // Write hex listing of instruction as comment after instruction
767    void    WriteStringInstruction();             // Write string instruction or xlat instruction
768    void    WriteShortRegOperand(uint32_t Type);    // Write register operand from lower 3 bits of opcode byte to OutFile
769    void    WriteRegOperand(uint32_t Type);         // Write register operand from reg bits to OutFile
770    void    WriteRMOperand(uint32_t Type);          // Write memory or register operand from mod/rm bits of mod/reg/rm byte and possibly SIB byte to OutFile
771    void    WriteDREXOperand(uint32_t Type);        // Write register operand from dest bits of DREX byte
772    void    WriteVEXOperand(uint32_t Type, int i);  // Write register operand from VEX.vvvv bits or immediate bits
773    void    WriteOperandAttributeEVEX(int i, int isMem);// Write operand attributes and instruction attributes from EVEX z, LL, b and aaa bits
774    void    WriteOperandAttributeMVEX(int i, int isMem);// Write operand attributes and instruction attributes from MVEX sss, e and kkk bits
775    void    WriteImmediateOperand(uint32_t Type);   // Write immediate operand or direct jump/call address
776    void    WriteOtherOperand(uint32_t Type);       // Write other type of operand
777    void    WriteRegisterName(uint32_t Value, uint32_t Type); // Write name of register to OutFile
778    void    WriteSectionName(int32_t SegIndex);     // Write section name from section index
779    void    WriteSymbolName(uint32_t symi);         // Write symbol name
780    void    WriteRelocationTarget(uint32_t irel, uint32_t Context, int64_t Addend);// Write cross reference
781    void    WriteOperandType(uint32_t type);        // Write type override before operand, e.g. "dword ptr"
782    void    WriteOperandTypeMASM(uint32_t type);    // Write type override before operand, e.g. "dword ptr", MASM syntax
783    void    WriteOperandTypeYASM(uint32_t type);    // Write type override before operand, e.g. "dword", YASM syntax
784    void    WriteOperandTypeGASM(uint32_t type);    // Write type override before operand, e.g. "dword ptr", GAS syntax
785    void    WriteDataItems();                     // Write data items
786    void    WriteDataLabelMASM(const char * name, uint32_t sym, int line); // Write label before data item, MASM syntax
787    void    WriteDataLabelYASM(const char * name, uint32_t sym, int line); // Write label before data item, YASM syntax
788    void    WriteDataLabelGASM(const char * name, uint32_t sym, int line); // Write label before data item, GAS  syntax
789    void    WriteUninitDataItemsMASM(uint32_t size, uint32_t count);// Write uninitialized (BSS) data, MASM syntax
790    void    WriteUninitDataItemsYASM(uint32_t size, uint32_t count);// Write uninitialized (BSS) data, YASM syntax
791    void    WriteUninitDataItemsGASM(uint32_t size, uint32_t count);// Write uninitialized (BSS) data, GAS  syntax
792    void    WriteDataDirectiveMASM(uint32_t size);  // Write DB, etc., MASM syntax
793    void    WriteDataDirectiveYASM(uint32_t size);  // Write DB, etc., MASM syntax
794    void    WriteDataDirectiveGASM(uint32_t size);  // Write DB, etc., MASM syntax
795    void    WriteDataComment(uint32_t ElementSize, uint32_t LinePos, uint32_t Pos, uint32_t irel);// Write comment after data item
796    uint32_t  GetDataItemSize(uint32_t Type);         // Get size of data item with specified type
797    uint32_t  GetDataElementSize(uint32_t Type);      // Get size of vector element in data item with specified type
798    int32_t   GetSegmentRegisterFromPrefix();       // Translate segment prefix to segment register
799 
Get(uint32_t Offset)800    template <class TX> TX & Get(uint32_t Offset) { // Get object of arbitrary type from buffer
801       return *(TX*)(Buffer + Offset);}
802 };
803 
804 
805 // Declare tables in opcodes.cpp:
806 extern SOpcodeDef OpcodeMap0[256];               // First opcode map
807 
808 extern uint32_t OpcodeStartPageVEX[];              // Entries to opcode maps, indexed by VEX.mmmm bits
809 extern SOpcodeDef const * OpcodeStartPageXOP[];  // Entries to opcode maps, indexed by XOP.mmmm bits
810 
811 extern const uint32_t NumOpcodeStartPageVEX;       // Number of entries in OpcodeStartPage
812 extern const uint32_t NumOpcodeStartPageXOP;       // Number of entries in OpcodeStartPageXOP
813 
814 extern const SOpcodeDef * const OpcodeTables[];  // Pointers to all opcode tables
815 
816 extern const uint32_t OpcodeTableLength[];         // Size of each table pointed to by OpcodeTables[]
817 
818 extern const uint32_t NumOpcodeTables1, NumOpcodeTables2;// Number of entries in OpcodeTables[] and OpcodeTableLength[]
819 
820 extern const char * RegisterNames8[8];           // Names of 8 bit registers
821 extern const char * RegisterNames8x[16];         // Names of 8 bit registers with REX prefix
822 extern const char * RegisterNames16[16];         // Names of 16 bit registers
823 extern const char * RegisterNames32[16];         // Names of 32 bit registers
824 extern const char * RegisterNames64[16];         // Names of 64 bit registers
825 extern const char * RegisterNamesSeg[8];         // Names of segment registers
826 extern const char * RegisterNamesCR[16];         // Names of control registers
827 
828 extern SwizSpec const * SwizTables[][2];         // Pointers to swizzle tables
829 extern SwizSpec const * SwizRoundTables[][2];    // Pointers to swizzle round tables
830 extern const char * EVEXRoundingNames[5];        // Tables of rounding mode names for EVEX
831 
832 
833 // Define constants for special section/segment/group values
834 #define ASM_SEGMENT_UNKNOWN    0   // Unknown segment for external symbols
835 #define ASM_SEGMENT_ABSOLUTE  -1   // No segment for absolute public symbols
836 #define ASM_SEGMENT_FLAT      -2   // Flat segment group for non-segmented code
837 #define ASM_SEGMENT_NOTHING   -3   // Segment register assumed to nothing by assume directive
838 #define ASM_SEGMENT_ERROR     -4   // Segment register assumed to error (don't use) by assume directive
839 #define ASM_SEGMENT_IMGREL   -16   // Offset is relative to image base or file base,
840                                    // ..leave it to the disassembler to find which section contains this address.
841 // Values > 0 are indices into the Sections buffer representing a named section, segment or group
842 
843 #endif // #ifndef DISASM_H
844