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