github.com/cnboonhan/delve@v0.0.0-20230908061759-363f2388c2fb/pkg/proc/native/registers_linux_ppc64le.go (about) 1 package native 2 3 import ( 4 "debug/elf" 5 "syscall" 6 "unsafe" 7 8 "github.com/go-delve/delve/pkg/dwarf/op" 9 "github.com/go-delve/delve/pkg/dwarf/regnum" 10 "github.com/go-delve/delve/pkg/proc" 11 "github.com/go-delve/delve/pkg/proc/linutil" 12 sys "golang.org/x/sys/unix" 13 ) 14 15 const ( 16 _PPC64LE_GPREGS_SIZE = 44 * 8 17 _PPC64LE_FPREGS_SIZE = 33*8 + 8 18 ) 19 20 func ptraceGetGRegs(pid int, regs *linutil.PPC64LEPtraceRegs) (err error) { 21 sys.PtraceGetRegs(pid, (*sys.PtraceRegs)(regs)) 22 if err == syscall.Errno(0) { 23 err = nil 24 } 25 return 26 } 27 28 func ptraceSetGRegs(pid int, regs *linutil.PPC64LEPtraceRegs) (err error) { 29 sys.PtraceSetRegs(pid, (*sys.PtraceRegs)(regs)) 30 if err == syscall.Errno(0) { 31 err = nil 32 } 33 return 34 } 35 36 func ptraceGetFpRegset(tid int) (fpregset []byte, err error) { 37 var ppc64leFpregs [_PPC64LE_FPREGS_SIZE]byte 38 iov := sys.Iovec{Base: &ppc64leFpregs[0], Len: _PPC64LE_FPREGS_SIZE} 39 _, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_GETREGSET, uintptr(tid), uintptr(elf.NT_FPREGSET), uintptr(unsafe.Pointer(&iov)), 0, 0) 40 if err != syscall.Errno(0) { 41 if err == syscall.ENODEV { 42 err = nil 43 } 44 return 45 } else { 46 err = nil 47 } 48 49 fpregset = ppc64leFpregs[:iov.Len-8] 50 return fpregset, err 51 } 52 53 // SetPC sets PC to the value specified by 'pc'. 54 func (t *nativeThread) setPC(pc uint64) error { 55 ir, err := registers(t) 56 if err != nil { 57 return err 58 } 59 r := ir.(*linutil.PPC64LERegisters) 60 r.Regs.Nip = pc 61 t.dbp.execPtraceFunc(func() { err = ptraceSetGRegs(t.ID, r.Regs) }) 62 return err 63 } 64 65 // SetReg changes the value of the specified register. 66 func (t *nativeThread) SetReg(regNum uint64, reg *op.DwarfRegister) error { 67 ir, err := registers(t) 68 if err != nil { 69 return err 70 } 71 r := ir.(*linutil.PPC64LERegisters) 72 73 switch regNum { 74 case regnum.PPC64LE_PC: 75 r.Regs.Nip = reg.Uint64Val 76 case regnum.PPC64LE_SP: 77 r.Regs.Gpr[1] = reg.Uint64Val 78 case regnum.PPC64LE_LR: 79 r.Regs.Link = reg.Uint64Val 80 default: 81 panic("SetReg") 82 } 83 84 t.dbp.execPtraceFunc(func() { err = ptraceSetGRegs(t.ID, r.Regs) }) 85 return err 86 } 87 88 func registers(thread *nativeThread) (proc.Registers, error) { 89 var ( 90 regs linutil.PPC64LEPtraceRegs 91 err error 92 ) 93 94 thread.dbp.execPtraceFunc(func() { err = ptraceGetGRegs(thread.ID, ®s) }) 95 if err != nil { 96 return nil, err 97 } 98 r := linutil.NewPPC64LERegisters(®s, func(r *linutil.PPC64LERegisters) error { 99 var floatLoadError error 100 r.Fpregs, r.Fpregset, floatLoadError = thread.fpRegisters() 101 return floatLoadError 102 }) 103 return r, nil 104 }