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