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, &regs) })
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  	r := linutil.NewPPC64LERegisters(&regs, 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  }