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