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
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.
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]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
29 * Copyright 2018 Joyent, Inc.
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/thread.h>
35 #include <sys/sysmacros.h>
36 #include <sys/signal.h>
41 #include <sys/errno.h>
42 #include <sys/vnode.h>
48 #include <sys/pathname.h>
49 #include <sys/cmn_err.h>
50 #include <sys/systm.h>
52 #include <sys/vmsystm.h>
53 #include <sys/debug.h>
54 #include <sys/procfs.h>
55 #include <sys/regset.h>
58 #include <sys/prsystm.h>
59 #include <sys/utsname.h>
63 #include <sys/modctl.h>
64 #include <sys/systeminfo.h>
65 #include <sys/machelf.h>
66 #include <sys/sunddi.h>
68 #if defined(__i386) || defined(__i386_COMPAT)
69 #include <sys/sysi86.h>
73 setup_note_header(Phdr
*v
, proc_t
*p
)
75 int nlwp
= p
->p_lwpcnt
;
76 int nzomb
= p
->p_zombcnt
;
86 mutex_enter(&fip
->fi_lock
);
87 for (fd
= 0; fd
< fip
->fi_nfiles
; fd
++) {
88 UF_ENTER(ufp
, fip
, fd
);
89 if ((ufp
->uf_file
!= NULL
) && (ufp
->uf_file
->f_count
> 0))
93 mutex_exit(&fip
->fi_lock
);
95 v
[0].p_type
= PT_NOTE
;
97 v
[0].p_filesz
= (sizeof (Note
) * (10 + 3 * nlwp
+ nzomb
+ nfd
))
98 + roundup(sizeof (psinfo_t
), sizeof (Word
))
99 + roundup(sizeof (pstatus_t
), sizeof (Word
))
100 + roundup(prgetprivsize(), sizeof (Word
))
101 + roundup(priv_get_implinfo_size(), sizeof (Word
))
102 + roundup(strlen(platform
) + 1, sizeof (Word
))
103 + roundup(strlen(p
->p_zone
->zone_name
) + 1, sizeof (Word
))
104 + roundup(__KERN_NAUXV_IMPL
* sizeof (aux_entry_t
), sizeof (Word
))
105 + roundup(sizeof (utsname
), sizeof (Word
))
106 + roundup(sizeof (core_content_t
), sizeof (Word
))
107 + roundup(sizeof (prsecflags_t
), sizeof (Word
))
108 + (nlwp
+ nzomb
) * roundup(sizeof (lwpsinfo_t
), sizeof (Word
))
109 + nlwp
* roundup(sizeof (lwpstatus_t
), sizeof (Word
))
110 + nlwp
* roundup(sizeof (prlwpname_t
), sizeof (Word
))
111 + nfd
* roundup(sizeof (prfdinfo_t
), sizeof (Word
));
113 if (curproc
->p_agenttp
!= NULL
) {
114 v
[0].p_filesz
+= sizeof (Note
) +
115 roundup(sizeof (psinfo_t
), sizeof (Word
));
118 size
= sizeof (prcred_t
) + sizeof (gid_t
) * (ngroups_max
- 1);
119 pcrp
= kmem_alloc(size
, KM_SLEEP
);
121 if (pcrp
->pr_ngroups
!= 0) {
122 v
[0].p_filesz
+= sizeof (Note
) + roundup(sizeof (prcred_t
) +
123 sizeof (gid_t
) * (pcrp
->pr_ngroups
- 1), sizeof (Word
));
125 v
[0].p_filesz
+= sizeof (Note
) +
126 roundup(sizeof (prcred_t
), sizeof (Word
));
128 kmem_free(pcrp
, size
);
131 #if defined(__i386) || defined(__i386_COMPAT)
132 mutex_enter(&p
->p_ldtlock
);
133 size
= prnldt(p
) * sizeof (struct ssd
);
134 mutex_exit(&p
->p_ldtlock
);
136 v
[0].p_filesz
+= sizeof (Note
) + roundup(size
, sizeof (Word
));
137 #endif /* __i386 || __i386_COMPAT */
139 if ((size
= prhasx(p
)? prgetprxregsize(p
) : 0) != 0)
140 v
[0].p_filesz
+= nlwp
* sizeof (Note
)
141 + nlwp
* roundup(size
, sizeof (Word
));
145 * Figure out the number and sizes of register windows.
148 kthread_t
*t
= p
->p_tlist
;
150 if ((size
= prnwindows(ttolwp(t
))) != 0) {
151 size
= sizeof (gwindows_t
) -
152 (SPARC_MAXREGWINDOW
- size
) *
153 sizeof (struct rwindow
);
154 v
[0].p_filesz
+= sizeof (Note
) +
155 roundup(size
, sizeof (Word
));
157 } while ((t
= t
->t_forw
) != p
->p_tlist
);
160 * Space for the Ancillary State Registers.
162 if (p
->p_model
== DATAMODEL_LP64
)
163 v
[0].p_filesz
+= nlwp
* sizeof (Note
)
164 + nlwp
* roundup(sizeof (asrset_t
), sizeof (Word
));
169 write_elfnotes(proc_t
*p
, int sig
, vnode_t
*vp
, offset_t offset
,
170 rlim64_t rlimit
, cred_t
*credp
, core_content_t content
)
176 lwpstatus_t lwpstatus
;
182 aux_entry_t auxv
[__KERN_NAUXV_IMPL
];
185 priv_impl_info_t prinfo
;
187 prsecflags_t psecflags
;
190 size_t xregsize
= prhasx(p
)? prgetprxregsize(p
) : 0;
191 size_t crsize
= sizeof (prcred_t
) + sizeof (gid_t
) * (ngroups_max
- 1);
192 size_t psize
= prgetprivsize();
193 size_t bigsize
= MAX(psize
, MAX(sizeof (*bigwad
),
194 MAX(xregsize
, crsize
)));
196 priv_impl_info_t
*prii
;
212 #if defined(__i386) || defined(__i386_COMPAT)
215 #endif /* __i386 || __i386_COMPAT */
217 bigsize
= MAX(bigsize
, priv_get_implinfo_size());
219 bigwad
= kmem_alloc(bigsize
, KM_SLEEP
);
222 * The order of the elfnote entries should be same here
223 * and in the gcore(1) command. Synchronization is
224 * needed between the kernel and gcore(1).
228 * Get the psinfo, and set the wait status to indicate that a core was
229 * dumped. We have to forge this since p->p_wcode is not set yet.
231 mutex_enter(&p
->p_lock
);
232 prgetpsinfo(p
, &bigwad
->psinfo
);
233 mutex_exit(&p
->p_lock
);
234 bigwad
->psinfo
.pr_wstat
= wstat(CLD_DUMPED
, sig
);
236 error
= elfnote(vp
, &offset
, NT_PSINFO
, sizeof (bigwad
->psinfo
),
237 (caddr_t
)&bigwad
->psinfo
, rlimit
, credp
);
242 * Modify t_whystop and lwp_cursig so it appears that the current LWP
243 * is stopped after faulting on the signal that caused the core dump.
244 * As a result, prgetstatus() will record that signal, the saved
245 * lwp_siginfo, and its signal handler in the core file status. We
246 * restore lwp_cursig in case a subsequent signal was received while
249 mutex_enter(&p
->p_lock
);
250 lwp
= ttolwp(curthread
);
252 oldsig
= lwp
->lwp_cursig
;
253 lwp
->lwp_cursig
= (uchar_t
)sig
;
254 curthread
->t_whystop
= PR_FAULTED
;
256 prgetstatus(p
, &bigwad
->pstatus
, p
->p_zone
);
257 bigwad
->pstatus
.pr_lwp
.pr_why
= 0;
259 curthread
->t_whystop
= 0;
260 lwp
->lwp_cursig
= oldsig
;
261 mutex_exit(&p
->p_lock
);
263 error
= elfnote(vp
, &offset
, NT_PSTATUS
, sizeof (bigwad
->pstatus
),
264 (caddr_t
)&bigwad
->pstatus
, rlimit
, credp
);
268 error
= elfnote(vp
, &offset
, NT_PLATFORM
, strlen(platform
) + 1,
269 platform
, rlimit
, credp
);
274 for (i
= 0; i
< __KERN_NAUXV_IMPL
; i
++) {
275 bigwad
->auxv
[i
].a_type
= up
->u_auxv
[i
].a_type
;
276 bigwad
->auxv
[i
].a_un
.a_val
= up
->u_auxv
[i
].a_un
.a_val
;
278 error
= elfnote(vp
, &offset
, NT_AUXV
, sizeof (bigwad
->auxv
),
279 (caddr_t
)bigwad
->auxv
, rlimit
, credp
);
283 bcopy(&utsname
, &bigwad
->uts
, sizeof (struct utsname
));
284 if (!INGLOBALZONE(p
)) {
285 bcopy(p
->p_zone
->zone_nodename
, &bigwad
->uts
.nodename
,
288 error
= elfnote(vp
, &offset
, NT_UTSNAME
, sizeof (struct utsname
),
289 (caddr_t
)&bigwad
->uts
, rlimit
, credp
);
293 prgetsecflags(p
, &bigwad
->psecflags
);
294 error
= elfnote(vp
, &offset
, NT_SECFLAGS
, sizeof (prsecflags_t
),
295 (caddr_t
)&bigwad
->psecflags
, rlimit
, credp
);
299 prgetcred(p
, &bigwad
->pcred
);
301 if (bigwad
->pcred
.pr_ngroups
!= 0) {
302 crsize
= sizeof (prcred_t
) +
303 sizeof (gid_t
) * (bigwad
->pcred
.pr_ngroups
- 1);
305 crsize
= sizeof (prcred_t
);
307 error
= elfnote(vp
, &offset
, NT_PRCRED
, crsize
,
308 (caddr_t
)&bigwad
->pcred
, rlimit
, credp
);
312 error
= elfnote(vp
, &offset
, NT_CONTENT
, sizeof (core_content_t
),
313 (caddr_t
)&content
, rlimit
, credp
);
317 prgetpriv(p
, &bigwad
->ppriv
);
319 error
= elfnote(vp
, &offset
, NT_PRPRIV
, psize
,
320 (caddr_t
)&bigwad
->ppriv
, rlimit
, credp
);
324 prii
= priv_hold_implinfo();
325 error
= elfnote(vp
, &offset
, NT_PRPRIVINFO
, priv_get_implinfo_size(),
326 (caddr_t
)prii
, rlimit
, credp
);
327 priv_release_implinfo();
331 /* zone can't go away as long as process exists */
332 error
= elfnote(vp
, &offset
, NT_ZONENAME
,
333 strlen(p
->p_zone
->zone_name
) + 1, p
->p_zone
->zone_name
,
339 /* open file table */
340 vroot
= PTOU(p
)->u_rdir
;
348 for (fd
= 0; fd
< fip
->fi_nfiles
; fd
++) {
355 bzero(&fdinfo
, sizeof (fdinfo
));
357 mutex_enter(&fip
->fi_lock
);
358 UF_ENTER(ufp
, fip
, fd
);
359 if (((fp
= ufp
->uf_file
) == NULL
) || (fp
->f_count
< 1)) {
361 mutex_exit(&fip
->fi_lock
);
366 fdinfo
.pr_fdflags
= ufp
->uf_flag
;
367 fdinfo
.pr_fileflags
= fp
->f_flag2
;
368 fdinfo
.pr_fileflags
<<= 16;
369 fdinfo
.pr_fileflags
|= fp
->f_flag
;
370 if ((fdinfo
.pr_fileflags
& (FSEARCH
| FEXEC
)) == 0)
371 fdinfo
.pr_fileflags
+= FOPEN
;
372 fdinfo
.pr_offset
= fp
->f_offset
;
378 mutex_exit(&fip
->fi_lock
);
381 * There are some vnodes that have no corresponding
382 * path. Its reasonable for this to fail, in which
383 * case the path will remain an empty string.
385 (void) vnodetopath(vroot
, fvp
, fdinfo
.pr_path
,
386 sizeof (fdinfo
.pr_path
), credp
);
388 if (VOP_GETATTR(fvp
, &vattr
, 0, credp
, NULL
) != 0) {
390 * Try to write at least a subset of information
396 fdinfo
.pr_uid
= (uid_t
)-1;
397 fdinfo
.pr_gid
= (gid_t
)-1;
398 fdinfo
.pr_rmajor
= 0;
399 fdinfo
.pr_rminor
= 0;
402 error
= elfnote(vp
, &offset
, NT_FDINFO
,
403 sizeof (fdinfo
), &fdinfo
, rlimit
, credp
);
412 if (fvp
->v_type
== VSOCK
)
413 fdinfo
.pr_fileflags
|= sock_getfasync(fvp
);
418 * This logic mirrors fstat(), which we cannot use
419 * directly, as it calls copyout().
421 fdinfo
.pr_major
= getmajor(vattr
.va_fsid
);
422 fdinfo
.pr_minor
= getminor(vattr
.va_fsid
);
423 fdinfo
.pr_ino
= (ino64_t
)vattr
.va_nodeid
;
424 fdinfo
.pr_mode
= VTTOIF(vattr
.va_type
) | vattr
.va_mode
;
425 fdinfo
.pr_uid
= vattr
.va_uid
;
426 fdinfo
.pr_gid
= vattr
.va_gid
;
427 fdinfo
.pr_rmajor
= getmajor(vattr
.va_rdev
);
428 fdinfo
.pr_rminor
= getminor(vattr
.va_rdev
);
429 fdinfo
.pr_size
= (off64_t
)vattr
.va_size
;
431 error
= elfnote(vp
, &offset
, NT_FDINFO
,
432 sizeof (fdinfo
), &fdinfo
, rlimit
, credp
);
441 #if defined(__i386) || defined(__i386_COMPAT)
442 mutex_enter(&p
->p_ldtlock
);
443 ssdsize
= prnldt(p
) * sizeof (struct ssd
);
445 ssd
= kmem_alloc(ssdsize
, KM_SLEEP
);
447 error
= elfnote(vp
, &offset
, NT_LDT
, ssdsize
,
448 (caddr_t
)ssd
, rlimit
, credp
);
449 kmem_free(ssd
, ssdsize
);
451 mutex_exit(&p
->p_ldtlock
);
454 #endif /* __i386 || defined(__i386_COMPAT) */
457 nzomb
= p
->p_zombcnt
;
458 /* for each entry in the lwp directory ... */
459 for (ldp
= p
->p_lwpdir
; nlwp
+ nzomb
!= 0; ldp
++) {
460 prlwpname_t name
= { 0, };
462 if ((lep
= ldp
->ld_entry
) == NULL
) /* empty slot */
465 if ((t
= lep
->le_thread
) != NULL
) { /* active lwp */
469 mutex_enter(&p
->p_lock
);
470 prgetlwpsinfo(t
, &bigwad
->lwpsinfo
);
471 if (t
->t_name
!= NULL
) {
472 (void) strlcpy(name
.pr_lwpname
, t
->t_name
,
473 sizeof (name
.pr_lwpname
));
475 mutex_exit(&p
->p_lock
);
476 } else { /* zombie lwp */
479 bzero(&bigwad
->lwpsinfo
, sizeof (bigwad
->lwpsinfo
));
480 bigwad
->lwpsinfo
.pr_lwpid
= lep
->le_lwpid
;
481 bigwad
->lwpsinfo
.pr_state
= SZOMB
;
482 bigwad
->lwpsinfo
.pr_sname
= 'Z';
483 bigwad
->lwpsinfo
.pr_start
.tv_sec
= lep
->le_start
;
486 name
.pr_lwpid
= bigwad
->lwpsinfo
.pr_lwpid
;
488 error
= elfnote(vp
, &offset
, NT_LWPSINFO
,
489 sizeof (bigwad
->lwpsinfo
), (caddr_t
)&bigwad
->lwpsinfo
,
494 if (t
== NULL
) /* nothing more to do for a zombie */
497 mutex_enter(&p
->p_lock
);
498 if (t
== curthread
) {
500 * Modify t_whystop and lwp_cursig so it appears that
501 * the current LWP is stopped after faulting on the
502 * signal that caused the core dump. As a result,
503 * prgetlwpstatus() will record that signal, the saved
504 * lwp_siginfo, and its signal handler in the core file
505 * status. We restore lwp_cursig in case a subsequent
506 * signal was received while dumping core.
508 oldsig
= lwp
->lwp_cursig
;
509 lwp
->lwp_cursig
= (uchar_t
)sig
;
510 t
->t_whystop
= PR_FAULTED
;
512 prgetlwpstatus(t
, &bigwad
->lwpstatus
, p
->p_zone
);
513 bigwad
->lwpstatus
.pr_why
= 0;
516 lwp
->lwp_cursig
= oldsig
;
518 prgetlwpstatus(t
, &bigwad
->lwpstatus
, p
->p_zone
);
520 mutex_exit(&p
->p_lock
);
521 error
= elfnote(vp
, &offset
, NT_LWPSTATUS
,
522 sizeof (bigwad
->lwpstatus
), (caddr_t
)&bigwad
->lwpstatus
,
527 if ((error
= elfnote(vp
, &offset
, NT_LWPNAME
, sizeof (name
),
528 (caddr_t
)&name
, rlimit
, credp
)) != 0)
534 * Unspilled SPARC register windows.
537 size_t size
= prnwindows(lwp
);
540 size
= sizeof (gwindows_t
) -
541 (SPARC_MAXREGWINDOW
- size
) *
542 sizeof (struct rwindow
);
543 prgetwindows(lwp
, &bigwad
->gwindows
);
544 error
= elfnote(vp
, &offset
, NT_GWINDOWS
,
545 size
, (caddr_t
)&bigwad
->gwindows
,
552 * Ancillary State Registers.
554 if (p
->p_model
== DATAMODEL_LP64
) {
555 prgetasregs(lwp
, bigwad
->asrset
);
556 error
= elfnote(vp
, &offset
, NT_ASRS
,
557 sizeof (asrset_t
), (caddr_t
)bigwad
->asrset
,
565 prgetprxregs(lwp
, bigwad
->xregs
);
566 error
= elfnote(vp
, &offset
, NT_PRXREG
,
567 xregsize
, bigwad
->xregs
, rlimit
, credp
);
572 if (t
->t_lwp
->lwp_spymaster
!= NULL
) {
573 void *psaddr
= t
->t_lwp
->lwp_spymaster
;
576 * On a 64-bit kernel with 32-bit ELF compatibility,
577 * this file is compiled into two different objects:
578 * one is compiled normally, and the other is compiled
579 * with _ELF32_COMPAT set -- and therefore with a
580 * psinfo_t defined to be a psinfo32_t. However, the
581 * psinfo_t denoting our spymaster is always of the
582 * native type; if we are in the _ELF32_COMPAT case,
583 * we need to explicitly convert it.
585 if (p
->p_model
== DATAMODEL_ILP32
) {
586 psinfo_kto32(psaddr
, &bigwad
->psinfo
);
587 psaddr
= &bigwad
->psinfo
;
591 error
= elfnote(vp
, &offset
, NT_SPYMASTER
,
592 sizeof (psinfo_t
), psaddr
, rlimit
, credp
);
600 kmem_free(bigwad
, bigsize
);