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/uts/common/exec/elf/elf_notes.c
          +++ new/usr/src/uts/common/exec/elf/elf_notes.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, Version 1.0 only
   6    6   * (the "License").  You may not use this file except in compliance
   7    7   * with the License.
   8    8   *
   9    9   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10   10   * or http://www.opensolaris.org/os/licensing.
  11   11   * See the License for the specific language governing permissions
  12   12   * and limitations under the License.
  13   13   *
  14   14   * When distributing Covered Code, include this CDDL HEADER in each
  15   15   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   16   * If applicable, add the following below this CDDL HEADER, with the
  17   17   * fields enclosed by brackets "[]" replaced with your own identifying
  18   18   * information: Portions Copyright [yyyy] [name of copyright owner]
  19   19   *
  20   20   * CDDL HEADER END
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
  21   21   */
  22   22  /*
  23   23   * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
  27   27  /*
  28   28   * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  29   29   * Copyright 2018 Joyent, Inc.
  30   30   * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
  31      - * Copyright 2022 Oxide Computer Company
       31 + * Copyright 2023 Oxide Computer Company
  32   32   */
  33   33  
  34   34  #include <sys/types.h>
  35   35  #include <sys/param.h>
  36   36  #include <sys/thread.h>
  37   37  #include <sys/sysmacros.h>
  38   38  #include <sys/signal.h>
  39   39  #include <sys/cred.h>
  40   40  #include <sys/priv.h>
  41   41  #include <sys/user.h>
  42   42  #include <sys/file.h>
  43   43  #include <sys/errno.h>
  44   44  #include <sys/vnode.h>
  45   45  #include <sys/mode.h>
  46   46  #include <sys/vfs.h>
  47   47  #include <sys/mman.h>
  48   48  #include <sys/kmem.h>
  49   49  #include <sys/proc.h>
  50   50  #include <sys/pathname.h>
  51   51  #include <sys/cmn_err.h>
  52   52  #include <sys/systm.h>
  53   53  #include <sys/elf.h>
  54   54  #include <sys/vmsystm.h>
  55   55  #include <sys/debug.h>
  56   56  #include <sys/procfs.h>
  57   57  #include <sys/regset.h>
  58   58  #include <sys/auxv.h>
  59   59  #include <sys/exec.h>
  60   60  #include <sys/prsystm.h>
  61   61  #include <sys/utsname.h>
  62   62  #include <sys/zone.h>
  63   63  #include <vm/as.h>
  64   64  #include <vm/rm.h>
  65   65  #include <sys/modctl.h>
  66   66  #include <sys/systeminfo.h>
  67   67  #include <sys/machelf.h>
  68   68  #include <sys/sunddi.h>
  69   69  #include "elf_impl.h"
  70   70  #if defined(__i386_COMPAT)
  71   71  #include <sys/sysi86.h>
  72   72  #endif
  73   73  
  74   74  void
  75   75  setup_note_header(Phdr *v, proc_t *p)
  76   76  {
  77   77          int nlwp = p->p_lwpcnt;
  78   78          int nzomb = p->p_zombcnt;
  79   79          int nfd;
  80   80          size_t size;
  81   81          prcred_t *pcrp;
  82   82          uf_info_t *fip;
  83   83          uf_entry_t *ufp;
  84   84          int fd;
  85   85  
  86   86          fip = P_FINFO(p);
  87   87          nfd = 0;
  88   88          mutex_enter(&fip->fi_lock);
  89   89          for (fd = 0; fd < fip->fi_nfiles; fd++) {
  90   90                  UF_ENTER(ufp, fip, fd);
  91   91                  if ((ufp->uf_file != NULL) && (ufp->uf_file->f_count > 0))
  92   92                          nfd++;
  93   93                  UF_EXIT(ufp);
  94   94          }
  95   95          mutex_exit(&fip->fi_lock);
  96   96  
  97   97          v[0].p_type = PT_NOTE;
  98   98          v[0].p_flags = PF_R;
  99   99          v[0].p_filesz = (sizeof (Note) * (10 + 3 * nlwp + nzomb + nfd))
 100  100              + roundup(sizeof (psinfo_t), sizeof (Word))
 101  101              + roundup(sizeof (pstatus_t), sizeof (Word))
 102  102              + roundup(prgetprivsize(), sizeof (Word))
 103  103              + roundup(priv_get_implinfo_size(), sizeof (Word))
 104  104              + roundup(strlen(platform) + 1, sizeof (Word))
 105  105              + roundup(strlen(p->p_zone->zone_name) + 1, sizeof (Word))
 106  106              + roundup(__KERN_NAUXV_IMPL * sizeof (aux_entry_t), sizeof (Word))
 107  107              + roundup(sizeof (utsname), sizeof (Word))
 108  108              + roundup(sizeof (core_content_t), sizeof (Word))
 109  109              + roundup(sizeof (prsecflags_t), sizeof (Word))
 110  110              + (nlwp + nzomb) * roundup(sizeof (lwpsinfo_t), sizeof (Word))
 111  111              + nlwp * roundup(sizeof (lwpstatus_t), sizeof (Word))
 112  112              + nlwp * roundup(sizeof (prlwpname_t), sizeof (Word))
 113  113              + nfd * roundup(sizeof (prfdinfo_core_t), sizeof (Word));
 114  114  
 115  115          if (curproc->p_agenttp != NULL) {
 116  116                  v[0].p_filesz += sizeof (Note) +
 117  117                      roundup(sizeof (psinfo_t), sizeof (Word));
 118  118          }
 119  119  
 120  120          size = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1);
 121  121          pcrp = kmem_alloc(size, KM_SLEEP);
 122  122          prgetcred(p, pcrp);
 123  123          if (pcrp->pr_ngroups != 0) {
 124  124                  v[0].p_filesz += sizeof (Note) + roundup(sizeof (prcred_t) +
 125  125                      sizeof (gid_t) * (pcrp->pr_ngroups - 1), sizeof (Word));
 126  126          } else {
 127  127                  v[0].p_filesz += sizeof (Note) +
 128  128                      roundup(sizeof (prcred_t), sizeof (Word));
 129  129          }
 130  130          kmem_free(pcrp, size);
  
    | 
      ↓ open down ↓ | 
    89 lines elided | 
    
      ↑ open up ↑ | 
  
 131  131  
 132  132  
 133  133  #if defined(__i386_COMPAT)
 134  134          mutex_enter(&p->p_ldtlock);
 135  135          size = prnldt(p) * sizeof (struct ssd);
 136  136          mutex_exit(&p->p_ldtlock);
 137  137          if (size != 0)
 138  138                  v[0].p_filesz += sizeof (Note) + roundup(size, sizeof (Word));
 139  139  #endif  /* __i386_COMPAT */
 140  140  
 141      -        if ((size = prhasx(p)? prgetprxregsize(p) : 0) != 0)
      141 +        if ((size = prhasx(p) ? prgetprxregsize(p) : 0) != 0)
 142  142                  v[0].p_filesz += nlwp * sizeof (Note)
 143  143                      + nlwp * roundup(size, sizeof (Word));
 144  144  
 145  145  #if defined(__sparc)
 146  146          /*
 147  147           * Figure out the number and sizes of register windows.
 148  148           */
 149  149          {
 150  150                  kthread_t *t = p->p_tlist;
 151  151                  do {
 152  152                          if ((size = prnwindows(ttolwp(t))) != 0) {
 153  153                                  size = sizeof (gwindows_t) -
 154  154                                      (SPARC_MAXREGWINDOW - size) *
 155  155                                      sizeof (struct rwindow);
 156  156                                  v[0].p_filesz += sizeof (Note) +
 157  157                                      roundup(size, sizeof (Word));
 158  158                          }
 159  159                  } while ((t = t->t_forw) != p->p_tlist);
 160  160          }
 161  161          /*
 162  162           * Space for the Ancillary State Registers.
 163  163           */
 164  164          if (p->p_model == DATAMODEL_LP64)
 165  165                  v[0].p_filesz += nlwp * sizeof (Note)
 166  166                      + nlwp * roundup(sizeof (asrset_t), sizeof (Word));
 167  167  #endif /* __sparc */
 168  168  
 169  169          mutex_enter(&p->p_lock);
 170  170          if ((p->p_upanicflag & P_UPF_PANICKED) != 0) {
 171  171                  v[0].p_filesz += sizeof (Note) +
 172  172                      roundup(sizeof (prupanic_t), sizeof (Word));
 173  173          }
 174  174          mutex_exit(&p->p_lock);
 175  175  }
 176  176  
 177  177  int
 178  178  write_elfnotes(proc_t *p, int sig, vnode_t *vp, offset_t offset,
 179  179      rlim64_t rlimit, cred_t *credp, core_content_t content)
 180  180  {
 181  181          union {
 182  182                  psinfo_t        psinfo;
 183  183                  pstatus_t       pstatus;
 184  184                  lwpsinfo_t      lwpsinfo;
 185  185                  lwpstatus_t     lwpstatus;
 186  186  #if defined(__sparc)
 187  187                  gwindows_t      gwindows;
 188  188                  asrset_t        asrset;
 189  189  #endif /* __sparc */
  
    | 
      ↓ open down ↓ | 
    38 lines elided | 
    
      ↑ open up ↑ | 
  
 190  190                  char            xregs[1];
 191  191                  aux_entry_t     auxv[__KERN_NAUXV_IMPL];
 192  192                  prcred_t        pcred;
 193  193                  prpriv_t        ppriv;
 194  194                  priv_impl_info_t prinfo;
 195  195                  struct utsname  uts;
 196  196                  prsecflags_t    psecflags;
 197  197                  prupanic_t      upanic;
 198  198          } *bigwad;
 199  199  
 200      -        size_t xregsize = prhasx(p)? prgetprxregsize(p) : 0;
      200 +        size_t xregsize = prhasx(p) ? prgetprxregsize(p) : 0;
 201  201          size_t crsize = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1);
 202  202          size_t psize = prgetprivsize();
 203  203          size_t bigsize = MAX(psize, MAX(sizeof (*bigwad),
 204  204              MAX(xregsize, crsize)));
 205  205  
 206  206          priv_impl_info_t *prii;
 207  207  
 208  208          lwpdir_t *ldp;
 209  209          lwpent_t *lep;
 210  210          kthread_t *t;
 211  211          klwp_t *lwp;
 212  212          user_t *up;
 213  213          int i;
 214  214          int nlwp;
 215  215          int nzomb;
 216  216          int error;
 217  217          uchar_t oldsig;
 218  218          uf_info_t *fip;
 219  219          int fd;
 220  220          vnode_t *vroot;
 221  221  
 222  222  #if defined(__i386_COMPAT)
 223  223          struct ssd *ssd;
 224  224          size_t ssdsize;
 225  225  #endif  /* __i386_COMPAT */
 226  226  
 227  227          bigsize = MAX(bigsize, priv_get_implinfo_size());
 228  228  
 229  229          bigwad = kmem_alloc(bigsize, KM_SLEEP);
 230  230  
 231  231          /*
 232  232           * The order of the elfnote entries should be same here
 233  233           * and in the gcore(1) command.  Synchronization is
 234  234           * needed between the kernel and gcore(1).
 235  235           */
 236  236  
 237  237          /*
 238  238           * Get the psinfo, and set the wait status to indicate that a core was
 239  239           * dumped.  We have to forge this since p->p_wcode is not set yet.
 240  240           */
 241  241          mutex_enter(&p->p_lock);
 242  242          prgetpsinfo(p, &bigwad->psinfo);
 243  243          mutex_exit(&p->p_lock);
 244  244          bigwad->psinfo.pr_wstat = wstat(CLD_DUMPED, sig);
 245  245  
 246  246          error = elfnote(vp, &offset, NT_PSINFO, sizeof (bigwad->psinfo),
 247  247              (caddr_t)&bigwad->psinfo, rlimit, credp);
 248  248          if (error)
 249  249                  goto done;
 250  250  
 251  251          /*
 252  252           * Modify t_whystop and lwp_cursig so it appears that the current LWP
 253  253           * is stopped after faulting on the signal that caused the core dump.
 254  254           * As a result, prgetstatus() will record that signal, the saved
 255  255           * lwp_siginfo, and its signal handler in the core file status.  We
 256  256           * restore lwp_cursig in case a subsequent signal was received while
 257  257           * dumping core.
 258  258           */
 259  259          mutex_enter(&p->p_lock);
 260  260          lwp = ttolwp(curthread);
 261  261  
 262  262          oldsig = lwp->lwp_cursig;
 263  263          lwp->lwp_cursig = (uchar_t)sig;
 264  264          curthread->t_whystop = PR_FAULTED;
 265  265  
 266  266          prgetstatus(p, &bigwad->pstatus, p->p_zone);
 267  267          bigwad->pstatus.pr_lwp.pr_why = 0;
 268  268  
 269  269          curthread->t_whystop = 0;
 270  270          lwp->lwp_cursig = oldsig;
 271  271          mutex_exit(&p->p_lock);
 272  272  
 273  273          error = elfnote(vp, &offset, NT_PSTATUS, sizeof (bigwad->pstatus),
 274  274              (caddr_t)&bigwad->pstatus, rlimit, credp);
 275  275          if (error)
 276  276                  goto done;
 277  277  
 278  278          error = elfnote(vp, &offset, NT_PLATFORM, strlen(platform) + 1,
 279  279              platform, rlimit, credp);
 280  280          if (error)
 281  281                  goto done;
 282  282  
 283  283          up = PTOU(p);
 284  284          for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
 285  285                  bigwad->auxv[i].a_type = up->u_auxv[i].a_type;
 286  286                  bigwad->auxv[i].a_un.a_val = up->u_auxv[i].a_un.a_val;
 287  287          }
 288  288          error = elfnote(vp, &offset, NT_AUXV, sizeof (bigwad->auxv),
 289  289              (caddr_t)bigwad->auxv, rlimit, credp);
 290  290          if (error)
 291  291                  goto done;
 292  292  
 293  293          bcopy(&utsname, &bigwad->uts, sizeof (struct utsname));
 294  294          if (!INGLOBALZONE(p)) {
 295  295                  bcopy(p->p_zone->zone_nodename, &bigwad->uts.nodename,
 296  296                      _SYS_NMLN);
 297  297          }
 298  298          error = elfnote(vp, &offset, NT_UTSNAME, sizeof (struct utsname),
 299  299              (caddr_t)&bigwad->uts, rlimit, credp);
 300  300          if (error)
 301  301                  goto done;
 302  302  
 303  303          prgetsecflags(p, &bigwad->psecflags);
 304  304          error = elfnote(vp, &offset, NT_SECFLAGS, sizeof (prsecflags_t),
 305  305              (caddr_t)&bigwad->psecflags, rlimit, credp);
 306  306          if (error)
 307  307                  goto done;
 308  308  
 309  309          prgetcred(p, &bigwad->pcred);
 310  310  
 311  311          if (bigwad->pcred.pr_ngroups != 0) {
 312  312                  crsize = sizeof (prcred_t) +
 313  313                      sizeof (gid_t) * (bigwad->pcred.pr_ngroups - 1);
 314  314          } else
 315  315                  crsize = sizeof (prcred_t);
 316  316  
 317  317          error = elfnote(vp, &offset, NT_PRCRED, crsize,
 318  318              (caddr_t)&bigwad->pcred, rlimit, credp);
 319  319          if (error)
 320  320                  goto done;
 321  321  
 322  322          error = elfnote(vp, &offset, NT_CONTENT, sizeof (core_content_t),
 323  323              (caddr_t)&content, rlimit, credp);
 324  324          if (error)
 325  325                  goto done;
 326  326  
 327  327          prgetpriv(p, &bigwad->ppriv);
 328  328  
 329  329          error = elfnote(vp, &offset, NT_PRPRIV, psize,
 330  330              (caddr_t)&bigwad->ppriv, rlimit, credp);
 331  331          if (error)
 332  332                  goto done;
 333  333  
 334  334          prii = priv_hold_implinfo();
 335  335          error = elfnote(vp, &offset, NT_PRPRIVINFO, priv_get_implinfo_size(),
 336  336              (caddr_t)prii, rlimit, credp);
 337  337          priv_release_implinfo();
 338  338          if (error)
 339  339                  goto done;
 340  340  
 341  341          /* zone can't go away as long as process exists */
 342  342          error = elfnote(vp, &offset, NT_ZONENAME,
 343  343              strlen(p->p_zone->zone_name) + 1, p->p_zone->zone_name,
 344  344              rlimit, credp);
 345  345          if (error)
 346  346                  goto done;
 347  347  
 348  348  
 349  349          /* open file table */
 350  350          mutex_enter(&p->p_lock);
 351  351          vroot = PTOU(p)->u_rdir;
 352  352          if (vroot == NULL)
 353  353                  vroot = rootdir;
 354  354  
 355  355          VN_HOLD(vroot);
 356  356          mutex_exit(&p->p_lock);
 357  357  
 358  358          fip = P_FINFO(p);
 359  359  
 360  360          for (fd = 0; fd < fip->fi_nfiles; fd++) {
 361  361                  uf_entry_t *ufp;
 362  362                  vnode_t *fvp;
 363  363                  struct file *fp;
 364  364                  vattr_t vattr;
 365  365                  prfdinfo_core_t fdinfo;
 366  366  
 367  367                  bzero(&fdinfo, sizeof (fdinfo));
 368  368  
 369  369                  mutex_enter(&fip->fi_lock);
 370  370                  UF_ENTER(ufp, fip, fd);
 371  371                  if (((fp = ufp->uf_file) == NULL) || (fp->f_count < 1)) {
 372  372                          UF_EXIT(ufp);
 373  373                          mutex_exit(&fip->fi_lock);
 374  374                          continue;
 375  375                  }
 376  376  
 377  377                  fdinfo.pr_fd = fd;
 378  378                  fdinfo.pr_fdflags = ufp->uf_flag;
 379  379                  fdinfo.pr_fileflags = fp->f_flag2;
 380  380                  fdinfo.pr_fileflags <<= 16;
 381  381                  fdinfo.pr_fileflags |= fp->f_flag;
 382  382                  if ((fdinfo.pr_fileflags & (FSEARCH | FEXEC)) == 0)
 383  383                          fdinfo.pr_fileflags += FOPEN;
 384  384                  fdinfo.pr_offset = fp->f_offset;
 385  385  
 386  386  
 387  387                  fvp = fp->f_vnode;
 388  388                  VN_HOLD(fvp);
 389  389                  UF_EXIT(ufp);
 390  390                  mutex_exit(&fip->fi_lock);
 391  391  
 392  392                  /*
 393  393                   * There are some vnodes that have no corresponding
 394  394                   * path.  Its reasonable for this to fail, in which
 395  395                   * case the path will remain an empty string.
 396  396                   */
 397  397                  (void) vnodetopath(vroot, fvp, fdinfo.pr_path,
 398  398                      sizeof (fdinfo.pr_path), credp);
 399  399  
 400  400                  if (VOP_GETATTR(fvp, &vattr, 0, credp, NULL) != 0) {
 401  401                          /*
 402  402                           * Try to write at least a subset of information
 403  403                           */
 404  404                          fdinfo.pr_major = 0;
 405  405                          fdinfo.pr_minor = 0;
 406  406                          fdinfo.pr_ino = 0;
 407  407                          fdinfo.pr_mode = 0;
 408  408                          fdinfo.pr_uid = (uid_t)-1;
 409  409                          fdinfo.pr_gid = (gid_t)-1;
 410  410                          fdinfo.pr_rmajor = 0;
 411  411                          fdinfo.pr_rminor = 0;
 412  412                          fdinfo.pr_size = -1;
 413  413  
 414  414                          error = elfnote(vp, &offset, NT_FDINFO,
 415  415                              sizeof (fdinfo), &fdinfo, rlimit, credp);
 416  416                          VN_RELE(fvp);
 417  417                          if (error) {
 418  418                                  VN_RELE(vroot);
 419  419                                  goto done;
 420  420                          }
 421  421                          continue;
 422  422                  }
 423  423  
 424  424                  if (fvp->v_type == VSOCK)
 425  425                          fdinfo.pr_fileflags |= sock_getfasync(fvp);
 426  426  
 427  427                  VN_RELE(fvp);
 428  428  
 429  429                  /*
 430  430                   * This logic mirrors fstat(), which we cannot use
 431  431                   * directly, as it calls copyout().
 432  432                   */
 433  433                  fdinfo.pr_major = getmajor(vattr.va_fsid);
 434  434                  fdinfo.pr_minor = getminor(vattr.va_fsid);
 435  435                  fdinfo.pr_ino = (ino64_t)vattr.va_nodeid;
 436  436                  fdinfo.pr_mode = VTTOIF(vattr.va_type) | vattr.va_mode;
 437  437                  fdinfo.pr_uid = vattr.va_uid;
 438  438                  fdinfo.pr_gid = vattr.va_gid;
 439  439                  fdinfo.pr_rmajor = getmajor(vattr.va_rdev);
 440  440                  fdinfo.pr_rminor = getminor(vattr.va_rdev);
 441  441                  fdinfo.pr_size = (off64_t)vattr.va_size;
 442  442  
 443  443                  error = elfnote(vp, &offset, NT_FDINFO,
 444  444                      sizeof (fdinfo), &fdinfo, rlimit, credp);
 445  445                  if (error) {
 446  446                          VN_RELE(vroot);
 447  447                          goto done;
 448  448                  }
 449  449          }
 450  450  
 451  451          VN_RELE(vroot);
 452  452  
 453  453  #if defined(__i386_COMPAT)
 454  454          mutex_enter(&p->p_ldtlock);
 455  455          ssdsize = prnldt(p) * sizeof (struct ssd);
 456  456          if (ssdsize != 0) {
 457  457                  ssd = kmem_alloc(ssdsize, KM_SLEEP);
 458  458                  prgetldt(p, ssd);
 459  459                  error = elfnote(vp, &offset, NT_LDT, ssdsize,
 460  460                      (caddr_t)ssd, rlimit, credp);
 461  461                  kmem_free(ssd, ssdsize);
 462  462          }
 463  463          mutex_exit(&p->p_ldtlock);
 464  464          if (error)
 465  465                  goto done;
 466  466  #endif  /* defined(__i386_COMPAT) */
 467  467  
 468  468          nlwp = p->p_lwpcnt;
 469  469          nzomb = p->p_zombcnt;
 470  470          /* for each entry in the lwp directory ... */
 471  471          for (ldp = p->p_lwpdir; nlwp + nzomb != 0; ldp++) {
 472  472                  prlwpname_t name = { 0, };
 473  473  
 474  474                  if ((lep = ldp->ld_entry) == NULL)      /* empty slot */
 475  475                          continue;
 476  476  
 477  477                  if ((t = lep->le_thread) != NULL) {     /* active lwp */
 478  478                          ASSERT(nlwp != 0);
 479  479                          nlwp--;
 480  480                          lwp = ttolwp(t);
 481  481                          mutex_enter(&p->p_lock);
 482  482                          prgetlwpsinfo(t, &bigwad->lwpsinfo);
 483  483                          if (t->t_name != NULL) {
 484  484                                  (void) strlcpy(name.pr_lwpname, t->t_name,
 485  485                                      sizeof (name.pr_lwpname));
 486  486                          }
 487  487                          mutex_exit(&p->p_lock);
 488  488                  } else {                                /* zombie lwp */
 489  489                          ASSERT(nzomb != 0);
 490  490                          nzomb--;
 491  491                          bzero(&bigwad->lwpsinfo, sizeof (bigwad->lwpsinfo));
 492  492                          bigwad->lwpsinfo.pr_lwpid = lep->le_lwpid;
 493  493                          bigwad->lwpsinfo.pr_state = SZOMB;
 494  494                          bigwad->lwpsinfo.pr_sname = 'Z';
 495  495                          bigwad->lwpsinfo.pr_start.tv_sec = lep->le_start;
 496  496                  }
 497  497  
 498  498                  name.pr_lwpid = bigwad->lwpsinfo.pr_lwpid;
 499  499  
 500  500                  error = elfnote(vp, &offset, NT_LWPSINFO,
 501  501                      sizeof (bigwad->lwpsinfo), (caddr_t)&bigwad->lwpsinfo,
 502  502                      rlimit, credp);
 503  503                  if (error)
 504  504                          goto done;
 505  505  
 506  506                  if (t == NULL)          /* nothing more to do for a zombie */
 507  507                          continue;
 508  508  
 509  509                  mutex_enter(&p->p_lock);
 510  510                  if (t == curthread) {
 511  511                          /*
 512  512                           * Modify t_whystop and lwp_cursig so it appears that
 513  513                           * the current LWP is stopped after faulting on the
 514  514                           * signal that caused the core dump.  As a result,
 515  515                           * prgetlwpstatus() will record that signal, the saved
 516  516                           * lwp_siginfo, and its signal handler in the core file
 517  517                           * status.  We restore lwp_cursig in case a subsequent
 518  518                           * signal was received while dumping core.
 519  519                           */
 520  520                          oldsig = lwp->lwp_cursig;
 521  521                          lwp->lwp_cursig = (uchar_t)sig;
 522  522                          t->t_whystop = PR_FAULTED;
 523  523  
 524  524                          prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone);
 525  525                          bigwad->lwpstatus.pr_why = 0;
 526  526  
 527  527                          t->t_whystop = 0;
 528  528                          lwp->lwp_cursig = oldsig;
 529  529                  } else {
 530  530                          prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone);
 531  531                  }
 532  532                  mutex_exit(&p->p_lock);
 533  533                  error = elfnote(vp, &offset, NT_LWPSTATUS,
 534  534                      sizeof (bigwad->lwpstatus), (caddr_t)&bigwad->lwpstatus,
 535  535                      rlimit, credp);
 536  536                  if (error)
 537  537                          goto done;
 538  538  
 539  539                  if ((error = elfnote(vp, &offset, NT_LWPNAME, sizeof (name),
 540  540                      (caddr_t)&name, rlimit, credp)) != 0)
 541  541                          goto done;
 542  542  
 543  543  
 544  544  #if defined(__sparc)
 545  545                  /*
 546  546                   * Unspilled SPARC register windows.
 547  547                   */
 548  548                  {
 549  549                          size_t size = prnwindows(lwp);
 550  550  
 551  551                          if (size != 0) {
 552  552                                  size = sizeof (gwindows_t) -
 553  553                                      (SPARC_MAXREGWINDOW - size) *
 554  554                                      sizeof (struct rwindow);
 555  555                                  prgetwindows(lwp, &bigwad->gwindows);
 556  556                                  error = elfnote(vp, &offset, NT_GWINDOWS,
 557  557                                      size, (caddr_t)&bigwad->gwindows,
 558  558                                      rlimit, credp);
 559  559                                  if (error)
 560  560                                          goto done;
 561  561                          }
 562  562                  }
 563  563                  /*
 564  564                   * Ancillary State Registers.
 565  565                   */
 566  566                  if (p->p_model == DATAMODEL_LP64) {
  
    | 
      ↓ open down ↓ | 
    356 lines elided | 
    
      ↑ open up ↑ | 
  
 567  567                          prgetasregs(lwp, bigwad->asrset);
 568  568                          error = elfnote(vp, &offset, NT_ASRS,
 569  569                              sizeof (asrset_t), (caddr_t)bigwad->asrset,
 570  570                              rlimit, credp);
 571  571                          if (error)
 572  572                                  goto done;
 573  573                  }
 574  574  #endif /* __sparc */
 575  575  
 576  576                  if (xregsize) {
 577      -                        prgetprxregs(lwp, bigwad->xregs);
      577 +                        prgetprxregs(lwp, (prxregset_t *)bigwad->xregs);
 578  578                          error = elfnote(vp, &offset, NT_PRXREG,
 579  579                              xregsize, bigwad->xregs, rlimit, credp);
 580  580                          if (error)
 581  581                                  goto done;
 582  582                  }
 583  583  
 584  584                  if (t->t_lwp->lwp_spymaster != NULL) {
 585  585                          void *psaddr = t->t_lwp->lwp_spymaster;
 586  586  #ifdef _ELF32_COMPAT
 587  587                          /*
 588  588                           * On a 64-bit kernel with 32-bit ELF compatibility,
 589  589                           * this file is compiled into two different objects:
 590  590                           * one is compiled normally, and the other is compiled
 591  591                           * with _ELF32_COMPAT set -- and therefore with a
 592  592                           * psinfo_t defined to be a psinfo32_t.  However, the
 593  593                           * psinfo_t denoting our spymaster is always of the
 594  594                           * native type; if we are in the _ELF32_COMPAT case,
 595  595                           * we need to explicitly convert it.
 596  596                           */
 597  597                          if (p->p_model == DATAMODEL_ILP32) {
 598  598                                  psinfo_kto32(psaddr, &bigwad->psinfo);
 599  599                                  psaddr = &bigwad->psinfo;
 600  600                          }
 601  601  #endif
 602  602  
 603  603                          error = elfnote(vp, &offset, NT_SPYMASTER,
 604  604                              sizeof (psinfo_t), psaddr, rlimit, credp);
 605  605                          if (error)
 606  606                                  goto done;
 607  607                  }
 608  608          }
 609  609          ASSERT(nlwp == 0);
 610  610  
 611  611          /*
 612  612           * If a upanic occurred, add a note for it.
 613  613           */
 614  614          mutex_enter(&p->p_lock);
 615  615          if ((p->p_upanicflag & P_UPF_PANICKED) != 0) {
 616  616                  bzero(&bigwad->upanic, sizeof (prupanic_t));
 617  617                  bigwad->upanic.pru_version = PRUPANIC_VERSION_1;
 618  618                  if ((p->p_upanicflag & P_UPF_INVALMSG) != 0) {
 619  619                          bigwad->upanic.pru_flags |= PRUPANIC_FLAG_MSG_ERROR;
 620  620                  }
 621  621  
 622  622                  if ((p->p_upanicflag & P_UPF_TRUNCMSG) != 0) {
 623  623                          bigwad->upanic.pru_flags |= PRUPANIC_FLAG_MSG_TRUNC;
 624  624                  }
 625  625  
 626  626                  if ((p->p_upanicflag & P_UPF_HAVEMSG) != 0) {
 627  627                          bigwad->upanic.pru_flags |= PRUPANIC_FLAG_MSG_VALID;
 628  628                          bcopy(p->p_upanic, bigwad->upanic.pru_data,
 629  629                              PRUPANIC_BUFLEN);
 630  630                  }
 631  631  
 632  632                  mutex_exit(&p->p_lock);
 633  633                  error = elfnote(vp, &offset, NT_UPANIC, sizeof (prupanic_t),
 634  634                      &bigwad->upanic, rlimit, credp);
 635  635                  if (error != 0) {
 636  636                          goto done;
 637  637                  }
 638  638          } else {
 639  639                  mutex_exit(&p->p_lock);
 640  640          }
 641  641  
 642  642  done:
 643  643          kmem_free(bigwad, bigsize);
 644  644          return (error);
 645  645  }
  
    | 
      ↓ open down ↓ | 
    58 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX