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/Pservice.c
          +++ new/usr/src/lib/libproc/common/Pservice.c
↓ open down ↓ 16 lines elided ↑ open up ↑
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  /*
  26   26   * Copyright (c) 2013 by Delphix. All rights reserved.
       27 + * Copyright 2023 Oxide Computer Company
  27   28   */
  28   29  
  29   30  #include <stdarg.h>
  30   31  #include <string.h>
       32 +#include <errno.h>
  31   33  #include "Pcontrol.h"
  32   34  
  33   35  /*
  34   36   * This file implements the process services declared in <proc_service.h>.
  35   37   * This enables libproc to be used in conjunction with libc_db and
  36   38   * librtld_db.  As most of these facilities are already provided by
  37   39   * (more elegant) interfaces in <libproc.h>, we can just call those.
  38   40   *
  39   41   * NOTE: We explicitly do *not* implement the functions ps_kill() and
  40   42   * ps_lrolltoaddr() in this library.  The very existence of these functions
↓ open down ↓ 119 lines elided ↑ open up ↑
 160  162  {
 161  163          if (P->state != PS_STOP)
 162  164                  return (PS_ERR);
 163  165  
 164  166          if (Plwp_setfpregs(P, lwpid, regs) == 0)
 165  167                  return (PS_OK);
 166  168  
 167  169          return (PS_BADLID);
 168  170  }
 169  171  
 170      -#if defined(sparc) || defined(__sparc)
 171      -
 172  172  ps_err_e
 173  173  ps_lgetxregsize(struct ps_prochandle *P, lwpid_t lwpid, int *xrsize)
 174  174  {
 175  175          char fname[PATH_MAX];
 176  176          struct stat statb;
 177  177  
 178  178          if (P->state == PS_DEAD) {
 179  179                  core_info_t *core = P->data;
 180  180                  lwp_info_t *lwp;
 181  181  
 182  182                  for (lwp = list_head(&core->core_lwp_head); lwp != NULL;
 183  183                      lwp = list_next(&core->core_lwp_head, lwp)) {
 184  184                          if (lwp->lwp_id == lwpid) {
 185      -                                if (lwp->lwp_xregs != NULL)
 186      -                                        *xrsize = sizeof (prxregset_t);
 187      -                                else
      185 +                                if (lwp->lwp_xregs != NULL &&
      186 +                                    lwp->lwp_xregsize > 0) {
      187 +                                        if (lwp->lwp_xregsize >= INT_MAX) {
      188 +                                                return (PS_ERR);
      189 +                                        }
      190 +
      191 +                                        *xrsize = (int)lwp->lwp_xregsize;
      192 +                                } else {
 188  193                                          *xrsize = 0;
      194 +                                }
 189  195                                  return (PS_OK);
 190  196                          }
 191  197                  }
 192  198  
 193  199                  return (PS_BADLID);
 194  200          }
 195  201  
 196  202          (void) snprintf(fname, sizeof (fname), "%s/%d/lwp/%d/xregs",
 197  203              procfs_path, (int)P->status.pr_pid, (int)lwpid);
 198  204  
 199  205          if (stat(fname, &statb) != 0)
 200  206                  return (PS_BADLID);
 201  207  
      208 +        if (statb.st_size > INT_MAX)
      209 +                return (PS_ERR);
      210 +
 202  211          *xrsize = (int)statb.st_size;
 203  212          return (PS_OK);
 204  213  }
 205  214  
 206  215  ps_err_e
 207  216  ps_lgetxregs(struct ps_prochandle *P, lwpid_t lwpid, caddr_t xregs)
 208  217  {
      218 +        size_t xregsize;
      219 +        prxregset_t *prx;
      220 +
 209  221          if (P->state != PS_STOP && P->state != PS_DEAD)
 210  222                  return (PS_ERR);
 211  223  
 212      -        /* LINTED - alignment */
 213      -        if (Plwp_getxregs(P, lwpid, (prxregset_t *)xregs) == 0)
      224 +        if (Plwp_getxregs(P, lwpid, &prx, &xregsize) == 0) {
      225 +                (void) memcpy(xregs, prx, xregsize);
      226 +                Plwp_freexregs(P, prx, xregsize);
 214  227                  return (PS_OK);
      228 +        }
 215  229  
      230 +        if (errno == ENODATA)
      231 +                return (PS_NOXREGS);
      232 +
 216  233          return (PS_BADLID);
 217  234  }
 218  235  
 219  236  ps_err_e
 220  237  ps_lsetxregs(struct ps_prochandle *P, lwpid_t lwpid, caddr_t xregs)
      238 +{
      239 +        size_t xregsize = 0;
      240 +
      241 +        if (P->state != PS_STOP)
      242 +                return (PS_ERR);
      243 +
      244 +        /*
      245 +         * libproc asks the caller for the size of the extended register set.
      246 +         * Unfortunately, right now we aren't given the actual size of this
      247 +         * ourselves and we don't want to break the ABI that folks have used
      248 +         * historically. Therefore, we reach in and ask the structure in a
      249 +         * platform-specific way about what this should be. Sorry, this is a bit
      250 +         * unfortunate. This really shouldn't be a platform-specific #ifdef.
      251 +         */
      252 +#if defined(__i386) || defined(__amd64)
      253 +        prxregset_hdr_t *hdr = (prxregset_hdr_t *)xregs;
      254 +        xregsize = hdr->pr_size;
      255 +#endif
      256 +        if (xregsize == 0)
      257 +                return (PS_ERR);
      258 +
      259 +        if (Plwp_setxregs(P, lwpid, (prxregset_t *)xregs, xregsize) == 0)
      260 +                return (PS_OK);
      261 +
      262 +        return (PS_BADLID);
      263 +}
      264 +
      265 +#if defined(sparc) || defined(__sparc)
      266 +ps_err_e
      267 +ps_lsetxregs(struct ps_prochandle *P, lwpid_t lwpid, caddr_t xregs)
 221  268  {
 222  269          if (P->state != PS_STOP)
 223  270                  return (PS_ERR);
 224  271  
 225  272          /* LINTED - alignment */
 226  273          if (Plwp_setxregs(P, lwpid, (prxregset_t *)xregs) == 0)
 227  274                  return (PS_OK);
 228  275  
 229  276          return (PS_BADLID);
 230  277  }
↓ open down ↓ 149 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX