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