gitlab.com/Raven-IO/raven-delve@v1.22.4/pkg/proc/linutil/regs_amd64_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 "gitlab.com/Raven-IO/raven-delve/pkg/proc/amd64util" 10 ) 11 12 // AMD64Registers implements the proc.Registers interface for the native/linux 13 // backend and core/linux backends, on AMD64. 14 type AMD64Registers struct { 15 Regs *AMD64PtraceRegs 16 Fpregs []proc.Register 17 Fpregset *amd64util.AMD64Xstate 18 19 loadFpRegs func(*AMD64Registers) error 20 } 21 22 func NewAMD64Registers(regs *AMD64PtraceRegs, loadFpRegs func(*AMD64Registers) error) *AMD64Registers { 23 return &AMD64Registers{Regs: regs, loadFpRegs: loadFpRegs} 24 } 25 26 // AMD64PtraceRegs is the struct used by the linux kernel to return the 27 // general purpose registers for AMD64 CPUs. 28 type AMD64PtraceRegs struct { 29 R15 uint64 30 R14 uint64 31 R13 uint64 32 R12 uint64 33 Rbp uint64 34 Rbx uint64 35 R11 uint64 36 R10 uint64 37 R9 uint64 38 R8 uint64 39 Rax uint64 40 Rcx uint64 41 Rdx uint64 42 Rsi uint64 43 Rdi uint64 44 Orig_rax uint64 45 Rip uint64 46 Cs uint64 47 Eflags uint64 48 Rsp uint64 49 Ss uint64 50 Fs_base uint64 51 Gs_base uint64 52 Ds uint64 53 Es uint64 54 Fs uint64 55 Gs uint64 56 } 57 58 // Slice returns the registers as a list of (name, value) pairs. 59 func (r *AMD64Registers) Slice(floatingPoint bool) ([]proc.Register, error) { 60 var regs = []struct { 61 k string 62 v uint64 63 }{ 64 {"Rip", r.Regs.Rip}, 65 {"Rsp", r.Regs.Rsp}, 66 {"Rax", r.Regs.Rax}, 67 {"Rbx", r.Regs.Rbx}, 68 {"Rcx", r.Regs.Rcx}, 69 {"Rdx", r.Regs.Rdx}, 70 {"Rdi", r.Regs.Rdi}, 71 {"Rsi", r.Regs.Rsi}, 72 {"Rbp", r.Regs.Rbp}, 73 {"R8", r.Regs.R8}, 74 {"R9", r.Regs.R9}, 75 {"R10", r.Regs.R10}, 76 {"R11", r.Regs.R11}, 77 {"R12", r.Regs.R12}, 78 {"R13", r.Regs.R13}, 79 {"R14", r.Regs.R14}, 80 {"R15", r.Regs.R15}, 81 {"Orig_rax", r.Regs.Orig_rax}, 82 {"Cs", r.Regs.Cs}, 83 {"Rflags", r.Regs.Eflags}, 84 {"Ss", r.Regs.Ss}, 85 {"Fs_base", r.Regs.Fs_base}, 86 {"Gs_base", r.Regs.Gs_base}, 87 {"Ds", r.Regs.Ds}, 88 {"Es", r.Regs.Es}, 89 {"Fs", r.Regs.Fs}, 90 {"Gs", r.Regs.Gs}, 91 } 92 out := make([]proc.Register, 0, len(regs)+len(r.Fpregs)) 93 for _, reg := range regs { 94 out = proc.AppendUint64Register(out, reg.k, reg.v) 95 } 96 var floatLoadError error 97 if floatingPoint { 98 if r.loadFpRegs != nil { 99 floatLoadError = r.loadFpRegs(r) 100 r.loadFpRegs = nil 101 } 102 out = append(out, r.Fpregs...) 103 } 104 return out, floatLoadError 105 } 106 107 // PC returns the value of RIP register. 108 func (r *AMD64Registers) PC() uint64 { 109 return r.Regs.Rip 110 } 111 112 // SP returns the value of RSP register. 113 func (r *AMD64Registers) SP() uint64 { 114 return r.Regs.Rsp 115 } 116 117 func (r *AMD64Registers) BP() uint64 { 118 return r.Regs.Rbp 119 } 120 121 // TLS returns the address of the thread local storage memory segment. 122 func (r *AMD64Registers) TLS() uint64 { 123 return r.Regs.Fs_base 124 } 125 126 // GAddr returns the address of the G variable if it is known, 0 and false 127 // otherwise. 128 func (r *AMD64Registers) GAddr() (uint64, bool) { 129 return 0, false 130 } 131 132 // LR returns the link register. 133 func (r *AMD64Registers) LR() uint64 { 134 panic("not valid") 135 } 136 137 // Copy returns a copy of these registers that is guaranteed not to change. 138 func (r *AMD64Registers) Copy() (proc.Registers, error) { 139 if r.loadFpRegs != nil { 140 err := r.loadFpRegs(r) 141 r.loadFpRegs = nil 142 if err != nil { 143 return nil, err 144 } 145 } 146 var rr AMD64Registers 147 rr.Regs = &AMD64PtraceRegs{} 148 rr.Fpregset = &amd64util.AMD64Xstate{} 149 *(rr.Regs) = *(r.Regs) 150 if r.Fpregset != nil { 151 *(rr.Fpregset) = *(r.Fpregset) 152 } 153 if r.Fpregs != nil { 154 rr.Fpregs = make([]proc.Register, len(r.Fpregs)) 155 copy(rr.Fpregs, r.Fpregs) 156 } 157 return &rr, nil 158 } 159 160 func (r *AMD64Registers) SetReg(regNum uint64, reg *op.DwarfRegister) (bool, error) { 161 var p *uint64 162 switch regNum { 163 case regnum.AMD64_Rax: 164 p = &r.Regs.Rax 165 case regnum.AMD64_Rbx: 166 p = &r.Regs.Rbx 167 case regnum.AMD64_Rcx: 168 p = &r.Regs.Rcx 169 case regnum.AMD64_Rdx: 170 p = &r.Regs.Rdx 171 case regnum.AMD64_Rsi: 172 p = &r.Regs.Rsi 173 case regnum.AMD64_Rdi: 174 p = &r.Regs.Rdi 175 case regnum.AMD64_Rbp: 176 p = &r.Regs.Rbp 177 case regnum.AMD64_Rsp: 178 p = &r.Regs.Rsp 179 case regnum.AMD64_R8: 180 p = &r.Regs.R8 181 case regnum.AMD64_R9: 182 p = &r.Regs.R9 183 case regnum.AMD64_R10: 184 p = &r.Regs.R10 185 case regnum.AMD64_R11: 186 p = &r.Regs.R11 187 case regnum.AMD64_R12: 188 p = &r.Regs.R12 189 case regnum.AMD64_R13: 190 p = &r.Regs.R13 191 case regnum.AMD64_R14: 192 p = &r.Regs.R14 193 case regnum.AMD64_R15: 194 p = &r.Regs.R15 195 case regnum.AMD64_Rip: 196 p = &r.Regs.Rip 197 case regnum.AMD64_Rflags: 198 p = &r.Regs.Eflags 199 } 200 201 if p != nil { 202 if reg.Bytes != nil && len(reg.Bytes) != 8 { 203 return false, fmt.Errorf("wrong number of bytes for register %s (%d)", regnum.AMD64ToName(regNum), len(reg.Bytes)) 204 } 205 *p = reg.Uint64Val 206 return false, nil 207 } 208 209 if r.loadFpRegs != nil { 210 err := r.loadFpRegs(r) 211 if err != nil { 212 return false, err 213 } 214 r.loadFpRegs = nil 215 } 216 217 if regNum < regnum.AMD64_XMM0 || regNum > regnum.AMD64_XMM0+15 { 218 return false, fmt.Errorf("can not set %s", regnum.AMD64ToName(regNum)) 219 } 220 221 reg.FillBytes() 222 223 err := r.Fpregset.SetXmmRegister(int(regNum-regnum.AMD64_XMM0), reg.Bytes) 224 if err != nil { 225 return false, err 226 } 227 return true, nil 228 }