1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <sys/types.h> 30*0Sstevel@tonic-gate #include <sys/param.h> 31*0Sstevel@tonic-gate #include <sys/thread.h> 32*0Sstevel@tonic-gate #include <sys/sysmacros.h> 33*0Sstevel@tonic-gate #include <sys/signal.h> 34*0Sstevel@tonic-gate #include <sys/cred.h> 35*0Sstevel@tonic-gate #include <sys/priv.h> 36*0Sstevel@tonic-gate #include <sys/user.h> 37*0Sstevel@tonic-gate #include <sys/errno.h> 38*0Sstevel@tonic-gate #include <sys/vnode.h> 39*0Sstevel@tonic-gate #include <sys/mman.h> 40*0Sstevel@tonic-gate #include <sys/kmem.h> 41*0Sstevel@tonic-gate #include <sys/proc.h> 42*0Sstevel@tonic-gate #include <sys/pathname.h> 43*0Sstevel@tonic-gate #include <sys/cmn_err.h> 44*0Sstevel@tonic-gate #include <sys/systm.h> 45*0Sstevel@tonic-gate #include <sys/elf.h> 46*0Sstevel@tonic-gate #include <sys/vmsystm.h> 47*0Sstevel@tonic-gate #include <sys/debug.h> 48*0Sstevel@tonic-gate #include <sys/procfs.h> 49*0Sstevel@tonic-gate #include <sys/regset.h> 50*0Sstevel@tonic-gate #include <sys/auxv.h> 51*0Sstevel@tonic-gate #include <sys/exec.h> 52*0Sstevel@tonic-gate #include <sys/prsystm.h> 53*0Sstevel@tonic-gate #include <sys/utsname.h> 54*0Sstevel@tonic-gate #include <sys/zone.h> 55*0Sstevel@tonic-gate #include <vm/as.h> 56*0Sstevel@tonic-gate #include <vm/rm.h> 57*0Sstevel@tonic-gate #include <sys/modctl.h> 58*0Sstevel@tonic-gate #include <sys/systeminfo.h> 59*0Sstevel@tonic-gate #include <sys/machelf.h> 60*0Sstevel@tonic-gate #include "elf_impl.h" 61*0Sstevel@tonic-gate #if defined(__i386) || defined(__i386_COMPAT) 62*0Sstevel@tonic-gate #include <sys/sysi86.h> 63*0Sstevel@tonic-gate #endif 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate void 66*0Sstevel@tonic-gate setup_note_header(Phdr *v, proc_t *p) 67*0Sstevel@tonic-gate { 68*0Sstevel@tonic-gate int nlwp = p->p_lwpcnt; 69*0Sstevel@tonic-gate int nzomb = p->p_zombcnt; 70*0Sstevel@tonic-gate size_t size; 71*0Sstevel@tonic-gate prcred_t *pcrp; 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate v[0].p_type = PT_NOTE; 74*0Sstevel@tonic-gate v[0].p_flags = PF_R; 75*0Sstevel@tonic-gate v[0].p_filesz = (sizeof (Note) * (9 + 2 * nlwp + nzomb)) 76*0Sstevel@tonic-gate + roundup(sizeof (psinfo_t), sizeof (Word)) 77*0Sstevel@tonic-gate + roundup(sizeof (pstatus_t), sizeof (Word)) 78*0Sstevel@tonic-gate + roundup(prgetprivsize(), sizeof (Word)) 79*0Sstevel@tonic-gate + roundup(priv_get_implinfo_size(), sizeof (Word)) 80*0Sstevel@tonic-gate + roundup(strlen(platform) + 1, sizeof (Word)) 81*0Sstevel@tonic-gate + roundup(strlen(p->p_zone->zone_name) + 1, sizeof (Word)) 82*0Sstevel@tonic-gate + roundup(__KERN_NAUXV_IMPL * sizeof (aux_entry_t), sizeof (Word)) 83*0Sstevel@tonic-gate + roundup(sizeof (utsname), sizeof (Word)) 84*0Sstevel@tonic-gate + roundup(sizeof (core_content_t), sizeof (Word)) 85*0Sstevel@tonic-gate + (nlwp + nzomb) * roundup(sizeof (lwpsinfo_t), sizeof (Word)) 86*0Sstevel@tonic-gate + nlwp * roundup(sizeof (lwpstatus_t), sizeof (Word)); 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate size = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1); 89*0Sstevel@tonic-gate pcrp = kmem_alloc(size, KM_SLEEP); 90*0Sstevel@tonic-gate prgetcred(p, pcrp); 91*0Sstevel@tonic-gate if (pcrp->pr_ngroups != 0) { 92*0Sstevel@tonic-gate v[0].p_filesz += sizeof (Note) + roundup(sizeof (prcred_t) + 93*0Sstevel@tonic-gate sizeof (gid_t) * (pcrp->pr_ngroups - 1), sizeof (Word)); 94*0Sstevel@tonic-gate } else { 95*0Sstevel@tonic-gate v[0].p_filesz += sizeof (Note) + 96*0Sstevel@tonic-gate roundup(sizeof (prcred_t), sizeof (Word)); 97*0Sstevel@tonic-gate } 98*0Sstevel@tonic-gate kmem_free(pcrp, size); 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate #if defined(__i386) || defined(__i386_COMPAT) 101*0Sstevel@tonic-gate mutex_enter(&p->p_ldtlock); 102*0Sstevel@tonic-gate size = prnldt(p) * sizeof (struct ssd); 103*0Sstevel@tonic-gate mutex_exit(&p->p_ldtlock); 104*0Sstevel@tonic-gate if (size != 0) 105*0Sstevel@tonic-gate v[0].p_filesz += sizeof (Note) + roundup(size, sizeof (Word)); 106*0Sstevel@tonic-gate #endif /* __i386 || __i386_COMPAT */ 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate if ((size = prhasx(p)? prgetprxregsize(p) : 0) != 0) 109*0Sstevel@tonic-gate v[0].p_filesz += nlwp * sizeof (Note) 110*0Sstevel@tonic-gate + nlwp * roundup(size, sizeof (Word)); 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate #if defined(__sparc) 113*0Sstevel@tonic-gate /* 114*0Sstevel@tonic-gate * Figure out the number and sizes of register windows. 115*0Sstevel@tonic-gate */ 116*0Sstevel@tonic-gate { 117*0Sstevel@tonic-gate kthread_t *t = p->p_tlist; 118*0Sstevel@tonic-gate do { 119*0Sstevel@tonic-gate if ((size = prnwindows(ttolwp(t))) != 0) { 120*0Sstevel@tonic-gate size = sizeof (gwindows_t) - 121*0Sstevel@tonic-gate (SPARC_MAXREGWINDOW - size) * 122*0Sstevel@tonic-gate sizeof (struct rwindow); 123*0Sstevel@tonic-gate v[0].p_filesz += sizeof (Note) + 124*0Sstevel@tonic-gate roundup(size, sizeof (Word)); 125*0Sstevel@tonic-gate } 126*0Sstevel@tonic-gate } while ((t = t->t_forw) != p->p_tlist); 127*0Sstevel@tonic-gate } 128*0Sstevel@tonic-gate /* 129*0Sstevel@tonic-gate * Space for the Ancillary State Registers. 130*0Sstevel@tonic-gate */ 131*0Sstevel@tonic-gate if (p->p_model == DATAMODEL_LP64) 132*0Sstevel@tonic-gate v[0].p_filesz += nlwp * sizeof (Note) 133*0Sstevel@tonic-gate + nlwp * roundup(sizeof (asrset_t), sizeof (Word)); 134*0Sstevel@tonic-gate #endif /* __sparc */ 135*0Sstevel@tonic-gate } 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate int 138*0Sstevel@tonic-gate write_elfnotes(proc_t *p, int sig, vnode_t *vp, offset_t offset, 139*0Sstevel@tonic-gate rlim64_t rlimit, cred_t *credp, core_content_t content) 140*0Sstevel@tonic-gate { 141*0Sstevel@tonic-gate union { 142*0Sstevel@tonic-gate psinfo_t psinfo; 143*0Sstevel@tonic-gate pstatus_t pstatus; 144*0Sstevel@tonic-gate lwpsinfo_t lwpsinfo; 145*0Sstevel@tonic-gate lwpstatus_t lwpstatus; 146*0Sstevel@tonic-gate #if defined(__sparc) 147*0Sstevel@tonic-gate gwindows_t gwindows; 148*0Sstevel@tonic-gate asrset_t asrset; 149*0Sstevel@tonic-gate #endif /* __sparc */ 150*0Sstevel@tonic-gate char xregs[1]; 151*0Sstevel@tonic-gate aux_entry_t auxv[__KERN_NAUXV_IMPL]; 152*0Sstevel@tonic-gate prcred_t pcred; 153*0Sstevel@tonic-gate prpriv_t ppriv; 154*0Sstevel@tonic-gate priv_impl_info_t prinfo; 155*0Sstevel@tonic-gate struct utsname uts; 156*0Sstevel@tonic-gate } *bigwad; 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gate size_t xregsize = prhasx(p)? prgetprxregsize(p) : 0; 159*0Sstevel@tonic-gate size_t crsize = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1); 160*0Sstevel@tonic-gate size_t psize = prgetprivsize(); 161*0Sstevel@tonic-gate size_t bigsize = MAX(psize, MAX(sizeof (*bigwad), 162*0Sstevel@tonic-gate MAX(xregsize, crsize))); 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate priv_impl_info_t *prii; 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate lwpdir_t *ldp; 167*0Sstevel@tonic-gate lwpent_t *lep; 168*0Sstevel@tonic-gate kthread_t *t; 169*0Sstevel@tonic-gate klwp_t *lwp; 170*0Sstevel@tonic-gate user_t *up; 171*0Sstevel@tonic-gate int i; 172*0Sstevel@tonic-gate int nlwp; 173*0Sstevel@tonic-gate int nzomb; 174*0Sstevel@tonic-gate int error; 175*0Sstevel@tonic-gate uchar_t oldsig; 176*0Sstevel@tonic-gate #if defined(__i386) || defined(__i386_COMPAT) 177*0Sstevel@tonic-gate struct ssd *ssd; 178*0Sstevel@tonic-gate size_t ssdsize; 179*0Sstevel@tonic-gate #endif /* __i386 || __i386_COMPAT */ 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate bigsize = MAX(bigsize, priv_get_implinfo_size()); 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate bigwad = kmem_alloc(bigsize, KM_SLEEP); 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate /* 186*0Sstevel@tonic-gate * The order of the elfnote entries should be same here 187*0Sstevel@tonic-gate * and in the gcore(1) command. Synchronization is 188*0Sstevel@tonic-gate * needed between the kernel and gcore(1). 189*0Sstevel@tonic-gate */ 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate /* 192*0Sstevel@tonic-gate * Get the psinfo, and set the wait status to indicate that a core was 193*0Sstevel@tonic-gate * dumped. We have to forge this since p->p_wcode is not set yet. 194*0Sstevel@tonic-gate */ 195*0Sstevel@tonic-gate mutex_enter(&p->p_lock); 196*0Sstevel@tonic-gate prgetpsinfo(p, &bigwad->psinfo); 197*0Sstevel@tonic-gate mutex_exit(&p->p_lock); 198*0Sstevel@tonic-gate bigwad->psinfo.pr_wstat = wstat(CLD_DUMPED, sig); 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_PSINFO, sizeof (bigwad->psinfo), 201*0Sstevel@tonic-gate (caddr_t)&bigwad->psinfo, rlimit, credp); 202*0Sstevel@tonic-gate if (error) 203*0Sstevel@tonic-gate goto done; 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate /* 206*0Sstevel@tonic-gate * Modify t_whystop and lwp_cursig so it appears that the current LWP 207*0Sstevel@tonic-gate * is stopped after faulting on the signal that caused the core dump. 208*0Sstevel@tonic-gate * As a result, prgetstatus() will record that signal, the saved 209*0Sstevel@tonic-gate * lwp_siginfo, and its signal handler in the core file status. We 210*0Sstevel@tonic-gate * restore lwp_cursig in case a subsequent signal was received while 211*0Sstevel@tonic-gate * dumping core. 212*0Sstevel@tonic-gate */ 213*0Sstevel@tonic-gate mutex_enter(&p->p_lock); 214*0Sstevel@tonic-gate lwp = ttolwp(curthread); 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate oldsig = lwp->lwp_cursig; 217*0Sstevel@tonic-gate lwp->lwp_cursig = (uchar_t)sig; 218*0Sstevel@tonic-gate curthread->t_whystop = PR_FAULTED; 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate prgetstatus(p, &bigwad->pstatus, p->p_zone); 221*0Sstevel@tonic-gate bigwad->pstatus.pr_lwp.pr_why = 0; 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate curthread->t_whystop = 0; 224*0Sstevel@tonic-gate lwp->lwp_cursig = oldsig; 225*0Sstevel@tonic-gate mutex_exit(&p->p_lock); 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_PSTATUS, sizeof (bigwad->pstatus), 228*0Sstevel@tonic-gate (caddr_t)&bigwad->pstatus, rlimit, credp); 229*0Sstevel@tonic-gate if (error) 230*0Sstevel@tonic-gate goto done; 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_PLATFORM, strlen(platform) + 1, 233*0Sstevel@tonic-gate platform, rlimit, credp); 234*0Sstevel@tonic-gate if (error) 235*0Sstevel@tonic-gate goto done; 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate up = PTOU(p); 238*0Sstevel@tonic-gate for (i = 0; i < __KERN_NAUXV_IMPL; i++) { 239*0Sstevel@tonic-gate bigwad->auxv[i].a_type = up->u_auxv[i].a_type; 240*0Sstevel@tonic-gate bigwad->auxv[i].a_un.a_val = up->u_auxv[i].a_un.a_val; 241*0Sstevel@tonic-gate } 242*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_AUXV, sizeof (bigwad->auxv), 243*0Sstevel@tonic-gate (caddr_t)bigwad->auxv, rlimit, credp); 244*0Sstevel@tonic-gate if (error) 245*0Sstevel@tonic-gate goto done; 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate bcopy(&utsname, &bigwad->uts, sizeof (struct utsname)); 248*0Sstevel@tonic-gate if (!INGLOBALZONE(p)) { 249*0Sstevel@tonic-gate bcopy(p->p_zone->zone_nodename, &bigwad->uts.nodename, 250*0Sstevel@tonic-gate _SYS_NMLN); 251*0Sstevel@tonic-gate } 252*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_UTSNAME, sizeof (struct utsname), 253*0Sstevel@tonic-gate (caddr_t)&bigwad->uts, rlimit, credp); 254*0Sstevel@tonic-gate if (error) 255*0Sstevel@tonic-gate goto done; 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate prgetcred(p, &bigwad->pcred); 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate if (bigwad->pcred.pr_ngroups != 0) { 260*0Sstevel@tonic-gate crsize = sizeof (prcred_t) + 261*0Sstevel@tonic-gate sizeof (gid_t) * (bigwad->pcred.pr_ngroups - 1); 262*0Sstevel@tonic-gate } else 263*0Sstevel@tonic-gate crsize = sizeof (prcred_t); 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_PRCRED, crsize, 266*0Sstevel@tonic-gate (caddr_t)&bigwad->pcred, rlimit, credp); 267*0Sstevel@tonic-gate if (error) 268*0Sstevel@tonic-gate goto done; 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_CONTENT, sizeof (core_content_t), 271*0Sstevel@tonic-gate (caddr_t)&content, rlimit, credp); 272*0Sstevel@tonic-gate if (error) 273*0Sstevel@tonic-gate goto done; 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gate prgetpriv(p, &bigwad->ppriv); 276*0Sstevel@tonic-gate 277*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_PRPRIV, psize, 278*0Sstevel@tonic-gate (caddr_t)&bigwad->ppriv, rlimit, credp); 279*0Sstevel@tonic-gate if (error) 280*0Sstevel@tonic-gate goto done; 281*0Sstevel@tonic-gate 282*0Sstevel@tonic-gate prii = priv_hold_implinfo(); 283*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_PRPRIVINFO, priv_get_implinfo_size(), 284*0Sstevel@tonic-gate (caddr_t)prii, rlimit, credp); 285*0Sstevel@tonic-gate priv_release_implinfo(); 286*0Sstevel@tonic-gate if (error) 287*0Sstevel@tonic-gate goto done; 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate /* zone can't go away as long as process exists */ 290*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_ZONENAME, 291*0Sstevel@tonic-gate strlen(p->p_zone->zone_name) + 1, p->p_zone->zone_name, 292*0Sstevel@tonic-gate rlimit, credp); 293*0Sstevel@tonic-gate if (error) 294*0Sstevel@tonic-gate goto done; 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate #if defined(__i386) || defined(__i386_COMPAT) 297*0Sstevel@tonic-gate mutex_enter(&p->p_ldtlock); 298*0Sstevel@tonic-gate ssdsize = prnldt(p) * sizeof (struct ssd); 299*0Sstevel@tonic-gate if (ssdsize != 0) { 300*0Sstevel@tonic-gate ssd = kmem_alloc(ssdsize, KM_SLEEP); 301*0Sstevel@tonic-gate prgetldt(p, ssd); 302*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_LDT, ssdsize, 303*0Sstevel@tonic-gate (caddr_t)ssd, rlimit, credp); 304*0Sstevel@tonic-gate kmem_free(ssd, ssdsize); 305*0Sstevel@tonic-gate } 306*0Sstevel@tonic-gate mutex_exit(&p->p_ldtlock); 307*0Sstevel@tonic-gate if (error) 308*0Sstevel@tonic-gate goto done; 309*0Sstevel@tonic-gate #endif /* __i386 || defined(__i386_COMPAT) */ 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate nlwp = p->p_lwpcnt; 312*0Sstevel@tonic-gate nzomb = p->p_zombcnt; 313*0Sstevel@tonic-gate /* for each entry in the lwp directory ... */ 314*0Sstevel@tonic-gate for (ldp = p->p_lwpdir; nlwp + nzomb != 0; ldp++) { 315*0Sstevel@tonic-gate 316*0Sstevel@tonic-gate if ((lep = ldp->ld_entry) == NULL) /* empty slot */ 317*0Sstevel@tonic-gate continue; 318*0Sstevel@tonic-gate 319*0Sstevel@tonic-gate if ((t = lep->le_thread) != NULL) { /* active lwp */ 320*0Sstevel@tonic-gate ASSERT(nlwp != 0); 321*0Sstevel@tonic-gate nlwp--; 322*0Sstevel@tonic-gate lwp = ttolwp(t); 323*0Sstevel@tonic-gate mutex_enter(&p->p_lock); 324*0Sstevel@tonic-gate prgetlwpsinfo(t, &bigwad->lwpsinfo); 325*0Sstevel@tonic-gate mutex_exit(&p->p_lock); 326*0Sstevel@tonic-gate } else { /* zombie lwp */ 327*0Sstevel@tonic-gate ASSERT(nzomb != 0); 328*0Sstevel@tonic-gate nzomb--; 329*0Sstevel@tonic-gate bzero(&bigwad->lwpsinfo, sizeof (bigwad->lwpsinfo)); 330*0Sstevel@tonic-gate bigwad->lwpsinfo.pr_lwpid = lep->le_lwpid; 331*0Sstevel@tonic-gate bigwad->lwpsinfo.pr_state = SZOMB; 332*0Sstevel@tonic-gate bigwad->lwpsinfo.pr_sname = 'Z'; 333*0Sstevel@tonic-gate bigwad->lwpsinfo.pr_start.tv_sec = lep->le_start; 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_LWPSINFO, 336*0Sstevel@tonic-gate sizeof (bigwad->lwpsinfo), (caddr_t)&bigwad->lwpsinfo, 337*0Sstevel@tonic-gate rlimit, credp); 338*0Sstevel@tonic-gate if (error) 339*0Sstevel@tonic-gate goto done; 340*0Sstevel@tonic-gate if (t == NULL) /* nothing more to do for a zombie */ 341*0Sstevel@tonic-gate continue; 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gate mutex_enter(&p->p_lock); 344*0Sstevel@tonic-gate if (t == curthread) { 345*0Sstevel@tonic-gate /* 346*0Sstevel@tonic-gate * Modify t_whystop and lwp_cursig so it appears that 347*0Sstevel@tonic-gate * the current LWP is stopped after faulting on the 348*0Sstevel@tonic-gate * signal that caused the core dump. As a result, 349*0Sstevel@tonic-gate * prgetlwpstatus() will record that signal, the saved 350*0Sstevel@tonic-gate * lwp_siginfo, and its signal handler in the core file 351*0Sstevel@tonic-gate * status. We restore lwp_cursig in case a subsequent 352*0Sstevel@tonic-gate * signal was received while dumping core. 353*0Sstevel@tonic-gate */ 354*0Sstevel@tonic-gate oldsig = lwp->lwp_cursig; 355*0Sstevel@tonic-gate lwp->lwp_cursig = (uchar_t)sig; 356*0Sstevel@tonic-gate t->t_whystop = PR_FAULTED; 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone); 359*0Sstevel@tonic-gate bigwad->lwpstatus.pr_why = 0; 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate t->t_whystop = 0; 362*0Sstevel@tonic-gate lwp->lwp_cursig = oldsig; 363*0Sstevel@tonic-gate } else { 364*0Sstevel@tonic-gate prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone); 365*0Sstevel@tonic-gate } 366*0Sstevel@tonic-gate mutex_exit(&p->p_lock); 367*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_LWPSTATUS, 368*0Sstevel@tonic-gate sizeof (bigwad->lwpstatus), (caddr_t)&bigwad->lwpstatus, 369*0Sstevel@tonic-gate rlimit, credp); 370*0Sstevel@tonic-gate if (error) 371*0Sstevel@tonic-gate goto done; 372*0Sstevel@tonic-gate 373*0Sstevel@tonic-gate #if defined(__sparc) 374*0Sstevel@tonic-gate /* 375*0Sstevel@tonic-gate * Unspilled SPARC register windows. 376*0Sstevel@tonic-gate */ 377*0Sstevel@tonic-gate { 378*0Sstevel@tonic-gate size_t size = prnwindows(lwp); 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gate if (size != 0) { 381*0Sstevel@tonic-gate size = sizeof (gwindows_t) - 382*0Sstevel@tonic-gate (SPARC_MAXREGWINDOW - size) * 383*0Sstevel@tonic-gate sizeof (struct rwindow); 384*0Sstevel@tonic-gate prgetwindows(lwp, &bigwad->gwindows); 385*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_GWINDOWS, 386*0Sstevel@tonic-gate size, (caddr_t)&bigwad->gwindows, 387*0Sstevel@tonic-gate rlimit, credp); 388*0Sstevel@tonic-gate if (error) 389*0Sstevel@tonic-gate goto done; 390*0Sstevel@tonic-gate } 391*0Sstevel@tonic-gate } 392*0Sstevel@tonic-gate /* 393*0Sstevel@tonic-gate * Ancillary State Registers. 394*0Sstevel@tonic-gate */ 395*0Sstevel@tonic-gate if (p->p_model == DATAMODEL_LP64) { 396*0Sstevel@tonic-gate prgetasregs(lwp, bigwad->asrset); 397*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_ASRS, 398*0Sstevel@tonic-gate sizeof (asrset_t), (caddr_t)bigwad->asrset, 399*0Sstevel@tonic-gate rlimit, credp); 400*0Sstevel@tonic-gate if (error) 401*0Sstevel@tonic-gate goto done; 402*0Sstevel@tonic-gate } 403*0Sstevel@tonic-gate #endif /* __sparc */ 404*0Sstevel@tonic-gate 405*0Sstevel@tonic-gate if (xregsize) { 406*0Sstevel@tonic-gate prgetprxregs(lwp, bigwad->xregs); 407*0Sstevel@tonic-gate error = elfnote(vp, &offset, NT_PRXREG, 408*0Sstevel@tonic-gate xregsize, bigwad->xregs, rlimit, credp); 409*0Sstevel@tonic-gate if (error) 410*0Sstevel@tonic-gate goto done; 411*0Sstevel@tonic-gate } 412*0Sstevel@tonic-gate } 413*0Sstevel@tonic-gate ASSERT(nlwp == 0); 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate done: 416*0Sstevel@tonic-gate kmem_free(bigwad, bigsize); 417*0Sstevel@tonic-gate return (error); 418*0Sstevel@tonic-gate } 419