mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 09:46:56 +08:00
proc: remove duplicate Registers.Get implementations (#2415)
Moves the implementation of Registers.Get out of the backends and into proc where it can be implemented only once per architecture.
This commit is contained in:
committed by
GitHub
parent
7bf5482b32
commit
35d4f05c4e
@ -16,7 +16,7 @@ const (
|
||||
ARM64_SP = 31
|
||||
ARM64_PC = 32
|
||||
ARM64_V0 = 64 // V1 through V31 follow
|
||||
|
||||
_ARM64_MaxRegNum = ARM64_V0 + 31
|
||||
)
|
||||
|
||||
func ARM64ToName(num uint64) string {
|
||||
@ -33,3 +33,24 @@ func ARM64ToName(num uint64) string {
|
||||
return fmt.Sprintf("unknown%d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func ARM64MaxRegNum() uint64 {
|
||||
return _ARM64_MaxRegNum
|
||||
}
|
||||
|
||||
var ARM64NameToDwarf = func() map[string]int {
|
||||
r := make(map[string]int)
|
||||
for i := 0; i <= 32; i++ {
|
||||
r[fmt.Sprintf("x%d", i)] = ARM64_X0 + i
|
||||
}
|
||||
r["fp"] = 29
|
||||
r["lr"] = 30
|
||||
r["sp"] = 31
|
||||
r["pc"] = 32
|
||||
|
||||
for i := 0; i <= 31; i++ {
|
||||
r[fmt.Sprintf("v%d", i)] = ARM64_V0 + i
|
||||
}
|
||||
|
||||
return r
|
||||
}()
|
||||
|
||||
@ -38,6 +38,7 @@ func AMD64Arch(goos string) *Arch {
|
||||
SPRegNum: regnum.AMD64_Rsp,
|
||||
BPRegNum: regnum.AMD64_Rbp,
|
||||
ContextRegNum: regnum.AMD64_Rdx,
|
||||
asmRegisters: amd64AsmRegisters,
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,11 +256,11 @@ func amd64RegSize(rn uint64) int {
|
||||
return 8
|
||||
}
|
||||
|
||||
func amd64RegistersToDwarfRegisters(staticBase uint64, regs Registers) op.DwarfRegisters {
|
||||
func amd64RegistersToDwarfRegisters(staticBase uint64, regs Registers) *op.DwarfRegisters {
|
||||
dregs := initDwarfRegistersFromSlice(int(regnum.AMD64MaxRegNum()), regs, regnum.AMD64NameToDwarf)
|
||||
dr := op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.AMD64_Rip, regnum.AMD64_Rsp, regnum.AMD64_Rbp, 0)
|
||||
dr.SetLoadMoreCallback(loadMoreDwarfRegistersFromSliceFunc(dr, regs, regnum.AMD64NameToDwarf))
|
||||
return *dr
|
||||
return dr
|
||||
}
|
||||
|
||||
func initDwarfRegistersFromSlice(maxRegs int, regs Registers, nameToDwarf map[string]int) []*op.DwarfRegister {
|
||||
|
||||
@ -5,10 +5,13 @@
|
||||
package proc
|
||||
|
||||
import (
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
"github.com/go-delve/delve/pkg/dwarf/regnum"
|
||||
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
)
|
||||
|
||||
func amd64AsmDecode(asmInst *AsmInstruction, mem []byte, regs Registers, memrw MemoryReadWriter, bi *BinaryInfo) error {
|
||||
func amd64AsmDecode(asmInst *AsmInstruction, mem []byte, regs *op.DwarfRegisters, memrw MemoryReadWriter, bi *BinaryInfo) error {
|
||||
return x86AsmDecode(asmInst, mem, regs, memrw, bi, 64)
|
||||
}
|
||||
|
||||
@ -36,3 +39,81 @@ func init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var amd64AsmRegisters = map[int]asmRegister{
|
||||
// 8-bit
|
||||
int(x86asm.AL): asmRegister{regnum.AMD64_Rax, 0, mask8},
|
||||
int(x86asm.CL): asmRegister{regnum.AMD64_Rcx, 0, mask8},
|
||||
int(x86asm.DL): asmRegister{regnum.AMD64_Rdx, 0, mask8},
|
||||
int(x86asm.BL): asmRegister{regnum.AMD64_Rbx, 0, mask8},
|
||||
int(x86asm.AH): asmRegister{regnum.AMD64_Rax, 8, mask8},
|
||||
int(x86asm.CH): asmRegister{regnum.AMD64_Rcx, 8, mask8},
|
||||
int(x86asm.DH): asmRegister{regnum.AMD64_Rdx, 8, mask8},
|
||||
int(x86asm.BH): asmRegister{regnum.AMD64_Rbx, 8, mask8},
|
||||
int(x86asm.SPB): asmRegister{regnum.AMD64_Rsp, 0, mask8},
|
||||
int(x86asm.BPB): asmRegister{regnum.AMD64_Rbp, 0, mask8},
|
||||
int(x86asm.SIB): asmRegister{regnum.AMD64_Rsi, 0, mask8},
|
||||
int(x86asm.DIB): asmRegister{regnum.AMD64_Rdi, 0, mask8},
|
||||
int(x86asm.R8B): asmRegister{regnum.AMD64_R8, 0, mask8},
|
||||
int(x86asm.R9B): asmRegister{regnum.AMD64_R9, 0, mask8},
|
||||
int(x86asm.R10B): asmRegister{regnum.AMD64_R10, 0, mask8},
|
||||
int(x86asm.R11B): asmRegister{regnum.AMD64_R11, 0, mask8},
|
||||
int(x86asm.R12B): asmRegister{regnum.AMD64_R12, 0, mask8},
|
||||
int(x86asm.R13B): asmRegister{regnum.AMD64_R13, 0, mask8},
|
||||
int(x86asm.R14B): asmRegister{regnum.AMD64_R14, 0, mask8},
|
||||
int(x86asm.R15B): asmRegister{regnum.AMD64_R15, 0, mask8},
|
||||
|
||||
// 16-bit
|
||||
int(x86asm.AX): asmRegister{regnum.AMD64_Rax, 0, mask16},
|
||||
int(x86asm.CX): asmRegister{regnum.AMD64_Rcx, 0, mask16},
|
||||
int(x86asm.DX): asmRegister{regnum.AMD64_Rdx, 0, mask16},
|
||||
int(x86asm.BX): asmRegister{regnum.AMD64_Rbx, 0, mask16},
|
||||
int(x86asm.SP): asmRegister{regnum.AMD64_Rsp, 0, mask16},
|
||||
int(x86asm.BP): asmRegister{regnum.AMD64_Rbp, 0, mask16},
|
||||
int(x86asm.SI): asmRegister{regnum.AMD64_Rsi, 0, mask16},
|
||||
int(x86asm.DI): asmRegister{regnum.AMD64_Rdi, 0, mask16},
|
||||
int(x86asm.R8W): asmRegister{regnum.AMD64_R8, 0, mask16},
|
||||
int(x86asm.R9W): asmRegister{regnum.AMD64_R9, 0, mask16},
|
||||
int(x86asm.R10W): asmRegister{regnum.AMD64_R10, 0, mask16},
|
||||
int(x86asm.R11W): asmRegister{regnum.AMD64_R11, 0, mask16},
|
||||
int(x86asm.R12W): asmRegister{regnum.AMD64_R12, 0, mask16},
|
||||
int(x86asm.R13W): asmRegister{regnum.AMD64_R13, 0, mask16},
|
||||
int(x86asm.R14W): asmRegister{regnum.AMD64_R14, 0, mask16},
|
||||
int(x86asm.R15W): asmRegister{regnum.AMD64_R15, 0, mask16},
|
||||
|
||||
// 32-bit
|
||||
int(x86asm.EAX): asmRegister{regnum.AMD64_Rax, 0, mask32},
|
||||
int(x86asm.ECX): asmRegister{regnum.AMD64_Rcx, 0, mask32},
|
||||
int(x86asm.EDX): asmRegister{regnum.AMD64_Rdx, 0, mask32},
|
||||
int(x86asm.EBX): asmRegister{regnum.AMD64_Rbx, 0, mask32},
|
||||
int(x86asm.ESP): asmRegister{regnum.AMD64_Rsp, 0, mask32},
|
||||
int(x86asm.EBP): asmRegister{regnum.AMD64_Rbp, 0, mask32},
|
||||
int(x86asm.ESI): asmRegister{regnum.AMD64_Rsi, 0, mask32},
|
||||
int(x86asm.EDI): asmRegister{regnum.AMD64_Rdi, 0, mask32},
|
||||
int(x86asm.R8L): asmRegister{regnum.AMD64_R8, 0, mask32},
|
||||
int(x86asm.R9L): asmRegister{regnum.AMD64_R9, 0, mask32},
|
||||
int(x86asm.R10L): asmRegister{regnum.AMD64_R10, 0, mask32},
|
||||
int(x86asm.R11L): asmRegister{regnum.AMD64_R11, 0, mask32},
|
||||
int(x86asm.R12L): asmRegister{regnum.AMD64_R12, 0, mask32},
|
||||
int(x86asm.R13L): asmRegister{regnum.AMD64_R13, 0, mask32},
|
||||
int(x86asm.R14L): asmRegister{regnum.AMD64_R14, 0, mask32},
|
||||
int(x86asm.R15L): asmRegister{regnum.AMD64_R15, 0, mask32},
|
||||
|
||||
// 64-bit
|
||||
int(x86asm.RAX): asmRegister{regnum.AMD64_Rax, 0, 0},
|
||||
int(x86asm.RCX): asmRegister{regnum.AMD64_Rcx, 0, 0},
|
||||
int(x86asm.RDX): asmRegister{regnum.AMD64_Rdx, 0, 0},
|
||||
int(x86asm.RBX): asmRegister{regnum.AMD64_Rbx, 0, 0},
|
||||
int(x86asm.RSP): asmRegister{regnum.AMD64_Rsp, 0, 0},
|
||||
int(x86asm.RBP): asmRegister{regnum.AMD64_Rbp, 0, 0},
|
||||
int(x86asm.RSI): asmRegister{regnum.AMD64_Rsi, 0, 0},
|
||||
int(x86asm.RDI): asmRegister{regnum.AMD64_Rdi, 0, 0},
|
||||
int(x86asm.R8): asmRegister{regnum.AMD64_R8, 0, 0},
|
||||
int(x86asm.R9): asmRegister{regnum.AMD64_R9, 0, 0},
|
||||
int(x86asm.R10): asmRegister{regnum.AMD64_R10, 0, 0},
|
||||
int(x86asm.R11): asmRegister{regnum.AMD64_R11, 0, 0},
|
||||
int(x86asm.R12): asmRegister{regnum.AMD64_R12, 0, 0},
|
||||
int(x86asm.R13): asmRegister{regnum.AMD64_R13, 0, 0},
|
||||
int(x86asm.R14): asmRegister{regnum.AMD64_R14, 0, 0},
|
||||
int(x86asm.R15): asmRegister{regnum.AMD64_R15, 0, 0},
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package proc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-delve/delve/pkg/dwarf/frame"
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
)
|
||||
@ -24,7 +26,7 @@ type Arch struct {
|
||||
|
||||
// asmDecode decodes the assembly instruction starting at mem[0:] into asmInst.
|
||||
// It assumes that the Loc and AtPC fields of asmInst have already been filled.
|
||||
asmDecode func(asmInst *AsmInstruction, mem []byte, regs Registers, memrw MemoryReadWriter, bi *BinaryInfo) error
|
||||
asmDecode func(asmInst *AsmInstruction, mem []byte, regs *op.DwarfRegisters, memrw MemoryReadWriter, bi *BinaryInfo) error
|
||||
// fixFrameUnwindContext applies architecture specific rules for unwinding a stack frame
|
||||
// on the given arch.
|
||||
fixFrameUnwindContext func(*frame.FrameContext, uint64, *BinaryInfo) *frame.FrameContext
|
||||
@ -34,7 +36,7 @@ type Arch struct {
|
||||
// regSize returns the size (in bytes) of register regnum.
|
||||
regSize func(uint64) int
|
||||
// RegistersToDwarfRegisters maps hardware registers to DWARF registers.
|
||||
RegistersToDwarfRegisters func(uint64, Registers) op.DwarfRegisters
|
||||
RegistersToDwarfRegisters func(uint64, Registers) *op.DwarfRegisters
|
||||
// addrAndStackRegsToDwarfRegisters returns DWARF registers from the passed in
|
||||
// PC, SP, and BP registers in the format used by the DWARF expression interpreter.
|
||||
addrAndStackRegsToDwarfRegisters func(uint64, uint64, uint64, uint64, uint64) op.DwarfRegisters
|
||||
@ -45,6 +47,9 @@ type Arch struct {
|
||||
// inhibitStepInto returns whether StepBreakpoint can be set at pc.
|
||||
inhibitStepInto func(bi *BinaryInfo, pc uint64) bool
|
||||
|
||||
// asmRegisters maps assembly register numbers to dwarf registers.
|
||||
asmRegisters map[int]asmRegister
|
||||
|
||||
// crosscall2fn is the DIE of crosscall2, a function used by the go runtime
|
||||
// to call C functions. This function in go 1.9 (and previous versions) had
|
||||
// a bad frame descriptor which needs to be fixed to generate good stack
|
||||
@ -57,6 +62,18 @@ type Arch struct {
|
||||
sigreturnfn *Function
|
||||
}
|
||||
|
||||
type asmRegister struct {
|
||||
dwarfNum uint64
|
||||
offset uint
|
||||
mask uint64
|
||||
}
|
||||
|
||||
const (
|
||||
mask8 = 0x000000ff
|
||||
mask16 = 0x0000ffff
|
||||
mask32 = 0xffffffff
|
||||
)
|
||||
|
||||
// PtrSize returns the size of a pointer for the architecture.
|
||||
func (a *Arch) PtrSize() int {
|
||||
return a.ptrSize
|
||||
@ -95,6 +112,25 @@ func (a *Arch) DerefTLS() bool {
|
||||
return a.derefTLS
|
||||
}
|
||||
|
||||
// getAsmRegister returns the value of the asm register asmreg using the asmRegisters table of arch.
|
||||
// The interpretation of asmreg is architecture specific and defined by the disassembler.
|
||||
// A mask value of 0 inside asmRegisters is equivalent to ^uint64(0).
|
||||
func (arch *Arch) getAsmRegister(regs *op.DwarfRegisters, asmreg int) (uint64, error) {
|
||||
hwreg, ok := arch.asmRegisters[asmreg]
|
||||
if !ok {
|
||||
return 0, ErrUnknownRegister
|
||||
}
|
||||
reg := regs.Reg(hwreg.dwarfNum)
|
||||
if reg == nil {
|
||||
return 0, fmt.Errorf("register %#x not found", asmreg)
|
||||
}
|
||||
n := (reg.Uint64Val >> hwreg.offset)
|
||||
if hwreg.mask != 0 {
|
||||
n = n & hwreg.mask
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// crosscall2 is defined in $GOROOT/src/runtime/cgo/asm_amd64.s.
|
||||
const (
|
||||
crosscall2SPOffsetBad = 0x8
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
"github.com/go-delve/delve/pkg/dwarf/frame"
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
"github.com/go-delve/delve/pkg/dwarf/regnum"
|
||||
"golang.org/x/arch/arm64/arm64asm"
|
||||
)
|
||||
|
||||
var arm64BreakInstruction = []byte{0x0, 0x0, 0x20, 0xd4}
|
||||
@ -36,6 +35,7 @@ func ARM64Arch(goos string) *Arch {
|
||||
usesLR: true,
|
||||
PCRegNum: regnum.ARM64_PC,
|
||||
SPRegNum: regnum.ARM64_SP,
|
||||
asmRegisters: arm64AsmRegisters,
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,78 +235,6 @@ func arm64RegSize(regnum uint64) int {
|
||||
return 8 // general registers
|
||||
}
|
||||
|
||||
// The mapping between hardware registers and DWARF registers is specified
|
||||
// in the DWARF for the ARM® Architecture page 7,
|
||||
// Table 1
|
||||
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040b/IHI0040B_aadwarf.pdf
|
||||
var arm64DwarfToHardware = map[int]arm64asm.Reg{
|
||||
0: arm64asm.X0,
|
||||
1: arm64asm.X1,
|
||||
2: arm64asm.X2,
|
||||
3: arm64asm.X3,
|
||||
4: arm64asm.X4,
|
||||
5: arm64asm.X5,
|
||||
6: arm64asm.X6,
|
||||
7: arm64asm.X7,
|
||||
8: arm64asm.X8,
|
||||
9: arm64asm.X9,
|
||||
10: arm64asm.X10,
|
||||
11: arm64asm.X11,
|
||||
12: arm64asm.X12,
|
||||
13: arm64asm.X13,
|
||||
14: arm64asm.X14,
|
||||
15: arm64asm.X15,
|
||||
16: arm64asm.X16,
|
||||
17: arm64asm.X17,
|
||||
18: arm64asm.X18,
|
||||
19: arm64asm.X19,
|
||||
20: arm64asm.X20,
|
||||
21: arm64asm.X21,
|
||||
22: arm64asm.X22,
|
||||
23: arm64asm.X23,
|
||||
24: arm64asm.X24,
|
||||
25: arm64asm.X25,
|
||||
26: arm64asm.X26,
|
||||
27: arm64asm.X27,
|
||||
28: arm64asm.X28,
|
||||
29: arm64asm.X29,
|
||||
30: arm64asm.X30,
|
||||
31: arm64asm.SP,
|
||||
|
||||
64: arm64asm.V0,
|
||||
65: arm64asm.V1,
|
||||
66: arm64asm.V2,
|
||||
67: arm64asm.V3,
|
||||
68: arm64asm.V4,
|
||||
69: arm64asm.V5,
|
||||
70: arm64asm.V6,
|
||||
71: arm64asm.V7,
|
||||
72: arm64asm.V8,
|
||||
73: arm64asm.V9,
|
||||
74: arm64asm.V10,
|
||||
75: arm64asm.V11,
|
||||
76: arm64asm.V12,
|
||||
77: arm64asm.V13,
|
||||
78: arm64asm.V14,
|
||||
79: arm64asm.V15,
|
||||
80: arm64asm.V16,
|
||||
81: arm64asm.V17,
|
||||
82: arm64asm.V18,
|
||||
83: arm64asm.V19,
|
||||
84: arm64asm.V20,
|
||||
85: arm64asm.V21,
|
||||
86: arm64asm.V22,
|
||||
87: arm64asm.V23,
|
||||
88: arm64asm.V24,
|
||||
89: arm64asm.V25,
|
||||
90: arm64asm.V26,
|
||||
91: arm64asm.V27,
|
||||
92: arm64asm.V28,
|
||||
93: arm64asm.V29,
|
||||
94: arm64asm.V30,
|
||||
95: arm64asm.V31,
|
||||
}
|
||||
|
||||
var arm64NameToDwarf = func() map[string]int {
|
||||
r := make(map[string]int)
|
||||
for i := 0; i <= 30; i++ {
|
||||
@ -321,36 +249,11 @@ var arm64NameToDwarf = func() map[string]int {
|
||||
return r
|
||||
}()
|
||||
|
||||
func maxArm64DwarfRegister() int {
|
||||
max := int(regnum.ARM64_PC)
|
||||
for i := range arm64DwarfToHardware {
|
||||
if i > max {
|
||||
max = i
|
||||
}
|
||||
}
|
||||
return max
|
||||
}
|
||||
|
||||
func arm64RegistersToDwarfRegisters(staticBase uint64, regs Registers) op.DwarfRegisters {
|
||||
dregs := make([]*op.DwarfRegister, maxArm64DwarfRegister()+1)
|
||||
|
||||
dregs[regnum.ARM64_PC] = op.DwarfRegisterFromUint64(regs.PC())
|
||||
dregs[regnum.ARM64_SP] = op.DwarfRegisterFromUint64(regs.SP())
|
||||
dregs[regnum.ARM64_BP] = op.DwarfRegisterFromUint64(regs.BP())
|
||||
if lr, err := regs.Get(int(arm64asm.X30)); err != nil {
|
||||
dregs[regnum.ARM64_LR] = op.DwarfRegisterFromUint64(lr)
|
||||
}
|
||||
|
||||
for dwarfReg, asmReg := range arm64DwarfToHardware {
|
||||
v, err := regs.Get(int(asmReg))
|
||||
if err == nil {
|
||||
dregs[dwarfReg] = op.DwarfRegisterFromUint64(v)
|
||||
}
|
||||
}
|
||||
|
||||
func arm64RegistersToDwarfRegisters(staticBase uint64, regs Registers) *op.DwarfRegisters {
|
||||
dregs := initDwarfRegistersFromSlice(int(regnum.ARM64MaxRegNum()), regs, regnum.ARM64NameToDwarf)
|
||||
dr := op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.ARM64_PC, regnum.ARM64_SP, regnum.ARM64_BP, regnum.ARM64_LR)
|
||||
dr.SetLoadMoreCallback(loadMoreDwarfRegistersFromSliceFunc(dr, regs, arm64NameToDwarf))
|
||||
return *dr
|
||||
return dr
|
||||
}
|
||||
|
||||
func arm64AddrAndStackRegsToDwarfRegisters(staticBase, pc, sp, bp, lr uint64) op.DwarfRegisters {
|
||||
|
||||
@ -5,10 +5,13 @@
|
||||
package proc
|
||||
|
||||
import (
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
"github.com/go-delve/delve/pkg/dwarf/regnum"
|
||||
|
||||
"golang.org/x/arch/arm64/arm64asm"
|
||||
)
|
||||
|
||||
func arm64AsmDecode(asmInst *AsmInstruction, mem []byte, regs Registers, memrw MemoryReadWriter, bi *BinaryInfo) error {
|
||||
func arm64AsmDecode(asmInst *AsmInstruction, mem []byte, regs *op.DwarfRegisters, memrw MemoryReadWriter, bi *BinaryInfo) error {
|
||||
asmInst.Size = 4
|
||||
asmInst.Bytes = mem[:asmInst.Size]
|
||||
|
||||
@ -37,7 +40,7 @@ func arm64AsmDecode(asmInst *AsmInstruction, mem []byte, regs Registers, memrw M
|
||||
return nil
|
||||
}
|
||||
|
||||
func resolveCallArgARM64(inst *arm64asm.Inst, instAddr uint64, currentGoroutine bool, regs Registers, mem MemoryReadWriter, bininfo *BinaryInfo) *Location {
|
||||
func resolveCallArgARM64(inst *arm64asm.Inst, instAddr uint64, currentGoroutine bool, regs *op.DwarfRegisters, mem MemoryReadWriter, bininfo *BinaryInfo) *Location {
|
||||
switch inst.Op {
|
||||
case arm64asm.BL, arm64asm.BLR, arm64asm.B, arm64asm.BR:
|
||||
//ok
|
||||
@ -55,7 +58,7 @@ func resolveCallArgARM64(inst *arm64asm.Inst, instAddr uint64, currentGoroutine
|
||||
if !currentGoroutine || regs == nil {
|
||||
return nil
|
||||
}
|
||||
pc, err = regs.Get(int(arg))
|
||||
pc, err = bininfo.Arch.getAsmRegister(regs, int(arg))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -118,3 +121,11 @@ func (inst *arm64ArchInst) OpcodeEquals(op uint64) bool {
|
||||
}
|
||||
return uint64(inst.Op) == op
|
||||
}
|
||||
|
||||
var arm64AsmRegisters = func() map[int]asmRegister {
|
||||
r := make(map[int]asmRegister)
|
||||
for i := arm64asm.X0; i <= arm64asm.X30; i++ {
|
||||
r[int(i)] = asmRegister{regnum.ARM64_X0 + uint64(i-arm64asm.X0), 0, 0}
|
||||
}
|
||||
return r
|
||||
}()
|
||||
|
||||
@ -3,7 +3,6 @@ package core
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -156,10 +155,6 @@ func (regs *delveRegisters) Copy() (proc.Registers, error) {
|
||||
return regs, nil
|
||||
}
|
||||
|
||||
func (regs *delveRegisters) Get(int) (uint64, error) {
|
||||
return 0, errors.New("not supported")
|
||||
}
|
||||
|
||||
func (regs *delveRegisters) Slice(bool) ([]proc.Register, error) {
|
||||
return regs.slice, nil
|
||||
}
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
package proc
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
)
|
||||
|
||||
// AsmInstruction represents one assembly instruction.
|
||||
type AsmInstruction struct {
|
||||
@ -124,6 +128,11 @@ func Disassemble(mem MemoryReadWriter, regs Registers, breakpoints *BreakpointMa
|
||||
}
|
||||
|
||||
func disassemble(memrw MemoryReadWriter, regs Registers, breakpoints *BreakpointMap, bi *BinaryInfo, startAddr, endAddr uint64, singleInstr bool) ([]AsmInstruction, error) {
|
||||
var dregs *op.DwarfRegisters
|
||||
if regs != nil {
|
||||
dregs = bi.Arch.RegistersToDwarfRegisters(0, regs)
|
||||
}
|
||||
|
||||
mem := make([]byte, int(endAddr-startAddr))
|
||||
_, err := memrw.ReadMemory(mem, startAddr)
|
||||
if err != nil {
|
||||
@ -153,7 +162,7 @@ func disassemble(memrw MemoryReadWriter, regs Registers, breakpoints *Breakpoint
|
||||
inst.Breakpoint = atbp
|
||||
inst.AtPC = (regs != nil) && (curpc == pc)
|
||||
|
||||
bi.Arch.asmDecode(&inst, mem, regs, memrw, bi)
|
||||
bi.Arch.asmDecode(&inst, mem, dregs, memrw, bi)
|
||||
|
||||
r = append(r, inst)
|
||||
|
||||
|
||||
@ -17,5 +17,5 @@ func NewCompositeMemory(p *Target, pieces []op.Piece) (*compositeMemory, error)
|
||||
dwarfregs := arch.RegistersToDwarfRegisters(0, regs)
|
||||
dwarfregs.ChangeFunc = p.CurrentThread().SetReg
|
||||
|
||||
return newCompositeMemory(p.Memory(), arch, dwarfregs, pieces)
|
||||
return newCompositeMemory(p.Memory(), arch, *dwarfregs, pieces)
|
||||
}
|
||||
|
||||
@ -102,8 +102,8 @@ func uintExprCheck(t *testing.T, scope *proc.EvalScope, expr string, tgt uint64)
|
||||
}
|
||||
}
|
||||
|
||||
func fakeScope(mem proc.MemoryReadWriter, regs op.DwarfRegisters, bi *proc.BinaryInfo, fn *proc.Function) *proc.EvalScope {
|
||||
return &proc.EvalScope{Location: proc.Location{PC: 0x40100, Fn: fn}, Regs: regs, Mem: mem, BinInfo: bi}
|
||||
func fakeScope(mem proc.MemoryReadWriter, regs *op.DwarfRegisters, bi *proc.BinaryInfo, fn *proc.Function) *proc.EvalScope {
|
||||
return &proc.EvalScope{Location: proc.Location{PC: 0x40100, Fn: fn}, Regs: *regs, Mem: mem, BinInfo: bi}
|
||||
}
|
||||
|
||||
func dwarfExprCheck(t *testing.T, scope *proc.EvalScope, testCases map[string]uint16) {
|
||||
@ -112,7 +112,7 @@ func dwarfExprCheck(t *testing.T, scope *proc.EvalScope, testCases map[string]ui
|
||||
}
|
||||
}
|
||||
|
||||
func dwarfRegisters(bi *proc.BinaryInfo, regs *linutil.AMD64Registers) op.DwarfRegisters {
|
||||
func dwarfRegisters(bi *proc.BinaryInfo, regs *linutil.AMD64Registers) *op.DwarfRegisters {
|
||||
a := proc.AMD64Arch("linux")
|
||||
so := bi.PCToImage(regs.PC())
|
||||
dwarfRegs := a.RegistersToDwarfRegisters(so.StaticBase, regs)
|
||||
@ -271,7 +271,7 @@ func TestDwarfExprLoclist(t *testing.T) {
|
||||
const PC = 0x40100
|
||||
regs := linutil.AMD64Registers{Regs: &linutil.AMD64PtraceRegs{Rip: PC}}
|
||||
|
||||
scope := &proc.EvalScope{Location: proc.Location{PC: PC, Fn: mainfn}, Regs: dwarfRegisters(bi, ®s), Mem: mem, BinInfo: bi}
|
||||
scope := &proc.EvalScope{Location: proc.Location{PC: PC, Fn: mainfn}, Regs: *dwarfRegisters(bi, ®s), Mem: mem, BinInfo: bi}
|
||||
|
||||
uintExprCheck(t, scope, "a", before)
|
||||
scope.PC = 0x40800
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package fbsdutil
|
||||
|
||||
import (
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
|
||||
"github.com/go-delve/delve/pkg/proc"
|
||||
"github.com/go-delve/delve/pkg/proc/amd64util"
|
||||
)
|
||||
@ -154,164 +152,6 @@ func (r *AMD64Registers) GAddr() (uint64, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Get returns the value of the n-th register (in x86asm order).
|
||||
func (r *AMD64Registers) Get(n int) (uint64, error) {
|
||||
reg := x86asm.Reg(n)
|
||||
const (
|
||||
mask8 = 0x000000ff
|
||||
mask16 = 0x0000ffff
|
||||
mask32 = 0xffffffff
|
||||
)
|
||||
|
||||
switch reg {
|
||||
// 8-bit
|
||||
case x86asm.AL:
|
||||
return uint64(r.Regs.Rax) & mask8, nil
|
||||
case x86asm.CL:
|
||||
return uint64(r.Regs.Rcx) & mask8, nil
|
||||
case x86asm.DL:
|
||||
return uint64(r.Regs.Rdx) & mask8, nil
|
||||
case x86asm.BL:
|
||||
return uint64(r.Regs.Rbx) & mask8, nil
|
||||
case x86asm.AH:
|
||||
return (uint64(r.Regs.Rax) >> 8) & mask8, nil
|
||||
case x86asm.CH:
|
||||
return (uint64(r.Regs.Rcx) >> 8) & mask8, nil
|
||||
case x86asm.DH:
|
||||
return (uint64(r.Regs.Rdx) >> 8) & mask8, nil
|
||||
case x86asm.BH:
|
||||
return (uint64(r.Regs.Rbx) >> 8) & mask8, nil
|
||||
case x86asm.SPB:
|
||||
return uint64(r.Regs.Rsp) & mask8, nil
|
||||
case x86asm.BPB:
|
||||
return uint64(r.Regs.Rbp) & mask8, nil
|
||||
case x86asm.SIB:
|
||||
return uint64(r.Regs.Rsi) & mask8, nil
|
||||
case x86asm.DIB:
|
||||
return uint64(r.Regs.Rdi) & mask8, nil
|
||||
case x86asm.R8B:
|
||||
return uint64(r.Regs.R8) & mask8, nil
|
||||
case x86asm.R9B:
|
||||
return uint64(r.Regs.R9) & mask8, nil
|
||||
case x86asm.R10B:
|
||||
return uint64(r.Regs.R10) & mask8, nil
|
||||
case x86asm.R11B:
|
||||
return uint64(r.Regs.R11) & mask8, nil
|
||||
case x86asm.R12B:
|
||||
return uint64(r.Regs.R12) & mask8, nil
|
||||
case x86asm.R13B:
|
||||
return uint64(r.Regs.R13) & mask8, nil
|
||||
case x86asm.R14B:
|
||||
return uint64(r.Regs.R14) & mask8, nil
|
||||
case x86asm.R15B:
|
||||
return uint64(r.Regs.R15) & mask8, nil
|
||||
|
||||
// 16-bit
|
||||
case x86asm.AX:
|
||||
return uint64(r.Regs.Rax) & mask16, nil
|
||||
case x86asm.CX:
|
||||
return uint64(r.Regs.Rcx) & mask16, nil
|
||||
case x86asm.DX:
|
||||
return uint64(r.Regs.Rdx) & mask16, nil
|
||||
case x86asm.BX:
|
||||
return uint64(r.Regs.Rbx) & mask16, nil
|
||||
case x86asm.SP:
|
||||
return uint64(r.Regs.Rsp) & mask16, nil
|
||||
case x86asm.BP:
|
||||
return uint64(r.Regs.Rbp) & mask16, nil
|
||||
case x86asm.SI:
|
||||
return uint64(r.Regs.Rsi) & mask16, nil
|
||||
case x86asm.DI:
|
||||
return uint64(r.Regs.Rdi) & mask16, nil
|
||||
case x86asm.R8W:
|
||||
return uint64(r.Regs.R8) & mask16, nil
|
||||
case x86asm.R9W:
|
||||
return uint64(r.Regs.R9) & mask16, nil
|
||||
case x86asm.R10W:
|
||||
return uint64(r.Regs.R10) & mask16, nil
|
||||
case x86asm.R11W:
|
||||
return uint64(r.Regs.R11) & mask16, nil
|
||||
case x86asm.R12W:
|
||||
return uint64(r.Regs.R12) & mask16, nil
|
||||
case x86asm.R13W:
|
||||
return uint64(r.Regs.R13) & mask16, nil
|
||||
case x86asm.R14W:
|
||||
return uint64(r.Regs.R14) & mask16, nil
|
||||
case x86asm.R15W:
|
||||
return uint64(r.Regs.R15) & mask16, nil
|
||||
|
||||
// 32-bit
|
||||
case x86asm.EAX:
|
||||
return uint64(r.Regs.Rax) & mask32, nil
|
||||
case x86asm.ECX:
|
||||
return uint64(r.Regs.Rcx) & mask32, nil
|
||||
case x86asm.EDX:
|
||||
return uint64(r.Regs.Rdx) & mask32, nil
|
||||
case x86asm.EBX:
|
||||
return uint64(r.Regs.Rbx) & mask32, nil
|
||||
case x86asm.ESP:
|
||||
return uint64(r.Regs.Rsp) & mask32, nil
|
||||
case x86asm.EBP:
|
||||
return uint64(r.Regs.Rbp) & mask32, nil
|
||||
case x86asm.ESI:
|
||||
return uint64(r.Regs.Rsi) & mask32, nil
|
||||
case x86asm.EDI:
|
||||
return uint64(r.Regs.Rdi) & mask32, nil
|
||||
case x86asm.R8L:
|
||||
return uint64(r.Regs.R8) & mask32, nil
|
||||
case x86asm.R9L:
|
||||
return uint64(r.Regs.R9) & mask32, nil
|
||||
case x86asm.R10L:
|
||||
return uint64(r.Regs.R10) & mask32, nil
|
||||
case x86asm.R11L:
|
||||
return uint64(r.Regs.R11) & mask32, nil
|
||||
case x86asm.R12L:
|
||||
return uint64(r.Regs.R12) & mask32, nil
|
||||
case x86asm.R13L:
|
||||
return uint64(r.Regs.R13) & mask32, nil
|
||||
case x86asm.R14L:
|
||||
return uint64(r.Regs.R14) & mask32, nil
|
||||
case x86asm.R15L:
|
||||
return uint64(r.Regs.R15) & mask32, nil
|
||||
|
||||
// 64-bit
|
||||
case x86asm.RAX:
|
||||
return uint64(r.Regs.Rax), nil
|
||||
case x86asm.RCX:
|
||||
return uint64(r.Regs.Rcx), nil
|
||||
case x86asm.RDX:
|
||||
return uint64(r.Regs.Rdx), nil
|
||||
case x86asm.RBX:
|
||||
return uint64(r.Regs.Rbx), nil
|
||||
case x86asm.RSP:
|
||||
return uint64(r.Regs.Rsp), nil
|
||||
case x86asm.RBP:
|
||||
return uint64(r.Regs.Rbp), nil
|
||||
case x86asm.RSI:
|
||||
return uint64(r.Regs.Rsi), nil
|
||||
case x86asm.RDI:
|
||||
return uint64(r.Regs.Rdi), nil
|
||||
case x86asm.R8:
|
||||
return uint64(r.Regs.R8), nil
|
||||
case x86asm.R9:
|
||||
return uint64(r.Regs.R9), nil
|
||||
case x86asm.R10:
|
||||
return uint64(r.Regs.R10), nil
|
||||
case x86asm.R11:
|
||||
return uint64(r.Regs.R11), nil
|
||||
case x86asm.R12:
|
||||
return uint64(r.Regs.R12), nil
|
||||
case x86asm.R13:
|
||||
return uint64(r.Regs.R13), nil
|
||||
case x86asm.R14:
|
||||
return uint64(r.Regs.R14), nil
|
||||
case x86asm.R15:
|
||||
return uint64(r.Regs.R15), nil
|
||||
}
|
||||
|
||||
return 0, proc.ErrUnknownRegister
|
||||
}
|
||||
|
||||
// Copy returns a copy of these registers that is guaranteed not to change.
|
||||
func (r *AMD64Registers) Copy() (proc.Registers, error) {
|
||||
if r.loadFpRegs != nil {
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
package fbsdutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
)
|
||||
|
||||
func TestAMD64Get(t *testing.T) {
|
||||
val := int64(0x7fffffffdeadbeef)
|
||||
regs := AMD64Registers{
|
||||
Regs: &AMD64PtraceRegs{
|
||||
Rax: val,
|
||||
},
|
||||
}
|
||||
// Test AL, low 8 bits of RAX
|
||||
al, err := regs.Get(int(x86asm.AL))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if al != 0xef {
|
||||
t.Fatalf("expected %#v, got %#v\n", 0xef, al)
|
||||
}
|
||||
|
||||
// Test AH, high 8 bits of RAX
|
||||
ah, err := regs.Get(int(x86asm.AH))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ah != 0xBE {
|
||||
t.Fatalf("expected %#v, got %#v\n", 0xbe, ah)
|
||||
}
|
||||
|
||||
// Test AX, lower 16 bits of RAX
|
||||
ax, err := regs.Get(int(x86asm.AX))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ax != 0xBEEF {
|
||||
t.Fatalf("expected %#v, got %#v\n", 0xbeef, ax)
|
||||
}
|
||||
|
||||
// Test EAX, lower 32 bits of RAX
|
||||
eax, err := regs.Get(int(x86asm.EAX))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if eax != 0xDEADBEEF {
|
||||
t.Fatalf("expected %#v, got %#v\n", uint64(0xdeadbeef), eax)
|
||||
}
|
||||
|
||||
// Test RAX, full 64 bits of register
|
||||
rax, err := regs.Get(int(x86asm.RAX))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if rax != uint64(val) {
|
||||
t.Fatalf("expected %#v, got %#v\n", val, rax)
|
||||
}
|
||||
}
|
||||
@ -16,9 +16,9 @@ import (
|
||||
"github.com/go-delve/delve/pkg/dwarf/godwarf"
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
"github.com/go-delve/delve/pkg/dwarf/reader"
|
||||
"github.com/go-delve/delve/pkg/dwarf/regnum"
|
||||
"github.com/go-delve/delve/pkg/goversion"
|
||||
"github.com/go-delve/delve/pkg/logflags"
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
)
|
||||
|
||||
// This file implements the function call injection introduced in go1.11.
|
||||
@ -289,8 +289,7 @@ func evalFunctionCall(scope *EvalScope, node *ast.CallExpr) (*Variable, error) {
|
||||
if regs.SP()-256 <= stacklo {
|
||||
return nil, errNotEnoughStack
|
||||
}
|
||||
_, err = regs.Get(int(x86asm.RAX))
|
||||
if err != nil {
|
||||
if bi.Arch.RegistersToDwarfRegisters(0, regs).Reg(regnum.AMD64_Rax) == nil { //TODO(aarzilli): make this generic when call injection is supported on other architectures
|
||||
return nil, errFuncCallUnsupportedBackend
|
||||
}
|
||||
|
||||
@ -705,7 +704,7 @@ func funcCallStep(callScope *EvalScope, fncall *functionCallState, thread Thread
|
||||
return true
|
||||
}
|
||||
|
||||
rax, _ := regs.Get(int(x86asm.RAX))
|
||||
rax := bi.Arch.RegistersToDwarfRegisters(0, regs).Uint64Val(regnum.AMD64_Rax) //TODO(aarzilli): make this generic when call injection is supported on other architectures
|
||||
|
||||
if logflags.FnCall() {
|
||||
loc, _ := thread.Location()
|
||||
|
||||
@ -77,9 +77,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/arch/arm64/arm64asm"
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
"github.com/go-delve/delve/pkg/elfwriter"
|
||||
"github.com/go-delve/delve/pkg/logflags"
|
||||
@ -1835,375 +1832,6 @@ func (regs *gdbRegisters) byName(name string) uint64 {
|
||||
return binary.LittleEndian.Uint64(reg.value)
|
||||
}
|
||||
|
||||
func (regs *gdbRegisters) Get(n int) (uint64, error) {
|
||||
const (
|
||||
mask8 = 0xff
|
||||
mask16 = 0xffff
|
||||
mask32 = 0xffffffff
|
||||
)
|
||||
|
||||
if regs.arch.Name == "arm64" {
|
||||
reg := arm64asm.Reg(n)
|
||||
|
||||
switch reg {
|
||||
// 64-bit
|
||||
case arm64asm.X0:
|
||||
return regs.byName("x0"), nil
|
||||
case arm64asm.X1:
|
||||
return regs.byName("x1"), nil
|
||||
case arm64asm.X2:
|
||||
return regs.byName("x2"), nil
|
||||
case arm64asm.X3:
|
||||
return regs.byName("x3"), nil
|
||||
case arm64asm.X4:
|
||||
return regs.byName("x4"), nil
|
||||
case arm64asm.X5:
|
||||
return regs.byName("x5"), nil
|
||||
case arm64asm.X6:
|
||||
return regs.byName("x6"), nil
|
||||
case arm64asm.X7:
|
||||
return regs.byName("x7"), nil
|
||||
case arm64asm.X8:
|
||||
return regs.byName("x8"), nil
|
||||
case arm64asm.X9:
|
||||
return regs.byName("x9"), nil
|
||||
case arm64asm.X10:
|
||||
return regs.byName("x10"), nil
|
||||
case arm64asm.X11:
|
||||
return regs.byName("x11"), nil
|
||||
case arm64asm.X12:
|
||||
return regs.byName("x12"), nil
|
||||
case arm64asm.X13:
|
||||
return regs.byName("x13"), nil
|
||||
case arm64asm.X14:
|
||||
return regs.byName("x14"), nil
|
||||
case arm64asm.X15:
|
||||
return regs.byName("x15"), nil
|
||||
case arm64asm.X16:
|
||||
return regs.byName("x16"), nil
|
||||
case arm64asm.X17:
|
||||
return regs.byName("x17"), nil
|
||||
case arm64asm.X18:
|
||||
return regs.byName("x18"), nil
|
||||
case arm64asm.X19:
|
||||
return regs.byName("x19"), nil
|
||||
case arm64asm.X20:
|
||||
return regs.byName("x20"), nil
|
||||
case arm64asm.X21:
|
||||
return regs.byName("x21"), nil
|
||||
case arm64asm.X22:
|
||||
return regs.byName("x22"), nil
|
||||
case arm64asm.X23:
|
||||
return regs.byName("x23"), nil
|
||||
case arm64asm.X24:
|
||||
return regs.byName("x24"), nil
|
||||
case arm64asm.X25:
|
||||
return regs.byName("x25"), nil
|
||||
case arm64asm.X26:
|
||||
return regs.byName("x26"), nil
|
||||
case arm64asm.X27:
|
||||
return regs.byName("x27"), nil
|
||||
case arm64asm.X28:
|
||||
return regs.byName("x28"), nil
|
||||
case arm64asm.X29:
|
||||
return regs.byName("fp"), nil
|
||||
case arm64asm.X30:
|
||||
return regs.byName("lr"), nil
|
||||
case arm64asm.SP:
|
||||
return regs.byName("sp"), nil
|
||||
}
|
||||
|
||||
// 64-bit
|
||||
switch reg {
|
||||
case arm64asm.W0:
|
||||
return regs.byName("w0"), nil
|
||||
case arm64asm.W1:
|
||||
return regs.byName("w1"), nil
|
||||
case arm64asm.W2:
|
||||
return regs.byName("w2"), nil
|
||||
case arm64asm.W3:
|
||||
return regs.byName("w3"), nil
|
||||
case arm64asm.W4:
|
||||
return regs.byName("w4"), nil
|
||||
case arm64asm.W5:
|
||||
return regs.byName("w5"), nil
|
||||
case arm64asm.W6:
|
||||
return regs.byName("w6"), nil
|
||||
case arm64asm.W7:
|
||||
return regs.byName("w7"), nil
|
||||
case arm64asm.W8:
|
||||
return regs.byName("w8"), nil
|
||||
case arm64asm.W9:
|
||||
return regs.byName("w9"), nil
|
||||
case arm64asm.W10:
|
||||
return regs.byName("w10"), nil
|
||||
case arm64asm.W11:
|
||||
return regs.byName("w11"), nil
|
||||
case arm64asm.W12:
|
||||
return regs.byName("w12"), nil
|
||||
case arm64asm.W13:
|
||||
return regs.byName("w13"), nil
|
||||
case arm64asm.W14:
|
||||
return regs.byName("w14"), nil
|
||||
case arm64asm.W15:
|
||||
return regs.byName("w15"), nil
|
||||
case arm64asm.W16:
|
||||
return regs.byName("w16"), nil
|
||||
case arm64asm.W17:
|
||||
return regs.byName("w17"), nil
|
||||
case arm64asm.W18:
|
||||
return regs.byName("w18"), nil
|
||||
case arm64asm.W19:
|
||||
return regs.byName("w19"), nil
|
||||
case arm64asm.W20:
|
||||
return regs.byName("w20"), nil
|
||||
case arm64asm.W21:
|
||||
return regs.byName("w21"), nil
|
||||
case arm64asm.W22:
|
||||
return regs.byName("w22"), nil
|
||||
case arm64asm.W23:
|
||||
return regs.byName("w23"), nil
|
||||
case arm64asm.W24:
|
||||
return regs.byName("w24"), nil
|
||||
case arm64asm.W25:
|
||||
return regs.byName("w25"), nil
|
||||
case arm64asm.W26:
|
||||
return regs.byName("w26"), nil
|
||||
case arm64asm.W27:
|
||||
return regs.byName("w27"), nil
|
||||
case arm64asm.W28:
|
||||
return regs.byName("w28"), nil
|
||||
// TODO: not sure about these ones, they are not returned by debugserver
|
||||
// probably need to take the x-register and bitmask them
|
||||
/*case arm64asm.W29:
|
||||
return regs.byName("w29"), nil
|
||||
case arm64asm.W30:
|
||||
return regs.byName("w30"), nil
|
||||
/*case arm64asm.WSP:
|
||||
return regs.byName("wsp"), nil*/
|
||||
}
|
||||
|
||||
// vector registers
|
||||
// 64-bit
|
||||
switch reg {
|
||||
case arm64asm.V0:
|
||||
return regs.byName("v0"), nil
|
||||
case arm64asm.V1:
|
||||
return regs.byName("v1"), nil
|
||||
case arm64asm.V2:
|
||||
return regs.byName("v2"), nil
|
||||
case arm64asm.V3:
|
||||
return regs.byName("v3"), nil
|
||||
case arm64asm.V4:
|
||||
return regs.byName("v4"), nil
|
||||
case arm64asm.V5:
|
||||
return regs.byName("v5"), nil
|
||||
case arm64asm.V6:
|
||||
return regs.byName("v6"), nil
|
||||
case arm64asm.V7:
|
||||
return regs.byName("v7"), nil
|
||||
case arm64asm.V8:
|
||||
return regs.byName("v8"), nil
|
||||
case arm64asm.V9:
|
||||
return regs.byName("v9"), nil
|
||||
case arm64asm.V10:
|
||||
return regs.byName("v10"), nil
|
||||
case arm64asm.V11:
|
||||
return regs.byName("v11"), nil
|
||||
case arm64asm.V12:
|
||||
return regs.byName("v12"), nil
|
||||
case arm64asm.V13:
|
||||
return regs.byName("v13"), nil
|
||||
case arm64asm.V14:
|
||||
return regs.byName("v14"), nil
|
||||
case arm64asm.V15:
|
||||
return regs.byName("v15"), nil
|
||||
case arm64asm.V16:
|
||||
return regs.byName("v16"), nil
|
||||
case arm64asm.V17:
|
||||
return regs.byName("v17"), nil
|
||||
case arm64asm.V18:
|
||||
return regs.byName("v18"), nil
|
||||
case arm64asm.V19:
|
||||
return regs.byName("v19"), nil
|
||||
case arm64asm.V20:
|
||||
return regs.byName("v20"), nil
|
||||
case arm64asm.V21:
|
||||
return regs.byName("v21"), nil
|
||||
case arm64asm.V22:
|
||||
return regs.byName("v22"), nil
|
||||
case arm64asm.V23:
|
||||
return regs.byName("v23"), nil
|
||||
case arm64asm.V24:
|
||||
return regs.byName("v24"), nil
|
||||
case arm64asm.V25:
|
||||
return regs.byName("v25"), nil
|
||||
case arm64asm.V26:
|
||||
return regs.byName("v26"), nil
|
||||
case arm64asm.V27:
|
||||
return regs.byName("v27"), nil
|
||||
case arm64asm.V28:
|
||||
return regs.byName("v28"), nil
|
||||
case arm64asm.V29:
|
||||
return regs.byName("v29"), nil
|
||||
case arm64asm.V30:
|
||||
return regs.byName("v30"), nil
|
||||
case arm64asm.V31:
|
||||
return regs.byName("v31"), nil
|
||||
}
|
||||
} else {
|
||||
reg := x86asm.Reg(n)
|
||||
|
||||
switch reg {
|
||||
// 8-bit
|
||||
case x86asm.AL:
|
||||
return regs.byName("rax") & mask8, nil
|
||||
case x86asm.CL:
|
||||
return regs.byName("rcx") & mask8, nil
|
||||
case x86asm.DL:
|
||||
return regs.byName("rdx") & mask8, nil
|
||||
case x86asm.BL:
|
||||
return regs.byName("rbx") & mask8, nil
|
||||
case x86asm.AH:
|
||||
return (regs.byName("rax") >> 8) & mask8, nil
|
||||
case x86asm.CH:
|
||||
return (regs.byName("rcx") >> 8) & mask8, nil
|
||||
case x86asm.DH:
|
||||
return (regs.byName("rdx") >> 8) & mask8, nil
|
||||
case x86asm.BH:
|
||||
return (regs.byName("rbx") >> 8) & mask8, nil
|
||||
case x86asm.SPB:
|
||||
return regs.byName("rsp") & mask8, nil
|
||||
case x86asm.BPB:
|
||||
return regs.byName("rbp") & mask8, nil
|
||||
case x86asm.SIB:
|
||||
return regs.byName("rsi") & mask8, nil
|
||||
case x86asm.DIB:
|
||||
return regs.byName("rdi") & mask8, nil
|
||||
case x86asm.R8B:
|
||||
return regs.byName("r8") & mask8, nil
|
||||
case x86asm.R9B:
|
||||
return regs.byName("r9") & mask8, nil
|
||||
case x86asm.R10B:
|
||||
return regs.byName("r10") & mask8, nil
|
||||
case x86asm.R11B:
|
||||
return regs.byName("r11") & mask8, nil
|
||||
case x86asm.R12B:
|
||||
return regs.byName("r12") & mask8, nil
|
||||
case x86asm.R13B:
|
||||
return regs.byName("r13") & mask8, nil
|
||||
case x86asm.R14B:
|
||||
return regs.byName("r14") & mask8, nil
|
||||
case x86asm.R15B:
|
||||
return regs.byName("r15") & mask8, nil
|
||||
|
||||
// 16-bit
|
||||
case x86asm.AX:
|
||||
return regs.byName("rax") & mask16, nil
|
||||
case x86asm.CX:
|
||||
return regs.byName("rcx") & mask16, nil
|
||||
case x86asm.DX:
|
||||
return regs.byName("rdx") & mask16, nil
|
||||
case x86asm.BX:
|
||||
return regs.byName("rbx") & mask16, nil
|
||||
case x86asm.SP:
|
||||
return regs.byName("rsp") & mask16, nil
|
||||
case x86asm.BP:
|
||||
return regs.byName("rbp") & mask16, nil
|
||||
case x86asm.SI:
|
||||
return regs.byName("rsi") & mask16, nil
|
||||
case x86asm.DI:
|
||||
return regs.byName("rdi") & mask16, nil
|
||||
case x86asm.R8W:
|
||||
return regs.byName("r8") & mask16, nil
|
||||
case x86asm.R9W:
|
||||
return regs.byName("r9") & mask16, nil
|
||||
case x86asm.R10W:
|
||||
return regs.byName("r10") & mask16, nil
|
||||
case x86asm.R11W:
|
||||
return regs.byName("r11") & mask16, nil
|
||||
case x86asm.R12W:
|
||||
return regs.byName("r12") & mask16, nil
|
||||
case x86asm.R13W:
|
||||
return regs.byName("r13") & mask16, nil
|
||||
case x86asm.R14W:
|
||||
return regs.byName("r14") & mask16, nil
|
||||
case x86asm.R15W:
|
||||
return regs.byName("r15") & mask16, nil
|
||||
|
||||
// 32-bit
|
||||
case x86asm.EAX:
|
||||
return regs.byName("rax") & mask32, nil
|
||||
case x86asm.ECX:
|
||||
return regs.byName("rcx") & mask32, nil
|
||||
case x86asm.EDX:
|
||||
return regs.byName("rdx") & mask32, nil
|
||||
case x86asm.EBX:
|
||||
return regs.byName("rbx") & mask32, nil
|
||||
case x86asm.ESP:
|
||||
return regs.byName("rsp") & mask32, nil
|
||||
case x86asm.EBP:
|
||||
return regs.byName("rbp") & mask32, nil
|
||||
case x86asm.ESI:
|
||||
return regs.byName("rsi") & mask32, nil
|
||||
case x86asm.EDI:
|
||||
return regs.byName("rdi") & mask32, nil
|
||||
case x86asm.R8L:
|
||||
return regs.byName("r8") & mask32, nil
|
||||
case x86asm.R9L:
|
||||
return regs.byName("r9") & mask32, nil
|
||||
case x86asm.R10L:
|
||||
return regs.byName("r10") & mask32, nil
|
||||
case x86asm.R11L:
|
||||
return regs.byName("r11") & mask32, nil
|
||||
case x86asm.R12L:
|
||||
return regs.byName("r12") & mask32, nil
|
||||
case x86asm.R13L:
|
||||
return regs.byName("r13") & mask32, nil
|
||||
case x86asm.R14L:
|
||||
return regs.byName("r14") & mask32, nil
|
||||
case x86asm.R15L:
|
||||
return regs.byName("r15") & mask32, nil
|
||||
|
||||
// 64-bit
|
||||
case x86asm.RAX:
|
||||
return regs.byName("rax"), nil
|
||||
case x86asm.RCX:
|
||||
return regs.byName("rcx"), nil
|
||||
case x86asm.RDX:
|
||||
return regs.byName("rdx"), nil
|
||||
case x86asm.RBX:
|
||||
return regs.byName("rbx"), nil
|
||||
case x86asm.RSP:
|
||||
return regs.byName("rsp"), nil
|
||||
case x86asm.RBP:
|
||||
return regs.byName("rbp"), nil
|
||||
case x86asm.RSI:
|
||||
return regs.byName("rsi"), nil
|
||||
case x86asm.RDI:
|
||||
return regs.byName("rdi"), nil
|
||||
case x86asm.R8:
|
||||
return regs.byName("r8"), nil
|
||||
case x86asm.R9:
|
||||
return regs.byName("r9"), nil
|
||||
case x86asm.R10:
|
||||
return regs.byName("r10"), nil
|
||||
case x86asm.R11:
|
||||
return regs.byName("r11"), nil
|
||||
case x86asm.R12:
|
||||
return regs.byName("r12"), nil
|
||||
case x86asm.R13:
|
||||
return regs.byName("r13"), nil
|
||||
case x86asm.R14:
|
||||
return regs.byName("r14"), nil
|
||||
case x86asm.R15:
|
||||
return regs.byName("r15"), nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, proc.ErrUnknownRegister
|
||||
}
|
||||
|
||||
func (r *gdbRegisters) FloatLoadError() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ func I386Arch(goos string) *Arch {
|
||||
asmDecode: i386AsmDecode,
|
||||
PCRegNum: regnum.I386_Eip,
|
||||
SPRegNum: regnum.I386_Esp,
|
||||
asmRegisters: i386AsmRegisters,
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,12 +185,12 @@ func i386RegSize(regnum uint64) int {
|
||||
return 4
|
||||
}
|
||||
|
||||
func i386RegistersToDwarfRegisters(staticBase uint64, regs Registers) op.DwarfRegisters {
|
||||
func i386RegistersToDwarfRegisters(staticBase uint64, regs Registers) *op.DwarfRegisters {
|
||||
dregs := initDwarfRegistersFromSlice(regnum.I386MaxRegNum(), regs, regnum.I386NameToDwarf)
|
||||
dr := op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.I386_Eip, regnum.I386_Esp, regnum.I386_Ebp, 0)
|
||||
dr.SetLoadMoreCallback(loadMoreDwarfRegistersFromSliceFunc(dr, regs, regnum.I386NameToDwarf))
|
||||
|
||||
return *dr
|
||||
return dr
|
||||
}
|
||||
|
||||
func i386AddrAndStackRegsToDwarfRegisters(staticBase, pc, sp, bp, lr uint64) op.DwarfRegisters {
|
||||
|
||||
@ -5,10 +5,13 @@
|
||||
package proc
|
||||
|
||||
import (
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
"github.com/go-delve/delve/pkg/dwarf/regnum"
|
||||
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
)
|
||||
|
||||
func i386AsmDecode(asmInst *AsmInstruction, mem []byte, regs Registers, memrw MemoryReadWriter, bi *BinaryInfo) error {
|
||||
func i386AsmDecode(asmInst *AsmInstruction, mem []byte, regs *op.DwarfRegisters, memrw MemoryReadWriter, bi *BinaryInfo) error {
|
||||
return x86AsmDecode(asmInst, mem, regs, memrw, bi, 32)
|
||||
}
|
||||
|
||||
@ -37,3 +40,39 @@ func init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var i386AsmRegisters = map[int]asmRegister{
|
||||
// 8-bit
|
||||
int(x86asm.AL): asmRegister{regnum.I386_Eax, 0, mask8},
|
||||
int(x86asm.CL): asmRegister{regnum.I386_Ecx, 0, mask8},
|
||||
int(x86asm.DL): asmRegister{regnum.I386_Edx, 0, mask8},
|
||||
int(x86asm.BL): asmRegister{regnum.I386_Ebx, 0, mask8},
|
||||
int(x86asm.AH): asmRegister{regnum.I386_Eax, 8, mask8},
|
||||
int(x86asm.CH): asmRegister{regnum.I386_Ecx, 8, mask8},
|
||||
int(x86asm.DH): asmRegister{regnum.I386_Edx, 8, mask8},
|
||||
int(x86asm.BH): asmRegister{regnum.I386_Ebx, 8, mask8},
|
||||
int(x86asm.SPB): asmRegister{regnum.I386_Esp, 0, mask8},
|
||||
int(x86asm.BPB): asmRegister{regnum.I386_Ebp, 0, mask8},
|
||||
int(x86asm.SIB): asmRegister{regnum.I386_Esi, 0, mask8},
|
||||
int(x86asm.DIB): asmRegister{regnum.I386_Edi, 0, mask8},
|
||||
|
||||
// 16-bit
|
||||
int(x86asm.AX): asmRegister{regnum.I386_Eax, 0, mask16},
|
||||
int(x86asm.CX): asmRegister{regnum.I386_Ecx, 0, mask16},
|
||||
int(x86asm.DX): asmRegister{regnum.I386_Edx, 0, mask16},
|
||||
int(x86asm.BX): asmRegister{regnum.I386_Ebx, 0, mask16},
|
||||
int(x86asm.SP): asmRegister{regnum.I386_Esp, 0, mask16},
|
||||
int(x86asm.BP): asmRegister{regnum.I386_Ebp, 0, mask16},
|
||||
int(x86asm.SI): asmRegister{regnum.I386_Esi, 0, mask16},
|
||||
int(x86asm.DI): asmRegister{regnum.I386_Edi, 0, mask16},
|
||||
|
||||
// 32-bit
|
||||
int(x86asm.EAX): asmRegister{regnum.I386_Eax, 0, mask32},
|
||||
int(x86asm.ECX): asmRegister{regnum.I386_Ecx, 0, mask32},
|
||||
int(x86asm.EDX): asmRegister{regnum.I386_Edx, 0, mask32},
|
||||
int(x86asm.EBX): asmRegister{regnum.I386_Ebx, 0, mask32},
|
||||
int(x86asm.ESP): asmRegister{regnum.I386_Esp, 0, mask32},
|
||||
int(x86asm.EBP): asmRegister{regnum.I386_Ebp, 0, mask32},
|
||||
int(x86asm.ESI): asmRegister{regnum.I386_Esi, 0, mask32},
|
||||
int(x86asm.EDI): asmRegister{regnum.I386_Edi, 0, mask32},
|
||||
}
|
||||
|
||||
@ -3,8 +3,6 @@ package linutil
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
"github.com/go-delve/delve/pkg/dwarf/regnum"
|
||||
"github.com/go-delve/delve/pkg/proc"
|
||||
@ -131,164 +129,6 @@ func (r *AMD64Registers) GAddr() (uint64, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Get returns the value of the n-th register (in x86asm order).
|
||||
func (r *AMD64Registers) Get(n int) (uint64, error) {
|
||||
reg := x86asm.Reg(n)
|
||||
const (
|
||||
mask8 = 0x000000ff
|
||||
mask16 = 0x0000ffff
|
||||
mask32 = 0xffffffff
|
||||
)
|
||||
|
||||
switch reg {
|
||||
// 8-bit
|
||||
case x86asm.AL:
|
||||
return r.Regs.Rax & mask8, nil
|
||||
case x86asm.CL:
|
||||
return r.Regs.Rcx & mask8, nil
|
||||
case x86asm.DL:
|
||||
return r.Regs.Rdx & mask8, nil
|
||||
case x86asm.BL:
|
||||
return r.Regs.Rbx & mask8, nil
|
||||
case x86asm.AH:
|
||||
return (r.Regs.Rax >> 8) & mask8, nil
|
||||
case x86asm.CH:
|
||||
return (r.Regs.Rcx >> 8) & mask8, nil
|
||||
case x86asm.DH:
|
||||
return (r.Regs.Rdx >> 8) & mask8, nil
|
||||
case x86asm.BH:
|
||||
return (r.Regs.Rbx >> 8) & mask8, nil
|
||||
case x86asm.SPB:
|
||||
return r.Regs.Rsp & mask8, nil
|
||||
case x86asm.BPB:
|
||||
return r.Regs.Rbp & mask8, nil
|
||||
case x86asm.SIB:
|
||||
return r.Regs.Rsi & mask8, nil
|
||||
case x86asm.DIB:
|
||||
return r.Regs.Rdi & mask8, nil
|
||||
case x86asm.R8B:
|
||||
return r.Regs.R8 & mask8, nil
|
||||
case x86asm.R9B:
|
||||
return r.Regs.R9 & mask8, nil
|
||||
case x86asm.R10B:
|
||||
return r.Regs.R10 & mask8, nil
|
||||
case x86asm.R11B:
|
||||
return r.Regs.R11 & mask8, nil
|
||||
case x86asm.R12B:
|
||||
return r.Regs.R12 & mask8, nil
|
||||
case x86asm.R13B:
|
||||
return r.Regs.R13 & mask8, nil
|
||||
case x86asm.R14B:
|
||||
return r.Regs.R14 & mask8, nil
|
||||
case x86asm.R15B:
|
||||
return r.Regs.R15 & mask8, nil
|
||||
|
||||
// 16-bit
|
||||
case x86asm.AX:
|
||||
return r.Regs.Rax & mask16, nil
|
||||
case x86asm.CX:
|
||||
return r.Regs.Rcx & mask16, nil
|
||||
case x86asm.DX:
|
||||
return r.Regs.Rdx & mask16, nil
|
||||
case x86asm.BX:
|
||||
return r.Regs.Rbx & mask16, nil
|
||||
case x86asm.SP:
|
||||
return r.Regs.Rsp & mask16, nil
|
||||
case x86asm.BP:
|
||||
return r.Regs.Rbp & mask16, nil
|
||||
case x86asm.SI:
|
||||
return r.Regs.Rsi & mask16, nil
|
||||
case x86asm.DI:
|
||||
return r.Regs.Rdi & mask16, nil
|
||||
case x86asm.R8W:
|
||||
return r.Regs.R8 & mask16, nil
|
||||
case x86asm.R9W:
|
||||
return r.Regs.R9 & mask16, nil
|
||||
case x86asm.R10W:
|
||||
return r.Regs.R10 & mask16, nil
|
||||
case x86asm.R11W:
|
||||
return r.Regs.R11 & mask16, nil
|
||||
case x86asm.R12W:
|
||||
return r.Regs.R12 & mask16, nil
|
||||
case x86asm.R13W:
|
||||
return r.Regs.R13 & mask16, nil
|
||||
case x86asm.R14W:
|
||||
return r.Regs.R14 & mask16, nil
|
||||
case x86asm.R15W:
|
||||
return r.Regs.R15 & mask16, nil
|
||||
|
||||
// 32-bit
|
||||
case x86asm.EAX:
|
||||
return r.Regs.Rax & mask32, nil
|
||||
case x86asm.ECX:
|
||||
return r.Regs.Rcx & mask32, nil
|
||||
case x86asm.EDX:
|
||||
return r.Regs.Rdx & mask32, nil
|
||||
case x86asm.EBX:
|
||||
return r.Regs.Rbx & mask32, nil
|
||||
case x86asm.ESP:
|
||||
return r.Regs.Rsp & mask32, nil
|
||||
case x86asm.EBP:
|
||||
return r.Regs.Rbp & mask32, nil
|
||||
case x86asm.ESI:
|
||||
return r.Regs.Rsi & mask32, nil
|
||||
case x86asm.EDI:
|
||||
return r.Regs.Rdi & mask32, nil
|
||||
case x86asm.R8L:
|
||||
return r.Regs.R8 & mask32, nil
|
||||
case x86asm.R9L:
|
||||
return r.Regs.R9 & mask32, nil
|
||||
case x86asm.R10L:
|
||||
return r.Regs.R10 & mask32, nil
|
||||
case x86asm.R11L:
|
||||
return r.Regs.R11 & mask32, nil
|
||||
case x86asm.R12L:
|
||||
return r.Regs.R12 & mask32, nil
|
||||
case x86asm.R13L:
|
||||
return r.Regs.R13 & mask32, nil
|
||||
case x86asm.R14L:
|
||||
return r.Regs.R14 & mask32, nil
|
||||
case x86asm.R15L:
|
||||
return r.Regs.R15 & mask32, nil
|
||||
|
||||
// 64-bit
|
||||
case x86asm.RAX:
|
||||
return r.Regs.Rax, nil
|
||||
case x86asm.RCX:
|
||||
return r.Regs.Rcx, nil
|
||||
case x86asm.RDX:
|
||||
return r.Regs.Rdx, nil
|
||||
case x86asm.RBX:
|
||||
return r.Regs.Rbx, nil
|
||||
case x86asm.RSP:
|
||||
return r.Regs.Rsp, nil
|
||||
case x86asm.RBP:
|
||||
return r.Regs.Rbp, nil
|
||||
case x86asm.RSI:
|
||||
return r.Regs.Rsi, nil
|
||||
case x86asm.RDI:
|
||||
return r.Regs.Rdi, nil
|
||||
case x86asm.R8:
|
||||
return r.Regs.R8, nil
|
||||
case x86asm.R9:
|
||||
return r.Regs.R9, nil
|
||||
case x86asm.R10:
|
||||
return r.Regs.R10, nil
|
||||
case x86asm.R11:
|
||||
return r.Regs.R11, nil
|
||||
case x86asm.R12:
|
||||
return r.Regs.R12, nil
|
||||
case x86asm.R13:
|
||||
return r.Regs.R13, nil
|
||||
case x86asm.R14:
|
||||
return r.Regs.R14, nil
|
||||
case x86asm.R15:
|
||||
return r.Regs.R15, nil
|
||||
}
|
||||
|
||||
return 0, proc.ErrUnknownRegister
|
||||
}
|
||||
|
||||
// Copy returns a copy of these registers that is guaranteed not to change.
|
||||
func (r *AMD64Registers) Copy() (proc.Registers, error) {
|
||||
if r.loadFpRegs != nil {
|
||||
|
||||
@ -2,7 +2,6 @@ package linutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"golang.org/x/arch/arm64/arm64asm"
|
||||
|
||||
"github.com/go-delve/delve/pkg/proc"
|
||||
)
|
||||
@ -116,17 +115,6 @@ func (r *ARM64Registers) GAddr() (uint64, bool) {
|
||||
return r.Regs.Regs[28], !r.iscgo
|
||||
}
|
||||
|
||||
// Get returns the value of the n-th register (in arm64asm order).
|
||||
func (r *ARM64Registers) Get(n int) (uint64, error) {
|
||||
reg := arm64asm.Reg(n)
|
||||
|
||||
if reg >= arm64asm.X0 && reg <= arm64asm.X30 {
|
||||
return r.Regs.Regs[reg-arm64asm.X0], nil
|
||||
}
|
||||
|
||||
return 0, proc.ErrUnknownRegister
|
||||
}
|
||||
|
||||
// Copy returns a copy of these registers that is guaranteed not to change.
|
||||
func (r *ARM64Registers) Copy() (proc.Registers, error) {
|
||||
if r.loadFpRegs != nil {
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package linutil
|
||||
|
||||
import (
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
|
||||
"github.com/go-delve/delve/pkg/proc"
|
||||
"github.com/go-delve/delve/pkg/proc/amd64util"
|
||||
)
|
||||
@ -113,80 +111,6 @@ func (r *I386Registers) GAddr() (uint64, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Get returns the value of the n-th register (in x86asm order).
|
||||
func (r *I386Registers) Get(n int) (uint64, error) {
|
||||
reg := x86asm.Reg(n)
|
||||
const (
|
||||
mask8 = 0x000000ff
|
||||
mask16 = 0x0000ffff
|
||||
)
|
||||
|
||||
switch reg {
|
||||
// 8-bit
|
||||
case x86asm.AL:
|
||||
return uint64(r.Regs.Eax) & mask8, nil
|
||||
case x86asm.CL:
|
||||
return uint64(r.Regs.Ecx) & mask8, nil
|
||||
case x86asm.DL:
|
||||
return uint64(r.Regs.Edx) & mask8, nil
|
||||
case x86asm.BL:
|
||||
return uint64(r.Regs.Ebx) & mask8, nil
|
||||
case x86asm.AH:
|
||||
return (uint64(r.Regs.Eax) >> 8) & mask8, nil
|
||||
case x86asm.CH:
|
||||
return (uint64(r.Regs.Ecx) >> 8) & mask8, nil
|
||||
case x86asm.DH:
|
||||
return (uint64(r.Regs.Edx) >> 8) & mask8, nil
|
||||
case x86asm.BH:
|
||||
return (uint64(r.Regs.Ebx) >> 8) & mask8, nil
|
||||
case x86asm.SPB:
|
||||
return uint64(r.Regs.Esp) & mask8, nil
|
||||
case x86asm.BPB:
|
||||
return uint64(r.Regs.Ebp) & mask8, nil
|
||||
case x86asm.SIB:
|
||||
return uint64(r.Regs.Esi) & mask8, nil
|
||||
case x86asm.DIB:
|
||||
return uint64(r.Regs.Edi) & mask8, nil
|
||||
|
||||
// 16-bit
|
||||
case x86asm.AX:
|
||||
return uint64(r.Regs.Eax) & mask16, nil
|
||||
case x86asm.CX:
|
||||
return uint64(r.Regs.Ecx) & mask16, nil
|
||||
case x86asm.DX:
|
||||
return uint64(r.Regs.Edx) & mask16, nil
|
||||
case x86asm.BX:
|
||||
return uint64(r.Regs.Ebx) & mask16, nil
|
||||
case x86asm.SP:
|
||||
return uint64(r.Regs.Esp) & mask16, nil
|
||||
case x86asm.BP:
|
||||
return uint64(r.Regs.Ebp) & mask16, nil
|
||||
case x86asm.SI:
|
||||
return uint64(r.Regs.Esi) & mask16, nil
|
||||
case x86asm.DI:
|
||||
return uint64(r.Regs.Edi) & mask16, nil
|
||||
|
||||
// 32-bit
|
||||
case x86asm.EAX:
|
||||
return uint64(uint32(r.Regs.Eax)), nil
|
||||
case x86asm.ECX:
|
||||
return uint64(uint32(r.Regs.Ecx)), nil
|
||||
case x86asm.EDX:
|
||||
return uint64(uint32(r.Regs.Edx)), nil
|
||||
case x86asm.EBX:
|
||||
return uint64(uint32(r.Regs.Ebx)), nil
|
||||
case x86asm.ESP:
|
||||
return uint64(uint32(r.Regs.Esp)), nil
|
||||
case x86asm.EBP:
|
||||
return uint64(uint32(r.Regs.Ebp)), nil
|
||||
case x86asm.ESI:
|
||||
return uint64(uint32(r.Regs.Esi)), nil
|
||||
case x86asm.EDI:
|
||||
return uint64(uint32(r.Regs.Edi)), nil
|
||||
}
|
||||
return 0, proc.ErrUnknownRegister
|
||||
}
|
||||
|
||||
// Copy returns a copy of these registers that is guaranteed not to change.
|
||||
func (r *I386Registers) Copy() (proc.Registers, error) {
|
||||
if r.loadFpRegs != nil {
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
package linutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
)
|
||||
|
||||
func TestAMD64Get(t *testing.T) {
|
||||
val := uint64(0xffffffffdeadbeef)
|
||||
regs := AMD64Registers{
|
||||
Regs: &AMD64PtraceRegs{
|
||||
Rax: val,
|
||||
},
|
||||
}
|
||||
// Test AL, low 8 bits of RAX
|
||||
al, err := regs.Get(int(x86asm.AL))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if al != 0xef {
|
||||
t.Fatalf("expected %#v, got %#v\n", 0xef, al)
|
||||
}
|
||||
|
||||
// Test AH, high 8 bits of RAX
|
||||
ah, err := regs.Get(int(x86asm.AH))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ah != 0xBE {
|
||||
t.Fatalf("expected %#v, got %#v\n", 0xbe, ah)
|
||||
}
|
||||
|
||||
// Test AX, lower 16 bits of RAX
|
||||
ax, err := regs.Get(int(x86asm.AX))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ax != 0xBEEF {
|
||||
t.Fatalf("expected %#v, got %#v\n", 0xbeef, ax)
|
||||
}
|
||||
|
||||
// Test EAX, lower 32 bits of RAX
|
||||
eax, err := regs.Get(int(x86asm.EAX))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if eax != 0xDEADBEEF {
|
||||
t.Fatalf("expected %#v, got %#v\n", uint64(0xdeadbeef), eax)
|
||||
}
|
||||
|
||||
// Test RAX, full 64 bits of register
|
||||
rax, err := regs.Get(int(x86asm.RAX))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if rax != val {
|
||||
t.Fatalf("expected %#v, got %#v\n", val, rax)
|
||||
}
|
||||
}
|
||||
@ -4994,7 +4994,7 @@ func TestDump(t *testing.T) {
|
||||
assertNoError(err, t, fmt.Sprintf("Thread registers %d", thread.ThreadID()))
|
||||
arch := thread.BinInfo().Arch
|
||||
dregs := arch.RegistersToDwarfRegisters(0, regs)
|
||||
return fmt.Sprintf("%08d %s", thread.ThreadID(), convertRegisters(arch, dregs))
|
||||
return fmt.Sprintf("%08d %s", thread.ThreadID(), convertRegisters(arch, *dregs))
|
||||
}
|
||||
|
||||
convertThreads := func(threads []proc.Thread) []string {
|
||||
|
||||
@ -20,7 +20,6 @@ type Registers interface {
|
||||
TLS() uint64
|
||||
// GAddr returns the address of the G variable if it is known, 0 and false otherwise
|
||||
GAddr() (uint64, bool)
|
||||
Get(int) (uint64, error)
|
||||
Slice(floatingPoint bool) ([]Register, error)
|
||||
// Copy returns a copy of the registers that is guaranteed not to change
|
||||
// when the registers of the associated thread change.
|
||||
|
||||
@ -100,7 +100,7 @@ func ThreadStacktrace(thread Thread, depth int) ([]Stackframe, error) {
|
||||
return nil, err
|
||||
}
|
||||
so := thread.BinInfo().PCToImage(regs.PC())
|
||||
dwarfRegs := thread.BinInfo().Arch.RegistersToDwarfRegisters(so.StaticBase, regs)
|
||||
dwarfRegs := *(thread.BinInfo().Arch.RegistersToDwarfRegisters(so.StaticBase, regs))
|
||||
dwarfRegs.ChangeFunc = thread.SetReg
|
||||
it := newStackIterator(thread.BinInfo(), thread.ProcessMemory(), dwarfRegs, 0, nil, -1, nil, 0)
|
||||
return it.stacktrace(depth)
|
||||
@ -121,7 +121,7 @@ func (g *G) stackIterator(opts StacktraceOptions) (*stackIterator, error) {
|
||||
return nil, err
|
||||
}
|
||||
so := bi.PCToImage(regs.PC())
|
||||
dwarfRegs := bi.Arch.RegistersToDwarfRegisters(so.StaticBase, regs)
|
||||
dwarfRegs := *(bi.Arch.RegistersToDwarfRegisters(so.StaticBase, regs))
|
||||
dwarfRegs.ChangeFunc = g.Thread.SetReg
|
||||
return newStackIterator(
|
||||
bi, g.variable.mem,
|
||||
|
||||
@ -6,8 +6,6 @@ import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
|
||||
"github.com/go-delve/delve/pkg/proc"
|
||||
)
|
||||
|
||||
@ -164,164 +162,6 @@ func (r *AMD64Registers) GAddr() (uint64, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Get returns the value of the n-th register (in x86asm order).
|
||||
func (r *AMD64Registers) Get(n int) (uint64, error) {
|
||||
reg := x86asm.Reg(n)
|
||||
const (
|
||||
mask8 = 0x000f
|
||||
mask16 = 0x00ff
|
||||
mask32 = 0xffff
|
||||
)
|
||||
|
||||
switch reg {
|
||||
// 8-bit
|
||||
case x86asm.AL:
|
||||
return r.rax & mask8, nil
|
||||
case x86asm.CL:
|
||||
return r.rcx & mask8, nil
|
||||
case x86asm.DL:
|
||||
return r.rdx & mask8, nil
|
||||
case x86asm.BL:
|
||||
return r.rbx & mask8, nil
|
||||
case x86asm.AH:
|
||||
return (r.rax >> 8) & mask8, nil
|
||||
case x86asm.CH:
|
||||
return (r.rcx >> 8) & mask8, nil
|
||||
case x86asm.DH:
|
||||
return (r.rdx >> 8) & mask8, nil
|
||||
case x86asm.BH:
|
||||
return (r.rbx >> 8) & mask8, nil
|
||||
case x86asm.SPB:
|
||||
return r.rsp & mask8, nil
|
||||
case x86asm.BPB:
|
||||
return r.rbp & mask8, nil
|
||||
case x86asm.SIB:
|
||||
return r.rsi & mask8, nil
|
||||
case x86asm.DIB:
|
||||
return r.rdi & mask8, nil
|
||||
case x86asm.R8B:
|
||||
return r.r8 & mask8, nil
|
||||
case x86asm.R9B:
|
||||
return r.r9 & mask8, nil
|
||||
case x86asm.R10B:
|
||||
return r.r10 & mask8, nil
|
||||
case x86asm.R11B:
|
||||
return r.r11 & mask8, nil
|
||||
case x86asm.R12B:
|
||||
return r.r12 & mask8, nil
|
||||
case x86asm.R13B:
|
||||
return r.r13 & mask8, nil
|
||||
case x86asm.R14B:
|
||||
return r.r14 & mask8, nil
|
||||
case x86asm.R15B:
|
||||
return r.r15 & mask8, nil
|
||||
|
||||
// 16-bit
|
||||
case x86asm.AX:
|
||||
return r.rax & mask16, nil
|
||||
case x86asm.CX:
|
||||
return r.rcx & mask16, nil
|
||||
case x86asm.DX:
|
||||
return r.rdx & mask16, nil
|
||||
case x86asm.BX:
|
||||
return r.rbx & mask16, nil
|
||||
case x86asm.SP:
|
||||
return r.rsp & mask16, nil
|
||||
case x86asm.BP:
|
||||
return r.rbp & mask16, nil
|
||||
case x86asm.SI:
|
||||
return r.rsi & mask16, nil
|
||||
case x86asm.DI:
|
||||
return r.rdi & mask16, nil
|
||||
case x86asm.R8W:
|
||||
return r.r8 & mask16, nil
|
||||
case x86asm.R9W:
|
||||
return r.r9 & mask16, nil
|
||||
case x86asm.R10W:
|
||||
return r.r10 & mask16, nil
|
||||
case x86asm.R11W:
|
||||
return r.r11 & mask16, nil
|
||||
case x86asm.R12W:
|
||||
return r.r12 & mask16, nil
|
||||
case x86asm.R13W:
|
||||
return r.r13 & mask16, nil
|
||||
case x86asm.R14W:
|
||||
return r.r14 & mask16, nil
|
||||
case x86asm.R15W:
|
||||
return r.r15 & mask16, nil
|
||||
|
||||
// 32-bit
|
||||
case x86asm.EAX:
|
||||
return r.rax & mask32, nil
|
||||
case x86asm.ECX:
|
||||
return r.rcx & mask32, nil
|
||||
case x86asm.EDX:
|
||||
return r.rdx & mask32, nil
|
||||
case x86asm.EBX:
|
||||
return r.rbx & mask32, nil
|
||||
case x86asm.ESP:
|
||||
return r.rsp & mask32, nil
|
||||
case x86asm.EBP:
|
||||
return r.rbp & mask32, nil
|
||||
case x86asm.ESI:
|
||||
return r.rsi & mask32, nil
|
||||
case x86asm.EDI:
|
||||
return r.rdi & mask32, nil
|
||||
case x86asm.R8L:
|
||||
return r.r8 & mask32, nil
|
||||
case x86asm.R9L:
|
||||
return r.r9 & mask32, nil
|
||||
case x86asm.R10L:
|
||||
return r.r10 & mask32, nil
|
||||
case x86asm.R11L:
|
||||
return r.r11 & mask32, nil
|
||||
case x86asm.R12L:
|
||||
return r.r12 & mask32, nil
|
||||
case x86asm.R13L:
|
||||
return r.r13 & mask32, nil
|
||||
case x86asm.R14L:
|
||||
return r.r14 & mask32, nil
|
||||
case x86asm.R15L:
|
||||
return r.r15 & mask32, nil
|
||||
|
||||
// 64-bit
|
||||
case x86asm.RAX:
|
||||
return r.rax, nil
|
||||
case x86asm.RCX:
|
||||
return r.rcx, nil
|
||||
case x86asm.RDX:
|
||||
return r.rdx, nil
|
||||
case x86asm.RBX:
|
||||
return r.rbx, nil
|
||||
case x86asm.RSP:
|
||||
return r.rsp, nil
|
||||
case x86asm.RBP:
|
||||
return r.rbp, nil
|
||||
case x86asm.RSI:
|
||||
return r.rsi, nil
|
||||
case x86asm.RDI:
|
||||
return r.rdi, nil
|
||||
case x86asm.R8:
|
||||
return r.r8, nil
|
||||
case x86asm.R9:
|
||||
return r.r9, nil
|
||||
case x86asm.R10:
|
||||
return r.r10, nil
|
||||
case x86asm.R11:
|
||||
return r.r11, nil
|
||||
case x86asm.R12:
|
||||
return r.r12, nil
|
||||
case x86asm.R13:
|
||||
return r.r13, nil
|
||||
case x86asm.R14:
|
||||
return r.r14, nil
|
||||
case x86asm.R15:
|
||||
return r.r15, nil
|
||||
}
|
||||
|
||||
return 0, proc.ErrUnknownRegister
|
||||
}
|
||||
|
||||
// Copy returns a copy of these registers that is guaranteed not to change.
|
||||
func (r *AMD64Registers) Copy() (proc.Registers, error) {
|
||||
var rr AMD64Registers
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package proc
|
||||
|
||||
import (
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
)
|
||||
|
||||
@ -8,7 +10,7 @@ type x86Inst x86asm.Inst
|
||||
|
||||
// AsmDecode decodes the assembly instruction starting at mem[0:] into asmInst.
|
||||
// It assumes that the Loc and AtPC fields of asmInst have already been filled.
|
||||
func x86AsmDecode(asmInst *AsmInstruction, mem []byte, regs Registers, memrw MemoryReadWriter, bi *BinaryInfo, bit int) error {
|
||||
func x86AsmDecode(asmInst *AsmInstruction, mem []byte, regs *op.DwarfRegisters, memrw MemoryReadWriter, bi *BinaryInfo, bit int) error {
|
||||
inst, err := x86asm.Decode(mem, bit)
|
||||
if err != nil {
|
||||
asmInst.Inst = (*x86Inst)(nil)
|
||||
@ -76,7 +78,7 @@ func (inst *x86Inst) OpcodeEquals(op uint64) bool {
|
||||
return uint64(inst.Op) == op
|
||||
}
|
||||
|
||||
func resolveCallArgX86(inst *x86asm.Inst, instAddr uint64, currentGoroutine bool, regs Registers, mem MemoryReadWriter, bininfo *BinaryInfo) *Location {
|
||||
func resolveCallArgX86(inst *x86asm.Inst, instAddr uint64, currentGoroutine bool, regs *op.DwarfRegisters, mem MemoryReadWriter, bininfo *BinaryInfo) *Location {
|
||||
switch inst.Op {
|
||||
case x86asm.CALL, x86asm.LCALL, x86asm.JMP, x86asm.LJMP:
|
||||
// ok
|
||||
@ -94,7 +96,7 @@ func resolveCallArgX86(inst *x86asm.Inst, instAddr uint64, currentGoroutine bool
|
||||
if !currentGoroutine || regs == nil {
|
||||
return nil
|
||||
}
|
||||
pc, err = regs.Get(int(arg))
|
||||
pc, err = bininfo.Arch.getAsmRegister(regs, int(arg))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -105,8 +107,8 @@ func resolveCallArgX86(inst *x86asm.Inst, instAddr uint64, currentGoroutine bool
|
||||
if arg.Segment != 0 {
|
||||
return nil
|
||||
}
|
||||
base, err1 := regs.Get(int(arg.Base))
|
||||
index, err2 := regs.Get(int(arg.Index))
|
||||
base, err1 := bininfo.Arch.getAsmRegister(regs, int(arg.Base))
|
||||
index, err2 := bininfo.Arch.getAsmRegister(regs, int(arg.Index))
|
||||
if err1 != nil || err2 != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1313,8 +1313,7 @@ func (d *Debugger) ThreadRegisters(threadID int, floatingPoint bool) (*op.DwarfR
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dregs := d.target.BinInfo().Arch.RegistersToDwarfRegisters(0, regs)
|
||||
return &dregs, nil
|
||||
return d.target.BinInfo().Arch.RegistersToDwarfRegisters(0, regs), nil
|
||||
}
|
||||
|
||||
// ScopeRegisters returns registers for the specified scope.
|
||||
|
||||
Reference in New Issue
Block a user