inst.go (10858B)
1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package x86asm implements decoding of x86 machine code. 6 package x86asm 7 8 import ( 9 "bytes" 10 "fmt" 11 ) 12 13 // An Inst is a single instruction. 14 type Inst struct { 15 Prefix Prefixes // Prefixes applied to the instruction. 16 Op Op // Opcode mnemonic 17 Opcode uint32 // Encoded opcode bits, left aligned (first byte is Opcode>>24, etc) 18 Args Args // Instruction arguments, in Intel order 19 Mode int // processor mode in bits: 16, 32, or 64 20 AddrSize int // address size in bits: 16, 32, or 64 21 DataSize int // operand size in bits: 16, 32, or 64 22 MemBytes int // size of memory argument in bytes: 1, 2, 4, 8, 16, and so on. 23 Len int // length of encoded instruction in bytes 24 PCRel int // length of PC-relative address in instruction encoding 25 PCRelOff int // index of start of PC-relative address in instruction encoding 26 } 27 28 // Prefixes is an array of prefixes associated with a single instruction. 29 // The prefixes are listed in the same order as found in the instruction: 30 // each prefix byte corresponds to one slot in the array. The first zero 31 // in the array marks the end of the prefixes. 32 type Prefixes [14]Prefix 33 34 // A Prefix represents an Intel instruction prefix. 35 // The low 8 bits are the actual prefix byte encoding, 36 // and the top 8 bits contain distinguishing bits and metadata. 37 type Prefix uint16 38 39 const ( 40 // Metadata about the role of a prefix in an instruction. 41 PrefixImplicit Prefix = 0x8000 // prefix is implied by instruction text 42 PrefixIgnored Prefix = 0x4000 // prefix is ignored: either irrelevant or overridden by a later prefix 43 PrefixInvalid Prefix = 0x2000 // prefix makes entire instruction invalid (bad LOCK) 44 45 // Memory segment overrides. 46 PrefixES Prefix = 0x26 // ES segment override 47 PrefixCS Prefix = 0x2E // CS segment override 48 PrefixSS Prefix = 0x36 // SS segment override 49 PrefixDS Prefix = 0x3E // DS segment override 50 PrefixFS Prefix = 0x64 // FS segment override 51 PrefixGS Prefix = 0x65 // GS segment override 52 53 // Branch prediction. 54 PrefixPN Prefix = 0x12E // predict not taken (conditional branch only) 55 PrefixPT Prefix = 0x13E // predict taken (conditional branch only) 56 57 // Size attributes. 58 PrefixDataSize Prefix = 0x66 // operand size override 59 PrefixData16 Prefix = 0x166 60 PrefixData32 Prefix = 0x266 61 PrefixAddrSize Prefix = 0x67 // address size override 62 PrefixAddr16 Prefix = 0x167 63 PrefixAddr32 Prefix = 0x267 64 65 // One of a kind. 66 PrefixLOCK Prefix = 0xF0 // lock 67 PrefixREPN Prefix = 0xF2 // repeat not zero 68 PrefixXACQUIRE Prefix = 0x1F2 69 PrefixBND Prefix = 0x2F2 70 PrefixREP Prefix = 0xF3 // repeat 71 PrefixXRELEASE Prefix = 0x1F3 72 73 // The REX prefixes must be in the range [PrefixREX, PrefixREX+0x10). 74 // the other bits are set or not according to the intended use. 75 PrefixREX Prefix = 0x40 // REX 64-bit extension prefix 76 PrefixREXW Prefix = 0x08 // extension bit W (64-bit instruction width) 77 PrefixREXR Prefix = 0x04 // extension bit R (r field in modrm) 78 PrefixREXX Prefix = 0x02 // extension bit X (index field in sib) 79 PrefixREXB Prefix = 0x01 // extension bit B (r/m field in modrm or base field in sib) 80 PrefixVEX2Bytes Prefix = 0xC5 // Short form of vex prefix 81 PrefixVEX3Bytes Prefix = 0xC4 // Long form of vex prefix 82 ) 83 84 // IsREX reports whether p is a REX prefix byte. 85 func (p Prefix) IsREX() bool { 86 return p&0xF0 == PrefixREX 87 } 88 89 func (p Prefix) IsVEX() bool { 90 return p&0xFF == PrefixVEX2Bytes || p&0xFF == PrefixVEX3Bytes 91 } 92 93 func (p Prefix) String() string { 94 p &^= PrefixImplicit | PrefixIgnored | PrefixInvalid 95 if s := prefixNames[p]; s != "" { 96 return s 97 } 98 99 if p.IsREX() { 100 s := "REX." 101 if p&PrefixREXW != 0 { 102 s += "W" 103 } 104 if p&PrefixREXR != 0 { 105 s += "R" 106 } 107 if p&PrefixREXX != 0 { 108 s += "X" 109 } 110 if p&PrefixREXB != 0 { 111 s += "B" 112 } 113 return s 114 } 115 116 return fmt.Sprintf("Prefix(%#x)", int(p)) 117 } 118 119 // An Op is an x86 opcode. 120 type Op uint32 121 122 func (op Op) String() string { 123 i := int(op) 124 if i < 0 || i >= len(opNames) || opNames[i] == "" { 125 return fmt.Sprintf("Op(%d)", i) 126 } 127 return opNames[i] 128 } 129 130 // An Args holds the instruction arguments. 131 // If an instruction has fewer than 4 arguments, 132 // the final elements in the array are nil. 133 type Args [4]Arg 134 135 // An Arg is a single instruction argument, 136 // one of these types: Reg, Mem, Imm, Rel. 137 type Arg interface { 138 String() string 139 isArg() 140 } 141 142 // Note that the implements of Arg that follow are all sized 143 // so that on a 64-bit machine the data can be inlined in 144 // the interface value instead of requiring an allocation. 145 146 // A Reg is a single register. 147 // The zero Reg value has no name but indicates ``no register.'' 148 type Reg uint8 149 150 const ( 151 _ Reg = iota 152 153 // 8-bit 154 AL 155 CL 156 DL 157 BL 158 AH 159 CH 160 DH 161 BH 162 SPB 163 BPB 164 SIB 165 DIB 166 R8B 167 R9B 168 R10B 169 R11B 170 R12B 171 R13B 172 R14B 173 R15B 174 175 // 16-bit 176 AX 177 CX 178 DX 179 BX 180 SP 181 BP 182 SI 183 DI 184 R8W 185 R9W 186 R10W 187 R11W 188 R12W 189 R13W 190 R14W 191 R15W 192 193 // 32-bit 194 EAX 195 ECX 196 EDX 197 EBX 198 ESP 199 EBP 200 ESI 201 EDI 202 R8L 203 R9L 204 R10L 205 R11L 206 R12L 207 R13L 208 R14L 209 R15L 210 211 // 64-bit 212 RAX 213 RCX 214 RDX 215 RBX 216 RSP 217 RBP 218 RSI 219 RDI 220 R8 221 R9 222 R10 223 R11 224 R12 225 R13 226 R14 227 R15 228 229 // Instruction pointer. 230 IP // 16-bit 231 EIP // 32-bit 232 RIP // 64-bit 233 234 // 387 floating point registers. 235 F0 236 F1 237 F2 238 F3 239 F4 240 F5 241 F6 242 F7 243 244 // MMX registers. 245 M0 246 M1 247 M2 248 M3 249 M4 250 M5 251 M6 252 M7 253 254 // XMM registers. 255 X0 256 X1 257 X2 258 X3 259 X4 260 X5 261 X6 262 X7 263 X8 264 X9 265 X10 266 X11 267 X12 268 X13 269 X14 270 X15 271 272 // Segment registers. 273 ES 274 CS 275 SS 276 DS 277 FS 278 GS 279 280 // System registers. 281 GDTR 282 IDTR 283 LDTR 284 MSW 285 TASK 286 287 // Control registers. 288 CR0 289 CR1 290 CR2 291 CR3 292 CR4 293 CR5 294 CR6 295 CR7 296 CR8 297 CR9 298 CR10 299 CR11 300 CR12 301 CR13 302 CR14 303 CR15 304 305 // Debug registers. 306 DR0 307 DR1 308 DR2 309 DR3 310 DR4 311 DR5 312 DR6 313 DR7 314 DR8 315 DR9 316 DR10 317 DR11 318 DR12 319 DR13 320 DR14 321 DR15 322 323 // Task registers. 324 TR0 325 TR1 326 TR2 327 TR3 328 TR4 329 TR5 330 TR6 331 TR7 332 ) 333 334 const regMax = TR7 335 336 func (Reg) isArg() {} 337 338 func (r Reg) String() string { 339 i := int(r) 340 if i < 0 || i >= len(regNames) || regNames[i] == "" { 341 return fmt.Sprintf("Reg(%d)", i) 342 } 343 return regNames[i] 344 } 345 346 // A Mem is a memory reference. 347 // The general form is Segment:[Base+Scale*Index+Disp]. 348 type Mem struct { 349 Segment Reg 350 Base Reg 351 Scale uint8 352 Index Reg 353 Disp int64 354 } 355 356 func (Mem) isArg() {} 357 358 func (m Mem) String() string { 359 var base, plus, scale, index, disp string 360 361 if m.Base != 0 { 362 base = m.Base.String() 363 } 364 if m.Scale != 0 { 365 if m.Base != 0 { 366 plus = "+" 367 } 368 if m.Scale > 1 { 369 scale = fmt.Sprintf("%d*", m.Scale) 370 } 371 index = m.Index.String() 372 } 373 if m.Disp != 0 || m.Base == 0 && m.Scale == 0 { 374 disp = fmt.Sprintf("%+#x", m.Disp) 375 } 376 return "[" + base + plus + scale + index + disp + "]" 377 } 378 379 // A Rel is an offset relative to the current instruction pointer. 380 type Rel int32 381 382 func (Rel) isArg() {} 383 384 func (r Rel) String() string { 385 return fmt.Sprintf(".%+d", r) 386 } 387 388 // An Imm is an integer constant. 389 type Imm int64 390 391 func (Imm) isArg() {} 392 393 func (i Imm) String() string { 394 return fmt.Sprintf("%#x", int64(i)) 395 } 396 397 func (i Inst) String() string { 398 var buf bytes.Buffer 399 for _, p := range i.Prefix { 400 if p == 0 { 401 break 402 } 403 if p&PrefixImplicit != 0 { 404 continue 405 } 406 fmt.Fprintf(&buf, "%v ", p) 407 } 408 fmt.Fprintf(&buf, "%v", i.Op) 409 sep := " " 410 for _, v := range i.Args { 411 if v == nil { 412 break 413 } 414 fmt.Fprintf(&buf, "%s%v", sep, v) 415 sep = ", " 416 } 417 return buf.String() 418 } 419 420 func isReg(a Arg) bool { 421 _, ok := a.(Reg) 422 return ok 423 } 424 425 func isSegReg(a Arg) bool { 426 r, ok := a.(Reg) 427 return ok && ES <= r && r <= GS 428 } 429 430 func isMem(a Arg) bool { 431 _, ok := a.(Mem) 432 return ok 433 } 434 435 func isImm(a Arg) bool { 436 _, ok := a.(Imm) 437 return ok 438 } 439 440 func regBytes(a Arg) int { 441 r, ok := a.(Reg) 442 if !ok { 443 return 0 444 } 445 if AL <= r && r <= R15B { 446 return 1 447 } 448 if AX <= r && r <= R15W { 449 return 2 450 } 451 if EAX <= r && r <= R15L { 452 return 4 453 } 454 if RAX <= r && r <= R15 { 455 return 8 456 } 457 return 0 458 } 459 460 func isSegment(p Prefix) bool { 461 switch p { 462 case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS: 463 return true 464 } 465 return false 466 } 467 468 // The Op definitions and string list are in tables.go. 469 470 var prefixNames = map[Prefix]string{ 471 PrefixCS: "CS", 472 PrefixDS: "DS", 473 PrefixES: "ES", 474 PrefixFS: "FS", 475 PrefixGS: "GS", 476 PrefixSS: "SS", 477 PrefixLOCK: "LOCK", 478 PrefixREP: "REP", 479 PrefixREPN: "REPN", 480 PrefixAddrSize: "ADDRSIZE", 481 PrefixDataSize: "DATASIZE", 482 PrefixAddr16: "ADDR16", 483 PrefixData16: "DATA16", 484 PrefixAddr32: "ADDR32", 485 PrefixData32: "DATA32", 486 PrefixBND: "BND", 487 PrefixXACQUIRE: "XACQUIRE", 488 PrefixXRELEASE: "XRELEASE", 489 PrefixREX: "REX", 490 PrefixPT: "PT", 491 PrefixPN: "PN", 492 } 493 494 var regNames = [...]string{ 495 AL: "AL", 496 CL: "CL", 497 BL: "BL", 498 DL: "DL", 499 AH: "AH", 500 CH: "CH", 501 BH: "BH", 502 DH: "DH", 503 SPB: "SPB", 504 BPB: "BPB", 505 SIB: "SIB", 506 DIB: "DIB", 507 R8B: "R8B", 508 R9B: "R9B", 509 R10B: "R10B", 510 R11B: "R11B", 511 R12B: "R12B", 512 R13B: "R13B", 513 R14B: "R14B", 514 R15B: "R15B", 515 AX: "AX", 516 CX: "CX", 517 BX: "BX", 518 DX: "DX", 519 SP: "SP", 520 BP: "BP", 521 SI: "SI", 522 DI: "DI", 523 R8W: "R8W", 524 R9W: "R9W", 525 R10W: "R10W", 526 R11W: "R11W", 527 R12W: "R12W", 528 R13W: "R13W", 529 R14W: "R14W", 530 R15W: "R15W", 531 EAX: "EAX", 532 ECX: "ECX", 533 EDX: "EDX", 534 EBX: "EBX", 535 ESP: "ESP", 536 EBP: "EBP", 537 ESI: "ESI", 538 EDI: "EDI", 539 R8L: "R8L", 540 R9L: "R9L", 541 R10L: "R10L", 542 R11L: "R11L", 543 R12L: "R12L", 544 R13L: "R13L", 545 R14L: "R14L", 546 R15L: "R15L", 547 RAX: "RAX", 548 RCX: "RCX", 549 RDX: "RDX", 550 RBX: "RBX", 551 RSP: "RSP", 552 RBP: "RBP", 553 RSI: "RSI", 554 RDI: "RDI", 555 R8: "R8", 556 R9: "R9", 557 R10: "R10", 558 R11: "R11", 559 R12: "R12", 560 R13: "R13", 561 R14: "R14", 562 R15: "R15", 563 IP: "IP", 564 EIP: "EIP", 565 RIP: "RIP", 566 F0: "F0", 567 F1: "F1", 568 F2: "F2", 569 F3: "F3", 570 F4: "F4", 571 F5: "F5", 572 F6: "F6", 573 F7: "F7", 574 M0: "M0", 575 M1: "M1", 576 M2: "M2", 577 M3: "M3", 578 M4: "M4", 579 M5: "M5", 580 M6: "M6", 581 M7: "M7", 582 X0: "X0", 583 X1: "X1", 584 X2: "X2", 585 X3: "X3", 586 X4: "X4", 587 X5: "X5", 588 X6: "X6", 589 X7: "X7", 590 X8: "X8", 591 X9: "X9", 592 X10: "X10", 593 X11: "X11", 594 X12: "X12", 595 X13: "X13", 596 X14: "X14", 597 X15: "X15", 598 CS: "CS", 599 SS: "SS", 600 DS: "DS", 601 ES: "ES", 602 FS: "FS", 603 GS: "GS", 604 GDTR: "GDTR", 605 IDTR: "IDTR", 606 LDTR: "LDTR", 607 MSW: "MSW", 608 TASK: "TASK", 609 CR0: "CR0", 610 CR1: "CR1", 611 CR2: "CR2", 612 CR3: "CR3", 613 CR4: "CR4", 614 CR5: "CR5", 615 CR6: "CR6", 616 CR7: "CR7", 617 CR8: "CR8", 618 CR9: "CR9", 619 CR10: "CR10", 620 CR11: "CR11", 621 CR12: "CR12", 622 CR13: "CR13", 623 CR14: "CR14", 624 CR15: "CR15", 625 DR0: "DR0", 626 DR1: "DR1", 627 DR2: "DR2", 628 DR3: "DR3", 629 DR4: "DR4", 630 DR5: "DR5", 631 DR6: "DR6", 632 DR7: "DR7", 633 DR8: "DR8", 634 DR9: "DR9", 635 DR10: "DR10", 636 DR11: "DR11", 637 DR12: "DR12", 638 DR13: "DR13", 639 DR14: "DR14", 640 DR15: "DR15", 641 TR0: "TR0", 642 TR1: "TR1", 643 TR2: "TR2", 644 TR3: "TR3", 645 TR4: "TR4", 646 TR5: "TR5", 647 TR6: "TR6", 648 TR7: "TR7", 649 }