github.com/cnboonhan/delve@v0.0.0-20230908061759-363f2388c2fb/pkg/proc/linutil/regs_ppc64le_arch.go (about)

     1  package linutil
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/go-delve/delve/pkg/proc"
     7  )
     8  
     9  // PPC64LERegisters implements the proc.Registers interface for the native/linux
    10  // backend and core/linux backends, on PPC64LE.
    11  type PPC64LERegisters struct {
    12  	Regs       *PPC64LEPtraceRegs
    13  	Fpregs     []proc.Register //Formatted floating point registers
    14  	Fpregset   []byte          //holding all floating point register values
    15  	loadFpRegs func(*PPC64LERegisters) error
    16  }
    17  
    18  func NewPPC64LERegisters(regs *PPC64LEPtraceRegs, loadFpRegs func(*PPC64LERegisters) error) *PPC64LERegisters {
    19  	return &PPC64LERegisters{Regs: regs, loadFpRegs: loadFpRegs}
    20  }
    21  
    22  // PPC64LEPtraceRegs is the struct used by the linux kernel to return the
    23  // general purpose registers for PPC64LE CPUs.
    24  // Copied from src/syscall/ztypes_linux_ppc64le.go#L518-L532
    25  type PPC64LEPtraceRegs struct {
    26  	Gpr       [32]uint64 // 32 general-purpose registers, each 64 bits wide
    27  	Nip       uint64
    28  	Msr       uint64
    29  	Orig_gpr3 uint64
    30  	Ctr       uint64
    31  	Link      uint64 // Link register -- LLDB dwarf_lr_ppc64le = 65
    32  	Xer       uint64 // Fixed point exception register -- LLDB dwarf_xer_ppc64le = 76
    33  	Ccr       uint64
    34  	Softe     uint64
    35  	Trap      uint64
    36  	Dar       uint64
    37  	Dsisr     uint64
    38  	Result    uint64
    39  }
    40  
    41  // PC returns the value of the NIP register
    42  // Also called the IAR/Instruction Address Register or NIP/Next Instruction Pointer
    43  func (r *PPC64LERegisters) PC() uint64 {
    44  	return r.Regs.Nip
    45  }
    46  
    47  // SP returns the value of Stack frame pointer stored in Gpr[1].
    48  func (r *PPC64LERegisters) SP() uint64 {
    49  	return r.Regs.Gpr[1]
    50  }
    51  
    52  // LR The Link Register is a 64-bit register. It can be
    53  // used to provide the branch target address for the
    54  // Branch Conditional to Link Register instruction, and it
    55  // holds the return address after Branch instructions for
    56  // which LK=1 and after System Call Vectored instructions.
    57  // Extracted from the 2.3.2 section of the PowerISA Book 3.1
    58  func (r *PPC64LERegisters) LR() uint64 {
    59  	return r.Regs.Link
    60  }
    61  
    62  func (r *PPC64LERegisters) BP() uint64 {
    63  	return r.Regs.Gpr[1]
    64  }
    65  
    66  // TLS returns the value of the thread pointer stored in Gpr[13]
    67  func (r *PPC64LERegisters) TLS() uint64 {
    68  	return r.Regs.Gpr[13]
    69  }
    70  
    71  // GAddr returns the address of the G variable
    72  func (r *PPC64LERegisters) GAddr() (uint64, bool) {
    73  	return r.Regs.Gpr[30], true
    74  }
    75  
    76  // Slice returns the registers as a list of (name, value) pairs.
    77  func (r *PPC64LERegisters) Slice(floatingPoint bool) ([]proc.Register, error) {
    78  	var regs = []struct {
    79  		k string
    80  		v uint64
    81  	}{
    82  		{"R0", r.Regs.Gpr[0]},
    83  		{"R1", r.Regs.Gpr[1]},
    84  		{"R2", r.Regs.Gpr[2]},
    85  		{"R3", r.Regs.Gpr[3]},
    86  		{"R4", r.Regs.Gpr[4]},
    87  		{"R5", r.Regs.Gpr[5]},
    88  		{"R6", r.Regs.Gpr[6]},
    89  		{"R7", r.Regs.Gpr[7]},
    90  		{"R8", r.Regs.Gpr[8]},
    91  		{"R9", r.Regs.Gpr[9]},
    92  		{"R10", r.Regs.Gpr[10]},
    93  		{"R11", r.Regs.Gpr[11]},
    94  		{"R12", r.Regs.Gpr[12]},
    95  		{"R13", r.Regs.Gpr[13]},
    96  		{"R14", r.Regs.Gpr[14]},
    97  		{"R15", r.Regs.Gpr[15]},
    98  		{"R16", r.Regs.Gpr[16]},
    99  		{"R17", r.Regs.Gpr[17]},
   100  		{"R18", r.Regs.Gpr[18]},
   101  		{"R19", r.Regs.Gpr[19]},
   102  		{"R20", r.Regs.Gpr[20]},
   103  		{"R21", r.Regs.Gpr[21]},
   104  		{"R22", r.Regs.Gpr[22]},
   105  		{"R23", r.Regs.Gpr[23]},
   106  		{"R24", r.Regs.Gpr[24]},
   107  		{"R25", r.Regs.Gpr[25]},
   108  		{"R26", r.Regs.Gpr[26]},
   109  		{"R27", r.Regs.Gpr[27]},
   110  		{"R28", r.Regs.Gpr[28]},
   111  		{"R29", r.Regs.Gpr[29]},
   112  		{"R30", r.Regs.Gpr[30]},
   113  		{"R31", r.Regs.Gpr[31]},
   114  		{"Nip", r.Regs.Nip},
   115  		{"MSr", r.Regs.Msr},
   116  		{"Orig_gpr3", r.Regs.Orig_gpr3},
   117  		{"Ctr", r.Regs.Ctr},
   118  		{"Link", r.Regs.Link},
   119  		{"Xer", r.Regs.Xer},
   120  		{"Ccr", r.Regs.Ccr},
   121  		{"Softe", r.Regs.Softe},
   122  		{"Trap", r.Regs.Trap},
   123  		{"Dar", r.Regs.Dar},
   124  		{"Dsisr", r.Regs.Dsisr},
   125  		{"Result", r.Regs.Result},
   126  	}
   127  	out := make([]proc.Register, 0, len(regs)+len(r.Fpregs))
   128  	for _, reg := range regs {
   129  		out = proc.AppendUint64Register(out, reg.k, reg.v)
   130  	}
   131  	var floatLoadError error
   132  	if floatingPoint {
   133  		if r.loadFpRegs != nil {
   134  			floatLoadError = r.loadFpRegs(r)
   135  			r.loadFpRegs = nil
   136  		}
   137  		out = append(out, r.Fpregs...)
   138  	}
   139  	return out, floatLoadError
   140  }
   141  
   142  // Copy returns a copy of these registers that is guaranteed not to change.
   143  func (r *PPC64LERegisters) Copy() (proc.Registers, error) {
   144  	if r.loadFpRegs != nil {
   145  		err := r.loadFpRegs(r)
   146  		r.loadFpRegs = nil
   147  		if err != nil {
   148  			return nil, err
   149  		}
   150  	}
   151  	var rr PPC64LERegisters
   152  	rr.Regs = &PPC64LEPtraceRegs{}
   153  	*(rr.Regs) = *(r.Regs)
   154  	if r.Fpregs != nil {
   155  		rr.Fpregs = make([]proc.Register, len(r.Fpregs))
   156  		copy(rr.Fpregs, r.Fpregs)
   157  	}
   158  	if r.Fpregset != nil {
   159  		rr.Fpregset = make([]byte, len(r.Fpregset))
   160  		copy(rr.Fpregset, r.Fpregset)
   161  	}
   162  	return &rr, nil
   163  }
   164  
   165  type PPC64LEPtraceFpRegs struct {
   166  	Fp []byte
   167  }
   168  
   169  func (fpregs *PPC64LEPtraceFpRegs) Decode() (regs []proc.Register) {
   170  	for i := 0; i < len(fpregs.Fp); i += 16 {
   171  		regs = proc.AppendBytesRegister(regs, fmt.Sprintf("V%d", i/16), fpregs.Fp[i:i+16])
   172  	}
   173  	return
   174  }