xref: /illumos-gate/usr/src/lib/libproc/common/Pgcore.c (revision ed093b41)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5d51e9074Sab196087  * Common Development and Distribution License (the "License").
6d51e9074Sab196087  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
212c797a4eSRoger A. Faulkner 
227c478bd9Sstevel@tonic-gate /*
232c797a4eSRoger A. Faulkner  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
2634bdffbfSGarrett D'Amore /*
2734bdffbfSGarrett D'Amore  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
28ab618543SJohn Levon  * Copyright 2018 Joyent, Inc.
292a12f85aSJeremy Jones  * Copyright (c) 2013 by Delphix. All rights reserved.
30a02120c4SAndy Fiddaman  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
31*ed093b41SRobert Mustacchi  * Copyright 2023 Oxide Computer Company
3234bdffbfSGarrett D'Amore  */
337c478bd9Sstevel@tonic-gate 
342c797a4eSRoger A. Faulkner #define	_STRUCTURED_PROC	1
357c478bd9Sstevel@tonic-gate 
368e458de0SRobert Mustacchi #include <assert.h>
377c478bd9Sstevel@tonic-gate #include <stdlib.h>
387c478bd9Sstevel@tonic-gate #include <ctype.h>
397c478bd9Sstevel@tonic-gate #include <string.h>
407c478bd9Sstevel@tonic-gate #include <strings.h>
417c478bd9Sstevel@tonic-gate #include <errno.h>
427c478bd9Sstevel@tonic-gate #include <procfs.h>
437c478bd9Sstevel@tonic-gate #include <priv.h>
447c478bd9Sstevel@tonic-gate #include <sys/elf.h>
457c478bd9Sstevel@tonic-gate #include <sys/machelf.h>
467c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
477c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
487c478bd9Sstevel@tonic-gate #include <sys/proc.h>
497c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
508e458de0SRobert Mustacchi #include <core_shstrtab.h>
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #include <sys/old_procfs.h>
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #include "Pcontrol.h"
557c478bd9Sstevel@tonic-gate #include "P32ton.h"
56a02120c4SAndy Fiddaman #include "proc_fd.h"
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate typedef struct {
597c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P;
607c478bd9Sstevel@tonic-gate 	int		pgc_fd;
617c478bd9Sstevel@tonic-gate 	off64_t		*pgc_poff;
627c478bd9Sstevel@tonic-gate 	off64_t		*pgc_soff;
637c478bd9Sstevel@tonic-gate 	off64_t		*pgc_doff;
647c478bd9Sstevel@tonic-gate 	core_content_t	pgc_content;
657c478bd9Sstevel@tonic-gate 	void		*pgc_chunk;
667c478bd9Sstevel@tonic-gate 	size_t		pgc_chunksz;
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate 	shstrtab_t	pgc_shstrtab;
697c478bd9Sstevel@tonic-gate } pgcore_t;
707c478bd9Sstevel@tonic-gate 
7134bdffbfSGarrett D'Amore typedef struct {
7234bdffbfSGarrett D'Amore 	int		fd_fd;
7334bdffbfSGarrett D'Amore 	off64_t		*fd_doff;
7434bdffbfSGarrett D'Amore } fditer_t;
7534bdffbfSGarrett D'Amore 
7664e4e50aSKeith M Wesolowski static int
gc_pwrite64(int fd,const void * buf,size_t len,off64_t off)7764e4e50aSKeith M Wesolowski gc_pwrite64(int fd, const void *buf, size_t len, off64_t off)
7864e4e50aSKeith M Wesolowski {
7964e4e50aSKeith M Wesolowski 	int err;
8064e4e50aSKeith M Wesolowski 
8164e4e50aSKeith M Wesolowski 	err = pwrite64(fd, buf, len, off);
8264e4e50aSKeith M Wesolowski 
8364e4e50aSKeith M Wesolowski 	if (err < 0)
8464e4e50aSKeith M Wesolowski 		return (err);
8564e4e50aSKeith M Wesolowski 
8664e4e50aSKeith M Wesolowski 	/*
8764e4e50aSKeith M Wesolowski 	 * We will take a page from ZFS's book here and use the otherwise
8864e4e50aSKeith M Wesolowski 	 * unused EBADE to mean a short write.  Typically this will actually
8964e4e50aSKeith M Wesolowski 	 * result from ENOSPC or EDQUOT, but we can't be sure.
9064e4e50aSKeith M Wesolowski 	 */
9164e4e50aSKeith M Wesolowski 	if (err < len) {
9264e4e50aSKeith M Wesolowski 		errno = EBADE;
9364e4e50aSKeith M Wesolowski 		return (-1);
9464e4e50aSKeith M Wesolowski 	}
9564e4e50aSKeith M Wesolowski 
9664e4e50aSKeith M Wesolowski 	return (0);
9764e4e50aSKeith M Wesolowski }
9864e4e50aSKeith M Wesolowski 
997c478bd9Sstevel@tonic-gate int
Pgcore(struct ps_prochandle * P,const char * fname,core_content_t content)1007c478bd9Sstevel@tonic-gate Pgcore(struct ps_prochandle *P, const char *fname, core_content_t content)
1017c478bd9Sstevel@tonic-gate {
1027c478bd9Sstevel@tonic-gate 	int fd;
1037c478bd9Sstevel@tonic-gate 	int err;
10464e4e50aSKeith M Wesolowski 	int saved_errno;
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 	if ((fd = creat64(fname, 0666)) < 0)
1077c478bd9Sstevel@tonic-gate 		return (-1);
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 	if ((err = Pfgcore(P, fd, content)) != 0) {
11064e4e50aSKeith M Wesolowski 		saved_errno = errno;
1117c478bd9Sstevel@tonic-gate 		(void) close(fd);
1127c478bd9Sstevel@tonic-gate 		(void) unlink(fname);
11364e4e50aSKeith M Wesolowski 		errno = saved_errno;
1147c478bd9Sstevel@tonic-gate 		return (err);
1157c478bd9Sstevel@tonic-gate 	}
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	return (close(fd));
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate /*
1217c478bd9Sstevel@tonic-gate  * Since we don't want to use the old-school procfs interfaces, we use the
1227c478bd9Sstevel@tonic-gate  * new-style data structures we already have to construct the old-style
1237c478bd9Sstevel@tonic-gate  * data structures. We include these data structures in core files for
1247c478bd9Sstevel@tonic-gate  * backward compatability.
1257c478bd9Sstevel@tonic-gate  */
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate static void
mkprstatus(struct ps_prochandle * P,const lwpstatus_t * lsp,const lwpsinfo_t * lip,prstatus_t * psp)1287c478bd9Sstevel@tonic-gate mkprstatus(struct ps_prochandle *P, const lwpstatus_t *lsp,
1297c478bd9Sstevel@tonic-gate     const lwpsinfo_t *lip, prstatus_t *psp)
1307c478bd9Sstevel@tonic-gate {
1317c478bd9Sstevel@tonic-gate 	bzero(psp, sizeof (*psp));
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_STOPPED)
1347c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0001;
1357c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ISTOP)
1367c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0002;
1377c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_DSTOP)
1387c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0004;
1397c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASLEEP)
1407c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0008;
1417c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_FORK)
1427c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0010;
1437c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_RLC)
1447c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0020;
1457c478bd9Sstevel@tonic-gate 	/*
1467c478bd9Sstevel@tonic-gate 	 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
1477c478bd9Sstevel@tonic-gate 	 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
1487c478bd9Sstevel@tonic-gate 	 */
1497c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_PCINVAL)
1507c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0080;
1517c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ISSYS)
1527c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0100;
1537c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_STEP)
1547c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0200;
1557c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_KLC)
1567c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0400;
1577c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASYNC)
1587c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0800;
1597c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_PTRACE)
1607c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x1000;
1617c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_MSACCT)
1627c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x2000;
1637c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_BPTADJ)
1647c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x4000;
1657c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASLWP)
1667c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x8000;
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 	psp->pr_why = lsp->pr_why;
1697c478bd9Sstevel@tonic-gate 	psp->pr_what = lsp->pr_what;
1707c478bd9Sstevel@tonic-gate 	psp->pr_info = lsp->pr_info;
1717c478bd9Sstevel@tonic-gate 	psp->pr_cursig = lsp->pr_cursig;
1727c478bd9Sstevel@tonic-gate 	psp->pr_nlwp = P->status.pr_nlwp;
1737c478bd9Sstevel@tonic-gate 	psp->pr_sigpend = P->status.pr_sigpend;
1747c478bd9Sstevel@tonic-gate 	psp->pr_sighold = lsp->pr_lwphold;
1757c478bd9Sstevel@tonic-gate 	psp->pr_altstack = lsp->pr_altstack;
1767c478bd9Sstevel@tonic-gate 	psp->pr_action = lsp->pr_action;
1777c478bd9Sstevel@tonic-gate 	psp->pr_pid = P->status.pr_pid;
1787c478bd9Sstevel@tonic-gate 	psp->pr_ppid = P->status.pr_ppid;
1797c478bd9Sstevel@tonic-gate 	psp->pr_pgrp = P->status.pr_pgid;
1807c478bd9Sstevel@tonic-gate 	psp->pr_sid = P->status.pr_sid;
1817c478bd9Sstevel@tonic-gate 	psp->pr_utime = P->status.pr_utime;
1827c478bd9Sstevel@tonic-gate 	psp->pr_stime = P->status.pr_stime;
1837c478bd9Sstevel@tonic-gate 	psp->pr_cutime = P->status.pr_cutime;
1847c478bd9Sstevel@tonic-gate 	psp->pr_cstime = P->status.pr_cstime;
1857c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
1867c478bd9Sstevel@tonic-gate 	psp->pr_syscall = lsp->pr_syscall;
1877c478bd9Sstevel@tonic-gate 	psp->pr_nsysarg = lsp->pr_nsysarg;
1887c478bd9Sstevel@tonic-gate 	bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg));
1897c478bd9Sstevel@tonic-gate 	psp->pr_who = lsp->pr_lwpid;
1907c478bd9Sstevel@tonic-gate 	psp->pr_lwppend = lsp->pr_lwppend;
1917c478bd9Sstevel@tonic-gate 	psp->pr_oldcontext = (ucontext_t *)lsp->pr_oldcontext;
1927c478bd9Sstevel@tonic-gate 	psp->pr_brkbase = (caddr_t)P->status.pr_brkbase;
1937c478bd9Sstevel@tonic-gate 	psp->pr_brksize = P->status.pr_brksize;
1947c478bd9Sstevel@tonic-gate 	psp->pr_stkbase = (caddr_t)P->status.pr_stkbase;
1957c478bd9Sstevel@tonic-gate 	psp->pr_stksize = P->status.pr_stksize;
1967c478bd9Sstevel@tonic-gate 	psp->pr_processor = (short)lip->pr_onpro;
1977c478bd9Sstevel@tonic-gate 	psp->pr_bind = (short)lip->pr_bindpro;
1987c478bd9Sstevel@tonic-gate 	psp->pr_instr = lsp->pr_instr;
1997c478bd9Sstevel@tonic-gate 	bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
2007c478bd9Sstevel@tonic-gate }
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate static void
mkprpsinfo(struct ps_prochandle * P,prpsinfo_t * psp)2037c478bd9Sstevel@tonic-gate mkprpsinfo(struct ps_prochandle *P, prpsinfo_t *psp)
2047c478bd9Sstevel@tonic-gate {
2057c478bd9Sstevel@tonic-gate 	bzero(psp, sizeof (*psp));
2067c478bd9Sstevel@tonic-gate 	psp->pr_state = P->psinfo.pr_lwp.pr_state;
2077c478bd9Sstevel@tonic-gate 	psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
2087c478bd9Sstevel@tonic-gate 	psp->pr_zomb = (psp->pr_state == SZOMB);
2097c478bd9Sstevel@tonic-gate 	psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
2107c478bd9Sstevel@tonic-gate 	psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
2117c478bd9Sstevel@tonic-gate 	psp->pr_uid = P->psinfo.pr_uid;
2127c478bd9Sstevel@tonic-gate 	psp->pr_gid = P->psinfo.pr_gid;
2137c478bd9Sstevel@tonic-gate 	psp->pr_pid = P->psinfo.pr_pid;
2147c478bd9Sstevel@tonic-gate 	psp->pr_ppid = P->psinfo.pr_ppid;
2157c478bd9Sstevel@tonic-gate 	psp->pr_pgrp = P->psinfo.pr_pgid;
2167c478bd9Sstevel@tonic-gate 	psp->pr_sid = P->psinfo.pr_sid;
2177c478bd9Sstevel@tonic-gate 	psp->pr_addr = (caddr_t)P->psinfo.pr_addr;
2187c478bd9Sstevel@tonic-gate 	psp->pr_size = P->psinfo.pr_size;
2197c478bd9Sstevel@tonic-gate 	psp->pr_rssize = P->psinfo.pr_rssize;
2207c478bd9Sstevel@tonic-gate 	psp->pr_wchan = (caddr_t)P->psinfo.pr_lwp.pr_wchan;
2217c478bd9Sstevel@tonic-gate 	psp->pr_start = P->psinfo.pr_start;
2227c478bd9Sstevel@tonic-gate 	psp->pr_time = P->psinfo.pr_time;
2237c478bd9Sstevel@tonic-gate 	psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
2247c478bd9Sstevel@tonic-gate 	psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
2257c478bd9Sstevel@tonic-gate 	psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
2267c478bd9Sstevel@tonic-gate 	psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
2277c478bd9Sstevel@tonic-gate 	psp->pr_lttydev = P->psinfo.pr_ttydev;
2287c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
2297c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_clname));
2307c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
2317c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_fname));
2327c478bd9Sstevel@tonic-gate 	bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
2337c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_psargs));
2347c478bd9Sstevel@tonic-gate 	psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
2357c478bd9Sstevel@tonic-gate 	psp->pr_ctime = P->psinfo.pr_ctime;
2367c478bd9Sstevel@tonic-gate 	psp->pr_bysize = psp->pr_size * PAGESIZE;
2377c478bd9Sstevel@tonic-gate 	psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
2387c478bd9Sstevel@tonic-gate 	psp->pr_argc = P->psinfo.pr_argc;
2397c478bd9Sstevel@tonic-gate 	psp->pr_argv = (char **)P->psinfo.pr_argv;
2407c478bd9Sstevel@tonic-gate 	psp->pr_envp = (char **)P->psinfo.pr_envp;
2417c478bd9Sstevel@tonic-gate 	psp->pr_wstat = P->psinfo.pr_wstat;
2427c478bd9Sstevel@tonic-gate 	psp->pr_pctcpu = P->psinfo.pr_pctcpu;
2437c478bd9Sstevel@tonic-gate 	psp->pr_pctmem = P->psinfo.pr_pctmem;
2447c478bd9Sstevel@tonic-gate 	psp->pr_euid = P->psinfo.pr_euid;
2457c478bd9Sstevel@tonic-gate 	psp->pr_egid = P->psinfo.pr_egid;
2467c478bd9Sstevel@tonic-gate 	psp->pr_aslwpid = 0;
2477c478bd9Sstevel@tonic-gate 	psp->pr_dmodel = P->psinfo.pr_dmodel;
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate #ifdef _LP64
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate static void
mkprstatus32(struct ps_prochandle * P,const lwpstatus_t * lsp,const lwpsinfo_t * lip,prstatus32_t * psp)2537c478bd9Sstevel@tonic-gate mkprstatus32(struct ps_prochandle *P, const lwpstatus_t *lsp,
2547c478bd9Sstevel@tonic-gate     const lwpsinfo_t *lip, prstatus32_t *psp)
2557c478bd9Sstevel@tonic-gate {
2567c478bd9Sstevel@tonic-gate 	bzero(psp, sizeof (*psp));
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_STOPPED)
2597c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0001;
2607c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ISTOP)
2617c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0002;
2627c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_DSTOP)
2637c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0004;
2647c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASLEEP)
2657c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0008;
2667c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_FORK)
2677c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0010;
2687c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_RLC)
2697c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0020;
2707c478bd9Sstevel@tonic-gate 	/*
2717c478bd9Sstevel@tonic-gate 	 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
2727c478bd9Sstevel@tonic-gate 	 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
2737c478bd9Sstevel@tonic-gate 	 */
2747c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_PCINVAL)
2757c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0080;
2767c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ISSYS)
2777c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0100;
2787c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_STEP)
2797c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0200;
2807c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_KLC)
2817c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0400;
2827c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASYNC)
2837c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0800;
2847c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_PTRACE)
2857c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x1000;
2867c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_MSACCT)
2877c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x2000;
2887c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_BPTADJ)
2897c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x4000;
2907c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASLWP)
2917c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x8000;
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 	psp->pr_why = lsp->pr_why;
2947c478bd9Sstevel@tonic-gate 	psp->pr_what = lsp->pr_what;
2957c478bd9Sstevel@tonic-gate 	siginfo_n_to_32(&lsp->pr_info, &psp->pr_info);
2967c478bd9Sstevel@tonic-gate 	psp->pr_cursig = lsp->pr_cursig;
2977c478bd9Sstevel@tonic-gate 	psp->pr_nlwp = P->status.pr_nlwp;
2987c478bd9Sstevel@tonic-gate 	psp->pr_sigpend = P->status.pr_sigpend;
2997c478bd9Sstevel@tonic-gate 	psp->pr_sighold = lsp->pr_lwphold;
3007c478bd9Sstevel@tonic-gate 	stack_n_to_32(&lsp->pr_altstack, &psp->pr_altstack);
3017c478bd9Sstevel@tonic-gate 	sigaction_n_to_32(&lsp->pr_action, &psp->pr_action);
3027c478bd9Sstevel@tonic-gate 	psp->pr_pid = P->status.pr_pid;
3037c478bd9Sstevel@tonic-gate 	psp->pr_ppid = P->status.pr_ppid;
3047c478bd9Sstevel@tonic-gate 	psp->pr_pgrp = P->status.pr_pgid;
3057c478bd9Sstevel@tonic-gate 	psp->pr_sid = P->status.pr_sid;
3067c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->status.pr_utime, &psp->pr_utime);
3077c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->status.pr_stime, &psp->pr_stime);
3087c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->status.pr_cutime, &psp->pr_cutime);
3097c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->status.pr_cstime, &psp->pr_cstime);
3107c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
3117c478bd9Sstevel@tonic-gate 	psp->pr_syscall = lsp->pr_syscall;
3127c478bd9Sstevel@tonic-gate 	psp->pr_nsysarg = lsp->pr_nsysarg;
3132c797a4eSRoger A. Faulkner 	bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg));
3142c797a4eSRoger A. Faulkner 	psp->pr_who = lsp->pr_lwpid;
3157c478bd9Sstevel@tonic-gate 	psp->pr_lwppend = lsp->pr_lwppend;
3167c478bd9Sstevel@tonic-gate 	psp->pr_oldcontext = (caddr32_t)lsp->pr_oldcontext;
3177c478bd9Sstevel@tonic-gate 	psp->pr_brkbase = (caddr32_t)P->status.pr_brkbase;
3187c478bd9Sstevel@tonic-gate 	psp->pr_brksize = P->status.pr_brksize;
3197c478bd9Sstevel@tonic-gate 	psp->pr_stkbase = (caddr32_t)P->status.pr_stkbase;
3207c478bd9Sstevel@tonic-gate 	psp->pr_stksize = P->status.pr_stksize;
3217c478bd9Sstevel@tonic-gate 	psp->pr_processor = (short)lip->pr_onpro;
3227c478bd9Sstevel@tonic-gate 	psp->pr_bind = (short)lip->pr_bindpro;
3237c478bd9Sstevel@tonic-gate 	psp->pr_instr = lsp->pr_instr;
3247c478bd9Sstevel@tonic-gate 	bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate static void
mkprpsinfo32(struct ps_prochandle * P,prpsinfo32_t * psp)3287c478bd9Sstevel@tonic-gate mkprpsinfo32(struct ps_prochandle *P, prpsinfo32_t *psp)
3297c478bd9Sstevel@tonic-gate {
3307c478bd9Sstevel@tonic-gate 	bzero(psp, sizeof (*psp));
3317c478bd9Sstevel@tonic-gate 	psp->pr_state = P->psinfo.pr_lwp.pr_state;
3327c478bd9Sstevel@tonic-gate 	psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
3337c478bd9Sstevel@tonic-gate 	psp->pr_zomb = (psp->pr_state == SZOMB);
3347c478bd9Sstevel@tonic-gate 	psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
3357c478bd9Sstevel@tonic-gate 	psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
3367c478bd9Sstevel@tonic-gate 	psp->pr_uid = P->psinfo.pr_uid;
3377c478bd9Sstevel@tonic-gate 	psp->pr_gid = P->psinfo.pr_gid;
3387c478bd9Sstevel@tonic-gate 	psp->pr_pid = P->psinfo.pr_pid;
3397c478bd9Sstevel@tonic-gate 	psp->pr_ppid = P->psinfo.pr_ppid;
3407c478bd9Sstevel@tonic-gate 	psp->pr_pgrp = P->psinfo.pr_pgid;
3417c478bd9Sstevel@tonic-gate 	psp->pr_sid = P->psinfo.pr_sid;
3427c478bd9Sstevel@tonic-gate 	psp->pr_addr = (caddr32_t)P->psinfo.pr_addr;
3437c478bd9Sstevel@tonic-gate 	psp->pr_size = P->psinfo.pr_size;
3447c478bd9Sstevel@tonic-gate 	psp->pr_rssize = P->psinfo.pr_rssize;
3457c478bd9Sstevel@tonic-gate 	psp->pr_wchan = (caddr32_t)P->psinfo.pr_lwp.pr_wchan;
3467c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->psinfo.pr_start, &psp->pr_start);
3477c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->psinfo.pr_time, &psp->pr_time);
3487c478bd9Sstevel@tonic-gate 	psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
3497c478bd9Sstevel@tonic-gate 	psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
3507c478bd9Sstevel@tonic-gate 	psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
3517c478bd9Sstevel@tonic-gate 	psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
3527c478bd9Sstevel@tonic-gate 	psp->pr_lttydev = prcmpldev(P->psinfo.pr_ttydev);
3537c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
3547c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_clname));
3557c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
3567c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_fname));
3577c478bd9Sstevel@tonic-gate 	bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
3587c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_psargs));
3597c478bd9Sstevel@tonic-gate 	psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
3607c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->psinfo.pr_ctime, &psp->pr_ctime);
3617c478bd9Sstevel@tonic-gate 	psp->pr_bysize = psp->pr_size * PAGESIZE;
3627c478bd9Sstevel@tonic-gate 	psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
3637c478bd9Sstevel@tonic-gate 	psp->pr_argc = P->psinfo.pr_argc;
3647c478bd9Sstevel@tonic-gate 	psp->pr_argv = (caddr32_t)P->psinfo.pr_argv;
3657c478bd9Sstevel@tonic-gate 	psp->pr_envp = (caddr32_t)P->psinfo.pr_envp;
3667c478bd9Sstevel@tonic-gate 	psp->pr_wstat = P->psinfo.pr_wstat;
3677c478bd9Sstevel@tonic-gate 	psp->pr_pctcpu = P->psinfo.pr_pctcpu;
3687c478bd9Sstevel@tonic-gate 	psp->pr_pctmem = P->psinfo.pr_pctmem;
3697c478bd9Sstevel@tonic-gate 	psp->pr_euid = P->psinfo.pr_euid;
3707c478bd9Sstevel@tonic-gate 	psp->pr_egid = P->psinfo.pr_egid;
3717c478bd9Sstevel@tonic-gate 	psp->pr_aslwpid = 0;
3727c478bd9Sstevel@tonic-gate 	psp->pr_dmodel = P->psinfo.pr_dmodel;
3737c478bd9Sstevel@tonic-gate }
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate static int
write_note(int fd,uint_t type,const void * desc,size_t descsz,off64_t * offp)3787c478bd9Sstevel@tonic-gate write_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp)
3797c478bd9Sstevel@tonic-gate {
3807c478bd9Sstevel@tonic-gate 	/*
3817c478bd9Sstevel@tonic-gate 	 * Note headers are the same regardless of the data model of the
3827c478bd9Sstevel@tonic-gate 	 * ELF file; we arbitrarily use Elf64_Nhdr here.
3837c478bd9Sstevel@tonic-gate 	 */
3847c478bd9Sstevel@tonic-gate 	struct {
3857c478bd9Sstevel@tonic-gate 		Elf64_Nhdr nhdr;
3867c478bd9Sstevel@tonic-gate 		char name[8];
3877c478bd9Sstevel@tonic-gate 	} n;
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 	bzero(&n, sizeof (n));
3907c478bd9Sstevel@tonic-gate 	bcopy("CORE", n.name, 4);
3917c478bd9Sstevel@tonic-gate 	n.nhdr.n_type = type;
3927c478bd9Sstevel@tonic-gate 	n.nhdr.n_namesz = 5;
3937c478bd9Sstevel@tonic-gate 	n.nhdr.n_descsz = roundup(descsz, 4);
3947c478bd9Sstevel@tonic-gate 
39564e4e50aSKeith M Wesolowski 	if (gc_pwrite64(fd, &n, sizeof (n), *offp) != 0)
3967c478bd9Sstevel@tonic-gate 		return (-1);
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate 	*offp += sizeof (n);
3997c478bd9Sstevel@tonic-gate 
40064e4e50aSKeith M Wesolowski 	if (gc_pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != 0)
4017c478bd9Sstevel@tonic-gate 		return (-1);
4027c478bd9Sstevel@tonic-gate 
4037c478bd9Sstevel@tonic-gate 	*offp += n.nhdr.n_descsz;
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 	return (0);
4067c478bd9Sstevel@tonic-gate }
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate static int
old_per_lwp(void * data,const lwpstatus_t * lsp,const lwpsinfo_t * lip)4097c478bd9Sstevel@tonic-gate old_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
4107c478bd9Sstevel@tonic-gate {
4117c478bd9Sstevel@tonic-gate 	pgcore_t *pgc = data;
4127c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P = pgc->P;
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate 	/*
4157c478bd9Sstevel@tonic-gate 	 * Legacy core files don't contain information about zombie LWPs.
4167c478bd9Sstevel@tonic-gate 	 * We use Plwp_iter_all() so that we get the lwpsinfo_t structure
4177c478bd9Sstevel@tonic-gate 	 * more cheaply.
4187c478bd9Sstevel@tonic-gate 	 */
4197c478bd9Sstevel@tonic-gate 	if (lsp == NULL)
4207c478bd9Sstevel@tonic-gate 		return (0);
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
4237c478bd9Sstevel@tonic-gate 		prstatus_t prstatus;
4247c478bd9Sstevel@tonic-gate 		mkprstatus(P, lsp, lip, &prstatus);
4257c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_PRSTATUS, &prstatus,
4267c478bd9Sstevel@tonic-gate 		    sizeof (prstatus_t), pgc->pgc_doff) != 0)
4277c478bd9Sstevel@tonic-gate 			return (0);
4287c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_PRFPREG, &lsp->pr_fpreg,
4297c478bd9Sstevel@tonic-gate 		    sizeof (prfpregset_t), pgc->pgc_doff) != 0)
4307c478bd9Sstevel@tonic-gate 			return (1);
4317c478bd9Sstevel@tonic-gate #ifdef _LP64
4327c478bd9Sstevel@tonic-gate 	} else {
4337c478bd9Sstevel@tonic-gate 		prstatus32_t pr32;
4347c478bd9Sstevel@tonic-gate 		prfpregset32_t pf32;
4357c478bd9Sstevel@tonic-gate 		mkprstatus32(P, lsp, lip, &pr32);
4367c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_PRSTATUS, &pr32,
4377c478bd9Sstevel@tonic-gate 		    sizeof (prstatus32_t), pgc->pgc_doff) != 0)
4387c478bd9Sstevel@tonic-gate 			return (1);
4397c478bd9Sstevel@tonic-gate 		prfpregset_n_to_32(&lsp->pr_fpreg, &pf32);
4407c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_PRFPREG, &pf32,
4417c478bd9Sstevel@tonic-gate 		    sizeof (prfpregset32_t), pgc->pgc_doff) != 0)
4427c478bd9Sstevel@tonic-gate 			return (1);
4437c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
4447c478bd9Sstevel@tonic-gate 	}
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate 	return (0);
4477c478bd9Sstevel@tonic-gate }
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate static int
new_per_lwp(void * data,const lwpstatus_t * lsp,const lwpsinfo_t * lip)4507c478bd9Sstevel@tonic-gate new_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
4517c478bd9Sstevel@tonic-gate {
4527c478bd9Sstevel@tonic-gate 	pgcore_t *pgc = data;
4537c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P = pgc->P;
454ab618543SJohn Levon 	prlwpname_t name = { 0, "" };
455f971a346SBryan Cantrill 	psinfo_t ps;
456*ed093b41SRobert Mustacchi 	prxregset_t *xregs;
457*ed093b41SRobert Mustacchi 	size_t size;
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate 	/*
4607c478bd9Sstevel@tonic-gate 	 * If lsp is NULL this indicates that this is a zombie LWP in
4617c478bd9Sstevel@tonic-gate 	 * which case we dump only the lwpsinfo_t structure and none of
4627c478bd9Sstevel@tonic-gate 	 * the other ancillary LWP state data.
4637c478bd9Sstevel@tonic-gate 	 */
4647c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
4657c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip,
4667c478bd9Sstevel@tonic-gate 		    sizeof (lwpsinfo_t), pgc->pgc_doff) != 0)
4677c478bd9Sstevel@tonic-gate 			return (1);
4687c478bd9Sstevel@tonic-gate 		if (lsp == NULL)
4697c478bd9Sstevel@tonic-gate 			return (0);
4707c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp,
4717c478bd9Sstevel@tonic-gate 		    sizeof (lwpstatus_t), pgc->pgc_doff) != 0)
4727c478bd9Sstevel@tonic-gate 			return (1);
4737c478bd9Sstevel@tonic-gate #ifdef _LP64
4747c478bd9Sstevel@tonic-gate 	} else {
4757c478bd9Sstevel@tonic-gate 		lwpsinfo32_t li32;
4767c478bd9Sstevel@tonic-gate 		lwpstatus32_t ls32;
4777c478bd9Sstevel@tonic-gate 		lwpsinfo_n_to_32(lip, &li32);
4787c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32,
4797c478bd9Sstevel@tonic-gate 		    sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0)
4807c478bd9Sstevel@tonic-gate 			return (1);
4817c478bd9Sstevel@tonic-gate 		if (lsp == NULL)
4827c478bd9Sstevel@tonic-gate 			return (0);
4837c478bd9Sstevel@tonic-gate 		lwpstatus_n_to_32(lsp, &ls32);
4847c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32,
4857c478bd9Sstevel@tonic-gate 		    sizeof (lwpstatus32_t), pgc->pgc_doff) != 0)
4867c478bd9Sstevel@tonic-gate 			return (1);
4877c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
4887c478bd9Sstevel@tonic-gate 	}
4897c478bd9Sstevel@tonic-gate 
490*ed093b41SRobert Mustacchi 	if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs, &size) == 0) {
491*ed093b41SRobert Mustacchi 		if (write_note(pgc->pgc_fd, NT_PRXREG, xregs, size,
4927c478bd9Sstevel@tonic-gate 		    pgc->pgc_doff) != 0)
4937c478bd9Sstevel@tonic-gate 			return (1);
4947c478bd9Sstevel@tonic-gate 
495*ed093b41SRobert Mustacchi 		Plwp_freexregs(P, xregs, size);
4967c478bd9Sstevel@tonic-gate 	}
4977c478bd9Sstevel@tonic-gate 
498ab618543SJohn Levon 	if (Plwp_getname(P, lsp->pr_lwpid, name.pr_lwpname,
499ab618543SJohn Levon 	    sizeof (name.pr_lwpname)) == 0) {
500ab618543SJohn Levon 		name.pr_lwpid = lsp->pr_lwpid;
501ab618543SJohn Levon 		if (write_note(pgc->pgc_fd, NT_LWPNAME, &name,
502ab618543SJohn Levon 		    sizeof (name), pgc->pgc_doff) != 0)
503ab618543SJohn Levon 			return (1);
504ab618543SJohn Levon 	}
505ab618543SJohn Levon 
506f971a346SBryan Cantrill 	if (!(lsp->pr_flags & PR_AGENT))
507f971a346SBryan Cantrill 		return (0);
508f971a346SBryan Cantrill 
509f971a346SBryan Cantrill 	if (Plwp_getspymaster(P, lsp->pr_lwpid, &ps) != 0)
510f971a346SBryan Cantrill 		return (0);
511f971a346SBryan Cantrill 
512f971a346SBryan Cantrill 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
513f971a346SBryan Cantrill 		if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps,
514f971a346SBryan Cantrill 		    sizeof (psinfo_t), pgc->pgc_doff) != 0)
515f971a346SBryan Cantrill 			return (1);
516f971a346SBryan Cantrill #ifdef _LP64
517f971a346SBryan Cantrill 	} else {
518f971a346SBryan Cantrill 		psinfo32_t ps32;
519f971a346SBryan Cantrill 		psinfo_n_to_32(&ps, &ps32);
520f971a346SBryan Cantrill 		if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps32,
521f971a346SBryan Cantrill 		    sizeof (psinfo32_t), pgc->pgc_doff) != 0)
522f971a346SBryan Cantrill 			return (1);
523f971a346SBryan Cantrill #endif	/* _LP64 */
524f971a346SBryan Cantrill 	}
525f971a346SBryan Cantrill 
526f971a346SBryan Cantrill 
5277c478bd9Sstevel@tonic-gate 	return (0);
5287c478bd9Sstevel@tonic-gate }
5297c478bd9Sstevel@tonic-gate 
53034bdffbfSGarrett D'Amore static int
iter_fd(void * data,const prfdinfo_t * fdinfo)531a02120c4SAndy Fiddaman iter_fd(void *data, const prfdinfo_t *fdinfo)
53234bdffbfSGarrett D'Amore {
53334bdffbfSGarrett D'Amore 	fditer_t *iter = data;
534a02120c4SAndy Fiddaman 	prfdinfo_core_t core;
535a02120c4SAndy Fiddaman 	int ret = 0;
53634bdffbfSGarrett D'Amore 
537a02120c4SAndy Fiddaman 	if (proc_fdinfo_to_core(fdinfo, &core) != 0)
538a02120c4SAndy Fiddaman 		return (1);
539a02120c4SAndy Fiddaman 
540a02120c4SAndy Fiddaman 	ret = write_note(iter->fd_fd, NT_FDINFO, &core,
541a02120c4SAndy Fiddaman 	    sizeof (core), iter->fd_doff);
542a02120c4SAndy Fiddaman 
543a02120c4SAndy Fiddaman 	if (ret != 0)
54434bdffbfSGarrett D'Amore 		return (1);
54534bdffbfSGarrett D'Amore 	return (0);
54634bdffbfSGarrett D'Amore }
54734bdffbfSGarrett D'Amore 
5488e458de0SRobert Mustacchi /*
5498e458de0SRobert Mustacchi  * Look for sections that begin with the string '.debug_'. In particular, this
5508e458de0SRobert Mustacchi  * will catch all DWARF related sections and it will catch those that different
5518e458de0SRobert Mustacchi  * folks use that are not related to DWARF, but still begin with this prefix
5528e458de0SRobert Mustacchi  * (e.g. .debug_gdb_scripts). Notably though, this does not catch something like
5538e458de0SRobert Mustacchi  * stabs (though it could). This really is filtering based on the section name,
5548e458de0SRobert Mustacchi  * less so intent.
5558e458de0SRobert Mustacchi  */
5568e458de0SRobert Mustacchi static boolean_t
is_debug_section(file_info_t * fptr,GElf_Shdr * shdr)5578e458de0SRobert Mustacchi is_debug_section(file_info_t *fptr, GElf_Shdr *shdr)
5588e458de0SRobert Mustacchi {
5598e458de0SRobert Mustacchi 	if (shdr->sh_name == 0 || shdr->sh_name > fptr->file_shstrsz)
5608e458de0SRobert Mustacchi 		return (B_FALSE);
5618e458de0SRobert Mustacchi 
5628e458de0SRobert Mustacchi 	if (strncmp(fptr->file_shstrs + shdr->sh_name, ".debug_",
5638e458de0SRobert Mustacchi 	    strlen(".debug_")) != 0) {
5648e458de0SRobert Mustacchi 		return (B_FALSE);
5658e458de0SRobert Mustacchi 	}
5668e458de0SRobert Mustacchi 
5678e458de0SRobert Mustacchi 	return (B_TRUE);
5688e458de0SRobert Mustacchi }
5698e458de0SRobert Mustacchi 
5708e458de0SRobert Mustacchi static uint_t
count_debug(file_info_t * fptr)5718e458de0SRobert Mustacchi count_debug(file_info_t *fptr)
5728e458de0SRobert Mustacchi {
5738e458de0SRobert Mustacchi 	uint_t count = 0;
5748e458de0SRobert Mustacchi 	Elf_Scn *scn = NULL;
5758e458de0SRobert Mustacchi 
5768e458de0SRobert Mustacchi 	if (fptr->file_elf == NULL || fptr->file_shstrsz <= 1) {
5778e458de0SRobert Mustacchi 		return (0);
5788e458de0SRobert Mustacchi 	}
5798e458de0SRobert Mustacchi 
5808e458de0SRobert Mustacchi 	while ((scn = elf_nextscn(fptr->file_elf, scn)) != NULL) {
5818e458de0SRobert Mustacchi 		GElf_Shdr shdr;
5828e458de0SRobert Mustacchi 
5838e458de0SRobert Mustacchi 		if (gelf_getshdr(scn, &shdr) == NULL)
5848e458de0SRobert Mustacchi 			continue;
5858e458de0SRobert Mustacchi 
5868e458de0SRobert Mustacchi 		if (is_debug_section(fptr, &shdr))
5878e458de0SRobert Mustacchi 			count++;
5888e458de0SRobert Mustacchi 	}
5898e458de0SRobert Mustacchi 
5908e458de0SRobert Mustacchi 	return (count);
5918e458de0SRobert Mustacchi }
5928e458de0SRobert Mustacchi 
5937c478bd9Sstevel@tonic-gate static uint_t
count_sections(pgcore_t * pgc)5947c478bd9Sstevel@tonic-gate count_sections(pgcore_t *pgc)
5957c478bd9Sstevel@tonic-gate {
5967c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P = pgc->P;
5977c478bd9Sstevel@tonic-gate 	file_info_t *fptr;
5987c478bd9Sstevel@tonic-gate 	uint_t nshdrs = 0;
5997c478bd9Sstevel@tonic-gate 
6008e458de0SRobert Mustacchi 	if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB |
6018e458de0SRobert Mustacchi 	    CC_CONTENT_DEBUG))) {
6027c478bd9Sstevel@tonic-gate 		return (0);
6038e458de0SRobert Mustacchi 	}
6047c478bd9Sstevel@tonic-gate 
60550d4d24eSRobert Mustacchi 	for (fptr = list_head(&P->file_head); fptr != NULL;
60650d4d24eSRobert Mustacchi 	    fptr = list_next(&P->file_head, fptr)) {
6077c478bd9Sstevel@tonic-gate 		int hit_symtab = 0;
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate 		Pbuild_file_symtab(P, fptr);
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 		if ((pgc->pgc_content & CC_CONTENT_CTF) &&
6127c478bd9Sstevel@tonic-gate 		    Pbuild_file_ctf(P, fptr) != NULL) {
6137c478bd9Sstevel@tonic-gate 			sym_tbl_t *sym;
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate 			nshdrs++;
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate 			if (fptr->file_ctf_dyn) {
6187c478bd9Sstevel@tonic-gate 				sym = &fptr->file_dynsym;
6197c478bd9Sstevel@tonic-gate 			} else {
6207c478bd9Sstevel@tonic-gate 				sym = &fptr->file_symtab;
6217c478bd9Sstevel@tonic-gate 				hit_symtab = 1;
6227c478bd9Sstevel@tonic-gate 			}
6237c478bd9Sstevel@tonic-gate 
624d51e9074Sab196087 			if (sym->sym_data_pri != NULL && sym->sym_symn != 0 &&
6257c478bd9Sstevel@tonic-gate 			    sym->sym_strs != NULL)
6267c478bd9Sstevel@tonic-gate 				nshdrs += 2;
6277c478bd9Sstevel@tonic-gate 		}
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate 		if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
630d51e9074Sab196087 		    fptr->file_symtab.sym_data_pri != NULL &&
6317c478bd9Sstevel@tonic-gate 		    fptr->file_symtab.sym_symn != 0 &&
6327c478bd9Sstevel@tonic-gate 		    fptr->file_symtab.sym_strs != NULL) {
6337c478bd9Sstevel@tonic-gate 			nshdrs += 2;
6347c478bd9Sstevel@tonic-gate 		}
6358e458de0SRobert Mustacchi 
6368e458de0SRobert Mustacchi 		if ((pgc->pgc_content & CC_CONTENT_DEBUG) != 0)
6378e458de0SRobert Mustacchi 			nshdrs += count_debug(fptr);
6387c478bd9Sstevel@tonic-gate 	}
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate 	return (nshdrs == 0 ? 0 : nshdrs + 2);
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate static int
write_shdr(pgcore_t * pgc,const char * name,uint_t type,ulong_t flags,uintptr_t addr,ulong_t offset,size_t size,uint_t link,uint_t info,uintptr_t addralign,uintptr_t entsize)6448e458de0SRobert Mustacchi write_shdr(pgcore_t *pgc, const char *name, uint_t type, ulong_t flags,
6457c478bd9Sstevel@tonic-gate     uintptr_t addr, ulong_t offset, size_t size, uint_t link, uint_t info,
6467c478bd9Sstevel@tonic-gate     uintptr_t addralign, uintptr_t entsize)
6477c478bd9Sstevel@tonic-gate {
6487c478bd9Sstevel@tonic-gate 	if (pgc->P->status.pr_dmodel == PR_MODEL_ILP32) {
6497c478bd9Sstevel@tonic-gate 		Elf32_Shdr shdr;
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate 		bzero(&shdr, sizeof (shdr));
6528e458de0SRobert Mustacchi 		if (!shstrtab_ndx(&pgc->pgc_shstrtab, name, &shdr.sh_name)) {
6538e458de0SRobert Mustacchi 			return (-1);
6548e458de0SRobert Mustacchi 		}
6557c478bd9Sstevel@tonic-gate 		shdr.sh_type = type;
6567c478bd9Sstevel@tonic-gate 		shdr.sh_flags = flags;
6577c478bd9Sstevel@tonic-gate 		shdr.sh_addr = (Elf32_Addr)addr;
6587c478bd9Sstevel@tonic-gate 		shdr.sh_offset = offset;
6597c478bd9Sstevel@tonic-gate 		shdr.sh_size = size;
6607c478bd9Sstevel@tonic-gate 		shdr.sh_link = link;
6617c478bd9Sstevel@tonic-gate 		shdr.sh_info = info;
6627c478bd9Sstevel@tonic-gate 		shdr.sh_addralign = addralign;
6637c478bd9Sstevel@tonic-gate 		shdr.sh_entsize = entsize;
6647c478bd9Sstevel@tonic-gate 
66564e4e50aSKeith M Wesolowski 		if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
66664e4e50aSKeith M Wesolowski 		    *pgc->pgc_soff) != 0)
6677c478bd9Sstevel@tonic-gate 			return (-1);
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate 		*pgc->pgc_soff += sizeof (shdr);
6707c478bd9Sstevel@tonic-gate #ifdef _LP64
6717c478bd9Sstevel@tonic-gate 	} else {
6727c478bd9Sstevel@tonic-gate 		Elf64_Shdr shdr;
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate 		bzero(&shdr, sizeof (shdr));
6758e458de0SRobert Mustacchi 		if (!shstrtab_ndx(&pgc->pgc_shstrtab, name, &shdr.sh_name)) {
6768e458de0SRobert Mustacchi 			return (-1);
6778e458de0SRobert Mustacchi 		}
6787c478bd9Sstevel@tonic-gate 		shdr.sh_type = type;
6797c478bd9Sstevel@tonic-gate 		shdr.sh_flags = flags;
6807c478bd9Sstevel@tonic-gate 		shdr.sh_addr = addr;
6817c478bd9Sstevel@tonic-gate 		shdr.sh_offset = offset;
6827c478bd9Sstevel@tonic-gate 		shdr.sh_size = size;
6837c478bd9Sstevel@tonic-gate 		shdr.sh_link = link;
6847c478bd9Sstevel@tonic-gate 		shdr.sh_info = info;
6857c478bd9Sstevel@tonic-gate 		shdr.sh_addralign = addralign;
6867c478bd9Sstevel@tonic-gate 		shdr.sh_entsize = entsize;
6877c478bd9Sstevel@tonic-gate 
68864e4e50aSKeith M Wesolowski 		if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
68964e4e50aSKeith M Wesolowski 		    *pgc->pgc_soff) != 0)
6907c478bd9Sstevel@tonic-gate 			return (-1);
6917c478bd9Sstevel@tonic-gate 
6927c478bd9Sstevel@tonic-gate 		*pgc->pgc_soff += sizeof (shdr);
6937c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
6947c478bd9Sstevel@tonic-gate 	}
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate 	return (0);
6977c478bd9Sstevel@tonic-gate }
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate static int
dump_symtab(pgcore_t * pgc,file_info_t * fptr,uint_t index,int dynsym)7007c478bd9Sstevel@tonic-gate dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym)
7017c478bd9Sstevel@tonic-gate {
7027c478bd9Sstevel@tonic-gate 	sym_tbl_t *sym = dynsym ? &fptr->file_dynsym : &fptr->file_symtab;
7037c478bd9Sstevel@tonic-gate 	shstrtype_t symname = dynsym ? STR_DYNSYM : STR_SYMTAB;
7047c478bd9Sstevel@tonic-gate 	shstrtype_t strname = dynsym ? STR_DYNSTR : STR_STRTAB;
7057c478bd9Sstevel@tonic-gate 	uint_t symtype = dynsym ? SHT_DYNSYM : SHT_SYMTAB;
7067c478bd9Sstevel@tonic-gate 	size_t size;
7077c478bd9Sstevel@tonic-gate 	uintptr_t addr = fptr->file_map->map_pmap.pr_vaddr;
7087c478bd9Sstevel@tonic-gate 
709d51e9074Sab196087 	if (sym->sym_data_pri == NULL || sym->sym_symn == 0 ||
7107c478bd9Sstevel@tonic-gate 	    sym->sym_strs == NULL)
7117c478bd9Sstevel@tonic-gate 		return (0);
7127c478bd9Sstevel@tonic-gate 
713d51e9074Sab196087 	size = sym->sym_hdr_pri.sh_size;
71464e4e50aSKeith M Wesolowski 	if (gc_pwrite64(pgc->pgc_fd, sym->sym_data_pri->d_buf, size,
71564e4e50aSKeith M Wesolowski 	    *pgc->pgc_doff) != 0)
7167c478bd9Sstevel@tonic-gate 		return (-1);
7177c478bd9Sstevel@tonic-gate 
7188e458de0SRobert Mustacchi 	if (write_shdr(pgc, shstrtab_data[symname], symtype, 0, addr,
7198e458de0SRobert Mustacchi 	    *pgc->pgc_doff, size, index + 1, sym->sym_hdr_pri.sh_info,
7208e458de0SRobert Mustacchi 	    sym->sym_hdr_pri.sh_addralign, sym->sym_hdr_pri.sh_entsize) != 0)
7217c478bd9Sstevel@tonic-gate 		return (-1);
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate 	*pgc->pgc_doff += roundup(size, 8);
7247c478bd9Sstevel@tonic-gate 
7257c478bd9Sstevel@tonic-gate 	size = sym->sym_strhdr.sh_size;
72664e4e50aSKeith M Wesolowski 	if (gc_pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != 0)
7277c478bd9Sstevel@tonic-gate 		return (-1);
7287c478bd9Sstevel@tonic-gate 
7298e458de0SRobert Mustacchi 	if (write_shdr(pgc, shstrtab_data[strname], SHT_STRTAB, SHF_STRINGS,
7308e458de0SRobert Mustacchi 	    addr, *pgc->pgc_doff, size, 0, 0, 1, 0) != 0)
7317c478bd9Sstevel@tonic-gate 		return (-1);
7327c478bd9Sstevel@tonic-gate 
7337c478bd9Sstevel@tonic-gate 	*pgc->pgc_doff += roundup(size, 8);
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate 	return (0);
7367c478bd9Sstevel@tonic-gate }
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate static int
dump_debug(pgcore_t * pgc,file_info_t * fptr,uint_t * indexp)7398e458de0SRobert Mustacchi dump_debug(pgcore_t *pgc, file_info_t *fptr, uint_t *indexp)
7408e458de0SRobert Mustacchi {
7418e458de0SRobert Mustacchi 	Elf_Scn *scn = NULL;
7428e458de0SRobert Mustacchi 
7438e458de0SRobert Mustacchi 	if (fptr->file_elf == NULL || fptr->file_shstrsz <= 1) {
7448e458de0SRobert Mustacchi 		return (0);
7458e458de0SRobert Mustacchi 	}
7468e458de0SRobert Mustacchi 
7478e458de0SRobert Mustacchi 	while ((scn = elf_nextscn(fptr->file_elf, scn)) != NULL) {
7488e458de0SRobert Mustacchi 		GElf_Shdr shdr;
7498e458de0SRobert Mustacchi 		Elf_Data *data;
7508e458de0SRobert Mustacchi 
7518e458de0SRobert Mustacchi 		if (gelf_getshdr(scn, &shdr) == NULL)
7528e458de0SRobert Mustacchi 			continue;
7538e458de0SRobert Mustacchi 
7548e458de0SRobert Mustacchi 		if (!is_debug_section(fptr, &shdr))
7558e458de0SRobert Mustacchi 			continue;
7568e458de0SRobert Mustacchi 
7578e458de0SRobert Mustacchi 		if ((data = elf_getdata(scn, NULL)) == NULL) {
7588e458de0SRobert Mustacchi 			return (-1);
7598e458de0SRobert Mustacchi 		}
7608e458de0SRobert Mustacchi 
7618e458de0SRobert Mustacchi 		if (gc_pwrite64(pgc->pgc_fd, data->d_buf, data->d_size,
7628e458de0SRobert Mustacchi 		    *pgc->pgc_doff) != 0)
7638e458de0SRobert Mustacchi 			return (-1);
7648e458de0SRobert Mustacchi 
7658e458de0SRobert Mustacchi 		if (write_shdr(pgc, fptr->file_shstrs + shdr.sh_name,
7668e458de0SRobert Mustacchi 		    shdr.sh_type, shdr.sh_flags,
7678e458de0SRobert Mustacchi 		    fptr->file_map->map_pmap.pr_vaddr, *pgc->pgc_doff,
7688e458de0SRobert Mustacchi 		    data->d_size, 0, shdr.sh_info, shdr.sh_addralign,
7698e458de0SRobert Mustacchi 		    shdr.sh_entsize) != 0) {
7708e458de0SRobert Mustacchi 			return (-1);
7718e458de0SRobert Mustacchi 		}
7728e458de0SRobert Mustacchi 
7738e458de0SRobert Mustacchi 		*indexp = *indexp + 1;
7748e458de0SRobert Mustacchi 		*pgc->pgc_doff += roundup(data->d_size, 8);
7758e458de0SRobert Mustacchi 	}
7768e458de0SRobert Mustacchi 
7778e458de0SRobert Mustacchi 	return (0);
7788e458de0SRobert Mustacchi }
7798e458de0SRobert Mustacchi 
7808e458de0SRobert Mustacchi static int
dump_sections(pgcore_t * pgc)7817c478bd9Sstevel@tonic-gate dump_sections(pgcore_t *pgc)
7827c478bd9Sstevel@tonic-gate {
7837c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P = pgc->P;
7847c478bd9Sstevel@tonic-gate 	file_info_t *fptr;
7857c478bd9Sstevel@tonic-gate 	uint_t index = 1;
7867c478bd9Sstevel@tonic-gate 
7878e458de0SRobert Mustacchi 	if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB |
7888e458de0SRobert Mustacchi 	    CC_CONTENT_DEBUG))) {
7897c478bd9Sstevel@tonic-gate 		return (0);
7908e458de0SRobert Mustacchi 	}
7917c478bd9Sstevel@tonic-gate 
79250d4d24eSRobert Mustacchi 	for (fptr = list_head(&P->file_head); fptr != NULL;
79350d4d24eSRobert Mustacchi 	    fptr = list_next(&P->file_head, fptr)) {
7947c478bd9Sstevel@tonic-gate 		int hit_symtab = 0;
7957c478bd9Sstevel@tonic-gate 
7967c478bd9Sstevel@tonic-gate 		Pbuild_file_symtab(P, fptr);
7977c478bd9Sstevel@tonic-gate 
7987c478bd9Sstevel@tonic-gate 		if ((pgc->pgc_content & CC_CONTENT_CTF) &&
7997c478bd9Sstevel@tonic-gate 		    Pbuild_file_ctf(P, fptr) != NULL) {
8007c478bd9Sstevel@tonic-gate 			sym_tbl_t *sym;
8017c478bd9Sstevel@tonic-gate 			uint_t dynsym;
8027c478bd9Sstevel@tonic-gate 			uint_t symindex = 0;
8037c478bd9Sstevel@tonic-gate 
8047c478bd9Sstevel@tonic-gate 			/*
8057c478bd9Sstevel@tonic-gate 			 * Write the symtab out first so we can correctly
8067c478bd9Sstevel@tonic-gate 			 * set the sh_link field in the CTF section header.
8077c478bd9Sstevel@tonic-gate 			 * symindex will be 0 if there is no corresponding
8087c478bd9Sstevel@tonic-gate 			 * symbol table section.
8097c478bd9Sstevel@tonic-gate 			 */
8107c478bd9Sstevel@tonic-gate 			if (fptr->file_ctf_dyn) {
8117c478bd9Sstevel@tonic-gate 				sym = &fptr->file_dynsym;
8127c478bd9Sstevel@tonic-gate 				dynsym = 1;
8137c478bd9Sstevel@tonic-gate 			} else {
8147c478bd9Sstevel@tonic-gate 				sym = &fptr->file_symtab;
8157c478bd9Sstevel@tonic-gate 				dynsym = 0;
8167c478bd9Sstevel@tonic-gate 				hit_symtab = 1;
8177c478bd9Sstevel@tonic-gate 			}
8187c478bd9Sstevel@tonic-gate 
819d51e9074Sab196087 			if (sym->sym_data_pri != NULL && sym->sym_symn != 0 &&
8207c478bd9Sstevel@tonic-gate 			    sym->sym_strs != NULL) {
8217c478bd9Sstevel@tonic-gate 				symindex = index;
8227c478bd9Sstevel@tonic-gate 				if (dump_symtab(pgc, fptr, index, dynsym) != 0)
8237c478bd9Sstevel@tonic-gate 					return (-1);
8247c478bd9Sstevel@tonic-gate 				index += 2;
8257c478bd9Sstevel@tonic-gate 			}
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate 			/*
8287c478bd9Sstevel@tonic-gate 			 * Write the CTF data that we've read out of the
8297c478bd9Sstevel@tonic-gate 			 * file itself into the core file.
8307c478bd9Sstevel@tonic-gate 			 */
83164e4e50aSKeith M Wesolowski 			if (gc_pwrite64(pgc->pgc_fd, fptr->file_ctf_buf,
83264e4e50aSKeith M Wesolowski 			    fptr->file_ctf_size, *pgc->pgc_doff) != 0)
8337c478bd9Sstevel@tonic-gate 				return (-1);
8347c478bd9Sstevel@tonic-gate 
8358e458de0SRobert Mustacchi 			if (write_shdr(pgc, shstrtab_data[STR_CTF],
8368e458de0SRobert Mustacchi 			    SHT_PROGBITS, 0, fptr->file_map->map_pmap.pr_vaddr,
8378e458de0SRobert Mustacchi 			    *pgc->pgc_doff, fptr->file_ctf_size, symindex, 0,
8388e458de0SRobert Mustacchi 			    4, 0) != 0)
8397c478bd9Sstevel@tonic-gate 				return (-1);
8407c478bd9Sstevel@tonic-gate 
8417c478bd9Sstevel@tonic-gate 			index++;
8427c478bd9Sstevel@tonic-gate 			*pgc->pgc_doff += roundup(fptr->file_ctf_size, 8);
8437c478bd9Sstevel@tonic-gate 		}
8447c478bd9Sstevel@tonic-gate 
8457c478bd9Sstevel@tonic-gate 		if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
846d51e9074Sab196087 		    fptr->file_symtab.sym_data_pri != NULL &&
8477c478bd9Sstevel@tonic-gate 		    fptr->file_symtab.sym_symn != 0 &&
8487c478bd9Sstevel@tonic-gate 		    fptr->file_symtab.sym_strs != NULL) {
8497c478bd9Sstevel@tonic-gate 			if (dump_symtab(pgc, fptr, index, 0) != 0)
8507c478bd9Sstevel@tonic-gate 				return (-1);
8517c478bd9Sstevel@tonic-gate 			index += 2;
8527c478bd9Sstevel@tonic-gate 		}
8538e458de0SRobert Mustacchi 
8548e458de0SRobert Mustacchi 		if ((pgc->pgc_content & CC_CONTENT_DEBUG) != 0 &&
8558e458de0SRobert Mustacchi 		    dump_debug(pgc, fptr, &index) != 0) {
8568e458de0SRobert Mustacchi 			return (-1);
8578e458de0SRobert Mustacchi 		}
8587c478bd9Sstevel@tonic-gate 	}
8597c478bd9Sstevel@tonic-gate 
8607c478bd9Sstevel@tonic-gate 	return (0);
8617c478bd9Sstevel@tonic-gate }
8627c478bd9Sstevel@tonic-gate 
8637c478bd9Sstevel@tonic-gate /*ARGSUSED*/
8647c478bd9Sstevel@tonic-gate static int
dump_map(void * data,const prmap_t * pmp,const char * name)8657c478bd9Sstevel@tonic-gate dump_map(void *data, const prmap_t *pmp, const char *name)
8667c478bd9Sstevel@tonic-gate {
8677c478bd9Sstevel@tonic-gate 	pgcore_t *pgc = data;
8687c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P = pgc->P;
8697c478bd9Sstevel@tonic-gate #ifdef _LP64
8707c478bd9Sstevel@tonic-gate 	Elf64_Phdr phdr;
8717c478bd9Sstevel@tonic-gate #else
8727c478bd9Sstevel@tonic-gate 	Elf32_Phdr phdr;
8737c478bd9Sstevel@tonic-gate #endif
8747c478bd9Sstevel@tonic-gate 	size_t n;
8757c478bd9Sstevel@tonic-gate 
8767c478bd9Sstevel@tonic-gate 	bzero(&phdr, sizeof (phdr));
8777c478bd9Sstevel@tonic-gate 	phdr.p_type = PT_LOAD;
8787c478bd9Sstevel@tonic-gate 	phdr.p_vaddr = pmp->pr_vaddr;
8797c478bd9Sstevel@tonic-gate 	phdr.p_memsz = pmp->pr_size;
8807c478bd9Sstevel@tonic-gate 	if (pmp->pr_mflags & MA_READ)
8817c478bd9Sstevel@tonic-gate 		phdr.p_flags |= PF_R;
8827c478bd9Sstevel@tonic-gate 	if (pmp->pr_mflags & MA_WRITE)
8837c478bd9Sstevel@tonic-gate 		phdr.p_flags |= PF_W;
8847c478bd9Sstevel@tonic-gate 	if (pmp->pr_mflags & MA_EXEC)
8857c478bd9Sstevel@tonic-gate 		phdr.p_flags |= PF_X;
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate 	if (pmp->pr_vaddr + pmp->pr_size > P->status.pr_stkbase &&
8887c478bd9Sstevel@tonic-gate 	    pmp->pr_vaddr < P->status.pr_stkbase + P->status.pr_stksize) {
8897c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_STACK))
8907c478bd9Sstevel@tonic-gate 			goto exclude;
8917c478bd9Sstevel@tonic-gate 
8927c478bd9Sstevel@tonic-gate 	} else if ((pmp->pr_mflags & MA_ANON) &&
8937c478bd9Sstevel@tonic-gate 	    pmp->pr_vaddr + pmp->pr_size > P->status.pr_brkbase &&
8947c478bd9Sstevel@tonic-gate 	    pmp->pr_vaddr < P->status.pr_brkbase + P->status.pr_brksize) {
8957c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_HEAP))
8967c478bd9Sstevel@tonic-gate 			goto exclude;
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 	} else if (pmp->pr_mflags & MA_ISM) {
8997c478bd9Sstevel@tonic-gate 		if (pmp->pr_mflags & MA_NORESERVE) {
9007c478bd9Sstevel@tonic-gate 			if (!(pgc->pgc_content & CC_CONTENT_DISM))
9017c478bd9Sstevel@tonic-gate 				goto exclude;
9027c478bd9Sstevel@tonic-gate 		} else {
9037c478bd9Sstevel@tonic-gate 			if (!(pgc->pgc_content & CC_CONTENT_ISM))
9047c478bd9Sstevel@tonic-gate 				goto exclude;
9057c478bd9Sstevel@tonic-gate 		}
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate 	} else if (pmp->pr_mflags & MA_SHM) {
9087c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_SHM))
9097c478bd9Sstevel@tonic-gate 			goto exclude;
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate 	} else if (pmp->pr_mflags & MA_SHARED) {
9127c478bd9Sstevel@tonic-gate 		if (pmp->pr_mflags & MA_ANON) {
9137c478bd9Sstevel@tonic-gate 			if (!(pgc->pgc_content & CC_CONTENT_SHANON))
9147c478bd9Sstevel@tonic-gate 				goto exclude;
9157c478bd9Sstevel@tonic-gate 		} else {
9167c478bd9Sstevel@tonic-gate 			if (!(pgc->pgc_content & CC_CONTENT_SHFILE))
9177c478bd9Sstevel@tonic-gate 				goto exclude;
9187c478bd9Sstevel@tonic-gate 		}
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate 	} else if (pmp->pr_mflags & MA_ANON) {
9217c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_ANON))
9227c478bd9Sstevel@tonic-gate 			goto exclude;
9237c478bd9Sstevel@tonic-gate 
9247c478bd9Sstevel@tonic-gate 	} else if (phdr.p_flags == (PF_R | PF_X)) {
9257c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_TEXT))
9267c478bd9Sstevel@tonic-gate 			goto exclude;
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate 	} else if (phdr.p_flags == PF_R) {
9297c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_RODATA))
9307c478bd9Sstevel@tonic-gate 			goto exclude;
9317c478bd9Sstevel@tonic-gate 
9327c478bd9Sstevel@tonic-gate 	} else {
9337c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_DATA))
9347c478bd9Sstevel@tonic-gate 			goto exclude;
9357c478bd9Sstevel@tonic-gate 	}
9367c478bd9Sstevel@tonic-gate 
9377c478bd9Sstevel@tonic-gate 	n = 0;
9387c478bd9Sstevel@tonic-gate 	while (n < pmp->pr_size) {
9397c478bd9Sstevel@tonic-gate 		size_t csz = MIN(pmp->pr_size - n, pgc->pgc_chunksz);
9405d228828SRobert Mustacchi 		ssize_t ret;
9415d228828SRobert Mustacchi 
9425d228828SRobert Mustacchi 		/*
9435d228828SRobert Mustacchi 		 * If we happen to have a PROT_NONE mapping, don't try to read
9445d228828SRobert Mustacchi 		 * from the address space.
9455d228828SRobert Mustacchi 		 */
9465d228828SRobert Mustacchi 		if ((pmp->pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) == 0) {
9475d228828SRobert Mustacchi 			bzero(pgc->pgc_chunk, csz);
9485d228828SRobert Mustacchi 			ret = csz;
9495d228828SRobert Mustacchi 		} else {
9505d228828SRobert Mustacchi 			ret = Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n);
9515d228828SRobert Mustacchi 		}
9527c478bd9Sstevel@tonic-gate 
9537c478bd9Sstevel@tonic-gate 		/*
9547c478bd9Sstevel@tonic-gate 		 * If we can't read out part of the victim's address
9557c478bd9Sstevel@tonic-gate 		 * space for some reason ignore that failure and try to
9567c478bd9Sstevel@tonic-gate 		 * emit a partial core file without that mapping's data.
9577c478bd9Sstevel@tonic-gate 		 * As in the kernel, we mark these failures with the
9587c478bd9Sstevel@tonic-gate 		 * PF_SUNW_FAILURE flag and store the errno where the
9597c478bd9Sstevel@tonic-gate 		 * mapping would have been.
9607c478bd9Sstevel@tonic-gate 		 */
9615d228828SRobert Mustacchi 		if (ret != csz || gc_pwrite64(pgc->pgc_fd, pgc->pgc_chunk, csz,
96264e4e50aSKeith M Wesolowski 		    *pgc->pgc_doff + n) != 0) {
9637c478bd9Sstevel@tonic-gate 			int err = errno;
96464e4e50aSKeith M Wesolowski 			(void) gc_pwrite64(pgc->pgc_fd, &err, sizeof (err),
9657c478bd9Sstevel@tonic-gate 			    *pgc->pgc_doff);
9667c478bd9Sstevel@tonic-gate 			*pgc->pgc_doff += roundup(sizeof (err), 8);
9677c478bd9Sstevel@tonic-gate 
9687c478bd9Sstevel@tonic-gate 			phdr.p_flags |= PF_SUNW_FAILURE;
9697c478bd9Sstevel@tonic-gate 			(void) ftruncate64(pgc->pgc_fd, *pgc->pgc_doff);
9707c478bd9Sstevel@tonic-gate 			goto exclude;
9717c478bd9Sstevel@tonic-gate 		}
9727c478bd9Sstevel@tonic-gate 
9737c478bd9Sstevel@tonic-gate 		n += csz;
9747c478bd9Sstevel@tonic-gate 	}
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 	phdr.p_offset = *pgc->pgc_doff;
9777c478bd9Sstevel@tonic-gate 	phdr.p_filesz = pmp->pr_size;
9787c478bd9Sstevel@tonic-gate 	*pgc->pgc_doff += roundup(phdr.p_filesz, 8);
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate exclude:
9817c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
98264e4e50aSKeith M Wesolowski 		if (gc_pwrite64(pgc->pgc_fd, &phdr, sizeof (phdr),
98364e4e50aSKeith M Wesolowski 		    *pgc->pgc_poff) != 0)
9847c478bd9Sstevel@tonic-gate 			return (1);
9857c478bd9Sstevel@tonic-gate 
9867c478bd9Sstevel@tonic-gate 		*pgc->pgc_poff += sizeof (phdr);
9877c478bd9Sstevel@tonic-gate #ifdef _LP64
9887c478bd9Sstevel@tonic-gate 	} else {
9897c478bd9Sstevel@tonic-gate 		Elf32_Phdr phdr32;
9907c478bd9Sstevel@tonic-gate 
9917c478bd9Sstevel@tonic-gate 		bzero(&phdr32, sizeof (phdr32));
9927c478bd9Sstevel@tonic-gate 		phdr32.p_type = phdr.p_type;
9937c478bd9Sstevel@tonic-gate 		phdr32.p_vaddr = (Elf32_Addr)phdr.p_vaddr;
9947c478bd9Sstevel@tonic-gate 		phdr32.p_memsz = (Elf32_Word)phdr.p_memsz;
9957c478bd9Sstevel@tonic-gate 		phdr32.p_flags = phdr.p_flags;
9967c478bd9Sstevel@tonic-gate 		phdr32.p_offset = (Elf32_Off)phdr.p_offset;
9977c478bd9Sstevel@tonic-gate 		phdr32.p_filesz = (Elf32_Word)phdr.p_filesz;
9987c478bd9Sstevel@tonic-gate 
99964e4e50aSKeith M Wesolowski 		if (gc_pwrite64(pgc->pgc_fd, &phdr32, sizeof (phdr32),
100064e4e50aSKeith M Wesolowski 		    *pgc->pgc_poff) != 0)
10017c478bd9Sstevel@tonic-gate 			return (1);
10027c478bd9Sstevel@tonic-gate 
10037c478bd9Sstevel@tonic-gate 		*pgc->pgc_poff += sizeof (phdr32);
10047c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
10057c478bd9Sstevel@tonic-gate 	}
10067c478bd9Sstevel@tonic-gate 
10077c478bd9Sstevel@tonic-gate 	return (0);
10087c478bd9Sstevel@tonic-gate }
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate int
write_shstrtab(struct ps_prochandle * P,pgcore_t * pgc)10117c478bd9Sstevel@tonic-gate write_shstrtab(struct ps_prochandle *P, pgcore_t *pgc)
10127c478bd9Sstevel@tonic-gate {
10137c478bd9Sstevel@tonic-gate 	off64_t off = *pgc->pgc_doff;
10147c478bd9Sstevel@tonic-gate 	size_t size = 0;
10157c478bd9Sstevel@tonic-gate 	shstrtab_t *s = &pgc->pgc_shstrtab;
10167c478bd9Sstevel@tonic-gate 
10177c478bd9Sstevel@tonic-gate 	if (shstrtab_size(s) == 1)
10187c478bd9Sstevel@tonic-gate 		return (0);
10197c478bd9Sstevel@tonic-gate 
10207c478bd9Sstevel@tonic-gate 	/*
10217c478bd9Sstevel@tonic-gate 	 * Preemptively stick the name of the shstrtab in the string table.
10227c478bd9Sstevel@tonic-gate 	 */
10238e458de0SRobert Mustacchi 	if (!shstrtab_ndx(&pgc->pgc_shstrtab,
10248e458de0SRobert Mustacchi 	    shstrtab_data[STR_SHSTRTAB], NULL)) {
10258e458de0SRobert Mustacchi 		return (1);
10268e458de0SRobert Mustacchi 	}
10277c478bd9Sstevel@tonic-gate 	size = shstrtab_size(s);
10287c478bd9Sstevel@tonic-gate 
10297c478bd9Sstevel@tonic-gate 	/*
10307c478bd9Sstevel@tonic-gate 	 * Dump all the strings that we used being sure we include the
10317c478bd9Sstevel@tonic-gate 	 * terminating null character.
10327c478bd9Sstevel@tonic-gate 	 */
10338e458de0SRobert Mustacchi 	for (shstrtab_ent_t *ent = list_head(&s->sst_names); ent != NULL;
10348e458de0SRobert Mustacchi 	    ent = list_next(&s->sst_names, ent)) {
10358e458de0SRobert Mustacchi 		if (gc_pwrite64(pgc->pgc_fd, ent->sste_name, ent->sste_len,
10368e458de0SRobert Mustacchi 		    off + ent->sste_offset) != 0) {
10377c478bd9Sstevel@tonic-gate 			return (1);
10387c478bd9Sstevel@tonic-gate 		}
10397c478bd9Sstevel@tonic-gate 	}
10407c478bd9Sstevel@tonic-gate 
10417c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
10427c478bd9Sstevel@tonic-gate 		Elf32_Shdr shdr;
10437c478bd9Sstevel@tonic-gate 
10447c478bd9Sstevel@tonic-gate 		bzero(&shdr, sizeof (shdr));
10458e458de0SRobert Mustacchi 		if (!shstrtab_ndx(&pgc->pgc_shstrtab,
10468e458de0SRobert Mustacchi 		    shstrtab_data[STR_SHSTRTAB], &shdr.sh_name)) {
10478e458de0SRobert Mustacchi 			return (1);
10488e458de0SRobert Mustacchi 		}
10497c478bd9Sstevel@tonic-gate 		shdr.sh_size = size;
10507c478bd9Sstevel@tonic-gate 		shdr.sh_offset = *pgc->pgc_doff;
10517c478bd9Sstevel@tonic-gate 		shdr.sh_addralign = 1;
10527c478bd9Sstevel@tonic-gate 		shdr.sh_flags = SHF_STRINGS;
10537c478bd9Sstevel@tonic-gate 		shdr.sh_type = SHT_STRTAB;
10547c478bd9Sstevel@tonic-gate 
105564e4e50aSKeith M Wesolowski 		if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
105664e4e50aSKeith M Wesolowski 		    *pgc->pgc_soff) != 0)
10577c478bd9Sstevel@tonic-gate 			return (1);
10587c478bd9Sstevel@tonic-gate 
10597c478bd9Sstevel@tonic-gate 		*pgc->pgc_soff += sizeof (shdr);
10607c478bd9Sstevel@tonic-gate #ifdef _LP64
10617c478bd9Sstevel@tonic-gate 	} else {
10627c478bd9Sstevel@tonic-gate 		Elf64_Shdr shdr;
10637c478bd9Sstevel@tonic-gate 
10647c478bd9Sstevel@tonic-gate 		bzero(&shdr, sizeof (shdr));
10658e458de0SRobert Mustacchi 		if (!shstrtab_ndx(&pgc->pgc_shstrtab,
10668e458de0SRobert Mustacchi 		    shstrtab_data[STR_SHSTRTAB], &shdr.sh_name)) {
10678e458de0SRobert Mustacchi 			return (1);
10688e458de0SRobert Mustacchi 		}
10697c478bd9Sstevel@tonic-gate 		shdr.sh_size = size;
10707c478bd9Sstevel@tonic-gate 		shdr.sh_offset = *pgc->pgc_doff;
10717c478bd9Sstevel@tonic-gate 		shdr.sh_addralign = 1;
10727c478bd9Sstevel@tonic-gate 		shdr.sh_flags = SHF_STRINGS;
10737c478bd9Sstevel@tonic-gate 		shdr.sh_type = SHT_STRTAB;
10747c478bd9Sstevel@tonic-gate 
107564e4e50aSKeith M Wesolowski 		if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
107664e4e50aSKeith M Wesolowski 		    *pgc->pgc_soff) != 0)
10777c478bd9Sstevel@tonic-gate 			return (1);
10787c478bd9Sstevel@tonic-gate 
10797c478bd9Sstevel@tonic-gate 		*pgc->pgc_soff += sizeof (shdr);
10807c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
10817c478bd9Sstevel@tonic-gate 	}
10827c478bd9Sstevel@tonic-gate 
10837c478bd9Sstevel@tonic-gate 	*pgc->pgc_doff += roundup(size, 8);
10847c478bd9Sstevel@tonic-gate 
10857c478bd9Sstevel@tonic-gate 	return (0);
10867c478bd9Sstevel@tonic-gate }
10877c478bd9Sstevel@tonic-gate 
10887c478bd9Sstevel@tonic-gate /*
10897c478bd9Sstevel@tonic-gate  * Don't explicity stop the process; that's up to the consumer.
10907c478bd9Sstevel@tonic-gate  */
10917c478bd9Sstevel@tonic-gate int
Pfgcore(struct ps_prochandle * P,int fd,core_content_t content)10927c478bd9Sstevel@tonic-gate Pfgcore(struct ps_prochandle *P, int fd, core_content_t content)
10937c478bd9Sstevel@tonic-gate {
10947c478bd9Sstevel@tonic-gate 	char plat[SYS_NMLN];
10957c478bd9Sstevel@tonic-gate 	char zonename[ZONENAME_MAX];
10967c478bd9Sstevel@tonic-gate 	int platlen = -1;
10977c478bd9Sstevel@tonic-gate 	pgcore_t pgc;
10987c478bd9Sstevel@tonic-gate 	off64_t poff, soff, doff, boff;
10997c478bd9Sstevel@tonic-gate 	struct utsname uts;
11007c478bd9Sstevel@tonic-gate 	uint_t nphdrs, nshdrs;
11017c478bd9Sstevel@tonic-gate 
11027c478bd9Sstevel@tonic-gate 	if (ftruncate64(fd, 0) != 0)
11037c478bd9Sstevel@tonic-gate 		return (-1);
11047c478bd9Sstevel@tonic-gate 
11057c478bd9Sstevel@tonic-gate 	if (content == CC_CONTENT_INVALID) {
11067c478bd9Sstevel@tonic-gate 		errno = EINVAL;
11077c478bd9Sstevel@tonic-gate 		return (-1);
11087c478bd9Sstevel@tonic-gate 	}
11097c478bd9Sstevel@tonic-gate 
11107c478bd9Sstevel@tonic-gate 	/*
11117c478bd9Sstevel@tonic-gate 	 * Cache the mappings and other useful data.
11127c478bd9Sstevel@tonic-gate 	 */
11137c478bd9Sstevel@tonic-gate 	(void) Prd_agent(P);
11147c478bd9Sstevel@tonic-gate 	(void) Ppsinfo(P);
11157c478bd9Sstevel@tonic-gate 
11168e458de0SRobert Mustacchi 	(void) memset(&pgc, 0, sizeof (pgc));
11177c478bd9Sstevel@tonic-gate 	pgc.P = P;
11187c478bd9Sstevel@tonic-gate 	pgc.pgc_fd = fd;
11197c478bd9Sstevel@tonic-gate 	pgc.pgc_poff = &poff;
11207c478bd9Sstevel@tonic-gate 	pgc.pgc_soff = &soff;
11217c478bd9Sstevel@tonic-gate 	pgc.pgc_doff = &doff;
11227c478bd9Sstevel@tonic-gate 	pgc.pgc_content = content;
11237c478bd9Sstevel@tonic-gate 	pgc.pgc_chunksz = PAGESIZE;
11247c478bd9Sstevel@tonic-gate 	if ((pgc.pgc_chunk = malloc(pgc.pgc_chunksz)) == NULL)
11257c478bd9Sstevel@tonic-gate 		return (-1);
11267c478bd9Sstevel@tonic-gate 
11278e458de0SRobert Mustacchi 	if (!shstrtab_init(&pgc.pgc_shstrtab)) {
11288e458de0SRobert Mustacchi 		goto err;
11298e458de0SRobert Mustacchi 	}
11307c478bd9Sstevel@tonic-gate 
11317c478bd9Sstevel@tonic-gate 	/*
11327c478bd9Sstevel@tonic-gate 	 * There are two PT_NOTE program headers for ancillary data, and
11337c478bd9Sstevel@tonic-gate 	 * one for each mapping.
11347c478bd9Sstevel@tonic-gate 	 */
11357c478bd9Sstevel@tonic-gate 	nphdrs = 2 + P->map_count;
11367c478bd9Sstevel@tonic-gate 	nshdrs = count_sections(&pgc);
11377c478bd9Sstevel@tonic-gate 
11387c478bd9Sstevel@tonic-gate 	(void) Pplatform(P, plat, sizeof (plat));
11397c478bd9Sstevel@tonic-gate 	platlen = strlen(plat) + 1;
11407c478bd9Sstevel@tonic-gate 	Preadauxvec(P);
11417c478bd9Sstevel@tonic-gate 	(void) Puname(P, &uts);
11427c478bd9Sstevel@tonic-gate 	if (Pzonename(P, zonename, sizeof (zonename)) == NULL)
11437c478bd9Sstevel@tonic-gate 		zonename[0] = '\0';
11447c478bd9Sstevel@tonic-gate 
11457c478bd9Sstevel@tonic-gate 	/*
114630da1432Sahl 	 * The core file contents may required zero section headers, but if we
114730da1432Sahl 	 * overflow the 16 bits allotted to the program header count in the ELF
114830da1432Sahl 	 * header, we'll need that program header at index zero.
114930da1432Sahl 	 */
115030da1432Sahl 	if (nshdrs == 0 && nphdrs >= PN_XNUM)
115130da1432Sahl 		nshdrs = 1;
115230da1432Sahl 
115330da1432Sahl 	/*
11547c478bd9Sstevel@tonic-gate 	 * Set up the ELF header.
11557c478bd9Sstevel@tonic-gate 	 */
11567c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
11577c478bd9Sstevel@tonic-gate 		Elf32_Ehdr ehdr;
11587c478bd9Sstevel@tonic-gate 
11597c478bd9Sstevel@tonic-gate 		bzero(&ehdr, sizeof (ehdr));
11607c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG0] = ELFMAG0;
11617c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG1] = ELFMAG1;
11627c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG2] = ELFMAG2;
11637c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG3] = ELFMAG3;
11647c478bd9Sstevel@tonic-gate 		ehdr.e_type = ET_CORE;
11657c478bd9Sstevel@tonic-gate 
11667c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_CLASS] = ELFCLASS32;
11677c478bd9Sstevel@tonic-gate #if defined(__sparc)
11687c478bd9Sstevel@tonic-gate 		ehdr.e_machine = EM_SPARC;
11697c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
11707c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64)
11717c478bd9Sstevel@tonic-gate 		ehdr.e_machine = EM_386;
11727c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
11737c478bd9Sstevel@tonic-gate #else
11747c478bd9Sstevel@tonic-gate #error "unknown machine type"
11757c478bd9Sstevel@tonic-gate #endif
11767c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_VERSION] = EV_CURRENT;
11777c478bd9Sstevel@tonic-gate 
11787c478bd9Sstevel@tonic-gate 		ehdr.e_version = EV_CURRENT;
11797c478bd9Sstevel@tonic-gate 		ehdr.e_ehsize = sizeof (ehdr);
118030da1432Sahl 
118130da1432Sahl 		if (nphdrs >= PN_XNUM)
118230da1432Sahl 			ehdr.e_phnum = PN_XNUM;
118330da1432Sahl 		else
11847c478bd9Sstevel@tonic-gate 			ehdr.e_phnum = (unsigned short)nphdrs;
118530da1432Sahl 
118630da1432Sahl 		ehdr.e_phentsize = sizeof (Elf32_Phdr);
11877c478bd9Sstevel@tonic-gate 		ehdr.e_phoff = ehdr.e_ehsize;
11887c478bd9Sstevel@tonic-gate 
118930da1432Sahl 		if (nshdrs > 0) {
119030da1432Sahl 			if (nshdrs >= SHN_LORESERVE)
119130da1432Sahl 				ehdr.e_shnum = 0;
119230da1432Sahl 			else
11937c478bd9Sstevel@tonic-gate 				ehdr.e_shnum = (unsigned short)nshdrs;
119430da1432Sahl 
119530da1432Sahl 			if (nshdrs - 1 >= SHN_LORESERVE)
119630da1432Sahl 				ehdr.e_shstrndx = SHN_XINDEX;
119730da1432Sahl 			else
119830da1432Sahl 				ehdr.e_shstrndx = (unsigned short)(nshdrs - 1);
119930da1432Sahl 
120030da1432Sahl 			ehdr.e_shentsize = sizeof (Elf32_Shdr);
120130da1432Sahl 			ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs;
12027c478bd9Sstevel@tonic-gate 		}
12037c478bd9Sstevel@tonic-gate 
120464e4e50aSKeith M Wesolowski 		if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0)
12057c478bd9Sstevel@tonic-gate 			goto err;
12067c478bd9Sstevel@tonic-gate 
12077c478bd9Sstevel@tonic-gate 		poff = ehdr.e_phoff;
120830da1432Sahl 		soff = ehdr.e_shoff;
12097c478bd9Sstevel@tonic-gate 		doff = boff = ehdr.e_ehsize +
121030da1432Sahl 		    ehdr.e_phentsize * nphdrs +
121130da1432Sahl 		    ehdr.e_shentsize * nshdrs;
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate #ifdef _LP64
12147c478bd9Sstevel@tonic-gate 	} else {
12157c478bd9Sstevel@tonic-gate 		Elf64_Ehdr ehdr;
12167c478bd9Sstevel@tonic-gate 
12177c478bd9Sstevel@tonic-gate 		bzero(&ehdr, sizeof (ehdr));
12187c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG0] = ELFMAG0;
12197c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG1] = ELFMAG1;
12207c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG2] = ELFMAG2;
12217c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG3] = ELFMAG3;
12227c478bd9Sstevel@tonic-gate 		ehdr.e_type = ET_CORE;
12237c478bd9Sstevel@tonic-gate 
12247c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_CLASS] = ELFCLASS64;
12257c478bd9Sstevel@tonic-gate #if defined(__sparc)
12267c478bd9Sstevel@tonic-gate 		ehdr.e_machine = EM_SPARCV9;
12277c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
12287c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64)
12297c478bd9Sstevel@tonic-gate 		ehdr.e_machine = EM_AMD64;
12307c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
12317c478bd9Sstevel@tonic-gate #else
12327c478bd9Sstevel@tonic-gate #error "unknown machine type"
12337c478bd9Sstevel@tonic-gate #endif
12347c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_VERSION] = EV_CURRENT;
12357c478bd9Sstevel@tonic-gate 
12367c478bd9Sstevel@tonic-gate 		ehdr.e_version = EV_CURRENT;
12377c478bd9Sstevel@tonic-gate 		ehdr.e_ehsize = sizeof (ehdr);
123830da1432Sahl 
123930da1432Sahl 		if (nphdrs >= PN_XNUM)
124030da1432Sahl 			ehdr.e_phnum = PN_XNUM;
124130da1432Sahl 		else
12427c478bd9Sstevel@tonic-gate 			ehdr.e_phnum = (unsigned short)nphdrs;
124330da1432Sahl 
124430da1432Sahl 		ehdr.e_phentsize = sizeof (Elf64_Phdr);
12457c478bd9Sstevel@tonic-gate 		ehdr.e_phoff = ehdr.e_ehsize;
12467c478bd9Sstevel@tonic-gate 
124730da1432Sahl 		if (nshdrs > 0) {
124830da1432Sahl 			if (nshdrs >= SHN_LORESERVE)
124930da1432Sahl 				ehdr.e_shnum = 0;
125030da1432Sahl 			else
12517c478bd9Sstevel@tonic-gate 				ehdr.e_shnum = (unsigned short)nshdrs;
125230da1432Sahl 
125330da1432Sahl 			if (nshdrs - 1 >= SHN_LORESERVE)
125430da1432Sahl 				ehdr.e_shstrndx = SHN_XINDEX;
125530da1432Sahl 			else
125630da1432Sahl 				ehdr.e_shstrndx = (unsigned short)(nshdrs - 1);
125730da1432Sahl 
125830da1432Sahl 			ehdr.e_shentsize = sizeof (Elf64_Shdr);
125930da1432Sahl 			ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs;
12607c478bd9Sstevel@tonic-gate 		}
12617c478bd9Sstevel@tonic-gate 
126264e4e50aSKeith M Wesolowski 		if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0)
12637c478bd9Sstevel@tonic-gate 			goto err;
12647c478bd9Sstevel@tonic-gate 
12657c478bd9Sstevel@tonic-gate 		poff = ehdr.e_phoff;
126630da1432Sahl 		soff = ehdr.e_shoff;
126730da1432Sahl 		doff = boff = ehdr.e_ehsize +
126830da1432Sahl 		    ehdr.e_phentsize * nphdrs +
126930da1432Sahl 		    ehdr.e_shentsize * nshdrs;
12707c478bd9Sstevel@tonic-gate 
12717c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
12727c478bd9Sstevel@tonic-gate 	}
12737c478bd9Sstevel@tonic-gate 
12747c478bd9Sstevel@tonic-gate 	/*
127530da1432Sahl 	 * Write the zero indexed section if it exists.
127630da1432Sahl 	 */
12778e458de0SRobert Mustacchi 	if (nshdrs > 0 && write_shdr(&pgc, shstrtab_data[STR_NONE], 0, 0, 0, 0,
127830da1432Sahl 	    nshdrs >= SHN_LORESERVE ? nshdrs : 0,
127930da1432Sahl 	    nshdrs - 1 >= SHN_LORESERVE ? nshdrs - 1 : 0,
128030da1432Sahl 	    nphdrs >= PN_XNUM ? nphdrs : 0, 0, 0) != 0)
128130da1432Sahl 		goto err;
128230da1432Sahl 
128330da1432Sahl 	/*
12847c478bd9Sstevel@tonic-gate 	 * Construct the old-style note header and section.
12857c478bd9Sstevel@tonic-gate 	 */
12867c478bd9Sstevel@tonic-gate 
12877c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
12887c478bd9Sstevel@tonic-gate 		prpsinfo_t prpsinfo;
12897c478bd9Sstevel@tonic-gate 
12907c478bd9Sstevel@tonic-gate 		mkprpsinfo(P, &prpsinfo);
12917c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PRPSINFO, &prpsinfo, sizeof (prpsinfo_t),
12927c478bd9Sstevel@tonic-gate 		    &doff) != 0) {
12937c478bd9Sstevel@tonic-gate 			goto err;
12947c478bd9Sstevel@tonic-gate 		}
12957c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_AUXV, P->auxv,
12967c478bd9Sstevel@tonic-gate 		    P->nauxv * sizeof (P->auxv[0]), &doff) != 0) {
12977c478bd9Sstevel@tonic-gate 			goto err;
12987c478bd9Sstevel@tonic-gate 		}
12997c478bd9Sstevel@tonic-gate #ifdef _LP64
13007c478bd9Sstevel@tonic-gate 	} else {
13017c478bd9Sstevel@tonic-gate 		prpsinfo32_t pi32;
13027c478bd9Sstevel@tonic-gate 		auxv32_t *av32;
13037c478bd9Sstevel@tonic-gate 		size_t size = sizeof (auxv32_t) * P->nauxv;
13047c478bd9Sstevel@tonic-gate 		int i;
13057c478bd9Sstevel@tonic-gate 
13067c478bd9Sstevel@tonic-gate 		mkprpsinfo32(P, &pi32);
13077c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PRPSINFO, &pi32, sizeof (prpsinfo32_t),
13087c478bd9Sstevel@tonic-gate 		    &doff) != 0) {
13097c478bd9Sstevel@tonic-gate 			goto err;
13107c478bd9Sstevel@tonic-gate 		}
13117c478bd9Sstevel@tonic-gate 
13127c478bd9Sstevel@tonic-gate 		if ((av32 = malloc(size)) == NULL)
13137c478bd9Sstevel@tonic-gate 			goto err;
13147c478bd9Sstevel@tonic-gate 
13157c478bd9Sstevel@tonic-gate 		for (i = 0; i < P->nauxv; i++) {
13167c478bd9Sstevel@tonic-gate 			auxv_n_to_32(&P->auxv[i], &av32[i]);
13177c478bd9Sstevel@tonic-gate 		}
13187c478bd9Sstevel@tonic-gate 
13197c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) {
13207c478bd9Sstevel@tonic-gate 			free(av32);
13217c478bd9Sstevel@tonic-gate 			goto err;
13227c478bd9Sstevel@tonic-gate 		}
13237c478bd9Sstevel@tonic-gate 
13247c478bd9Sstevel@tonic-gate 		free(av32);
13257c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
13267c478bd9Sstevel@tonic-gate 	}
13277c478bd9Sstevel@tonic-gate 
13287c478bd9Sstevel@tonic-gate 	if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0)
13297c478bd9Sstevel@tonic-gate 		goto err;
13307c478bd9Sstevel@tonic-gate 
13317c478bd9Sstevel@tonic-gate 	if (Plwp_iter_all(P, old_per_lwp, &pgc) != 0)
13327c478bd9Sstevel@tonic-gate 		goto err;
13337c478bd9Sstevel@tonic-gate 
13347c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
13357c478bd9Sstevel@tonic-gate 		Elf32_Phdr phdr;
13367c478bd9Sstevel@tonic-gate 
13377c478bd9Sstevel@tonic-gate 		bzero(&phdr, sizeof (phdr));
13387c478bd9Sstevel@tonic-gate 		phdr.p_type = PT_NOTE;
13397c478bd9Sstevel@tonic-gate 		phdr.p_flags = PF_R;
13407c478bd9Sstevel@tonic-gate 		phdr.p_offset = (Elf32_Off)boff;
13417c478bd9Sstevel@tonic-gate 		phdr.p_filesz = doff - boff;
13427c478bd9Sstevel@tonic-gate 		boff = doff;
13437c478bd9Sstevel@tonic-gate 
134464e4e50aSKeith M Wesolowski 		if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
13457c478bd9Sstevel@tonic-gate 			goto err;
13467c478bd9Sstevel@tonic-gate 		poff += sizeof (phdr);
13477c478bd9Sstevel@tonic-gate #ifdef _LP64
13487c478bd9Sstevel@tonic-gate 	} else {
13497c478bd9Sstevel@tonic-gate 		Elf64_Phdr phdr;
13507c478bd9Sstevel@tonic-gate 
13517c478bd9Sstevel@tonic-gate 		bzero(&phdr, sizeof (phdr));
13527c478bd9Sstevel@tonic-gate 		phdr.p_type = PT_NOTE;
13537c478bd9Sstevel@tonic-gate 		phdr.p_flags = PF_R;
13547c478bd9Sstevel@tonic-gate 		phdr.p_offset = boff;
13557c478bd9Sstevel@tonic-gate 		phdr.p_filesz = doff - boff;
13567c478bd9Sstevel@tonic-gate 		boff = doff;
13577c478bd9Sstevel@tonic-gate 
135864e4e50aSKeith M Wesolowski 		if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
13597c478bd9Sstevel@tonic-gate 			goto err;
13607c478bd9Sstevel@tonic-gate 		poff += sizeof (phdr);
13617c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
13627c478bd9Sstevel@tonic-gate 	}
13637c478bd9Sstevel@tonic-gate 
13647c478bd9Sstevel@tonic-gate 	/*
13657c478bd9Sstevel@tonic-gate 	 * Construct the new-style note header and section.
13667c478bd9Sstevel@tonic-gate 	 */
13677c478bd9Sstevel@tonic-gate 
13687c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
13697c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PSINFO, &P->psinfo, sizeof (psinfo_t),
13707c478bd9Sstevel@tonic-gate 		    &doff) != 0) {
13717c478bd9Sstevel@tonic-gate 			goto err;
13727c478bd9Sstevel@tonic-gate 		}
13737c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PSTATUS, &P->status, sizeof (pstatus_t),
13747c478bd9Sstevel@tonic-gate 		    &doff) != 0) {
13757c478bd9Sstevel@tonic-gate 			goto err;
13767c478bd9Sstevel@tonic-gate 		}
13777c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_AUXV, P->auxv,
13787c478bd9Sstevel@tonic-gate 		    P->nauxv * sizeof (P->auxv[0]), &doff) != 0) {
13797c478bd9Sstevel@tonic-gate 			goto err;
13807c478bd9Sstevel@tonic-gate 		}
13817c478bd9Sstevel@tonic-gate #ifdef _LP64
13827c478bd9Sstevel@tonic-gate 	} else {
13837c478bd9Sstevel@tonic-gate 		psinfo32_t pi32;
13847c478bd9Sstevel@tonic-gate 		pstatus32_t ps32;
13857c478bd9Sstevel@tonic-gate 		auxv32_t *av32;
13867c478bd9Sstevel@tonic-gate 		size_t size = sizeof (auxv32_t) * P->nauxv;
13877c478bd9Sstevel@tonic-gate 		int i;
13887c478bd9Sstevel@tonic-gate 
13897c478bd9Sstevel@tonic-gate 		psinfo_n_to_32(&P->psinfo, &pi32);
13907c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PSINFO, &pi32, sizeof (psinfo32_t),
13917c478bd9Sstevel@tonic-gate 		    &doff) != 0) {
13927c478bd9Sstevel@tonic-gate 			goto err;
13937c478bd9Sstevel@tonic-gate 		}
13947c478bd9Sstevel@tonic-gate 		pstatus_n_to_32(&P->status, &ps32);
13957c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PSTATUS, &ps32, sizeof (pstatus32_t),
13967c478bd9Sstevel@tonic-gate 		    &doff) != 0) {
13977c478bd9Sstevel@tonic-gate 			goto err;
13987c478bd9Sstevel@tonic-gate 		}
13997c478bd9Sstevel@tonic-gate 		if ((av32 = malloc(size)) == NULL)
14007c478bd9Sstevel@tonic-gate 			goto err;
14017c478bd9Sstevel@tonic-gate 
14027c478bd9Sstevel@tonic-gate 		for (i = 0; i < P->nauxv; i++) {
14037c478bd9Sstevel@tonic-gate 			auxv_n_to_32(&P->auxv[i], &av32[i]);
14047c478bd9Sstevel@tonic-gate 		}
14057c478bd9Sstevel@tonic-gate 
14067c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) {
14077c478bd9Sstevel@tonic-gate 			free(av32);
14087c478bd9Sstevel@tonic-gate 			goto err;
14097c478bd9Sstevel@tonic-gate 		}
14107c478bd9Sstevel@tonic-gate 
14117c478bd9Sstevel@tonic-gate 		free(av32);
14127c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
14137c478bd9Sstevel@tonic-gate 	}
14147c478bd9Sstevel@tonic-gate 
14157c478bd9Sstevel@tonic-gate 	if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0 ||
14167c478bd9Sstevel@tonic-gate 	    write_note(fd, NT_UTSNAME, &uts, sizeof (uts), &doff) != 0 ||
14177c478bd9Sstevel@tonic-gate 	    write_note(fd, NT_CONTENT, &content, sizeof (content), &doff) != 0)
14187c478bd9Sstevel@tonic-gate 		goto err;
14197c478bd9Sstevel@tonic-gate 
14207c478bd9Sstevel@tonic-gate 	{
14217c478bd9Sstevel@tonic-gate 		prcred_t cred, *cp;
14227c478bd9Sstevel@tonic-gate 		size_t size = sizeof (prcred_t);
14237c478bd9Sstevel@tonic-gate 
14247c478bd9Sstevel@tonic-gate 		if (Pcred(P, &cred, 0) != 0)
14257c478bd9Sstevel@tonic-gate 			goto err;
14267c478bd9Sstevel@tonic-gate 
14277c478bd9Sstevel@tonic-gate 		if (cred.pr_ngroups > 0)
14287c478bd9Sstevel@tonic-gate 			size += sizeof (gid_t) * (cred.pr_ngroups - 1);
14297c478bd9Sstevel@tonic-gate 		if ((cp = malloc(size)) == NULL)
14307c478bd9Sstevel@tonic-gate 			goto err;
14317c478bd9Sstevel@tonic-gate 
14327c478bd9Sstevel@tonic-gate 		if (Pcred(P, cp, cred.pr_ngroups) != 0 ||
14337c478bd9Sstevel@tonic-gate 		    write_note(fd, NT_PRCRED, cp, size, &doff) != 0) {
14347c478bd9Sstevel@tonic-gate 			free(cp);
14357c478bd9Sstevel@tonic-gate 			goto err;
14367c478bd9Sstevel@tonic-gate 		}
14377c478bd9Sstevel@tonic-gate 
14387c478bd9Sstevel@tonic-gate 		free(cp);
14397c478bd9Sstevel@tonic-gate 	}
14407c478bd9Sstevel@tonic-gate 
14417c478bd9Sstevel@tonic-gate 	{
14422a12f85aSJeremy Jones 		prpriv_t *ppriv = NULL;
14437c478bd9Sstevel@tonic-gate 		const priv_impl_info_t *pinfo;
14447c478bd9Sstevel@tonic-gate 		size_t pprivsz, pinfosz;
14457c478bd9Sstevel@tonic-gate 
14462a12f85aSJeremy Jones 		if (Ppriv(P, &ppriv) == -1)
14477c478bd9Sstevel@tonic-gate 			goto err;
14487c478bd9Sstevel@tonic-gate 		pprivsz = PRIV_PRPRIV_SIZE(ppriv);
14497c478bd9Sstevel@tonic-gate 
14507c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PRPRIV, ppriv, pprivsz, &doff) != 0) {
145143051d27SRobert Mustacchi 			Ppriv_free(P, ppriv);
14527c478bd9Sstevel@tonic-gate 			goto err;
14537c478bd9Sstevel@tonic-gate 		}
145443051d27SRobert Mustacchi 		Ppriv_free(P, ppriv);
14557c478bd9Sstevel@tonic-gate 
14567c478bd9Sstevel@tonic-gate 		if ((pinfo = getprivimplinfo()) == NULL)
14577c478bd9Sstevel@tonic-gate 			goto err;
14587c478bd9Sstevel@tonic-gate 		pinfosz = PRIV_IMPL_INFO_SIZE(pinfo);
14597c478bd9Sstevel@tonic-gate 
14607c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PRPRIVINFO, pinfo, pinfosz, &doff) != 0)
14617c478bd9Sstevel@tonic-gate 			goto err;
14627c478bd9Sstevel@tonic-gate 	}
14637c478bd9Sstevel@tonic-gate 
14647c478bd9Sstevel@tonic-gate 	if (write_note(fd, NT_ZONENAME, zonename, strlen(zonename) + 1,
14657c478bd9Sstevel@tonic-gate 	    &doff) != 0)
14667c478bd9Sstevel@tonic-gate 		goto err;
14677c478bd9Sstevel@tonic-gate 
146834bdffbfSGarrett D'Amore 	{
146934bdffbfSGarrett D'Amore 		fditer_t iter;
147034bdffbfSGarrett D'Amore 		iter.fd_fd = fd;
147134bdffbfSGarrett D'Amore 		iter.fd_doff = &doff;
147234bdffbfSGarrett D'Amore 
147334bdffbfSGarrett D'Amore 		if (Pfdinfo_iter(P, iter_fd, &iter) != 0)
147434bdffbfSGarrett D'Amore 			goto err;
147534bdffbfSGarrett D'Amore 	}
147634bdffbfSGarrett D'Amore 
1477d2a70789SRichard Lowe 
1478d2a70789SRichard Lowe 	{
1479d2a70789SRichard Lowe 		prsecflags_t *psf = NULL;
1480d2a70789SRichard Lowe 
1481d2a70789SRichard Lowe 		if (Psecflags(P, &psf) != 0)
1482d2a70789SRichard Lowe 			goto err;
1483d2a70789SRichard Lowe 
1484d2a70789SRichard Lowe 		if (write_note(fd, NT_SECFLAGS, psf,
1485d2a70789SRichard Lowe 		    sizeof (prsecflags_t), &doff) != 0) {
1486d2a70789SRichard Lowe 			Psecflags_free(psf);
1487d2a70789SRichard Lowe 			goto err;
1488d2a70789SRichard Lowe 		}
1489d2a70789SRichard Lowe 
1490d2a70789SRichard Lowe 		Psecflags_free(psf);
1491d2a70789SRichard Lowe 	}
1492d2a70789SRichard Lowe 
14937c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64)
14947c478bd9Sstevel@tonic-gate 	/* CSTYLED */
14957c478bd9Sstevel@tonic-gate 	{
14967c478bd9Sstevel@tonic-gate 		struct ssd *ldtp;
14977c478bd9Sstevel@tonic-gate 		size_t size;
14987c478bd9Sstevel@tonic-gate 		int nldt;
14997c478bd9Sstevel@tonic-gate 
150040c00cd7Sahl 		/*
150140c00cd7Sahl 		 * Only dump out non-zero sized LDT notes.
150240c00cd7Sahl 		 */
150340c00cd7Sahl 		if ((nldt = Pldt(P, NULL, 0)) != 0) {
15047c478bd9Sstevel@tonic-gate 			size = sizeof (struct ssd) * nldt;
15057c478bd9Sstevel@tonic-gate 			if ((ldtp = malloc(size)) == NULL)
15067c478bd9Sstevel@tonic-gate 				goto err;
15077c478bd9Sstevel@tonic-gate 
15087c478bd9Sstevel@tonic-gate 			if (Pldt(P, ldtp, nldt) == -1 ||
15097c478bd9Sstevel@tonic-gate 			    write_note(fd, NT_LDT, ldtp, size, &doff) != 0) {
15107c478bd9Sstevel@tonic-gate 				free(ldtp);
15117c478bd9Sstevel@tonic-gate 				goto err;
15127c478bd9Sstevel@tonic-gate 			}
15137c478bd9Sstevel@tonic-gate 
15147c478bd9Sstevel@tonic-gate 			free(ldtp);
15157c478bd9Sstevel@tonic-gate 		}
151640c00cd7Sahl 	}
15177c478bd9Sstevel@tonic-gate #endif	/* __i386 || __amd64 */
15187c478bd9Sstevel@tonic-gate 
15197c478bd9Sstevel@tonic-gate 	if (Plwp_iter_all(P, new_per_lwp, &pgc) != 0)
15207c478bd9Sstevel@tonic-gate 		goto err;
15217c478bd9Sstevel@tonic-gate 
15227c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
15237c478bd9Sstevel@tonic-gate 		Elf32_Phdr phdr;
15247c478bd9Sstevel@tonic-gate 
15257c478bd9Sstevel@tonic-gate 		bzero(&phdr, sizeof (phdr));
15267c478bd9Sstevel@tonic-gate 		phdr.p_type = PT_NOTE;
15277c478bd9Sstevel@tonic-gate 		phdr.p_flags = PF_R;
15287c478bd9Sstevel@tonic-gate 		phdr.p_offset = (Elf32_Off)boff;
15297c478bd9Sstevel@tonic-gate 		phdr.p_filesz = doff - boff;
15307c478bd9Sstevel@tonic-gate 		boff = doff;
15317c478bd9Sstevel@tonic-gate 
153264e4e50aSKeith M Wesolowski 		if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
15337c478bd9Sstevel@tonic-gate 			goto err;
15347c478bd9Sstevel@tonic-gate 		poff += sizeof (phdr);
15357c478bd9Sstevel@tonic-gate #ifdef _LP64
15367c478bd9Sstevel@tonic-gate 	} else {
15377c478bd9Sstevel@tonic-gate 		Elf64_Phdr phdr;
15387c478bd9Sstevel@tonic-gate 
15397c478bd9Sstevel@tonic-gate 		bzero(&phdr, sizeof (phdr));
15407c478bd9Sstevel@tonic-gate 		phdr.p_type = PT_NOTE;
15417c478bd9Sstevel@tonic-gate 		phdr.p_flags = PF_R;
15427c478bd9Sstevel@tonic-gate 		phdr.p_offset = boff;
15437c478bd9Sstevel@tonic-gate 		phdr.p_filesz = doff - boff;
15447c478bd9Sstevel@tonic-gate 		boff = doff;
15457c478bd9Sstevel@tonic-gate 
154664e4e50aSKeith M Wesolowski 		if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
15477c478bd9Sstevel@tonic-gate 			goto err;
15487c478bd9Sstevel@tonic-gate 		poff += sizeof (phdr);
15497c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
15507c478bd9Sstevel@tonic-gate 	}
15517c478bd9Sstevel@tonic-gate 
15527c478bd9Sstevel@tonic-gate 	/*
15537c478bd9Sstevel@tonic-gate 	 * Construct the headers for each mapping and write out its data
15547c478bd9Sstevel@tonic-gate 	 * if the content parameter indicates that it should be present
15557c478bd9Sstevel@tonic-gate 	 * in the core file.
15567c478bd9Sstevel@tonic-gate 	 */
15577c478bd9Sstevel@tonic-gate 	if (Pmapping_iter(P, dump_map, &pgc) != 0)
15587c478bd9Sstevel@tonic-gate 		goto err;
15597c478bd9Sstevel@tonic-gate 
15607c478bd9Sstevel@tonic-gate 	if (dump_sections(&pgc) != 0)
15617c478bd9Sstevel@tonic-gate 		goto err;
15627c478bd9Sstevel@tonic-gate 
15637c478bd9Sstevel@tonic-gate 	if (write_shstrtab(P, &pgc) != 0)
15647c478bd9Sstevel@tonic-gate 		goto err;
15657c478bd9Sstevel@tonic-gate 
15667c478bd9Sstevel@tonic-gate 	free(pgc.pgc_chunk);
15678e458de0SRobert Mustacchi 	shstrtab_fini(&pgc.pgc_shstrtab);
15687c478bd9Sstevel@tonic-gate 
15697c478bd9Sstevel@tonic-gate 	return (0);
15707c478bd9Sstevel@tonic-gate 
15717c478bd9Sstevel@tonic-gate err:
15727c478bd9Sstevel@tonic-gate 	/*
15737c478bd9Sstevel@tonic-gate 	 * Wipe out anything we may have written if there was an error.
15747c478bd9Sstevel@tonic-gate 	 */
15757c478bd9Sstevel@tonic-gate 	(void) ftruncate64(fd, 0);
15767c478bd9Sstevel@tonic-gate 	free(pgc.pgc_chunk);
15778e458de0SRobert Mustacchi 	shstrtab_fini(&pgc.pgc_shstrtab);
1578d2a70789SRichard Lowe 
15797c478bd9Sstevel@tonic-gate 	return (-1);
15807c478bd9Sstevel@tonic-gate }
15817c478bd9Sstevel@tonic-gate 
15827c478bd9Sstevel@tonic-gate static const char *content_str[] = {
15837c478bd9Sstevel@tonic-gate 	"stack",	/* CC_CONTENT_STACK */
15847c478bd9Sstevel@tonic-gate 	"heap",		/* CC_CONTENT_HEAP */
15857c478bd9Sstevel@tonic-gate 	"shfile",	/* CC_CONTENT_SHFILE */
15867c478bd9Sstevel@tonic-gate 	"shanon",	/* CC_CONTENT_SHANON */
15877c478bd9Sstevel@tonic-gate 	"text",		/* CC_CONTENT_TEXT */
15887c478bd9Sstevel@tonic-gate 	"data",		/* CC_CONTENT_DATA */
15897c478bd9Sstevel@tonic-gate 	"rodata",	/* CC_CONTENT_RODATA */
15907c478bd9Sstevel@tonic-gate 	"anon",		/* CC_CONTENT_ANON */
15917c478bd9Sstevel@tonic-gate 	"shm",		/* CC_CONTENT_SHM */
15927c478bd9Sstevel@tonic-gate 	"ism",		/* CC_CONTENT_ISM */
15937c478bd9Sstevel@tonic-gate 	"dism",		/* CC_CONTENT_DISM */
15947c478bd9Sstevel@tonic-gate 	"ctf",		/* CC_CONTENT_CTF */
15957c478bd9Sstevel@tonic-gate 	"symtab",	/* CC_CONTENT_SYMTAB */
15968e458de0SRobert Mustacchi 	"debug"		/* CC_CONTENT_DEBUG */
15977c478bd9Sstevel@tonic-gate };
15987c478bd9Sstevel@tonic-gate 
15997c478bd9Sstevel@tonic-gate static uint_t ncontent_str = sizeof (content_str) / sizeof (content_str[0]);
16007c478bd9Sstevel@tonic-gate 
16017c478bd9Sstevel@tonic-gate #define	STREQ(a, b, n)	(strlen(b) == (n) && strncmp(a, b, n) == 0)
16027c478bd9Sstevel@tonic-gate 
16037c478bd9Sstevel@tonic-gate int
proc_str2content(const char * str,core_content_t * cp)16047c478bd9Sstevel@tonic-gate proc_str2content(const char *str, core_content_t *cp)
16057c478bd9Sstevel@tonic-gate {
16067c478bd9Sstevel@tonic-gate 	const char *cur = str;
16077c478bd9Sstevel@tonic-gate 	int add = 1;
16087c478bd9Sstevel@tonic-gate 	core_content_t mask, content = 0;
16097c478bd9Sstevel@tonic-gate 
16107c478bd9Sstevel@tonic-gate 	for (;;) {
16117c478bd9Sstevel@tonic-gate 		for (cur = str; isalpha(*cur); cur++)
16127c478bd9Sstevel@tonic-gate 			continue;
16137c478bd9Sstevel@tonic-gate 
16147c478bd9Sstevel@tonic-gate 		if (STREQ(str, "default", cur - str)) {
16157c478bd9Sstevel@tonic-gate 			mask = CC_CONTENT_DEFAULT;
16167c478bd9Sstevel@tonic-gate 		} else if (STREQ(str, "all", cur - str)) {
16177c478bd9Sstevel@tonic-gate 			mask = CC_CONTENT_ALL;
16187c478bd9Sstevel@tonic-gate 		} else if (STREQ(str, "none", cur - str)) {
16197c478bd9Sstevel@tonic-gate 			mask = 0;
16207c478bd9Sstevel@tonic-gate 		} else {
16217c478bd9Sstevel@tonic-gate 			int i = 0;
16227c478bd9Sstevel@tonic-gate 
16237c478bd9Sstevel@tonic-gate 			while (!STREQ(str, content_str[i], cur - str)) {
16247c478bd9Sstevel@tonic-gate 				i++;
16257c478bd9Sstevel@tonic-gate 
16267c478bd9Sstevel@tonic-gate 				if (i >= ncontent_str)
16277c478bd9Sstevel@tonic-gate 					return (-1);
16287c478bd9Sstevel@tonic-gate 			}
16297c478bd9Sstevel@tonic-gate 
16307c478bd9Sstevel@tonic-gate 			mask = (core_content_t)1 << i;
16317c478bd9Sstevel@tonic-gate 		}
16327c478bd9Sstevel@tonic-gate 
16337c478bd9Sstevel@tonic-gate 		if (add)
16347c478bd9Sstevel@tonic-gate 			content |= mask;
16357c478bd9Sstevel@tonic-gate 		else
16367c478bd9Sstevel@tonic-gate 			content &= ~mask;
16377c478bd9Sstevel@tonic-gate 
16387c478bd9Sstevel@tonic-gate 		switch (*cur) {
16397c478bd9Sstevel@tonic-gate 		case '\0':
16407c478bd9Sstevel@tonic-gate 			*cp = content;
16417c478bd9Sstevel@tonic-gate 			return (0);
16427c478bd9Sstevel@tonic-gate 		case '+':
16437c478bd9Sstevel@tonic-gate 			add = 1;
16447c478bd9Sstevel@tonic-gate 			break;
16457c478bd9Sstevel@tonic-gate 		case '-':
16467c478bd9Sstevel@tonic-gate 			add = 0;
16477c478bd9Sstevel@tonic-gate 			break;
16487c478bd9Sstevel@tonic-gate 		default:
16497c478bd9Sstevel@tonic-gate 			return (-1);
16507c478bd9Sstevel@tonic-gate 		}
16517c478bd9Sstevel@tonic-gate 
16527c478bd9Sstevel@tonic-gate 		str = cur + 1;
16537c478bd9Sstevel@tonic-gate 	}
16547c478bd9Sstevel@tonic-gate }
16557c478bd9Sstevel@tonic-gate 
16567c478bd9Sstevel@tonic-gate static int
popc(core_content_t x)16577c478bd9Sstevel@tonic-gate popc(core_content_t x)
16587c478bd9Sstevel@tonic-gate {
16597c478bd9Sstevel@tonic-gate 	int i;
16607c478bd9Sstevel@tonic-gate 
16617c478bd9Sstevel@tonic-gate 	for (i = 0; x != 0; i++)
16627c478bd9Sstevel@tonic-gate 		x &= x - 1;
16637c478bd9Sstevel@tonic-gate 
16647c478bd9Sstevel@tonic-gate 	return (i);
16657c478bd9Sstevel@tonic-gate }
16667c478bd9Sstevel@tonic-gate 
16677c478bd9Sstevel@tonic-gate int
proc_content2str(core_content_t content,char * buf,size_t size)16687c478bd9Sstevel@tonic-gate proc_content2str(core_content_t content, char *buf, size_t size)
16697c478bd9Sstevel@tonic-gate {
16707c478bd9Sstevel@tonic-gate 	int nonecnt, defcnt, allcnt;
16717c478bd9Sstevel@tonic-gate 	core_content_t mask, bit;
16727c478bd9Sstevel@tonic-gate 	int first;
16737c478bd9Sstevel@tonic-gate 	uint_t index;
16747c478bd9Sstevel@tonic-gate 	size_t n, tot = 0;
16757c478bd9Sstevel@tonic-gate 
16767c478bd9Sstevel@tonic-gate 	if (content == 0)
16777c478bd9Sstevel@tonic-gate 		return ((int)strlcpy(buf, "none", size));
16787c478bd9Sstevel@tonic-gate 
16797c478bd9Sstevel@tonic-gate 	if (content & ~CC_CONTENT_ALL)
16807c478bd9Sstevel@tonic-gate 		return ((int)strlcpy(buf, "<invalid>", size));
16817c478bd9Sstevel@tonic-gate 
16827c478bd9Sstevel@tonic-gate 	nonecnt = popc(content);
16837c478bd9Sstevel@tonic-gate 	defcnt = 1 + popc(content ^ CC_CONTENT_DEFAULT);
16847c478bd9Sstevel@tonic-gate 	allcnt = 1 + popc(content ^ CC_CONTENT_ALL);
16857c478bd9Sstevel@tonic-gate 
16867c478bd9Sstevel@tonic-gate 	if (defcnt <= nonecnt && defcnt <= allcnt) {
16877c478bd9Sstevel@tonic-gate 		mask = content ^ CC_CONTENT_DEFAULT;
16887c478bd9Sstevel@tonic-gate 		first = 0;
16897c478bd9Sstevel@tonic-gate 		tot += (n = strlcpy(buf, "default", size));
16907c478bd9Sstevel@tonic-gate 		if (n > size)
16917c478bd9Sstevel@tonic-gate 			n = size;
16927c478bd9Sstevel@tonic-gate 		buf += n;
16937c478bd9Sstevel@tonic-gate 		size -= n;
16947c478bd9Sstevel@tonic-gate 	} else if (allcnt < nonecnt) {
16957c478bd9Sstevel@tonic-gate 		mask = content ^ CC_CONTENT_ALL;
16967c478bd9Sstevel@tonic-gate 		first = 0;
16977c478bd9Sstevel@tonic-gate 		tot += (n = strlcpy(buf, "all", size));
16987c478bd9Sstevel@tonic-gate 		if (n > size)
16997c478bd9Sstevel@tonic-gate 			n = size;
17007c478bd9Sstevel@tonic-gate 		buf += n;
17017c478bd9Sstevel@tonic-gate 		size -= n;
17027c478bd9Sstevel@tonic-gate 	} else {
17037c478bd9Sstevel@tonic-gate 		mask = content;
17047c478bd9Sstevel@tonic-gate 		first = 1;
17057c478bd9Sstevel@tonic-gate 	}
17067c478bd9Sstevel@tonic-gate 
17077c478bd9Sstevel@tonic-gate 	while (mask != 0) {
17087c478bd9Sstevel@tonic-gate 		bit = mask ^ (mask & (mask - 1));
17097c478bd9Sstevel@tonic-gate 
17107c478bd9Sstevel@tonic-gate 		if (!first) {
17117c478bd9Sstevel@tonic-gate 			if (size > 1) {
17127c478bd9Sstevel@tonic-gate 				*buf = (bit & content) ? '+' : '-';
17137c478bd9Sstevel@tonic-gate 				buf++;
17147c478bd9Sstevel@tonic-gate 				size--;
17157c478bd9Sstevel@tonic-gate 			}
17167c478bd9Sstevel@tonic-gate 
17177c478bd9Sstevel@tonic-gate 			tot++;
17187c478bd9Sstevel@tonic-gate 		}
17197c478bd9Sstevel@tonic-gate 		index = popc(bit - 1);
17207c478bd9Sstevel@tonic-gate 		tot += (n = strlcpy(buf, content_str[index], size));
17217c478bd9Sstevel@tonic-gate 		if (n > size)
17227c478bd9Sstevel@tonic-gate 			n = size;
17237c478bd9Sstevel@tonic-gate 		buf += n;
17247c478bd9Sstevel@tonic-gate 		size -= n;
17257c478bd9Sstevel@tonic-gate 
17267c478bd9Sstevel@tonic-gate 		mask ^= bit;
17277c478bd9Sstevel@tonic-gate 		first = 0;
17287c478bd9Sstevel@tonic-gate 	}
17297c478bd9Sstevel@tonic-gate 
17307c478bd9Sstevel@tonic-gate 	return ((int)tot);
17317c478bd9Sstevel@tonic-gate }
1732