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  }