github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/libmach/linux.c (about)

     1  // Derived from Plan 9 from User Space src/libmach/Linux.c
     2  // http://code.swtch.com/plan9port/src/tip/src/libmach/Linux.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.
     5  //	Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited.
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
     8  //	Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
     9  //	Portions Copyright © 2001-2007 Russ Cox.
    10  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    11  //
    12  // Permission is hereby granted, free of charge, to any person obtaining a copy
    13  // of this software and associated documentation files (the "Software"), to deal
    14  // in the Software without restriction, including without limitation the rights
    15  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    16  // copies of the Software, and to permit persons to whom the Software is
    17  // furnished to do so, subject to the following conditions:
    18  //
    19  // The above copyright notice and this permission notice shall be included in
    20  // all copies or substantial portions of the Software.
    21  //
    22  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    23  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    24  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    25  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    26  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    27  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    28  // THE SOFTWARE.
    29  
    30  #include <u.h>
    31  #include <sys/syscall.h>	/* for tkill */
    32  #include <unistd.h>
    33  #include <dirent.h>
    34  #include <sys/ptrace.h>
    35  #include <sys/signal.h>
    36  #include <sys/wait.h>
    37  #include <errno.h>
    38  #include <libc.h>
    39  #include <bio.h>
    40  #include <mach.h>
    41  #define Ureg Ureg32
    42  #include <ureg_x86.h>
    43  #undef Ureg
    44  #define Ureg Ureg64
    45  #include <ureg_amd64.h>
    46  #undef Ureg
    47  #undef waitpid
    48  
    49  // The old glibc used with crosstool compilers on thresher
    50  // doesn't know these numbers, but the Linux kernel
    51  // had them as far back as 2.6.0.
    52  #ifndef WSTOPPED
    53  #define WSTOPPED 2
    54  #define WCONTINUED 8
    55  #define WIFCONTINUED(x) ((x) == 0xffff)
    56  #endif
    57  #ifndef PTRACE_SETOPTIONS
    58  #define PTRACE_SETOPTIONS 0x4200
    59  #define PTRACE_GETEVENTMSG 0x4201
    60  #define PTRACE_O_TRACEFORK 0x2
    61  #define PTRACE_O_TRACEVFORK 0x4
    62  #define PTRACE_O_TRACECLONE 0x8
    63  #define PTRACE_O_TRACEEXEC 0x10
    64  #define PTRACE_O_TRACEVFORKDONE 0x20
    65  #define PTRACE_O_TRACEEXIT 0x40
    66  #define PTRACE_EVENT_FORK 0x1
    67  #define PTRACE_EVENT_VFORK 0x2
    68  #define PTRACE_EVENT_CLONE 0x3
    69  #define PTRACE_EVENT_EXEC 0x4
    70  #define PTRACE_EVENT_VFORK_DONE 0x5
    71  #define PTRACE_EVENT_EXIT 0x6
    72  #endif
    73  
    74  typedef struct Ureg64 Ureg64;
    75  
    76  static Maprw ptracesegrw;
    77  static Maprw ptraceregrw;
    78  
    79  // /usr/include/asm-x86_64/user.h
    80  struct user_regs_struct {
    81  	unsigned long r15,r14,r13,r12,rbp,rbx,r11,r10;
    82  	unsigned long r9,r8,rax,rcx,rdx,rsi,rdi,orig_rax;
    83  	unsigned long rip,cs,eflags;
    84  	unsigned long rsp,ss;
    85    	unsigned long fs_base, gs_base;
    86  	unsigned long ds,es,fs,gs;
    87  };
    88  
    89  // Linux gets very upset if a debugger forgets the reported state
    90  // of a debugged process, so we keep everything we know about
    91  // a debugged process in the LinuxThread structure.
    92  //
    93  // We can poll for state changes by calling waitpid and interpreting
    94  // the integer status code that comes back.  Wait1 does this.
    95  //
    96  // If the process is already running, it is an error to PTRACE_CONT it.
    97  //
    98  // If the process is already stopped, it is an error to stop it again.
    99  //
   100  // If the process is stopped because of a signal, the debugger must
   101  // relay the signal to the PTRACE_CONT call, or else the signal is
   102  // dropped.
   103  //
   104  // If the process exits, the debugger should detach so that the real
   105  // parent can reap the zombie.
   106  //
   107  // On first attach, the debugger should set a handful of flags in order
   108  // to catch future events like fork, clone, exec, etc.
   109  
   110  // One for every attached thread.
   111  typedef struct LinuxThread LinuxThread;
   112  struct LinuxThread
   113  {
   114  	int pid;
   115  	int tid;
   116  	int state;
   117  	int signal;
   118  	int child;
   119  	int exitcode;
   120  };
   121  
   122  static int trace = 0;
   123  
   124  static LinuxThread **thr;
   125  static int nthr;
   126  static int mthr;
   127  
   128  static int realpid(int pid);
   129  
   130  enum
   131  {
   132  	Unknown,
   133  	Detached,
   134  	Attached,
   135  	AttachStop,
   136  	Stopped,
   137  	Running,
   138  	Forking,
   139  	Vforking,
   140  	VforkDone,
   141  	Cloning,
   142  	Execing,
   143  	Exiting,
   144  	Exited,
   145  	Killed,
   146  
   147  	NSTATE,
   148  };
   149  
   150  static char* statestr[NSTATE] = {
   151  	"Unknown",
   152  	"Detached",
   153  	"Attached",
   154  	"AttachStop",
   155  	"Stopped",
   156  	"Running",
   157  	"Forking",
   158  	"Vforking",
   159  	"VforkDone",
   160  	"Cloning",
   161  	"Execing",
   162  	"Exiting",
   163  	"Exited",
   164  	"Killed"
   165  };
   166  
   167  static LinuxThread*
   168  attachthread(int pid, int tid, int *new, int newstate)
   169  {
   170  	int i, n, status;
   171  	LinuxThread **p, *t;
   172  	uintptr flags;
   173  
   174  	if(new)
   175  		*new = 0;
   176  
   177  	for(i=0; i<nthr; i++)
   178  		if((pid == 0 || thr[i]->pid == pid) && thr[i]->tid == tid) {
   179  			t = thr[i];
   180  			goto fixup;
   181  		}
   182  
   183  	if(!new)
   184  		return nil;
   185  
   186  	if(nthr >= mthr) {
   187  		n = mthr;
   188  		if(n == 0)
   189  			n = 64;
   190  		else
   191  			n *= 2;
   192  		p = realloc(thr, n*sizeof thr[0]);
   193  		if(p == nil)
   194  			return nil;
   195  		thr = p;
   196  		mthr = n;
   197  	}
   198  
   199  	t = malloc(sizeof *t);
   200  	if(t == nil)
   201  		return nil;
   202  	memset(t, 0, sizeof *t);
   203  
   204  	thr[nthr++] = t;
   205  	if(pid == 0 && nthr > 0)
   206  		pid = thr[0]->pid;
   207  	t->pid = pid;
   208  	t->tid = tid;
   209  	t->state = newstate;
   210  	if(trace)
   211  		fprint(2, "new thread %d %d\n", t->pid, t->tid);
   212  	if(new)
   213  		*new = 1;
   214  
   215  fixup:
   216  	if(t->state == Detached) {
   217  		if(ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) {
   218  			fprint(2, "ptrace ATTACH %d: %r\n", tid);
   219  			return nil;
   220  		}
   221  		t->state = Attached;
   222  	}
   223  
   224  	if(t->state == Attached) {
   225  		// wait for stop, so we can set options
   226  		if(waitpid(tid, &status, __WALL|WUNTRACED|WSTOPPED) < 0)
   227  			return nil;
   228  		if(!WIFSTOPPED(status)) {
   229  			fprint(2, "waitpid %d: status=%#x not stopped\n", tid);
   230  			return nil;
   231  		}
   232  		t->state = AttachStop;
   233  	}
   234  
   235  	if(t->state == AttachStop) {
   236  		// set options so we'll find out about new threads
   237  		flags = PTRACE_O_TRACEFORK |
   238  			PTRACE_O_TRACEVFORK |
   239  			PTRACE_O_TRACECLONE |
   240  			PTRACE_O_TRACEEXEC |
   241  			PTRACE_O_TRACEVFORKDONE;
   242  		if(ptrace(PTRACE_SETOPTIONS, tid, 0, (void*)flags) < 0)	{
   243  			fprint(2, "ptrace PTRACE_SETOPTIONS %d: %r\n", tid);
   244  			return nil;
   245  		}
   246  		t->state = Stopped;
   247  	}
   248  
   249  	return t;
   250  }
   251  
   252  static LinuxThread*
   253  findthread(int tid)
   254  {
   255  	return attachthread(0, tid, nil, 0);
   256  }
   257  
   258  int
   259  procthreadpids(int pid, int *p, int np)
   260  {
   261  	int i, n;
   262  	LinuxThread *t;
   263  
   264  	n = 0;
   265  	for(i=0; i<nthr; i++) {
   266  		t = thr[i];
   267  		if(t->pid == pid) {
   268  			switch(t->state) {
   269  			case Exited:
   270  			case Detached:
   271  			case Killed:
   272  				break;
   273  
   274  			default:
   275  				if(n < np)
   276  					p[n] = t->tid;
   277  				n++;
   278  				break;
   279  			}
   280  		}
   281  	}
   282  	return n;
   283  }
   284  
   285  // Execute a single wait and update the corresponding thread.
   286  static int
   287  wait1(int nohang)
   288  {
   289  	int tid, new, status, event;
   290  	ulong data;
   291  	LinuxThread *t;
   292  	enum
   293  	{
   294  		NormalStop = 0x137f
   295  	};
   296  
   297  	if(nohang != 0)
   298  		nohang = WNOHANG;
   299  
   300  	status = 0;
   301  	tid = waitpid(-1, &status, __WALL|WUNTRACED|WSTOPPED|WCONTINUED|nohang);
   302  
   303  	if(tid < 0)
   304  		return -1;
   305  	if(tid == 0)
   306  		return 0;
   307  
   308  	if(trace > 0 && status != NormalStop)
   309  		fprint(2, "TID %d: %#x\n", tid, status);
   310  
   311  	t = findthread(tid);
   312  	if(t == nil) {
   313  		// Sometimes the kernel tells us about new threads
   314  		// before we see the parent clone.
   315  		t = attachthread(0, tid, &new, Stopped);
   316  		if(t == nil) {
   317  			fprint(2, "failed to attach to new thread %d\n", tid);
   318  			return -1;
   319  		}
   320  	}
   321  
   322  	if(WIFSTOPPED(status)) {
   323  		t->state = Stopped;
   324  		t->signal = WSTOPSIG(status);
   325  		if(trace)
   326  			fprint(2, "tid %d: stopped %#x%s\n", tid, status,
   327  				status != NormalStop ? " ***" : "");
   328  		if(t->signal == SIGTRAP && (event = status>>16) != 0) {	// ptrace event
   329  			switch(event) {
   330  			case PTRACE_EVENT_FORK:
   331  				t->state = Forking;
   332  				goto child;
   333  
   334  			case PTRACE_EVENT_VFORK:
   335  				t->state = Vforking;
   336  				goto child;
   337  
   338  			case PTRACE_EVENT_CLONE:
   339  				t->state = Cloning;
   340  				goto child;
   341  
   342  			child:
   343  				if(ptrace(PTRACE_GETEVENTMSG, t->tid, 0, &data) < 0) {
   344  					fprint(2, "ptrace GETEVENTMSG tid %d: %r\n", tid);
   345  					break;
   346  				}
   347  				t->child = data;
   348  				attachthread(t->pid, t->child, &new, Running);
   349  				break;
   350  
   351  			case PTRACE_EVENT_EXEC:
   352  				t->state = Execing;
   353  				break;
   354  
   355  			case PTRACE_EVENT_VFORK_DONE:
   356  				t->state = VforkDone;
   357  				break;
   358  
   359  			case PTRACE_EVENT_EXIT:
   360  				// We won't see this unless we set PTRACE_O_TRACEEXIT.
   361  				// The debuggers assume that a read or write on a Map
   362  				// will fail for a thread that has exited.  This event
   363  				// breaks that assumption.  It's not a big deal: we
   364  				// only lose the ability to see the register state at
   365  				// the time of exit.
   366  				if(trace)
   367  					fprint(2, "tid %d: exiting %#x\n", tid, status);
   368  				t->state = Exiting;
   369  				if(ptrace(PTRACE_GETEVENTMSG, t->tid, 0, &data) < 0) {
   370  					fprint(2, "ptrace GETEVENTMSG tid %d: %r\n", tid);
   371  					break;
   372  				}
   373  				t->exitcode = data;
   374  				break;
   375  			}
   376  		}
   377  	}
   378  	if(WIFCONTINUED(status)) {
   379  		if(trace)
   380  			fprint(2, "tid %d: continued %#x\n", tid, status);
   381  		t->state = Running;
   382  	}
   383  	if(WIFEXITED(status)) {
   384  		if(trace)
   385  			fprint(2, "tid %d: exited %#x\n", tid, status);
   386  		t->state = Exited;
   387  		t->exitcode = WEXITSTATUS(status);
   388  		t->signal = -1;
   389  		ptrace(PTRACE_DETACH, t->tid, 0, 0);
   390  		if(trace)
   391  			fprint(2, "tid %d: detach exited\n", tid);
   392  	}
   393  	if(WIFSIGNALED(status)) {
   394  		if(trace)
   395  			fprint(2, "tid %d: signaled %#x\n", tid, status);
   396  		t->state = Exited;
   397  		t->signal = WTERMSIG(status);
   398  		t->exitcode = -1;
   399  		ptrace(PTRACE_DETACH, t->tid, 0, 0);
   400  		if(trace)
   401  			fprint(2, "tid %d: detach signaled\n", tid);
   402  	}
   403  	return 1;
   404  }
   405  
   406  static int
   407  waitstop(LinuxThread *t)
   408  {
   409  	while(t->state == Running)
   410  		if(wait1(0) < 0)
   411  			return -1;
   412  	return 0;
   413  }
   414  
   415  // Attach to and stop all threads in process pid.
   416  // Must stop everyone in order to make sure we set
   417  // the "tell me about new threads" option in every
   418  // task.
   419  int
   420  attachallthreads(int pid)
   421  {
   422  	int tid, foundnew, new;
   423  	char buf[100];
   424  	DIR *d;
   425  	struct dirent *de;
   426  	LinuxThread *t;
   427  
   428  	if(pid == 0) {
   429  		fprint(2, "attachallthreads(0)\n");
   430  		return -1;
   431  	}
   432  
   433  	pid = realpid(pid);
   434  
   435  	snprint(buf, sizeof buf, "/proc/%d/task", pid);
   436  	if((d = opendir(buf)) == nil) {
   437  		fprint(2, "opendir %s: %r\n", buf);
   438  		return -1;
   439  	}
   440  
   441  	// Loop in case new threads are being created right now.
   442  	// We stop every thread as we find it, so eventually
   443  	// this has to stop (or the system runs out of procs).
   444  	do {
   445  		foundnew = 0;
   446  		while((de = readdir(d)) != nil) {
   447  			tid = atoi(de->d_name);
   448  			if(tid == 0)
   449  				continue;
   450  			t = attachthread(pid, tid, &new, Detached);
   451  			foundnew |= new;
   452  			if(t)
   453  				waitstop(t);
   454  		}
   455  		rewinddir(d);
   456  	} while(foundnew);
   457  	closedir(d);
   458  
   459  	return 0;
   460  }
   461  
   462  Map*
   463  attachproc(int pid, Fhdr *fp)
   464  {
   465  	Map *map;
   466  
   467  	if(pid == 0) {
   468  		fprint(2, "attachproc(0)\n");
   469  		return nil;
   470  	}
   471  
   472  	if(findthread(pid) == nil && attachallthreads(pid) < 0)
   473  		return nil;
   474  
   475  	map = newmap(0, 4);
   476  	if (!map)
   477  		return 0;
   478  	map->pid = pid;
   479  	if(mach->regsize)
   480  		setmap(map, -1, 0, mach->regsize, 0, "regs", ptraceregrw);
   481  //	if(mach->fpregsize)
   482  //		setmap(map, -1, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs", ptraceregrw);
   483  	setmap(map, -1, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "*text", ptracesegrw);
   484  	setmap(map, -1, fp->dataddr, mach->utop, fp->dataddr, "*data", ptracesegrw);
   485  	return map;
   486  }
   487  
   488  void
   489  detachproc(Map *m)
   490  {
   491  	LinuxThread *t;
   492  
   493  	t = findthread(m->pid);
   494  	if(t != nil) {
   495  		ptrace(PTRACE_DETACH, t->tid, 0, 0);
   496  		t->state = Detached;
   497  		if(trace)
   498  			fprint(2, "tid %d: detachproc\n", t->tid);
   499  		// TODO(rsc): Reclaim thread structs somehow?
   500  	}
   501  	free(m);
   502  }
   503  
   504  /* /proc/pid/stat contains
   505  	pid
   506  	command in parens
   507  	0. state
   508  	1. ppid
   509  	2. pgrp
   510  	3. session
   511  	4. tty_nr
   512  	5. tpgid
   513  	6. flags (math=4, traced=10)
   514  	7. minflt
   515  	8. cminflt
   516  	9. majflt
   517  	10. cmajflt
   518  	11. utime
   519  	12. stime
   520  	13. cutime
   521  	14. cstime
   522  	15. priority
   523  	16. nice
   524  	17. 0
   525  	18. itrealvalue
   526  	19. starttime
   527  	20. vsize
   528  	21. rss
   529  	22. rlim
   530  	23. startcode
   531  	24. endcode
   532  	25. startstack
   533  	26. kstkesp
   534  	27. kstkeip
   535  	28. pending signal bitmap
   536  	29. blocked signal bitmap
   537  	30. ignored signal bitmap
   538  	31. caught signal bitmap
   539  	32. wchan
   540  	33. nswap
   541  	34. cnswap
   542  	35. exit_signal
   543  	36. processor
   544  */
   545  
   546  static int
   547  readstat(int pid, char *buf, int nbuf, char **f, int nf)
   548  {
   549  	int fd, n;
   550  	char *p;
   551  
   552  	snprint(buf, nbuf, "/proc/%d/stat", pid);
   553  	if((fd = open(buf, OREAD)) < 0){
   554  		fprint(2, "open %s: %r\n", buf);
   555  		return -1;
   556  	}
   557  	n = read(fd, buf, nbuf-1);
   558  	close(fd);
   559  	if(n <= 0){
   560  		fprint(2, "read %s: %r\n", buf);
   561  		return -1;
   562  	}
   563  	buf[n] = 0;
   564  
   565  	/* command name is in parens, no parens afterward */
   566  	p = strrchr(buf, ')');
   567  	if(p == nil || *++p != ' '){
   568  		fprint(2, "bad format in /proc/%d/stat\n", pid);
   569  		return -1;
   570  	}
   571  	++p;
   572  
   573  	nf = tokenize(p, f, nf);
   574  	if(0) print("code 0x%lux-0x%lux stack 0x%lux kstk 0x%lux keip 0x%lux pending 0x%lux\n",
   575  		strtoul(f[23], 0, 0), strtoul(f[24], 0, 0), strtoul(f[25], 0, 0),
   576  		strtoul(f[26], 0, 0), strtoul(f[27], 0, 0), strtoul(f[28], 0, 0));
   577  
   578  	return nf;
   579  }
   580  
   581  static char*
   582  readstatus(int pid, char *buf, int nbuf, char *key)
   583  {
   584  	int fd, n;
   585  	char *p;
   586  
   587  	snprint(buf, nbuf, "/proc/%d/status", pid);
   588  	if((fd = open(buf, OREAD)) < 0){
   589  		fprint(2, "open %s: %r\n", buf);
   590  		return nil;
   591  	}
   592  	n = read(fd, buf, nbuf-1);
   593  	close(fd);
   594  	if(n <= 0){
   595  		fprint(2, "read %s: %r\n", buf);
   596  		return nil;
   597  	}
   598  	buf[n] = 0;
   599  	p = strstr(buf, key);
   600  	if(p)
   601  		return p+strlen(key);
   602  	return nil;
   603  }
   604  
   605  int
   606  procnotes(int pid, char ***pnotes)
   607  {
   608  	char buf[1024], *f[40];
   609  	int i, n, nf;
   610  	char *s, **notes;
   611  	ulong sigs;
   612  	extern char *_p9sigstr(int, char*);
   613  
   614  	*pnotes = nil;
   615  	nf = readstat(pid, buf, sizeof buf, f, nelem(f));
   616  	if(nf <= 28)
   617  		return -1;
   618  
   619  	sigs = strtoul(f[28], 0, 0) & ~(1<<SIGCONT);
   620  	if(sigs == 0){
   621  		*pnotes = nil;
   622  		return 0;
   623  	}
   624  
   625  	notes = malloc(32*sizeof(char*));
   626  	if(notes == nil)
   627  		return -1;
   628  	memset(notes, 0, 32*sizeof(char*));
   629  	n = 0;
   630  	for(i=0; i<32; i++){
   631  		if((sigs&(1<<i)) == 0)
   632  			continue;
   633  		if((s = _p9sigstr(i, nil)) == nil)
   634  			continue;
   635  		notes[n++] = s;
   636  	}
   637  	*pnotes = notes;
   638  	return n;
   639  }
   640  
   641  static int
   642  realpid(int pid)
   643  {
   644  	char buf[1024], *p;
   645  
   646  	p = readstatus(pid, buf, sizeof buf, "\nTgid:");
   647  	if(p == nil)
   648  		return pid;
   649  	return atoi(p);
   650  }
   651  
   652  int
   653  ctlproc(int pid, char *msg)
   654  {
   655  	int new;
   656  	LinuxThread *t;
   657  	uintptr data;
   658  
   659  	while(wait1(1) > 0)
   660  		;
   661  
   662  	if(strcmp(msg, "attached") == 0){
   663  		t = attachthread(pid, pid, &new, Attached);
   664  		if(t == nil)
   665  			return -1;
   666  		return 0;
   667  	}
   668  
   669  	if(strcmp(msg, "hang") == 0){
   670  		if(pid == getpid())
   671  			return ptrace(PTRACE_TRACEME, 0, 0, 0);
   672  		werrstr("can only hang self");
   673  		return -1;
   674  	}
   675  
   676  	t = findthread(pid);
   677  	if(t == nil) {
   678  		werrstr("not attached to pid %d", pid);
   679  		return -1;
   680  	}
   681  	if(t->state == Exited) {
   682  		werrstr("pid %d has exited", pid);
   683  		return -1;
   684  	}
   685  	if(t->state == Killed) {
   686  		werrstr("pid %d has been killed", pid);
   687  		return -1;
   688  	}
   689  
   690  	if(strcmp(msg, "kill") == 0) {
   691  		if(ptrace(PTRACE_KILL, pid, 0, 0) < 0)
   692  			return -1;
   693  		t->state = Killed;
   694  		return 0;
   695  	}
   696  	if(strcmp(msg, "startstop") == 0){
   697  		if(ctlproc(pid, "start") < 0)
   698  			return -1;
   699  		return waitstop(t);
   700  	}
   701  	if(strcmp(msg, "sysstop") == 0){
   702  		if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
   703  			return -1;
   704  		t->state = Running;
   705  		return waitstop(t);
   706  	}
   707  	if(strcmp(msg, "stop") == 0){
   708  		if(trace > 1)
   709  			fprint(2, "tid %d: tkill stop\n", pid);
   710  		if(t->state == Stopped)
   711  			return 0;
   712  		if(syscall(__NR_tkill, pid, SIGSTOP) < 0)
   713  			return -1;
   714  		return waitstop(t);
   715  	}
   716  	if(strcmp(msg, "step") == 0){
   717  		if(t->state == Running) {
   718  			werrstr("cannot single-step unstopped %d", pid);
   719  			return -1;
   720  		}
   721  		if(ptrace(PTRACE_SINGLESTEP, pid, 0, 0) < 0)
   722  			return -1;
   723  		return waitstop(t);
   724  	}
   725  	if(strcmp(msg, "start") == 0) {
   726  		if(t->state == Running)
   727  			return 0;
   728  		data = 0;
   729  		if(t->state == Stopped && t->signal != SIGSTOP && t->signal != SIGTRAP)
   730  			data = t->signal;
   731  		if(trace && data)
   732  			fprint(2, "tid %d: continue %lud\n", pid, (ulong)data);
   733  		if(ptrace(PTRACE_CONT, pid, 0, (void*)data) < 0)
   734  			return -1;
   735  		t->state = Running;
   736  		return 0;
   737  	}
   738  	if(strcmp(msg, "waitstop") == 0) {
   739  		return waitstop(t);
   740  	}
   741  	werrstr("unknown control message '%s'", msg);
   742  	return -1;
   743  }
   744  
   745  char*
   746  proctextfile(int pid)
   747  {
   748  	static char buf[1024], pbuf[128];
   749  
   750  	snprint(pbuf, sizeof pbuf, "/proc/%d/exe", pid);
   751  	if(readlink(pbuf, buf, sizeof buf) >= 0)
   752  		return strdup(buf);
   753  	if(access(pbuf, AEXIST) >= 0)
   754  		return strdup(pbuf);
   755  	return nil;
   756  }
   757  
   758  
   759  static int
   760  ptracerw(int type, int xtype, int isr, int pid, uvlong addr, void *v, uint n)
   761  {
   762  	int i;
   763  	uintptr u, a;
   764  	uchar buf[sizeof(uintptr)];
   765  
   766  	for(i=0; i<n; i+=sizeof(uintptr)){
   767  		// Tread carefully here.  On recent versions of glibc,
   768  		// ptrace is a variadic function which means the third
   769  		// argument will be pushed onto the stack as a uvlong.
   770  		// This is fine on amd64 but will not work for 386.
   771  		// We must convert addr to a uintptr.
   772  		a = addr+i;
   773  		if(isr){
   774  			errno = 0;
   775  			u = ptrace(type, pid, a, 0);
   776  			if(errno)
   777  				goto ptraceerr;
   778  			if(n-i >= sizeof(uintptr))
   779  				memmove((char*)v+i, &u, sizeof(uintptr));
   780  			else{
   781  				memmove(buf, &u, sizeof u);
   782  				memmove((char*)v+i, buf, n-i);
   783  			}
   784  		}else{
   785  			if(n-i >= sizeof(uintptr))
   786  				u = *(uintptr*)((char*)v+i);
   787  			else{
   788  				errno = 0;
   789  				u = ptrace(xtype, pid, a, 0);
   790  				if(errno)
   791  					return -1;
   792  				memmove(buf, &u, sizeof u);
   793  				memmove(buf, (char*)v+i, n-i);
   794  				memmove(&u, buf, sizeof u);
   795  			}
   796  			if(ptrace(type, pid, a, u) < 0)
   797  				goto ptraceerr;
   798  		}
   799  	}
   800  	return 0;
   801  
   802  ptraceerr:
   803  	werrstr("ptrace %s addr=%#llux pid=%d: %r", isr ? "read" : "write", addr, pid);
   804  	return -1;
   805  }
   806  
   807  static int
   808  ptracesegrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr)
   809  {
   810  	USED(seg);
   811  
   812  	return ptracerw(isr ? PTRACE_PEEKDATA : PTRACE_POKEDATA, PTRACE_PEEKDATA,
   813  		isr, map->pid, addr, v, n);
   814  }
   815  
   816  // If the debugger is compiled as an x86-64 program,
   817  // then all the ptrace register read/writes are done on
   818  // a 64-bit register set.  If the target program
   819  // is a 32-bit program, the debugger is expected to
   820  // read the bottom half of the relevant registers
   821  // out of the 64-bit set.
   822  
   823  // Linux 32-bit is
   824  //	BX CX DX SI DI BP AX DS ES FS GS OrigAX IP CS EFLAGS SP SS
   825  
   826  // Linux 64-bit is
   827  //	R15 R14 R13 R12 BP BX R11 R10 R9 R8 AX CX DX SI DI OrigAX IP CS EFLAGS SP SS FSBase GSBase DS ES FS GS
   828  
   829  // Go 32-bit is
   830  //	DI SI BP NSP BX DX CX AX GS FS ES DS TRAP ECODE PC CS EFLAGS SP SS
   831  
   832  uint go32tolinux32tab[] = {
   833  	4, 3, 5, 15, 0, 2, 1, 6, 10, 9, 8, 7, -1, -1, 12, 13, 14, 15, 16
   834  };
   835  static int
   836  go32tolinux32(uvlong addr)
   837  {
   838  	int r;
   839  
   840  	if(addr%4 || addr/4 >= nelem(go32tolinux32tab))
   841  		return -1;
   842  	r = go32tolinux32tab[addr/4];
   843  	if(r < 0)
   844  		return -1;
   845  	return r*4;
   846  }
   847  
   848  uint go32tolinux64tab[] = {
   849  	14, 13, 4, 19, 5, 12, 11, 10, 26, 25, 24, 23, -1, -1, 16, 17, 18, 19, 20
   850  };
   851  static int
   852  go32tolinux64(uvlong addr)
   853  {
   854  	int r;
   855  
   856  	if(addr%4 || addr/4 >= nelem(go32tolinux64tab))
   857  		return -1;
   858  	r = go32tolinux64tab[addr/4];
   859  	if(r < 0)
   860  		return -1;
   861  	return r*8;
   862  }
   863  
   864  extern Mach mi386;
   865  extern Mach mamd64;
   866  
   867  static int
   868  go2linux(uvlong addr)
   869  {
   870  	if(sizeof(void*) == 4) {
   871  		if(mach == &mi386)
   872  			return go32tolinux32(addr);
   873  		werrstr("unsupported architecture");
   874  		return -1;
   875  	}
   876  
   877  	if(mach == &mi386)
   878  		return go32tolinux64(addr);
   879  	if(mach != &mamd64) {
   880  		werrstr("unsupported architecture");
   881  		return -1;
   882  	}
   883  
   884  	switch(addr){
   885  	case offsetof(Ureg64, ax):
   886  		return offsetof(struct user_regs_struct, rax);
   887  	case offsetof(Ureg64, bx):
   888  		return offsetof(struct user_regs_struct, rbx);
   889  	case offsetof(Ureg64, cx):
   890  		return offsetof(struct user_regs_struct, rcx);
   891  	case offsetof(Ureg64, dx):
   892  		return offsetof(struct user_regs_struct, rdx);
   893  	case offsetof(Ureg64, si):
   894  		return offsetof(struct user_regs_struct, rsi);
   895  	case offsetof(Ureg64, di):
   896  		return offsetof(struct user_regs_struct, rdi);
   897  	case offsetof(Ureg64, bp):
   898  		return offsetof(struct user_regs_struct, rbp);
   899  	case offsetof(Ureg64, r8):
   900  		return offsetof(struct user_regs_struct, r8);
   901  	case offsetof(Ureg64, r9):
   902  		return offsetof(struct user_regs_struct, r9);
   903  	case offsetof(Ureg64, r10):
   904  		return offsetof(struct user_regs_struct, r10);
   905  	case offsetof(Ureg64, r11):
   906  		return offsetof(struct user_regs_struct, r11);
   907  	case offsetof(Ureg64, r12):
   908  		return offsetof(struct user_regs_struct, r12);
   909  	case offsetof(Ureg64, r13):
   910  		return offsetof(struct user_regs_struct, r13);
   911  	case offsetof(Ureg64, r14):
   912  		return offsetof(struct user_regs_struct, r14);
   913  	case offsetof(Ureg64, r15):
   914  		return offsetof(struct user_regs_struct, r15);
   915  	case offsetof(Ureg64, ds):
   916  		return offsetof(struct user_regs_struct, ds);
   917  	case offsetof(Ureg64, es):
   918  		return offsetof(struct user_regs_struct, es);
   919  	case offsetof(Ureg64, fs):
   920  		return offsetof(struct user_regs_struct, fs);
   921  	case offsetof(Ureg64, gs):
   922  		return offsetof(struct user_regs_struct, gs);
   923  	case offsetof(Ureg64, ip):
   924  		return offsetof(struct user_regs_struct, rip);
   925  	case offsetof(Ureg64, cs):
   926  		return offsetof(struct user_regs_struct, cs);
   927  	case offsetof(Ureg64, flags):
   928  		return offsetof(struct user_regs_struct, eflags);
   929  	case offsetof(Ureg64, sp):
   930  		return offsetof(struct user_regs_struct, rsp);
   931  	case offsetof(Ureg64, ss):
   932  		return offsetof(struct user_regs_struct, ss);
   933  	}
   934  	return -1;
   935  }
   936  
   937  static int
   938  ptraceregrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr)
   939  {
   940  	int laddr;
   941  	uvlong u;
   942  	
   943  	USED(seg);
   944  
   945  	if((laddr = go2linux(addr)) < 0){
   946  		if(isr){
   947  			memset(v, 0, n);
   948  			return 0;
   949  		}
   950  		werrstr("register %llud not available", addr);
   951  		return -1;
   952  	}
   953  
   954  	if(isr){
   955  		errno = 0;
   956  		u = ptrace(PTRACE_PEEKUSER, map->pid, laddr, 0);
   957  		if(errno)
   958  			goto ptraceerr;
   959  		switch(n){
   960  		case 1:
   961  			*(uint8*)v = u;
   962  			break;
   963  		case 2:
   964  			*(uint16*)v = u;
   965  			break;
   966  		case 4:
   967  			*(uint32*)v = u;
   968  			break;
   969  		case 8:
   970  			*(uint64*)v = u;
   971  			break;
   972  		default:
   973  			werrstr("bad register size");
   974  			return -1;
   975  		}
   976  	}else{
   977  		switch(n){
   978  		case 1:
   979  			u = *(uint8*)v;
   980  			break;
   981  		case 2:
   982  			u = *(uint16*)v;
   983  			break;
   984  		case 4:
   985  			u = *(uint32*)v;
   986  			break;
   987  		case 8:
   988  			u = *(uint64*)v;
   989  			break;
   990  		default:
   991  			werrstr("bad register size");
   992  			return -1;
   993  		}
   994  		if(ptrace(PTRACE_POKEUSER, map->pid, laddr, (void*)(uintptr)u) < 0)
   995  			goto ptraceerr;
   996  	}
   997  	return 0;
   998  
   999  ptraceerr:
  1000  	werrstr("ptrace %s register laddr=%d pid=%d n=%d: %r", isr ? "read" : "write", laddr, map->pid, n);
  1001  	return -1;
  1002  }
  1003  
  1004  char*
  1005  procstatus(int pid)
  1006  {
  1007  	LinuxThread *t;
  1008  
  1009  	t = findthread(pid);
  1010  	if(t == nil)
  1011  		return "???";
  1012  
  1013  	return statestr[t->state];
  1014  }