Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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 InstructionSet;              // mmx, sse, 3dnow, x64, etc.
  27.    uint32 AllowedPrefixes;             // prefixes allowed for this opcode
  28.    uint16 InstructionFormat;           // opcode type, number of operands
  29.    uint16 Destination;                 // type and size of destination operand
  30.    uint16 Source1;                     // type and size of 1. source operand
  31.    uint16 Source2;                     // type and size of 2. source operand
  32.    uint16 Source3;                     // type and size of 3. source operand
  33.    uint16 EVEX;                        // options for interpreting EVEX prefix, may be used for 4. source operand otherwise (unused)
  34.    uint16 MVEX;                        // options for interpreting MVEX prefix: swizzle, convert, mask options
  35.    uint16 TableLink;                   // this entry is a link to another map
  36.    uint16 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 memop;       // memory operand type
  407.     uint32 memopsize;   // memory operand size = byte offset multiplier = required alignment
  408.     uint32 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  Prefixes[8];                           // Stores the last prefix encountered in each category
  419.    uint8  Conflicts[8];                          // Counts prefix conflicts as different prefixes in the same category
  420.    uint32 Warnings1;                             // Warnings about conditions that could be intentional and suboptimal code
  421.    uint32 Warnings2;                             // Warnings about possible misinterpretation
  422.    uint32 Errors;                                // Errors that will prevent execution or are unlikely to be intentional
  423.    uint32 AddressSize;                           // Address size: 16, 32 or 64
  424.    uint32 OperandSize;                           // Operand size: 16, 32 or 64
  425.    uint32 MaxNumOperands;                        // Number of opcode table operands to check
  426.    uint32 Mod;                                   // mod bits of mod/reg/rm byte
  427.    uint32 Reg;                                   // reg bits of mod/reg/rm byte
  428.    uint32 RM;                                    // r/m bits of mod/reg/rm byte
  429.    uint32 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 BaseReg;                               // Base  register + 1. (0 if none)
  431.    uint32 IndexReg;                              // Index register + 1. (0 if none)
  432.    uint32 Scale;                                 // Scale factor = 2^Scale
  433.    uint32 Vreg;                                  // ~VEX.vvvv or AMD DREX byte
  434.    uint32 Kreg;                                  // EVEX.aaa = MVEX.kkk mask register
  435.    uint32 Esss;                                  // EVEX.zLLb = MVEX.Esss option bits
  436.    SwizSpec const * SwizRecord;                  // Selected entry in MVEX table for MVEX code
  437.    uint32 OffsetMultiplier;                      // Multiplier for 1-byte offset calculated from EVEX or obtained from MVEX.sss and table lookup
  438.    uint32 Operands[5];                           // Operand types for destination, source, immediate
  439.    uint32 OpcodeStart1;                          // Index to first opcode byte, after prefixes
  440.    uint32 OpcodeStart2;                          // Index to last opcode byte, after 0F, 0F 38, etc., before mod/reg/rm byte and operands
  441.    uint32 AddressField;                          // Beginning of address/displacement field
  442.    uint32 AddressFieldSize;                      // Size of address/displacement field
  443.    uint32 AddressRelocation;                     // Relocation pointing to address field
  444.    uint32 ImmediateField;                        // Beginning of immediate operand or jump address field
  445.    uint32 ImmediateFieldSize;                    // Size of immediate operand or jump address field
  446.    uint32 ImmediateRelocation;                   // Relocation pointing to immediate operand or jump address field
  447.    const char * OpComment;                       // Additional comment for opcode
  448.    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  Regist[16];                            // Defines the type of information contained in each g.p. register
  479.    uint32 Value[16];                             // Meaning depends on the value of Regist[i]
  480.    void Reset() {                                // Set to zero
  481.       *(uint64*)Regist = 0; *(uint64*)(Regist+8) = 0;
  482.    }
  483. };
  484.  
  485. // Structure for defining section
  486. struct SASection {
  487.    uint8 * Start;                                // Point to start of binary data
  488.    uint32  SectionAddress;                       // Address of section (image relative)
  489.    uint32  InitSize;                             // Size of initialized data in section
  490.    uint32  TotalSize;                            // Size of initialized and uninitialized data in section
  491.    uint32  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  Align;                                // Alignment = 1 << Align
  497.    uint32  WordSize;                             // Word size, 16, 32, 64
  498.    uint32  Name;                                 // Name, as index into CDisassembler::NameBuffer
  499.    int32   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   Section;                              // Section of relocation source
  505.    uint32  Offset;                               // Offset of relocation source into section
  506.    uint32  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  Size;                                 // 1 = byte, 2 = word, 4 = dword, 6 = fword, 8 = qword
  517.    int32   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  TargetOldIndex;                       // Old symbol table index of target
  521.    uint32  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  Section;                               // Section containing function
  529.    uint32 Start;                                 // Offset of function start
  530.    uint32 End;                                   // Offset of function end
  531.    uint32 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 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   Section;                              // Section number. 0 = external, -1 = absolute symbol, -16 = section to be found from image-relative offset
  541.    uint32  Offset;                               // Offset into section. (Value for absolute symbol)
  542.    uint32  Size;                                 // Number of bytes used by symbol or function. 0 = unknown
  543.    uint32  Type;                                 // Use values listed above for SOpcodeDef operands. 0 = unknown type
  544.    uint32  Name;                                 // Name, as index into CDisassembler::SymbolNameBuffer. 0 = no name yet
  545.    uint32  DLLName;                              // Name of DLL if symbol imported by dynamic linking
  546.    uint32  Scope;                                // 0 = inaccessible, 1 = function local, 2 = file local, 4 = public, 8 = weak public, 0x10 = communal, 0x20 = external, 0x100 = has been written
  547.    uint32  OldIndex;                             // Index in original symbol table. Used for tracking relocation entries
  548.    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 AddSymbol(int32 Section, uint32 Offset,// Add a symbol from original file
  559.       uint32 Size, uint32 Type, uint32 Scope,
  560.       uint32 OldIndex, const char * Name, const char * DLLName = 0);
  561.    uint32 NewSymbol(int32 Section, uint32 Offset, uint32 Scope); // Add symbol to list
  562.    uint32 NewSymbol(SASymbol & sym);             // Add symbol to list
  563.    void AssignNames();                           // Assign names to symbols that do not have a name
  564.    uint32 FindByAddress(int32 Section, uint32 Offset, uint32 * Last, uint32 * NextAfter = 0); // Find symbols by address
  565.    uint32 FindByAddress(int32 Section, uint32 Offset); // Find symbols by address
  566.    uint32 Old2NewIndex(uint32 OldIndex);         // Translate old symbol index to new index
  567.    SASymbol & operator [](uint32 NewIndex) {     // Access symbol by new index
  568.       return List[NewIndex];}
  569.    const char * HasName(uint32 symo);            // Ask if symbol has a name, input = old index, output = name or 0
  570.    const char * GetName(uint32 symi);            // Get symbol name by new index. (Assign a name if none)
  571.    const char * GetNameO(uint32 symo);           // Get symbol name by old index. (Assign a name if none)
  572.    const char * GetDLLName(uint32 symi);         // Get import DLL name
  573.    void   AssignName(uint32 symi, const char *name); // Give symbol a specific name
  574.    uint32 GetLimit() {return OldNum;}            // Get highest old symbol number + 1
  575.    uint32 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>   TranslateOldIndex;           // Table to translate old symbol index to new symbol index
  580.    void UpdateIndex();                           // Update TranslateOldIndex
  581.    uint32 OldNum;                                // = 1 + max OldIndex
  582.    uint32 NewNum;                                // Number of entries in List
  583.    uint32 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 ExeType, int64 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 * Buffer,                            // Buffer containing raw data
  614.       uint32  InitSize,                          // Size of initialized data in section
  615.       uint32  TotalSize,                         // Size of initialized and uninitialized data in section
  616.       uint32  SectionAddress,                    // Start address of section (image relative)
  617.       uint32  Type,                              // 0 = unknown, 1 = code, 2 = data, 3 = uninitialized data, 4 = constant data
  618.       uint32  Align,                             // Alignment = 1 << Align
  619.       uint32  WordSize,                          // Segment word size: 16, 32 or 64
  620.       const char * Name,                         // Name of section
  621.       uint32  NameLength = 0);                   // Length of name if not zero terminated
  622.    uint32 AddSymbol(                             // Define symbol for disassembler
  623.       int32   Section,                           // Section number (1-based). 0 = external, -1 = absolute, -16 = Offset contains image-relative address
  624.       uint32  Offset,                            // Offset into section. (Value for absolute symbol)
  625.       uint32  Size,                              // Number of bytes used by symbol or function. 0 = unknown
  626.       uint32  Type,                              // Symbol type. Use values listed above for SOpcodeDef operands. 0 = unknown type
  627.       uint32  Scope,                             // 1 = function local, 2 = file local, 4 = public, 8 = weak public, 0x10 = communal, 0x20 = external
  628.       uint32  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   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  Offset,                            // Offset of relocation source into section
  638.       int32   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  Type,                              // see above at SARelocation for definition of relocation types
  642.       uint32  Size,                              // 1 = byte, 2 = word, 4 = dword, 8 = qword
  643.       uint32  TargetIndex,                       // Symbol index of target
  644.       uint32  ReferenceIndex = 0);               // Symbol index of reference point if Type 0x10, Segment index if Type = 8 or 0x200
  645.    int32 AddSectionGroup(                        // Define section group (from OMF file)
  646.       const char * Name,                         // Name of group
  647.       int32 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   ImageBase;                            // Image base for executable files
  659.    uint32  ExeType;                              // File type: 0 = object, 1 = position independent shared object, 2 = executable
  660.    uint32  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 * Buffer;                               // Point to start of binary data
  665.    SOpcodeProp s;                                // Properties of current opcode
  666.    SATracer t;                                   // Trace of register contents
  667.    uint32  Pass;                                 // 1 = pass 1, 2-3 = pass 1 repeated, 0x10 = pass 2, 0x100 = repetition requested
  668.    uint32  SectionEnd;                           // End of current section
  669.    uint32  WordSize;                             // Segment word size: 16, 32, 64
  670.    uint32  Section;                              // Current section/segment
  671.    uint32  SectionAddress;                       // Address of beginning of this section
  672.    uint32  SectionType;                          // 0 = unknown, 1 = code, 2 = data, 3 = uninitialized data, 4 = constant data
  673.    uint32  CodeMode;                             // 1 if current position contains code, 2 if dubiuos, 4 if data
  674.    uint32  IFunction;                            // Index into FunctionList
  675.    uint32  FunctionEnd;                          // End address of current function (pass 2)
  676.    uint32  LabelBegin;                           // Address of nearest preceding label
  677.    uint32  LabelEnd;                             // Address of next label
  678.    uint32  LabelInaccessible;                    // Address of inaccessible code
  679.    uint32  IBegin;                               // Begin of current instruction
  680.    uint32  IEnd;                                 // End of current instruction
  681.    uint32  DataType;                             // Type of current data
  682.    uint32  DataSize;                             // Size of current data
  683.    uint32  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   InstructionSetMax;                    // Highest instruction set encountered
  688.    uint8   InstructionSetAMDMAX;                 // Highest AMD-specific instruction set encountered
  689.    uint16  InstructionSetOR;                     // Bitwise OR of all instruction sets encountered
  690.    uint16  Opcodei;                              // Map number and index in opcodes.cpp
  691.    uint16  OpcodeOptions;                        // Option flags for opcode
  692.    uint16  PreviousOpcodei;                      // Opcode for previous instruction
  693.    uint16  PreviousOpcodeOptions;                // Option flags for previous instruction
  694.    uint32  CountErrors;                          // Number of errors since last label
  695.    uint32  Syntax;                               // Assembly syntax dialect: 1: MASM/TASM, 2: NASM/YASM, 4: GAS
  696.    uint32  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  NamesChanged;                         // Symbol names containing invalid characters changed
  699.    int32   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 Category, uint8 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 IRel, uint32 TargetType, uint32 TargetSize);// Update relocation record and its target
  725.    void    CheckJumpTarget(uint32 symi);         // Extend range of current function to jump target, if needed
  726.    void    FollowJumpTable(uint32 symi, uint32 RelType);// Check jump/call table and its targets
  727.    uint32  MakeMissingRelocation(int32 Section, uint32 Offset, uint32 RelType, uint32 TargetType, uint32 TargetScope, uint32 SourceSize = 0, uint32 RefPoint = 0); // Make a relocation and its target symbol from inline address
  728.    void    CheckImportSymbol(uint32 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 Addr, int32 &Sect, uint32 &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 symi, uint32 scope);// Write begin of function, MASM syntax
  751.    void    WriteFunctionBeginYASM(uint32 symi, uint32 scope);// Write begin of function, YASM syntax
  752.    void    WriteFunctionBeginGASM(uint32 symi, uint32 scope);// Write begin of function, GAS  syntax
  753.    void    WriteFunctionEnd();                   // Write end of function
  754.    void    WriteFunctionEndMASM(uint32 symi);    // Write end of function, MASM syntax
  755.    void    WriteFunctionEndYASM(uint32 symi);    // Write end of function, YASM syntax
  756.    void    WriteFunctionEndGASM(uint32 symi);    // Write end of function, GAS  syntax
  757.    void    WriteCodeLabel(uint32 symi);          // Write private or public code label
  758.    void    WriteCodeLabelMASM(uint32 symi, uint32 scope);// Write private or public code label, MASM syntax
  759.    void    WriteCodeLabelYASM(uint32 symi, uint32 scope);// Write private or public code label, MASM syntax
  760.    void    WriteCodeLabelGASM(uint32 symi, uint32 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 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 Type);    // Write register operand from lower 3 bits of opcode byte to OutFile
  769.    void    WriteRegOperand(uint32 Type);         // Write register operand from reg bits to OutFile
  770.    void    WriteRMOperand(uint32 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 Type);        // Write register operand from dest bits of DREX byte
  772.    void    WriteVEXOperand(uint32 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 Type);   // Write immediate operand or direct jump/call address
  776.    void    WriteOtherOperand(uint32 Type);       // Write other type of operand
  777.    void    WriteRegisterName(uint32 Value, uint32 Type); // Write name of register to OutFile
  778.    void    WriteSectionName(int32 SegIndex);     // Write section name from section index
  779.    void    WriteSymbolName(uint32 symi);         // Write symbol name
  780.    void    WriteRelocationTarget(uint32 irel, uint32 Context, int64 Addend);// Write cross reference
  781.    void    WriteOperandType(uint32 type);        // Write type override before operand, e.g. "dword ptr"
  782.    void    WriteOperandTypeMASM(uint32 type);    // Write type override before operand, e.g. "dword ptr", MASM syntax
  783.    void    WriteOperandTypeYASM(uint32 type);    // Write type override before operand, e.g. "dword", YASM syntax
  784.    void    WriteOperandTypeGASM(uint32 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 sym, int line); // Write label before data item, MASM syntax
  787.    void    WriteDataLabelYASM(const char * name, uint32 sym, int line); // Write label before data item, YASM syntax
  788.    void    WriteDataLabelGASM(const char * name, uint32 sym, int line); // Write label before data item, GAS  syntax
  789.    void    WriteUninitDataItemsMASM(uint32 size, uint32 count);// Write uninitialized (BSS) data, MASM syntax
  790.    void    WriteUninitDataItemsYASM(uint32 size, uint32 count);// Write uninitialized (BSS) data, YASM syntax
  791.    void    WriteUninitDataItemsGASM(uint32 size, uint32 count);// Write uninitialized (BSS) data, GAS  syntax
  792.    void    WriteDataDirectiveMASM(uint32 size);  // Write DB, etc., MASM syntax
  793.    void    WriteDataDirectiveYASM(uint32 size);  // Write DB, etc., MASM syntax
  794.    void    WriteDataDirectiveGASM(uint32 size);  // Write DB, etc., MASM syntax
  795.    void    WriteDataComment(uint32 ElementSize, uint32 LinePos, uint32 Pos, uint32 irel);// Write comment after data item
  796.    uint32  GetDataItemSize(uint32 Type);         // Get size of data item with specified type
  797.    uint32  GetDataElementSize(uint32 Type);      // Get size of vector element in data item with specified type
  798.    int32   GetSegmentRegisterFromPrefix();       // Translate segment prefix to segment register
  799.  
  800.    template <class TX> TX & Get(uint32 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 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 NumOpcodeStartPageVEX;       // Number of entries in OpcodeStartPage
  812. extern const uint32 NumOpcodeStartPageXOP;       // Number of entries in OpcodeStartPageXOP
  813.  
  814. extern const SOpcodeDef * const OpcodeTables[];  // Pointers to all opcode tables
  815.  
  816. extern const uint32 OpcodeTableLength[];         // Size of each table pointed to by OpcodeTables[]
  817.  
  818. extern const uint32 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.