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
setup_note_header(Phdr * v,proc_t * p)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
write_elfnotes(proc_t * p,int sig,vnode_t * vp,offset_t offset,rlim64_t rlimit,cred_t * credp,core_content_t content)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