diff --git a/pkg/dwarf/regnum/arm64.go b/pkg/dwarf/regnum/arm64.go index 13b15c1e..3f7805b9 100644 --- a/pkg/dwarf/regnum/arm64.go +++ b/pkg/dwarf/regnum/arm64.go @@ -10,13 +10,13 @@ import ( // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040b/IHI0040B_aadwarf.pdf const ( - ARM64_X0 = 0 // X1 through X30 follow - ARM64_BP = 29 // also X29 - ARM64_LR = 30 // also X30 - ARM64_SP = 31 - ARM64_PC = 32 - ARM64_V0 = 64 // V1 through V31 follow - + ARM64_X0 = 0 // X1 through X30 follow + ARM64_BP = 29 // also X29 + ARM64_LR = 30 // also X30 + 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 +}() diff --git a/pkg/proc/amd64_arch.go b/pkg/proc/amd64_arch.go index 6a20bbfe..1e53d5cf 100644 --- a/pkg/proc/amd64_arch.go +++ b/pkg/proc/amd64_arch.go @@ -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 { diff --git a/pkg/proc/amd64_disasm.go b/pkg/proc/amd64_disasm.go index cbacd726..be855e19 100644 --- a/pkg/proc/amd64_disasm.go +++ b/pkg/proc/amd64_disasm.go @@ -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}, +} diff --git a/pkg/proc/arch.go b/pkg/proc/arch.go index 39d2ec23..9aadc6bd 100644 --- a/pkg/proc/arch.go +++ b/pkg/proc/arch.go @@ -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 diff --git a/pkg/proc/arm64_arch.go b/pkg/proc/arm64_arch.go index 8196ef96..30c35765 100644 --- a/pkg/proc/arm64_arch.go +++ b/pkg/proc/arm64_arch.go @@ -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 { diff --git a/pkg/proc/arm64_disasm.go b/pkg/proc/arm64_disasm.go index 8a137a1b..bd918f4a 100644 --- a/pkg/proc/arm64_disasm.go +++ b/pkg/proc/arm64_disasm.go @@ -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 +}() diff --git a/pkg/proc/core/delve_core.go b/pkg/proc/core/delve_core.go index 3d2fefd2..8dbc88db 100644 --- a/pkg/proc/core/delve_core.go +++ b/pkg/proc/core/delve_core.go @@ -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 } diff --git a/pkg/proc/disasm.go b/pkg/proc/disasm.go index 5566bb82..161f81b7 100644 --- a/pkg/proc/disasm.go +++ b/pkg/proc/disasm.go @@ -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) diff --git a/pkg/proc/dwarf_export_test.go b/pkg/proc/dwarf_export_test.go index 57f723fc..b28c8bba 100644 --- a/pkg/proc/dwarf_export_test.go +++ b/pkg/proc/dwarf_export_test.go @@ -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) } diff --git a/pkg/proc/dwarf_expr_test.go b/pkg/proc/dwarf_expr_test.go index 573707f8..ed514c64 100644 --- a/pkg/proc/dwarf_expr_test.go +++ b/pkg/proc/dwarf_expr_test.go @@ -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 diff --git a/pkg/proc/fbsdutil/regs.go b/pkg/proc/fbsdutil/regs.go index aa29a61b..4b9cd80b 100644 --- a/pkg/proc/fbsdutil/regs.go +++ b/pkg/proc/fbsdutil/regs.go @@ -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 { diff --git a/pkg/proc/fbsdutil/regs_test.go b/pkg/proc/fbsdutil/regs_test.go deleted file mode 100644 index 19aa7641..00000000 --- a/pkg/proc/fbsdutil/regs_test.go +++ /dev/null @@ -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) - } -} diff --git a/pkg/proc/fncall.go b/pkg/proc/fncall.go index d50f3297..3b35c12a 100644 --- a/pkg/proc/fncall.go +++ b/pkg/proc/fncall.go @@ -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() diff --git a/pkg/proc/gdbserial/gdbserver.go b/pkg/proc/gdbserial/gdbserver.go index 12d550f6..4a1cab30 100644 --- a/pkg/proc/gdbserial/gdbserver.go +++ b/pkg/proc/gdbserial/gdbserver.go @@ -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 } diff --git a/pkg/proc/i386_arch.go b/pkg/proc/i386_arch.go index bf22d359..5a33c1cc 100644 --- a/pkg/proc/i386_arch.go +++ b/pkg/proc/i386_arch.go @@ -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 { diff --git a/pkg/proc/i386_disasm.go b/pkg/proc/i386_disasm.go index 6803375d..b1762278 100644 --- a/pkg/proc/i386_disasm.go +++ b/pkg/proc/i386_disasm.go @@ -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}, +} diff --git a/pkg/proc/linutil/regs_amd64_arch.go b/pkg/proc/linutil/regs_amd64_arch.go index 6d6f0cf4..dbea3396 100644 --- a/pkg/proc/linutil/regs_amd64_arch.go +++ b/pkg/proc/linutil/regs_amd64_arch.go @@ -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 { diff --git a/pkg/proc/linutil/regs_arm64_arch.go b/pkg/proc/linutil/regs_arm64_arch.go index 5141e579..acb2d497 100644 --- a/pkg/proc/linutil/regs_arm64_arch.go +++ b/pkg/proc/linutil/regs_arm64_arch.go @@ -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 { diff --git a/pkg/proc/linutil/regs_i386_arch.go b/pkg/proc/linutil/regs_i386_arch.go index 823505cb..d456ff00 100644 --- a/pkg/proc/linutil/regs_i386_arch.go +++ b/pkg/proc/linutil/regs_i386_arch.go @@ -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 { diff --git a/pkg/proc/linutil/regs_test.go b/pkg/proc/linutil/regs_test.go deleted file mode 100644 index a9ed0fbf..00000000 --- a/pkg/proc/linutil/regs_test.go +++ /dev/null @@ -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) - } -} diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 3820ae9d..36144115 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -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 { diff --git a/pkg/proc/registers.go b/pkg/proc/registers.go index 22c79f6f..83a58650 100644 --- a/pkg/proc/registers.go +++ b/pkg/proc/registers.go @@ -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. diff --git a/pkg/proc/stack.go b/pkg/proc/stack.go index 0e05d474..1befb68f 100644 --- a/pkg/proc/stack.go +++ b/pkg/proc/stack.go @@ -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, diff --git a/pkg/proc/winutil/regs.go b/pkg/proc/winutil/regs.go index 3822e415..a2c482e9 100644 --- a/pkg/proc/winutil/regs.go +++ b/pkg/proc/winutil/regs.go @@ -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 diff --git a/pkg/proc/x86_disasm.go b/pkg/proc/x86_disasm.go index f2ed572d..96e20701 100644 --- a/pkg/proc/x86_disasm.go +++ b/pkg/proc/x86_disasm.go @@ -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 } diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 850419a9..053b8787 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -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.