github.com/undoio/delve@v1.9.0/pkg/proc/gdbserial/gdbserver.go (about)

     1  // This file and its companion gdbserver_conn implement a target.Interface
     2  // backed by a connection to a debugger speaking the "Gdb Remote Serial
     3  // Protocol".
     4  //
     5  // The "Gdb Remote Serial Protocol" is a low level debugging protocol
     6  // originally designed so that gdb could be used to debug programs running
     7  // in embedded environments but it was later extended to support programs
     8  // running on any environment and a variety of debuggers support it:
     9  // gdbserver, lldb-server, macOS's debugserver and rr.
    10  //
    11  // The protocol is specified at:
    12  //   https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html
    13  // with additional documentation for lldb specific extensions described at:
    14  //   https://github.com/llvm/llvm-project/blob/main/lldb/docs/lldb-gdb-remote.txt
    15  //
    16  // Terminology:
    17  //  * inferior: the program we are trying to debug
    18  //  * stub: the debugger on the other side of the protocol's connection (for
    19  //    example lldb-server)
    20  //  * gdbserver: stub version of gdb
    21  //  * lldb-server: stub version of lldb
    22  //  * debugserver: a different stub version of lldb, installed with lldb on
    23  //    macOS.
    24  //  * mozilla rr: a stub that records the full execution of a program
    25  //    and can then play it back.
    26  //  * undo: a stub that records the full execution of a program
    27  //    and can then play it back.
    28  //
    29  // Implementations of the protocol vary wildly between stubs, while there is
    30  // a command to query the stub about supported features (qSupported) this
    31  // only covers *some* of the more recent additions to the protocol and most
    32  // of the older packets are optional and *not* implemented by all stubs.
    33  // For example gdbserver implements 'g' (read all registers) but not 'p'
    34  // (read single register) while lldb-server implements 'p' but not 'g'.
    35  //
    36  // The protocol is also underspecified with regards to how the stub should
    37  // handle a multithreaded inferior. Its default mode of operation is
    38  // "all-stop mode", when a thread hits a breakpoint all other threads are
    39  // also stopped. But the protocol doesn't say what happens if a second
    40  // thread hits a breakpoint while the stub is in the process of stopping all
    41  // other threads.
    42  //
    43  // In practice the stub is allowed to swallow the second breakpoint hit or
    44  // to return it at a later time. If the stub chooses the latter behavior
    45  // (like gdbserver does) it is allowed to return delayed events on *any*
    46  // vCont packet. This is incredibly inconvenient since if we get notified
    47  // about a delayed breakpoint while we are trying to singlestep another
    48  // thread it's impossible to know when the singlestep we requested ended.
    49  //
    50  // What this means is that gdbserver can only be supported for multithreaded
    51  // inferiors by selecting non-stop mode, which behaves in a markedly
    52  // different way from all-stop mode and isn't supported by anything except
    53  // gdbserver.
    54  //
    55  // lldb-server/debugserver takes a different approach, only the first stop
    56  // event is reported, if any other event happens "simultaneously" they are
    57  // suppressed by the stub and the debugger can query for them using
    58  // qThreadStopInfo. This is much easier for us to implement and the
    59  // implementation gracefully degrades to the case where qThreadStopInfo is
    60  // unavailable but the inferior is run in single threaded mode.
    61  //
    62  // Therefore the following code will assume lldb-server-like behavior.
    63  
    64  package gdbserial
    65  
    66  import (
    67  	"debug/macho"
    68  	"encoding/binary"
    69  	"errors"
    70  	"fmt"
    71  	"net"
    72  	"os"
    73  	"os/exec"
    74  	"path/filepath"
    75  	"runtime"
    76  	"strconv"
    77  	"strings"
    78  	"sync"
    79  	"time"
    80  
    81  	isatty "github.com/mattn/go-isatty"
    82  	"github.com/undoio/delve/pkg/dwarf/op"
    83  	"github.com/undoio/delve/pkg/elfwriter"
    84  	"github.com/undoio/delve/pkg/logflags"
    85  	"github.com/undoio/delve/pkg/proc"
    86  	"github.com/undoio/delve/pkg/proc/internal/ebpf"
    87  	"github.com/undoio/delve/pkg/proc/linutil"
    88  	"github.com/undoio/delve/pkg/proc/macutil"
    89  )
    90  
    91  const (
    92  	gdbWireFullStopPacket = false
    93  	gdbWireMaxLen         = 120
    94  
    95  	maxTransmitAttempts    = 3    // number of retransmission attempts on failed checksum
    96  	initialInputBufferSize = 2048 // size of the input buffer for gdbConn
    97  
    98  	debugServerEnvVar = "DELVE_DEBUGSERVER_PATH" // use this environment variable to override the path to debugserver used by Launch/Attach
    99  )
   100  
   101  const heartbeatInterval = 10 * time.Second
   102  
   103  // Relative to $(xcode-select --print-path)/../
   104  // xcode-select typically returns the path to the Developer directory, which is a sibling to SharedFrameworks.
   105  var debugserverXcodeRelativeExecutablePath = "SharedFrameworks/LLDB.framework/Versions/A/Resources/debugserver"
   106  
   107  var debugserverExecutablePaths = []string{
   108  	"debugserver",
   109  	"/Library/Developer/CommandLineTools/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/debugserver",
   110  	// Function returns the active developer directory provided by xcode-select to compute a debugserver path.
   111  	func() string {
   112  		if _, err := exec.LookPath("xcode-select"); err != nil {
   113  			return ""
   114  		}
   115  
   116  		stdout, err := exec.Command("xcode-select", "--print-path").Output()
   117  		if err != nil {
   118  			return ""
   119  		}
   120  
   121  		xcodePath := strings.TrimSpace(string(stdout))
   122  		if xcodePath == "" {
   123  			return ""
   124  		}
   125  
   126  		// xcode-select prints the path to the active Developer directory, which is typically a sibling to SharedFrameworks.
   127  		return filepath.Join(xcodePath, "..", debugserverXcodeRelativeExecutablePath)
   128  	}(),
   129  }
   130  
   131  // ErrDirChange is returned when trying to change execution direction
   132  // while there are still internal breakpoints set.
   133  var ErrDirChange = errors.New("direction change with internal breakpoints")
   134  
   135  // ErrStartCallInjectionBackwards is returned when trying to start a call
   136  // injection while the recording is being run backwards.
   137  var ErrStartCallInjectionBackwards = errors.New("can not start a call injection while running backwards")
   138  
   139  var checkCanUnmaskSignalsOnce sync.Once
   140  var canUnmaskSignalsCached bool
   141  
   142  // gdbProcess implements proc.Process using a connection to a debugger stub
   143  // that understands Gdb Remote Serial Protocol.
   144  type gdbProcess struct {
   145  	bi       *proc.BinaryInfo
   146  	regnames *gdbRegnames
   147  	conn     gdbConn
   148  
   149  	threads       map[int]*gdbThread
   150  	currentThread *gdbThread
   151  
   152  	exited, detached bool
   153  	almostExited     bool // true if 'rr' has sent its synthetic SIGKILL
   154  	ctrlC            bool // ctrl-c was sent to stop inferior
   155  
   156  	breakpoints proc.BreakpointMap
   157  
   158  	gcmdok         bool   // true if the stub supports g and (maybe) G commands
   159  	_Gcmdok        bool   // true if the stub supports G command
   160  	threadStopInfo bool   // true if the stub supports qThreadStopInfo
   161  	tracedir       string // if attached to rr the path to the trace directory
   162  
   163  	breakpointKind int // breakpoint kind to pass to 'z' and 'Z' when creating software breakpoints
   164  
   165  	process  *os.Process
   166  	waitChan chan *os.ProcessState
   167  
   168  	onDetach func() // called after a successful detach
   169  
   170  	localCheckpointLastId int
   171  	localCheckpoints      map[int]proc.Checkpoint
   172  }
   173  
   174  var _ proc.RecordingManipulationInternal = &gdbProcess{}
   175  
   176  // gdbThread represents an operating system thread.
   177  type gdbThread struct {
   178  	ID                int
   179  	strID             string
   180  	regs              gdbRegisters
   181  	CurrentBreakpoint proc.BreakpointState
   182  	p                 *gdbProcess
   183  	sig               uint8  // signal received by thread after last stop
   184  	setbp             bool   // thread was stopped because of a breakpoint
   185  	watchAddr         uint64 // if > 0 this is the watchpoint address
   186  	common            proc.CommonThread
   187  }
   188  
   189  // ErrBackendUnavailable is returned when the stub program can not be found.
   190  type ErrBackendUnavailable struct{}
   191  
   192  func (err *ErrBackendUnavailable) Error() string {
   193  	return "backend unavailable"
   194  }
   195  
   196  // gdbRegisters represents the current value of the registers of a thread.
   197  // The storage space for all the registers is allocated as a single memory
   198  // block in buf, the value field inside an individual gdbRegister will be a
   199  // slice of the global buf field.
   200  type gdbRegisters struct {
   201  	regs     map[string]gdbRegister
   202  	regsInfo []gdbRegisterInfo
   203  	tls      uint64
   204  	gaddr    uint64
   205  	hasgaddr bool
   206  	buf      []byte
   207  	arch     *proc.Arch
   208  	regnames *gdbRegnames
   209  }
   210  
   211  type gdbRegister struct {
   212  	value  []byte
   213  	regnum int
   214  
   215  	ignoreOnWrite bool
   216  }
   217  
   218  // gdbRegname records names of important CPU registers
   219  type gdbRegnames struct {
   220  	PC, SP, BP, CX, FsBase string
   221  }
   222  
   223  // newProcess creates a new Process instance.
   224  // If process is not nil it is the stub's process and will be killed after
   225  // Detach.
   226  // Use Listen, Dial or Connect to complete connection.
   227  func newProcess(process *os.Process) *gdbProcess {
   228  	logger := logflags.GdbWireLogger()
   229  	p := &gdbProcess{
   230  		conn: gdbConn{
   231  			maxTransmitAttempts: maxTransmitAttempts,
   232  			inbuf:               make([]byte, 0, initialInputBufferSize),
   233  			direction:           proc.Forward,
   234  			log:                 logger,
   235  			goarch:              runtime.GOARCH,
   236  			goos:                runtime.GOOS,
   237  		},
   238  		threads:               make(map[int]*gdbThread),
   239  		bi:                    proc.NewBinaryInfo(runtime.GOOS, runtime.GOARCH),
   240  		regnames:              new(gdbRegnames),
   241  		breakpoints:           proc.NewBreakpointMap(),
   242  		gcmdok:                true,
   243  		threadStopInfo:        true,
   244  		process:               process,
   245  		localCheckpointLastId: 1,
   246  		localCheckpoints:      make(map[int]proc.Checkpoint),
   247  	}
   248  
   249  	switch p.bi.Arch.Name {
   250  	default:
   251  		fallthrough
   252  	case "amd64":
   253  		p.breakpointKind = 1
   254  	case "arm64":
   255  		p.breakpointKind = 4
   256  	}
   257  
   258  	p.regnames.PC = registerName(p.bi.Arch, p.bi.Arch.PCRegNum)
   259  	p.regnames.SP = registerName(p.bi.Arch, p.bi.Arch.SPRegNum)
   260  	p.regnames.BP = registerName(p.bi.Arch, p.bi.Arch.BPRegNum)
   261  
   262  	switch p.bi.Arch.Name {
   263  	case "arm64":
   264  		p.regnames.BP = "fp"
   265  		p.regnames.CX = "x0"
   266  	case "amd64":
   267  		p.regnames.CX = "rcx"
   268  		p.regnames.FsBase = "fs_base"
   269  	default:
   270  		panic("not implemented")
   271  	}
   272  
   273  	if process != nil {
   274  		p.waitChan = make(chan *os.ProcessState)
   275  		go func() {
   276  			state, _ := process.Wait()
   277  			p.waitChan <- state
   278  		}()
   279  	}
   280  
   281  	return p
   282  }
   283  
   284  // Listen waits for a connection from the stub.
   285  func (p *gdbProcess) Listen(listener net.Listener, path string, pid int, debugInfoDirs []string, stopReason proc.StopReason) (*proc.Target, error) {
   286  	acceptChan := make(chan net.Conn)
   287  
   288  	go func() {
   289  		conn, _ := listener.Accept()
   290  		acceptChan <- conn
   291  	}()
   292  
   293  	select {
   294  	case conn := <-acceptChan:
   295  		listener.Close()
   296  		if conn == nil {
   297  			return nil, errors.New("could not connect")
   298  		}
   299  		return p.Connect(conn, path, pid, debugInfoDirs, stopReason)
   300  	case status := <-p.waitChan:
   301  		listener.Close()
   302  		return nil, fmt.Errorf("stub exited while waiting for connection: %v", status)
   303  	}
   304  }
   305  
   306  // Dial attempts to connect to the stub.
   307  func (p *gdbProcess) Dial(addr string, path string, pid int, debugInfoDirs []string, stopReason proc.StopReason) (*proc.Target, error) {
   308  	for {
   309  		conn, err := net.Dial("tcp", addr)
   310  		if err == nil {
   311  			return p.Connect(conn, path, pid, debugInfoDirs, stopReason)
   312  		}
   313  		select {
   314  		case status := <-p.waitChan:
   315  			return nil, fmt.Errorf("stub exited while attempting to connect: %v", status)
   316  		default:
   317  		}
   318  		time.Sleep(time.Second)
   319  	}
   320  }
   321  
   322  // Connect connects to a stub and performs a handshake.
   323  //
   324  // Path and pid are, respectively, the path to the executable of the target
   325  // program and the PID of the target process, both are optional, however
   326  // some stubs do not provide ways to determine path and pid automatically
   327  // and Connect will be unable to function without knowing them.
   328  func (p *gdbProcess) Connect(conn net.Conn, path string, pid int, debugInfoDirs []string, stopReason proc.StopReason) (*proc.Target, error) {
   329  	p.conn.conn = conn
   330  	p.conn.pid = pid
   331  	err := p.conn.handshake(p.regnames)
   332  	if err != nil {
   333  		conn.Close()
   334  		return nil, err
   335  	}
   336  
   337  	if p.conn.isDebugserver {
   338  		// There are multiple problems with the 'g'/'G' commands on debugserver.
   339  		// On version 902 it used to crash the server completely (https://bugs.llvm.org/show_bug.cgi?id=36968),
   340  		// on arm64 it results in E74 being returned (https://bugs.llvm.org/show_bug.cgi?id=50169)
   341  		// and on systems where AVX-512 is used it returns the floating point
   342  		// registers scrambled and sometimes causes the mask registers to be
   343  		// zeroed out (https://github.com/go-delve/delve/pull/2498).
   344  		// All of these bugs stem from the fact that the main consumer of
   345  		// debugserver, lldb, never uses 'g' or 'G' which would make Delve the
   346  		// sole tester of those codepaths.
   347  		// Therefore we disable it here. The associated code is kept around to be
   348  		// used with Mozilla RR.
   349  		p.gcmdok = false
   350  	}
   351  
   352  	tgt, err := p.initialize(path, debugInfoDirs, stopReason)
   353  	if err != nil {
   354  		return nil, err
   355  	}
   356  
   357  	return tgt, nil
   358  }
   359  
   360  func (p *gdbProcess) SupportsBPF() bool {
   361  	return false
   362  }
   363  
   364  func (dbp *gdbProcess) GetBufferedTracepoints() []ebpf.RawUProbeParams {
   365  	return nil
   366  }
   367  
   368  func (dbp *gdbProcess) SetUProbe(fnName string, goidOffset int64, args []ebpf.UProbeArgMap) error {
   369  	panic("not implemented")
   370  }
   371  
   372  // unusedPort returns an unused tcp port
   373  // This is a hack and subject to a race condition with other running
   374  // programs, but most (all?) OS will cycle through all ephemeral ports
   375  // before reassigning one port they just assigned, unless there's heavy
   376  // churn in the ephemeral range this should work.
   377  func unusedPort() string {
   378  	listener, err := net.Listen("tcp", "127.0.0.1:0")
   379  	if err != nil {
   380  		return ":8081"
   381  	}
   382  	port := listener.Addr().(*net.TCPAddr).Port
   383  	listener.Close()
   384  	return fmt.Sprintf(":%d", port)
   385  }
   386  
   387  // getDebugServerAbsolutePath returns a string of the absolute path to the debugserver binary IFF it is
   388  // found in the system path ($PATH), the Xcode bundle or the standalone CLT location.
   389  func getDebugServerAbsolutePath() string {
   390  	if path := os.Getenv(debugServerEnvVar); path != "" {
   391  		return path
   392  	}
   393  	for _, debugServerPath := range debugserverExecutablePaths {
   394  		if debugServerPath == "" {
   395  			continue
   396  		}
   397  		if _, err := exec.LookPath(debugServerPath); err == nil {
   398  			return debugServerPath
   399  		}
   400  	}
   401  	return ""
   402  }
   403  
   404  func canUnmaskSignals(debugServerExecutable string) bool {
   405  	checkCanUnmaskSignalsOnce.Do(func() {
   406  		buf, _ := exec.Command(debugServerExecutable, "--unmask-signals").CombinedOutput()
   407  		canUnmaskSignalsCached = !strings.Contains(string(buf), "unrecognized option")
   408  	})
   409  	return canUnmaskSignalsCached
   410  }
   411  
   412  // commandLogger is a wrapper around the exec.Command() function to log the arguments prior to
   413  // starting the process
   414  func commandLogger(binary string, arguments ...string) *exec.Cmd {
   415  	logflags.GdbWireLogger().Debugf("executing %s %v", binary, arguments)
   416  	return exec.Command(binary, arguments...)
   417  }
   418  
   419  // ErrUnsupportedOS is returned when trying to use the lldb backend on Windows.
   420  var ErrUnsupportedOS = errors.New("lldb backend not supported on Windows")
   421  
   422  func getLdEnvVars() []string {
   423  	var result []string
   424  
   425  	environ := os.Environ()
   426  	for i := 0; i < len(environ); i++ {
   427  		if strings.HasPrefix(environ[i], "LD_") ||
   428  			strings.HasPrefix(environ[i], "DYLD_") {
   429  			result = append(result, "-e", environ[i])
   430  		}
   431  	}
   432  
   433  	return result
   434  }
   435  
   436  // LLDBLaunch starts an instance of lldb-server and connects to it, asking
   437  // it to launch the specified target program with the specified arguments
   438  // (cmd) on the specified directory wd.
   439  func LLDBLaunch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs []string, tty string, redirects [3]string) (*proc.Target, error) {
   440  	if runtime.GOOS == "windows" {
   441  		return nil, ErrUnsupportedOS
   442  	}
   443  	if err := macutil.CheckRosetta(); err != nil {
   444  		return nil, err
   445  	}
   446  
   447  	foreground := flags&proc.LaunchForeground != 0
   448  
   449  	var (
   450  		isDebugserver bool
   451  		listener      net.Listener
   452  		port          string
   453  		process       *exec.Cmd
   454  		err           error
   455  		hasRedirects  bool
   456  	)
   457  
   458  	if debugserverExecutable := getDebugServerAbsolutePath(); debugserverExecutable != "" {
   459  		listener, err = net.Listen("tcp", "127.0.0.1:0")
   460  		if err != nil {
   461  			return nil, err
   462  		}
   463  		ldEnvVars := getLdEnvVars()
   464  		args := make([]string, 0, len(cmd)+4+len(ldEnvVars))
   465  		args = append(args, ldEnvVars...)
   466  
   467  		if tty != "" {
   468  			args = append(args, "--stdio-path", tty)
   469  		} else {
   470  			found := [3]bool{}
   471  			names := [3]string{"stdin", "stdout", "stderr"}
   472  			for i := range redirects {
   473  				if redirects[i] != "" {
   474  					found[i] = true
   475  					hasRedirects = true
   476  					args = append(args, fmt.Sprintf("--%s-path", names[i]), redirects[i])
   477  				}
   478  			}
   479  
   480  			if foreground || hasRedirects {
   481  				for i := range found {
   482  					if !found[i] {
   483  						args = append(args, fmt.Sprintf("--%s-path", names[i]), "/dev/"+names[i])
   484  					}
   485  				}
   486  			}
   487  		}
   488  
   489  		if logflags.LLDBServerOutput() {
   490  			args = append(args, "-g", "-l", "stdout")
   491  		}
   492  		if flags&proc.LaunchDisableASLR != 0 {
   493  			args = append(args, "-D")
   494  		}
   495  		if canUnmaskSignals(debugserverExecutable) {
   496  			args = append(args, "--unmask-signals")
   497  		}
   498  		args = append(args, "-F", "-R", fmt.Sprintf("127.0.0.1:%d", listener.Addr().(*net.TCPAddr).Port), "--")
   499  		args = append(args, cmd...)
   500  
   501  		isDebugserver = true
   502  
   503  		process = commandLogger(debugserverExecutable, args...)
   504  	} else {
   505  		if _, err = exec.LookPath("lldb-server"); err != nil {
   506  			return nil, &ErrBackendUnavailable{}
   507  		}
   508  		port = unusedPort()
   509  		args := make([]string, 0, len(cmd)+3)
   510  		args = append(args, "gdbserver", port, "--")
   511  		args = append(args, cmd...)
   512  
   513  		process = commandLogger("lldb-server", args...)
   514  	}
   515  
   516  	if logflags.LLDBServerOutput() || logflags.GdbWire() || foreground || hasRedirects {
   517  		process.Stdout = os.Stdout
   518  		process.Stderr = os.Stderr
   519  	}
   520  	if foreground || hasRedirects {
   521  		if isatty.IsTerminal(os.Stdin.Fd()) {
   522  			foregroundSignalsIgnore()
   523  		}
   524  		process.Stdin = os.Stdin
   525  	}
   526  	if wd != "" {
   527  		process.Dir = wd
   528  	}
   529  
   530  	if isatty.IsTerminal(os.Stdin.Fd()) {
   531  		process.SysProcAttr = sysProcAttr(foreground)
   532  	}
   533  
   534  	if runtime.GOOS == "darwin" {
   535  		process.Env = proc.DisableAsyncPreemptEnv()
   536  	}
   537  
   538  	if err = process.Start(); err != nil {
   539  		return nil, err
   540  	}
   541  
   542  	p := newProcess(process.Process)
   543  	p.conn.isDebugserver = isDebugserver
   544  
   545  	var tgt *proc.Target
   546  	if listener != nil {
   547  		tgt, err = p.Listen(listener, cmd[0], 0, debugInfoDirs, proc.StopLaunched)
   548  	} else {
   549  		tgt, err = p.Dial(port, cmd[0], 0, debugInfoDirs, proc.StopLaunched)
   550  	}
   551  	return tgt, err
   552  }
   553  
   554  // LLDBAttach starts an instance of lldb-server and connects to it, asking
   555  // it to attach to the specified pid.
   556  // Path is path to the target's executable, path only needs to be specified
   557  // for some stubs that do not provide an automated way of determining it
   558  // (for example debugserver).
   559  func LLDBAttach(pid int, path string, debugInfoDirs []string) (*proc.Target, error) {
   560  	if runtime.GOOS == "windows" {
   561  		return nil, ErrUnsupportedOS
   562  	}
   563  	if err := macutil.CheckRosetta(); err != nil {
   564  		return nil, err
   565  	}
   566  
   567  	var (
   568  		isDebugserver bool
   569  		process       *exec.Cmd
   570  		listener      net.Listener
   571  		port          string
   572  		err           error
   573  	)
   574  	if debugserverExecutable := getDebugServerAbsolutePath(); debugserverExecutable != "" {
   575  		isDebugserver = true
   576  		listener, err = net.Listen("tcp", "127.0.0.1:0")
   577  		if err != nil {
   578  			return nil, err
   579  		}
   580  		args := []string{"-R", fmt.Sprintf("127.0.0.1:%d", listener.Addr().(*net.TCPAddr).Port), "--attach=" + strconv.Itoa(pid)}
   581  		if canUnmaskSignals(debugserverExecutable) {
   582  			args = append(args, "--unmask-signals")
   583  		}
   584  		process = commandLogger(debugserverExecutable, args...)
   585  	} else {
   586  		if _, err = exec.LookPath("lldb-server"); err != nil {
   587  			return nil, &ErrBackendUnavailable{}
   588  		}
   589  		port = unusedPort()
   590  		process = commandLogger("lldb-server", "gdbserver", "--attach", strconv.Itoa(pid), port)
   591  	}
   592  
   593  	process.Stdout = os.Stdout
   594  	process.Stderr = os.Stderr
   595  	process.SysProcAttr = sysProcAttr(false)
   596  
   597  	if err = process.Start(); err != nil {
   598  		return nil, err
   599  	}
   600  
   601  	p := newProcess(process.Process)
   602  	p.conn.isDebugserver = isDebugserver
   603  
   604  	var tgt *proc.Target
   605  	if listener != nil {
   606  		tgt, err = p.Listen(listener, path, pid, debugInfoDirs, proc.StopAttached)
   607  	} else {
   608  		tgt, err = p.Dial(port, path, pid, debugInfoDirs, proc.StopAttached)
   609  	}
   610  	return tgt, err
   611  }
   612  
   613  // EntryPoint will return the process entry point address, useful for
   614  // debugging PIEs.
   615  func (p *gdbProcess) EntryPoint() (uint64, error) {
   616  	var entryPoint uint64
   617  	if p.bi.GOOS == "darwin" && p.bi.Arch.Name == "arm64" {
   618  		// There is no auxv on darwin, however, we can get the location of the mach-o
   619  		// header from the debugserver by going through the loaded libraries, which includes
   620  		// the exe itself
   621  		images, _ := p.conn.getLoadedDynamicLibraries()
   622  		for _, image := range images {
   623  			if image.MachHeader.FileType == macho.TypeExec {
   624  				// This is a bit hacky. This is technically not the entrypoint,
   625  				// but rather we use the variable to points at the mach-o header,
   626  				// so we can get the offset in bininfo
   627  				entryPoint = image.LoadAddress
   628  				break
   629  			}
   630  		}
   631  	} else if auxv, err := p.conn.readAuxv(); err == nil {
   632  		// If we can't read the auxiliary vector it just means it's not supported
   633  		// by the OS or by the stub. If we are debugging a PIE and the entry point
   634  		// is needed proc.LoadBinaryInfo will complain about it.
   635  		entryPoint = linutil.EntryPointFromAuxv(auxv, p.BinInfo().Arch.PtrSize())
   636  	}
   637  
   638  	return entryPoint, nil
   639  }
   640  
   641  // initialize uses qProcessInfo to load the inferior's PID and
   642  // executable path. This command is not supported by all stubs and not all
   643  // stubs will report both the PID and executable path.
   644  func (p *gdbProcess) initialize(path string, debugInfoDirs []string, stopReason proc.StopReason) (*proc.Target, error) {
   645  	var err error
   646  	if path == "" {
   647  		// If we are attaching to a running process and the user didn't specify
   648  		// the executable file manually we must ask the stub for it.
   649  		// We support both qXfer:exec-file:read:: (the gdb way) and calling
   650  		// qProcessInfo (the lldb way).
   651  		// Unfortunately debugserver on macOS supports neither.
   652  		path, err = p.conn.readExecFile()
   653  		if err != nil {
   654  			if isProtocolErrorUnsupported(err) {
   655  				_, path, err = queryProcessInfo(p, p.Pid())
   656  				if err != nil {
   657  					p.conn.conn.Close()
   658  					return nil, err
   659  				}
   660  			} else {
   661  				p.conn.conn.Close()
   662  				return nil, fmt.Errorf("could not determine executable path: %v", err)
   663  			}
   664  		}
   665  	}
   666  
   667  	if path == "" {
   668  		// try using jGetLoadedDynamicLibrariesInfos which is the only way to do
   669  		// this supported on debugserver (but only on macOS >= 12.10)
   670  		images, _ := p.conn.getLoadedDynamicLibraries()
   671  		for _, image := range images {
   672  			if image.MachHeader.FileType == macho.TypeExec {
   673  				path = image.Pathname
   674  				break
   675  			}
   676  		}
   677  	}
   678  
   679  	err = p.updateThreadList(&threadUpdater{p: p})
   680  	if err != nil {
   681  		p.conn.conn.Close()
   682  		p.bi.Close()
   683  		return nil, err
   684  	}
   685  	p.clearThreadSignals()
   686  
   687  	if p.conn.pid <= 0 {
   688  		p.conn.pid, _, err = queryProcessInfo(p, 0)
   689  		if err != nil && !isProtocolErrorUnsupported(err) {
   690  			p.conn.conn.Close()
   691  			p.bi.Close()
   692  			return nil, err
   693  		}
   694  	}
   695  	tgt, err := proc.NewTarget(p, p.conn.pid, p.currentThread, proc.NewTargetConfig{
   696  		Path:                path,
   697  		DebugInfoDirs:       debugInfoDirs,
   698  		DisableAsyncPreempt: runtime.GOOS == "darwin",
   699  		StopReason:          stopReason,
   700  		CanDump:             runtime.GOOS == "darwin"})
   701  	if err != nil {
   702  		p.Detach(true)
   703  		return nil, err
   704  	}
   705  	return tgt, nil
   706  }
   707  
   708  func queryProcessInfo(p *gdbProcess, pid int) (int, string, error) {
   709  	pi, err := p.conn.queryProcessInfo(pid)
   710  	if err != nil {
   711  		return 0, "", err
   712  	}
   713  	if pid == 0 {
   714  		n, _ := strconv.ParseUint(pi["pid"], 16, 64)
   715  		pid = int(n)
   716  	}
   717  	return pid, pi["name"], nil
   718  }
   719  
   720  // BinInfo returns information on the binary.
   721  func (p *gdbProcess) BinInfo() *proc.BinaryInfo {
   722  	return p.bi
   723  }
   724  
   725  // Recorded returns whether or not we are debugging
   726  // a recorded "traced" program.
   727  func (p *gdbProcess) Recorded() (bool, string) {
   728  	return p.tracedir != "", p.tracedir
   729  }
   730  
   731  // Pid returns the process ID.
   732  func (p *gdbProcess) Pid() int {
   733  	return int(p.conn.pid)
   734  }
   735  
   736  // Valid returns true if we are not detached
   737  // and the process has not exited.
   738  func (p *gdbProcess) Valid() (bool, error) {
   739  	if p.detached {
   740  		return false, proc.ErrProcessDetached
   741  	}
   742  	if p.exited {
   743  		return false, proc.ErrProcessExited{Pid: p.Pid()}
   744  	}
   745  	if p.almostExited && p.conn.direction == proc.Forward {
   746  		return false, proc.ErrProcessExited{Pid: p.Pid()}
   747  	}
   748  	return true, nil
   749  }
   750  
   751  // FindThread returns the thread with the given ID.
   752  func (p *gdbProcess) FindThread(threadID int) (proc.Thread, bool) {
   753  	thread, ok := p.threads[threadID]
   754  	return thread, ok
   755  }
   756  
   757  // ThreadList returns all threads in the process.
   758  func (p *gdbProcess) ThreadList() []proc.Thread {
   759  	r := make([]proc.Thread, 0, len(p.threads))
   760  	for _, thread := range p.threads {
   761  		r = append(r, thread)
   762  	}
   763  	return r
   764  }
   765  
   766  // Memory returns the process memory.
   767  func (p *gdbProcess) Memory() proc.MemoryReadWriter {
   768  	return p
   769  }
   770  
   771  const (
   772  	interruptSignal  = 0x2
   773  	breakpointSignal = 0x5
   774  	faultSignal      = 0xb
   775  	childSignal      = 0x11
   776  	stopSignal       = 0x13
   777  
   778  	_SIGILL  = 0x4
   779  	_SIGFPE  = 0x8
   780  	_SIGKILL = 0x9
   781  
   782  	debugServerTargetExcBadAccess      = 0x91
   783  	debugServerTargetExcBadInstruction = 0x92
   784  	debugServerTargetExcArithmetic     = 0x93
   785  	debugServerTargetExcEmulation      = 0x94
   786  	debugServerTargetExcSoftware       = 0x95
   787  	debugServerTargetExcBreakpoint     = 0x96
   788  )
   789  
   790  // ContinueOnce will continue execution of the process until
   791  // a breakpoint is hit or signal is received.
   792  func (p *gdbProcess) ContinueOnce(cctx *proc.ContinueOnceContext) (proc.Thread, proc.StopReason, error) {
   793  	if p.exited {
   794  		return nil, proc.StopExited, proc.ErrProcessExited{Pid: p.conn.pid}
   795  	}
   796  	if p.almostExited {
   797  		if p.conn.direction == proc.Forward {
   798  			return nil, proc.StopExited, proc.ErrProcessExited{Pid: p.conn.pid}
   799  		}
   800  		p.almostExited = false
   801  	}
   802  
   803  	if p.conn.direction == proc.Forward {
   804  		// step threads stopped at any breakpoint over their breakpoint
   805  		for _, thread := range p.threads {
   806  			if thread.CurrentBreakpoint.Breakpoint != nil {
   807  				if err := thread.StepInstruction(); err != nil {
   808  					return nil, proc.StopUnknown, err
   809  				}
   810  			}
   811  		}
   812  	}
   813  
   814  	for _, th := range p.threads {
   815  		th.clearBreakpointState()
   816  	}
   817  
   818  	p.setCtrlC(cctx, false)
   819  
   820  	// resume all threads
   821  	var threadID string
   822  	var trapthread *gdbThread
   823  	var tu = threadUpdater{p: p}
   824  	var atstart bool
   825  continueLoop:
   826  	for {
   827  		tu.Reset()
   828  		sp, err := p.conn.resume(cctx, p.threads, &tu)
   829  		threadID = sp.threadID
   830  		if err != nil {
   831  			if _, exited := err.(proc.ErrProcessExited); exited {
   832  				p.exited = true
   833  				return nil, proc.StopExited, err
   834  			}
   835  			return nil, proc.StopUnknown, err
   836  		}
   837  
   838  		// For stubs that support qThreadStopInfo updateThreadList will
   839  		// find out the reason why each thread stopped.
   840  		// NOTE: because debugserver will sometimes send two stop packets after a
   841  		// continue it is important that this is the very first thing we do after
   842  		// resume(). See comment in threadStopInfo for an explanation.
   843  		p.updateThreadList(&tu)
   844  
   845  		trapthread = p.findThreadByStrID(threadID)
   846  		if trapthread != nil && !p.threadStopInfo {
   847  			// For stubs that do not support qThreadStopInfo we manually set the
   848  			// reason the thread returned by resume() stopped.
   849  			trapthread.sig = sp.sig
   850  			trapthread.watchAddr = sp.watchAddr
   851  		}
   852  
   853  		var shouldStop, shouldExitErr bool
   854  		trapthread, atstart, shouldStop, shouldExitErr = p.handleThreadSignals(cctx, trapthread)
   855  		if shouldExitErr {
   856  			p.almostExited = true
   857  			return nil, proc.StopExited, proc.ErrProcessExited{Pid: p.conn.pid}
   858  		}
   859  		if shouldStop {
   860  			break continueLoop
   861  		}
   862  	}
   863  
   864  	p.clearThreadRegisters()
   865  
   866  	stopReason := proc.StopUnknown
   867  	if atstart {
   868  		stopReason = proc.StopLaunched
   869  	}
   870  
   871  	if p.BinInfo().GOOS == "linux" {
   872  		if err := linutil.ElfUpdateSharedObjects(p); err != nil {
   873  			return nil, stopReason, err
   874  		}
   875  	}
   876  
   877  	if err := p.setCurrentBreakpoints(); err != nil {
   878  		return nil, stopReason, err
   879  	}
   880  
   881  	if trapthread == nil {
   882  		return nil, stopReason, fmt.Errorf("could not find thread %s", threadID)
   883  	}
   884  
   885  	err := machTargetExcToError(trapthread.sig)
   886  	if err != nil {
   887  		// the signals that are reported here can not be propagated back to the target process.
   888  		trapthread.sig = 0
   889  	}
   890  	p.currentThread = trapthread
   891  	return trapthread, stopReason, err
   892  }
   893  
   894  func (p *gdbProcess) findThreadByStrID(threadID string) *gdbThread {
   895  	for _, thread := range p.threads {
   896  		if thread.strID == threadID {
   897  			return thread
   898  		}
   899  	}
   900  	return nil
   901  }
   902  
   903  // handleThreadSignals looks at the signals received by each thread and
   904  // decides which ones to mask and which ones to propagate back to the target
   905  // and returns true if we should stop execution in response to one of the
   906  // signals and return control to the user.
   907  // Adjusts trapthread to a thread that we actually want to stop at.
   908  func (p *gdbProcess) handleThreadSignals(cctx *proc.ContinueOnceContext, trapthread *gdbThread) (trapthreadOut *gdbThread, atstart, shouldStop, shouldExitErr bool) {
   909  	var trapthreadCandidate *gdbThread
   910  
   911  	for _, th := range p.threads {
   912  		isStopSignal := false
   913  
   914  		// 0x5 is always a breakpoint, a manual stop either manifests as 0x13
   915  		// (lldb), 0x11 (debugserver) or 0x2 (gdbserver).
   916  		// Since 0x2 could also be produced by the user
   917  		// pressing ^C (in which case it should be passed to the inferior) we need
   918  		// the ctrlC flag to know that we are the originators.
   919  		switch th.sig {
   920  		case interruptSignal: // interrupt
   921  			if p.getCtrlC(cctx) {
   922  				isStopSignal = true
   923  			}
   924  		case breakpointSignal: // breakpoint
   925  			isStopSignal = true
   926  		case childSignal: // stop on debugserver but SIGCHLD on lldb-server/linux
   927  			if p.conn.isDebugserver {
   928  				isStopSignal = true
   929  			}
   930  		case stopSignal: // stop
   931  			isStopSignal = true
   932  
   933  		case _SIGKILL:
   934  			if p.tracedir != "" {
   935  				// RR will send a synthetic SIGKILL packet right before the program
   936  				// exits, even if the program exited normally.
   937  				// Treat this signal as if the process had exited because right after
   938  				// this it is still possible to set breakpoints and rewind the process.
   939  				shouldExitErr = true
   940  				isStopSignal = true
   941  			}
   942  
   943  		// The following are fake BSD-style signals sent by debugserver
   944  		// Unfortunately debugserver can not convert them into signals for the
   945  		// process so we must stop here.
   946  		case debugServerTargetExcBadAccess, debugServerTargetExcBadInstruction, debugServerTargetExcArithmetic, debugServerTargetExcEmulation, debugServerTargetExcSoftware, debugServerTargetExcBreakpoint:
   947  
   948  			trapthreadCandidate = th
   949  			shouldStop = true
   950  
   951  		// Signal 0 is returned by rr when it reaches the start of the process
   952  		// in backward continue mode.
   953  		case 0:
   954  			if p.conn.direction == proc.Backward && th == trapthread {
   955  				isStopSignal = true
   956  				atstart = true
   957  			}
   958  
   959  		default:
   960  			// any other signal is always propagated to inferior
   961  		}
   962  
   963  		if isStopSignal {
   964  			if trapthreadCandidate == nil {
   965  				trapthreadCandidate = th
   966  			}
   967  			th.sig = 0
   968  			shouldStop = true
   969  		}
   970  	}
   971  
   972  	if (trapthread == nil || trapthread.sig != 0) && trapthreadCandidate != nil {
   973  		// proc.Continue wants us to return one of the threads that we should stop
   974  		// at, if the thread returned by vCont received a signal that we want to
   975  		// propagate back to the target thread but there were also other threads
   976  		// that we wish to stop at we should pick one of those.
   977  		trapthread = trapthreadCandidate
   978  	}
   979  
   980  	if p.getCtrlC(cctx) || cctx.GetManualStopRequested() {
   981  		// If we request an interrupt and a target thread simultaneously receives
   982  		// an unrelated singal debugserver will discard our interrupt request and
   983  		// report the signal but we should stop anyway.
   984  		shouldStop = true
   985  	}
   986  
   987  	return trapthread, atstart, shouldStop, shouldExitErr
   988  }
   989  
   990  // RequestManualStop will attempt to stop the process
   991  // without a breakpoint or signal having been received.
   992  func (p *gdbProcess) RequestManualStop(cctx *proc.ContinueOnceContext) error {
   993  	if !p.conn.running {
   994  		return nil
   995  	}
   996  	p.ctrlC = true
   997  	return p.conn.sendCtrlC()
   998  }
   999  
  1000  func (p *gdbProcess) setCtrlC(cctx *proc.ContinueOnceContext, v bool) {
  1001  	cctx.StopMu.Lock()
  1002  	p.ctrlC = v
  1003  	cctx.StopMu.Unlock()
  1004  }
  1005  
  1006  func (p *gdbProcess) getCtrlC(cctx *proc.ContinueOnceContext) bool {
  1007  	cctx.StopMu.Lock()
  1008  	defer cctx.StopMu.Unlock()
  1009  	return p.ctrlC
  1010  }
  1011  
  1012  // Detach will detach from the target process,
  1013  // if 'kill' is true it will also kill the process.
  1014  func (p *gdbProcess) Detach(kill bool) error {
  1015  	if kill && !p.exited {
  1016  		err := p.conn.kill()
  1017  		if err != nil {
  1018  			if _, exited := err.(proc.ErrProcessExited); !exited {
  1019  				return err
  1020  			}
  1021  			p.exited = true
  1022  		}
  1023  	}
  1024  	if !p.exited {
  1025  		if err := p.conn.detach(); err != nil {
  1026  			return err
  1027  		}
  1028  	}
  1029  	if p.process != nil {
  1030  		p.process.Kill()
  1031  		<-p.waitChan
  1032  		p.process = nil
  1033  	}
  1034  	p.detached = true
  1035  	if p.onDetach != nil {
  1036  		p.onDetach()
  1037  	}
  1038  	return p.bi.Close()
  1039  }
  1040  
  1041  // Restart will restart the process from the given position.
  1042  func (p *gdbProcess) Restart(cctx *proc.ContinueOnceContext, pos string) (proc.Thread, error) {
  1043  	if p.tracedir == "" {
  1044  		return nil, proc.ErrNotRecorded
  1045  	}
  1046  
  1047  	// Is this a checkpoint on a server using local checkpoints?
  1048  	if len(pos) > 1 && pos[:1] == "c" && p.conn.isUndoServer {
  1049  		cpid, _ := strconv.Atoi(pos[1:])
  1050  		checkpoint, exists := p.localCheckpoints[cpid]
  1051  		if !exists {
  1052  			return nil, errors.New("Checkpoint not found")
  1053  		}
  1054  		pos = checkpoint.When
  1055  	}
  1056  
  1057  	p.exited = false
  1058  	p.almostExited = false
  1059  
  1060  	for _, th := range p.threads {
  1061  		th.clearBreakpointState()
  1062  	}
  1063  
  1064  	p.ctrlC = false
  1065  
  1066  	err := p.conn.restart(pos)
  1067  	if err != nil {
  1068  		return nil, err
  1069  	}
  1070  
  1071  	// for some reason we have to send a vCont;c after a vRun to make rr behave
  1072  	// properly, because that's what gdb does.
  1073  	if !p.conn.isUndoServer {
  1074  		_, err = p.conn.resume(cctx, nil, nil)
  1075  		if err != nil {
  1076  			return nil, err
  1077  		}
  1078  	}
  1079  
  1080  	err = p.updateThreadList(&threadUpdater{p: p})
  1081  	if err != nil {
  1082  		return nil, err
  1083  	}
  1084  	p.clearThreadSignals()
  1085  	p.clearThreadRegisters()
  1086  
  1087  	for _, bp := range p.breakpoints.M {
  1088  		p.WriteBreakpoint(bp)
  1089  	}
  1090  
  1091  	return p.currentThread, p.setCurrentBreakpoints()
  1092  }
  1093  
  1094  // When executes the 'when' command for the Mozilla RR/Undo backends.
  1095  // This command will return rr's internal event number.
  1096  func (p *gdbProcess) When() (string, error) {
  1097  	if p.tracedir == "" {
  1098  		return "", proc.ErrNotRecorded
  1099  	}
  1100  	result := ""
  1101  	if p.conn.isUndoServer {
  1102  		extent, err := p.conn.undoCmd("get_time")
  1103  		if err != nil {
  1104  			return "", err
  1105  		}
  1106  		result = extent
  1107  	} else {
  1108  		event, err := p.conn.qRRCmd("when")
  1109  		if err != nil {
  1110  			return "", err
  1111  		}
  1112  		result = strings.TrimSpace(event)
  1113  	}
  1114  	return result, nil
  1115  }
  1116  
  1117  const (
  1118  	checkpointPrefix = "Checkpoint "
  1119  )
  1120  
  1121  // Checkpoint creates a checkpoint from which you can restart the program.
  1122  func (p *gdbProcess) Checkpoint(where string) (int, error) {
  1123  	if p.tracedir == "" {
  1124  		return -1, proc.ErrNotRecorded
  1125  	}
  1126  
  1127  	// Handle locally managed checkpoints first
  1128  	if p.conn.isUndoServer {
  1129  		cpid := p.localCheckpointLastId
  1130  		p.localCheckpointLastId++
  1131  		when, err := p.conn.undoCmd("get_time")
  1132  		if err != nil {
  1133  			return -1, err
  1134  		}
  1135  		p.localCheckpoints[cpid] = proc.Checkpoint{ID: cpid, When: when, Where: where}
  1136  		return cpid, nil
  1137  	}
  1138  
  1139  	resp, err := p.conn.qRRCmd("checkpoint", where)
  1140  	if err != nil {
  1141  		return -1, err
  1142  	}
  1143  
  1144  	if !strings.HasPrefix(resp, checkpointPrefix) {
  1145  		return -1, fmt.Errorf("can not parse checkpoint response %q", resp)
  1146  	}
  1147  
  1148  	idstr := resp[len(checkpointPrefix):]
  1149  	space := strings.Index(idstr, " ")
  1150  	if space < 0 {
  1151  		return -1, fmt.Errorf("can not parse checkpoint response %q", resp)
  1152  	}
  1153  	idstr = idstr[:space]
  1154  
  1155  	cpid, err := strconv.Atoi(idstr)
  1156  	if err != nil {
  1157  		return -1, err
  1158  	}
  1159  	return cpid, nil
  1160  }
  1161  
  1162  // Checkpoints returns a list of all checkpoints set.
  1163  func (p *gdbProcess) Checkpoints() ([]proc.Checkpoint, error) {
  1164  	if p.tracedir == "" {
  1165  		return nil, proc.ErrNotRecorded
  1166  	}
  1167  
  1168  	// Handle locally managed checkpoints first
  1169  	if p.conn.isUndoServer {
  1170  		r := make([]proc.Checkpoint, 0, len(p.localCheckpoints))
  1171  		for _, cp := range p.localCheckpoints {
  1172  			r = append(r, cp)
  1173  		}
  1174  		return r, nil
  1175  	}
  1176  
  1177  	resp, err := p.conn.qRRCmd("info checkpoints")
  1178  	if err != nil {
  1179  		return nil, err
  1180  	}
  1181  	lines := strings.Split(resp, "\n")
  1182  	r := make([]proc.Checkpoint, 0, len(lines)-1)
  1183  	for _, line := range lines[1:] {
  1184  		if line == "" {
  1185  			continue
  1186  		}
  1187  		fields := strings.Split(line, "\t")
  1188  		if len(fields) != 3 {
  1189  			return nil, fmt.Errorf("can not parse \"info checkpoints\" output line %q", line)
  1190  		}
  1191  		cpid, err := strconv.Atoi(fields[0])
  1192  		if err != nil {
  1193  			return nil, fmt.Errorf("can not parse \"info checkpoints\" output line %q: %v", line, err)
  1194  		}
  1195  		r = append(r, proc.Checkpoint{ID: cpid, When: fields[1], Where: fields[2]})
  1196  	}
  1197  	return r, nil
  1198  }
  1199  
  1200  const deleteCheckpointPrefix = "Deleted checkpoint "
  1201  
  1202  // ClearCheckpoint clears the checkpoint for the given ID.
  1203  func (p *gdbProcess) ClearCheckpoint(id int) error {
  1204  	if p.tracedir == "" {
  1205  		return proc.ErrNotRecorded
  1206  	}
  1207  
  1208  	// Handle locally managed checkpoints first
  1209  	if p.conn.isUndoServer {
  1210  		delete(p.localCheckpoints, id)
  1211  		// We don't care if it didn't exist
  1212  		return nil
  1213  	}
  1214  
  1215  	resp, err := p.conn.qRRCmd("delete checkpoint", strconv.Itoa(id))
  1216  	if err != nil {
  1217  		return err
  1218  	}
  1219  	if !strings.HasPrefix(resp, deleteCheckpointPrefix) {
  1220  		return errors.New(resp)
  1221  	}
  1222  	return nil
  1223  }
  1224  
  1225  // ChangeDirection sets whether to run the program forwards or in reverse execution.
  1226  func (p *gdbProcess) ChangeDirection(dir proc.Direction) error {
  1227  	if p.tracedir == "" {
  1228  		if dir != proc.Forward {
  1229  			return proc.ErrNotRecorded
  1230  		}
  1231  		return nil
  1232  	}
  1233  	if p.conn.conn == nil {
  1234  		return proc.ErrProcessExited{Pid: p.conn.pid}
  1235  	}
  1236  	if p.conn.direction == dir {
  1237  		return nil
  1238  	}
  1239  	if p.Breakpoints().HasSteppingBreakpoints() {
  1240  		return ErrDirChange
  1241  	}
  1242  	p.conn.direction = dir
  1243  	return nil
  1244  }
  1245  
  1246  // StartCallInjection notifies the backend that we are about to inject a function call.
  1247  func (p *gdbProcess) StartCallInjection() (func(), error) {
  1248  	if p.tracedir == "" {
  1249  		return func() {}, nil
  1250  	}
  1251  	if p.conn.conn == nil {
  1252  		return nil, proc.ErrProcessExited{Pid: p.conn.pid}
  1253  	}
  1254  	if p.conn.direction != proc.Forward {
  1255  		return nil, ErrStartCallInjectionBackwards
  1256  	}
  1257  
  1258  	if p.conn.isUndoServer {
  1259  		_, err := p.conn.undoCmd("set_debuggee_volatile", "1")
  1260  		if err != nil {
  1261  			return nil, err
  1262  		}
  1263  		return func() {
  1264  			_, _ = p.conn.undoCmd("set_debuggee_volatile", "0")
  1265  		}, nil
  1266  	}
  1267  
  1268  	// Normally it's impossible to inject function calls in a recorded target
  1269  	// because the sequence of instructions that the target will execute is
  1270  	// predetermined.
  1271  	// RR however allows this in a "diversion". When a diversion is started rr
  1272  	// takes the current state of the process and runs it forward as a normal
  1273  	// process, not following the recording.
  1274  	// The gdb serial protocol does not have a way to start a diversion and gdb
  1275  	// (the main frontend of rr) does not know how to do it. Instead a
  1276  	// diversion is started by reading siginfo, because that's the first
  1277  	// request gdb does when starting a function call injection.
  1278  
  1279  	_, err := p.conn.qXfer("siginfo", "", true)
  1280  	if err != nil {
  1281  		return nil, err
  1282  	}
  1283  
  1284  	return func() {
  1285  		_ = p.conn.qXferWrite("siginfo", "") // rr always returns an error for qXfer:siginfo:write... even though it works
  1286  	}, nil
  1287  }
  1288  
  1289  // GetDirection returns the current direction of execution.
  1290  func (p *gdbProcess) GetDirection() proc.Direction {
  1291  	return p.conn.direction
  1292  }
  1293  
  1294  // Breakpoints returns the list of breakpoints currently set.
  1295  func (p *gdbProcess) Breakpoints() *proc.BreakpointMap {
  1296  	return &p.breakpoints
  1297  }
  1298  
  1299  // FindBreakpoint returns the breakpoint at the given address.
  1300  func (p *gdbProcess) FindBreakpoint(pc uint64) (*proc.Breakpoint, bool) {
  1301  	// Directly use addr to lookup breakpoint.
  1302  	if bp, ok := p.breakpoints.M[pc]; ok {
  1303  		return bp, true
  1304  	}
  1305  	return nil, false
  1306  }
  1307  
  1308  func watchTypeToBreakpointType(wtype proc.WatchType) breakpointType {
  1309  	switch {
  1310  	case wtype.Read() && wtype.Write():
  1311  		return accessWatchpoint
  1312  	case wtype.Write():
  1313  		return writeWatchpoint
  1314  	case wtype.Read():
  1315  		return readWatchpoint
  1316  	default:
  1317  		return swBreakpoint
  1318  	}
  1319  }
  1320  
  1321  func (p *gdbProcess) WriteBreakpoint(bp *proc.Breakpoint) error {
  1322  	kind := p.breakpointKind
  1323  	if bp.WatchType != 0 {
  1324  		kind = bp.WatchType.Size()
  1325  	}
  1326  	return p.conn.setBreakpoint(bp.Addr, watchTypeToBreakpointType(bp.WatchType), kind)
  1327  }
  1328  
  1329  func (p *gdbProcess) EraseBreakpoint(bp *proc.Breakpoint) error {
  1330  	kind := p.breakpointKind
  1331  	if bp.WatchType != 0 {
  1332  		kind = bp.WatchType.Size()
  1333  	}
  1334  	return p.conn.clearBreakpoint(bp.Addr, watchTypeToBreakpointType(bp.WatchType), kind)
  1335  }
  1336  
  1337  type threadUpdater struct {
  1338  	p    *gdbProcess
  1339  	seen map[int]bool
  1340  	done bool
  1341  }
  1342  
  1343  func (tu *threadUpdater) Reset() {
  1344  	tu.done = false
  1345  	tu.seen = nil
  1346  }
  1347  
  1348  func (tu *threadUpdater) Add(threads []string) error {
  1349  	if tu.done {
  1350  		panic("threadUpdater: Add after Finish")
  1351  	}
  1352  	if tu.seen == nil {
  1353  		tu.seen = map[int]bool{}
  1354  	}
  1355  	for _, threadID := range threads {
  1356  		b := threadID
  1357  		if period := strings.Index(b, "."); period >= 0 {
  1358  			b = b[period+1:]
  1359  		}
  1360  		n, err := strconv.ParseUint(b, 16, 32)
  1361  		if err != nil {
  1362  			return &GdbMalformedThreadIDError{threadID}
  1363  		}
  1364  		tid := int(n)
  1365  		tu.seen[tid] = true
  1366  		if _, found := tu.p.threads[tid]; !found {
  1367  			tu.p.threads[tid] = &gdbThread{ID: tid, strID: threadID, p: tu.p}
  1368  		}
  1369  	}
  1370  	return nil
  1371  }
  1372  
  1373  func (tu *threadUpdater) Finish() {
  1374  	tu.done = true
  1375  	for threadID := range tu.p.threads {
  1376  		_, threadSeen := tu.seen[threadID]
  1377  		if threadSeen {
  1378  			continue
  1379  		}
  1380  		delete(tu.p.threads, threadID)
  1381  		if tu.p.currentThread != nil && tu.p.currentThread.ID == threadID {
  1382  			tu.p.currentThread = nil
  1383  		}
  1384  	}
  1385  	if tu.p.currentThread != nil {
  1386  		if _, exists := tu.p.threads[tu.p.currentThread.ID]; !exists {
  1387  			// current thread was removed
  1388  			tu.p.currentThread = nil
  1389  		}
  1390  	}
  1391  	if tu.p.currentThread == nil {
  1392  		for _, thread := range tu.p.threads {
  1393  			tu.p.currentThread = thread
  1394  			break
  1395  		}
  1396  	}
  1397  }
  1398  
  1399  // updateThreadList retrieves the list of inferior threads from
  1400  // the stub and passes it to threadUpdater.
  1401  // Some stubs will return the list of running threads in the stop packet, if
  1402  // this happens the threadUpdater will know that we have already updated the
  1403  // thread list and the first step of updateThreadList will be skipped.
  1404  func (p *gdbProcess) updateThreadList(tu *threadUpdater) error {
  1405  	if !tu.done {
  1406  		first := true
  1407  		for {
  1408  			threads, err := p.conn.queryThreads(first)
  1409  			if err != nil {
  1410  				return err
  1411  			}
  1412  			if len(threads) == 0 {
  1413  				break
  1414  			}
  1415  			first = false
  1416  			if err := tu.Add(threads); err != nil {
  1417  				return err
  1418  			}
  1419  		}
  1420  
  1421  		tu.Finish()
  1422  	}
  1423  
  1424  	for _, th := range p.threads {
  1425  		if p.threadStopInfo {
  1426  			sp, err := p.conn.threadStopInfo(th.strID)
  1427  			if err != nil {
  1428  				if isProtocolErrorUnsupported(err) {
  1429  					p.threadStopInfo = false
  1430  					break
  1431  				}
  1432  				return err
  1433  			}
  1434  			th.setbp = (sp.reason == "breakpoint" || (sp.reason == "" && sp.sig == breakpointSignal) || (sp.watchAddr > 0))
  1435  			th.sig = sp.sig
  1436  			th.watchAddr = sp.watchAddr
  1437  		} else {
  1438  			th.sig = 0
  1439  			th.watchAddr = 0
  1440  		}
  1441  	}
  1442  
  1443  	return nil
  1444  }
  1445  
  1446  // clearThreadRegisters clears the memoized thread register state.
  1447  func (p *gdbProcess) clearThreadRegisters() {
  1448  	for _, thread := range p.threads {
  1449  		thread.regs.regs = nil
  1450  	}
  1451  }
  1452  
  1453  func (p *gdbProcess) clearThreadSignals() {
  1454  	for _, th := range p.threads {
  1455  		th.sig = 0
  1456  	}
  1457  }
  1458  
  1459  func (p *gdbProcess) setCurrentBreakpoints() error {
  1460  	if p.threadStopInfo {
  1461  		for _, th := range p.threads {
  1462  			if th.setbp {
  1463  				err := th.SetCurrentBreakpoint(true)
  1464  				if err != nil {
  1465  					return err
  1466  				}
  1467  			}
  1468  		}
  1469  	}
  1470  	if !p.threadStopInfo {
  1471  		for _, th := range p.threads {
  1472  			if th.CurrentBreakpoint.Breakpoint == nil {
  1473  				err := th.SetCurrentBreakpoint(true)
  1474  				if err != nil {
  1475  					return err
  1476  				}
  1477  			}
  1478  		}
  1479  	}
  1480  	return nil
  1481  }
  1482  
  1483  // ReadMemory will read into 'data' memory at the address provided.
  1484  func (p *gdbProcess) ReadMemory(data []byte, addr uint64) (n int, err error) {
  1485  	err = p.conn.readMemory(data, addr)
  1486  	if err != nil {
  1487  		return 0, err
  1488  	}
  1489  	return len(data), nil
  1490  }
  1491  
  1492  // WriteMemory will write into the memory at 'addr' the data provided.
  1493  func (p *gdbProcess) WriteMemory(addr uint64, data []byte) (written int, err error) {
  1494  	return p.conn.writeMemory(addr, data)
  1495  }
  1496  
  1497  func (t *gdbThread) ProcessMemory() proc.MemoryReadWriter {
  1498  	return t.p
  1499  }
  1500  
  1501  // Location returns the current location of this thread.
  1502  func (t *gdbThread) Location() (*proc.Location, error) {
  1503  	regs, err := t.Registers()
  1504  	if err != nil {
  1505  		return nil, err
  1506  	}
  1507  	if pcreg, ok := regs.(*gdbRegisters).regs[regs.(*gdbRegisters).regnames.PC]; !ok {
  1508  		t.p.conn.log.Errorf("thread %d could not find RIP register", t.ID)
  1509  	} else if len(pcreg.value) < t.p.bi.Arch.PtrSize() {
  1510  		t.p.conn.log.Errorf("thread %d bad length for RIP register: %d", t.ID, len(pcreg.value))
  1511  	}
  1512  	pc := regs.PC()
  1513  	f, l, fn := t.p.bi.PCToLine(pc)
  1514  	return &proc.Location{PC: pc, File: f, Line: l, Fn: fn}, nil
  1515  }
  1516  
  1517  // Breakpoint returns the current active breakpoint for this thread.
  1518  func (t *gdbThread) Breakpoint() *proc.BreakpointState {
  1519  	return &t.CurrentBreakpoint
  1520  }
  1521  
  1522  // ThreadID returns this threads ID.
  1523  func (t *gdbThread) ThreadID() int {
  1524  	return t.ID
  1525  }
  1526  
  1527  // Registers returns the CPU registers for this thread.
  1528  func (t *gdbThread) Registers() (proc.Registers, error) {
  1529  	if t.regs.regs == nil {
  1530  		if err := t.reloadRegisters(); err != nil {
  1531  			return nil, err
  1532  		}
  1533  	}
  1534  	return &t.regs, nil
  1535  }
  1536  
  1537  // RestoreRegisters will set the CPU registers the value of those provided.
  1538  func (t *gdbThread) RestoreRegisters(savedRegs proc.Registers) error {
  1539  	copy(t.regs.buf, savedRegs.(*gdbRegisters).buf)
  1540  	return t.writeRegisters()
  1541  }
  1542  
  1543  // BinInfo will return information on the binary being debugged.
  1544  func (t *gdbThread) BinInfo() *proc.BinaryInfo {
  1545  	return t.p.bi
  1546  }
  1547  
  1548  // Common returns common information across Process implementations.
  1549  func (t *gdbThread) Common() *proc.CommonThread {
  1550  	return &t.common
  1551  }
  1552  
  1553  // StepInstruction will step exactly 1 CPU instruction.
  1554  func (t *gdbThread) StepInstruction() error {
  1555  	pc := t.regs.PC()
  1556  	if bp, atbp := t.p.breakpoints.M[pc]; atbp && bp.WatchType == 0 {
  1557  		err := t.p.conn.clearBreakpoint(pc, swBreakpoint, t.p.breakpointKind)
  1558  		if err != nil {
  1559  			return err
  1560  		}
  1561  		defer t.p.conn.setBreakpoint(pc, swBreakpoint, t.p.breakpointKind)
  1562  	}
  1563  	// Reset thread registers so the next call to
  1564  	// Thread.Registers will not be cached.
  1565  	t.regs.regs = nil
  1566  	return t.p.conn.step(t, &threadUpdater{p: t.p}, false)
  1567  }
  1568  
  1569  // SoftExc returns true if this thread received a software exception during the last resume.
  1570  func (t *gdbThread) SoftExc() bool {
  1571  	return t.setbp
  1572  }
  1573  
  1574  // Blocked returns true if the thread is blocked in runtime or kernel code.
  1575  func (t *gdbThread) Blocked() bool {
  1576  	regs, err := t.Registers()
  1577  	if err != nil {
  1578  		return false
  1579  	}
  1580  	pc := regs.PC()
  1581  	f, ln, fn := t.BinInfo().PCToLine(pc)
  1582  	if fn == nil {
  1583  		if f == "" && ln == 0 {
  1584  			return true
  1585  		}
  1586  		return false
  1587  	}
  1588  	switch fn.Name {
  1589  	case "runtime.futex", "runtime.usleep", "runtime.clone":
  1590  		return true
  1591  	case "runtime.kevent":
  1592  		return true
  1593  	case "runtime.mach_semaphore_wait", "runtime.mach_semaphore_timedwait":
  1594  		return true
  1595  	default:
  1596  		return strings.HasPrefix(fn.Name, "syscall.Syscall") || strings.HasPrefix(fn.Name, "syscall.RawSyscall")
  1597  	}
  1598  }
  1599  
  1600  func (p *gdbProcess) MemoryMap() ([]proc.MemoryMapEntry, error) {
  1601  	r := []proc.MemoryMapEntry{}
  1602  	addr := uint64(0)
  1603  	for addr != ^uint64(0) {
  1604  		mri, err := p.conn.memoryRegionInfo(addr)
  1605  		if err != nil {
  1606  			return nil, err
  1607  		}
  1608  		if addr+mri.size <= addr {
  1609  			return nil, errors.New("qMemoryRegionInfo response wrapped around the address space or stuck")
  1610  		}
  1611  		if mri.permissions != "" {
  1612  			var mme proc.MemoryMapEntry
  1613  
  1614  			mme.Addr = addr
  1615  			mme.Size = mri.size
  1616  			mme.Read = strings.Contains(mri.permissions, "r")
  1617  			mme.Write = strings.Contains(mri.permissions, "w")
  1618  			mme.Exec = strings.Contains(mri.permissions, "x")
  1619  
  1620  			r = append(r, mme)
  1621  		}
  1622  		addr += mri.size
  1623  	}
  1624  	return r, nil
  1625  }
  1626  
  1627  func (p *gdbProcess) DumpProcessNotes(notes []elfwriter.Note, threadDone func()) (threadsDone bool, out []elfwriter.Note, err error) {
  1628  	return false, notes, nil
  1629  }
  1630  
  1631  func (regs *gdbRegisters) init(regsInfo []gdbRegisterInfo, arch *proc.Arch, regnames *gdbRegnames) {
  1632  	regs.arch = arch
  1633  	regs.regnames = regnames
  1634  	regs.regs = make(map[string]gdbRegister)
  1635  	regs.regsInfo = regsInfo
  1636  
  1637  	regsz := 0
  1638  	for _, reginfo := range regsInfo {
  1639  		if endoff := reginfo.Offset + (reginfo.Bitsize / 8); endoff > regsz {
  1640  			regsz = endoff
  1641  		}
  1642  	}
  1643  	regs.buf = make([]byte, regsz)
  1644  	for _, reginfo := range regsInfo {
  1645  		regs.regs[reginfo.Name] = regs.gdbRegisterNew(&reginfo)
  1646  	}
  1647  }
  1648  
  1649  func (regs *gdbRegisters) gdbRegisterNew(reginfo *gdbRegisterInfo) gdbRegister {
  1650  	return gdbRegister{regnum: reginfo.Regnum, value: regs.buf[reginfo.Offset : reginfo.Offset+reginfo.Bitsize/8], ignoreOnWrite: reginfo.ignoreOnWrite}
  1651  }
  1652  
  1653  // reloadRegisters loads the current value of the thread's registers.
  1654  // It will also load the address of the thread's G.
  1655  // Loading the address of G can be done in one of two ways reloadGAlloc, if
  1656  // the stub can allocate memory, or reloadGAtPC, if the stub can't.
  1657  func (t *gdbThread) reloadRegisters() error {
  1658  	if t.regs.regs == nil {
  1659  		t.regs.init(t.p.conn.regsInfo, t.p.bi.Arch, t.p.regnames)
  1660  	}
  1661  
  1662  	if t.p.gcmdok {
  1663  		if err := t.p.conn.readRegisters(t.strID, t.regs.buf); err != nil {
  1664  			gdberr, isProt := err.(*GdbProtocolError)
  1665  			if isProtocolErrorUnsupported(err) || (t.p.conn.isDebugserver && isProt && gdberr.code == "E74") {
  1666  				t.p.gcmdok = false
  1667  			} else {
  1668  				return err
  1669  			}
  1670  		}
  1671  	}
  1672  	if !t.p.gcmdok {
  1673  		for _, reginfo := range t.p.conn.regsInfo {
  1674  			if err := t.p.conn.readRegister(t.strID, reginfo.Regnum, t.regs.regs[reginfo.Name].value); err != nil {
  1675  				return err
  1676  			}
  1677  		}
  1678  	}
  1679  
  1680  	if t.p.bi.Arch.Name == "arm64" {
  1681  		// no need to play around with the GInstr on ARM64 because
  1682  		// the G addr is stored in a register
  1683  
  1684  		t.regs.gaddr = t.regs.byName("x28")
  1685  		t.regs.hasgaddr = true
  1686  		t.regs.tls = 0
  1687  	} else {
  1688  		return t.readG()
  1689  	}
  1690  
  1691  	return nil
  1692  }
  1693  
  1694  func (t *gdbThread) writeSomeRegisters(regNames ...string) error {
  1695  	if t.p.gcmdok {
  1696  		return t.p.conn.writeRegisters(t.strID, t.regs.buf)
  1697  	}
  1698  	for _, regName := range regNames {
  1699  		if err := t.p.conn.writeRegister(t.strID, t.regs.regs[regName].regnum, t.regs.regs[regName].value); err != nil {
  1700  			return err
  1701  		}
  1702  	}
  1703  	return nil
  1704  }
  1705  
  1706  func (t *gdbThread) writeRegisters() error {
  1707  	if t.p.gcmdok && t.p._Gcmdok {
  1708  		err := t.p.conn.writeRegisters(t.strID, t.regs.buf)
  1709  		if isProtocolErrorUnsupported(err) {
  1710  			t.p._Gcmdok = false
  1711  		} else {
  1712  			return err
  1713  		}
  1714  
  1715  	}
  1716  	for _, r := range t.regs.regs {
  1717  		if r.ignoreOnWrite {
  1718  			continue
  1719  		}
  1720  		if err := t.p.conn.writeRegister(t.strID, r.regnum, r.value); err != nil {
  1721  			return err
  1722  		}
  1723  	}
  1724  	return nil
  1725  }
  1726  
  1727  func (t *gdbThread) readSomeRegisters(regNames ...string) error {
  1728  	if t.p.gcmdok {
  1729  		return t.p.conn.readRegisters(t.strID, t.regs.buf)
  1730  	}
  1731  	for _, regName := range regNames {
  1732  		err := t.p.conn.readRegister(t.strID, t.regs.regs[regName].regnum, t.regs.regs[regName].value)
  1733  		if err != nil {
  1734  			return err
  1735  		}
  1736  	}
  1737  	return nil
  1738  }
  1739  
  1740  func (t *gdbThread) clearBreakpointState() {
  1741  	t.setbp = false
  1742  	t.CurrentBreakpoint.Clear()
  1743  }
  1744  
  1745  // SetCurrentBreakpoint will find and set the threads current breakpoint.
  1746  func (t *gdbThread) SetCurrentBreakpoint(adjustPC bool) error {
  1747  	// adjustPC is ignored, it is the stub's responsibiility to set the PC
  1748  	// address correctly after hitting a breakpoint.
  1749  	t.CurrentBreakpoint.Clear()
  1750  	if t.watchAddr > 0 {
  1751  		t.CurrentBreakpoint.Breakpoint = t.p.Breakpoints().M[t.watchAddr]
  1752  		if t.CurrentBreakpoint.Breakpoint == nil {
  1753  			return fmt.Errorf("could not find watchpoint at address %#x", t.watchAddr)
  1754  		}
  1755  		return nil
  1756  	}
  1757  	regs, err := t.Registers()
  1758  	if err != nil {
  1759  		return err
  1760  	}
  1761  	pc := regs.PC()
  1762  	if bp, ok := t.p.FindBreakpoint(pc); ok {
  1763  		if t.regs.PC() != bp.Addr {
  1764  			if err := t.setPC(bp.Addr); err != nil {
  1765  				return err
  1766  			}
  1767  		}
  1768  		t.CurrentBreakpoint.Breakpoint = bp
  1769  	}
  1770  	return nil
  1771  }
  1772  
  1773  func (regs *gdbRegisters) PC() uint64 {
  1774  	return binary.LittleEndian.Uint64(regs.regs[regs.regnames.PC].value)
  1775  }
  1776  
  1777  func (regs *gdbRegisters) setPC(value uint64) {
  1778  	binary.LittleEndian.PutUint64(regs.regs[regs.regnames.PC].value, value)
  1779  }
  1780  
  1781  func (regs *gdbRegisters) SP() uint64 {
  1782  	return binary.LittleEndian.Uint64(regs.regs[regs.regnames.SP].value)
  1783  }
  1784  
  1785  func (regs *gdbRegisters) BP() uint64 {
  1786  	return binary.LittleEndian.Uint64(regs.regs[regs.regnames.BP].value)
  1787  }
  1788  
  1789  func (regs *gdbRegisters) CX() uint64 {
  1790  	return binary.LittleEndian.Uint64(regs.regs[regs.regnames.CX].value)
  1791  }
  1792  
  1793  func (regs *gdbRegisters) setCX(value uint64) {
  1794  	binary.LittleEndian.PutUint64(regs.regs[regs.regnames.CX].value, value)
  1795  }
  1796  
  1797  func (regs *gdbRegisters) TLS() uint64 {
  1798  	return regs.tls
  1799  }
  1800  
  1801  func (regs *gdbRegisters) GAddr() (uint64, bool) {
  1802  	return regs.gaddr, regs.hasgaddr
  1803  }
  1804  
  1805  func (regs *gdbRegisters) LR() uint64 {
  1806  	return binary.LittleEndian.Uint64(regs.regs["lr"].value)
  1807  }
  1808  
  1809  func (regs *gdbRegisters) byName(name string) uint64 {
  1810  	reg, ok := regs.regs[name]
  1811  	if !ok {
  1812  		return 0
  1813  	}
  1814  	return binary.LittleEndian.Uint64(reg.value)
  1815  }
  1816  
  1817  func (r *gdbRegisters) FloatLoadError() error {
  1818  	return nil
  1819  }
  1820  
  1821  // SetPC will set the value of the PC register to the given value.
  1822  func (t *gdbThread) setPC(pc uint64) error {
  1823  	_, _ = t.Registers() // Registes must be loaded first
  1824  	t.regs.setPC(pc)
  1825  	if t.p.gcmdok {
  1826  		return t.p.conn.writeRegisters(t.strID, t.regs.buf)
  1827  	}
  1828  	reg := t.regs.regs[t.regs.regnames.PC]
  1829  	return t.p.conn.writeRegister(t.strID, reg.regnum, reg.value)
  1830  }
  1831  
  1832  // SetReg will change the value of a list of registers
  1833  func (t *gdbThread) SetReg(regNum uint64, reg *op.DwarfRegister) error {
  1834  	regName := registerName(t.p.bi.Arch, regNum)
  1835  	_, _ = t.Registers() // Registers must be loaded first
  1836  	gdbreg, ok := t.regs.regs[regName]
  1837  	if !ok && strings.HasPrefix(regName, "xmm") {
  1838  		// XMMn and YMMn are the same amd64 register (in different sizes), if we
  1839  		// don't find XMMn try YMMn or ZMMn instead.
  1840  		gdbreg, ok = t.regs.regs["y"+regName[1:]]
  1841  		if !ok {
  1842  			gdbreg, ok = t.regs.regs["z"+regName[1:]]
  1843  		}
  1844  	}
  1845  	if !ok && t.p.bi.Arch.Name == "arm64" && regName == "x30" {
  1846  		gdbreg, ok = t.regs.regs["lr"]
  1847  	}
  1848  	if !ok && regName == "rflags" {
  1849  		// rr has eflags instead of rflags
  1850  		regName = "eflags"
  1851  		gdbreg, ok = t.regs.regs[regName]
  1852  		if ok {
  1853  			reg.FillBytes()
  1854  			reg.Bytes = reg.Bytes[:4]
  1855  		}
  1856  	}
  1857  	if !ok {
  1858  		return fmt.Errorf("could not set register %s: not found", regName)
  1859  	}
  1860  	reg.FillBytes()
  1861  
  1862  	wrongSizeErr := func(n int) error {
  1863  		return fmt.Errorf("could not set register %s: wrong size, expected %d got %d", regName, n, len(reg.Bytes))
  1864  	}
  1865  
  1866  	if len(reg.Bytes) == len(gdbreg.value) {
  1867  		copy(gdbreg.value, reg.Bytes)
  1868  		err := t.p.conn.writeRegister(t.strID, gdbreg.regnum, gdbreg.value)
  1869  		if err != nil {
  1870  			return err
  1871  		}
  1872  		if t.p.conn.workaroundReg != nil && len(gdbreg.value) > 16 {
  1873  			// This is a workaround for a bug in debugserver where register writes (P
  1874  			// packet) on AVX-2 and AVX-512 registers are ignored unless they are
  1875  			// followed by a write to an AVX register.
  1876  			// See:
  1877  			//  Issue #2767
  1878  			//  https://bugs.llvm.org/show_bug.cgi?id=52362
  1879  			reg := t.regs.gdbRegisterNew(t.p.conn.workaroundReg)
  1880  			return t.p.conn.writeRegister(t.strID, reg.regnum, reg.value)
  1881  		}
  1882  	} else if len(reg.Bytes) == 2*len(gdbreg.value) && strings.HasPrefix(regName, "xmm") {
  1883  		// rr uses xmmN for the low part of the register and ymmNh for the high part
  1884  		gdbregh, ok := t.regs.regs["y"+regName[1:]+"h"]
  1885  		if !ok {
  1886  			return wrongSizeErr(len(gdbreg.value))
  1887  		}
  1888  		if len(reg.Bytes) != len(gdbreg.value)+len(gdbregh.value) {
  1889  			return wrongSizeErr(len(gdbreg.value) + len(gdbregh.value))
  1890  		}
  1891  		copy(gdbreg.value, reg.Bytes[:len(gdbreg.value)])
  1892  		copy(gdbregh.value, reg.Bytes[len(gdbreg.value):])
  1893  		err := t.p.conn.writeRegister(t.strID, gdbreg.regnum, gdbreg.value)
  1894  		if err != nil {
  1895  			return err
  1896  		}
  1897  		err = t.p.conn.writeRegister(t.strID, gdbregh.regnum, gdbregh.value)
  1898  		if err != nil {
  1899  			return err
  1900  		}
  1901  	} else {
  1902  		return wrongSizeErr(len(gdbreg.value))
  1903  	}
  1904  	return nil
  1905  }
  1906  
  1907  func (regs *gdbRegisters) Slice(floatingPoint bool) ([]proc.Register, error) {
  1908  	r := make([]proc.Register, 0, len(regs.regsInfo))
  1909  	for _, reginfo := range regs.regsInfo {
  1910  		if reginfo.Group == "float" && !floatingPoint {
  1911  			continue
  1912  		}
  1913  		switch {
  1914  		case reginfo.Name == "eflags":
  1915  			r = proc.AppendBytesRegister(r, "Rflags", regs.regs[reginfo.Name].value)
  1916  		case reginfo.Name == "mxcsr":
  1917  			r = proc.AppendBytesRegister(r, reginfo.Name, regs.regs[reginfo.Name].value)
  1918  		case reginfo.Bitsize == 16:
  1919  			r = proc.AppendBytesRegister(r, reginfo.Name, regs.regs[reginfo.Name].value)
  1920  		case reginfo.Bitsize == 32:
  1921  			r = proc.AppendBytesRegister(r, reginfo.Name, regs.regs[reginfo.Name].value)
  1922  		case reginfo.Bitsize == 64:
  1923  			r = proc.AppendBytesRegister(r, reginfo.Name, regs.regs[reginfo.Name].value)
  1924  		case reginfo.Bitsize == 80:
  1925  			if !floatingPoint {
  1926  				continue
  1927  			}
  1928  			idx := 0
  1929  			for _, stprefix := range []string{"stmm", "st"} {
  1930  				if strings.HasPrefix(reginfo.Name, stprefix) {
  1931  					idx, _ = strconv.Atoi(reginfo.Name[len(stprefix):])
  1932  					break
  1933  				}
  1934  			}
  1935  			r = proc.AppendBytesRegister(r, fmt.Sprintf("ST(%d)", idx), regs.regs[reginfo.Name].value)
  1936  
  1937  		case reginfo.Bitsize == 128:
  1938  			if floatingPoint {
  1939  				name := reginfo.Name
  1940  				if last := name[len(name)-1]; last == 'h' || last == 'H' {
  1941  					name = name[:len(name)-1]
  1942  				}
  1943  				r = proc.AppendBytesRegister(r, strings.ToUpper(name), regs.regs[reginfo.Name].value)
  1944  			}
  1945  
  1946  		case reginfo.Bitsize == 256:
  1947  			if !strings.HasPrefix(strings.ToLower(reginfo.Name), "ymm") || !floatingPoint {
  1948  				continue
  1949  			}
  1950  
  1951  			value := regs.regs[reginfo.Name].value
  1952  			xmmName := "x" + reginfo.Name[1:]
  1953  			r = proc.AppendBytesRegister(r, strings.ToUpper(xmmName), value)
  1954  
  1955  		case reginfo.Bitsize == 512:
  1956  			if !strings.HasPrefix(strings.ToLower(reginfo.Name), "zmm") || !floatingPoint {
  1957  				continue
  1958  			}
  1959  
  1960  			value := regs.regs[reginfo.Name].value
  1961  			xmmName := "x" + reginfo.Name[1:]
  1962  			r = proc.AppendBytesRegister(r, strings.ToUpper(xmmName), value)
  1963  		}
  1964  	}
  1965  	return r, nil
  1966  }
  1967  
  1968  func (regs *gdbRegisters) Copy() (proc.Registers, error) {
  1969  	savedRegs := &gdbRegisters{}
  1970  	savedRegs.init(regs.regsInfo, regs.arch, regs.regnames)
  1971  	copy(savedRegs.buf, regs.buf)
  1972  	return savedRegs, nil
  1973  }
  1974  
  1975  func registerName(arch *proc.Arch, regNum uint64) string {
  1976  	regName, _, _ := arch.DwarfRegisterToString(int(regNum), nil)
  1977  	return strings.ToLower(regName)
  1978  }
  1979  
  1980  func machTargetExcToError(sig uint8) error {
  1981  	switch sig {
  1982  	case 0x91:
  1983  		return errors.New("bad access")
  1984  	case 0x92:
  1985  		return errors.New("bad instruction")
  1986  	case 0x93:
  1987  		return errors.New("arithmetic exception")
  1988  	case 0x94:
  1989  		return errors.New("emulation exception")
  1990  	case 0x95:
  1991  		return errors.New("software exception")
  1992  	case 0x96:
  1993  		return errors.New("breakpoint exception")
  1994  	}
  1995  	return nil
  1996  }
  1997  
  1998  // readG reads the G pointer on x86 by peeking the word before the TLS pointer.
  1999  func (t *gdbThread) readG() error {
  2000  	var regnum int
  2001  
  2002  	switch t.p.bi.GOOS {
  2003  	case "windows":
  2004  	case "darwin":
  2005  		regnum = 59 // gs_base
  2006  	case "linux":
  2007  		regnum = 58 // fs_base
  2008  	default:
  2009  		panic("unsupported operating system attempting to find Goroutine on Thread")
  2010  	}
  2011  
  2012  	wordSize := t.p.bi.Arch.PtrSize()
  2013  	tls := make([]byte, wordSize)
  2014  	err := t.p.conn.readRegister(t.strID, regnum, tls)
  2015  	if err != nil {
  2016  		return err
  2017  	}
  2018  
  2019  	data := make([]byte, wordSize)
  2020  	tlsaddr := binary.LittleEndian.Uint64(tls)
  2021  	if tlsaddr == 0 {
  2022  		t.regs.tls = 0
  2023  		t.regs.gaddr = 0
  2024  		t.regs.hasgaddr = true
  2025  		return nil
  2026  	}
  2027  
  2028  	len, err := t.p.ReadMemory(data, tlsaddr-uint64(wordSize))
  2029  	if err != nil {
  2030  		return err
  2031  	}
  2032  	if len != wordSize {
  2033  		return fmt.Errorf("too little data: only %d bytes", len)
  2034  	}
  2035  
  2036  	t.regs.tls = tlsaddr
  2037  	t.regs.gaddr = binary.LittleEndian.Uint64(data)
  2038  	t.regs.hasgaddr = true
  2039  	return nil
  2040  }