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/libproc.h
          +++ new/usr/src/lib/libproc/common/libproc.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  
    | 
      ↓ open down ↓ | 
    21 lines elided | 
    
      ↑ open up ↑ | 
  
  22   22  /*
  23   23   * Copyright 2009 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 2019 Joyent, Inc.
  29   29   * Copyright (c) 2013 by Delphix. All rights reserved.
  30   30   * Copyright 2019, Carlos Neira <cneirabustos@gmail.com>
  31   31   * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
       32 + * Copyright 2023 Oxide Computer Company
  32   33   */
  33   34  
  34   35  /*
  35   36   * Interfaces available from the process control library, libproc.
  36   37   */
  37   38  
  38   39  #ifndef _LIBPROC_H
  39   40  #define _LIBPROC_H
  40   41  
  41   42  #include <stdlib.h>
  42   43  #include <unistd.h>
  43   44  #include <fcntl.h>
  44   45  #include <nlist.h>
  45   46  #include <door.h>
  46   47  #include <gelf.h>
  47   48  #include <proc_service.h>
  48   49  #include <rtld_db.h>
  49   50  #include <procfs.h>
  50   51  #include <ucred.h>
  51   52  #include <rctl.h>
  52   53  #include <libctf.h>
  53   54  #include <sys/stat.h>
  54   55  #include <sys/statvfs.h>
  55   56  #include <sys/auxv.h>
  56   57  #include <sys/resource.h>
  57   58  #include <sys/socket.h>
  58   59  #include <sys/utsname.h>
  59   60  #include <sys/corectl.h>
  60   61  #include <sys/secflags.h>
  61   62  #if defined(__i386) || defined(__amd64)
  62   63  #include <sys/sysi86.h>
  63   64  #endif
  64   65  
  65   66  #ifdef  __cplusplus
  66   67  extern "C" {
  67   68  #endif
  68   69  
  69   70  /*
  70   71   * Opaque structure tag reference to a process control structure.
  71   72   * Clients of libproc cannot look inside the process control structure.
  72   73   * The implementation of struct ps_prochandle can change w/o affecting clients.
  73   74   */
  74   75  struct ps_prochandle;
  75   76  
  76   77  /*
  77   78   * Opaque structure tag reference to an lwp control structure.
  78   79   */
  79   80  struct ps_lwphandle;
  80   81  
  81   82  extern  int     _libproc_debug; /* set non-zero to enable debugging fprintfs */
  82   83  extern  int     _libproc_no_qsort;      /* set non-zero to inhibit sorting */
  83   84                                          /* of symbol tables */
  84   85  extern  int     _libproc_incore_elf;    /* only use in-core elf data */
  85   86  
  86   87  #if defined(__sparc)
  87   88  #define R_RVAL1 R_O0            /* register holding a function return value */
  88   89  #define R_RVAL2 R_O1            /* 32 more bits for a 64-bit return value */
  89   90  #endif  /* __sparc */
  90   91  
  91   92  #if defined(__amd64)
  92   93  #define R_PC    REG_RIP
  93   94  #define R_SP    REG_RSP
  94   95  #define R_RVAL1 REG_RAX         /* register holding a function return value */
  95   96  #define R_RVAL2 REG_RDX         /* 32 more bits for a 64-bit return value */
  96   97  #elif defined(__i386)
  97   98  #define R_PC    EIP
  98   99  #define R_SP    UESP
  99  100  #define R_RVAL1 EAX             /* register holding a function return value */
 100  101  #define R_RVAL2 EDX             /* 32 more bits for a 64-bit return value */
 101  102  #endif  /* __amd64 || __i386 */
 102  103  
 103  104  #define R_RVAL  R_RVAL1         /* simple function return value register */
 104  105  
 105  106  /* maximum sizes of things */
 106  107  #define PRMAXSIG        (32 * sizeof (sigset_t) / sizeof (uint32_t))
 107  108  #define PRMAXFAULT      (32 * sizeof (fltset_t) / sizeof (uint32_t))
 108  109  #define PRMAXSYS        (32 * sizeof (sysset_t) / sizeof (uint32_t))
 109  110  
 110  111  /* State values returned by Pstate() */
 111  112  #define PS_RUN          1       /* process is running */
 112  113  #define PS_STOP         2       /* process is stopped */
 113  114  #define PS_LOST         3       /* process is lost to control (EAGAIN) */
 114  115  #define PS_UNDEAD       4       /* process is terminated (zombie) */
 115  116  #define PS_DEAD         5       /* process is terminated (core file) */
 116  117  #define PS_IDLE         6       /* process has not been run */
 117  118  
 118  119  /* Flags accepted by Pgrab() */
 119  120  #define PGRAB_RETAIN    0x01    /* Retain tracing flags, else clear flags */
 120  121  #define PGRAB_FORCE     0x02    /* Open the process w/o O_EXCL */
 121  122  #define PGRAB_RDONLY    0x04    /* Open the process or core w/ O_RDONLY */
 122  123  #define PGRAB_NOSTOP    0x08    /* Open the process but do not stop it */
 123  124  #define PGRAB_INCORE    0x10    /* Use in-core data to build symbol tables */
 124  125  
 125  126  /* Error codes from Pcreate() */
 126  127  #define C_STRANGE       -1      /* Unanticipated error, errno is meaningful */
 127  128  #define C_FORK          1       /* Unable to fork */
 128  129  #define C_PERM          2       /* No permission (file set-id or unreadable) */
 129  130  #define C_NOEXEC        3       /* Cannot execute file */
 130  131  #define C_INTR          4       /* Interrupt received while creating */
 131  132  #define C_LP64          5       /* Program is _LP64, self is _ILP32 */
 132  133  #define C_NOENT         6       /* Cannot find executable file */
 133  134  
 134  135  /* Error codes from Pgrab(), Pfgrab_core(), and Pgrab_core() */
 135  136  #define G_STRANGE       -1      /* Unanticipated error, errno is meaningful */
 136  137  #define G_NOPROC        1       /* No such process */
 137  138  #define G_NOCORE        2       /* No such core file */
 138  139  #define G_NOPROCORCORE  3       /* No such proc or core (for proc_arg_grab) */
 139  140  #define G_NOEXEC        4       /* Cannot locate executable file */
 140  141  #define G_ZOMB          5       /* Zombie process */
 141  142  #define G_PERM          6       /* No permission */
 142  143  #define G_BUSY          7       /* Another process has control */
 143  144  #define G_SYS           8       /* System process */
 144  145  #define G_SELF          9       /* Process is self */
 145  146  #define G_INTR          10      /* Interrupt received while grabbing */
 146  147  #define G_LP64          11      /* Process is _LP64, self is ILP32 */
 147  148  #define G_FORMAT        12      /* File is not an ELF format core file */
 148  149  #define G_ELF           13      /* Libelf error, elf_errno() is meaningful */
 149  150  #define G_NOTE          14      /* Required PT_NOTE Phdr not present in core */
 150  151  #define G_ISAINVAL      15      /* Wrong ELF machine type */
 151  152  #define G_BADLWPS       16      /* Bad '/lwps' specification */
 152  153  #define G_NOFD          17      /* No more file descriptors */
 153  154  
 154  155  
 155  156  /* Flags accepted by Prelease */
 156  157  #define PRELEASE_CLEAR  0x10    /* Clear all tracing flags */
 157  158  #define PRELEASE_RETAIN 0x20    /* Retain final tracing flags */
 158  159  #define PRELEASE_HANG   0x40    /* Leave the process stopped */
 159  160  #define PRELEASE_KILL   0x80    /* Terminate the process */
 160  161  
 161  162  typedef struct {        /* argument descriptor for system call (Psyscall) */
 162  163          long    arg_value;      /* value of argument given to system call */
 163  164          void    *arg_object;    /* pointer to object in controlling process */
 164  165          char    arg_type;       /* AT_BYVAL, AT_BYREF */
 165  166          char    arg_inout;      /* AI_INPUT, AI_OUTPUT, AI_INOUT */
 166  167          ushort_t arg_size;      /* if AT_BYREF, size of object in bytes */
 167  168  } argdes_t;
 168  169  
 169  170  /* values for type */
 170  171  #define AT_BYVAL        1
 171  172  #define AT_BYREF        2
 172  173  
 173  174  /* values for inout */
 174  175  #define AI_INPUT        1
 175  176  #define AI_OUTPUT       2
 176  177  #define AI_INOUT        3
 177  178  
 178  179  /* maximum number of syscall arguments */
 179  180  #define MAXARGS         8
 180  181  
 181  182  /* maximum size in bytes of a BYREF argument */
 182  183  #define MAXARGL         (4*1024)
 183  184  
 184  185  /*
 185  186   * Ops vector definition for the Pgrab_ops().
 186  187   */
 187  188  typedef ssize_t (*pop_pread_t)(struct ps_prochandle *, void *, size_t,
 188  189      uintptr_t, void *);
 189  190  typedef ssize_t (*pop_pwrite_t)(struct ps_prochandle *, const void *, size_t,
 190  191      uintptr_t, void *);
 191  192  typedef int (*pop_read_maps_t)(struct ps_prochandle *, prmap_t **, ssize_t *,
 192  193      void *);
 193  194  typedef void (*pop_read_aux_t)(struct ps_prochandle *, auxv_t **, int *,
 194  195      void *);
 195  196  typedef int (*pop_cred_t)(struct ps_prochandle *, prcred_t *, int,
 196  197      void *);
 197  198  typedef int (*pop_priv_t)(struct ps_prochandle *, prpriv_t **, void *);
 198  199  typedef int (*pop_secflags_t)(struct ps_prochandle *, prsecflags_t **, void *);
 199  200  typedef const psinfo_t *(*pop_psinfo_t)(struct ps_prochandle *, psinfo_t *,
 200  201      void *);
 201  202  typedef void (*pop_status_t)(struct ps_prochandle *, pstatus_t *, void *);
 202  203  typedef prheader_t *(*pop_lstatus_t)(struct ps_prochandle *, void *);
 203  204  typedef prheader_t *(*pop_lpsinfo_t)(struct ps_prochandle *, void *);
 204  205  typedef void (*pop_fini_t)(struct ps_prochandle *, void *);
 205  206  typedef char *(*pop_platform_t)(struct ps_prochandle *, char *, size_t, void *);
 206  207  typedef int (*pop_uname_t)(struct ps_prochandle *, struct utsname *, void *);
 207  208  typedef char *(*pop_zonename_t)(struct ps_prochandle *, char *, size_t, void *);
 208  209  typedef char *(*pop_execname_t)(struct ps_prochandle *, char *, size_t, void *);
 209  210  #if defined(__i386) || defined(__amd64)
 210  211  typedef int (*pop_ldt_t)(struct ps_prochandle *, struct ssd *, int, void *);
 211  212  #endif
 212  213  
 213  214  typedef struct ps_ops {
 214  215          pop_pread_t             pop_pread;
 215  216          pop_pwrite_t            pop_pwrite;
 216  217          pop_read_maps_t         pop_read_maps;
 217  218          pop_read_aux_t          pop_read_aux;
 218  219          pop_cred_t              pop_cred;
 219  220          pop_priv_t              pop_priv;
 220  221          pop_psinfo_t            pop_psinfo;
 221  222          pop_status_t            pop_status;
 222  223          pop_lstatus_t           pop_lstatus;
 223  224          pop_lpsinfo_t           pop_lpsinfo;
 224  225          pop_fini_t              pop_fini;
 225  226          pop_platform_t          pop_platform;
 226  227          pop_uname_t             pop_uname;
 227  228          pop_zonename_t          pop_zonename;
 228  229          pop_execname_t          pop_execname;
 229  230          pop_secflags_t          pop_secflags;
 230  231  #if defined(__i386) || defined(__amd64)
 231  232          pop_ldt_t               pop_ldt;
 232  233  #endif
 233  234  } ps_ops_t;
 234  235  
 235  236  /*
 236  237   * Function prototypes for routines in the process control package.
 237  238   */
 238  239  extern struct ps_prochandle *Pcreate(const char *, char *const *,
 239  240      int *, char *, size_t);
 240  241  extern struct ps_prochandle *Pxcreate(const char *, char *const *,
 241  242      char *const *, int *, char *, size_t);
 242  243  
 243  244  extern const char *Pcreate_error(int);
 244  245  
 245  246  extern struct ps_prochandle *Pgrab(pid_t, int, int *);
 246  247  extern struct ps_prochandle *Pgrab_core(const char *, const char *, int, int *);
 247  248  extern struct ps_prochandle *Pfgrab_core(int, const char *, int *);
 248  249  extern struct ps_prochandle *Pgrab_file(const char *, int *);
 249  250  extern struct ps_prochandle *Pgrab_ops(pid_t, void *, const ps_ops_t *, int);
 250  251  extern const char *Pgrab_error(int);
 251  252  
 252  253  extern  int     Preopen(struct ps_prochandle *);
 253  254  extern  void    Prelease(struct ps_prochandle *, int);
 254  255  extern  void    Pfree(struct ps_prochandle *);
 255  256  
 256  257  extern  int     Pasfd(struct ps_prochandle *);
 257  258  extern  char   *Pbrandname(struct ps_prochandle *, char *, size_t);
 258  259  extern  int     Pctlfd(struct ps_prochandle *);
 259  260  extern  int     Pcreate_agent(struct ps_prochandle *);
 260  261  extern  void    Pdestroy_agent(struct ps_prochandle *);
 261  262  extern  int     Pstopstatus(struct ps_prochandle *, long, uint_t);
 262  263  extern  int     Pwait(struct ps_prochandle *, uint_t);
 263  264  extern  int     Pstop(struct ps_prochandle *, uint_t);
 264  265  extern  int     Pdstop(struct ps_prochandle *);
 265  266  extern  int     Pstate(struct ps_prochandle *);
 266  267  extern  const psinfo_t *Ppsinfo(struct ps_prochandle *);
 267  268  extern  const pstatus_t *Pstatus(struct ps_prochandle *);
 268  269  extern  int     Pcred(struct ps_prochandle *, prcred_t *, int);
 269  270  extern  int     Psetcred(struct ps_prochandle *, const prcred_t *);
 270  271  extern  int     Ppriv(struct ps_prochandle *, prpriv_t **);
 271  272  extern  void    Ppriv_free(struct ps_prochandle *, prpriv_t *);
 272  273  extern  int     Psetpriv(struct ps_prochandle *, prpriv_t *);
 273  274  extern  void   *Pprivinfo(struct ps_prochandle *);
 274  275  extern  int     Psetzoneid(struct ps_prochandle *, zoneid_t);
 275  276  extern  int     Pgetareg(struct ps_prochandle *, int, prgreg_t *);
 276  277  extern  int     Pputareg(struct ps_prochandle *, int, prgreg_t);
 277  278  extern  int     Psetrun(struct ps_prochandle *, int, int);
 278  279  extern  int     Psecflags(struct ps_prochandle *, prsecflags_t **);
 279  280  extern  void    Psecflags_free(prsecflags_t *);
 280  281  extern  ssize_t Pread(struct ps_prochandle *, void *, size_t, uintptr_t);
 281  282  extern  ssize_t Pread_string(struct ps_prochandle *, char *, size_t, uintptr_t);
 282  283  extern  ssize_t Pwrite(struct ps_prochandle *, const void *, size_t, uintptr_t);
 283  284  extern  int     Pclearsig(struct ps_prochandle *);
 284  285  extern  int     Pclearfault(struct ps_prochandle *);
 285  286  extern  int     Psetbkpt(struct ps_prochandle *, uintptr_t, ulong_t *);
 286  287  extern  int     Pdelbkpt(struct ps_prochandle *, uintptr_t, ulong_t);
 287  288  extern  int     Pxecbkpt(struct ps_prochandle *, ulong_t);
 288  289  extern  int     Psetwapt(struct ps_prochandle *, const prwatch_t *);
 289  290  extern  int     Pdelwapt(struct ps_prochandle *, const prwatch_t *);
 290  291  extern  int     Pxecwapt(struct ps_prochandle *, const prwatch_t *);
 291  292  extern  int     Psetflags(struct ps_prochandle *, long);
 292  293  extern  int     Punsetflags(struct ps_prochandle *, long);
 293  294  extern  int     Psignal(struct ps_prochandle *, int, int);
 294  295  extern  int     Pfault(struct ps_prochandle *, int, int);
 295  296  extern  int     Psysentry(struct ps_prochandle *, int, int);
 296  297  extern  int     Psysexit(struct ps_prochandle *, int, int);
 297  298  extern  void    Psetsignal(struct ps_prochandle *, const sigset_t *);
 298  299  extern  void    Psetfault(struct ps_prochandle *, const fltset_t *);
 299  300  extern  void    Psetsysentry(struct ps_prochandle *, const sysset_t *);
 300  301  extern  void    Psetsysexit(struct ps_prochandle *, const sysset_t *);
 301  302  
 302  303  extern  void    Psync(struct ps_prochandle *);
 303  304  extern  int     Psyscall(struct ps_prochandle *, sysret_t *,
 304  305                          int, uint_t, argdes_t *);
 305  306  extern  int     Pisprocdir(struct ps_prochandle *, const char *);
 306  307  
 307  308  /*
 308  309   * Function prototypes for lwp-specific operations.
 309  310   */
 310  311  extern  struct ps_lwphandle *Lgrab(struct ps_prochandle *, lwpid_t, int *);
 311  312  extern  const char *Lgrab_error(int);
 312  313  
 313  314  extern  struct ps_prochandle *Lprochandle(struct ps_lwphandle *);
 314  315  extern  void    Lfree(struct ps_lwphandle *);
 315  316  
 316  317  extern  int     Lctlfd(struct ps_lwphandle *);
 317  318  extern  int     Lwait(struct ps_lwphandle *, uint_t);
 318  319  extern  int     Lstop(struct ps_lwphandle *, uint_t);
 319  320  extern  int     Ldstop(struct ps_lwphandle *);
 320  321  extern  int     Lstate(struct ps_lwphandle *);
 321  322  extern  const lwpsinfo_t *Lpsinfo(struct ps_lwphandle *);
 322  323  extern  const lwpstatus_t *Lstatus(struct ps_lwphandle *);
 323  324  extern  int     Lgetareg(struct ps_lwphandle *, int, prgreg_t *);
 324  325  extern  int     Lputareg(struct ps_lwphandle *, int, prgreg_t);
 325  326  extern  int     Lsetrun(struct ps_lwphandle *, int, int);
  
    | 
      ↓ open down ↓ | 
    284 lines elided | 
    
      ↑ open up ↑ | 
  
 326  327  extern  int     Lclearsig(struct ps_lwphandle *);
 327  328  extern  int     Lclearfault(struct ps_lwphandle *);
 328  329  extern  int     Lxecbkpt(struct ps_lwphandle *, ulong_t);
 329  330  extern  int     Lxecwapt(struct ps_lwphandle *, const prwatch_t *);
 330  331  extern  void    Lsync(struct ps_lwphandle *);
 331  332  
 332  333  extern  int     Lstack(struct ps_lwphandle *, stack_t *);
 333  334  extern  int     Lmain_stack(struct ps_lwphandle *, stack_t *);
 334  335  extern  int     Lalt_stack(struct ps_lwphandle *, stack_t *);
 335  336  
      337 +extern int      Lgetregs(struct ps_lwphandle *, prgregset_t *);
      338 +extern int      Lsetregs(struct ps_lwphandle *, const prgregset_t *);
      339 +extern int      Lgetfpregs(struct ps_lwphandle *, prfpregset_t *);
      340 +extern int      Lsetfpregs(struct ps_lwphandle *, const prfpregset_t *);
      341 +extern int      Lgetxregs(struct ps_lwphandle *, prxregset_t **, size_t *);
      342 +extern int      Lsetxregs(struct ps_lwphandle *, const prxregset_t *, size_t);
      343 +
 336  344  /*
 337  345   * Function prototypes for system calls forced on the victim process.
 338  346   */
 339  347  extern  int     pr_open(struct ps_prochandle *, const char *, int, mode_t);
 340  348  extern  int     pr_creat(struct ps_prochandle *, const char *, mode_t);
 341  349  extern  int     pr_close(struct ps_prochandle *, int);
 342  350  extern  int     pr_access(struct ps_prochandle *, const char *, int);
 343  351  extern  int     pr_door_info(struct ps_prochandle *, int, struct door_info *);
 344  352  extern  void    *pr_mmap(struct ps_prochandle *,
 345  353                          void *, size_t, int, int, int, off_t);
 346  354  extern  void    *pr_zmap(struct ps_prochandle *,
 347  355                          void *, size_t, int, int);
 348  356  extern  int     pr_munmap(struct ps_prochandle *, void *, size_t);
 349  357  extern  int     pr_memcntl(struct ps_prochandle *,
 350  358                          caddr_t, size_t, int, caddr_t, int, int);
 351  359  extern  int     pr_meminfo(struct ps_prochandle *, const uint64_t *addrs,
 352  360                          int addr_count, const uint_t *info, int info_count,
 353  361                          uint64_t *outdata, uint_t *validity);
 354  362  extern  int     pr_sigaction(struct ps_prochandle *,
 355  363                          int, const struct sigaction *, struct sigaction *);
 356  364  extern  int     pr_getitimer(struct ps_prochandle *,
 357  365                          int, struct itimerval *);
 358  366  extern  int     pr_setitimer(struct ps_prochandle *,
 359  367                          int, const struct itimerval *, struct itimerval *);
 360  368  extern  int     pr_ioctl(struct ps_prochandle *, int, int, void *, size_t);
 361  369  extern  int     pr_fcntl(struct ps_prochandle *, int, int, void *);
 362  370  extern  int     pr_stat(struct ps_prochandle *, const char *, struct stat *);
 363  371  extern  int     pr_lstat(struct ps_prochandle *, const char *, struct stat *);
 364  372  extern  int     pr_fstat(struct ps_prochandle *, int, struct stat *);
 365  373  extern  int     pr_stat64(struct ps_prochandle *, const char *,
 366  374                          struct stat64 *);
 367  375  extern  int     pr_lstat64(struct ps_prochandle *, const char *,
 368  376                          struct stat64 *);
 369  377  extern  int     pr_fstat64(struct ps_prochandle *, int, struct stat64 *);
 370  378  extern  int     pr_statvfs(struct ps_prochandle *, const char *, statvfs_t *);
 371  379  extern  int     pr_fstatvfs(struct ps_prochandle *, int, statvfs_t *);
 372  380  extern  projid_t pr_getprojid(struct ps_prochandle *Pr);
 373  381  extern  taskid_t pr_gettaskid(struct ps_prochandle *Pr);
 374  382  extern  taskid_t pr_settaskid(struct ps_prochandle *Pr, projid_t project,
 375  383                          int flags);
 376  384  extern  zoneid_t pr_getzoneid(struct ps_prochandle *Pr);
 377  385  extern  int     pr_getrctl(struct ps_prochandle *,
 378  386                          const char *, rctlblk_t *, rctlblk_t *, int);
 379  387  extern  int     pr_setrctl(struct ps_prochandle *,
 380  388                          const char *, rctlblk_t *, rctlblk_t *, int);
 381  389  extern  int     pr_getrlimit(struct ps_prochandle *,
 382  390                          int, struct rlimit *);
 383  391  extern  int     pr_setrlimit(struct ps_prochandle *,
 384  392                          int, const struct rlimit *);
 385  393  extern  int     pr_setprojrctl(struct ps_prochandle *, const char *,
 386  394                          rctlblk_t *, size_t, int);
 387  395  #if defined(_LARGEFILE64_SOURCE)
 388  396  extern  int     pr_getrlimit64(struct ps_prochandle *,
 389  397                          int, struct rlimit64 *);
 390  398  extern  int     pr_setrlimit64(struct ps_prochandle *,
 391  399                          int, const struct rlimit64 *);
 392  400  #endif  /* _LARGEFILE64_SOURCE */
 393  401  extern  int     pr_lwp_exit(struct ps_prochandle *);
 394  402  extern  int     pr_exit(struct ps_prochandle *, int);
 395  403  extern  int     pr_waitid(struct ps_prochandle *,
 396  404                          idtype_t, id_t, siginfo_t *, int);
 397  405  extern  off_t   pr_lseek(struct ps_prochandle *, int, off_t, int);
 398  406  extern  offset_t pr_llseek(struct ps_prochandle *, int, offset_t, int);
 399  407  extern  int     pr_rename(struct ps_prochandle *, const char *, const char *);
 400  408  extern  int     pr_link(struct ps_prochandle *, const char *, const char *);
 401  409  extern  int     pr_unlink(struct ps_prochandle *, const char *);
 402  410  extern  int     pr_getpeerucred(struct ps_prochandle *, int, ucred_t **);
 403  411  extern  int     pr_getpeername(struct ps_prochandle *,
 404  412                          int, struct sockaddr *, socklen_t *);
 405  413  extern  int     pr_getsockname(struct ps_prochandle *,
 406  414                          int, struct sockaddr *, socklen_t *);
 407  415  extern  int     pr_getsockopt(struct ps_prochandle *,
 408  416                          int, int, int, void *, int *);
 409  417  extern  int     pr_processor_bind(struct ps_prochandle *,
 410  418                          idtype_t, id_t, int, int *);
 411  419  
  
    | 
      ↓ open down ↓ | 
    66 lines elided | 
    
      ↑ open up ↑ | 
  
 412  420  /*
 413  421   * Function prototypes for accessing per-LWP register information.
 414  422   */
 415  423  extern int Plwp_getregs(struct ps_prochandle *, lwpid_t, prgregset_t);
 416  424  extern int Plwp_setregs(struct ps_prochandle *, lwpid_t, const prgregset_t);
 417  425  
 418  426  extern int Plwp_getfpregs(struct ps_prochandle *, lwpid_t, prfpregset_t *);
 419  427  extern int Plwp_setfpregs(struct ps_prochandle *, lwpid_t,
 420  428      const prfpregset_t *);
 421  429  
 422      -#if defined(__sparc)
      430 +extern int Plwp_getxregs(struct ps_prochandle *, lwpid_t, prxregset_t **,
      431 +    size_t *);
      432 +extern void Plwp_freexregs(struct ps_prochandle *, prxregset_t *, size_t);
      433 +extern int Plwp_setxregs(struct ps_prochandle *, lwpid_t, const prxregset_t *,
      434 +    size_t);
 423  435  
 424      -extern int Plwp_getxregs(struct ps_prochandle *, lwpid_t, prxregset_t *);
 425      -extern int Plwp_setxregs(struct ps_prochandle *, lwpid_t, const prxregset_t *);
 426      -
      436 +#if defined(__sparc)
 427  437  extern int Plwp_getgwindows(struct ps_prochandle *, lwpid_t, gwindows_t *);
 428  438  
 429  439  #if defined(__sparcv9)
 430  440  extern int Plwp_getasrs(struct ps_prochandle *, lwpid_t, asrset_t);
 431  441  extern int Plwp_setasrs(struct ps_prochandle *, lwpid_t, const asrset_t);
 432  442  #endif  /* __sparcv9 */
 433  443  
 434  444  #endif  /* __sparc */
 435  445  
 436  446  #if defined(__i386) || defined(__amd64)
 437  447  extern  int     Pldt(struct ps_prochandle *, struct ssd *, int);
 438  448  extern  int     proc_get_ldt(pid_t, struct ssd *, int);
 439  449  #endif  /* __i386 || __amd64 */
 440  450  
 441  451  extern int Plwp_getname(struct ps_prochandle *, lwpid_t, char *, size_t);
 442  452  extern int Plwp_getpsinfo(struct ps_prochandle *, lwpid_t, lwpsinfo_t *);
 443  453  extern int Plwp_getspymaster(struct ps_prochandle *, lwpid_t, psinfo_t *);
 444  454  
 445  455  extern int Plwp_stack(struct ps_prochandle *, lwpid_t, stack_t *);
 446  456  extern int Plwp_main_stack(struct ps_prochandle *, lwpid_t, stack_t *);
 447  457  extern int Plwp_alt_stack(struct ps_prochandle *, lwpid_t, stack_t *);
 448  458  
 449  459  /*
 450  460   * LWP iteration interface; iterate over all active LWPs.
 451  461   */
 452  462  typedef int proc_lwp_f(void *, const lwpstatus_t *);
 453  463  extern int Plwp_iter(struct ps_prochandle *, proc_lwp_f *, void *);
 454  464  
 455  465  /*
 456  466   * LWP iteration interface; iterate over all LWPs, active and zombie.
 457  467   */
 458  468  typedef int proc_lwp_all_f(void *, const lwpstatus_t *, const lwpsinfo_t *);
 459  469  extern int Plwp_iter_all(struct ps_prochandle *, proc_lwp_all_f *, void *);
 460  470  
 461  471  /*
 462  472   * Process iteration interface; iterate over all non-system processes.
 463  473   */
 464  474  typedef int proc_walk_f(psinfo_t *, lwpsinfo_t *, void *);
 465  475  extern int proc_walk(proc_walk_f *, void *, int);
 466  476  
 467  477  #define PR_WALK_PROC            0               /* walk processes only */
 468  478  #define PR_WALK_LWP             1               /* walk all lwps */
 469  479  #define PR_WALK_INCLUDE_SYS     0x80000000      /* include SSYS processes */
 470  480  
 471  481  /*
 472  482   * File descriptor iteration.
 473  483   */
 474  484  typedef int proc_fdwalk_f(const prfdinfo_t *, void *);
 475  485  extern int proc_fdwalk(pid_t, proc_fdwalk_f *, void *);
 476  486  
 477  487  /*
 478  488   * fdinfo iteration.
 479  489   */
 480  490  typedef int proc_fdinfowalk_f(uint_t, const void *, size_t, void *);
 481  491  extern int proc_fdinfowalk(const prfdinfo_t *, proc_fdinfowalk_f *, void *);
 482  492  
 483  493  /*
 484  494   * Determine if an lwp is in a set as returned from proc_arg_xgrab().
 485  495   */
 486  496  extern int proc_lwp_in_set(const char *, lwpid_t);
 487  497  extern int proc_lwp_range_valid(const char *);
 488  498  
 489  499  /*
 490  500   * Symbol table interfaces.
 491  501   */
 492  502  
 493  503  /*
 494  504   * Pseudo-names passed to Plookup_by_name() for well-known load objects.
 495  505   * NOTE: It is required that PR_OBJ_EXEC and PR_OBJ_LDSO exactly match
 496  506   * the definitions of PS_OBJ_EXEC and PS_OBJ_LDSO from <proc_service.h>.
 497  507   */
 498  508  #define PR_OBJ_EXEC     ((const char *)0)       /* search the executable file */
 499  509  #define PR_OBJ_LDSO     ((const char *)1)       /* search ld.so.1 */
 500  510  #define PR_OBJ_EVERY    ((const char *)-1)      /* search every load object */
 501  511  
 502  512  /*
 503  513   * Special Lmid_t passed to Plookup_by_lmid() to search all link maps.  The
 504  514   * special values LM_ID_BASE and LM_ID_LDSO from <link.h> may also be used.
 505  515   * If PR_OBJ_EXEC is used as the object name, the lmid must be PR_LMID_EVERY
 506  516   * or LM_ID_BASE in order to return a match.  If PR_OBJ_LDSO is used as the
 507  517   * object name, the lmid must be PR_LMID_EVERY or LM_ID_LDSO to return a match.
 508  518   */
 509  519  #define PR_LMID_EVERY   ((Lmid_t)-1UL)          /* search every link map */
 510  520  
 511  521  /*
 512  522   * 'object_name' is the name of a load object obtained from an
 513  523   * iteration over the process's address space mappings (Pmapping_iter),
 514  524   * or an iteration over the process's mapped objects (Pobject_iter),
 515  525   * or else it is one of the special PR_OBJ_* values above.
 516  526   */
 517  527  extern int Plookup_by_name(struct ps_prochandle *,
 518  528      const char *, const char *, GElf_Sym *);
 519  529  
 520  530  extern int Plookup_by_addr(struct ps_prochandle *,
 521  531      uintptr_t, char *, size_t, GElf_Sym *);
 522  532  
 523  533  typedef struct prsyminfo {
 524  534          const char      *prs_object;            /* object name */
 525  535          const char      *prs_name;              /* symbol name */
 526  536          Lmid_t          prs_lmid;               /* link map id */
 527  537          uint_t          prs_id;                 /* symbol id */
 528  538          uint_t          prs_table;              /* symbol table id */
 529  539  } prsyminfo_t;
 530  540  
 531  541  extern int Pxlookup_by_name(struct ps_prochandle *,
 532  542      Lmid_t, const char *, const char *, GElf_Sym *, prsyminfo_t *);
 533  543  
 534  544  extern int Pxlookup_by_addr(struct ps_prochandle *,
 535  545      uintptr_t, char *, size_t, GElf_Sym *, prsyminfo_t *);
 536  546  extern int Pxlookup_by_addr_resolved(struct ps_prochandle *,
 537  547      uintptr_t, char *, size_t, GElf_Sym *, prsyminfo_t *);
 538  548  
 539  549  typedef int proc_map_f(void *, const prmap_t *, const char *);
 540  550  
 541  551  extern int Pmapping_iter(struct ps_prochandle *, proc_map_f *, void *);
 542  552  extern int Pmapping_iter_resolved(struct ps_prochandle *, proc_map_f *, void *);
 543  553  extern int Pobject_iter(struct ps_prochandle *, proc_map_f *, void *);
 544  554  extern int Pobject_iter_resolved(struct ps_prochandle *, proc_map_f *, void *);
 545  555  
 546  556  extern const prmap_t *Paddr_to_map(struct ps_prochandle *, uintptr_t);
 547  557  extern const prmap_t *Paddr_to_text_map(struct ps_prochandle *, uintptr_t);
 548  558  extern const prmap_t *Pname_to_map(struct ps_prochandle *, const char *);
 549  559  extern const prmap_t *Plmid_to_map(struct ps_prochandle *,
 550  560      Lmid_t, const char *);
 551  561  
 552  562  extern const rd_loadobj_t *Paddr_to_loadobj(struct ps_prochandle *, uintptr_t);
 553  563  extern const rd_loadobj_t *Pname_to_loadobj(struct ps_prochandle *,
 554  564      const char *);
 555  565  extern const rd_loadobj_t *Plmid_to_loadobj(struct ps_prochandle *,
 556  566      Lmid_t, const char *);
 557  567  
 558  568  extern ctf_file_t *Paddr_to_ctf(struct ps_prochandle *, uintptr_t);
 559  569  extern ctf_file_t *Pname_to_ctf(struct ps_prochandle *, const char *);
 560  570  
 561  571  extern char *Pplatform(struct ps_prochandle *, char *, size_t);
 562  572  extern int Puname(struct ps_prochandle *, struct utsname *);
 563  573  extern char *Pzonename(struct ps_prochandle *, char *, size_t);
 564  574  extern char *Pfindobj(struct ps_prochandle *, const char *, char *, size_t);
 565  575  
 566  576  extern char *Pexecname(struct ps_prochandle *, char *, size_t);
 567  577  extern char *Pobjname(struct ps_prochandle *, uintptr_t, char *, size_t);
 568  578  extern char *Pobjname_resolved(struct ps_prochandle *, uintptr_t, char *,
 569  579      size_t);
 570  580  extern int Plmid(struct ps_prochandle *, uintptr_t, Lmid_t *);
 571  581  
 572  582  typedef int proc_env_f(void *, struct ps_prochandle *, uintptr_t, const char *);
 573  583  extern  int Penv_iter(struct ps_prochandle *, proc_env_f *, void *);
 574  584  extern char *Pgetenv(struct ps_prochandle *, const char *, char *, size_t);
 575  585  extern long Pgetauxval(struct ps_prochandle *, int);
 576  586  extern const auxv_t *Pgetauxvec(struct ps_prochandle *);
 577  587  
 578  588  extern void Pset_procfs_path(const char *);
 579  589  
 580  590  /*
 581  591   * Symbol table iteration interface.  The special lmid constants LM_ID_BASE,
 582  592   * LM_ID_LDSO, and PR_LMID_EVERY may be used with Psymbol_iter_by_lmid.
 583  593   */
 584  594  typedef int proc_sym_f(void *, const GElf_Sym *, const char *);
 585  595  typedef int proc_xsym_f(void *, const GElf_Sym *, const char *,
 586  596      const prsyminfo_t *);
 587  597  
 588  598  extern int Psymbol_iter(struct ps_prochandle *,
 589  599      const char *, int, int, proc_sym_f *, void *);
 590  600  extern int Psymbol_iter_by_addr(struct ps_prochandle *,
 591  601      const char *, int, int, proc_sym_f *, void *);
 592  602  extern int Psymbol_iter_by_name(struct ps_prochandle *,
 593  603      const char *, int, int, proc_sym_f *, void *);
 594  604  
 595  605  extern int Psymbol_iter_by_lmid(struct ps_prochandle *,
 596  606      Lmid_t, const char *, int, int, proc_sym_f *, void *);
 597  607  
 598  608  extern int Pxsymbol_iter(struct ps_prochandle *,
 599  609      Lmid_t, const char *, int, int, proc_xsym_f *, void *);
 600  610  
 601  611  /*
 602  612   * 'which' selects which symbol table and can be one of the following.
 603  613   */
 604  614  #define PR_SYMTAB       1
 605  615  #define PR_DYNSYM       2
 606  616  /*
 607  617   * 'type' selects the symbols of interest by binding and type.  It is a bit-
 608  618   * mask of one or more of the following flags, whose order MUST match the
 609  619   * order of STB and STT constants in <sys/elf.h>.
 610  620   */
 611  621  #define BIND_LOCAL      0x0001
 612  622  #define BIND_GLOBAL     0x0002
 613  623  #define BIND_WEAK       0x0004
 614  624  #define BIND_ANY (BIND_LOCAL|BIND_GLOBAL|BIND_WEAK)
 615  625  #define TYPE_NOTYPE     0x0100
 616  626  #define TYPE_OBJECT     0x0200
 617  627  #define TYPE_FUNC       0x0400
 618  628  #define TYPE_SECTION    0x0800
 619  629  #define TYPE_FILE       0x1000
 620  630  #define TYPE_ANY (TYPE_NOTYPE|TYPE_OBJECT|TYPE_FUNC|TYPE_SECTION|TYPE_FILE)
 621  631  
 622  632  /*
 623  633   * This returns the rtld_db agent handle for the process.
 624  634   * The handle will become invalid at the next successful exec() and
 625  635   * must not be used beyond that point (see Preset_maps(), below).
 626  636   */
 627  637  extern rd_agent_t *Prd_agent(struct ps_prochandle *);
 628  638  
 629  639  /*
 630  640   * This should be called when an RD_DLACTIVITY event with the
 631  641   * RD_CONSISTENT state occurs via librtld_db's event mechanism.
 632  642   * This makes libproc's address space mappings and symbol tables current.
 633  643   * The variant Pupdate_syms() can be used to preload all symbol tables as well.
 634  644   */
 635  645  extern void Pupdate_maps(struct ps_prochandle *);
 636  646  extern void Pupdate_syms(struct ps_prochandle *);
 637  647  
 638  648  /*
 639  649   * This must be called after the victim process performs a successful
 640  650   * exec() if any of the symbol table interface functions have been called
 641  651   * prior to that point.  This is essential because an exec() invalidates
 642  652   * all previous symbol table and address space mapping information.
 643  653   * It is always safe to call, but if it is called other than after an
 644  654   * exec() by the victim process it just causes unnecessary overhead.
 645  655   *
 646  656   * The rtld_db agent handle obtained from a previous call to Prd_agent() is
 647  657   * made invalid by Preset_maps() and Prd_agent() must be called again to get
 648  658   * the new handle.
 649  659   */
 650  660  extern void Preset_maps(struct ps_prochandle *);
 651  661  
 652  662  /*
 653  663   * Given an address, Ppltdest() determines if this is part of a PLT, and if
 654  664   * so returns a pointer to the symbol name that will be used for resolution.
 655  665   * If the specified address is not part of a PLT, the function returns NULL.
 656  666   */
 657  667  extern const char *Ppltdest(struct ps_prochandle *, uintptr_t);
 658  668  
 659  669  /*
 660  670   * See comments for Pissyscall(), in Pisadep.h
 661  671   */
 662  672  extern int Pissyscall_prev(struct ps_prochandle *, uintptr_t, uintptr_t *);
 663  673  
 664  674  /*
 665  675   * Stack frame iteration interface.
 666  676   */
 667  677  typedef int proc_stack_f(void *, prgregset_t, uint_t, const long *);
 668  678  
 669  679  extern int Pstack_iter(struct ps_prochandle *,
 670  680      const prgregset_t, proc_stack_f *, void *);
 671  681  
 672  682  /*
 673  683   * The following functions define a set of passive interfaces: libproc provides
 674  684   * default, empty definitions that are called internally.  If a client wishes
 675  685   * to override these definitions, it can simply provide its own version with
 676  686   * the same signature that interposes on the libproc definition.
 677  687   *
 678  688   * If the client program wishes to report additional error information, it
 679  689   * can provide its own version of Perror_printf.
 680  690   *
 681  691   * If the client program wishes to receive a callback after Pcreate forks
 682  692   * but before it execs, it can provide its own version of Pcreate_callback.
 683  693   */
 684  694  extern void Perror_printf(struct ps_prochandle *P, const char *format, ...);
 685  695  extern void Pcreate_callback(struct ps_prochandle *);
 686  696  
 687  697  /*
 688  698   * Remove unprintable characters from psinfo.pr_psargs and replace with
 689  699   * whitespace characters so it is safe for printing.
 690  700   */
 691  701  extern void proc_unctrl_psinfo(psinfo_t *);
 692  702  
 693  703  /*
 694  704   * Utility functions for processing arguments which should be /proc files,
 695  705   * pids, and/or core files.  The returned error code can be passed to
 696  706   * Pgrab_error() in order to convert it to an error string.
 697  707   */
 698  708  #define PR_ARG_PIDS     0x1     /* Allow pid and /proc file arguments */
 699  709  #define PR_ARG_CORES    0x2     /* Allow core file arguments */
 700  710  
 701  711  #define PR_ARG_ANY      (PR_ARG_PIDS | PR_ARG_CORES)
 702  712  
 703  713  extern struct ps_prochandle *proc_arg_grab(const char *, int, int, int *);
 704  714  extern struct ps_prochandle *proc_arg_xgrab(const char *, const char *, int,
 705  715      int, int *, const char **);
 706  716  extern pid_t proc_arg_psinfo(const char *, int, psinfo_t *, int *);
 707  717  extern pid_t proc_arg_xpsinfo(const char *, int, psinfo_t *, int *,
 708  718      const char **);
 709  719  
 710  720  /*
 711  721   * Utility functions for obtaining information via /proc without actually
 712  722   * performing a Pcreate() or Pgrab():
 713  723   */
 714  724  extern int proc_get_auxv(pid_t, auxv_t *, int);
 715  725  extern int proc_get_cred(pid_t, prcred_t *, int);
 716  726  extern prpriv_t *proc_get_priv(pid_t);
 717  727  extern void proc_free_priv(prpriv_t *);
 718  728  extern int proc_get_psinfo(pid_t, psinfo_t *);
 719  729  extern int proc_get_status(pid_t, pstatus_t *);
 720  730  extern int proc_get_secflags(pid_t, prsecflags_t **);
 721  731  extern prfdinfo_t *proc_get_fdinfo(pid_t, int);
 722  732  extern const void *proc_fdinfo_misc(const prfdinfo_t *, uint_t, size_t *);
 723  733  extern void proc_fdinfo_free(prfdinfo_t *);
 724  734  extern int proc_get_lwpsinfo(pid_t, uint_t, lwpsinfo_t *);
 725  735  
 726  736  /*
 727  737   * Utility functions for debugging tools to convert numeric fault,
 728  738   * signal, and system call numbers to symbolic names:
 729  739   */
 730  740  #define FLT2STR_MAX 32  /* max. string length of faults (like SIG2STR_MAX) */
 731  741  #define SYS2STR_MAX 32  /* max. string length of syscalls (like SIG2STR_MAX) */
 732  742  #define DMODELSTR_MAX 32 /* max. string length of data model names */
 733  743  
 734  744  extern char *proc_fltname(int, char *, size_t);
 735  745  extern char *proc_signame(int, char *, size_t);
 736  746  extern char *proc_sysname(int, char *, size_t);
 737  747  extern char *proc_dmodelname(int, char *, size_t);
 738  748  
 739  749  /*
 740  750   * Utility functions for debugging tools to convert fault, signal, and system
 741  751   * call names back to the numeric constants:
 742  752   */
 743  753  extern int proc_str2flt(const char *, int *);
 744  754  extern int proc_str2sig(const char *, int *);
 745  755  extern int proc_str2sys(const char *, int *);
 746  756  
 747  757  /*
 748  758   * Utility functions for debugging tools to convert a fault, signal or system
 749  759   * call set to a string representation (e.g. "BUS,SEGV" or "open,close,read").
 750  760   */
 751  761  #define PRSIGBUFSZ      1024    /* buffer size for proc_sigset2str() */
 752  762  
 753  763  extern char *proc_fltset2str(const fltset_t *, const char *, int,
 754  764      char *, size_t);
 755  765  extern char *proc_sigset2str(const sigset_t *, const char *, int,
 756  766      char *, size_t);
 757  767  extern char *proc_sysset2str(const sysset_t *, const char *, int,
 758  768      char *, size_t);
 759  769  
 760  770  extern int Pgcore(struct ps_prochandle *, const char *, core_content_t);
 761  771  extern int Pfgcore(struct ps_prochandle *, int, core_content_t);
 762  772  extern core_content_t Pcontent(struct ps_prochandle *);
 763  773  
 764  774  /*
 765  775   * Utility functions for debugging tools to convert a string representation of
 766  776   * a fault, signal or system call set back to the numeric value of the
 767  777   * corresponding set type.
 768  778   */
 769  779  extern char *proc_str2fltset(const char *, const char *, int, fltset_t *);
 770  780  extern char *proc_str2sigset(const char *, const char *, int, sigset_t *);
 771  781  extern char *proc_str2sysset(const char *, const char *, int, sysset_t *);
 772  782  
 773  783  /*
 774  784   * Utility functions for converting between strings and core_content_t.
 775  785   */
 776  786  #define PRCONTENTBUFSZ  80      /* buffer size for proc_content2str() */
 777  787  
 778  788  extern int proc_str2content(const char *, core_content_t *);
 779  789  extern int proc_content2str(core_content_t, char *, size_t);
 780  790  
 781  791  /*
 782  792   * Utility functions for buffering output to stdout, stderr while
 783  793   * process is grabbed.  Prevents deadlocks due to pfiles `pgrep xterm`
 784  794   * and other varients.
 785  795   */
 786  796  extern int proc_initstdio(void);
 787  797  extern int proc_flushstdio(void);
 788  798  extern int proc_finistdio(void);
 789  799  
 790  800  /*
 791  801   * Iterate over all open files.
 792  802   */
 793  803  typedef int proc_fdinfo_f(void *, const prfdinfo_t *);
 794  804  extern int Pfdinfo_iter(struct ps_prochandle *, proc_fdinfo_f *, void *);
 795  805  
 796  806  /*
 797  807   * NT_UPANIC information.
 798  808   */
 799  809  extern int Pupanic(struct ps_prochandle *, prupanic_t **);
 800  810  extern void Pupanic_free(prupanic_t *);
 801  811  
 802  812  #ifdef  __cplusplus
 803  813  }
 804  814  #endif
 805  815  
 806  816  #endif  /* _LIBPROC_H */
  
    | 
      ↓ open down ↓ | 
    370 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX