1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Portions Copyright 2007 Chad Mynhier
27  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
28  * Copyright (c) 2013 by Delphix. All rights reserved.
29  * Copyright 2015, Joyent, Inc.
30  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
31  * Copyright 2021 Oxide Computer Company
32  */
33 
34 #include <assert.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <ctype.h>
39 #include <fcntl.h>
40 #include <string.h>
41 #include <strings.h>
42 #include <memory.h>
43 #include <errno.h>
44 #include <dirent.h>
45 #include <limits.h>
46 #include <signal.h>
47 #include <atomic.h>
48 #include <zone.h>
49 #include <sys/types.h>
50 #include <sys/uio.h>
51 #include <sys/stat.h>
52 #include <sys/resource.h>
53 #include <sys/param.h>
54 #include <sys/stack.h>
55 #include <sys/fault.h>
56 #include <sys/syscall.h>
57 #include <sys/sysmacros.h>
58 #include <sys/systeminfo.h>
59 #include <sys/secflags.h>
60 
61 #include "libproc.h"
62 #include "Pcontrol.h"
63 #include "Putil.h"
64 #include "P32ton.h"
65 
66 int	_libproc_debug;		/* set non-zero to enable debugging printfs */
67 int	_libproc_no_qsort;	/* set non-zero to inhibit sorting */
68 				/* of symbol tables */
69 int	_libproc_incore_elf;	/* only use in-core elf data */
70 
71 sigset_t blockable_sigs;	/* signals to block when we need to be safe */
72 static	int	minfd;	/* minimum file descriptor returned by dupfd(fd, 0) */
73 char	procfs_path[PATH_MAX] = "/proc";
74 
75 /*
76  * Function prototypes for static routines in this module.
77  */
78 static	void	deadcheck(struct ps_prochandle *);
79 static	void	restore_tracing_flags(struct ps_prochandle *);
80 static	void	Lfree_internal(struct ps_prochandle *, struct ps_lwphandle *);
81 static  prheader_t *read_lfile(struct ps_prochandle *, const char *);
82 
83 /*
84  * Ops vector functions for live processes.
85  */
86 
87 /*ARGSUSED*/
88 static ssize_t
Pread_live(struct ps_prochandle * P,void * buf,size_t n,uintptr_t addr,void * data)89 Pread_live(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
90     void *data)
91 {
92 	return (pread(P->asfd, buf, n, (off_t)addr));
93 }
94 
95 /*ARGSUSED*/
96 static ssize_t
Pwrite_live(struct ps_prochandle * P,const void * buf,size_t n,uintptr_t addr,void * data)97 Pwrite_live(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr,
98     void *data)
99 {
100 	return (pwrite(P->asfd, buf, n, (off_t)addr));
101 }
102 
103 /*ARGSUSED*/
104 static int
Pread_maps_live(struct ps_prochandle * P,prmap_t ** Pmapp,ssize_t * nmapp,void * data)105 Pread_maps_live(struct ps_prochandle *P, prmap_t **Pmapp, ssize_t *nmapp,
106     void *data)
107 {
108 	char mapfile[PATH_MAX];
109 	int mapfd;
110 	struct stat statb;
111 	ssize_t nmap;
112 	prmap_t *Pmap = NULL;
113 
114 	(void) snprintf(mapfile, sizeof (mapfile), "%s/%d/map",
115 	    procfs_path, (int)P->pid);
116 	if ((mapfd = open(mapfile, O_RDONLY)) < 0 ||
117 	    fstat(mapfd, &statb) != 0 ||
118 	    statb.st_size < sizeof (prmap_t) ||
119 	    (Pmap = malloc(statb.st_size)) == NULL ||
120 	    (nmap = pread(mapfd, Pmap, statb.st_size, 0L)) <= 0 ||
121 	    (nmap /= sizeof (prmap_t)) == 0) {
122 		if (Pmap != NULL)
123 			free(Pmap);
124 		if (mapfd >= 0)
125 			(void) close(mapfd);
126 		Preset_maps(P); /* utter failure; destroy tables */
127 		return (-1);
128 	}
129 	(void) close(mapfd);
130 
131 	*Pmapp = Pmap;
132 	*nmapp = nmap;
133 
134 	return (0);
135 }
136 
137 /*ARGSUSED*/
138 static void
Pread_aux_live(struct ps_prochandle * P,auxv_t ** auxvp,int * nauxp,void * data)139 Pread_aux_live(struct ps_prochandle *P, auxv_t **auxvp, int *nauxp, void *data)
140 {
141 	char auxfile[64];
142 	int fd;
143 	struct stat statb;
144 	auxv_t *auxv;
145 	ssize_t naux;
146 
147 	(void) snprintf(auxfile, sizeof (auxfile), "%s/%d/auxv",
148 	    procfs_path, (int)P->pid);
149 	if ((fd = open(auxfile, O_RDONLY)) < 0) {
150 		dprintf("%s: failed to open %s: %s\n",
151 		    __func__, auxfile, strerror(errno));
152 		return;
153 	}
154 
155 	if (fstat(fd, &statb) == 0 &&
156 	    statb.st_size >= sizeof (auxv_t) &&
157 	    (auxv = malloc(statb.st_size + sizeof (auxv_t))) != NULL) {
158 		if ((naux = read(fd, auxv, statb.st_size)) < 0 ||
159 		    (naux /= sizeof (auxv_t)) < 1) {
160 			dprintf("%s: read failed: %s\n",
161 			    __func__, strerror(errno));
162 			free(auxv);
163 		} else {
164 			auxv[naux].a_type = AT_NULL;
165 			auxv[naux].a_un.a_val = 0L;
166 
167 			*auxvp = auxv;
168 			*nauxp = (int)naux;
169 		}
170 	}
171 
172 	(void) close(fd);
173 }
174 
175 /*ARGSUSED*/
176 static int
Pcred_live(struct ps_prochandle * P,prcred_t * pcrp,int ngroups,void * data)177 Pcred_live(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data)
178 {
179 	return (proc_get_cred(P->pid, pcrp, ngroups));
180 }
181 
182 /* ARGSUSED */
183 static int
Psecflags_live(struct ps_prochandle * P,prsecflags_t ** psf,void * data)184 Psecflags_live(struct ps_prochandle *P, prsecflags_t **psf, void *data)
185 {
186 	return (proc_get_secflags(P->pid, psf));
187 }
188 
189 /*ARGSUSED*/
190 static int
Ppriv_live(struct ps_prochandle * P,prpriv_t ** pprv,void * data)191 Ppriv_live(struct ps_prochandle *P, prpriv_t **pprv, void *data)
192 {
193 	prpriv_t *pp;
194 
195 	pp = proc_get_priv(P->pid);
196 	if (pp == NULL) {
197 		return (-1);
198 	}
199 
200 	*pprv = pp;
201 	return (0);
202 }
203 
204 /*ARGSUSED*/
205 static const psinfo_t *
Ppsinfo_live(struct ps_prochandle * P,psinfo_t * psinfo,void * data)206 Ppsinfo_live(struct ps_prochandle *P, psinfo_t *psinfo, void *data)
207 {
208 	if (proc_get_psinfo(P->pid, psinfo) == -1)
209 		return (NULL);
210 
211 	return (psinfo);
212 }
213 
214 /*ARGSUSED*/
215 static prheader_t *
Plstatus_live(struct ps_prochandle * P,void * data)216 Plstatus_live(struct ps_prochandle *P, void *data)
217 {
218 	return (read_lfile(P, "lstatus"));
219 }
220 
221 /*ARGSUSED*/
222 static prheader_t *
Plpsinfo_live(struct ps_prochandle * P,void * data)223 Plpsinfo_live(struct ps_prochandle *P, void *data)
224 {
225 	return (read_lfile(P, "lpsinfo"));
226 }
227 
228 /*ARGSUSED*/
229 static char *
Pplatform_live(struct ps_prochandle * P,char * s,size_t n,void * data)230 Pplatform_live(struct ps_prochandle *P, char *s, size_t n, void *data)
231 {
232 	if (sysinfo(SI_PLATFORM, s, n) == -1)
233 		return (NULL);
234 	return (s);
235 }
236 
237 /*ARGSUSED*/
238 static int
Puname_live(struct ps_prochandle * P,struct utsname * u,void * data)239 Puname_live(struct ps_prochandle *P, struct utsname *u, void *data)
240 {
241 	return (uname(u));
242 }
243 
244 /*ARGSUSED*/
245 static char *
Pzonename_live(struct ps_prochandle * P,char * s,size_t n,void * data)246 Pzonename_live(struct ps_prochandle *P, char *s, size_t n, void *data)
247 {
248 	if (getzonenamebyid(P->status.pr_zoneid, s, n) < 0)
249 		return (NULL);
250 	s[n - 1] = '\0';
251 	return (s);
252 }
253 
254 /*
255  * Callback function for Pfindexec().  We return a match if we can stat the
256  * suggested pathname and confirm its device and inode number match our
257  * previous information about the /proc/<pid>/object/a.out file.
258  */
259 static int
stat_exec(const char * path,void * arg)260 stat_exec(const char *path, void *arg)
261 {
262 	struct stat64 *stp = arg;
263 	struct stat64 st;
264 
265 	return (stat64(path, &st) == 0 && S_ISREG(st.st_mode) &&
266 	    stp->st_dev == st.st_dev && stp->st_ino == st.st_ino);
267 }
268 
269 /*ARGSUSED*/
270 static char *
Pexecname_live(struct ps_prochandle * P,char * buf,size_t buflen,void * data)271 Pexecname_live(struct ps_prochandle *P, char *buf, size_t buflen, void *data)
272 {
273 	char exec_name[PATH_MAX];
274 	char cwd[PATH_MAX];
275 	char proc_cwd[64];
276 	struct stat64 st;
277 	int ret;
278 
279 	/*
280 	 * Try to get the path information first.
281 	 */
282 	(void) snprintf(exec_name, sizeof (exec_name),
283 	    "%s/%d/path/a.out", procfs_path, (int)P->pid);
284 	if ((ret = readlink(exec_name, buf, buflen - 1)) > 0) {
285 		buf[ret] = '\0';
286 		(void) Pfindobj(P, buf, buf, buflen);
287 		return (buf);
288 	}
289 
290 	/*
291 	 * Stat the executable file so we can compare Pfindexec's
292 	 * suggestions to the actual device and inode number.
293 	 */
294 	(void) snprintf(exec_name, sizeof (exec_name),
295 	    "%s/%d/object/a.out", procfs_path, (int)P->pid);
296 
297 	if (stat64(exec_name, &st) != 0 || !S_ISREG(st.st_mode))
298 		return (NULL);
299 
300 	/*
301 	 * Attempt to figure out the current working directory of the
302 	 * target process.  This only works if the target process has
303 	 * not changed its current directory since it was exec'd.
304 	 */
305 	(void) snprintf(proc_cwd, sizeof (proc_cwd),
306 	    "%s/%d/path/cwd", procfs_path, (int)P->pid);
307 
308 	if ((ret = readlink(proc_cwd, cwd, PATH_MAX - 1)) > 0)
309 		cwd[ret] = '\0';
310 
311 	(void) Pfindexec(P, ret > 0 ? cwd : NULL, stat_exec, &st);
312 
313 	return (NULL);
314 }
315 
316 #if defined(__i386) || defined(__amd64)
317 /*ARGSUSED*/
318 static int
Pldt_live(struct ps_prochandle * P,struct ssd * pldt,int nldt,void * data)319 Pldt_live(struct ps_prochandle *P, struct ssd *pldt, int nldt, void *data)
320 {
321 	return (proc_get_ldt(P->pid, pldt, nldt));
322 }
323 #endif
324 
325 static const ps_ops_t P_live_ops = {
326 	.pop_pread	= Pread_live,
327 	.pop_pwrite	= Pwrite_live,
328 	.pop_read_maps	= Pread_maps_live,
329 	.pop_read_aux	= Pread_aux_live,
330 	.pop_cred	= Pcred_live,
331 	.pop_priv	= Ppriv_live,
332 	.pop_psinfo	= Ppsinfo_live,
333 	.pop_lstatus	= Plstatus_live,
334 	.pop_lpsinfo	= Plpsinfo_live,
335 	.pop_platform	= Pplatform_live,
336 	.pop_uname	= Puname_live,
337 	.pop_zonename	= Pzonename_live,
338 	.pop_execname	= Pexecname_live,
339 	.pop_secflags	= Psecflags_live,
340 #if defined(__i386) || defined(__amd64)
341 	.pop_ldt	= Pldt_live
342 #endif
343 };
344 
345 /*
346  * This is the library's .init handler.
347  */
348 #pragma init(_libproc_init)
349 void
_libproc_init(void)350 _libproc_init(void)
351 {
352 	_libproc_debug = getenv("LIBPROC_DEBUG") != NULL;
353 	_libproc_no_qsort = getenv("LIBPROC_NO_QSORT") != NULL;
354 	_libproc_incore_elf = getenv("LIBPROC_INCORE_ELF") != NULL;
355 
356 	(void) sigfillset(&blockable_sigs);
357 	(void) sigdelset(&blockable_sigs, SIGKILL);
358 	(void) sigdelset(&blockable_sigs, SIGSTOP);
359 }
360 
361 void
Pset_procfs_path(const char * path)362 Pset_procfs_path(const char *path)
363 {
364 	(void) snprintf(procfs_path, sizeof (procfs_path), "%s", path);
365 }
366 
367 /*
368  * Call set_minfd() once before calling dupfd() several times.
369  * We assume that the application will not reduce its current file
370  * descriptor limit lower than 512 once it has set at least that value.
371  */
372 int
set_minfd(void)373 set_minfd(void)
374 {
375 	static mutex_t minfd_lock = DEFAULTMUTEX;
376 	struct rlimit rlim;
377 	int fd;
378 
379 	if ((fd = minfd) < 256) {
380 		(void) mutex_lock(&minfd_lock);
381 		if ((fd = minfd) < 256) {
382 			if (getrlimit(RLIMIT_NOFILE, &rlim) != 0)
383 				rlim.rlim_cur = rlim.rlim_max = 0;
384 			if (rlim.rlim_cur >= 512)
385 				fd = 256;
386 			else if ((fd = rlim.rlim_cur / 2) < 3)
387 				fd = 3;
388 			membar_producer();
389 			minfd = fd;
390 		}
391 		(void) mutex_unlock(&minfd_lock);
392 	}
393 	return (fd);
394 }
395 
396 int
dupfd(int fd,int dfd)397 dupfd(int fd, int dfd)
398 {
399 	int mfd;
400 
401 	/*
402 	 * Make fd be greater than 255 (the 32-bit stdio limit),
403 	 * or at least make it greater than 2 so that the
404 	 * program will work when spawned by init(8).
405 	 * Also, if dfd is non-zero, dup the fd to be dfd.
406 	 */
407 	if ((mfd = minfd) == 0)
408 		mfd = set_minfd();
409 	if (dfd > 0 || (0 <= fd && fd < mfd)) {
410 		if (dfd <= 0)
411 			dfd = mfd;
412 		dfd = fcntl(fd, F_DUPFD, dfd);
413 		(void) close(fd);
414 		fd = dfd;
415 	}
416 	/*
417 	 * Mark it close-on-exec so any created process doesn't inherit it.
418 	 */
419 	if (fd >= 0)
420 		(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
421 	return (fd);
422 }
423 
424 /*
425  * Create a new controlled process.
426  * Leave it stopped on successful exit from exec() or execve().
427  * Return an opaque pointer to its process control structure.
428  * Return NULL if process cannot be created (fork()/exec() not successful).
429  */
430 struct ps_prochandle *
Pxcreate(const char * file,char * const * argv,char * const * envp,int * perr,char * path,size_t len)431 Pxcreate(const char *file,	/* executable file name */
432     char *const *argv,		/* argument vector */
433     char *const *envp,		/* environment */
434     int *perr,			/* pointer to error return code */
435     char *path,		/* if non-null, holds exec path name on return */
436     size_t len)			/* size of the path buffer */
437 {
438 	char execpath[PATH_MAX];
439 	char procname[PATH_MAX];
440 	struct ps_prochandle *P;
441 	pid_t pid;
442 	int fd;
443 	char *fname;
444 	int rc;
445 	int lasterrno = 0;
446 
447 	if (len == 0)	/* zero length, no path */
448 		path = NULL;
449 	if (path != NULL)
450 		*path = '\0';
451 
452 	if ((P = malloc(sizeof (struct ps_prochandle))) == NULL) {
453 		*perr = C_STRANGE;
454 		return (NULL);
455 	}
456 
457 	if ((pid = fork1()) == -1) {
458 		free(P);
459 		*perr = C_FORK;
460 		return (NULL);
461 	}
462 
463 	if (pid == 0) {			/* child process */
464 		id_t id;
465 		extern char **environ;
466 
467 		/*
468 		 * If running setuid or setgid, reset credentials to normal.
469 		 */
470 		if ((id = getgid()) != getegid())
471 			(void) setgid(id);
472 		if ((id = getuid()) != geteuid())
473 			(void) setuid(id);
474 
475 		Pcreate_callback(P);	/* execute callback (see below) */
476 		(void) pause();		/* wait for PRSABORT from parent */
477 
478 		/*
479 		 * This is ugly.  There is no execvep() function that takes a
480 		 * path and an environment.  We cheat here by replacing the
481 		 * global 'environ' variable right before we call this.
482 		 */
483 		if (envp)
484 			environ = (char **)envp;
485 
486 		(void) execvp(file, argv);  /* execute the program */
487 		_exit(127);
488 	}
489 
490 	/*
491 	 * Initialize the process structure.
492 	 */
493 	(void) memset(P, 0, sizeof (*P));
494 	(void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
495 	P->flags |= CREATED;
496 	P->state = PS_RUN;
497 	P->pid = pid;
498 	P->asfd = -1;
499 	P->ctlfd = -1;
500 	P->statfd = -1;
501 	P->agentctlfd = -1;
502 	P->agentstatfd = -1;
503 	Pinit_ops(&P->ops, &P_live_ops);
504 	Pinitsym(P);
505 	Pinitfd(P);
506 
507 	/*
508 	 * Open the /proc/pid files.
509 	 */
510 	(void) snprintf(procname, sizeof (procname), "%s/%d/",
511 	    procfs_path, (int)pid);
512 	fname = procname + strlen(procname);
513 	(void) set_minfd();
514 
515 	/*
516 	 * Exclusive write open advises others not to interfere.
517 	 * There is no reason for any of these open()s to fail.
518 	 */
519 	(void) strcpy(fname, "as");
520 	if ((fd = open(procname, (O_RDWR|O_EXCL))) < 0 ||
521 	    (fd = dupfd(fd, 0)) < 0) {
522 		dprintf("Pcreate: failed to open %s: %s\n",
523 		    procname, strerror(errno));
524 		rc = C_STRANGE;
525 		goto bad;
526 	}
527 	P->asfd = fd;
528 
529 	(void) strcpy(fname, "status");
530 	if ((fd = open(procname, O_RDONLY)) < 0 ||
531 	    (fd = dupfd(fd, 0)) < 0) {
532 		dprintf("Pcreate: failed to open %s: %s\n",
533 		    procname, strerror(errno));
534 		rc = C_STRANGE;
535 		goto bad;
536 	}
537 	P->statfd = fd;
538 
539 	(void) strcpy(fname, "ctl");
540 	if ((fd = open(procname, O_WRONLY)) < 0 ||
541 	    (fd = dupfd(fd, 0)) < 0) {
542 		dprintf("Pcreate: failed to open %s: %s\n",
543 		    procname, strerror(errno));
544 		rc = C_STRANGE;
545 		goto bad;
546 	}
547 	P->ctlfd = fd;
548 
549 	(void) Pstop(P, 0);	/* stop the controlled process */
550 
551 	/*
552 	 * Wait for process to sleep in pause().
553 	 * If the process has already called pause(), then it should be
554 	 * stopped (PR_REQUESTED) while asleep in pause and we are done.
555 	 * Else we set up to catch entry/exit to pause() and set the process
556 	 * running again, expecting it to stop when it reaches pause().
557 	 * There is no reason for this to fail other than an interrupt.
558 	 */
559 	(void) Psysentry(P, SYS_pause, 1);
560 	(void) Psysexit(P, SYS_pause, 1);
561 	for (;;) {
562 		if (P->state == PS_STOP &&
563 		    P->status.pr_lwp.pr_syscall == SYS_pause &&
564 		    (P->status.pr_lwp.pr_why == PR_REQUESTED ||
565 		    P->status.pr_lwp.pr_why == PR_SYSENTRY ||
566 		    P->status.pr_lwp.pr_why == PR_SYSEXIT))
567 			break;
568 
569 		if (P->state != PS_STOP ||	/* interrupt or process died */
570 		    Psetrun(P, 0, 0) != 0) {	/* can't restart */
571 			if (errno == EINTR || errno == ERESTART)
572 				rc = C_INTR;
573 			else {
574 				dprintf("Pcreate: Psetrun failed: %s\n",
575 				    strerror(errno));
576 				rc = C_STRANGE;
577 			}
578 			goto bad;
579 		}
580 
581 		(void) Pwait(P, 0);
582 	}
583 	(void) Psysentry(P, SYS_pause, 0);
584 	(void) Psysexit(P, SYS_pause, 0);
585 
586 	/*
587 	 * Kick the process off the pause() and catch
588 	 * it again on entry to exec() or exit().
589 	 */
590 	(void) Psysentry(P, SYS_exit, 1);
591 	(void) Psysentry(P, SYS_execve, 1);
592 	if (Psetrun(P, 0, PRSABORT) == -1) {
593 		dprintf("Pcreate: Psetrun failed: %s\n", strerror(errno));
594 		rc = C_STRANGE;
595 		goto bad;
596 	}
597 	(void) Pwait(P, 0);
598 	if (P->state != PS_STOP) {
599 		dprintf("Pcreate: Pwait failed: %s\n", strerror(errno));
600 		rc = C_STRANGE;
601 		goto bad;
602 	}
603 
604 	/*
605 	 * Move the process through instances of failed exec()s
606 	 * to reach the point of stopped on successful exec().
607 	 */
608 	(void) Psysexit(P, SYS_execve, TRUE);
609 
610 	while (P->state == PS_STOP &&
611 	    P->status.pr_lwp.pr_why == PR_SYSENTRY &&
612 	    P->status.pr_lwp.pr_what == SYS_execve) {
613 		/*
614 		 * Fetch the exec path name now, before we complete
615 		 * the exec().  We may lose the process and be unable
616 		 * to get the information later.
617 		 */
618 		(void) Pread_string(P, execpath, sizeof (execpath),
619 		    (off_t)P->status.pr_lwp.pr_sysarg[0]);
620 		if (path != NULL)
621 			(void) strncpy(path, execpath, len);
622 		/*
623 		 * Set the process running and wait for
624 		 * it to stop on exit from the exec().
625 		 */
626 		(void) Psetrun(P, 0, 0);
627 		(void) Pwait(P, 0);
628 
629 		if (P->state == PS_LOST &&		/* we lost control */
630 		    Preopen(P) != 0) {		/* and we can't get it back */
631 			rc = C_PERM;
632 			goto bad;
633 		}
634 
635 		/*
636 		 * If the exec() failed, continue the loop, expecting
637 		 * there to be more attempts to exec(), based on PATH.
638 		 */
639 		if (P->state == PS_STOP &&
640 		    P->status.pr_lwp.pr_why == PR_SYSEXIT &&
641 		    P->status.pr_lwp.pr_what == SYS_execve &&
642 		    (lasterrno = P->status.pr_lwp.pr_errno) != 0) {
643 			/*
644 			 * The exec() failed.  Set the process running and
645 			 * wait for it to stop on entry to the next exec().
646 			 */
647 			(void) Psetrun(P, 0, 0);
648 			(void) Pwait(P, 0);
649 
650 			continue;
651 		}
652 		break;
653 	}
654 
655 	if (P->state == PS_STOP &&
656 	    P->status.pr_lwp.pr_why == PR_SYSEXIT &&
657 	    P->status.pr_lwp.pr_what == SYS_execve &&
658 	    P->status.pr_lwp.pr_errno == 0) {
659 		/*
660 		 * The process is stopped on successful exec() or execve().
661 		 * Turn off all tracing flags and return success.
662 		 */
663 		restore_tracing_flags(P);
664 #ifndef _LP64
665 		/* We must be a 64-bit process to deal with a 64-bit process */
666 		if (P->status.pr_dmodel == PR_MODEL_LP64) {
667 			rc = C_LP64;
668 			goto bad;
669 		}
670 #endif
671 		/*
672 		 * Set run-on-last-close so the controlled process
673 		 * runs even if we die on a signal.
674 		 */
675 		(void) Psetflags(P, PR_RLC);
676 		*perr = 0;
677 		return (P);
678 	}
679 
680 	rc = lasterrno == ENOENT ? C_NOENT : C_NOEXEC;
681 
682 bad:
683 	(void) kill(pid, SIGKILL);
684 	if (path != NULL && rc != C_PERM && rc != C_LP64)
685 		*path = '\0';
686 	Pfree(P);
687 	*perr = rc;
688 	return (NULL);
689 }
690 
691 struct ps_prochandle *
Pcreate(const char * file,char * const * argv,int * perr,char * path,size_t len)692 Pcreate(
693 	const char *file,	/* executable file name */
694 	char *const *argv,	/* argument vector */
695 	int *perr,	/* pointer to error return code */
696 	char *path,	/* if non-null, holds exec path name on return */
697 	size_t len)	/* size of the path buffer */
698 {
699 	return (Pxcreate(file, argv, NULL, perr, path, len));
700 }
701 
702 /*
703  * Return a printable string corresponding to a Pcreate() error return.
704  */
705 const char *
Pcreate_error(int error)706 Pcreate_error(int error)
707 {
708 	const char *str;
709 
710 	switch (error) {
711 	case C_FORK:
712 		str = "cannot fork";
713 		break;
714 	case C_PERM:
715 		str = "file is set-id or unreadable";
716 		break;
717 	case C_NOEXEC:
718 		str = "cannot execute file";
719 		break;
720 	case C_INTR:
721 		str = "operation interrupted";
722 		break;
723 	case C_LP64:
724 		str = "program is _LP64, self is not";
725 		break;
726 	case C_STRANGE:
727 		str = "unanticipated system error";
728 		break;
729 	case C_NOENT:
730 		str = "cannot find executable file";
731 		break;
732 	default:
733 		str = "unknown error";
734 		break;
735 	}
736 
737 	return (str);
738 }
739 
740 /*
741  * Callback to execute in each child process created with Pcreate() after fork
742  * but before it execs the new process image.  By default, we do nothing, but
743  * by calling this function we allow the client program to define its own
744  * version of the function which will interpose on our empty default.  This
745  * may be useful for clients that need to modify signal dispositions, terminal
746  * attributes, or process group and session properties for each new victim.
747  */
748 /*ARGSUSED*/
749 void
Pcreate_callback(struct ps_prochandle * P)750 Pcreate_callback(struct ps_prochandle *P)
751 {
752 	/* nothing to do here */
753 }
754 
755 /*
756  * Grab an existing process.
757  * Return an opaque pointer to its process control structure.
758  *
759  * pid:		UNIX process ID.
760  * flags:
761  *	PGRAB_RETAIN	Retain tracing flags (default clears all tracing flags).
762  *	PGRAB_FORCE	Grab regardless of whether process is already traced.
763  *	PGRAB_RDONLY	Open the address space file O_RDONLY instead of O_RDWR,
764  *                      and do not open the process control file.
765  *	PGRAB_NOSTOP	Open the process but do not force it to stop.
766  * perr:	pointer to error return code.
767  */
768 struct ps_prochandle *
Pgrab(pid_t pid,int flags,int * perr)769 Pgrab(pid_t pid, int flags, int *perr)
770 {
771 	struct ps_prochandle *P;
772 	int fd, omode;
773 	char procname[PATH_MAX];
774 	char *fname;
775 	int rc = 0;
776 
777 	/*
778 	 * PGRAB_RDONLY means that we do not open the /proc/<pid>/control file,
779 	 * and so it implies RETAIN and NOSTOP since both require control.
780 	 */
781 	if (flags & PGRAB_RDONLY)
782 		flags |= PGRAB_RETAIN | PGRAB_NOSTOP;
783 
784 	if ((P = malloc(sizeof (struct ps_prochandle))) == NULL) {
785 		*perr = G_STRANGE;
786 		return (NULL);
787 	}
788 
789 	P->asfd = -1;
790 	P->ctlfd = -1;
791 	P->statfd = -1;
792 
793 again:	/* Come back here if we lose it in the Window of Vulnerability */
794 	if (P->ctlfd >= 0)
795 		(void) close(P->ctlfd);
796 	if (P->asfd >= 0)
797 		(void) close(P->asfd);
798 	if (P->statfd >= 0)
799 		(void) close(P->statfd);
800 	(void) memset(P, 0, sizeof (*P));
801 	(void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
802 	P->ctlfd = -1;
803 	P->asfd = -1;
804 	P->statfd = -1;
805 	P->agentctlfd = -1;
806 	P->agentstatfd = -1;
807 	Pinit_ops(&P->ops, &P_live_ops);
808 	Pinitsym(P);
809 	Pinitfd(P);
810 
811 	/*
812 	 * Open the /proc/pid files
813 	 */
814 	(void) snprintf(procname, sizeof (procname), "%s/%d/",
815 	    procfs_path, (int)pid);
816 	fname = procname + strlen(procname);
817 	(void) set_minfd();
818 
819 	/*
820 	 * Request exclusive open to avoid grabbing someone else's
821 	 * process and to prevent others from interfering afterwards.
822 	 * If this fails and the 'PGRAB_FORCE' flag is set, attempt to
823 	 * open non-exclusively.
824 	 */
825 	(void) strcpy(fname, "as");
826 	omode = (flags & PGRAB_RDONLY) ? O_RDONLY : O_RDWR;
827 
828 	if (((fd = open(procname, omode | O_EXCL)) < 0 &&
829 	    (fd = ((flags & PGRAB_FORCE)? open(procname, omode) : -1)) < 0) ||
830 	    (fd = dupfd(fd, 0)) < 0) {
831 		switch (errno) {
832 		case ENOENT:
833 			rc = G_NOPROC;
834 			break;
835 		case EACCES:
836 		case EPERM:
837 			rc = G_PERM;
838 			break;
839 		case EMFILE:
840 			rc = G_NOFD;
841 			break;
842 		case EBUSY:
843 			if (!(flags & PGRAB_FORCE) || geteuid() != 0) {
844 				rc = G_BUSY;
845 				break;
846 			}
847 			/* FALLTHROUGH */
848 		default:
849 			dprintf("Pgrab: failed to open %s: %s\n",
850 			    procname, strerror(errno));
851 			rc = G_STRANGE;
852 			break;
853 		}
854 		goto err;
855 	}
856 	P->asfd = fd;
857 
858 	(void) strcpy(fname, "status");
859 	if ((fd = open(procname, O_RDONLY)) < 0 ||
860 	    (fd = dupfd(fd, 0)) < 0) {
861 		switch (errno) {
862 		case ENOENT:
863 			rc = G_NOPROC;
864 			break;
865 		case EMFILE:
866 			rc = G_NOFD;
867 			break;
868 		default:
869 			dprintf("Pgrab: failed to open %s: %s\n",
870 			    procname, strerror(errno));
871 			rc = G_STRANGE;
872 			break;
873 		}
874 		goto err;
875 	}
876 	P->statfd = fd;
877 
878 	if (!(flags & PGRAB_RDONLY)) {
879 		(void) strcpy(fname, "ctl");
880 		if ((fd = open(procname, O_WRONLY)) < 0 ||
881 		    (fd = dupfd(fd, 0)) < 0) {
882 			switch (errno) {
883 			case ENOENT:
884 				rc = G_NOPROC;
885 				break;
886 			case EMFILE:
887 				rc = G_NOFD;
888 				break;
889 			default:
890 				dprintf("Pgrab: failed to open %s: %s\n",
891 				    procname, strerror(errno));
892 				rc = G_STRANGE;
893 				break;
894 			}
895 			goto err;
896 		}
897 		P->ctlfd = fd;
898 	}
899 
900 	P->state = PS_RUN;
901 	P->pid = pid;
902 
903 	/*
904 	 * We are now in the Window of Vulnerability (WoV).  The process may
905 	 * exec() a setuid/setgid or unreadable object file between the open()
906 	 * and the PCSTOP.  We will get EAGAIN in this case and must start over.
907 	 * As Pstopstatus will trigger the first read() from a /proc file,
908 	 * we also need to handle EOVERFLOW here when 32-bit as an indicator
909 	 * that this process is 64-bit.  Finally, if the process has become
910 	 * a zombie (PS_UNDEAD) while we were trying to grab it, just remain
911 	 * silent about this and pretend there was no process.
912 	 */
913 	if (Pstopstatus(P, PCNULL, 0) != 0) {
914 #ifndef _LP64
915 		if (errno == EOVERFLOW) {
916 			rc = G_LP64;
917 			goto err;
918 		}
919 #endif
920 		if (P->state == PS_LOST) {	/* WoV */
921 			(void) mutex_destroy(&P->proc_lock);
922 			goto again;
923 		}
924 
925 		if (P->state == PS_UNDEAD)
926 			rc = G_NOPROC;
927 		else
928 			rc = G_STRANGE;
929 
930 		goto err;
931 	}
932 
933 	/*
934 	 * If the process is a system process, we can't control it even as root
935 	 */
936 	if (P->status.pr_flags & PR_ISSYS) {
937 		rc = G_SYS;
938 		goto err;
939 	}
940 #ifndef _LP64
941 	/*
942 	 * We must be a 64-bit process to deal with a 64-bit process
943 	 */
944 	if (P->status.pr_dmodel == PR_MODEL_LP64) {
945 		rc = G_LP64;
946 		goto err;
947 	}
948 #endif
949 
950 	/*
951 	 * Remember the status for use by Prelease().
952 	 */
953 	P->orig_status = P->status;	/* structure copy */
954 
955 	/*
956 	 * Before stopping the process, make sure we are not grabbing ourselves.
957 	 * If we are, make sure we are doing it PGRAB_RDONLY.
958 	 */
959 	if (pid == getpid()) {
960 		/*
961 		 * Verify that the process is really ourself:
962 		 * Set a magic number, read it through the
963 		 * /proc file and see if the results match.
964 		 */
965 		uint32_t magic1 = 0;
966 		uint32_t magic2 = 2;
967 
968 		errno = 0;
969 
970 		if (Pread(P, &magic2, sizeof (magic2), (uintptr_t)&magic1)
971 		    == sizeof (magic2) &&
972 		    magic2 == 0 &&
973 		    (magic1 = 0xfeedbeef) &&
974 		    Pread(P, &magic2, sizeof (magic2), (uintptr_t)&magic1)
975 		    == sizeof (magic2) &&
976 		    magic2 == 0xfeedbeef &&
977 		    !(flags & PGRAB_RDONLY)) {
978 			rc = G_SELF;
979 			goto err;
980 		}
981 	}
982 
983 	/*
984 	 * If the process is already stopped or has been directed
985 	 * to stop via /proc, do not set run-on-last-close.
986 	 */
987 	if (!(P->status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP)) &&
988 	    !(flags & PGRAB_RDONLY)) {
989 		/*
990 		 * Mark the process run-on-last-close so
991 		 * it runs even if we die from SIGKILL.
992 		 */
993 		if (Psetflags(P, PR_RLC) != 0) {
994 			if (errno == EAGAIN) {	/* WoV */
995 				(void) mutex_destroy(&P->proc_lock);
996 				goto again;
997 			}
998 			if (errno == ENOENT)	/* No complaint about zombies */
999 				rc = G_ZOMB;
1000 			else {
1001 				dprintf("Pgrab: failed to set RLC\n");
1002 				rc = G_STRANGE;
1003 			}
1004 			goto err;
1005 		}
1006 	}
1007 
1008 	/*
1009 	 * If a stop directive is pending and the process has not yet stopped,
1010 	 * then synchronously wait for the stop directive to take effect.
1011 	 * Limit the time spent waiting for the process to stop by iterating
1012 	 * at most 10 times. The time-out of 20 ms corresponds to the time
1013 	 * between sending the stop directive and the process actually stopped
1014 	 * as measured by DTrace on a slow, busy system. If the process doesn't
1015 	 * stop voluntarily, clear the PR_DSTOP flag so that the code below
1016 	 * forces the process to stop.
1017 	 */
1018 	if (!(flags & PGRAB_RDONLY)) {
1019 		int niter = 0;
1020 		while ((P->status.pr_lwp.pr_flags & (PR_STOPPED|PR_DSTOP)) ==
1021 		    PR_DSTOP && niter < 10 &&
1022 		    Pstopstatus(P, PCTWSTOP, 20) != 0) {
1023 			niter++;
1024 			if (flags & PGRAB_NOSTOP)
1025 				break;
1026 		}
1027 		if (niter == 10 && !(flags & PGRAB_NOSTOP)) {
1028 			/* Try it harder down below */
1029 			P->status.pr_lwp.pr_flags &= ~PR_DSTOP;
1030 		}
1031 	}
1032 
1033 	/*
1034 	 * If the process is not already stopped or directed to stop
1035 	 * and PGRAB_NOSTOP was not specified, stop the process now.
1036 	 */
1037 	if (!(P->status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP)) &&
1038 	    !(flags & PGRAB_NOSTOP)) {
1039 		/*
1040 		 * Stop the process, get its status and signal/syscall masks.
1041 		 */
1042 		if (((P->status.pr_lwp.pr_flags & PR_STOPPED) &&
1043 		    Pstopstatus(P, PCDSTOP, 0) != 0) ||
1044 		    Pstopstatus(P, PCSTOP, 2000) != 0) {
1045 #ifndef _LP64
1046 			if (errno == EOVERFLOW) {
1047 				rc = G_LP64;
1048 				goto err;
1049 			}
1050 #endif
1051 			if (P->state == PS_LOST) {	/* WoV */
1052 				(void) mutex_destroy(&P->proc_lock);
1053 				goto again;
1054 			}
1055 			if ((errno != EINTR && errno != ERESTART) ||
1056 			    (P->state != PS_STOP &&
1057 			    !(P->status.pr_flags & PR_DSTOP))) {
1058 				if (P->state != PS_RUN && errno != ENOENT) {
1059 					dprintf("Pgrab: failed to PCSTOP\n");
1060 					rc = G_STRANGE;
1061 				} else {
1062 					rc = G_ZOMB;
1063 				}
1064 				goto err;
1065 			}
1066 		}
1067 
1068 		/*
1069 		 * Process should now either be stopped via /proc or there
1070 		 * should be an outstanding stop directive.
1071 		 */
1072 		if (!(P->status.pr_flags & (PR_ISTOP|PR_DSTOP))) {
1073 			dprintf("Pgrab: process is not stopped\n");
1074 			rc = G_STRANGE;
1075 			goto err;
1076 		}
1077 #ifndef _LP64
1078 		/*
1079 		 * Test this again now because the 32-bit victim process may
1080 		 * have exec'd a 64-bit process in the meantime.
1081 		 */
1082 		if (P->status.pr_dmodel == PR_MODEL_LP64) {
1083 			rc = G_LP64;
1084 			goto err;
1085 		}
1086 #endif
1087 	}
1088 
1089 	/*
1090 	 * Cancel all tracing flags unless the PGRAB_RETAIN flag is set.
1091 	 */
1092 	if (!(flags & PGRAB_RETAIN)) {
1093 		(void) Psysentry(P, 0, FALSE);
1094 		(void) Psysexit(P, 0, FALSE);
1095 		(void) Psignal(P, 0, FALSE);
1096 		(void) Pfault(P, 0, FALSE);
1097 		Psync(P);
1098 	}
1099 
1100 	*perr = 0;
1101 	return (P);
1102 
1103 err:
1104 	Pfree(P);
1105 	*perr = rc;
1106 	return (NULL);
1107 }
1108 
1109 /*
1110  * Return a printable string corresponding to a Pgrab() error return.
1111  */
1112 const char *
Pgrab_error(int error)1113 Pgrab_error(int error)
1114 {
1115 	const char *str;
1116 
1117 	switch (error) {
1118 	case G_NOPROC:
1119 		str = "no such process";
1120 		break;
1121 	case G_NOCORE:
1122 		str = "no such core file";
1123 		break;
1124 	case G_NOPROCORCORE:
1125 		str = "no such process or core file";
1126 		break;
1127 	case G_NOEXEC:
1128 		str = "cannot find executable file";
1129 		break;
1130 	case G_ZOMB:
1131 		str = "zombie process";
1132 		break;
1133 	case G_PERM:
1134 		str = "permission denied";
1135 		break;
1136 	case G_BUSY:
1137 		str = "process is traced";
1138 		break;
1139 	case G_SYS:
1140 		str = "system process";
1141 		break;
1142 	case G_SELF:
1143 		str = "attempt to grab self";
1144 		break;
1145 	case G_INTR:
1146 		str = "operation interrupted";
1147 		break;
1148 	case G_LP64:
1149 		str = "program is _LP64, self is not";
1150 		break;
1151 	case G_FORMAT:
1152 		str = "file is not an ELF core file";
1153 		break;
1154 	case G_ELF:
1155 		str = "libelf error";
1156 		break;
1157 	case G_NOTE:
1158 		str = "core file is corrupt or missing required data";
1159 		break;
1160 	case G_STRANGE:
1161 		str = "unanticipated system error";
1162 		break;
1163 	case G_ISAINVAL:
1164 		str = "wrong ELF machine type";
1165 		break;
1166 	case G_BADLWPS:
1167 		str = "bad lwp specification";
1168 		break;
1169 	case G_NOFD:
1170 		str = "too many open files";
1171 		break;
1172 	default:
1173 		str = "unknown error";
1174 		break;
1175 	}
1176 
1177 	return (str);
1178 }
1179 
1180 /*
1181  * Free a process control structure.
1182  * Close the file descriptors but don't do the Prelease logic.
1183  */
1184 void
Pfree(struct ps_prochandle * P)1185 Pfree(struct ps_prochandle *P)
1186 {
1187 	uint_t i;
1188 	fd_info_t *fip;
1189 
1190 	if (P->ucaddrs != NULL) {
1191 		free(P->ucaddrs);
1192 		P->ucaddrs = NULL;
1193 		P->ucnelems = 0;
1194 	}
1195 
1196 	(void) mutex_lock(&P->proc_lock);
1197 	if (P->hashtab != NULL) {
1198 		struct ps_lwphandle *L;
1199 		for (i = 0; i < HASHSIZE; i++) {
1200 			while ((L = P->hashtab[i]) != NULL)
1201 				Lfree_internal(P, L);
1202 		}
1203 		free(P->hashtab);
1204 	}
1205 
1206 	while ((fip = list_remove_head(&P->fd_head)) != NULL) {
1207 		proc_fdinfo_free(fip->fd_info);
1208 		free(fip);
1209 	}
1210 	(void) mutex_unlock(&P->proc_lock);
1211 	(void) mutex_destroy(&P->proc_lock);
1212 
1213 	free(P->zoneroot);
1214 
1215 	if (P->agentctlfd >= 0)
1216 		(void) close(P->agentctlfd);
1217 	if (P->agentstatfd >= 0)
1218 		(void) close(P->agentstatfd);
1219 	if (P->ctlfd >= 0)
1220 		(void) close(P->ctlfd);
1221 	if (P->asfd >= 0)
1222 		(void) close(P->asfd);
1223 	if (P->statfd >= 0)
1224 		(void) close(P->statfd);
1225 	Preset_maps(P);
1226 	P->ops.pop_fini(P, P->data);
1227 
1228 	/* clear out the structure as a precaution against reuse */
1229 	(void) memset(P, 0, sizeof (*P));
1230 	P->ctlfd = -1;
1231 	P->asfd = -1;
1232 	P->statfd = -1;
1233 	P->agentctlfd = -1;
1234 	P->agentstatfd = -1;
1235 
1236 	free(P);
1237 }
1238 
1239 /*
1240  * Return the state of the process, one of the PS_* values.
1241  */
1242 int
Pstate(struct ps_prochandle * P)1243 Pstate(struct ps_prochandle *P)
1244 {
1245 	return (P->state);
1246 }
1247 
1248 /*
1249  * Return the open address space file descriptor for the process.
1250  * Clients must not close this file descriptor, not use it
1251  * after the process is freed.
1252  */
1253 int
Pasfd(struct ps_prochandle * P)1254 Pasfd(struct ps_prochandle *P)
1255 {
1256 	return (P->asfd);
1257 }
1258 
1259 /*
1260  * Return the open control file descriptor for the process.
1261  * Clients must not close this file descriptor, not use it
1262  * after the process is freed.
1263  */
1264 int
Pctlfd(struct ps_prochandle * P)1265 Pctlfd(struct ps_prochandle *P)
1266 {
1267 	return (P->ctlfd);
1268 }
1269 
1270 /*
1271  * Return a pointer to the process psinfo structure.
1272  * Clients should not hold on to this pointer indefinitely.
1273  * It will become invalid on Prelease().
1274  */
1275 const psinfo_t *
Ppsinfo(struct ps_prochandle * P)1276 Ppsinfo(struct ps_prochandle *P)
1277 {
1278 	return (P->ops.pop_psinfo(P, &P->psinfo, P->data));
1279 }
1280 
1281 /*
1282  * Return a pointer to the process status structure.
1283  * Clients should not hold on to this pointer indefinitely.
1284  * It will become invalid on Prelease().
1285  */
1286 const pstatus_t *
Pstatus(struct ps_prochandle * P)1287 Pstatus(struct ps_prochandle *P)
1288 {
1289 	return (&P->status);
1290 }
1291 
1292 static void
Pread_status(struct ps_prochandle * P)1293 Pread_status(struct ps_prochandle *P)
1294 {
1295 	P->ops.pop_status(P, &P->status, P->data);
1296 }
1297 
1298 /*
1299  * Fill in a pointer to a process credentials structure.  The ngroups parameter
1300  * is the number of supplementary group entries allocated in the caller's cred
1301  * structure.  It should equal zero or one unless extra space has been
1302  * allocated for the group list by the caller.
1303  */
1304 int
Pcred(struct ps_prochandle * P,prcred_t * pcrp,int ngroups)1305 Pcred(struct ps_prochandle *P, prcred_t *pcrp, int ngroups)
1306 {
1307 	return (P->ops.pop_cred(P, pcrp, ngroups, P->data));
1308 }
1309 
1310 /* Return an allocated prsecflags_t */
1311 int
Psecflags(struct ps_prochandle * P,prsecflags_t ** psf)1312 Psecflags(struct ps_prochandle *P, prsecflags_t **psf)
1313 {
1314 	int ret;
1315 
1316 	if ((ret = P->ops.pop_secflags(P, psf, P->data)) == 0) {
1317 		if ((*psf)->pr_version != PRSECFLAGS_VERSION_1) {
1318 			free(*psf);
1319 			*psf = NULL;
1320 			errno = EINVAL;
1321 			return (-1);
1322 		}
1323 	}
1324 
1325 	return (ret);
1326 }
1327 
1328 void
Psecflags_free(prsecflags_t * psf)1329 Psecflags_free(prsecflags_t *psf)
1330 {
1331 	free(psf);
1332 }
1333 
1334 static prheader_t *
Plstatus(struct ps_prochandle * P)1335 Plstatus(struct ps_prochandle *P)
1336 {
1337 	return (P->ops.pop_lstatus(P, P->data));
1338 }
1339 
1340 static prheader_t *
Plpsinfo(struct ps_prochandle * P)1341 Plpsinfo(struct ps_prochandle *P)
1342 {
1343 	return (P->ops.pop_lpsinfo(P, P->data));
1344 }
1345 
1346 
1347 #if defined(__i386) || defined(__amd64)
1348 /*
1349  * Fill in a pointer to a process LDT structure.
1350  * The caller provides a buffer of size 'nldt * sizeof (struct ssd)';
1351  * If pldt == NULL or nldt == 0, we return the number of existing LDT entries.
1352  * Otherwise we return the actual number of LDT entries fetched (<= nldt).
1353  */
1354 int
Pldt(struct ps_prochandle * P,struct ssd * pldt,int nldt)1355 Pldt(struct ps_prochandle *P, struct ssd *pldt, int nldt)
1356 {
1357 	return (P->ops.pop_ldt(P, pldt, nldt, P->data));
1358 
1359 }
1360 #endif	/* __i386 */
1361 
1362 /* ARGSUSED */
1363 void
Ppriv_free(struct ps_prochandle * P,prpriv_t * prv)1364 Ppriv_free(struct ps_prochandle *P, prpriv_t *prv)
1365 {
1366 	free(prv);
1367 }
1368 
1369 /*
1370  * Return a malloced process privilege structure in *pprv.
1371  */
1372 int
Ppriv(struct ps_prochandle * P,prpriv_t ** pprv)1373 Ppriv(struct ps_prochandle *P, prpriv_t **pprv)
1374 {
1375 	return (P->ops.pop_priv(P, pprv, P->data));
1376 }
1377 
1378 int
Psetpriv(struct ps_prochandle * P,prpriv_t * pprv)1379 Psetpriv(struct ps_prochandle *P, prpriv_t *pprv)
1380 {
1381 	int rc;
1382 	long *ctl;
1383 	size_t sz;
1384 
1385 	if (P->state == PS_DEAD) {
1386 		errno = EBADF;
1387 		return (-1);
1388 	}
1389 
1390 	sz = PRIV_PRPRIV_SIZE(pprv) + sizeof (long);
1391 
1392 	sz = ((sz - 1) / sizeof (long) + 1) * sizeof (long);
1393 
1394 	ctl = malloc(sz);
1395 	if (ctl == NULL)
1396 		return (-1);
1397 
1398 	ctl[0] = PCSPRIV;
1399 
1400 	(void) memcpy(&ctl[1], pprv, PRIV_PRPRIV_SIZE(pprv));
1401 
1402 	if (write(P->ctlfd, ctl, sz) != sz)
1403 		rc = -1;
1404 	else
1405 		rc = 0;
1406 
1407 	free(ctl);
1408 
1409 	return (rc);
1410 }
1411 
1412 void *
Pprivinfo(struct ps_prochandle * P)1413 Pprivinfo(struct ps_prochandle *P)
1414 {
1415 	core_info_t *core = P->data;
1416 
1417 	/* Use default from libc */
1418 	if (P->state != PS_DEAD)
1419 		return (NULL);
1420 
1421 	return (core->core_privinfo);
1422 }
1423 
1424 /*
1425  * Ensure that all cached state is written to the process.
1426  * The cached state is the LWP's signal mask and registers
1427  * and the process's tracing flags.
1428  */
1429 void
Psync(struct ps_prochandle * P)1430 Psync(struct ps_prochandle *P)
1431 {
1432 	int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
1433 	long cmd[6];
1434 	iovec_t iov[12];
1435 	int n = 0;
1436 
1437 	if (P->flags & SETHOLD) {
1438 		cmd[0] = PCSHOLD;
1439 		iov[n].iov_base = (caddr_t)&cmd[0];
1440 		iov[n++].iov_len = sizeof (long);
1441 		iov[n].iov_base = (caddr_t)&P->status.pr_lwp.pr_lwphold;
1442 		iov[n++].iov_len = sizeof (P->status.pr_lwp.pr_lwphold);
1443 	}
1444 	if (P->flags & SETREGS) {
1445 		cmd[1] = PCSREG;
1446 #ifdef __i386
1447 		/* XX64 we should probably restore REG_GS after this */
1448 		if (ctlfd == P->agentctlfd)
1449 			P->status.pr_lwp.pr_reg[GS] = 0;
1450 #elif defined(__amd64)
1451 		/* XX64 */
1452 #endif
1453 		iov[n].iov_base = (caddr_t)&cmd[1];
1454 		iov[n++].iov_len = sizeof (long);
1455 		iov[n].iov_base = (caddr_t)&P->status.pr_lwp.pr_reg[0];
1456 		iov[n++].iov_len = sizeof (P->status.pr_lwp.pr_reg);
1457 	}
1458 	if (P->flags & SETSIG) {
1459 		cmd[2] = PCSTRACE;
1460 		iov[n].iov_base = (caddr_t)&cmd[2];
1461 		iov[n++].iov_len = sizeof (long);
1462 		iov[n].iov_base = (caddr_t)&P->status.pr_sigtrace;
1463 		iov[n++].iov_len = sizeof (P->status.pr_sigtrace);
1464 	}
1465 	if (P->flags & SETFAULT) {
1466 		cmd[3] = PCSFAULT;
1467 		iov[n].iov_base = (caddr_t)&cmd[3];
1468 		iov[n++].iov_len = sizeof (long);
1469 		iov[n].iov_base = (caddr_t)&P->status.pr_flttrace;
1470 		iov[n++].iov_len = sizeof (P->status.pr_flttrace);
1471 	}
1472 	if (P->flags & SETENTRY) {
1473 		cmd[4] = PCSENTRY;
1474 		iov[n].iov_base = (caddr_t)&cmd[4];
1475 		iov[n++].iov_len = sizeof (long);
1476 		iov[n].iov_base = (caddr_t)&P->status.pr_sysentry;
1477 		iov[n++].iov_len = sizeof (P->status.pr_sysentry);
1478 	}
1479 	if (P->flags & SETEXIT) {
1480 		cmd[5] = PCSEXIT;
1481 		iov[n].iov_base = (caddr_t)&cmd[5];
1482 		iov[n++].iov_len = sizeof (long);
1483 		iov[n].iov_base = (caddr_t)&P->status.pr_sysexit;
1484 		iov[n++].iov_len = sizeof (P->status.pr_sysexit);
1485 	}
1486 
1487 	if (n == 0 || writev(ctlfd, iov, n) < 0)
1488 		return;		/* nothing to do or write failed */
1489 
1490 	P->flags &= ~(SETSIG|SETFAULT|SETENTRY|SETEXIT|SETHOLD|SETREGS);
1491 }
1492 
1493 /*
1494  * Reopen the /proc file (after PS_LOST).
1495  */
1496 int
Preopen(struct ps_prochandle * P)1497 Preopen(struct ps_prochandle *P)
1498 {
1499 	int fd;
1500 	char procname[PATH_MAX];
1501 	char *fname;
1502 
1503 	if (P->state == PS_DEAD || P->state == PS_IDLE)
1504 		return (0);
1505 
1506 	if (P->agentcnt > 0) {
1507 		P->agentcnt = 1;
1508 		Pdestroy_agent(P);
1509 	}
1510 
1511 	(void) snprintf(procname, sizeof (procname), "%s/%d/",
1512 	    procfs_path, (int)P->pid);
1513 	fname = procname + strlen(procname);
1514 
1515 	(void) strcpy(fname, "as");
1516 	if ((fd = open(procname, O_RDWR)) < 0 ||
1517 	    close(P->asfd) < 0 ||
1518 	    (fd = dupfd(fd, P->asfd)) != P->asfd) {
1519 		dprintf("Preopen: failed to open %s: %s\n",
1520 		    procname, strerror(errno));
1521 		if (fd >= 0)
1522 			(void) close(fd);
1523 		return (-1);
1524 	}
1525 	P->asfd = fd;
1526 
1527 	(void) strcpy(fname, "status");
1528 	if ((fd = open(procname, O_RDONLY)) < 0 ||
1529 	    close(P->statfd) < 0 ||
1530 	    (fd = dupfd(fd, P->statfd)) != P->statfd) {
1531 		dprintf("Preopen: failed to open %s: %s\n",
1532 		    procname, strerror(errno));
1533 		if (fd >= 0)
1534 			(void) close(fd);
1535 		return (-1);
1536 	}
1537 	P->statfd = fd;
1538 
1539 	(void) strcpy(fname, "ctl");
1540 	if ((fd = open(procname, O_WRONLY)) < 0 ||
1541 	    close(P->ctlfd) < 0 ||
1542 	    (fd = dupfd(fd, P->ctlfd)) != P->ctlfd) {
1543 		dprintf("Preopen: failed to open %s: %s\n",
1544 		    procname, strerror(errno));
1545 		if (fd >= 0)
1546 			(void) close(fd);
1547 		return (-1);
1548 	}
1549 	P->ctlfd = fd;
1550 
1551 	/*
1552 	 * Set the state to PS_RUN and wait for the process to stop so that
1553 	 * we re-read the status from the new P->statfd.  If this fails, Pwait
1554 	 * will reset the state to PS_LOST and we fail the reopen.  Before
1555 	 * returning, we also forge a bit of P->status to allow the debugger to
1556 	 * see that we are PS_LOST following a successful exec.
1557 	 */
1558 	P->state = PS_RUN;
1559 	if (Pwait(P, 0) == -1) {
1560 #ifdef _ILP32
1561 		if (errno == EOVERFLOW)
1562 			P->status.pr_dmodel = PR_MODEL_LP64;
1563 #endif
1564 		P->status.pr_lwp.pr_why = PR_SYSEXIT;
1565 		P->status.pr_lwp.pr_what = SYS_execve;
1566 		P->status.pr_lwp.pr_errno = 0;
1567 		return (-1);
1568 	}
1569 
1570 	/*
1571 	 * The process should be stopped on exec (REQUESTED)
1572 	 * or else should be stopped on exit from exec() (SYSEXIT)
1573 	 */
1574 	if (P->state == PS_STOP &&
1575 	    (P->status.pr_lwp.pr_why == PR_REQUESTED ||
1576 	    (P->status.pr_lwp.pr_why == PR_SYSEXIT &&
1577 	    P->status.pr_lwp.pr_what == SYS_execve))) {
1578 		/* fake up stop-on-exit-from-execve */
1579 		if (P->status.pr_lwp.pr_why == PR_REQUESTED) {
1580 			P->status.pr_lwp.pr_why = PR_SYSEXIT;
1581 			P->status.pr_lwp.pr_what = SYS_execve;
1582 			P->status.pr_lwp.pr_errno = 0;
1583 		}
1584 	} else {
1585 		dprintf("Preopen: expected REQUESTED or "
1586 		    "SYSEXIT(SYS_execve) stop\n");
1587 	}
1588 
1589 	return (0);
1590 }
1591 
1592 /*
1593  * Define all settable flags other than the microstate accounting flags.
1594  */
1595 #define	ALL_SETTABLE_FLAGS (PR_FORK|PR_RLC|PR_KLC|PR_ASYNC|PR_BPTADJ|PR_PTRACE)
1596 
1597 /*
1598  * Restore /proc tracing flags to their original values
1599  * in preparation for releasing the process.
1600  * Also called by Pcreate() to clear all tracing flags.
1601  */
1602 static void
restore_tracing_flags(struct ps_prochandle * P)1603 restore_tracing_flags(struct ps_prochandle *P)
1604 {
1605 	long flags;
1606 	long cmd[4];
1607 	iovec_t iov[8];
1608 
1609 	if (P->flags & CREATED) {
1610 		/* we created this process; clear all tracing flags */
1611 		premptyset(&P->status.pr_sigtrace);
1612 		premptyset(&P->status.pr_flttrace);
1613 		premptyset(&P->status.pr_sysentry);
1614 		premptyset(&P->status.pr_sysexit);
1615 		if ((P->status.pr_flags & ALL_SETTABLE_FLAGS) != 0)
1616 			(void) Punsetflags(P, ALL_SETTABLE_FLAGS);
1617 	} else {
1618 		/* we grabbed the process; restore its tracing flags */
1619 		P->status.pr_sigtrace = P->orig_status.pr_sigtrace;
1620 		P->status.pr_flttrace = P->orig_status.pr_flttrace;
1621 		P->status.pr_sysentry = P->orig_status.pr_sysentry;
1622 		P->status.pr_sysexit  = P->orig_status.pr_sysexit;
1623 		if ((P->status.pr_flags & ALL_SETTABLE_FLAGS) !=
1624 		    (flags = (P->orig_status.pr_flags & ALL_SETTABLE_FLAGS))) {
1625 			(void) Punsetflags(P, ALL_SETTABLE_FLAGS);
1626 			if (flags)
1627 				(void) Psetflags(P, flags);
1628 		}
1629 	}
1630 
1631 	cmd[0] = PCSTRACE;
1632 	iov[0].iov_base = (caddr_t)&cmd[0];
1633 	iov[0].iov_len = sizeof (long);
1634 	iov[1].iov_base = (caddr_t)&P->status.pr_sigtrace;
1635 	iov[1].iov_len = sizeof (P->status.pr_sigtrace);
1636 
1637 	cmd[1] = PCSFAULT;
1638 	iov[2].iov_base = (caddr_t)&cmd[1];
1639 	iov[2].iov_len = sizeof (long);
1640 	iov[3].iov_base = (caddr_t)&P->status.pr_flttrace;
1641 	iov[3].iov_len = sizeof (P->status.pr_flttrace);
1642 
1643 	cmd[2] = PCSENTRY;
1644 	iov[4].iov_base = (caddr_t)&cmd[2];
1645 	iov[4].iov_len = sizeof (long);
1646 	iov[5].iov_base = (caddr_t)&P->status.pr_sysentry;
1647 	iov[5].iov_len = sizeof (P->status.pr_sysentry);
1648 
1649 	cmd[3] = PCSEXIT;
1650 	iov[6].iov_base = (caddr_t)&cmd[3];
1651 	iov[6].iov_len = sizeof (long);
1652 	iov[7].iov_base = (caddr_t)&P->status.pr_sysexit;
1653 	iov[7].iov_len = sizeof (P->status.pr_sysexit);
1654 
1655 	(void) writev(P->ctlfd, iov, 8);
1656 
1657 	P->flags &= ~(SETSIG|SETFAULT|SETENTRY|SETEXIT);
1658 }
1659 
1660 /*
1661  * Release the process.  Frees the process control structure.
1662  * flags:
1663  *	PRELEASE_CLEAR	Clear all tracing flags.
1664  *	PRELEASE_RETAIN	Retain current tracing flags.
1665  *	PRELEASE_HANG	Leave the process stopped and abandoned.
1666  *	PRELEASE_KILL	Terminate the process with SIGKILL.
1667  */
1668 void
Prelease(struct ps_prochandle * P,int flags)1669 Prelease(struct ps_prochandle *P, int flags)
1670 {
1671 	if (P->state == PS_DEAD) {
1672 		dprintf("Prelease: releasing handle %p PS_DEAD of pid %d\n",
1673 		    (void *)P, (int)P->pid);
1674 		Pfree(P);
1675 		return;
1676 	}
1677 
1678 	if (P->state == PS_IDLE) {
1679 		file_info_t *fptr = list_head(&P->file_head);
1680 		dprintf("Prelease: releasing handle %p PS_IDLE of file %s\n",
1681 		    (void *)P, fptr->file_pname);
1682 		Pfree(P);
1683 		return;
1684 	}
1685 
1686 	dprintf("Prelease: releasing handle %p pid %d\n",
1687 	    (void *)P, (int)P->pid);
1688 
1689 	if (P->ctlfd == -1) {
1690 		Pfree(P);
1691 		return;
1692 	}
1693 
1694 	if (P->agentcnt > 0) {
1695 		P->agentcnt = 1;
1696 		Pdestroy_agent(P);
1697 	}
1698 
1699 	/*
1700 	 * Attempt to stop the process.
1701 	 */
1702 	P->state = PS_RUN;
1703 	(void) Pstop(P, 1000);
1704 
1705 	if (flags & PRELEASE_KILL) {
1706 		if (P->state == PS_STOP)
1707 			(void) Psetrun(P, SIGKILL, 0);
1708 		(void) kill(P->pid, SIGKILL);
1709 		Pfree(P);
1710 		return;
1711 	}
1712 
1713 	/*
1714 	 * If we lost control, all we can do now is close the files.
1715 	 * In this case, the last close sets the process running.
1716 	 */
1717 	if (P->state != PS_STOP &&
1718 	    (P->status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP)) == 0) {
1719 		Pfree(P);
1720 		return;
1721 	}
1722 
1723 	/*
1724 	 * We didn't lose control; we do more.
1725 	 */
1726 	Psync(P);
1727 
1728 	if (flags & PRELEASE_CLEAR)
1729 		P->flags |= CREATED;
1730 
1731 	if (!(flags & PRELEASE_RETAIN))
1732 		restore_tracing_flags(P);
1733 
1734 	if (flags & PRELEASE_HANG) {
1735 		/* Leave the process stopped and abandoned */
1736 		(void) Punsetflags(P, PR_RLC|PR_KLC);
1737 		Pfree(P);
1738 		return;
1739 	}
1740 
1741 	/*
1742 	 * Set the process running if we created it or if it was
1743 	 * not originally stopped or directed to stop via /proc
1744 	 * or if we were given the PRELEASE_CLEAR flag.
1745 	 */
1746 	if ((P->flags & CREATED) ||
1747 	    (P->orig_status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP)) == 0) {
1748 		(void) Psetflags(P, PR_RLC);
1749 		/*
1750 		 * We do this repeatedly because the process may have
1751 		 * more than one LWP stopped on an event of interest.
1752 		 * This makes sure all of them are set running.
1753 		 */
1754 		do {
1755 			if (Psetrun(P, 0, 0) == -1 && errno == EBUSY)
1756 				break; /* Agent LWP may be stuck */
1757 		} while (Pstopstatus(P, PCNULL, 0) == 0 &&
1758 		    P->status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP));
1759 
1760 		if (P->status.pr_lwp.pr_flags & (PR_ISTOP|PR_DSTOP))
1761 			dprintf("Prelease: failed to set process running\n");
1762 	}
1763 
1764 	Pfree(P);
1765 }
1766 
1767 /* debugging */
1768 void
prldump(const char * caller,lwpstatus_t * lsp)1769 prldump(const char *caller, lwpstatus_t *lsp)
1770 {
1771 	char name[32];
1772 	uint32_t bits;
1773 
1774 	switch (lsp->pr_why) {
1775 	case PR_REQUESTED:
1776 		dprintf("%s: REQUESTED\n", caller);
1777 		break;
1778 	case PR_SIGNALLED:
1779 		dprintf("%s: SIGNALLED %s\n", caller,
1780 		    proc_signame(lsp->pr_what, name, sizeof (name)));
1781 		break;
1782 	case PR_FAULTED:
1783 		dprintf("%s: FAULTED %s\n", caller,
1784 		    proc_fltname(lsp->pr_what, name, sizeof (name)));
1785 		break;
1786 	case PR_SYSENTRY:
1787 		dprintf("%s: SYSENTRY %s\n", caller,
1788 		    proc_sysname(lsp->pr_what, name, sizeof (name)));
1789 		break;
1790 	case PR_SYSEXIT:
1791 		dprintf("%s: SYSEXIT %s\n", caller,
1792 		    proc_sysname(lsp->pr_what, name, sizeof (name)));
1793 		break;
1794 	case PR_JOBCONTROL:
1795 		dprintf("%s: JOBCONTROL %s\n", caller,
1796 		    proc_signame(lsp->pr_what, name, sizeof (name)));
1797 		break;
1798 	case PR_SUSPENDED:
1799 		dprintf("%s: SUSPENDED\n", caller);
1800 		break;
1801 	default:
1802 		dprintf("%s: Unknown\n", caller);
1803 		break;
1804 	}
1805 
1806 	if (lsp->pr_cursig)
1807 		dprintf("%s: p_cursig  = %d\n", caller, lsp->pr_cursig);
1808 
1809 	bits = *((uint32_t *)&lsp->pr_lwppend);
1810 	if (bits)
1811 		dprintf("%s: pr_lwppend = 0x%.8X\n", caller, bits);
1812 }
1813 
1814 /* debugging */
1815 static void
prdump(struct ps_prochandle * P)1816 prdump(struct ps_prochandle *P)
1817 {
1818 	uint32_t bits;
1819 
1820 	prldump("Pstopstatus", &P->status.pr_lwp);
1821 
1822 	bits = *((uint32_t *)&P->status.pr_sigpend);
1823 	if (bits)
1824 		dprintf("Pstopstatus: pr_sigpend = 0x%.8X\n", bits);
1825 }
1826 
1827 /*
1828  * Wait for the specified process to stop or terminate.
1829  * Or, just get the current status (PCNULL).
1830  * Or, direct it to stop and get the current status (PCDSTOP).
1831  * If the agent LWP exists, do these things to the agent,
1832  * else do these things to the process as a whole.
1833  */
1834 int
Pstopstatus(struct ps_prochandle * P,long request,uint_t msec)1835 Pstopstatus(struct ps_prochandle *P,
1836     long request,		/* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */
1837     uint_t msec)		/* if non-zero, timeout in milliseconds */
1838 {
1839 	int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
1840 	long ctl[3];
1841 	ssize_t rc;
1842 	int err;
1843 	int old_state = P->state;
1844 
1845 	switch (P->state) {
1846 	case PS_RUN:
1847 		break;
1848 	case PS_STOP:
1849 		if (request != PCNULL && request != PCDSTOP)
1850 			return (0);
1851 		break;
1852 	case PS_LOST:
1853 		if (request != PCNULL) {
1854 			errno = EAGAIN;
1855 			return (-1);
1856 		}
1857 		break;
1858 	case PS_UNDEAD:
1859 	case PS_DEAD:
1860 	case PS_IDLE:
1861 		if (request != PCNULL) {
1862 			errno = ENOENT;
1863 			return (-1);
1864 		}
1865 		break;
1866 	default:	/* corrupted state */
1867 		dprintf("Pstopstatus: corrupted state: %d\n", P->state);
1868 		errno = EINVAL;
1869 		return (-1);
1870 	}
1871 
1872 	ctl[0] = PCDSTOP;
1873 	ctl[1] = PCTWSTOP;
1874 	ctl[2] = (long)msec;
1875 	rc = 0;
1876 	switch (request) {
1877 	case PCSTOP:
1878 		rc = write(ctlfd, &ctl[0], 3*sizeof (long));
1879 		break;
1880 	case PCWSTOP:
1881 		rc = write(ctlfd, &ctl[1], 2*sizeof (long));
1882 		break;
1883 	case PCDSTOP:
1884 		rc = write(ctlfd, &ctl[0], 1*sizeof (long));
1885 		break;
1886 	case PCNULL:
1887 		if (P->state == PS_DEAD || P->state == PS_IDLE)
1888 			return (0);
1889 		break;
1890 	default:	/* programming error */
1891 		errno = EINVAL;
1892 		return (-1);
1893 	}
1894 	err = (rc < 0)? errno : 0;
1895 	Psync(P);
1896 
1897 	if (P->agentstatfd < 0) {
1898 		if (pread(P->statfd, &P->status,
1899 		    sizeof (P->status), (off_t)0) < 0)
1900 			err = errno;
1901 	} else {
1902 		if (pread(P->agentstatfd, &P->status.pr_lwp,
1903 		    sizeof (P->status.pr_lwp), (off_t)0) < 0)
1904 			err = errno;
1905 		P->status.pr_flags = P->status.pr_lwp.pr_flags;
1906 	}
1907 
1908 	if (err) {
1909 		switch (err) {
1910 		case EINTR:		/* user typed ctl-C */
1911 		case ERESTART:
1912 			dprintf("Pstopstatus: EINTR\n");
1913 			break;
1914 		case EAGAIN:		/* we lost control of the the process */
1915 		case EOVERFLOW:
1916 			dprintf("Pstopstatus: PS_LOST, errno=%d\n", err);
1917 			P->state = PS_LOST;
1918 			break;
1919 		default:		/* check for dead process */
1920 			if (_libproc_debug) {
1921 				const char *errstr;
1922 
1923 				switch (request) {
1924 				case PCNULL:
1925 					errstr = "Pstopstatus PCNULL"; break;
1926 				case PCSTOP:
1927 					errstr = "Pstopstatus PCSTOP"; break;
1928 				case PCDSTOP:
1929 					errstr = "Pstopstatus PCDSTOP"; break;
1930 				case PCWSTOP:
1931 					errstr = "Pstopstatus PCWSTOP"; break;
1932 				default:
1933 					errstr = "Pstopstatus PC???"; break;
1934 				}
1935 				dprintf("%s: %s\n", errstr, strerror(err));
1936 			}
1937 			deadcheck(P);
1938 			break;
1939 		}
1940 		if (err != EINTR && err != ERESTART) {
1941 			errno = err;
1942 			return (-1);
1943 		}
1944 	}
1945 
1946 	if (!(P->status.pr_flags & PR_STOPPED)) {
1947 		P->state = PS_RUN;
1948 		if (request == PCNULL || request == PCDSTOP || msec != 0)
1949 			return (0);
1950 		dprintf("Pstopstatus: process is not stopped\n");
1951 		errno = EPROTO;
1952 		return (-1);
1953 	}
1954 
1955 	P->state = PS_STOP;
1956 
1957 	if (_libproc_debug)	/* debugging */
1958 		prdump(P);
1959 
1960 	/*
1961 	 * If the process was already stopped coming into Pstopstatus(),
1962 	 * then don't use its PC to set P->sysaddr since it may have been
1963 	 * changed since the time the process originally stopped.
1964 	 */
1965 	if (old_state == PS_STOP)
1966 		return (0);
1967 
1968 	switch (P->status.pr_lwp.pr_why) {
1969 	case PR_SYSENTRY:
1970 	case PR_SYSEXIT:
1971 		if (Pissyscall_prev(P, P->status.pr_lwp.pr_reg[R_PC],
1972 		    &P->sysaddr) == 0)
1973 			P->sysaddr = P->status.pr_lwp.pr_reg[R_PC];
1974 		break;
1975 	case PR_REQUESTED:
1976 	case PR_SIGNALLED:
1977 	case PR_FAULTED:
1978 	case PR_JOBCONTROL:
1979 	case PR_SUSPENDED:
1980 		break;
1981 	default:
1982 		errno = EPROTO;
1983 		return (-1);
1984 	}
1985 
1986 	return (0);
1987 }
1988 
1989 /*
1990  * Wait for the process to stop for any reason.
1991  */
1992 int
Pwait(struct ps_prochandle * P,uint_t msec)1993 Pwait(struct ps_prochandle *P, uint_t msec)
1994 {
1995 	return (Pstopstatus(P, PCWSTOP, msec));
1996 }
1997 
1998 /*
1999  * Direct the process to stop; wait for it to stop.
2000  */
2001 int
Pstop(struct ps_prochandle * P,uint_t msec)2002 Pstop(struct ps_prochandle *P, uint_t msec)
2003 {
2004 	return (Pstopstatus(P, PCSTOP, msec));
2005 }
2006 
2007 /*
2008  * Direct the process to stop; don't wait.
2009  */
2010 int
Pdstop(struct ps_prochandle * P)2011 Pdstop(struct ps_prochandle *P)
2012 {
2013 	return (Pstopstatus(P, PCDSTOP, 0));
2014 }
2015 
2016 static void
deadcheck(struct ps_prochandle * P)2017 deadcheck(struct ps_prochandle *P)
2018 {
2019 	int fd;
2020 	void *buf;
2021 	size_t size;
2022 
2023 	if (P->statfd < 0)
2024 		P->state = PS_UNDEAD;
2025 	else {
2026 		if (P->agentstatfd < 0) {
2027 			fd = P->statfd;
2028 			buf = &P->status;
2029 			size = sizeof (P->status);
2030 		} else {
2031 			fd = P->agentstatfd;
2032 			buf = &P->status.pr_lwp;
2033 			size = sizeof (P->status.pr_lwp);
2034 		}
2035 		while (pread(fd, buf, size, (off_t)0) != size) {
2036 			switch (errno) {
2037 			default:
2038 				P->state = PS_UNDEAD;
2039 				break;
2040 			case EINTR:
2041 			case ERESTART:
2042 				continue;
2043 			case EAGAIN:
2044 				P->state = PS_LOST;
2045 				break;
2046 			}
2047 			break;
2048 		}
2049 		P->status.pr_flags = P->status.pr_lwp.pr_flags;
2050 	}
2051 }
2052 
2053 /*
2054  * Get the value of one register from stopped process.
2055  */
2056 int
Pgetareg(struct ps_prochandle * P,int regno,prgreg_t * preg)2057 Pgetareg(struct ps_prochandle *P, int regno, prgreg_t *preg)
2058 {
2059 	if (regno < 0 || regno >= NPRGREG) {
2060 		errno = EINVAL;
2061 		return (-1);
2062 	}
2063 
2064 	if (P->state == PS_IDLE) {
2065 		errno = ENODATA;
2066 		return (-1);
2067 	}
2068 
2069 	if (P->state != PS_STOP && P->state != PS_DEAD) {
2070 		errno = EBUSY;
2071 		return (-1);
2072 	}
2073 
2074 	*preg = P->status.pr_lwp.pr_reg[regno];
2075 	return (0);
2076 }
2077 
2078 /*
2079  * Put value of one register into stopped process.
2080  */
2081 int
Pputareg(struct ps_prochandle * P,int regno,prgreg_t reg)2082 Pputareg(struct ps_prochandle *P, int regno, prgreg_t reg)
2083 {
2084 	if (regno < 0 || regno >= NPRGREG) {
2085 		errno = EINVAL;
2086 		return (-1);
2087 	}
2088 
2089 	if (P->state != PS_STOP) {
2090 		errno = EBUSY;
2091 		return (-1);
2092 	}
2093 
2094 	P->status.pr_lwp.pr_reg[regno] = reg;
2095 	P->flags |= SETREGS;	/* set registers before continuing */
2096 	return (0);
2097 }
2098 
2099 int
Psetrun(struct ps_prochandle * P,int sig,int flags)2100 Psetrun(struct ps_prochandle *P,
2101     int sig,	/* signal to pass to process */
2102     int flags)	/* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */
2103 {
2104 	int ctlfd = (P->agentctlfd >= 0) ? P->agentctlfd : P->ctlfd;
2105 	int sbits = (PR_DSTOP | PR_ISTOP | PR_ASLEEP);
2106 
2107 	long ctl[1 +					/* PCCFAULT	*/
2108 	    1 + sizeof (siginfo_t)/sizeof (long) +	/* PCSSIG/PCCSIG */
2109 	    2 ];					/* PCRUN	*/
2110 
2111 	long *ctlp = ctl;
2112 	size_t size;
2113 
2114 	if (P->state != PS_STOP && (P->status.pr_lwp.pr_flags & sbits) == 0) {
2115 		errno = EBUSY;
2116 		return (-1);
2117 	}
2118 
2119 	Psync(P);	/* flush tracing flags and registers */
2120 
2121 	if (flags & PRCFAULT) {		/* clear current fault */
2122 		*ctlp++ = PCCFAULT;
2123 		flags &= ~PRCFAULT;
2124 	}
2125 
2126 	if (flags & PRCSIG) {		/* clear current signal */
2127 		*ctlp++ = PCCSIG;
2128 		flags &= ~PRCSIG;
2129 	} else if (sig && sig != P->status.pr_lwp.pr_cursig) {
2130 		/* make current signal */
2131 		siginfo_t *infop;
2132 
2133 		*ctlp++ = PCSSIG;
2134 		infop = (siginfo_t *)ctlp;
2135 		(void) memset(infop, 0, sizeof (*infop));
2136 		infop->si_signo = sig;
2137 		ctlp += sizeof (siginfo_t) / sizeof (long);
2138 	}
2139 
2140 	*ctlp++ = PCRUN;
2141 	*ctlp++ = flags;
2142 	size = (char *)ctlp - (char *)ctl;
2143 
2144 	P->info_valid = 0;	/* will need to update map and file info */
2145 
2146 	/*
2147 	 * If we've cached ucontext-list information while we were stopped,
2148 	 * free it now.
2149 	 */
2150 	if (P->ucaddrs != NULL) {
2151 		free(P->ucaddrs);
2152 		P->ucaddrs = NULL;
2153 		P->ucnelems = 0;
2154 	}
2155 
2156 	if (write(ctlfd, ctl, size) != size) {
2157 		/* If it is dead or lost, return the real status, not PS_RUN */
2158 		if (errno == ENOENT || errno == EAGAIN) {
2159 			(void) Pstopstatus(P, PCNULL, 0);
2160 			return (0);
2161 		}
2162 		/* If it is not in a jobcontrol stop, issue an error message */
2163 		if (errno != EBUSY ||
2164 		    P->status.pr_lwp.pr_why != PR_JOBCONTROL) {
2165 			dprintf("Psetrun: %s\n", strerror(errno));
2166 			return (-1);
2167 		}
2168 		/* Otherwise pretend that the job-stopped process is running */
2169 	}
2170 
2171 	P->state = PS_RUN;
2172 	return (0);
2173 }
2174 
2175 ssize_t
Pread(struct ps_prochandle * P,void * buf,size_t nbyte,uintptr_t address)2176 Pread(struct ps_prochandle *P,
2177     void *buf,		/* caller's buffer */
2178     size_t nbyte,	/* number of bytes to read */
2179     uintptr_t address)	/* address in process */
2180 {
2181 	return (P->ops.pop_pread(P, buf, nbyte, address, P->data));
2182 }
2183 
2184 ssize_t
Pread_string(struct ps_prochandle * P,char * buf,size_t size,uintptr_t addr)2185 Pread_string(struct ps_prochandle *P,
2186     char *buf,			/* caller's buffer */
2187     size_t size,		/* upper limit on bytes to read */
2188     uintptr_t addr)		/* address in process */
2189 {
2190 	enum { STRSZ = 40 };
2191 	char string[STRSZ + 1];
2192 	ssize_t leng = 0;
2193 	int nbyte;
2194 
2195 	if (size < 2) {
2196 		errno = EINVAL;
2197 		return (-1);
2198 	}
2199 
2200 	size--;			/* ensure trailing null fits in buffer */
2201 
2202 	*buf = '\0';
2203 	string[STRSZ] = '\0';
2204 
2205 	for (nbyte = STRSZ; nbyte == STRSZ && leng < size; addr += STRSZ) {
2206 		if ((nbyte = P->ops.pop_pread(P, string, STRSZ, addr,
2207 		    P->data)) <= 0) {
2208 			buf[leng] = '\0';
2209 			return (leng ? leng : -1);
2210 		}
2211 		if ((nbyte = strlen(string)) > 0) {
2212 			if (leng + nbyte > size)
2213 				nbyte = size - leng;
2214 			(void) strncpy(buf + leng, string, nbyte);
2215 			leng += nbyte;
2216 		}
2217 	}
2218 	buf[leng] = '\0';
2219 	return (leng);
2220 }
2221 
2222 ssize_t
Pwrite(struct ps_prochandle * P,const void * buf,size_t nbyte,uintptr_t address)2223 Pwrite(struct ps_prochandle *P,
2224     const void *buf,	/* caller's buffer */
2225     size_t nbyte,	/* number of bytes to write */
2226     uintptr_t address)	/* address in process */
2227 {
2228 	return (P->ops.pop_pwrite(P, buf, nbyte, address, P->data));
2229 }
2230 
2231 int
Pclearsig(struct ps_prochandle * P)2232 Pclearsig(struct ps_prochandle *P)
2233 {
2234 	int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
2235 	long ctl = PCCSIG;
2236 
2237 	if (write(ctlfd, &ctl, sizeof (ctl)) != sizeof (ctl))
2238 		return (-1);
2239 	P->status.pr_lwp.pr_cursig = 0;
2240 	return (0);
2241 }
2242 
2243 int
Pclearfault(struct ps_prochandle * P)2244 Pclearfault(struct ps_prochandle *P)
2245 {
2246 	int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
2247 	long ctl = PCCFAULT;
2248 
2249 	if (write(ctlfd, &ctl, sizeof (ctl)) != sizeof (ctl))
2250 		return (-1);
2251 	return (0);
2252 }
2253 
2254 /*
2255  * Set a breakpoint trap, return original instruction.
2256  */
2257 int
Psetbkpt(struct ps_prochandle * P,uintptr_t address,ulong_t * saved)2258 Psetbkpt(struct ps_prochandle *P, uintptr_t address, ulong_t *saved)
2259 {
2260 	long ctl[1 + sizeof (priovec_t) / sizeof (long) +	/* PCREAD */
2261 	    1 + sizeof (priovec_t) / sizeof (long)];	/* PCWRITE */
2262 	long *ctlp = ctl;
2263 	size_t size;
2264 	priovec_t *iovp;
2265 	instr_t bpt = BPT;
2266 	instr_t old;
2267 
2268 	if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2269 	    P->state == PS_IDLE) {
2270 		errno = ENOENT;
2271 		return (-1);
2272 	}
2273 
2274 	/* fetch the old instruction */
2275 	*ctlp++ = PCREAD;
2276 	iovp = (priovec_t *)ctlp;
2277 	iovp->pio_base = &old;
2278 	iovp->pio_len = sizeof (old);
2279 	iovp->pio_offset = address;
2280 	ctlp += sizeof (priovec_t) / sizeof (long);
2281 
2282 	/* write the BPT instruction */
2283 	*ctlp++ = PCWRITE;
2284 	iovp = (priovec_t *)ctlp;
2285 	iovp->pio_base = &bpt;
2286 	iovp->pio_len = sizeof (bpt);
2287 	iovp->pio_offset = address;
2288 	ctlp += sizeof (priovec_t) / sizeof (long);
2289 
2290 	size = (char *)ctlp - (char *)ctl;
2291 	if (write(P->ctlfd, ctl, size) != size)
2292 		return (-1);
2293 
2294 	/*
2295 	 * Fail if there was already a breakpoint there from another debugger
2296 	 * or DTrace's user-level tracing on x86.
2297 	 */
2298 	if (old == BPT) {
2299 		errno = EBUSY;
2300 		return (-1);
2301 	}
2302 
2303 	*saved = (ulong_t)old;
2304 	return (0);
2305 }
2306 
2307 /*
2308  * Restore original instruction where a breakpoint was set.
2309  */
2310 int
Pdelbkpt(struct ps_prochandle * P,uintptr_t address,ulong_t saved)2311 Pdelbkpt(struct ps_prochandle *P, uintptr_t address, ulong_t saved)
2312 {
2313 	instr_t old = (instr_t)saved;
2314 	instr_t cur;
2315 
2316 	if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2317 	    P->state == PS_IDLE) {
2318 		errno = ENOENT;
2319 		return (-1);
2320 	}
2321 
2322 	/*
2323 	 * If the breakpoint instruction we had placed has been overwritten
2324 	 * with a new instruction, then don't try to replace it with the
2325 	 * old instruction. Doing do can cause problems with self-modifying
2326 	 * code -- PLTs for example. If the Pread() fails, we assume that we
2327 	 * should proceed though most likely the Pwrite() will also fail.
2328 	 */
2329 	if (Pread(P, &cur, sizeof (cur), address) == sizeof (cur) &&
2330 	    cur != BPT)
2331 		return (0);
2332 
2333 	if (Pwrite(P, &old, sizeof (old), address) != sizeof (old))
2334 		return (-1);
2335 
2336 	return (0);
2337 }
2338 
2339 /*
2340  * Common code for Pxecbkpt() and Lxecbkpt().
2341  * Develop the array of requests that will do the job, then
2342  * write them to the specified control file descriptor.
2343  * Return the non-zero errno if the write fails.
2344  */
2345 static int
execute_bkpt(int ctlfd,const fltset_t * faultset,const sigset_t * sigmask,uintptr_t address,ulong_t saved)2346 execute_bkpt(
2347 	int ctlfd,		/* process or LWP control file descriptor */
2348 	const fltset_t *faultset,	/* current set of traced faults */
2349 	const sigset_t *sigmask,	/* current signal mask */
2350 	uintptr_t address,		/* address of breakpint */
2351 	ulong_t saved)			/* the saved instruction */
2352 {
2353 	long ctl[
2354 	    1 + sizeof (sigset_t) / sizeof (long) +		/* PCSHOLD */
2355 	    1 + sizeof (fltset_t) / sizeof (long) +		/* PCSFAULT */
2356 	    1 + sizeof (priovec_t) / sizeof (long) +		/* PCWRITE */
2357 	    2 +							/* PCRUN */
2358 	    1 +							/* PCWSTOP */
2359 	    1 +							/* PCCFAULT */
2360 	    1 + sizeof (priovec_t) / sizeof (long) +		/* PCWRITE */
2361 	    1 + sizeof (fltset_t) / sizeof (long) +		/* PCSFAULT */
2362 	    1 + sizeof (sigset_t) / sizeof (long)];		/* PCSHOLD */
2363 	long *ctlp = ctl;
2364 	sigset_t unblock;
2365 	size_t size;
2366 	ssize_t ssize;
2367 	priovec_t *iovp;
2368 	sigset_t *holdp;
2369 	fltset_t *faultp;
2370 	instr_t old = (instr_t)saved;
2371 	instr_t bpt = BPT;
2372 	int error = 0;
2373 
2374 	/* block our signals for the duration */
2375 	(void) sigprocmask(SIG_BLOCK, &blockable_sigs, &unblock);
2376 
2377 	/* hold posted signals */
2378 	*ctlp++ = PCSHOLD;
2379 	holdp = (sigset_t *)ctlp;
2380 	prfillset(holdp);
2381 	prdelset(holdp, SIGKILL);
2382 	prdelset(holdp, SIGSTOP);
2383 	ctlp += sizeof (sigset_t) / sizeof (long);
2384 
2385 	/* force tracing of FLTTRACE */
2386 	if (!(prismember(faultset, FLTTRACE))) {
2387 		*ctlp++ = PCSFAULT;
2388 		faultp = (fltset_t *)ctlp;
2389 		*faultp = *faultset;
2390 		praddset(faultp, FLTTRACE);
2391 		ctlp += sizeof (fltset_t) / sizeof (long);
2392 	}
2393 
2394 	/* restore the old instruction */
2395 	*ctlp++ = PCWRITE;
2396 	iovp = (priovec_t *)ctlp;
2397 	iovp->pio_base = &old;
2398 	iovp->pio_len = sizeof (old);
2399 	iovp->pio_offset = address;
2400 	ctlp += sizeof (priovec_t) / sizeof (long);
2401 
2402 	/* clear current signal and fault; set running w/ single-step */
2403 	*ctlp++ = PCRUN;
2404 	*ctlp++ = PRCSIG | PRCFAULT | PRSTEP;
2405 
2406 	/* wait for stop, cancel the fault */
2407 	*ctlp++ = PCWSTOP;
2408 	*ctlp++ = PCCFAULT;
2409 
2410 	/* restore the breakpoint trap */
2411 	*ctlp++ = PCWRITE;
2412 	iovp = (priovec_t *)ctlp;
2413 	iovp->pio_base = &bpt;
2414 	iovp->pio_len = sizeof (bpt);
2415 	iovp->pio_offset = address;
2416 	ctlp += sizeof (priovec_t) / sizeof (long);
2417 
2418 	/* restore fault tracing set */
2419 	if (!(prismember(faultset, FLTTRACE))) {
2420 		*ctlp++ = PCSFAULT;
2421 		*(fltset_t *)ctlp = *faultset;
2422 		ctlp += sizeof (fltset_t) / sizeof (long);
2423 	}
2424 
2425 	/* restore the hold mask */
2426 	*ctlp++ = PCSHOLD;
2427 	*(sigset_t *)ctlp = *sigmask;
2428 	ctlp += sizeof (sigset_t) / sizeof (long);
2429 
2430 	size = (char *)ctlp - (char *)ctl;
2431 	if ((ssize = write(ctlfd, ctl, size)) != size)
2432 		error = (ssize == -1)? errno : EINTR;
2433 	(void) sigprocmask(SIG_SETMASK, &unblock, NULL);
2434 	return (error);
2435 }
2436 
2437 /*
2438  * Step over a breakpoint, i.e., execute the instruction that
2439  * really belongs at the breakpoint location (the current %pc)
2440  * and leave the process stopped at the next instruction.
2441  */
2442 int
Pxecbkpt(struct ps_prochandle * P,ulong_t saved)2443 Pxecbkpt(struct ps_prochandle *P, ulong_t saved)
2444 {
2445 	int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
2446 	int rv, error;
2447 
2448 	if (P->state != PS_STOP) {
2449 		errno = EBUSY;
2450 		return (-1);
2451 	}
2452 
2453 	Psync(P);
2454 
2455 	error = execute_bkpt(ctlfd,
2456 	    &P->status.pr_flttrace, &P->status.pr_lwp.pr_lwphold,
2457 	    P->status.pr_lwp.pr_reg[R_PC], saved);
2458 	rv = Pstopstatus(P, PCNULL, 0);
2459 
2460 	if (error != 0) {
2461 		if (P->status.pr_lwp.pr_why == PR_JOBCONTROL &&
2462 		    error == EBUSY) {	/* jobcontrol stop -- back off */
2463 			P->state = PS_RUN;
2464 			return (0);
2465 		}
2466 		if (error == ENOENT)
2467 			return (0);
2468 		errno = error;
2469 		return (-1);
2470 	}
2471 
2472 	return (rv);
2473 }
2474 
2475 /*
2476  * Install the watchpoint described by wp.
2477  */
2478 int
Psetwapt(struct ps_prochandle * P,const prwatch_t * wp)2479 Psetwapt(struct ps_prochandle *P, const prwatch_t *wp)
2480 {
2481 	long ctl[1 + sizeof (prwatch_t) / sizeof (long)];
2482 	prwatch_t *cwp = (prwatch_t *)&ctl[1];
2483 
2484 	if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2485 	    P->state == PS_IDLE) {
2486 		errno = ENOENT;
2487 		return (-1);
2488 	}
2489 
2490 	ctl[0] = PCWATCH;
2491 	cwp->pr_vaddr = wp->pr_vaddr;
2492 	cwp->pr_size = wp->pr_size;
2493 	cwp->pr_wflags = wp->pr_wflags;
2494 
2495 	if (write(P->ctlfd, ctl, sizeof (ctl)) != sizeof (ctl))
2496 		return (-1);
2497 
2498 	return (0);
2499 }
2500 
2501 /*
2502  * Remove the watchpoint described by wp.
2503  */
2504 int
Pdelwapt(struct ps_prochandle * P,const prwatch_t * wp)2505 Pdelwapt(struct ps_prochandle *P, const prwatch_t *wp)
2506 {
2507 	long ctl[1 + sizeof (prwatch_t) / sizeof (long)];
2508 	prwatch_t *cwp = (prwatch_t *)&ctl[1];
2509 
2510 	if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2511 	    P->state == PS_IDLE) {
2512 		errno = ENOENT;
2513 		return (-1);
2514 	}
2515 
2516 	ctl[0] = PCWATCH;
2517 	cwp->pr_vaddr = wp->pr_vaddr;
2518 	cwp->pr_size = wp->pr_size;
2519 	cwp->pr_wflags = 0;
2520 
2521 	if (write(P->ctlfd, ctl, sizeof (ctl)) != sizeof (ctl))
2522 		return (-1);
2523 
2524 	return (0);
2525 }
2526 
2527 /*
2528  * Common code for Pxecwapt() and Lxecwapt().  Develop the array of requests
2529  * that will do the job, then write them to the specified control file
2530  * descriptor.  Return the non-zero errno if the write fails.
2531  */
2532 static int
execute_wapt(int ctlfd,const fltset_t * faultset,const sigset_t * sigmask,const prwatch_t * wp)2533 execute_wapt(
2534 	int ctlfd,		/* process or LWP control file descriptor */
2535 	const fltset_t *faultset,	/* current set of traced faults */
2536 	const sigset_t *sigmask,	/* current signal mask */
2537 	const prwatch_t *wp)		/* watchpoint descriptor */
2538 {
2539 	long ctl[
2540 	    1 + sizeof (sigset_t) / sizeof (long) +		/* PCSHOLD */
2541 	    1 + sizeof (fltset_t) / sizeof (long) +		/* PCSFAULT */
2542 	    1 + sizeof (prwatch_t) / sizeof (long) +		/* PCWATCH */
2543 	    2 +							/* PCRUN */
2544 	    1 +							/* PCWSTOP */
2545 	    1 +							/* PCCFAULT */
2546 	    1 + sizeof (prwatch_t) / sizeof (long) +		/* PCWATCH */
2547 	    1 + sizeof (fltset_t) / sizeof (long) +		/* PCSFAULT */
2548 	    1 + sizeof (sigset_t) / sizeof (long)];		/* PCSHOLD */
2549 
2550 	long *ctlp = ctl;
2551 	int error = 0;
2552 
2553 	sigset_t unblock;
2554 	sigset_t *holdp;
2555 	fltset_t *faultp;
2556 	prwatch_t *prw;
2557 	ssize_t ssize;
2558 	size_t size;
2559 
2560 	(void) sigprocmask(SIG_BLOCK, &blockable_sigs, &unblock);
2561 
2562 	/*
2563 	 * Hold all posted signals in the victim process prior to stepping.
2564 	 */
2565 	*ctlp++ = PCSHOLD;
2566 	holdp = (sigset_t *)ctlp;
2567 	prfillset(holdp);
2568 	prdelset(holdp, SIGKILL);
2569 	prdelset(holdp, SIGSTOP);
2570 	ctlp += sizeof (sigset_t) / sizeof (long);
2571 
2572 	/*
2573 	 * Force tracing of FLTTRACE since we need to single step.
2574 	 */
2575 	if (!(prismember(faultset, FLTTRACE))) {
2576 		*ctlp++ = PCSFAULT;
2577 		faultp = (fltset_t *)ctlp;
2578 		*faultp = *faultset;
2579 		praddset(faultp, FLTTRACE);
2580 		ctlp += sizeof (fltset_t) / sizeof (long);
2581 	}
2582 
2583 	/*
2584 	 * Clear only the current watchpoint by setting pr_wflags to zero.
2585 	 */
2586 	*ctlp++ = PCWATCH;
2587 	prw = (prwatch_t *)ctlp;
2588 	prw->pr_vaddr = wp->pr_vaddr;
2589 	prw->pr_size = wp->pr_size;
2590 	prw->pr_wflags = 0;
2591 	ctlp += sizeof (prwatch_t) / sizeof (long);
2592 
2593 	/*
2594 	 * Clear the current signal and fault; set running with single-step.
2595 	 * Then wait for the victim to stop and cancel the FLTTRACE.
2596 	 */
2597 	*ctlp++ = PCRUN;
2598 	*ctlp++ = PRCSIG | PRCFAULT | PRSTEP;
2599 	*ctlp++ = PCWSTOP;
2600 	*ctlp++ = PCCFAULT;
2601 
2602 	/*
2603 	 * Restore the current watchpoint.
2604 	 */
2605 	*ctlp++ = PCWATCH;
2606 	(void) memcpy(ctlp, wp, sizeof (prwatch_t));
2607 	ctlp += sizeof (prwatch_t) / sizeof (long);
2608 
2609 	/*
2610 	 * Restore fault tracing set if we modified it.
2611 	 */
2612 	if (!(prismember(faultset, FLTTRACE))) {
2613 		*ctlp++ = PCSFAULT;
2614 		*(fltset_t *)ctlp = *faultset;
2615 		ctlp += sizeof (fltset_t) / sizeof (long);
2616 	}
2617 
2618 	/*
2619 	 * Restore the hold mask to the current hold mask (i.e. the one
2620 	 * before we executed any of the previous operations).
2621 	 */
2622 	*ctlp++ = PCSHOLD;
2623 	*(sigset_t *)ctlp = *sigmask;
2624 	ctlp += sizeof (sigset_t) / sizeof (long);
2625 
2626 	size = (char *)ctlp - (char *)ctl;
2627 	if ((ssize = write(ctlfd, ctl, size)) != size)
2628 		error = (ssize == -1)? errno : EINTR;
2629 	(void) sigprocmask(SIG_SETMASK, &unblock, NULL);
2630 	return (error);
2631 }
2632 
2633 /*
2634  * Step over a watchpoint, i.e., execute the instruction that was stopped by
2635  * the watchpoint, and then leave the LWP stopped at the next instruction.
2636  */
2637 int
Pxecwapt(struct ps_prochandle * P,const prwatch_t * wp)2638 Pxecwapt(struct ps_prochandle *P, const prwatch_t *wp)
2639 {
2640 	int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd;
2641 	int rv, error;
2642 
2643 	if (P->state != PS_STOP) {
2644 		errno = EBUSY;
2645 		return (-1);
2646 	}
2647 
2648 	Psync(P);
2649 	error = execute_wapt(ctlfd,
2650 	    &P->status.pr_flttrace, &P->status.pr_lwp.pr_lwphold, wp);
2651 	rv = Pstopstatus(P, PCNULL, 0);
2652 
2653 	if (error != 0) {
2654 		if (P->status.pr_lwp.pr_why == PR_JOBCONTROL &&
2655 		    error == EBUSY) {	/* jobcontrol stop -- back off */
2656 			P->state = PS_RUN;
2657 			return (0);
2658 		}
2659 		if (error == ENOENT)
2660 			return (0);
2661 		errno = error;
2662 		return (-1);
2663 	}
2664 
2665 	return (rv);
2666 }
2667 
2668 int
Psetflags(struct ps_prochandle * P,long flags)2669 Psetflags(struct ps_prochandle *P, long flags)
2670 {
2671 	int rc;
2672 	long ctl[2];
2673 
2674 	ctl[0] = PCSET;
2675 	ctl[1] = flags;
2676 
2677 	if (write(P->ctlfd, ctl, 2*sizeof (long)) != 2*sizeof (long)) {
2678 		rc = -1;
2679 	} else {
2680 		P->status.pr_flags |= flags;
2681 		P->status.pr_lwp.pr_flags |= flags;
2682 		rc = 0;
2683 	}
2684 
2685 	return (rc);
2686 }
2687 
2688 int
Punsetflags(struct ps_prochandle * P,long flags)2689 Punsetflags(struct ps_prochandle *P, long flags)
2690 {
2691 	int rc;
2692 	long ctl[2];
2693 
2694 	ctl[0] = PCUNSET;
2695 	ctl[1] = flags;
2696 
2697 	if (write(P->ctlfd, ctl, 2*sizeof (long)) != 2*sizeof (long)) {
2698 		rc = -1;
2699 	} else {
2700 		P->status.pr_flags &= ~flags;
2701 		P->status.pr_lwp.pr_flags &= ~flags;
2702 		rc = 0;
2703 	}
2704 
2705 	return (rc);
2706 }
2707 
2708 /*
2709  * Common function to allow clients to manipulate the action to be taken
2710  * on receipt of a signal, receipt of machine fault, entry to a system call,
2711  * or exit from a system call.  We make use of our private prset_* functions
2712  * in order to make this code be common.  The 'which' parameter identifies
2713  * the code for the event of interest (0 means change the entire set), and
2714  * the 'stop' parameter is a boolean indicating whether the process should
2715  * stop when the event of interest occurs.  The previous value is returned
2716  * to the caller; -1 is returned if an error occurred.
2717  */
2718 static int
Psetaction(struct ps_prochandle * P,void * sp,size_t size,uint_t flag,int max,int which,int stop)2719 Psetaction(struct ps_prochandle *P, void *sp, size_t size,
2720     uint_t flag, int max, int which, int stop)
2721 {
2722 	int oldval;
2723 
2724 	if (which < 0 || which > max) {
2725 		errno = EINVAL;
2726 		return (-1);
2727 	}
2728 
2729 	if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2730 	    P->state == PS_IDLE) {
2731 		errno = ENOENT;
2732 		return (-1);
2733 	}
2734 
2735 	oldval = prset_ismember(sp, size, which) ? TRUE : FALSE;
2736 
2737 	if (stop) {
2738 		if (which == 0) {
2739 			prset_fill(sp, size);
2740 			P->flags |= flag;
2741 		} else if (!oldval) {
2742 			prset_add(sp, size, which);
2743 			P->flags |= flag;
2744 		}
2745 	} else {
2746 		if (which == 0) {
2747 			prset_empty(sp, size);
2748 			P->flags |= flag;
2749 		} else if (oldval) {
2750 			prset_del(sp, size, which);
2751 			P->flags |= flag;
2752 		}
2753 	}
2754 
2755 	if (P->state == PS_RUN)
2756 		Psync(P);
2757 
2758 	return (oldval);
2759 }
2760 
2761 /*
2762  * Set action on specified signal.
2763  */
2764 int
Psignal(struct ps_prochandle * P,int which,int stop)2765 Psignal(struct ps_prochandle *P, int which, int stop)
2766 {
2767 	int oldval;
2768 
2769 	if (which == SIGKILL && stop != 0) {
2770 		errno = EINVAL;
2771 		return (-1);
2772 	}
2773 
2774 	oldval = Psetaction(P, &P->status.pr_sigtrace, sizeof (sigset_t),
2775 	    SETSIG, PRMAXSIG, which, stop);
2776 
2777 	if (oldval != -1 && which == 0 && stop != 0)
2778 		prdelset(&P->status.pr_sigtrace, SIGKILL);
2779 
2780 	return (oldval);
2781 }
2782 
2783 /*
2784  * Set all signal tracing flags.
2785  */
2786 void
Psetsignal(struct ps_prochandle * P,const sigset_t * set)2787 Psetsignal(struct ps_prochandle *P, const sigset_t *set)
2788 {
2789 	if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2790 	    P->state == PS_IDLE)
2791 		return;
2792 
2793 	P->status.pr_sigtrace = *set;
2794 	P->flags |= SETSIG;
2795 
2796 	if (P->state == PS_RUN)
2797 		Psync(P);
2798 }
2799 
2800 /*
2801  * Set action on specified fault.
2802  */
2803 int
Pfault(struct ps_prochandle * P,int which,int stop)2804 Pfault(struct ps_prochandle *P, int which, int stop)
2805 {
2806 	return (Psetaction(P, &P->status.pr_flttrace, sizeof (fltset_t),
2807 	    SETFAULT, PRMAXFAULT, which, stop));
2808 }
2809 
2810 /*
2811  * Set all machine fault tracing flags.
2812  */
2813 void
Psetfault(struct ps_prochandle * P,const fltset_t * set)2814 Psetfault(struct ps_prochandle *P, const fltset_t *set)
2815 {
2816 	if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2817 	    P->state == PS_IDLE)
2818 		return;
2819 
2820 	P->status.pr_flttrace = *set;
2821 	P->flags |= SETFAULT;
2822 
2823 	if (P->state == PS_RUN)
2824 		Psync(P);
2825 }
2826 
2827 /*
2828  * Set action on specified system call entry.
2829  */
2830 int
Psysentry(struct ps_prochandle * P,int which,int stop)2831 Psysentry(struct ps_prochandle *P, int which, int stop)
2832 {
2833 	return (Psetaction(P, &P->status.pr_sysentry, sizeof (sysset_t),
2834 	    SETENTRY, PRMAXSYS, which, stop));
2835 }
2836 
2837 /*
2838  * Set all system call entry tracing flags.
2839  */
2840 void
Psetsysentry(struct ps_prochandle * P,const sysset_t * set)2841 Psetsysentry(struct ps_prochandle *P, const sysset_t *set)
2842 {
2843 	if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2844 	    P->state == PS_IDLE)
2845 		return;
2846 
2847 	P->status.pr_sysentry = *set;
2848 	P->flags |= SETENTRY;
2849 
2850 	if (P->state == PS_RUN)
2851 		Psync(P);
2852 }
2853 
2854 /*
2855  * Set action on specified system call exit.
2856  */
2857 int
Psysexit(struct ps_prochandle * P,int which,int stop)2858 Psysexit(struct ps_prochandle *P, int which, int stop)
2859 {
2860 	return (Psetaction(P, &P->status.pr_sysexit, sizeof (sysset_t),
2861 	    SETEXIT, PRMAXSYS, which, stop));
2862 }
2863 
2864 /*
2865  * Set all system call exit tracing flags.
2866  */
2867 void
Psetsysexit(struct ps_prochandle * P,const sysset_t * set)2868 Psetsysexit(struct ps_prochandle *P, const sysset_t *set)
2869 {
2870 	if (P->state == PS_DEAD || P->state == PS_UNDEAD ||
2871 	    P->state == PS_IDLE)
2872 		return;
2873 
2874 	P->status.pr_sysexit = *set;
2875 	P->flags |= SETEXIT;
2876 
2877 	if (P->state == PS_RUN)
2878 		Psync(P);
2879 }
2880 
2881 /*
2882  * Utility function to read the contents of a file that contains a
2883  * prheader_t at the start (/proc/pid/lstatus or /proc/pid/lpsinfo).
2884  * Returns a malloc()d buffer or NULL on failure.
2885  */
2886 static prheader_t *
read_lfile(struct ps_prochandle * P,const char * lname)2887 read_lfile(struct ps_prochandle *P, const char *lname)
2888 {
2889 	prheader_t *Lhp;
2890 	char lpath[PATH_MAX];
2891 	struct stat64 statb;
2892 	int fd;
2893 	size_t size;
2894 	ssize_t rval;
2895 
2896 	(void) snprintf(lpath, sizeof (lpath), "%s/%d/%s", procfs_path,
2897 	    (int)P->status.pr_pid, lname);
2898 	if ((fd = open(lpath, O_RDONLY)) < 0 || fstat64(fd, &statb) != 0) {
2899 		if (fd >= 0)
2900 			(void) close(fd);
2901 		return (NULL);
2902 	}
2903 
2904 	/*
2905 	 * 'size' is just the initial guess at the buffer size.
2906 	 * It will have to grow if the number of lwps increases
2907 	 * while we are looking at the process.
2908 	 * 'size' must be larger than the actual file size.
2909 	 */
2910 	size = statb.st_size + 32;
2911 
2912 	for (;;) {
2913 		if ((Lhp = malloc(size)) == NULL)
2914 			break;
2915 		if ((rval = pread(fd, Lhp, size, 0)) < 0 ||
2916 		    rval <= sizeof (prheader_t)) {
2917 			free(Lhp);
2918 			Lhp = NULL;
2919 			break;
2920 		}
2921 		if (rval < size)
2922 			break;
2923 		/* need a bigger buffer */
2924 		free(Lhp);
2925 		size *= 2;
2926 	}
2927 
2928 	(void) close(fd);
2929 	return (Lhp);
2930 }
2931 
2932 /*
2933  * LWP iteration interface.
2934  */
2935 int
Plwp_iter(struct ps_prochandle * P,proc_lwp_f * func,void * cd)2936 Plwp_iter(struct ps_prochandle *P, proc_lwp_f *func, void *cd)
2937 {
2938 	prheader_t *Lhp;
2939 	lwpstatus_t *Lsp;
2940 	long nlwp;
2941 	int rv;
2942 
2943 	switch (P->state) {
2944 	case PS_RUN:
2945 		(void) Pstopstatus(P, PCNULL, 0);
2946 		break;
2947 
2948 	case PS_STOP:
2949 		Psync(P);
2950 		break;
2951 
2952 	case PS_IDLE:
2953 		errno = ENODATA;
2954 		return (-1);
2955 	}
2956 
2957 	/*
2958 	 * For either live processes or cores, the single LWP case is easy:
2959 	 * the pstatus_t contains the lwpstatus_t for the only LWP.
2960 	 */
2961 	if (P->status.pr_nlwp <= 1)
2962 		return (func(cd, &P->status.pr_lwp));
2963 
2964 	/*
2965 	 * For the core file multi-LWP case, we just iterate through the
2966 	 * list of LWP structs we read in from the core file.
2967 	 */
2968 	if (P->state == PS_DEAD) {
2969 		core_info_t *core = P->data;
2970 		lwp_info_t *lwp;
2971 
2972 		for (lwp = list_tail(&core->core_lwp_head); lwp != NULL;
2973 		    lwp = list_prev(&core->core_lwp_head, lwp)) {
2974 			if (lwp->lwp_psinfo.pr_sname != 'Z' &&
2975 			    (rv = func(cd, &lwp->lwp_status)) != 0)
2976 				break;
2977 		}
2978 
2979 		return (rv);
2980 	}
2981 
2982 	/*
2983 	 * For the live process multi-LWP case, we have to work a little
2984 	 * harder: the /proc/pid/lstatus file has the array of LWP structs.
2985 	 */
2986 	if ((Lhp = Plstatus(P)) == NULL)
2987 		return (-1);
2988 
2989 	for (nlwp = Lhp->pr_nent, Lsp = (lwpstatus_t *)(uintptr_t)(Lhp + 1);
2990 	    nlwp > 0;
2991 	    nlwp--, Lsp = (lwpstatus_t *)((uintptr_t)Lsp + Lhp->pr_entsize)) {
2992 		if ((rv = func(cd, Lsp)) != 0)
2993 			break;
2994 	}
2995 
2996 	free(Lhp);
2997 	return (rv);
2998 }
2999 
3000 /*
3001  * Extended LWP iteration interface.
3002  * Iterate over all LWPs, active and zombie.
3003  */
3004 int
Plwp_iter_all(struct ps_prochandle * P,proc_lwp_all_f * func,void * cd)3005 Plwp_iter_all(struct ps_prochandle *P, proc_lwp_all_f *func, void *cd)
3006 {
3007 	prheader_t *Lhp = NULL;
3008 	lwpstatus_t *Lsp;
3009 	lwpstatus_t *sp;
3010 	prheader_t *Lphp = NULL;
3011 	lwpsinfo_t *Lpsp;
3012 	long nstat;
3013 	long ninfo;
3014 	int rv;
3015 
3016 retry:
3017 	if (Lhp != NULL)
3018 		free(Lhp);
3019 	if (Lphp != NULL)
3020 		free(Lphp);
3021 	if (P->state == PS_RUN)
3022 		(void) Pstopstatus(P, PCNULL, 0);
3023 	(void) Ppsinfo(P);
3024 
3025 	if (P->state == PS_STOP)
3026 		Psync(P);
3027 
3028 	/*
3029 	 * For either live processes or cores, the single LWP case is easy:
3030 	 * the pstatus_t contains the lwpstatus_t for the only LWP and
3031 	 * the psinfo_t contains the lwpsinfo_t for the only LWP.
3032 	 */
3033 	if (P->status.pr_nlwp + P->status.pr_nzomb <= 1)
3034 		return (func(cd, &P->status.pr_lwp, &P->psinfo.pr_lwp));
3035 
3036 	/*
3037 	 * For the core file multi-LWP case, we just iterate through the
3038 	 * list of LWP structs we read in from the core file.
3039 	 */
3040 	if (P->state == PS_DEAD) {
3041 		core_info_t *core = P->data;
3042 		lwp_info_t *lwp;
3043 
3044 		for (lwp = list_tail(&core->core_lwp_head); lwp != NULL;
3045 		    lwp = list_prev(&core->core_lwp_head, lwp)) {
3046 			sp = (lwp->lwp_psinfo.pr_sname == 'Z')? NULL :
3047 			    &lwp->lwp_status;
3048 			if ((rv = func(cd, sp, &lwp->lwp_psinfo)) != 0)
3049 				break;
3050 		}
3051 
3052 		return (rv);
3053 	}
3054 
3055 	/*
3056 	 * For all other cases retrieve the array of lwpstatus_t's and
3057 	 * lwpsinfo_t's.
3058 	 */
3059 	if ((Lhp = Plstatus(P)) == NULL)
3060 		return (-1);
3061 	if ((Lphp = Plpsinfo(P)) == NULL) {
3062 		free(Lhp);
3063 		return (-1);
3064 	}
3065 
3066 	/*
3067 	 * If we are looking at a running process, or one we do not control,
3068 	 * the active and zombie lwps in the process may have changed since
3069 	 * we read the process status structure.  If so, just start over.
3070 	 */
3071 	if (Lhp->pr_nent != P->status.pr_nlwp ||
3072 	    Lphp->pr_nent != P->status.pr_nlwp + P->status.pr_nzomb)
3073 		goto retry;
3074 
3075 	/*
3076 	 * To be perfectly safe, prescan the two arrays, checking consistency.
3077 	 * We rely on /proc giving us lwpstatus_t's and lwpsinfo_t's in the
3078 	 * same order (the lwp directory order) in their respective files.
3079 	 * We also rely on there being (possibly) more lwpsinfo_t's than
3080 	 * lwpstatus_t's (the extra lwpsinfo_t's are for zombie lwps).
3081 	 */
3082 	Lsp = (lwpstatus_t *)(uintptr_t)(Lhp + 1);
3083 	Lpsp = (lwpsinfo_t *)(uintptr_t)(Lphp + 1);
3084 	nstat = Lhp->pr_nent;
3085 	for (ninfo = Lphp->pr_nent; ninfo != 0; ninfo--) {
3086 		if (Lpsp->pr_sname != 'Z') {
3087 			/*
3088 			 * Not a zombie lwp; check for matching lwpids.
3089 			 */
3090 			if (nstat == 0 || Lsp->pr_lwpid != Lpsp->pr_lwpid)
3091 				goto retry;
3092 			Lsp = (lwpstatus_t *)((uintptr_t)Lsp + Lhp->pr_entsize);
3093 			nstat--;
3094 		}
3095 		Lpsp = (lwpsinfo_t *)((uintptr_t)Lpsp + Lphp->pr_entsize);
3096 	}
3097 	if (nstat != 0)
3098 		goto retry;
3099 
3100 	/*
3101 	 * Rescan, this time for real.
3102 	 */
3103 	Lsp = (lwpstatus_t *)(uintptr_t)(Lhp + 1);
3104 	Lpsp = (lwpsinfo_t *)(uintptr_t)(Lphp + 1);
3105 	for (ninfo = Lphp->pr_nent; ninfo != 0; ninfo--) {
3106 		if (Lpsp->pr_sname != 'Z') {
3107 			sp = Lsp;
3108 			Lsp = (lwpstatus_t *)((uintptr_t)Lsp + Lhp->pr_entsize);
3109 		} else {
3110 			sp = NULL;
3111 		}
3112 		if ((rv = func(cd, sp, Lpsp)) != 0)
3113 			break;
3114 		Lpsp = (lwpsinfo_t *)((uintptr_t)Lpsp + Lphp->pr_entsize);
3115 	}
3116 
3117 	free(Lhp);
3118 	free(Lphp);
3119 	return (rv);
3120 }
3121 
3122 core_content_t
Pcontent(struct ps_prochandle * P)3123 Pcontent(struct ps_prochandle *P)
3124 {
3125 	core_info_t *core = P->data;
3126 
3127 	if (P->state == PS_DEAD)
3128 		return (core->core_content);
3129 	if (P->state == PS_IDLE)
3130 		return (CC_CONTENT_TEXT | CC_CONTENT_DATA | CC_CONTENT_CTF);
3131 
3132 	return (CC_CONTENT_ALL);
3133 }
3134 
3135 /*
3136  * =================================================================
3137  * The remainder of the functions in this file are for the
3138  * control of individual LWPs in the controlled process.
3139  * =================================================================
3140  */
3141 
3142 /*
3143  * Find an entry in the process hash table for the specified lwpid.
3144  * The entry will either point to an existing struct ps_lwphandle
3145  * or it will point to an empty slot for a new struct ps_lwphandle.
3146  */
3147 static struct ps_lwphandle **
Lfind(struct ps_prochandle * P,lwpid_t lwpid)3148 Lfind(struct ps_prochandle *P, lwpid_t lwpid)
3149 {
3150 	struct ps_lwphandle **Lp;
3151 	struct ps_lwphandle *L;
3152 
3153 	for (Lp = &P->hashtab[lwpid % (HASHSIZE - 1)];
3154 	    (L = *Lp) != NULL; Lp = &L->lwp_hash)
3155 		if (L->lwp_id == lwpid)
3156 			break;
3157 	return (Lp);
3158 }
3159 
3160 /*
3161  * Grab an LWP contained within the controlled process.
3162  * Return an opaque pointer to its LWP control structure.
3163  *	perr: pointer to error return code.
3164  */
3165 struct ps_lwphandle *
Lgrab(struct ps_prochandle * P,lwpid_t lwpid,int * perr)3166 Lgrab(struct ps_prochandle *P, lwpid_t lwpid, int *perr)
3167 {
3168 	struct ps_lwphandle **Lp;
3169 	struct ps_lwphandle *L;
3170 	int fd;
3171 	char procname[PATH_MAX];
3172 	char *fname;
3173 	int rc = 0;
3174 
3175 	(void) mutex_lock(&P->proc_lock);
3176 
3177 	if (P->state == PS_UNDEAD || P->state == PS_IDLE)
3178 		rc = G_NOPROC;
3179 	else if (P->hashtab == NULL &&
3180 	    (P->hashtab = calloc(HASHSIZE, sizeof (struct ps_lwphandle *)))
3181 	    == NULL)
3182 		rc = G_STRANGE;
3183 	else if (*(Lp = Lfind(P, lwpid)) != NULL)
3184 		rc = G_BUSY;
3185 	else if ((L = malloc(sizeof (struct ps_lwphandle))) == NULL)
3186 		rc = G_STRANGE;
3187 	if (rc) {
3188 		*perr = rc;
3189 		(void) mutex_unlock(&P->proc_lock);
3190 		return (NULL);
3191 	}
3192 
3193 	(void) memset(L, 0, sizeof (*L));
3194 	L->lwp_ctlfd = -1;
3195 	L->lwp_statfd = -1;
3196 	L->lwp_proc = P;
3197 	L->lwp_id = lwpid;
3198 	*Lp = L;	/* insert into the hash table */
3199 
3200 	if (P->state == PS_DEAD) {	/* core file */
3201 		if (getlwpstatus(P, lwpid, &L->lwp_status) == -1) {
3202 			rc = G_NOPROC;
3203 			goto err;
3204 		}
3205 		L->lwp_state = PS_DEAD;
3206 		*perr = 0;
3207 		(void) mutex_unlock(&P->proc_lock);
3208 		return (L);
3209 	}
3210 
3211 	/*
3212 	 * Open the /proc/<pid>/lwp/<lwpid> files
3213 	 */
3214 	(void) snprintf(procname, sizeof (procname), "%s/%d/lwp/%d/",
3215 	    procfs_path, (int)P->pid, (int)lwpid);
3216 	fname = procname + strlen(procname);
3217 	(void) set_minfd();
3218 
3219 	(void) strcpy(fname, "lwpstatus");
3220 	if ((fd = open(procname, O_RDONLY)) < 0 ||
3221 	    (fd = dupfd(fd, 0)) < 0) {
3222 		switch (errno) {
3223 		case ENOENT:
3224 			rc = G_NOPROC;
3225 			break;
3226 		default:
3227 			dprintf("Lgrab: failed to open %s: %s\n",
3228 			    procname, strerror(errno));
3229 			rc = G_STRANGE;
3230 			break;
3231 		}
3232 		goto err;
3233 	}
3234 	L->lwp_statfd = fd;
3235 
3236 	if (pread(fd, &L->lwp_status, sizeof (L->lwp_status), (off_t)0) < 0) {
3237 		switch (errno) {
3238 		case ENOENT:
3239 			rc = G_NOPROC;
3240 			break;
3241 		default:
3242 			dprintf("Lgrab: failed to read %s: %s\n",
3243 			    procname, strerror(errno));
3244 			rc = G_STRANGE;
3245 			break;
3246 		}
3247 		goto err;
3248 	}
3249 
3250 	(void) strcpy(fname, "lwpctl");
3251 	if ((fd = open(procname, O_WRONLY)) < 0 ||
3252 	    (fd = dupfd(fd, 0)) < 0) {
3253 		switch (errno) {
3254 		case ENOENT:
3255 			rc = G_NOPROC;
3256 			break;
3257 		default:
3258 			dprintf("Lgrab: failed to open %s: %s\n",
3259 			    procname, strerror(errno));
3260 			rc = G_STRANGE;
3261 			break;
3262 		}
3263 		goto err;
3264 	}
3265 	L->lwp_ctlfd = fd;
3266 
3267 	L->lwp_state =
3268 	    ((L->lwp_status.pr_flags & (PR_STOPPED|PR_ISTOP))
3269 	    == (PR_STOPPED|PR_ISTOP))?
3270 	    PS_STOP : PS_RUN;
3271 
3272 	*perr = 0;
3273 	(void) mutex_unlock(&P->proc_lock);
3274 	return (L);
3275 
3276 err:
3277 	Lfree_internal(P, L);
3278 	*perr = rc;
3279 	(void) mutex_unlock(&P->proc_lock);
3280 	return (NULL);
3281 }
3282 
3283 /*
3284  * Return a printable string corresponding to an Lgrab() error return.
3285  */
3286 const char *
Lgrab_error(int error)3287 Lgrab_error(int error)
3288 {
3289 	const char *str;
3290 
3291 	switch (error) {
3292 	case G_NOPROC:
3293 		str = "no such LWP";
3294 		break;
3295 	case G_BUSY:
3296 		str = "LWP already grabbed";
3297 		break;
3298 	case G_STRANGE:
3299 		str = "unanticipated system error";
3300 		break;
3301 	default:
3302 		str = "unknown error";
3303 		break;
3304 	}
3305 
3306 	return (str);
3307 }
3308 
3309 /*
3310  * Free an LWP control structure.
3311  */
3312 void
Lfree(struct ps_lwphandle * L)3313 Lfree(struct ps_lwphandle *L)
3314 {
3315 	struct ps_prochandle *P = L->lwp_proc;
3316 
3317 	(void) mutex_lock(&P->proc_lock);
3318 	Lfree_internal(P, L);
3319 	(void) mutex_unlock(&P->proc_lock);
3320 }
3321 
3322 static void
Lfree_internal(struct ps_prochandle * P,struct ps_lwphandle * L)3323 Lfree_internal(struct ps_prochandle *P, struct ps_lwphandle *L)
3324 {
3325 	*Lfind(P, L->lwp_id) = L->lwp_hash;	/* delete from hash table */
3326 	if (L->lwp_ctlfd >= 0)
3327 		(void) close(L->lwp_ctlfd);
3328 	if (L->lwp_statfd >= 0)
3329 		(void) close(L->lwp_statfd);
3330 
3331 	/* clear out the structure as a precaution against reuse */
3332 	(void) memset(L, 0, sizeof (*L));
3333 	L->lwp_ctlfd = -1;
3334 	L->lwp_statfd = -1;
3335 
3336 	free(L);
3337 }
3338 
3339 /*
3340  * Return the state of the process, one of the PS_* values.
3341  */
3342 int
Lstate(struct ps_lwphandle * L)3343 Lstate(struct ps_lwphandle *L)
3344 {
3345 	return (L->lwp_state);
3346 }
3347 
3348 /*
3349  * Return the open control file descriptor for the LWP.
3350  * Clients must not close this file descriptor, nor use it
3351  * after the LWP is freed.
3352  */
3353 int
Lctlfd(struct ps_lwphandle * L)3354 Lctlfd(struct ps_lwphandle *L)
3355 {
3356 	return (L->lwp_ctlfd);
3357 }
3358 
3359 /*
3360  * Return a pointer to the LWP lwpsinfo structure.
3361  * Clients should not hold on to this pointer indefinitely.
3362  * It will become invalid on Lfree().
3363  */
3364 const lwpsinfo_t *
Lpsinfo(struct ps_lwphandle * L)3365 Lpsinfo(struct ps_lwphandle *L)
3366 {
3367 	if (Plwp_getpsinfo(L->lwp_proc, L->lwp_id, &L->lwp_psinfo) == -1)
3368 		return (NULL);
3369 
3370 	return (&L->lwp_psinfo);
3371 }
3372 
3373 /*
3374  * Return a pointer to the LWP status structure.
3375  * Clients should not hold on to this pointer indefinitely.
3376  * It will become invalid on Lfree().
3377  */
3378 const lwpstatus_t *
Lstatus(struct ps_lwphandle * L)3379 Lstatus(struct ps_lwphandle *L)
3380 {
3381 	return (&L->lwp_status);
3382 }
3383 
3384 /*
3385  * Given an LWP handle, return the process handle.
3386  */
3387 struct ps_prochandle *
Lprochandle(struct ps_lwphandle * L)3388 Lprochandle(struct ps_lwphandle *L)
3389 {
3390 	return (L->lwp_proc);
3391 }
3392 
3393 /*
3394  * Ensure that all cached state is written to the LWP.
3395  * The cached state is the LWP's signal mask and registers.
3396  */
3397 void
Lsync(struct ps_lwphandle * L)3398 Lsync(struct ps_lwphandle *L)
3399 {
3400 	int ctlfd = L->lwp_ctlfd;
3401 	long cmd[2];
3402 	iovec_t iov[4];
3403 	int n = 0;
3404 
3405 	if (L->lwp_flags & SETHOLD) {
3406 		cmd[0] = PCSHOLD;
3407 		iov[n].iov_base = (caddr_t)&cmd[0];
3408 		iov[n++].iov_len = sizeof (long);
3409 		iov[n].iov_base = (caddr_t)&L->lwp_status.pr_lwphold;
3410 		iov[n++].iov_len = sizeof (L->lwp_status.pr_lwphold);
3411 	}
3412 	if (L->lwp_flags & SETREGS) {
3413 		cmd[1] = PCSREG;
3414 		iov[n].iov_base = (caddr_t)&cmd[1];
3415 		iov[n++].iov_len = sizeof (long);
3416 		iov[n].iov_base = (caddr_t)&L->lwp_status.pr_reg[0];
3417 		iov[n++].iov_len = sizeof (L->lwp_status.pr_reg);
3418 	}
3419 
3420 	if (n == 0 || writev(ctlfd, iov, n) < 0)
3421 		return;		/* nothing to do or write failed */
3422 
3423 	L->lwp_flags &= ~(SETHOLD|SETREGS);
3424 }
3425 
3426 /*
3427  * Wait for the specified LWP to stop or terminate.
3428  * Or, just get the current status (PCNULL).
3429  * Or, direct it to stop and get the current status (PCDSTOP).
3430  */