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  }