github.com/cnboonhan/delve@v0.0.0-20230908061759-363f2388c2fb/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  	"github.com/go-delve/delve/pkg/dwarf/op"
    83  	"github.com/go-delve/delve/pkg/elfwriter"
    84  	"github.com/go-delve/delve/pkg/logflags"
    85  	"github.com/go-delve/delve/pkg/proc"
    86  	"github.com/go-delve/delve/pkg/proc/internal/ebpf"
    87  	"github.com/go-delve/delve/pkg/proc/linutil"
    88  	"github.com/go-delve/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://github.com/go-delve/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 int(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  	if p.onDetach != nil {
  1086  		p.onDetach()
  1087  	}
  1088  	return p.bi.Close()
  1089  }
  1090  
  1091  // Restart will restart the process from the given position.
  1092  func (p *gdbProcess) Restart(cctx *proc.ContinueOnceContext, pos string) (proc.Thread, error) {
  1093  	if p.tracedir == "" {
  1094  		return nil, proc.ErrNotRecorded
  1095  	}
  1096  
  1097  	p.exited = false
  1098  	p.almostExited = false
  1099  
  1100  	for _, th := range p.threads {
  1101  		th.clearBreakpointState()
  1102  	}
  1103  
  1104  	p.ctrlC = false
  1105  
  1106  	err := p.conn.restart(pos)
  1107  	if err != nil {
  1108  		return nil, err
  1109  	}
  1110  
  1111  	// for some reason we have to send a vCont;c after a vRun to make rr behave
  1112  	// properly, because that's what gdb does.
  1113  	_, err = p.conn.resume(cctx, nil, nil)
  1114  	if err != nil {
  1115  		return nil, err
  1116  	}
  1117  
  1118  	err = p.updateThreadList(&threadUpdater{p: p})
  1119  	if err != nil {
  1120  		return nil, err
  1121  	}
  1122  	p.clearThreadSignals()
  1123  	p.clearThreadRegisters()
  1124  
  1125  	for _, bp := range p.breakpoints.M {
  1126  		p.WriteBreakpoint(bp)
  1127  	}
  1128  
  1129  	return p.currentThread, p.setCurrentBreakpoints()
  1130  }
  1131  
  1132  // When executes the 'when' command for the Mozilla RR backend.
  1133  // This command will return rr's internal event number.
  1134  func (p *gdbProcess) When() (string, error) {
  1135  	if p.tracedir == "" {
  1136  		return "", proc.ErrNotRecorded
  1137  	}
  1138  	event, err := p.conn.qRRCmd("when")
  1139  	if err != nil {
  1140  		return "", err
  1141  	}
  1142  	return strings.TrimSpace(event), nil
  1143  }
  1144  
  1145  const (
  1146  	checkpointPrefix = "Checkpoint "
  1147  )
  1148  
  1149  // Checkpoint creates a checkpoint from which you can restart the program.
  1150  func (p *gdbProcess) Checkpoint(where string) (int, error) {
  1151  	if p.tracedir == "" {
  1152  		return -1, proc.ErrNotRecorded
  1153  	}
  1154  	resp, err := p.conn.qRRCmd("checkpoint", where)
  1155  	if err != nil {
  1156  		return -1, err
  1157  	}
  1158  
  1159  	if !strings.HasPrefix(resp, checkpointPrefix) {
  1160  		return -1, fmt.Errorf("can not parse checkpoint response %q", resp)
  1161  	}
  1162  
  1163  	idstr := resp[len(checkpointPrefix):]
  1164  	space := strings.Index(idstr, " ")
  1165  	if space < 0 {
  1166  		return -1, fmt.Errorf("can not parse checkpoint response %q", resp)
  1167  	}
  1168  	idstr = idstr[:space]
  1169  
  1170  	cpid, err := strconv.Atoi(idstr)
  1171  	if err != nil {
  1172  		return -1, err
  1173  	}
  1174  	return cpid, nil
  1175  }
  1176  
  1177  // Checkpoints returns a list of all checkpoints set.
  1178  func (p *gdbProcess) Checkpoints() ([]proc.Checkpoint, error) {
  1179  	if p.tracedir == "" {
  1180  		return nil, proc.ErrNotRecorded
  1181  	}
  1182  	resp, err := p.conn.qRRCmd("info checkpoints")
  1183  	if err != nil {
  1184  		return nil, err
  1185  	}
  1186  	lines := strings.Split(resp, "\n")
  1187  	r := make([]proc.Checkpoint, 0, len(lines)-1)
  1188  	for _, line := range lines[1:] {
  1189  		if line == "" {
  1190  			continue
  1191  		}
  1192  		fields := strings.Split(line, "\t")
  1193  		if len(fields) != 3 {
  1194  			return nil, fmt.Errorf("can not parse \"info checkpoints\" output line %q", line)
  1195  		}
  1196  		cpid, err := strconv.Atoi(fields[0])
  1197  		if err != nil {
  1198  			return nil, fmt.Errorf("can not parse \"info checkpoints\" output line %q: %v", line, err)
  1199  		}
  1200  		r = append(r, proc.Checkpoint{ID: cpid, When: fields[1], Where: fields[2]})
  1201  	}
  1202  	return r, nil
  1203  }
  1204  
  1205  const deleteCheckpointPrefix = "Deleted checkpoint "
  1206  
  1207  // ClearCheckpoint clears the checkpoint for the given ID.
  1208  func (p *gdbProcess) ClearCheckpoint(id int) error {
  1209  	if p.tracedir == "" {
  1210  		return proc.ErrNotRecorded
  1211  	}
  1212  	resp, err := p.conn.qRRCmd("delete checkpoint", strconv.Itoa(id))
  1213  	if err != nil {
  1214  		return err
  1215  	}
  1216  	if !strings.HasPrefix(resp, deleteCheckpointPrefix) {
  1217  		return errors.New(resp)
  1218  	}
  1219  	return nil
  1220  }
  1221  
  1222  // ChangeDirection sets whether to run the program forwards or in reverse execution.
  1223  func (p *gdbProcess) ChangeDirection(dir proc.Direction) error {
  1224  	if p.tracedir == "" {
  1225  		if dir != proc.Forward {
  1226  			return proc.ErrNotRecorded
  1227  		}
  1228  		return nil
  1229  	}
  1230  	if p.conn.conn == nil {
  1231  		return proc.ErrProcessExited{Pid: p.conn.pid}
  1232  	}
  1233  	if p.conn.direction == dir {
  1234  		return nil
  1235  	}
  1236  	if p.Breakpoints().HasSteppingBreakpoints() {
  1237  		return ErrDirChange
  1238  	}
  1239  	p.conn.direction = dir
  1240  	return nil
  1241  }
  1242  
  1243  // StartCallInjection notifies the backend that we are about to inject a function call.
  1244  func (p *gdbProcess) StartCallInjection() (func(), error) {
  1245  	if p.tracedir == "" {
  1246  		return func() {}, nil
  1247  	}
  1248  	if p.conn.conn == nil {
  1249  		return nil, proc.ErrProcessExited{Pid: p.conn.pid}
  1250  	}
  1251  	if p.conn.direction != proc.Forward {
  1252  		return nil, ErrStartCallInjectionBackwards
  1253  	}
  1254  
  1255  	// Normally it's impossible to inject function calls in a recorded target
  1256  	// because the sequence of instructions that the target will execute is
  1257  	// predetermined.
  1258  	// RR however allows this in a "diversion". When a diversion is started rr
  1259  	// takes the current state of the process and runs it forward as a normal
  1260  	// process, not following the recording.
  1261  	// The gdb serial protocol does not have a way to start a diversion and gdb
  1262  	// (the main frontend of rr) does not know how to do it. Instead a
  1263  	// diversion is started by reading siginfo, because that's the first
  1264  	// request gdb does when starting a function call injection.
  1265  
  1266  	_, err := p.conn.qXfer("siginfo", "", true)
  1267  	if err != nil {
  1268  		return nil, err
  1269  	}
  1270  
  1271  	return func() {
  1272  		_ = p.conn.qXferWrite("siginfo", "") // rr always returns an error for qXfer:siginfo:write... even though it works
  1273  	}, nil
  1274  }
  1275  
  1276  // GetDirection returns the current direction of execution.
  1277  func (p *gdbProcess) GetDirection() proc.Direction {
  1278  	return p.conn.direction
  1279  }
  1280  
  1281  // Breakpoints returns the list of breakpoints currently set.
  1282  func (p *gdbProcess) Breakpoints() *proc.BreakpointMap {
  1283  	return &p.breakpoints
  1284  }
  1285  
  1286  // FindBreakpoint returns the breakpoint at the given address.
  1287  func (p *gdbProcess) FindBreakpoint(pc uint64) (*proc.Breakpoint, bool) {
  1288  	// Directly use addr to lookup breakpoint.
  1289  	if bp, ok := p.breakpoints.M[pc]; ok {
  1290  		return bp, true
  1291  	}
  1292  	return nil, false
  1293  }
  1294  
  1295  func watchTypeToBreakpointType(wtype proc.WatchType) breakpointType {
  1296  	switch {
  1297  	case wtype.Read() && wtype.Write():
  1298  		return accessWatchpoint
  1299  	case wtype.Write():
  1300  		return writeWatchpoint
  1301  	case wtype.Read():
  1302  		return readWatchpoint
  1303  	default:
  1304  		return swBreakpoint
  1305  	}
  1306  }
  1307  
  1308  func (p *gdbProcess) WriteBreakpoint(bp *proc.Breakpoint) error {
  1309  	kind := p.breakpointKind
  1310  	if bp.WatchType != 0 {
  1311  		kind = bp.WatchType.Size()
  1312  	}
  1313  	return p.conn.setBreakpoint(bp.Addr, watchTypeToBreakpointType(bp.WatchType), kind)
  1314  }
  1315  
  1316  func (p *gdbProcess) EraseBreakpoint(bp *proc.Breakpoint) error {
  1317  	kind := p.breakpointKind
  1318  	if bp.WatchType != 0 {
  1319  		kind = bp.WatchType.Size()
  1320  	}
  1321  	return p.conn.clearBreakpoint(bp.Addr, watchTypeToBreakpointType(bp.WatchType), kind)
  1322  }
  1323  
  1324  // FollowExec enables (or disables) follow exec mode
  1325  func (p *gdbProcess) FollowExec(bool) error {
  1326  	return errors.New("follow exec not supported")
  1327  }
  1328  
  1329  type threadUpdater struct {
  1330  	p    *gdbProcess
  1331  	seen map[int]bool
  1332  	done bool
  1333  }
  1334  
  1335  func (tu *threadUpdater) Reset() {
  1336  	tu.done = false
  1337  	tu.seen = nil
  1338  }
  1339  
  1340  func (tu *threadUpdater) Add(threads []string) error {
  1341  	if tu.done {
  1342  		panic("threadUpdater: Add after Finish")
  1343  	}
  1344  	if tu.seen == nil {
  1345  		tu.seen = map[int]bool{}
  1346  	}
  1347  	for _, threadID := range threads {
  1348  		b := threadID
  1349  		if period := strings.Index(b, "."); period >= 0 {
  1350  			b = b[period+1:]
  1351  		}
  1352  		n, err := strconv.ParseUint(b, 16, 32)
  1353  		if err != nil {
  1354  			return &GdbMalformedThreadIDError{threadID}
  1355  		}
  1356  		tid := int(n)
  1357  		tu.seen[tid] = true
  1358  		if _, found := tu.p.threads[tid]; !found {
  1359  			tu.p.threads[tid] = &gdbThread{ID: tid, strID: threadID, p: tu.p}
  1360  		}
  1361  	}
  1362  	return nil
  1363  }
  1364  
  1365  func (tu *threadUpdater) Finish() {
  1366  	tu.done = true
  1367  	for threadID := range tu.p.threads {
  1368  		_, threadSeen := tu.seen[threadID]
  1369  		if threadSeen {
  1370  			continue
  1371  		}
  1372  		delete(tu.p.threads, threadID)
  1373  		if tu.p.currentThread != nil && tu.p.currentThread.ID == threadID {
  1374  			tu.p.currentThread = nil
  1375  		}
  1376  	}
  1377  	if tu.p.currentThread != nil {
  1378  		if _, exists := tu.p.threads[tu.p.currentThread.ID]; !exists {
  1379  			// current thread was removed
  1380  			tu.p.currentThread = nil
  1381  		}
  1382  	}
  1383  	if tu.p.currentThread == nil {
  1384  		for _, thread := range tu.p.threads {
  1385  			tu.p.currentThread = thread
  1386  			break
  1387  		}
  1388  	}
  1389  }
  1390  
  1391  // updateThreadList retrieves the list of inferior threads from
  1392  // the stub and passes it to threadUpdater.
  1393  // Some stubs will return the list of running threads in the stop packet, if
  1394  // this happens the threadUpdater will know that we have already updated the
  1395  // thread list and the first step of updateThreadList will be skipped.
  1396  func (p *gdbProcess) updateThreadList(tu *threadUpdater) error {
  1397  	if !tu.done {
  1398  		first := true
  1399  		for {
  1400  			threads, err := p.conn.queryThreads(first)
  1401  			if err != nil {
  1402  				return err
  1403  			}
  1404  			if len(threads) == 0 {
  1405  				break
  1406  			}
  1407  			first = false
  1408  			if err := tu.Add(threads); err != nil {
  1409  				return err
  1410  			}
  1411  		}
  1412  
  1413  		tu.Finish()
  1414  	}
  1415  
  1416  	for _, th := range p.threads {
  1417  		if p.threadStopInfo {
  1418  			sp, err := p.conn.threadStopInfo(th.strID)
  1419  			if err != nil {
  1420  				if isProtocolErrorUnsupported(err) {
  1421  					p.threadStopInfo = false
  1422  					break
  1423  				}
  1424  				return err
  1425  			}
  1426  			th.setbp = (sp.reason == "breakpoint" || (sp.reason == "" && sp.sig == breakpointSignal) || (sp.watchAddr > 0))
  1427  			th.sig = sp.sig
  1428  			th.watchAddr = sp.watchAddr
  1429  		} else {
  1430  			th.sig = 0
  1431  			th.watchAddr = 0
  1432  		}
  1433  	}
  1434  
  1435  	return nil
  1436  }
  1437  
  1438  // clearThreadRegisters clears the memoized thread register state.
  1439  func (p *gdbProcess) clearThreadRegisters() {
  1440  	for _, thread := range p.threads {
  1441  		thread.regs.regs = nil
  1442  	}
  1443  }
  1444  
  1445  func (p *gdbProcess) clearThreadSignals() {
  1446  	for _, th := range p.threads {
  1447  		th.sig = 0
  1448  	}
  1449  }
  1450  
  1451  func (p *gdbProcess) setCurrentBreakpoints() error {
  1452  	if p.threadStopInfo {
  1453  		for _, th := range p.threads {
  1454  			if th.setbp {
  1455  				err := th.SetCurrentBreakpoint(true)
  1456  				if err != nil {
  1457  					return err
  1458  				}
  1459  			}
  1460  		}
  1461  	}
  1462  	if !p.threadStopInfo {
  1463  		for _, th := range p.threads {
  1464  			if th.CurrentBreakpoint.Breakpoint == nil {
  1465  				err := th.SetCurrentBreakpoint(true)
  1466  				if err != nil {
  1467  					return err
  1468  				}
  1469  			}
  1470  		}
  1471  	}
  1472  	return nil
  1473  }
  1474  
  1475  // ReadMemory will read into 'data' memory at the address provided.
  1476  func (p *gdbProcess) ReadMemory(data []byte, addr uint64) (n int, err error) {
  1477  	err = p.conn.readMemory(data, addr)
  1478  	if err != nil {
  1479  		return 0, err
  1480  	}
  1481  	return len(data), nil
  1482  }
  1483  
  1484  // WriteMemory will write into the memory at 'addr' the data provided.
  1485  func (p *gdbProcess) WriteMemory(addr uint64, data []byte) (written int, err error) {
  1486  	return p.conn.writeMemory(addr, data)
  1487  }
  1488  
  1489  func (t *gdbThread) ProcessMemory() proc.MemoryReadWriter {
  1490  	return t.p
  1491  }
  1492  
  1493  // Location returns the current location of this thread.
  1494  func (t *gdbThread) Location() (*proc.Location, error) {
  1495  	regs, err := t.Registers()
  1496  	if err != nil {
  1497  		return nil, err
  1498  	}
  1499  	if pcreg, ok := regs.(*gdbRegisters).regs[regs.(*gdbRegisters).regnames.PC]; !ok {
  1500  		t.p.conn.log.Errorf("thread %d could not find RIP register", t.ID)
  1501  	} else if len(pcreg.value) < t.p.bi.Arch.PtrSize() {
  1502  		t.p.conn.log.Errorf("thread %d bad length for RIP register: %d", t.ID, len(pcreg.value))
  1503  	}
  1504  	pc := regs.PC()
  1505  	f, l, fn := t.p.bi.PCToLine(pc)
  1506  	return &proc.Location{PC: pc, File: f, Line: l, Fn: fn}, nil
  1507  }
  1508  
  1509  // Breakpoint returns the current active breakpoint for this thread.
  1510  func (t *gdbThread) Breakpoint() *proc.BreakpointState {
  1511  	return &t.CurrentBreakpoint
  1512  }
  1513  
  1514  // ThreadID returns this threads ID.
  1515  func (t *gdbThread) ThreadID() int {
  1516  	return t.ID
  1517  }
  1518  
  1519  // Registers returns the CPU registers for this thread.
  1520  func (t *gdbThread) Registers() (proc.Registers, error) {
  1521  	if t.regs.regs == nil {
  1522  		if err := t.reloadRegisters(); err != nil {
  1523  			return nil, err
  1524  		}
  1525  	}
  1526  	return &t.regs, nil
  1527  }
  1528  
  1529  // RestoreRegisters will set the CPU registers the value of those provided.
  1530  func (t *gdbThread) RestoreRegisters(savedRegs proc.Registers) error {
  1531  	copy(t.regs.buf, savedRegs.(*gdbRegisters).buf)
  1532  	return t.writeRegisters()
  1533  }
  1534  
  1535  // BinInfo will return information on the binary being debugged.
  1536  func (t *gdbThread) BinInfo() *proc.BinaryInfo {
  1537  	return t.p.bi
  1538  }
  1539  
  1540  // Common returns common information across Process implementations.
  1541  func (t *gdbThread) Common() *proc.CommonThread {
  1542  	return &t.common
  1543  }
  1544  
  1545  // StepInstruction will step exactly 1 CPU instruction.
  1546  func (t *gdbThread) StepInstruction() error {
  1547  	pc := t.regs.PC()
  1548  	if bp, atbp := t.p.breakpoints.M[pc]; atbp && bp.WatchType == 0 {
  1549  		err := t.p.conn.clearBreakpoint(pc, swBreakpoint, t.p.breakpointKind)
  1550  		if err != nil {
  1551  			return err
  1552  		}
  1553  		defer t.p.conn.setBreakpoint(pc, swBreakpoint, t.p.breakpointKind)
  1554  	}
  1555  	// Reset thread registers so the next call to
  1556  	// Thread.Registers will not be cached.
  1557  	t.regs.regs = nil
  1558  	return t.p.conn.step(t, &threadUpdater{p: t.p}, false)
  1559  }
  1560  
  1561  // SoftExc returns true if this thread received a software exception during the last resume.
  1562  func (t *gdbThread) SoftExc() bool {
  1563  	return t.setbp
  1564  }
  1565  
  1566  // Blocked returns true if the thread is blocked in runtime or kernel code.
  1567  func (t *gdbThread) Blocked() bool {
  1568  	regs, err := t.Registers()
  1569  	if err != nil {
  1570  		return false
  1571  	}
  1572  	pc := regs.PC()
  1573  	f, ln, fn := t.BinInfo().PCToLine(pc)
  1574  	if fn == nil {
  1575  		if f == "" && ln == 0 {
  1576  			return true
  1577  		}
  1578  		return false
  1579  	}
  1580  	switch fn.Name {
  1581  	case "runtime.futex", "runtime.usleep", "runtime.clone":
  1582  		return true
  1583  	case "runtime.kevent":
  1584  		return true
  1585  	case "runtime.mach_semaphore_wait", "runtime.mach_semaphore_timedwait":
  1586  		return true
  1587  	default:
  1588  		return strings.HasPrefix(fn.Name, "syscall.Syscall") || strings.HasPrefix(fn.Name, "syscall.RawSyscall")
  1589  	}
  1590  }
  1591  
  1592  // loadGInstr returns the correct MOV instruction for the current
  1593  // OS/architecture that can be executed to load the address of G from an
  1594  // inferior's thread.
  1595  func (p *gdbProcess) loadGInstr() ([]byte, error) {
  1596  	var op []byte
  1597  	switch p.bi.GOOS {
  1598  	case "windows", "darwin", "freebsd":
  1599  		// mov rcx, QWORD PTR gs:{uint32(off)}
  1600  		op = []byte{0x65, 0x48, 0x8b, 0x0c, 0x25}
  1601  	case "linux":
  1602  		// mov rcx,QWORD PTR fs:{uint32(off)}
  1603  		op = []byte{0x64, 0x48, 0x8B, 0x0C, 0x25}
  1604  	default:
  1605  		panic("unsupported operating system attempting to find Goroutine on Thread")
  1606  	}
  1607  	offset, err := p.bi.GStructOffset(p.Memory())
  1608  	if err != nil {
  1609  		return nil, err
  1610  	}
  1611  	buf := &bytes.Buffer{}
  1612  	buf.Write(op)
  1613  	binary.Write(buf, binary.LittleEndian, uint32(offset))
  1614  	return buf.Bytes(), nil
  1615  }
  1616  
  1617  func (p *gdbProcess) MemoryMap() ([]proc.MemoryMapEntry, error) {
  1618  	r := []proc.MemoryMapEntry{}
  1619  	addr := uint64(0)
  1620  	for addr != ^uint64(0) {
  1621  		mri, err := p.conn.memoryRegionInfo(addr)
  1622  		if err != nil {
  1623  			return nil, err
  1624  		}
  1625  		if addr+mri.size <= addr {
  1626  			return nil, errors.New("qMemoryRegionInfo response wrapped around the address space or stuck")
  1627  		}
  1628  		if mri.permissions != "" {
  1629  			var mme proc.MemoryMapEntry
  1630  
  1631  			mme.Addr = addr
  1632  			mme.Size = mri.size
  1633  			mme.Read = strings.Contains(mri.permissions, "r")
  1634  			mme.Write = strings.Contains(mri.permissions, "w")
  1635  			mme.Exec = strings.Contains(mri.permissions, "x")
  1636  
  1637  			r = append(r, mme)
  1638  		}
  1639  		addr += mri.size
  1640  	}
  1641  	return r, nil
  1642  }
  1643  
  1644  func (p *gdbProcess) DumpProcessNotes(notes []elfwriter.Note, threadDone func()) (threadsDone bool, out []elfwriter.Note, err error) {
  1645  	return false, notes, nil
  1646  }
  1647  
  1648  func (regs *gdbRegisters) init(regsInfo []gdbRegisterInfo, arch *proc.Arch, regnames *gdbRegnames) {
  1649  	regs.arch = arch
  1650  	regs.regnames = regnames
  1651  	regs.regs = make(map[string]gdbRegister)
  1652  	regs.regsInfo = regsInfo
  1653  
  1654  	regsz := 0
  1655  	for _, reginfo := range regsInfo {
  1656  		if endoff := reginfo.Offset + (reginfo.Bitsize / 8); endoff > regsz {
  1657  			regsz = endoff
  1658  		}
  1659  	}
  1660  	regs.buf = make([]byte, regsz)
  1661  	for _, reginfo := range regsInfo {
  1662  		regs.regs[reginfo.Name] = regs.gdbRegisterNew(&reginfo)
  1663  	}
  1664  }
  1665  
  1666  func (regs *gdbRegisters) gdbRegisterNew(reginfo *gdbRegisterInfo) gdbRegister {
  1667  	return gdbRegister{regnum: reginfo.Regnum, value: regs.buf[reginfo.Offset : reginfo.Offset+reginfo.Bitsize/8], ignoreOnWrite: reginfo.ignoreOnWrite}
  1668  }
  1669  
  1670  // reloadRegisters loads the current value of the thread's registers.
  1671  // It will also load the address of the thread's G.
  1672  // Loading the address of G can be done in one of two ways reloadGAlloc, if
  1673  // the stub can allocate memory, or reloadGAtPC, if the stub can't.
  1674  func (t *gdbThread) reloadRegisters() error {
  1675  	if t.regs.regs == nil {
  1676  		t.regs.init(t.p.conn.regsInfo, t.p.bi.Arch, t.p.regnames)
  1677  	}
  1678  
  1679  	if t.p.gcmdok {
  1680  		if err := t.p.conn.readRegisters(t.strID, t.regs.buf); err != nil {
  1681  			gdberr, isProt := err.(*GdbProtocolError)
  1682  			if isProtocolErrorUnsupported(err) || (t.p.conn.isDebugserver && isProt && gdberr.code == "E74") {
  1683  				t.p.gcmdok = false
  1684  			} else {
  1685  				return err
  1686  			}
  1687  		}
  1688  	}
  1689  	if !t.p.gcmdok {
  1690  		for _, reginfo := range t.p.conn.regsInfo {
  1691  			if err := t.p.conn.readRegister(t.strID, reginfo.Regnum, t.regs.regs[reginfo.Name].value); err != nil {
  1692  				return err
  1693  			}
  1694  		}
  1695  	}
  1696  
  1697  	if t.p.bi.GOOS == "linux" {
  1698  		if reg, hasFsBase := t.regs.regs[t.p.regnames.FsBase]; hasFsBase {
  1699  			t.regs.gaddr = 0
  1700  			t.regs.tls = binary.LittleEndian.Uint64(reg.value)
  1701  			t.regs.hasgaddr = false
  1702  			return nil
  1703  		}
  1704  	}
  1705  
  1706  	if t.p.bi.Arch.Name == "arm64" {
  1707  		// no need to play around with the GInstr on ARM64 because
  1708  		// the G addr is stored in a register
  1709  
  1710  		t.regs.gaddr = t.regs.byName("x28")
  1711  		t.regs.hasgaddr = true
  1712  		t.regs.tls = 0
  1713  	} else {
  1714  		if t.p.loadGInstrAddr > 0 {
  1715  			return t.reloadGAlloc()
  1716  		}
  1717  		return t.reloadGAtPC()
  1718  	}
  1719  
  1720  	return nil
  1721  }
  1722  
  1723  func (t *gdbThread) writeSomeRegisters(regNames ...string) error {
  1724  	if t.p.gcmdok {
  1725  		return t.p.conn.writeRegisters(t.strID, t.regs.buf)
  1726  	}
  1727  	for _, regName := range regNames {
  1728  		if err := t.p.conn.writeRegister(t.strID, t.regs.regs[regName].regnum, t.regs.regs[regName].value); err != nil {
  1729  			return err
  1730  		}
  1731  	}
  1732  	return nil
  1733  }
  1734  
  1735  func (t *gdbThread) writeRegisters() error {
  1736  	if t.p.gcmdok && t.p._Gcmdok {
  1737  		err := t.p.conn.writeRegisters(t.strID, t.regs.buf)
  1738  		if isProtocolErrorUnsupported(err) {
  1739  			t.p._Gcmdok = false
  1740  		} else {
  1741  			return err
  1742  		}
  1743  
  1744  	}
  1745  	for _, r := range t.regs.regs {
  1746  		if r.ignoreOnWrite {
  1747  			continue
  1748  		}
  1749  		if err := t.p.conn.writeRegister(t.strID, r.regnum, r.value); err != nil {
  1750  			return err
  1751  		}
  1752  	}
  1753  	return nil
  1754  }
  1755  
  1756  func (t *gdbThread) readSomeRegisters(regNames ...string) error {
  1757  	if t.p.gcmdok {
  1758  		return t.p.conn.readRegisters(t.strID, t.regs.buf)
  1759  	}
  1760  	for _, regName := range regNames {
  1761  		err := t.p.conn.readRegister(t.strID, t.regs.regs[regName].regnum, t.regs.regs[regName].value)
  1762  		if err != nil {
  1763  			return err
  1764  		}
  1765  	}
  1766  	return nil
  1767  }
  1768  
  1769  // reloadGAtPC overwrites the instruction that the thread is stopped at with
  1770  // the MOV instruction used to load current G, executes this single
  1771  // instruction and then puts everything back the way it was.
  1772  func (t *gdbThread) reloadGAtPC() error {
  1773  	movinstr, err := t.p.loadGInstr()
  1774  	if err != nil {
  1775  		return err
  1776  	}
  1777  
  1778  	if t.Blocked() {
  1779  		t.regs.tls = 0
  1780  		t.regs.gaddr = 0
  1781  		t.regs.hasgaddr = true
  1782  		return nil
  1783  	}
  1784  
  1785  	cx := t.regs.CX()
  1786  	pc := t.regs.PC()
  1787  
  1788  	// We are partially replicating the code of GdbserverThread.stepInstruction
  1789  	// here.
  1790  	// The reason is that lldb-server has a bug with writing to memory and
  1791  	// setting/clearing breakpoints to that same memory which we must work
  1792  	// around by clearing and re-setting the breakpoint in a specific sequence
  1793  	// with the memory writes.
  1794  	// Additionally all breakpoints in [pc, pc+len(movinstr)] need to be removed
  1795  	for addr, bp := range t.p.breakpoints.M {
  1796  		if bp.WatchType != 0 {
  1797  			continue
  1798  		}
  1799  		if addr >= pc && addr <= pc+uint64(len(movinstr)) {
  1800  			err := t.p.conn.clearBreakpoint(addr, swBreakpoint, t.p.breakpointKind)
  1801  			if err != nil {
  1802  				return err
  1803  			}
  1804  			defer t.p.conn.setBreakpoint(addr, swBreakpoint, t.p.breakpointKind)
  1805  		}
  1806  	}
  1807  
  1808  	savedcode := make([]byte, len(movinstr))
  1809  	_, err = t.p.ReadMemory(savedcode, pc)
  1810  	if err != nil {
  1811  		return err
  1812  	}
  1813  
  1814  	_, err = t.p.WriteMemory(pc, movinstr)
  1815  	if err != nil {
  1816  		return err
  1817  	}
  1818  
  1819  	defer func() {
  1820  		_, err0 := t.p.WriteMemory(pc, savedcode)
  1821  		if err == nil {
  1822  			err = err0
  1823  		}
  1824  		t.regs.setPC(pc)
  1825  		t.regs.setCX(cx)
  1826  		err1 := t.writeSomeRegisters(t.p.regnames.PC, t.p.regnames.CX)
  1827  		if err == nil {
  1828  			err = err1
  1829  		}
  1830  	}()
  1831  
  1832  	err = t.p.conn.step(t, nil, true)
  1833  	if err != nil {
  1834  		if err == errThreadBlocked {
  1835  			t.regs.tls = 0
  1836  			t.regs.gaddr = 0
  1837  			t.regs.hasgaddr = true
  1838  			return nil
  1839  		}
  1840  		return err
  1841  	}
  1842  
  1843  	if err := t.readSomeRegisters(t.p.regnames.PC, t.p.regnames.CX); err != nil {
  1844  		return err
  1845  	}
  1846  
  1847  	t.regs.gaddr = t.regs.CX()
  1848  	t.regs.hasgaddr = true
  1849  
  1850  	return err
  1851  }
  1852  
  1853  // reloadGAlloc makes the specified thread execute one instruction stored at
  1854  // t.p.loadGInstrAddr then restores the value of the thread's registers.
  1855  // t.p.loadGInstrAddr must point to valid memory on the inferior, containing
  1856  // a MOV instruction that loads the address of the current G in the RCX
  1857  // register.
  1858  func (t *gdbThread) reloadGAlloc() error {
  1859  	if t.Blocked() {
  1860  		t.regs.tls = 0
  1861  		t.regs.gaddr = 0
  1862  		t.regs.hasgaddr = true
  1863  		return nil
  1864  	}
  1865  
  1866  	cx := t.regs.CX()
  1867  	pc := t.regs.PC()
  1868  
  1869  	t.regs.setPC(t.p.loadGInstrAddr)
  1870  	if err := t.writeSomeRegisters(t.p.regnames.PC); err != nil {
  1871  		return err
  1872  	}
  1873  
  1874  	var err error
  1875  
  1876  	defer func() {
  1877  		t.regs.setPC(pc)
  1878  		t.regs.setCX(cx)
  1879  		err1 := t.writeSomeRegisters(t.p.regnames.PC, t.p.regnames.CX)
  1880  		if err == nil {
  1881  			err = err1
  1882  		}
  1883  	}()
  1884  
  1885  	err = t.p.conn.step(t, nil, true)
  1886  	if err != nil {
  1887  		if err == errThreadBlocked {
  1888  			t.regs.tls = 0
  1889  			t.regs.gaddr = 0
  1890  			t.regs.hasgaddr = true
  1891  			return nil
  1892  		}
  1893  		return err
  1894  	}
  1895  
  1896  	if err := t.readSomeRegisters(t.p.regnames.CX); err != nil {
  1897  		return err
  1898  	}
  1899  
  1900  	t.regs.gaddr = t.regs.CX()
  1901  	t.regs.hasgaddr = true
  1902  
  1903  	return err
  1904  }
  1905  
  1906  func (t *gdbThread) clearBreakpointState() {
  1907  	t.setbp = false
  1908  	t.CurrentBreakpoint.Clear()
  1909  }
  1910  
  1911  // SetCurrentBreakpoint will find and set the threads current breakpoint.
  1912  func (t *gdbThread) SetCurrentBreakpoint(adjustPC bool) error {
  1913  	// adjustPC is ignored, it is the stub's responsibility to set the PC
  1914  	// address correctly after hitting a breakpoint.
  1915  	t.CurrentBreakpoint.Clear()
  1916  	if t.watchAddr > 0 {
  1917  		t.CurrentBreakpoint.Breakpoint = t.p.Breakpoints().M[t.watchAddr]
  1918  		if t.CurrentBreakpoint.Breakpoint == nil {
  1919  			return fmt.Errorf("could not find watchpoint at address %#x", t.watchAddr)
  1920  		}
  1921  		return nil
  1922  	}
  1923  	regs, err := t.Registers()
  1924  	if err != nil {
  1925  		return err
  1926  	}
  1927  	pc := regs.PC()
  1928  	if bp, ok := t.p.FindBreakpoint(pc); ok {
  1929  		if t.regs.PC() != bp.Addr {
  1930  			if err := t.setPC(bp.Addr); err != nil {
  1931  				return err
  1932  			}
  1933  		}
  1934  		t.CurrentBreakpoint.Breakpoint = bp
  1935  	}
  1936  	return nil
  1937  }
  1938  
  1939  func (regs *gdbRegisters) PC() uint64 {
  1940  	return binary.LittleEndian.Uint64(regs.regs[regs.regnames.PC].value)
  1941  }
  1942  
  1943  func (regs *gdbRegisters) setPC(value uint64) {
  1944  	binary.LittleEndian.PutUint64(regs.regs[regs.regnames.PC].value, value)
  1945  }
  1946  
  1947  func (regs *gdbRegisters) SP() uint64 {
  1948  	return binary.LittleEndian.Uint64(regs.regs[regs.regnames.SP].value)
  1949  }
  1950  
  1951  func (regs *gdbRegisters) BP() uint64 {
  1952  	return binary.LittleEndian.Uint64(regs.regs[regs.regnames.BP].value)
  1953  }
  1954  
  1955  func (regs *gdbRegisters) CX() uint64 {
  1956  	return binary.LittleEndian.Uint64(regs.regs[regs.regnames.CX].value)
  1957  }
  1958  
  1959  func (regs *gdbRegisters) setCX(value uint64) {
  1960  	binary.LittleEndian.PutUint64(regs.regs[regs.regnames.CX].value, value)
  1961  }
  1962  
  1963  func (regs *gdbRegisters) TLS() uint64 {
  1964  	return regs.tls
  1965  }
  1966  
  1967  func (regs *gdbRegisters) GAddr() (uint64, bool) {
  1968  	return regs.gaddr, regs.hasgaddr
  1969  }
  1970  
  1971  func (regs *gdbRegisters) LR() uint64 {
  1972  	return binary.LittleEndian.Uint64(regs.regs["lr"].value)
  1973  }
  1974  
  1975  func (regs *gdbRegisters) byName(name string) uint64 {
  1976  	reg, ok := regs.regs[name]
  1977  	if !ok {
  1978  		return 0
  1979  	}
  1980  	return binary.LittleEndian.Uint64(reg.value)
  1981  }
  1982  
  1983  func (regs *gdbRegisters) FloatLoadError() error {
  1984  	return nil
  1985  }
  1986  
  1987  // SetPC will set the value of the PC register to the given value.
  1988  func (t *gdbThread) setPC(pc uint64) error {
  1989  	_, _ = t.Registers() // Registers must be loaded first
  1990  	t.regs.setPC(pc)
  1991  	if t.p.gcmdok {
  1992  		return t.p.conn.writeRegisters(t.strID, t.regs.buf)
  1993  	}
  1994  	reg := t.regs.regs[t.regs.regnames.PC]
  1995  	return t.p.conn.writeRegister(t.strID, reg.regnum, reg.value)
  1996  }
  1997  
  1998  // SetReg will change the value of a list of registers
  1999  func (t *gdbThread) SetReg(regNum uint64, reg *op.DwarfRegister) error {
  2000  	regName := registerName(t.p.bi.Arch, regNum)
  2001  	_, _ = t.Registers() // Registers must be loaded first
  2002  	gdbreg, ok := t.regs.regs[regName]
  2003  	if !ok && strings.HasPrefix(regName, "xmm") {
  2004  		// XMMn and YMMn are the same amd64 register (in different sizes), if we
  2005  		// don't find XMMn try YMMn or ZMMn instead.
  2006  		gdbreg, ok = t.regs.regs["y"+regName[1:]]
  2007  		if !ok {
  2008  			gdbreg, ok = t.regs.regs["z"+regName[1:]]
  2009  		}
  2010  	}
  2011  	if !ok && t.p.bi.Arch.Name == "arm64" && regName == "x30" {
  2012  		gdbreg, ok = t.regs.regs["lr"]
  2013  	}
  2014  	if !ok && regName == "rflags" {
  2015  		// rr has eflags instead of rflags
  2016  		regName = "eflags"
  2017  		gdbreg, ok = t.regs.regs[regName]
  2018  		if ok {
  2019  			reg.FillBytes()
  2020  			reg.Bytes = reg.Bytes[:4]
  2021  		}
  2022  	}
  2023  	if !ok {
  2024  		return fmt.Errorf("could not set register %s: not found", regName)
  2025  	}
  2026  	reg.FillBytes()
  2027  
  2028  	wrongSizeErr := func(n int) error {
  2029  		return fmt.Errorf("could not set register %s: wrong size, expected %d got %d", regName, n, len(reg.Bytes))
  2030  	}
  2031  
  2032  	if len(reg.Bytes) == len(gdbreg.value) {
  2033  		copy(gdbreg.value, reg.Bytes)
  2034  		err := t.p.conn.writeRegister(t.strID, gdbreg.regnum, gdbreg.value)
  2035  		if err != nil {
  2036  			return err
  2037  		}
  2038  		if t.p.conn.workaroundReg != nil && len(gdbreg.value) > 16 {
  2039  			// This is a workaround for a bug in debugserver where register writes (P
  2040  			// packet) on AVX-2 and AVX-512 registers are ignored unless they are
  2041  			// followed by a write to an AVX register.
  2042  			// See:
  2043  			//  Issue #2767
  2044  			//  https://bugs.llvm.org/show_bug.cgi?id=52362
  2045  			reg := t.regs.gdbRegisterNew(t.p.conn.workaroundReg)
  2046  			return t.p.conn.writeRegister(t.strID, reg.regnum, reg.value)
  2047  		}
  2048  	} else if len(reg.Bytes) == 2*len(gdbreg.value) && strings.HasPrefix(regName, "xmm") {
  2049  		// rr uses xmmN for the low part of the register and ymmNh for the high part
  2050  		gdbregh, ok := t.regs.regs["y"+regName[1:]+"h"]
  2051  		if !ok {
  2052  			return wrongSizeErr(len(gdbreg.value))
  2053  		}
  2054  		if len(reg.Bytes) != len(gdbreg.value)+len(gdbregh.value) {
  2055  			return wrongSizeErr(len(gdbreg.value) + len(gdbregh.value))
  2056  		}
  2057  		copy(gdbreg.value, reg.Bytes[:len(gdbreg.value)])
  2058  		copy(gdbregh.value, reg.Bytes[len(gdbreg.value):])
  2059  		err := t.p.conn.writeRegister(t.strID, gdbreg.regnum, gdbreg.value)
  2060  		if err != nil {
  2061  			return err
  2062  		}
  2063  		err = t.p.conn.writeRegister(t.strID, gdbregh.regnum, gdbregh.value)
  2064  		if err != nil {
  2065  			return err
  2066  		}
  2067  	} else {
  2068  		return wrongSizeErr(len(gdbreg.value))
  2069  	}
  2070  	return nil
  2071  }
  2072  
  2073  func (regs *gdbRegisters) Slice(floatingPoint bool) ([]proc.Register, error) {
  2074  	r := make([]proc.Register, 0, len(regs.regsInfo))
  2075  	for _, reginfo := range regs.regsInfo {
  2076  		if reginfo.Group == "float" && !floatingPoint {
  2077  			continue
  2078  		}
  2079  		switch {
  2080  		case reginfo.Name == "eflags":
  2081  			r = proc.AppendBytesRegister(r, "Rflags", regs.regs[reginfo.Name].value)
  2082  		case reginfo.Name == "mxcsr":
  2083  			r = proc.AppendBytesRegister(r, reginfo.Name, regs.regs[reginfo.Name].value)
  2084  		case reginfo.Bitsize == 16:
  2085  			r = proc.AppendBytesRegister(r, reginfo.Name, regs.regs[reginfo.Name].value)
  2086  		case reginfo.Bitsize == 32:
  2087  			r = proc.AppendBytesRegister(r, reginfo.Name, regs.regs[reginfo.Name].value)
  2088  		case reginfo.Bitsize == 64:
  2089  			r = proc.AppendBytesRegister(r, reginfo.Name, regs.regs[reginfo.Name].value)
  2090  		case reginfo.Bitsize == 80:
  2091  			if !floatingPoint {
  2092  				continue
  2093  			}
  2094  			idx := 0
  2095  			for _, stprefix := range []string{"stmm", "st"} {
  2096  				if strings.HasPrefix(reginfo.Name, stprefix) {
  2097  					idx, _ = strconv.Atoi(reginfo.Name[len(stprefix):])
  2098  					break
  2099  				}
  2100  			}
  2101  			r = proc.AppendBytesRegister(r, fmt.Sprintf("ST(%d)", idx), regs.regs[reginfo.Name].value)
  2102  
  2103  		case reginfo.Bitsize == 128:
  2104  			if floatingPoint {
  2105  				name := reginfo.Name
  2106  				if last := name[len(name)-1]; last == 'h' || last == 'H' {
  2107  					name = name[:len(name)-1]
  2108  				}
  2109  				r = proc.AppendBytesRegister(r, strings.ToUpper(name), regs.regs[reginfo.Name].value)
  2110  			}
  2111  
  2112  		case reginfo.Bitsize == 256:
  2113  			if !strings.HasPrefix(strings.ToLower(reginfo.Name), "ymm") || !floatingPoint {
  2114  				continue
  2115  			}
  2116  
  2117  			value := regs.regs[reginfo.Name].value
  2118  			xmmName := "x" + reginfo.Name[1:]
  2119  			r = proc.AppendBytesRegister(r, strings.ToUpper(xmmName), value)
  2120  
  2121  		case reginfo.Bitsize == 512:
  2122  			if !strings.HasPrefix(strings.ToLower(reginfo.Name), "zmm") || !floatingPoint {
  2123  				continue
  2124  			}
  2125  
  2126  			value := regs.regs[reginfo.Name].value
  2127  			xmmName := "x" + reginfo.Name[1:]
  2128  			r = proc.AppendBytesRegister(r, strings.ToUpper(xmmName), value)
  2129  		}
  2130  	}
  2131  	return r, nil
  2132  }
  2133  
  2134  func (regs *gdbRegisters) Copy() (proc.Registers, error) {
  2135  	savedRegs := &gdbRegisters{}
  2136  	savedRegs.init(regs.regsInfo, regs.arch, regs.regnames)
  2137  	copy(savedRegs.buf, regs.buf)
  2138  	return savedRegs, nil
  2139  }
  2140  
  2141  func registerName(arch *proc.Arch, regNum uint64) string {
  2142  	regName, _, _ := arch.DwarfRegisterToString(int(regNum), nil)
  2143  	return strings.ToLower(regName)
  2144  }
  2145  
  2146  func machTargetExcToError(sig uint8) error {
  2147  	switch sig {
  2148  	case 0x91:
  2149  		return errors.New("bad access")
  2150  	case 0x92:
  2151  		return errors.New("bad instruction")
  2152  	case 0x93:
  2153  		return errors.New("arithmetic exception")
  2154  	case 0x94:
  2155  		return errors.New("emulation exception")
  2156  	case 0x95:
  2157  		return errors.New("software exception")
  2158  	case 0x96:
  2159  		return errors.New("breakpoint exception")
  2160  	}
  2161  	return nil
  2162  }