github.com/undoio/delve@v1.9.0/pkg/proc/linutil/regs_i386_arch.go (about) 1 package linutil 2 3 import ( 4 "github.com/undoio/delve/pkg/proc" 5 "github.com/undoio/delve/pkg/proc/amd64util" 6 ) 7 8 // I386Registers implements the proc.Registers interface for the native/linux 9 // backend and core/linux backends, on I386. 10 type I386Registers struct { 11 Regs *I386PtraceRegs 12 Fpregs []proc.Register 13 Fpregset *amd64util.AMD64Xstate 14 Tls uint64 15 16 loadFpRegs func(*I386Registers) error 17 } 18 19 func NewI386Registers(regs *I386PtraceRegs, loadFpRegs func(*I386Registers) error) *I386Registers { 20 return &I386Registers{Regs: regs, Fpregs: nil, Fpregset: nil, Tls: 0, loadFpRegs: loadFpRegs} 21 } 22 23 // I386PtraceRegs is the struct used by the linux kernel to return the 24 // general purpose registers for I386 CPUs. 25 type I386PtraceRegs struct { 26 Ebx int32 27 Ecx int32 28 Edx int32 29 Esi int32 30 Edi int32 31 Ebp int32 32 Eax int32 33 Xds int32 34 Xes int32 35 Xfs int32 36 Xgs int32 37 Orig_eax int32 38 Eip int32 39 Xcs int32 40 Eflags int32 41 Esp int32 42 Xss int32 43 } 44 45 // Slice returns the registers as a list of (name, value) pairs. 46 func (r *I386Registers) Slice(floatingPoint bool) ([]proc.Register, error) { 47 var regs = []struct { 48 k string 49 v int32 50 }{ 51 {"Ebx", r.Regs.Ebx}, 52 {"Ecx", r.Regs.Ecx}, 53 {"Edx", r.Regs.Edx}, 54 {"Esi", r.Regs.Esi}, 55 {"Edi", r.Regs.Edi}, 56 {"Ebp", r.Regs.Ebp}, 57 {"Eax", r.Regs.Eax}, 58 {"Xds", r.Regs.Xds}, 59 {"Xes", r.Regs.Xes}, 60 {"Xfs", r.Regs.Xfs}, 61 {"Xgs", r.Regs.Xgs}, 62 {"Orig_eax", r.Regs.Orig_eax}, 63 {"Eip", r.Regs.Eip}, 64 {"Xcs", r.Regs.Xcs}, 65 {"Eflags", r.Regs.Eflags}, 66 {"Esp", r.Regs.Esp}, 67 {"Xss", r.Regs.Xss}, 68 } 69 out := make([]proc.Register, 0, len(regs)+len(r.Fpregs)) 70 for _, reg := range regs { 71 out = proc.AppendUint64Register(out, reg.k, uint64(uint32(reg.v))) 72 } 73 var floatLoadError error 74 if floatingPoint { 75 if r.loadFpRegs != nil { 76 floatLoadError = r.loadFpRegs(r) 77 r.loadFpRegs = nil 78 } 79 out = append(out, r.Fpregs...) 80 } 81 return out, floatLoadError 82 } 83 84 // PC returns the value of EIP register. 85 func (r *I386Registers) PC() uint64 { 86 return uint64(uint32(r.Regs.Eip)) 87 } 88 89 // SP returns the value of ESP register. 90 func (r *I386Registers) SP() uint64 { 91 return uint64(uint32(r.Regs.Esp)) 92 } 93 94 func (r *I386Registers) BP() uint64 { 95 return uint64(uint32(r.Regs.Ebp)) 96 } 97 98 // CX returns the value of ECX register. 99 func (r *I386Registers) CX() uint64 { 100 return uint64(uint32(r.Regs.Ecx)) 101 } 102 103 // TLS returns the address of the thread local storage memory segment. 104 func (r *I386Registers) TLS() uint64 { 105 return r.Tls 106 } 107 108 // LR returns the link register. 109 func (r *I386Registers) LR() uint64 { 110 panic("not valid") 111 } 112 113 // GAddr returns the address of the G variable if it is known, 0 and false 114 // otherwise. 115 func (r *I386Registers) GAddr() (uint64, bool) { 116 return 0, false 117 } 118 119 // Copy returns a copy of these registers that is guaranteed not to change. 120 func (r *I386Registers) Copy() (proc.Registers, error) { 121 if r.loadFpRegs != nil { 122 err := r.loadFpRegs(r) 123 r.loadFpRegs = nil 124 if err != nil { 125 return nil, err 126 } 127 } 128 var rr I386Registers 129 rr.Regs = &I386PtraceRegs{} 130 rr.Fpregset = &amd64util.AMD64Xstate{} 131 *(rr.Regs) = *(r.Regs) 132 if r.Fpregset != nil { 133 *(rr.Fpregset) = *(r.Fpregset) 134 } 135 if r.Fpregs != nil { 136 rr.Fpregs = make([]proc.Register, len(r.Fpregs)) 137 copy(rr.Fpregs, r.Fpregs) 138 } 139 return &rr, nil 140 }