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