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