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