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 }