mirror of
https://github.com/beego/bee.git
synced 2025-07-04 06:30:18 +00:00
Update vendor folder (Delve support)
This commit is contained in:
643
vendor/rsc.io/x86/x86asm/inst.go
generated
vendored
Normal file
643
vendor/rsc.io/x86/x86asm/inst.go
generated
vendored
Normal file
@ -0,0 +1,643 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package x86asm implements decoding of x86 machine code.
|
||||
package x86asm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// An Inst is a single instruction.
|
||||
type Inst struct {
|
||||
Prefix Prefixes // Prefixes applied to the instruction.
|
||||
Op Op // Opcode mnemonic
|
||||
Opcode uint32 // Encoded opcode bits, left aligned (first byte is Opcode>>24, etc)
|
||||
Args Args // Instruction arguments, in Intel order
|
||||
Mode int // processor mode in bits: 16, 32, or 64
|
||||
AddrSize int // address size in bits: 16, 32, or 64
|
||||
DataSize int // operand size in bits: 16, 32, or 64
|
||||
MemBytes int // size of memory argument in bytes: 1, 2, 4, 8, 16, and so on.
|
||||
Len int // length of encoded instruction in bytes
|
||||
PCRel int // length of PC-relative address in instruction encoding
|
||||
PCRelOff int // index of start of PC-relative address in instruction encoding
|
||||
}
|
||||
|
||||
// Prefixes is an array of prefixes associated with a single instruction.
|
||||
// The prefixes are listed in the same order as found in the instruction:
|
||||
// each prefix byte corresponds to one slot in the array. The first zero
|
||||
// in the array marks the end of the prefixes.
|
||||
type Prefixes [14]Prefix
|
||||
|
||||
// A Prefix represents an Intel instruction prefix.
|
||||
// The low 8 bits are the actual prefix byte encoding,
|
||||
// and the top 8 bits contain distinguishing bits and metadata.
|
||||
type Prefix uint16
|
||||
|
||||
const (
|
||||
// Metadata about the role of a prefix in an instruction.
|
||||
PrefixImplicit Prefix = 0x8000 // prefix is implied by instruction text
|
||||
PrefixIgnored Prefix = 0x4000 // prefix is ignored: either irrelevant or overridden by a later prefix
|
||||
PrefixInvalid Prefix = 0x2000 // prefix makes entire instruction invalid (bad LOCK)
|
||||
|
||||
// Memory segment overrides.
|
||||
PrefixES Prefix = 0x26 // ES segment override
|
||||
PrefixCS Prefix = 0x2E // CS segment override
|
||||
PrefixSS Prefix = 0x36 // SS segment override
|
||||
PrefixDS Prefix = 0x3E // DS segment override
|
||||
PrefixFS Prefix = 0x64 // FS segment override
|
||||
PrefixGS Prefix = 0x65 // GS segment override
|
||||
|
||||
// Branch prediction.
|
||||
PrefixPN Prefix = 0x12E // predict not taken (conditional branch only)
|
||||
PrefixPT Prefix = 0x13E // predict taken (conditional branch only)
|
||||
|
||||
// Size attributes.
|
||||
PrefixDataSize Prefix = 0x66 // operand size override
|
||||
PrefixData16 Prefix = 0x166
|
||||
PrefixData32 Prefix = 0x266
|
||||
PrefixAddrSize Prefix = 0x67 // address size override
|
||||
PrefixAddr16 Prefix = 0x167
|
||||
PrefixAddr32 Prefix = 0x267
|
||||
|
||||
// One of a kind.
|
||||
PrefixLOCK Prefix = 0xF0 // lock
|
||||
PrefixREPN Prefix = 0xF2 // repeat not zero
|
||||
PrefixXACQUIRE Prefix = 0x1F2
|
||||
PrefixBND Prefix = 0x2F2
|
||||
PrefixREP Prefix = 0xF3 // repeat
|
||||
PrefixXRELEASE Prefix = 0x1F3
|
||||
|
||||
// The REX prefixes must be in the range [PrefixREX, PrefixREX+0x10).
|
||||
// the other bits are set or not according to the intended use.
|
||||
PrefixREX Prefix = 0x40 // REX 64-bit extension prefix
|
||||
PrefixREXW Prefix = 0x08 // extension bit W (64-bit instruction width)
|
||||
PrefixREXR Prefix = 0x04 // extension bit R (r field in modrm)
|
||||
PrefixREXX Prefix = 0x02 // extension bit X (index field in sib)
|
||||
PrefixREXB Prefix = 0x01 // extension bit B (r/m field in modrm or base field in sib)
|
||||
)
|
||||
|
||||
// IsREX reports whether p is a REX prefix byte.
|
||||
func (p Prefix) IsREX() bool {
|
||||
return p&0xF0 == PrefixREX
|
||||
}
|
||||
|
||||
func (p Prefix) String() string {
|
||||
p &^= PrefixImplicit | PrefixIgnored | PrefixInvalid
|
||||
if s := prefixNames[p]; s != "" {
|
||||
return s
|
||||
}
|
||||
|
||||
if p.IsREX() {
|
||||
s := "REX."
|
||||
if p&PrefixREXW != 0 {
|
||||
s += "W"
|
||||
}
|
||||
if p&PrefixREXR != 0 {
|
||||
s += "R"
|
||||
}
|
||||
if p&PrefixREXX != 0 {
|
||||
s += "X"
|
||||
}
|
||||
if p&PrefixREXB != 0 {
|
||||
s += "B"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Prefix(%#x)", int(p))
|
||||
}
|
||||
|
||||
// An Op is an x86 opcode.
|
||||
type Op uint32
|
||||
|
||||
func (op Op) String() string {
|
||||
i := int(op)
|
||||
if i < 0 || i >= len(opNames) || opNames[i] == "" {
|
||||
return fmt.Sprintf("Op(%d)", i)
|
||||
}
|
||||
return opNames[i]
|
||||
}
|
||||
|
||||
// An Args holds the instruction arguments.
|
||||
// If an instruction has fewer than 4 arguments,
|
||||
// the final elements in the array are nil.
|
||||
type Args [4]Arg
|
||||
|
||||
// An Arg is a single instruction argument,
|
||||
// one of these types: Reg, Mem, Imm, Rel.
|
||||
type Arg interface {
|
||||
String() string
|
||||
isArg()
|
||||
}
|
||||
|
||||
// Note that the implements of Arg that follow are all sized
|
||||
// so that on a 64-bit machine the data can be inlined in
|
||||
// the interface value instead of requiring an allocation.
|
||||
|
||||
// A Reg is a single register.
|
||||
// The zero Reg value has no name but indicates ``no register.''
|
||||
type Reg uint8
|
||||
|
||||
const (
|
||||
_ Reg = iota
|
||||
|
||||
// 8-bit
|
||||
AL
|
||||
CL
|
||||
DL
|
||||
BL
|
||||
AH
|
||||
CH
|
||||
DH
|
||||
BH
|
||||
SPB
|
||||
BPB
|
||||
SIB
|
||||
DIB
|
||||
R8B
|
||||
R9B
|
||||
R10B
|
||||
R11B
|
||||
R12B
|
||||
R13B
|
||||
R14B
|
||||
R15B
|
||||
|
||||
// 16-bit
|
||||
AX
|
||||
CX
|
||||
DX
|
||||
BX
|
||||
SP
|
||||
BP
|
||||
SI
|
||||
DI
|
||||
R8W
|
||||
R9W
|
||||
R10W
|
||||
R11W
|
||||
R12W
|
||||
R13W
|
||||
R14W
|
||||
R15W
|
||||
|
||||
// 32-bit
|
||||
EAX
|
||||
ECX
|
||||
EDX
|
||||
EBX
|
||||
ESP
|
||||
EBP
|
||||
ESI
|
||||
EDI
|
||||
R8L
|
||||
R9L
|
||||
R10L
|
||||
R11L
|
||||
R12L
|
||||
R13L
|
||||
R14L
|
||||
R15L
|
||||
|
||||
// 64-bit
|
||||
RAX
|
||||
RCX
|
||||
RDX
|
||||
RBX
|
||||
RSP
|
||||
RBP
|
||||
RSI
|
||||
RDI
|
||||
R8
|
||||
R9
|
||||
R10
|
||||
R11
|
||||
R12
|
||||
R13
|
||||
R14
|
||||
R15
|
||||
|
||||
// Instruction pointer.
|
||||
IP // 16-bit
|
||||
EIP // 32-bit
|
||||
RIP // 64-bit
|
||||
|
||||
// 387 floating point registers.
|
||||
F0
|
||||
F1
|
||||
F2
|
||||
F3
|
||||
F4
|
||||
F5
|
||||
F6
|
||||
F7
|
||||
|
||||
// MMX registers.
|
||||
M0
|
||||
M1
|
||||
M2
|
||||
M3
|
||||
M4
|
||||
M5
|
||||
M6
|
||||
M7
|
||||
|
||||
// XMM registers.
|
||||
X0
|
||||
X1
|
||||
X2
|
||||
X3
|
||||
X4
|
||||
X5
|
||||
X6
|
||||
X7
|
||||
X8
|
||||
X9
|
||||
X10
|
||||
X11
|
||||
X12
|
||||
X13
|
||||
X14
|
||||
X15
|
||||
|
||||
// Segment registers.
|
||||
ES
|
||||
CS
|
||||
SS
|
||||
DS
|
||||
FS
|
||||
GS
|
||||
|
||||
// System registers.
|
||||
GDTR
|
||||
IDTR
|
||||
LDTR
|
||||
MSW
|
||||
TASK
|
||||
|
||||
// Control registers.
|
||||
CR0
|
||||
CR1
|
||||
CR2
|
||||
CR3
|
||||
CR4
|
||||
CR5
|
||||
CR6
|
||||
CR7
|
||||
CR8
|
||||
CR9
|
||||
CR10
|
||||
CR11
|
||||
CR12
|
||||
CR13
|
||||
CR14
|
||||
CR15
|
||||
|
||||
// Debug registers.
|
||||
DR0
|
||||
DR1
|
||||
DR2
|
||||
DR3
|
||||
DR4
|
||||
DR5
|
||||
DR6
|
||||
DR7
|
||||
DR8
|
||||
DR9
|
||||
DR10
|
||||
DR11
|
||||
DR12
|
||||
DR13
|
||||
DR14
|
||||
DR15
|
||||
|
||||
// Task registers.
|
||||
TR0
|
||||
TR1
|
||||
TR2
|
||||
TR3
|
||||
TR4
|
||||
TR5
|
||||
TR6
|
||||
TR7
|
||||
)
|
||||
|
||||
const regMax = TR7
|
||||
|
||||
func (Reg) isArg() {}
|
||||
|
||||
func (r Reg) String() string {
|
||||
i := int(r)
|
||||
if i < 0 || i >= len(regNames) || regNames[i] == "" {
|
||||
return fmt.Sprintf("Reg(%d)", i)
|
||||
}
|
||||
return regNames[i]
|
||||
}
|
||||
|
||||
// A Mem is a memory reference.
|
||||
// The general form is Segment:[Base+Scale*Index+Disp].
|
||||
type Mem struct {
|
||||
Segment Reg
|
||||
Base Reg
|
||||
Scale uint8
|
||||
Index Reg
|
||||
Disp int64
|
||||
}
|
||||
|
||||
func (Mem) isArg() {}
|
||||
|
||||
func (m Mem) String() string {
|
||||
var base, plus, scale, index, disp string
|
||||
|
||||
if m.Base != 0 {
|
||||
base = m.Base.String()
|
||||
}
|
||||
if m.Scale != 0 {
|
||||
if m.Base != 0 {
|
||||
plus = "+"
|
||||
}
|
||||
if m.Scale > 1 {
|
||||
scale = fmt.Sprintf("%d*", m.Scale)
|
||||
}
|
||||
index = m.Index.String()
|
||||
}
|
||||
if m.Disp != 0 || m.Base == 0 && m.Scale == 0 {
|
||||
disp = fmt.Sprintf("%+#x", m.Disp)
|
||||
}
|
||||
return "[" + base + plus + scale + index + disp + "]"
|
||||
}
|
||||
|
||||
// A Rel is an offset relative to the current instruction pointer.
|
||||
type Rel int32
|
||||
|
||||
func (Rel) isArg() {}
|
||||
|
||||
func (r Rel) String() string {
|
||||
return fmt.Sprintf(".%+d", r)
|
||||
}
|
||||
|
||||
// An Imm is an integer constant.
|
||||
type Imm int64
|
||||
|
||||
func (Imm) isArg() {}
|
||||
|
||||
func (i Imm) String() string {
|
||||
return fmt.Sprintf("%#x", int64(i))
|
||||
}
|
||||
|
||||
func (i Inst) String() string {
|
||||
var buf bytes.Buffer
|
||||
for _, p := range i.Prefix {
|
||||
if p == 0 {
|
||||
break
|
||||
}
|
||||
if p&PrefixImplicit != 0 {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(&buf, "%v ", p)
|
||||
}
|
||||
fmt.Fprintf(&buf, "%v", i.Op)
|
||||
sep := " "
|
||||
for _, v := range i.Args {
|
||||
if v == nil {
|
||||
break
|
||||
}
|
||||
fmt.Fprintf(&buf, "%s%v", sep, v)
|
||||
sep = ", "
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func isReg(a Arg) bool {
|
||||
_, ok := a.(Reg)
|
||||
return ok
|
||||
}
|
||||
|
||||
func isSegReg(a Arg) bool {
|
||||
r, ok := a.(Reg)
|
||||
return ok && ES <= r && r <= GS
|
||||
}
|
||||
|
||||
func isMem(a Arg) bool {
|
||||
_, ok := a.(Mem)
|
||||
return ok
|
||||
}
|
||||
|
||||
func isImm(a Arg) bool {
|
||||
_, ok := a.(Imm)
|
||||
return ok
|
||||
}
|
||||
|
||||
func regBytes(a Arg) int {
|
||||
r, ok := a.(Reg)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
if AL <= r && r <= R15B {
|
||||
return 1
|
||||
}
|
||||
if AX <= r && r <= R15W {
|
||||
return 2
|
||||
}
|
||||
if EAX <= r && r <= R15L {
|
||||
return 4
|
||||
}
|
||||
if RAX <= r && r <= R15 {
|
||||
return 8
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func isSegment(p Prefix) bool {
|
||||
switch p {
|
||||
case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// The Op definitions and string list are in tables.go.
|
||||
|
||||
var prefixNames = map[Prefix]string{
|
||||
PrefixCS: "CS",
|
||||
PrefixDS: "DS",
|
||||
PrefixES: "ES",
|
||||
PrefixFS: "FS",
|
||||
PrefixGS: "GS",
|
||||
PrefixSS: "SS",
|
||||
PrefixLOCK: "LOCK",
|
||||
PrefixREP: "REP",
|
||||
PrefixREPN: "REPN",
|
||||
PrefixAddrSize: "ADDRSIZE",
|
||||
PrefixDataSize: "DATASIZE",
|
||||
PrefixAddr16: "ADDR16",
|
||||
PrefixData16: "DATA16",
|
||||
PrefixAddr32: "ADDR32",
|
||||
PrefixData32: "DATA32",
|
||||
PrefixBND: "BND",
|
||||
PrefixXACQUIRE: "XACQUIRE",
|
||||
PrefixXRELEASE: "XRELEASE",
|
||||
PrefixREX: "REX",
|
||||
PrefixPT: "PT",
|
||||
PrefixPN: "PN",
|
||||
}
|
||||
|
||||
var regNames = [...]string{
|
||||
AL: "AL",
|
||||
CL: "CL",
|
||||
BL: "BL",
|
||||
DL: "DL",
|
||||
AH: "AH",
|
||||
CH: "CH",
|
||||
BH: "BH",
|
||||
DH: "DH",
|
||||
SPB: "SPB",
|
||||
BPB: "BPB",
|
||||
SIB: "SIB",
|
||||
DIB: "DIB",
|
||||
R8B: "R8B",
|
||||
R9B: "R9B",
|
||||
R10B: "R10B",
|
||||
R11B: "R11B",
|
||||
R12B: "R12B",
|
||||
R13B: "R13B",
|
||||
R14B: "R14B",
|
||||
R15B: "R15B",
|
||||
AX: "AX",
|
||||
CX: "CX",
|
||||
BX: "BX",
|
||||
DX: "DX",
|
||||
SP: "SP",
|
||||
BP: "BP",
|
||||
SI: "SI",
|
||||
DI: "DI",
|
||||
R8W: "R8W",
|
||||
R9W: "R9W",
|
||||
R10W: "R10W",
|
||||
R11W: "R11W",
|
||||
R12W: "R12W",
|
||||
R13W: "R13W",
|
||||
R14W: "R14W",
|
||||
R15W: "R15W",
|
||||
EAX: "EAX",
|
||||
ECX: "ECX",
|
||||
EDX: "EDX",
|
||||
EBX: "EBX",
|
||||
ESP: "ESP",
|
||||
EBP: "EBP",
|
||||
ESI: "ESI",
|
||||
EDI: "EDI",
|
||||
R8L: "R8L",
|
||||
R9L: "R9L",
|
||||
R10L: "R10L",
|
||||
R11L: "R11L",
|
||||
R12L: "R12L",
|
||||
R13L: "R13L",
|
||||
R14L: "R14L",
|
||||
R15L: "R15L",
|
||||
RAX: "RAX",
|
||||
RCX: "RCX",
|
||||
RDX: "RDX",
|
||||
RBX: "RBX",
|
||||
RSP: "RSP",
|
||||
RBP: "RBP",
|
||||
RSI: "RSI",
|
||||
RDI: "RDI",
|
||||
R8: "R8",
|
||||
R9: "R9",
|
||||
R10: "R10",
|
||||
R11: "R11",
|
||||
R12: "R12",
|
||||
R13: "R13",
|
||||
R14: "R14",
|
||||
R15: "R15",
|
||||
IP: "IP",
|
||||
EIP: "EIP",
|
||||
RIP: "RIP",
|
||||
F0: "F0",
|
||||
F1: "F1",
|
||||
F2: "F2",
|
||||
F3: "F3",
|
||||
F4: "F4",
|
||||
F5: "F5",
|
||||
F6: "F6",
|
||||
F7: "F7",
|
||||
M0: "M0",
|
||||
M1: "M1",
|
||||
M2: "M2",
|
||||
M3: "M3",
|
||||
M4: "M4",
|
||||
M5: "M5",
|
||||
M6: "M6",
|
||||
M7: "M7",
|
||||
X0: "X0",
|
||||
X1: "X1",
|
||||
X2: "X2",
|
||||
X3: "X3",
|
||||
X4: "X4",
|
||||
X5: "X5",
|
||||
X6: "X6",
|
||||
X7: "X7",
|
||||
X8: "X8",
|
||||
X9: "X9",
|
||||
X10: "X10",
|
||||
X11: "X11",
|
||||
X12: "X12",
|
||||
X13: "X13",
|
||||
X14: "X14",
|
||||
X15: "X15",
|
||||
CS: "CS",
|
||||
SS: "SS",
|
||||
DS: "DS",
|
||||
ES: "ES",
|
||||
FS: "FS",
|
||||
GS: "GS",
|
||||
GDTR: "GDTR",
|
||||
IDTR: "IDTR",
|
||||
LDTR: "LDTR",
|
||||
MSW: "MSW",
|
||||
TASK: "TASK",
|
||||
CR0: "CR0",
|
||||
CR1: "CR1",
|
||||
CR2: "CR2",
|
||||
CR3: "CR3",
|
||||
CR4: "CR4",
|
||||
CR5: "CR5",
|
||||
CR6: "CR6",
|
||||
CR7: "CR7",
|
||||
CR8: "CR8",
|
||||
CR9: "CR9",
|
||||
CR10: "CR10",
|
||||
CR11: "CR11",
|
||||
CR12: "CR12",
|
||||
CR13: "CR13",
|
||||
CR14: "CR14",
|
||||
CR15: "CR15",
|
||||
DR0: "DR0",
|
||||
DR1: "DR1",
|
||||
DR2: "DR2",
|
||||
DR3: "DR3",
|
||||
DR4: "DR4",
|
||||
DR5: "DR5",
|
||||
DR6: "DR6",
|
||||
DR7: "DR7",
|
||||
DR8: "DR8",
|
||||
DR9: "DR9",
|
||||
DR10: "DR10",
|
||||
DR11: "DR11",
|
||||
DR12: "DR12",
|
||||
DR13: "DR13",
|
||||
DR14: "DR14",
|
||||
DR15: "DR15",
|
||||
TR0: "TR0",
|
||||
TR1: "TR1",
|
||||
TR2: "TR2",
|
||||
TR3: "TR3",
|
||||
TR4: "TR4",
|
||||
TR5: "TR5",
|
||||
TR6: "TR6",
|
||||
TR7: "TR7",
|
||||
}
|
Reference in New Issue
Block a user