github.com/undoio/delve@v1.9.0/pkg/proc/registers.go (about) 1 package proc 2 3 import ( 4 "errors" 5 "fmt" 6 "math" 7 "strings" 8 9 "github.com/undoio/delve/pkg/dwarf/op" 10 ) 11 12 // Registers is an interface for a generic register type. The 13 // interface encapsulates the generic values / actions 14 // we need independent of arch. The concrete register types 15 // will be different depending on OS/Arch. 16 type Registers interface { 17 PC() uint64 18 SP() uint64 19 BP() uint64 20 LR() uint64 21 TLS() uint64 22 // GAddr returns the address of the G variable if it is known, 0 and false otherwise 23 GAddr() (uint64, bool) 24 Slice(floatingPoint bool) ([]Register, error) 25 // Copy returns a copy of the registers that is guaranteed not to change 26 // when the registers of the associated thread change. 27 Copy() (Registers, error) 28 } 29 30 // Register represents a CPU register. 31 type Register struct { 32 Name string 33 Reg *op.DwarfRegister 34 } 35 36 // AppendUint64Register will create a new Register struct with the name and value 37 // specified and append it to the `regs` slice. 38 func AppendUint64Register(regs []Register, name string, value uint64) []Register { 39 return append(regs, Register{name, op.DwarfRegisterFromUint64(value)}) 40 } 41 42 // AppendBytesRegister will create a new Register struct with the name and value 43 // specified and append it to the `regs` slice. 44 func AppendBytesRegister(regs []Register, name string, value []byte) []Register { 45 return append(regs, Register{name, op.DwarfRegisterFromBytes(value)}) 46 } 47 48 // ErrUnknownRegister is returned when the value of an unknown 49 // register is requested. 50 var ErrUnknownRegister = errors.New("unknown register") 51 52 type flagRegisterDescr []flagDescr 53 type flagDescr struct { 54 name string 55 mask uint64 56 } 57 58 var mxcsrDescription flagRegisterDescr = []flagDescr{ 59 {"FZ", 1 << 15}, 60 {"RZ/RN", 1<<14 | 1<<13}, 61 {"PM", 1 << 12}, 62 {"UM", 1 << 11}, 63 {"OM", 1 << 10}, 64 {"ZM", 1 << 9}, 65 {"DM", 1 << 8}, 66 {"IM", 1 << 7}, 67 {"DAZ", 1 << 6}, 68 {"PE", 1 << 5}, 69 {"UE", 1 << 4}, 70 {"OE", 1 << 3}, 71 {"ZE", 1 << 2}, 72 {"DE", 1 << 1}, 73 {"IE", 1 << 0}, 74 } 75 76 var eflagsDescription flagRegisterDescr = []flagDescr{ 77 {"CF", 1 << 0}, 78 {"", 1 << 1}, 79 {"PF", 1 << 2}, 80 {"AF", 1 << 4}, 81 {"ZF", 1 << 6}, 82 {"SF", 1 << 7}, 83 {"TF", 1 << 8}, 84 {"IF", 1 << 9}, 85 {"DF", 1 << 10}, 86 {"OF", 1 << 11}, 87 {"IOPL", 1<<12 | 1<<13}, 88 {"NT", 1 << 14}, 89 {"RF", 1 << 16}, 90 {"VM", 1 << 17}, 91 {"AC", 1 << 18}, 92 {"VIF", 1 << 19}, 93 {"VIP", 1 << 20}, 94 {"ID", 1 << 21}, 95 } 96 97 func (descr flagRegisterDescr) Mask() uint64 { 98 var r uint64 99 for _, f := range descr { 100 r = r | f.mask 101 } 102 return r 103 } 104 105 func (descr flagRegisterDescr) Describe(reg uint64, bitsize int) string { 106 var r []string 107 for _, f := range descr { 108 if f.name == "" { 109 continue 110 } 111 // rbm is f.mask with only the right-most bit set: 112 // 0001 1100 -> 0000 0100 113 rbm := f.mask & -f.mask 114 if rbm == f.mask { 115 if reg&f.mask != 0 { 116 r = append(r, f.name) 117 } 118 } else { 119 x := (reg & f.mask) >> uint64(math.Log2(float64(rbm))) 120 r = append(r, fmt.Sprintf("%s=%x", f.name, x)) 121 } 122 } 123 if reg & ^descr.Mask() != 0 { 124 r = append(r, fmt.Sprintf("unknown_flags=%x", reg&^descr.Mask())) 125 } 126 return fmt.Sprintf("%#0*x\t[%s]", bitsize/4, reg, strings.Join(r, " ")) 127 }