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