xref: /illumos-gate/usr/src/lib/libproc/common/Pgcore.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
30*7c478bd9Sstevel@tonic-gate #include <ctype.h>
31*7c478bd9Sstevel@tonic-gate #include <string.h>
32*7c478bd9Sstevel@tonic-gate #include <strings.h>
33*7c478bd9Sstevel@tonic-gate #include <errno.h>
34*7c478bd9Sstevel@tonic-gate #include <procfs.h>
35*7c478bd9Sstevel@tonic-gate #include <priv.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/elf.h>
37*7c478bd9Sstevel@tonic-gate #include <sys/machelf.h>
38*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
39*7c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
40*7c478bd9Sstevel@tonic-gate #include <sys/proc.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate #include <sys/old_procfs.h>
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate #include "Pcontrol.h"
46*7c478bd9Sstevel@tonic-gate #include "P32ton.h"
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate typedef enum {
49*7c478bd9Sstevel@tonic-gate 	STR_CTF,
50*7c478bd9Sstevel@tonic-gate 	STR_SYMTAB,
51*7c478bd9Sstevel@tonic-gate 	STR_DYNSYM,
52*7c478bd9Sstevel@tonic-gate 	STR_STRTAB,
53*7c478bd9Sstevel@tonic-gate 	STR_DYNSTR,
54*7c478bd9Sstevel@tonic-gate 	STR_SHSTRTAB,
55*7c478bd9Sstevel@tonic-gate 	STR_NUM
56*7c478bd9Sstevel@tonic-gate } shstrtype_t;
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate static const char *shstrtab_data[] = {
59*7c478bd9Sstevel@tonic-gate 	".SUNW_ctf",
60*7c478bd9Sstevel@tonic-gate 	".symtab",
61*7c478bd9Sstevel@tonic-gate 	".dynsym",
62*7c478bd9Sstevel@tonic-gate 	".strtab",
63*7c478bd9Sstevel@tonic-gate 	".dynstr",
64*7c478bd9Sstevel@tonic-gate 	".shstrtab"
65*7c478bd9Sstevel@tonic-gate };
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate typedef struct shstrtab {
68*7c478bd9Sstevel@tonic-gate 	int	sst_ndx[STR_NUM];
69*7c478bd9Sstevel@tonic-gate 	int	sst_cur;
70*7c478bd9Sstevel@tonic-gate } shstrtab_t;
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate typedef struct {
73*7c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P;
74*7c478bd9Sstevel@tonic-gate 	int		pgc_fd;
75*7c478bd9Sstevel@tonic-gate 	off64_t		*pgc_poff;
76*7c478bd9Sstevel@tonic-gate 	off64_t		*pgc_soff;
77*7c478bd9Sstevel@tonic-gate 	off64_t		*pgc_doff;
78*7c478bd9Sstevel@tonic-gate 	core_content_t	pgc_content;
79*7c478bd9Sstevel@tonic-gate 	void		*pgc_chunk;
80*7c478bd9Sstevel@tonic-gate 	size_t		pgc_chunksz;
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate 	shstrtab_t	pgc_shstrtab;
83*7c478bd9Sstevel@tonic-gate } pgcore_t;
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate static void
86*7c478bd9Sstevel@tonic-gate shstrtab_init(shstrtab_t *s)
87*7c478bd9Sstevel@tonic-gate {
88*7c478bd9Sstevel@tonic-gate 	bzero(&s->sst_ndx, sizeof (s->sst_ndx));
89*7c478bd9Sstevel@tonic-gate 	s->sst_cur = 1;
90*7c478bd9Sstevel@tonic-gate }
91*7c478bd9Sstevel@tonic-gate 
92*7c478bd9Sstevel@tonic-gate static int
93*7c478bd9Sstevel@tonic-gate shstrtab_ndx(shstrtab_t *s, shstrtype_t type)
94*7c478bd9Sstevel@tonic-gate {
95*7c478bd9Sstevel@tonic-gate 	int ret;
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate 	if ((ret = s->sst_ndx[type]) != 0)
98*7c478bd9Sstevel@tonic-gate 		return (ret);
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate 	ret = s->sst_ndx[type] = s->sst_cur;
101*7c478bd9Sstevel@tonic-gate 	s->sst_cur += strlen(shstrtab_data[type]) + 1;
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate 	return (ret);
104*7c478bd9Sstevel@tonic-gate }
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate static size_t
107*7c478bd9Sstevel@tonic-gate shstrtab_size(const shstrtab_t *s)
108*7c478bd9Sstevel@tonic-gate {
109*7c478bd9Sstevel@tonic-gate 	return (s->sst_cur);
110*7c478bd9Sstevel@tonic-gate }
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate int
113*7c478bd9Sstevel@tonic-gate Pgcore(struct ps_prochandle *P, const char *fname, core_content_t content)
114*7c478bd9Sstevel@tonic-gate {
115*7c478bd9Sstevel@tonic-gate 	int fd;
116*7c478bd9Sstevel@tonic-gate 	int err;
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate 	if ((fd = creat64(fname, 0666)) < 0)
119*7c478bd9Sstevel@tonic-gate 		return (-1);
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate 	if ((err = Pfgcore(P, fd, content)) != 0) {
122*7c478bd9Sstevel@tonic-gate 		(void) close(fd);
123*7c478bd9Sstevel@tonic-gate 		(void) unlink(fname);
124*7c478bd9Sstevel@tonic-gate 		return (err);
125*7c478bd9Sstevel@tonic-gate 	}
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate 	return (close(fd));
128*7c478bd9Sstevel@tonic-gate }
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate /*
131*7c478bd9Sstevel@tonic-gate  * Since we don't want to use the old-school procfs interfaces, we use the
132*7c478bd9Sstevel@tonic-gate  * new-style data structures we already have to construct the old-style
133*7c478bd9Sstevel@tonic-gate  * data structures. We include these data structures in core files for
134*7c478bd9Sstevel@tonic-gate  * backward compatability.
135*7c478bd9Sstevel@tonic-gate  */
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate static void
138*7c478bd9Sstevel@tonic-gate mkprstatus(struct ps_prochandle *P, const lwpstatus_t *lsp,
139*7c478bd9Sstevel@tonic-gate     const lwpsinfo_t *lip, prstatus_t *psp)
140*7c478bd9Sstevel@tonic-gate {
141*7c478bd9Sstevel@tonic-gate 	bzero(psp, sizeof (*psp));
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_STOPPED)
144*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0001;
145*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ISTOP)
146*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0002;
147*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_DSTOP)
148*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0004;
149*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASLEEP)
150*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0008;
151*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_FORK)
152*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0010;
153*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_RLC)
154*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0020;
155*7c478bd9Sstevel@tonic-gate 	/*
156*7c478bd9Sstevel@tonic-gate 	 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
157*7c478bd9Sstevel@tonic-gate 	 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
158*7c478bd9Sstevel@tonic-gate 	 */
159*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_PCINVAL)
160*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0080;
161*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ISSYS)
162*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0100;
163*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_STEP)
164*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0200;
165*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_KLC)
166*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0400;
167*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASYNC)
168*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0800;
169*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_PTRACE)
170*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x1000;
171*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_MSACCT)
172*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x2000;
173*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_BPTADJ)
174*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x4000;
175*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASLWP)
176*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x8000;
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 	psp->pr_why = lsp->pr_why;
179*7c478bd9Sstevel@tonic-gate 	psp->pr_what = lsp->pr_what;
180*7c478bd9Sstevel@tonic-gate 	psp->pr_info = lsp->pr_info;
181*7c478bd9Sstevel@tonic-gate 	psp->pr_cursig = lsp->pr_cursig;
182*7c478bd9Sstevel@tonic-gate 	psp->pr_nlwp = P->status.pr_nlwp;
183*7c478bd9Sstevel@tonic-gate 	psp->pr_sigpend = P->status.pr_sigpend;
184*7c478bd9Sstevel@tonic-gate 	psp->pr_sighold = lsp->pr_lwphold;
185*7c478bd9Sstevel@tonic-gate 	psp->pr_altstack = lsp->pr_altstack;
186*7c478bd9Sstevel@tonic-gate 	psp->pr_action = lsp->pr_action;
187*7c478bd9Sstevel@tonic-gate 	psp->pr_pid = P->status.pr_pid;
188*7c478bd9Sstevel@tonic-gate 	psp->pr_ppid = P->status.pr_ppid;
189*7c478bd9Sstevel@tonic-gate 	psp->pr_pgrp = P->status.pr_pgid;
190*7c478bd9Sstevel@tonic-gate 	psp->pr_sid = P->status.pr_sid;
191*7c478bd9Sstevel@tonic-gate 	psp->pr_utime = P->status.pr_utime;
192*7c478bd9Sstevel@tonic-gate 	psp->pr_stime = P->status.pr_stime;
193*7c478bd9Sstevel@tonic-gate 	psp->pr_cutime = P->status.pr_cutime;
194*7c478bd9Sstevel@tonic-gate 	psp->pr_cstime = P->status.pr_cstime;
195*7c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
196*7c478bd9Sstevel@tonic-gate 	psp->pr_syscall = lsp->pr_syscall;
197*7c478bd9Sstevel@tonic-gate 	psp->pr_nsysarg = lsp->pr_nsysarg;
198*7c478bd9Sstevel@tonic-gate 	bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg));
199*7c478bd9Sstevel@tonic-gate 	psp->pr_who = lsp->pr_lwpid;
200*7c478bd9Sstevel@tonic-gate 	psp->pr_lwppend = lsp->pr_lwppend;
201*7c478bd9Sstevel@tonic-gate 	psp->pr_oldcontext = (ucontext_t *)lsp->pr_oldcontext;
202*7c478bd9Sstevel@tonic-gate 	psp->pr_brkbase = (caddr_t)P->status.pr_brkbase;
203*7c478bd9Sstevel@tonic-gate 	psp->pr_brksize = P->status.pr_brksize;
204*7c478bd9Sstevel@tonic-gate 	psp->pr_stkbase = (caddr_t)P->status.pr_stkbase;
205*7c478bd9Sstevel@tonic-gate 	psp->pr_stksize = P->status.pr_stksize;
206*7c478bd9Sstevel@tonic-gate 	psp->pr_processor = (short)lip->pr_onpro;
207*7c478bd9Sstevel@tonic-gate 	psp->pr_bind = (short)lip->pr_bindpro;
208*7c478bd9Sstevel@tonic-gate 	psp->pr_instr = lsp->pr_instr;
209*7c478bd9Sstevel@tonic-gate 	bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
210*7c478bd9Sstevel@tonic-gate }
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate static void
213*7c478bd9Sstevel@tonic-gate mkprpsinfo(struct ps_prochandle *P, prpsinfo_t *psp)
214*7c478bd9Sstevel@tonic-gate {
215*7c478bd9Sstevel@tonic-gate 	bzero(psp, sizeof (*psp));
216*7c478bd9Sstevel@tonic-gate 	psp->pr_state = P->psinfo.pr_lwp.pr_state;
217*7c478bd9Sstevel@tonic-gate 	psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
218*7c478bd9Sstevel@tonic-gate 	psp->pr_zomb = (psp->pr_state == SZOMB);
219*7c478bd9Sstevel@tonic-gate 	psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
220*7c478bd9Sstevel@tonic-gate 	psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
221*7c478bd9Sstevel@tonic-gate 	psp->pr_uid = P->psinfo.pr_uid;
222*7c478bd9Sstevel@tonic-gate 	psp->pr_gid = P->psinfo.pr_gid;
223*7c478bd9Sstevel@tonic-gate 	psp->pr_pid = P->psinfo.pr_pid;
224*7c478bd9Sstevel@tonic-gate 	psp->pr_ppid = P->psinfo.pr_ppid;
225*7c478bd9Sstevel@tonic-gate 	psp->pr_pgrp = P->psinfo.pr_pgid;
226*7c478bd9Sstevel@tonic-gate 	psp->pr_sid = P->psinfo.pr_sid;
227*7c478bd9Sstevel@tonic-gate 	psp->pr_addr = (caddr_t)P->psinfo.pr_addr;
228*7c478bd9Sstevel@tonic-gate 	psp->pr_size = P->psinfo.pr_size;
229*7c478bd9Sstevel@tonic-gate 	psp->pr_rssize = P->psinfo.pr_rssize;
230*7c478bd9Sstevel@tonic-gate 	psp->pr_wchan = (caddr_t)P->psinfo.pr_lwp.pr_wchan;
231*7c478bd9Sstevel@tonic-gate 	psp->pr_start = P->psinfo.pr_start;
232*7c478bd9Sstevel@tonic-gate 	psp->pr_time = P->psinfo.pr_time;
233*7c478bd9Sstevel@tonic-gate 	psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
234*7c478bd9Sstevel@tonic-gate 	psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
235*7c478bd9Sstevel@tonic-gate 	psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
236*7c478bd9Sstevel@tonic-gate 	psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
237*7c478bd9Sstevel@tonic-gate 	psp->pr_lttydev = P->psinfo.pr_ttydev;
238*7c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
239*7c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_clname));
240*7c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
241*7c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_fname));
242*7c478bd9Sstevel@tonic-gate 	bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
243*7c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_psargs));
244*7c478bd9Sstevel@tonic-gate 	psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
245*7c478bd9Sstevel@tonic-gate 	psp->pr_ctime = P->psinfo.pr_ctime;
246*7c478bd9Sstevel@tonic-gate 	psp->pr_bysize = psp->pr_size * PAGESIZE;
247*7c478bd9Sstevel@tonic-gate 	psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
248*7c478bd9Sstevel@tonic-gate 	psp->pr_argc = P->psinfo.pr_argc;
249*7c478bd9Sstevel@tonic-gate 	psp->pr_argv = (char **)P->psinfo.pr_argv;
250*7c478bd9Sstevel@tonic-gate 	psp->pr_envp = (char **)P->psinfo.pr_envp;
251*7c478bd9Sstevel@tonic-gate 	psp->pr_wstat = P->psinfo.pr_wstat;
252*7c478bd9Sstevel@tonic-gate 	psp->pr_pctcpu = P->psinfo.pr_pctcpu;
253*7c478bd9Sstevel@tonic-gate 	psp->pr_pctmem = P->psinfo.pr_pctmem;
254*7c478bd9Sstevel@tonic-gate 	psp->pr_euid = P->psinfo.pr_euid;
255*7c478bd9Sstevel@tonic-gate 	psp->pr_egid = P->psinfo.pr_egid;
256*7c478bd9Sstevel@tonic-gate 	psp->pr_aslwpid = 0;
257*7c478bd9Sstevel@tonic-gate 	psp->pr_dmodel = P->psinfo.pr_dmodel;
258*7c478bd9Sstevel@tonic-gate }
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate #ifdef _LP64
261*7c478bd9Sstevel@tonic-gate 
262*7c478bd9Sstevel@tonic-gate static void
263*7c478bd9Sstevel@tonic-gate mkprstatus32(struct ps_prochandle *P, const lwpstatus_t *lsp,
264*7c478bd9Sstevel@tonic-gate     const lwpsinfo_t *lip, prstatus32_t *psp)
265*7c478bd9Sstevel@tonic-gate {
266*7c478bd9Sstevel@tonic-gate 	bzero(psp, sizeof (*psp));
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_STOPPED)
269*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0001;
270*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ISTOP)
271*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0002;
272*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_DSTOP)
273*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0004;
274*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASLEEP)
275*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0008;
276*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_FORK)
277*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0010;
278*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_RLC)
279*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0020;
280*7c478bd9Sstevel@tonic-gate 	/*
281*7c478bd9Sstevel@tonic-gate 	 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
282*7c478bd9Sstevel@tonic-gate 	 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
283*7c478bd9Sstevel@tonic-gate 	 */
284*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_PCINVAL)
285*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0080;
286*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ISSYS)
287*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0100;
288*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_STEP)
289*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0200;
290*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_KLC)
291*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0400;
292*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASYNC)
293*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x0800;
294*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_PTRACE)
295*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x1000;
296*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_MSACCT)
297*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x2000;
298*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_BPTADJ)
299*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x4000;
300*7c478bd9Sstevel@tonic-gate 	if (lsp->pr_flags & PR_ASLWP)
301*7c478bd9Sstevel@tonic-gate 		psp->pr_flags = 0x8000;
302*7c478bd9Sstevel@tonic-gate 
303*7c478bd9Sstevel@tonic-gate 	psp->pr_why = lsp->pr_why;
304*7c478bd9Sstevel@tonic-gate 	psp->pr_what = lsp->pr_what;
305*7c478bd9Sstevel@tonic-gate 	siginfo_n_to_32(&lsp->pr_info, &psp->pr_info);
306*7c478bd9Sstevel@tonic-gate 	psp->pr_cursig = lsp->pr_cursig;
307*7c478bd9Sstevel@tonic-gate 	psp->pr_nlwp = P->status.pr_nlwp;
308*7c478bd9Sstevel@tonic-gate 	psp->pr_sigpend = P->status.pr_sigpend;
309*7c478bd9Sstevel@tonic-gate 	psp->pr_sighold = lsp->pr_lwphold;
310*7c478bd9Sstevel@tonic-gate 	stack_n_to_32(&lsp->pr_altstack, &psp->pr_altstack);
311*7c478bd9Sstevel@tonic-gate 	sigaction_n_to_32(&lsp->pr_action, &psp->pr_action);
312*7c478bd9Sstevel@tonic-gate 	psp->pr_pid = P->status.pr_pid;
313*7c478bd9Sstevel@tonic-gate 	psp->pr_ppid = P->status.pr_ppid;
314*7c478bd9Sstevel@tonic-gate 	psp->pr_pgrp = P->status.pr_pgid;
315*7c478bd9Sstevel@tonic-gate 	psp->pr_sid = P->status.pr_sid;
316*7c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->status.pr_utime, &psp->pr_utime);
317*7c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->status.pr_stime, &psp->pr_stime);
318*7c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->status.pr_cutime, &psp->pr_cutime);
319*7c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->status.pr_cstime, &psp->pr_cstime);
320*7c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
321*7c478bd9Sstevel@tonic-gate 	psp->pr_syscall = lsp->pr_syscall;
322*7c478bd9Sstevel@tonic-gate 	psp->pr_nsysarg = lsp->pr_nsysarg;
323*7c478bd9Sstevel@tonic-gate 	bcopy(lsp->pr_sysarg, psp->pr_sysarg,
324*7c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_sysarg)); psp->pr_who = lsp->pr_lwpid;
325*7c478bd9Sstevel@tonic-gate 	psp->pr_lwppend = lsp->pr_lwppend;
326*7c478bd9Sstevel@tonic-gate 	psp->pr_oldcontext = (caddr32_t)lsp->pr_oldcontext;
327*7c478bd9Sstevel@tonic-gate 	psp->pr_brkbase = (caddr32_t)P->status.pr_brkbase;
328*7c478bd9Sstevel@tonic-gate 	psp->pr_brksize = P->status.pr_brksize;
329*7c478bd9Sstevel@tonic-gate 	psp->pr_stkbase = (caddr32_t)P->status.pr_stkbase;
330*7c478bd9Sstevel@tonic-gate 	psp->pr_stksize = P->status.pr_stksize;
331*7c478bd9Sstevel@tonic-gate 	psp->pr_processor = (short)lip->pr_onpro;
332*7c478bd9Sstevel@tonic-gate 	psp->pr_bind = (short)lip->pr_bindpro;
333*7c478bd9Sstevel@tonic-gate 	psp->pr_instr = lsp->pr_instr;
334*7c478bd9Sstevel@tonic-gate 	bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
335*7c478bd9Sstevel@tonic-gate }
336*7c478bd9Sstevel@tonic-gate 
337*7c478bd9Sstevel@tonic-gate static void
338*7c478bd9Sstevel@tonic-gate mkprpsinfo32(struct ps_prochandle *P, prpsinfo32_t *psp)
339*7c478bd9Sstevel@tonic-gate {
340*7c478bd9Sstevel@tonic-gate 	bzero(psp, sizeof (*psp));
341*7c478bd9Sstevel@tonic-gate 	psp->pr_state = P->psinfo.pr_lwp.pr_state;
342*7c478bd9Sstevel@tonic-gate 	psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
343*7c478bd9Sstevel@tonic-gate 	psp->pr_zomb = (psp->pr_state == SZOMB);
344*7c478bd9Sstevel@tonic-gate 	psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
345*7c478bd9Sstevel@tonic-gate 	psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
346*7c478bd9Sstevel@tonic-gate 	psp->pr_uid = P->psinfo.pr_uid;
347*7c478bd9Sstevel@tonic-gate 	psp->pr_gid = P->psinfo.pr_gid;
348*7c478bd9Sstevel@tonic-gate 	psp->pr_pid = P->psinfo.pr_pid;
349*7c478bd9Sstevel@tonic-gate 	psp->pr_ppid = P->psinfo.pr_ppid;
350*7c478bd9Sstevel@tonic-gate 	psp->pr_pgrp = P->psinfo.pr_pgid;
351*7c478bd9Sstevel@tonic-gate 	psp->pr_sid = P->psinfo.pr_sid;
352*7c478bd9Sstevel@tonic-gate 	psp->pr_addr = (caddr32_t)P->psinfo.pr_addr;
353*7c478bd9Sstevel@tonic-gate 	psp->pr_size = P->psinfo.pr_size;
354*7c478bd9Sstevel@tonic-gate 	psp->pr_rssize = P->psinfo.pr_rssize;
355*7c478bd9Sstevel@tonic-gate 	psp->pr_wchan = (caddr32_t)P->psinfo.pr_lwp.pr_wchan;
356*7c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->psinfo.pr_start, &psp->pr_start);
357*7c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->psinfo.pr_time, &psp->pr_time);
358*7c478bd9Sstevel@tonic-gate 	psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
359*7c478bd9Sstevel@tonic-gate 	psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
360*7c478bd9Sstevel@tonic-gate 	psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
361*7c478bd9Sstevel@tonic-gate 	psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
362*7c478bd9Sstevel@tonic-gate 	psp->pr_lttydev = prcmpldev(P->psinfo.pr_ttydev);
363*7c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
364*7c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_clname));
365*7c478bd9Sstevel@tonic-gate 	(void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
366*7c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_fname));
367*7c478bd9Sstevel@tonic-gate 	bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
368*7c478bd9Sstevel@tonic-gate 	    sizeof (psp->pr_psargs));
369*7c478bd9Sstevel@tonic-gate 	psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
370*7c478bd9Sstevel@tonic-gate 	timestruc_n_to_32(&P->psinfo.pr_ctime, &psp->pr_ctime);
371*7c478bd9Sstevel@tonic-gate 	psp->pr_bysize = psp->pr_size * PAGESIZE;
372*7c478bd9Sstevel@tonic-gate 	psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
373*7c478bd9Sstevel@tonic-gate 	psp->pr_argc = P->psinfo.pr_argc;
374*7c478bd9Sstevel@tonic-gate 	psp->pr_argv = (caddr32_t)P->psinfo.pr_argv;
375*7c478bd9Sstevel@tonic-gate 	psp->pr_envp = (caddr32_t)P->psinfo.pr_envp;
376*7c478bd9Sstevel@tonic-gate 	psp->pr_wstat = P->psinfo.pr_wstat;
377*7c478bd9Sstevel@tonic-gate 	psp->pr_pctcpu = P->psinfo.pr_pctcpu;
378*7c478bd9Sstevel@tonic-gate 	psp->pr_pctmem = P->psinfo.pr_pctmem;
379*7c478bd9Sstevel@tonic-gate 	psp->pr_euid = P->psinfo.pr_euid;
380*7c478bd9Sstevel@tonic-gate 	psp->pr_egid = P->psinfo.pr_egid;
381*7c478bd9Sstevel@tonic-gate 	psp->pr_aslwpid = 0;
382*7c478bd9Sstevel@tonic-gate 	psp->pr_dmodel = P->psinfo.pr_dmodel;
383*7c478bd9Sstevel@tonic-gate }
384*7c478bd9Sstevel@tonic-gate 
385*7c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
386*7c478bd9Sstevel@tonic-gate 
387*7c478bd9Sstevel@tonic-gate static int
388*7c478bd9Sstevel@tonic-gate write_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp)
389*7c478bd9Sstevel@tonic-gate {
390*7c478bd9Sstevel@tonic-gate 	/*
391*7c478bd9Sstevel@tonic-gate 	 * Note headers are the same regardless of the data model of the
392*7c478bd9Sstevel@tonic-gate 	 * ELF file; we arbitrarily use Elf64_Nhdr here.
393*7c478bd9Sstevel@tonic-gate 	 */
394*7c478bd9Sstevel@tonic-gate 	struct {
395*7c478bd9Sstevel@tonic-gate 		Elf64_Nhdr nhdr;
396*7c478bd9Sstevel@tonic-gate 		char name[8];
397*7c478bd9Sstevel@tonic-gate 	} n;
398*7c478bd9Sstevel@tonic-gate 
399*7c478bd9Sstevel@tonic-gate 	bzero(&n, sizeof (n));
400*7c478bd9Sstevel@tonic-gate 	bcopy("CORE", n.name, 4);
401*7c478bd9Sstevel@tonic-gate 	n.nhdr.n_type = type;
402*7c478bd9Sstevel@tonic-gate 	n.nhdr.n_namesz = 5;
403*7c478bd9Sstevel@tonic-gate 	n.nhdr.n_descsz = roundup(descsz, 4);
404*7c478bd9Sstevel@tonic-gate 
405*7c478bd9Sstevel@tonic-gate 	if (pwrite64(fd, &n, sizeof (n), *offp) != sizeof (n))
406*7c478bd9Sstevel@tonic-gate 		return (-1);
407*7c478bd9Sstevel@tonic-gate 
408*7c478bd9Sstevel@tonic-gate 	*offp += sizeof (n);
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate 	if (pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != n.nhdr.n_descsz)
411*7c478bd9Sstevel@tonic-gate 		return (-1);
412*7c478bd9Sstevel@tonic-gate 
413*7c478bd9Sstevel@tonic-gate 	*offp += n.nhdr.n_descsz;
414*7c478bd9Sstevel@tonic-gate 
415*7c478bd9Sstevel@tonic-gate 	return (0);
416*7c478bd9Sstevel@tonic-gate }
417*7c478bd9Sstevel@tonic-gate 
418*7c478bd9Sstevel@tonic-gate static int
419*7c478bd9Sstevel@tonic-gate old_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
420*7c478bd9Sstevel@tonic-gate {
421*7c478bd9Sstevel@tonic-gate 	pgcore_t *pgc = data;
422*7c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P = pgc->P;
423*7c478bd9Sstevel@tonic-gate 
424*7c478bd9Sstevel@tonic-gate 	/*
425*7c478bd9Sstevel@tonic-gate 	 * Legacy core files don't contain information about zombie LWPs.
426*7c478bd9Sstevel@tonic-gate 	 * We use Plwp_iter_all() so that we get the lwpsinfo_t structure
427*7c478bd9Sstevel@tonic-gate 	 * more cheaply.
428*7c478bd9Sstevel@tonic-gate 	 */
429*7c478bd9Sstevel@tonic-gate 	if (lsp == NULL)
430*7c478bd9Sstevel@tonic-gate 		return (0);
431*7c478bd9Sstevel@tonic-gate 
432*7c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
433*7c478bd9Sstevel@tonic-gate 		prstatus_t prstatus;
434*7c478bd9Sstevel@tonic-gate 		mkprstatus(P, lsp, lip, &prstatus);
435*7c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_PRSTATUS, &prstatus,
436*7c478bd9Sstevel@tonic-gate 		    sizeof (prstatus_t), pgc->pgc_doff) != 0)
437*7c478bd9Sstevel@tonic-gate 			return (0);
438*7c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_PRFPREG, &lsp->pr_fpreg,
439*7c478bd9Sstevel@tonic-gate 		    sizeof (prfpregset_t), pgc->pgc_doff) != 0)
440*7c478bd9Sstevel@tonic-gate 			return (1);
441*7c478bd9Sstevel@tonic-gate #ifdef _LP64
442*7c478bd9Sstevel@tonic-gate 	} else {
443*7c478bd9Sstevel@tonic-gate 		prstatus32_t pr32;
444*7c478bd9Sstevel@tonic-gate 		prfpregset32_t pf32;
445*7c478bd9Sstevel@tonic-gate 		mkprstatus32(P, lsp, lip, &pr32);
446*7c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_PRSTATUS, &pr32,
447*7c478bd9Sstevel@tonic-gate 		    sizeof (prstatus32_t), pgc->pgc_doff) != 0)
448*7c478bd9Sstevel@tonic-gate 			return (1);
449*7c478bd9Sstevel@tonic-gate 		prfpregset_n_to_32(&lsp->pr_fpreg, &pf32);
450*7c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_PRFPREG, &pf32,
451*7c478bd9Sstevel@tonic-gate 		    sizeof (prfpregset32_t), pgc->pgc_doff) != 0)
452*7c478bd9Sstevel@tonic-gate 			return (1);
453*7c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
454*7c478bd9Sstevel@tonic-gate 	}
455*7c478bd9Sstevel@tonic-gate 
456*7c478bd9Sstevel@tonic-gate #ifdef sparc
457*7c478bd9Sstevel@tonic-gate 	{
458*7c478bd9Sstevel@tonic-gate 		prxregset_t xregs;
459*7c478bd9Sstevel@tonic-gate 		if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0 &&
460*7c478bd9Sstevel@tonic-gate 		    write_note(pgc->pgc_fd, NT_PRXREG, &xregs,
461*7c478bd9Sstevel@tonic-gate 		    sizeof (prxregset_t), pgc->pgc_doff) != 0)
462*7c478bd9Sstevel@tonic-gate 			return (1);
463*7c478bd9Sstevel@tonic-gate 	}
464*7c478bd9Sstevel@tonic-gate #endif	/* sparc */
465*7c478bd9Sstevel@tonic-gate 
466*7c478bd9Sstevel@tonic-gate 	return (0);
467*7c478bd9Sstevel@tonic-gate }
468*7c478bd9Sstevel@tonic-gate 
469*7c478bd9Sstevel@tonic-gate static int
470*7c478bd9Sstevel@tonic-gate new_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
471*7c478bd9Sstevel@tonic-gate {
472*7c478bd9Sstevel@tonic-gate 	pgcore_t *pgc = data;
473*7c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P = pgc->P;
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate 	/*
476*7c478bd9Sstevel@tonic-gate 	 * If lsp is NULL this indicates that this is a zombie LWP in
477*7c478bd9Sstevel@tonic-gate 	 * which case we dump only the lwpsinfo_t structure and none of
478*7c478bd9Sstevel@tonic-gate 	 * the other ancillary LWP state data.
479*7c478bd9Sstevel@tonic-gate 	 */
480*7c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
481*7c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip,
482*7c478bd9Sstevel@tonic-gate 		    sizeof (lwpsinfo_t), pgc->pgc_doff) != 0)
483*7c478bd9Sstevel@tonic-gate 			return (1);
484*7c478bd9Sstevel@tonic-gate 		if (lsp == NULL)
485*7c478bd9Sstevel@tonic-gate 			return (0);
486*7c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp,
487*7c478bd9Sstevel@tonic-gate 		    sizeof (lwpstatus_t), pgc->pgc_doff) != 0)
488*7c478bd9Sstevel@tonic-gate 			return (1);
489*7c478bd9Sstevel@tonic-gate #ifdef _LP64
490*7c478bd9Sstevel@tonic-gate 	} else {
491*7c478bd9Sstevel@tonic-gate 		lwpsinfo32_t li32;
492*7c478bd9Sstevel@tonic-gate 		lwpstatus32_t ls32;
493*7c478bd9Sstevel@tonic-gate 		lwpsinfo_n_to_32(lip, &li32);
494*7c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32,
495*7c478bd9Sstevel@tonic-gate 		    sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0)
496*7c478bd9Sstevel@tonic-gate 			return (1);
497*7c478bd9Sstevel@tonic-gate 		if (lsp == NULL)
498*7c478bd9Sstevel@tonic-gate 			return (0);
499*7c478bd9Sstevel@tonic-gate 		lwpstatus_n_to_32(lsp, &ls32);
500*7c478bd9Sstevel@tonic-gate 		if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32,
501*7c478bd9Sstevel@tonic-gate 		    sizeof (lwpstatus32_t), pgc->pgc_doff) != 0)
502*7c478bd9Sstevel@tonic-gate 			return (1);
503*7c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
504*7c478bd9Sstevel@tonic-gate 	}
505*7c478bd9Sstevel@tonic-gate 
506*7c478bd9Sstevel@tonic-gate #ifdef sparc
507*7c478bd9Sstevel@tonic-gate 	{
508*7c478bd9Sstevel@tonic-gate 		prxregset_t xregs;
509*7c478bd9Sstevel@tonic-gate 		gwindows_t gwins;
510*7c478bd9Sstevel@tonic-gate 		size_t size;
511*7c478bd9Sstevel@tonic-gate 
512*7c478bd9Sstevel@tonic-gate 		if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0) {
513*7c478bd9Sstevel@tonic-gate 			if (write_note(pgc->pgc_fd, NT_PRXREG, &xregs,
514*7c478bd9Sstevel@tonic-gate 			    sizeof (prxregset_t), pgc->pgc_doff) != 0)
515*7c478bd9Sstevel@tonic-gate 				return (1);
516*7c478bd9Sstevel@tonic-gate 		}
517*7c478bd9Sstevel@tonic-gate 
518*7c478bd9Sstevel@tonic-gate 		if (Plwp_getgwindows(P, lsp->pr_lwpid, &gwins) == 0 &&
519*7c478bd9Sstevel@tonic-gate 		    gwins.wbcnt > 0) {
520*7c478bd9Sstevel@tonic-gate 			size = sizeof (gwins) - sizeof (gwins.wbuf) +
521*7c478bd9Sstevel@tonic-gate 			    gwins.wbcnt * sizeof (gwins.wbuf[0]);
522*7c478bd9Sstevel@tonic-gate 
523*7c478bd9Sstevel@tonic-gate 			if (write_note(pgc->pgc_fd, NT_GWINDOWS, &gwins, size,
524*7c478bd9Sstevel@tonic-gate 			    pgc->pgc_doff) != 0)
525*7c478bd9Sstevel@tonic-gate 				return (1);
526*7c478bd9Sstevel@tonic-gate 		}
527*7c478bd9Sstevel@tonic-gate 
528*7c478bd9Sstevel@tonic-gate 	}
529*7c478bd9Sstevel@tonic-gate #ifdef __sparcv9
530*7c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_LP64) {
531*7c478bd9Sstevel@tonic-gate 		asrset_t asrs;
532*7c478bd9Sstevel@tonic-gate 		if (Plwp_getasrs(P, lsp->pr_lwpid, asrs) == 0) {
533*7c478bd9Sstevel@tonic-gate 			if (write_note(pgc->pgc_fd, NT_ASRS, &asrs,
534*7c478bd9Sstevel@tonic-gate 			    sizeof (asrset_t), pgc->pgc_doff) != 0)
535*7c478bd9Sstevel@tonic-gate 				return (1);
536*7c478bd9Sstevel@tonic-gate 		}
537*7c478bd9Sstevel@tonic-gate 	}
538*7c478bd9Sstevel@tonic-gate #endif	/* __sparcv9 */
539*7c478bd9Sstevel@tonic-gate #endif	/* sparc */
540*7c478bd9Sstevel@tonic-gate 
541*7c478bd9Sstevel@tonic-gate 	return (0);
542*7c478bd9Sstevel@tonic-gate }
543*7c478bd9Sstevel@tonic-gate 
544*7c478bd9Sstevel@tonic-gate static uint_t
545*7c478bd9Sstevel@tonic-gate count_sections(pgcore_t *pgc)
546*7c478bd9Sstevel@tonic-gate {
547*7c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P = pgc->P;
548*7c478bd9Sstevel@tonic-gate 	file_info_t *fptr;
549*7c478bd9Sstevel@tonic-gate 	uint_t cnt;
550*7c478bd9Sstevel@tonic-gate 	uint_t nshdrs = 0;
551*7c478bd9Sstevel@tonic-gate 
552*7c478bd9Sstevel@tonic-gate 	if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)))
553*7c478bd9Sstevel@tonic-gate 		return (0);
554*7c478bd9Sstevel@tonic-gate 
555*7c478bd9Sstevel@tonic-gate 	fptr = list_next(&P->file_head);
556*7c478bd9Sstevel@tonic-gate 	for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) {
557*7c478bd9Sstevel@tonic-gate 		int hit_symtab = 0;
558*7c478bd9Sstevel@tonic-gate 
559*7c478bd9Sstevel@tonic-gate 		Pbuild_file_symtab(P, fptr);
560*7c478bd9Sstevel@tonic-gate 
561*7c478bd9Sstevel@tonic-gate 		if ((pgc->pgc_content & CC_CONTENT_CTF) &&
562*7c478bd9Sstevel@tonic-gate 		    Pbuild_file_ctf(P, fptr) != NULL) {
563*7c478bd9Sstevel@tonic-gate 			sym_tbl_t *sym;
564*7c478bd9Sstevel@tonic-gate 
565*7c478bd9Sstevel@tonic-gate 			nshdrs++;
566*7c478bd9Sstevel@tonic-gate 
567*7c478bd9Sstevel@tonic-gate 			if (fptr->file_ctf_dyn) {
568*7c478bd9Sstevel@tonic-gate 				sym = &fptr->file_dynsym;
569*7c478bd9Sstevel@tonic-gate 			} else {
570*7c478bd9Sstevel@tonic-gate 				sym = &fptr->file_symtab;
571*7c478bd9Sstevel@tonic-gate 				hit_symtab = 1;
572*7c478bd9Sstevel@tonic-gate 			}
573*7c478bd9Sstevel@tonic-gate 
574*7c478bd9Sstevel@tonic-gate 			if (sym->sym_data != NULL && sym->sym_symn != 0 &&
575*7c478bd9Sstevel@tonic-gate 			    sym->sym_strs != NULL)
576*7c478bd9Sstevel@tonic-gate 				nshdrs += 2;
577*7c478bd9Sstevel@tonic-gate 		}
578*7c478bd9Sstevel@tonic-gate 
579*7c478bd9Sstevel@tonic-gate 		if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
580*7c478bd9Sstevel@tonic-gate 		    fptr->file_symtab.sym_data != NULL &&
581*7c478bd9Sstevel@tonic-gate 		    fptr->file_symtab.sym_symn != 0 &&
582*7c478bd9Sstevel@tonic-gate 		    fptr->file_symtab.sym_strs != NULL) {
583*7c478bd9Sstevel@tonic-gate 			nshdrs += 2;
584*7c478bd9Sstevel@tonic-gate 		}
585*7c478bd9Sstevel@tonic-gate 	}
586*7c478bd9Sstevel@tonic-gate 
587*7c478bd9Sstevel@tonic-gate 	return (nshdrs == 0 ? 0 : nshdrs + 2);
588*7c478bd9Sstevel@tonic-gate }
589*7c478bd9Sstevel@tonic-gate 
590*7c478bd9Sstevel@tonic-gate static int
591*7c478bd9Sstevel@tonic-gate write_shdr(pgcore_t *pgc, shstrtype_t name, uint_t type, ulong_t flags,
592*7c478bd9Sstevel@tonic-gate     uintptr_t addr, ulong_t offset, size_t size, uint_t link, uint_t info,
593*7c478bd9Sstevel@tonic-gate     uintptr_t addralign, uintptr_t entsize)
594*7c478bd9Sstevel@tonic-gate {
595*7c478bd9Sstevel@tonic-gate 	if (pgc->P->status.pr_dmodel == PR_MODEL_ILP32) {
596*7c478bd9Sstevel@tonic-gate 		Elf32_Shdr shdr;
597*7c478bd9Sstevel@tonic-gate 
598*7c478bd9Sstevel@tonic-gate 		bzero(&shdr, sizeof (shdr));
599*7c478bd9Sstevel@tonic-gate 		shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name);
600*7c478bd9Sstevel@tonic-gate 		shdr.sh_type = type;
601*7c478bd9Sstevel@tonic-gate 		shdr.sh_flags = flags;
602*7c478bd9Sstevel@tonic-gate 		shdr.sh_addr = (Elf32_Addr)addr;
603*7c478bd9Sstevel@tonic-gate 		shdr.sh_offset = offset;
604*7c478bd9Sstevel@tonic-gate 		shdr.sh_size = size;
605*7c478bd9Sstevel@tonic-gate 		shdr.sh_link = link;
606*7c478bd9Sstevel@tonic-gate 		shdr.sh_info = info;
607*7c478bd9Sstevel@tonic-gate 		shdr.sh_addralign = addralign;
608*7c478bd9Sstevel@tonic-gate 		shdr.sh_entsize = entsize;
609*7c478bd9Sstevel@tonic-gate 
610*7c478bd9Sstevel@tonic-gate 		if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
611*7c478bd9Sstevel@tonic-gate 		    *pgc->pgc_soff) != sizeof (shdr))
612*7c478bd9Sstevel@tonic-gate 			return (-1);
613*7c478bd9Sstevel@tonic-gate 
614*7c478bd9Sstevel@tonic-gate 		*pgc->pgc_soff += sizeof (shdr);
615*7c478bd9Sstevel@tonic-gate #ifdef _LP64
616*7c478bd9Sstevel@tonic-gate 	} else {
617*7c478bd9Sstevel@tonic-gate 		Elf64_Shdr shdr;
618*7c478bd9Sstevel@tonic-gate 
619*7c478bd9Sstevel@tonic-gate 		bzero(&shdr, sizeof (shdr));
620*7c478bd9Sstevel@tonic-gate 		shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name);
621*7c478bd9Sstevel@tonic-gate 		shdr.sh_type = type;
622*7c478bd9Sstevel@tonic-gate 		shdr.sh_flags = flags;
623*7c478bd9Sstevel@tonic-gate 		shdr.sh_addr = addr;
624*7c478bd9Sstevel@tonic-gate 		shdr.sh_offset = offset;
625*7c478bd9Sstevel@tonic-gate 		shdr.sh_size = size;
626*7c478bd9Sstevel@tonic-gate 		shdr.sh_link = link;
627*7c478bd9Sstevel@tonic-gate 		shdr.sh_info = info;
628*7c478bd9Sstevel@tonic-gate 		shdr.sh_addralign = addralign;
629*7c478bd9Sstevel@tonic-gate 		shdr.sh_entsize = entsize;
630*7c478bd9Sstevel@tonic-gate 
631*7c478bd9Sstevel@tonic-gate 		if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
632*7c478bd9Sstevel@tonic-gate 		    *pgc->pgc_soff) != sizeof (shdr))
633*7c478bd9Sstevel@tonic-gate 			return (-1);
634*7c478bd9Sstevel@tonic-gate 
635*7c478bd9Sstevel@tonic-gate 		*pgc->pgc_soff += sizeof (shdr);
636*7c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
637*7c478bd9Sstevel@tonic-gate 	}
638*7c478bd9Sstevel@tonic-gate 
639*7c478bd9Sstevel@tonic-gate 	return (0);
640*7c478bd9Sstevel@tonic-gate }
641*7c478bd9Sstevel@tonic-gate 
642*7c478bd9Sstevel@tonic-gate static int
643*7c478bd9Sstevel@tonic-gate dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym)
644*7c478bd9Sstevel@tonic-gate {
645*7c478bd9Sstevel@tonic-gate 	sym_tbl_t *sym = dynsym ? &fptr->file_dynsym : &fptr->file_symtab;
646*7c478bd9Sstevel@tonic-gate 	shstrtype_t symname = dynsym ? STR_DYNSYM : STR_SYMTAB;
647*7c478bd9Sstevel@tonic-gate 	shstrtype_t strname = dynsym ? STR_DYNSTR : STR_STRTAB;
648*7c478bd9Sstevel@tonic-gate 	uint_t symtype = dynsym ? SHT_DYNSYM : SHT_SYMTAB;
649*7c478bd9Sstevel@tonic-gate 	size_t size;
650*7c478bd9Sstevel@tonic-gate 	uintptr_t addr = fptr->file_map->map_pmap.pr_vaddr;
651*7c478bd9Sstevel@tonic-gate 
652*7c478bd9Sstevel@tonic-gate 	if (sym->sym_data == NULL || sym->sym_symn == 0 ||
653*7c478bd9Sstevel@tonic-gate 	    sym->sym_strs == NULL)
654*7c478bd9Sstevel@tonic-gate 		return (0);
655*7c478bd9Sstevel@tonic-gate 
656*7c478bd9Sstevel@tonic-gate 	size = sym->sym_hdr.sh_size;
657*7c478bd9Sstevel@tonic-gate 	if (pwrite64(pgc->pgc_fd, sym->sym_data->d_buf, size,
658*7c478bd9Sstevel@tonic-gate 	    *pgc->pgc_doff) != size)
659*7c478bd9Sstevel@tonic-gate 		return (-1);
660*7c478bd9Sstevel@tonic-gate 
661*7c478bd9Sstevel@tonic-gate 	if (write_shdr(pgc, symname, symtype, 0, addr, *pgc->pgc_doff, size,
662*7c478bd9Sstevel@tonic-gate 	    index + 1, sym->sym_hdr.sh_info, sym->sym_hdr.sh_addralign,
663*7c478bd9Sstevel@tonic-gate 	    sym->sym_hdr.sh_entsize) != 0)
664*7c478bd9Sstevel@tonic-gate 		return (-1);
665*7c478bd9Sstevel@tonic-gate 
666*7c478bd9Sstevel@tonic-gate 	*pgc->pgc_doff += roundup(size, 8);
667*7c478bd9Sstevel@tonic-gate 
668*7c478bd9Sstevel@tonic-gate 	size = sym->sym_strhdr.sh_size;
669*7c478bd9Sstevel@tonic-gate 	if (pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != size)
670*7c478bd9Sstevel@tonic-gate 		return (-1);
671*7c478bd9Sstevel@tonic-gate 
672*7c478bd9Sstevel@tonic-gate 	if (write_shdr(pgc, strname, SHT_STRTAB, SHF_STRINGS, addr,
673*7c478bd9Sstevel@tonic-gate 	    *pgc->pgc_doff, size, 0, 0, 1, 0) != 0)
674*7c478bd9Sstevel@tonic-gate 		return (-1);
675*7c478bd9Sstevel@tonic-gate 
676*7c478bd9Sstevel@tonic-gate 	*pgc->pgc_doff += roundup(size, 8);
677*7c478bd9Sstevel@tonic-gate 
678*7c478bd9Sstevel@tonic-gate 	return (0);
679*7c478bd9Sstevel@tonic-gate }
680*7c478bd9Sstevel@tonic-gate 
681*7c478bd9Sstevel@tonic-gate static int
682*7c478bd9Sstevel@tonic-gate dump_sections(pgcore_t *pgc)
683*7c478bd9Sstevel@tonic-gate {
684*7c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P = pgc->P;
685*7c478bd9Sstevel@tonic-gate 	file_info_t *fptr;
686*7c478bd9Sstevel@tonic-gate 	uint_t cnt;
687*7c478bd9Sstevel@tonic-gate 	uint_t index = 1;
688*7c478bd9Sstevel@tonic-gate 
689*7c478bd9Sstevel@tonic-gate 	if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)))
690*7c478bd9Sstevel@tonic-gate 		return (0);
691*7c478bd9Sstevel@tonic-gate 
692*7c478bd9Sstevel@tonic-gate 	fptr = list_next(&P->file_head);
693*7c478bd9Sstevel@tonic-gate 	for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) {
694*7c478bd9Sstevel@tonic-gate 		int hit_symtab = 0;
695*7c478bd9Sstevel@tonic-gate 
696*7c478bd9Sstevel@tonic-gate 		Pbuild_file_symtab(P, fptr);
697*7c478bd9Sstevel@tonic-gate 
698*7c478bd9Sstevel@tonic-gate 		if ((pgc->pgc_content & CC_CONTENT_CTF) &&
699*7c478bd9Sstevel@tonic-gate 		    Pbuild_file_ctf(P, fptr) != NULL) {
700*7c478bd9Sstevel@tonic-gate 			sym_tbl_t *sym;
701*7c478bd9Sstevel@tonic-gate 			uint_t dynsym;
702*7c478bd9Sstevel@tonic-gate 			uint_t symindex = 0;
703*7c478bd9Sstevel@tonic-gate 
704*7c478bd9Sstevel@tonic-gate 			/*
705*7c478bd9Sstevel@tonic-gate 			 * Write the symtab out first so we can correctly
706*7c478bd9Sstevel@tonic-gate 			 * set the sh_link field in the CTF section header.
707*7c478bd9Sstevel@tonic-gate 			 * symindex will be 0 if there is no corresponding
708*7c478bd9Sstevel@tonic-gate 			 * symbol table section.
709*7c478bd9Sstevel@tonic-gate 			 */
710*7c478bd9Sstevel@tonic-gate 			if (fptr->file_ctf_dyn) {
711*7c478bd9Sstevel@tonic-gate 				sym = &fptr->file_dynsym;
712*7c478bd9Sstevel@tonic-gate 				dynsym = 1;
713*7c478bd9Sstevel@tonic-gate 			} else {
714*7c478bd9Sstevel@tonic-gate 				sym = &fptr->file_symtab;
715*7c478bd9Sstevel@tonic-gate 				dynsym = 0;
716*7c478bd9Sstevel@tonic-gate 				hit_symtab = 1;
717*7c478bd9Sstevel@tonic-gate 			}
718*7c478bd9Sstevel@tonic-gate 
719*7c478bd9Sstevel@tonic-gate 			if (sym->sym_data != NULL && sym->sym_symn != 0 &&
720*7c478bd9Sstevel@tonic-gate 			    sym->sym_strs != NULL) {
721*7c478bd9Sstevel@tonic-gate 				symindex = index;
722*7c478bd9Sstevel@tonic-gate 				if (dump_symtab(pgc, fptr, index, dynsym) != 0)
723*7c478bd9Sstevel@tonic-gate 				    return (-1);
724*7c478bd9Sstevel@tonic-gate 				index += 2;
725*7c478bd9Sstevel@tonic-gate 			}
726*7c478bd9Sstevel@tonic-gate 
727*7c478bd9Sstevel@tonic-gate 			/*
728*7c478bd9Sstevel@tonic-gate 			 * Write the CTF data that we've read out of the
729*7c478bd9Sstevel@tonic-gate 			 * file itself into the core file.
730*7c478bd9Sstevel@tonic-gate 			 */
731*7c478bd9Sstevel@tonic-gate 			if (pwrite64(pgc->pgc_fd, fptr->file_ctf_buf,
732*7c478bd9Sstevel@tonic-gate 			    fptr->file_ctf_size, *pgc->pgc_doff) !=
733*7c478bd9Sstevel@tonic-gate 			    fptr->file_ctf_size)
734*7c478bd9Sstevel@tonic-gate 				return (-1);
735*7c478bd9Sstevel@tonic-gate 
736*7c478bd9Sstevel@tonic-gate 			if (write_shdr(pgc, STR_CTF, SHT_PROGBITS, 0,
737*7c478bd9Sstevel@tonic-gate 			    fptr->file_map->map_pmap.pr_vaddr, *pgc->pgc_doff,
738*7c478bd9Sstevel@tonic-gate 			    fptr->file_ctf_size, symindex, 0, 4, 0) != 0)
739*7c478bd9Sstevel@tonic-gate 				return (-1);
740*7c478bd9Sstevel@tonic-gate 
741*7c478bd9Sstevel@tonic-gate 			index++;
742*7c478bd9Sstevel@tonic-gate 			*pgc->pgc_doff += roundup(fptr->file_ctf_size, 8);
743*7c478bd9Sstevel@tonic-gate 		}
744*7c478bd9Sstevel@tonic-gate 
745*7c478bd9Sstevel@tonic-gate 		if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
746*7c478bd9Sstevel@tonic-gate 		    fptr->file_symtab.sym_data != NULL &&
747*7c478bd9Sstevel@tonic-gate 		    fptr->file_symtab.sym_symn != 0 &&
748*7c478bd9Sstevel@tonic-gate 		    fptr->file_symtab.sym_strs != NULL) {
749*7c478bd9Sstevel@tonic-gate 			if (dump_symtab(pgc, fptr, index, 0) != 0)
750*7c478bd9Sstevel@tonic-gate 				return (-1);
751*7c478bd9Sstevel@tonic-gate 			index += 2;
752*7c478bd9Sstevel@tonic-gate 		}
753*7c478bd9Sstevel@tonic-gate 	}
754*7c478bd9Sstevel@tonic-gate 
755*7c478bd9Sstevel@tonic-gate 	return (0);
756*7c478bd9Sstevel@tonic-gate }
757*7c478bd9Sstevel@tonic-gate 
758*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
759*7c478bd9Sstevel@tonic-gate static int
760*7c478bd9Sstevel@tonic-gate dump_map(void *data, const prmap_t *pmp, const char *name)
761*7c478bd9Sstevel@tonic-gate {
762*7c478bd9Sstevel@tonic-gate 	pgcore_t *pgc = data;
763*7c478bd9Sstevel@tonic-gate 	struct ps_prochandle *P = pgc->P;
764*7c478bd9Sstevel@tonic-gate #ifdef _LP64
765*7c478bd9Sstevel@tonic-gate 	Elf64_Phdr phdr;
766*7c478bd9Sstevel@tonic-gate #else
767*7c478bd9Sstevel@tonic-gate 	Elf32_Phdr phdr;
768*7c478bd9Sstevel@tonic-gate #endif
769*7c478bd9Sstevel@tonic-gate 	size_t n;
770*7c478bd9Sstevel@tonic-gate 
771*7c478bd9Sstevel@tonic-gate 	bzero(&phdr, sizeof (phdr));
772*7c478bd9Sstevel@tonic-gate 	phdr.p_type = PT_LOAD;
773*7c478bd9Sstevel@tonic-gate 	phdr.p_vaddr = pmp->pr_vaddr;
774*7c478bd9Sstevel@tonic-gate 	phdr.p_memsz = pmp->pr_size;
775*7c478bd9Sstevel@tonic-gate 	if (pmp->pr_mflags & MA_READ)
776*7c478bd9Sstevel@tonic-gate 		phdr.p_flags |= PF_R;
777*7c478bd9Sstevel@tonic-gate 	if (pmp->pr_mflags & MA_WRITE)
778*7c478bd9Sstevel@tonic-gate 		phdr.p_flags |= PF_W;
779*7c478bd9Sstevel@tonic-gate 	if (pmp->pr_mflags & MA_EXEC)
780*7c478bd9Sstevel@tonic-gate 		phdr.p_flags |= PF_X;
781*7c478bd9Sstevel@tonic-gate 
782*7c478bd9Sstevel@tonic-gate 	if (pmp->pr_vaddr + pmp->pr_size > P->status.pr_stkbase &&
783*7c478bd9Sstevel@tonic-gate 	    pmp->pr_vaddr < P->status.pr_stkbase + P->status.pr_stksize) {
784*7c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_STACK))
785*7c478bd9Sstevel@tonic-gate 			goto exclude;
786*7c478bd9Sstevel@tonic-gate 
787*7c478bd9Sstevel@tonic-gate 	} else if ((pmp->pr_mflags & MA_ANON) &&
788*7c478bd9Sstevel@tonic-gate 	    pmp->pr_vaddr + pmp->pr_size > P->status.pr_brkbase &&
789*7c478bd9Sstevel@tonic-gate 	    pmp->pr_vaddr < P->status.pr_brkbase + P->status.pr_brksize) {
790*7c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_HEAP))
791*7c478bd9Sstevel@tonic-gate 			goto exclude;
792*7c478bd9Sstevel@tonic-gate 
793*7c478bd9Sstevel@tonic-gate 	} else if (pmp->pr_mflags & MA_ISM) {
794*7c478bd9Sstevel@tonic-gate 		if (pmp->pr_mflags & MA_NORESERVE) {
795*7c478bd9Sstevel@tonic-gate 			if (!(pgc->pgc_content & CC_CONTENT_DISM))
796*7c478bd9Sstevel@tonic-gate 				goto exclude;
797*7c478bd9Sstevel@tonic-gate 		} else {
798*7c478bd9Sstevel@tonic-gate 			if (!(pgc->pgc_content & CC_CONTENT_ISM))
799*7c478bd9Sstevel@tonic-gate 				goto exclude;
800*7c478bd9Sstevel@tonic-gate 		}
801*7c478bd9Sstevel@tonic-gate 
802*7c478bd9Sstevel@tonic-gate 	} else if (pmp->pr_mflags & MA_SHM) {
803*7c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_SHM))
804*7c478bd9Sstevel@tonic-gate 			goto exclude;
805*7c478bd9Sstevel@tonic-gate 
806*7c478bd9Sstevel@tonic-gate 	} else if (pmp->pr_mflags & MA_SHARED) {
807*7c478bd9Sstevel@tonic-gate 		if (pmp->pr_mflags & MA_ANON) {
808*7c478bd9Sstevel@tonic-gate 			if (!(pgc->pgc_content & CC_CONTENT_SHANON))
809*7c478bd9Sstevel@tonic-gate 				goto exclude;
810*7c478bd9Sstevel@tonic-gate 		} else {
811*7c478bd9Sstevel@tonic-gate 			if (!(pgc->pgc_content & CC_CONTENT_SHFILE))
812*7c478bd9Sstevel@tonic-gate 				goto exclude;
813*7c478bd9Sstevel@tonic-gate 		}
814*7c478bd9Sstevel@tonic-gate 
815*7c478bd9Sstevel@tonic-gate 	} else if (pmp->pr_mflags & MA_ANON) {
816*7c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_ANON))
817*7c478bd9Sstevel@tonic-gate 			goto exclude;
818*7c478bd9Sstevel@tonic-gate 
819*7c478bd9Sstevel@tonic-gate 	} else if (phdr.p_flags == (PF_R | PF_X)) {
820*7c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_TEXT))
821*7c478bd9Sstevel@tonic-gate 			goto exclude;
822*7c478bd9Sstevel@tonic-gate 
823*7c478bd9Sstevel@tonic-gate 	} else if (phdr.p_flags == PF_R) {
824*7c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_RODATA))
825*7c478bd9Sstevel@tonic-gate 			goto exclude;
826*7c478bd9Sstevel@tonic-gate 
827*7c478bd9Sstevel@tonic-gate 	} else {
828*7c478bd9Sstevel@tonic-gate 		if (!(pgc->pgc_content & CC_CONTENT_DATA))
829*7c478bd9Sstevel@tonic-gate 			goto exclude;
830*7c478bd9Sstevel@tonic-gate 	}
831*7c478bd9Sstevel@tonic-gate 
832*7c478bd9Sstevel@tonic-gate 	n = 0;
833*7c478bd9Sstevel@tonic-gate 	while (n < pmp->pr_size) {
834*7c478bd9Sstevel@tonic-gate 		size_t csz = MIN(pmp->pr_size - n, pgc->pgc_chunksz);
835*7c478bd9Sstevel@tonic-gate 
836*7c478bd9Sstevel@tonic-gate 		/*
837*7c478bd9Sstevel@tonic-gate 		 * If we can't read out part of the victim's address
838*7c478bd9Sstevel@tonic-gate 		 * space for some reason ignore that failure and try to
839*7c478bd9Sstevel@tonic-gate 		 * emit a partial core file without that mapping's data.
840*7c478bd9Sstevel@tonic-gate 		 * As in the kernel, we mark these failures with the
841*7c478bd9Sstevel@tonic-gate 		 * PF_SUNW_FAILURE flag and store the errno where the
842*7c478bd9Sstevel@tonic-gate 		 * mapping would have been.
843*7c478bd9Sstevel@tonic-gate 		 */
844*7c478bd9Sstevel@tonic-gate 		if (Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n) != csz ||
845*7c478bd9Sstevel@tonic-gate 		    pwrite64(pgc->pgc_fd, pgc->pgc_chunk, csz,
846*7c478bd9Sstevel@tonic-gate 		    *pgc->pgc_doff + n) != csz) {
847*7c478bd9Sstevel@tonic-gate 			int err = errno;
848*7c478bd9Sstevel@tonic-gate 			(void) pwrite64(pgc->pgc_fd, &err, sizeof (err),
849*7c478bd9Sstevel@tonic-gate 			    *pgc->pgc_doff);
850*7c478bd9Sstevel@tonic-gate 			*pgc->pgc_doff += roundup(sizeof (err), 8);
851*7c478bd9Sstevel@tonic-gate 
852*7c478bd9Sstevel@tonic-gate 			phdr.p_flags |= PF_SUNW_FAILURE;
853*7c478bd9Sstevel@tonic-gate 			(void) ftruncate64(pgc->pgc_fd, *pgc->pgc_doff);
854*7c478bd9Sstevel@tonic-gate 			goto exclude;
855*7c478bd9Sstevel@tonic-gate 		}
856*7c478bd9Sstevel@tonic-gate 
857*7c478bd9Sstevel@tonic-gate 		n += csz;
858*7c478bd9Sstevel@tonic-gate 	}
859*7c478bd9Sstevel@tonic-gate 
860*7c478bd9Sstevel@tonic-gate 	phdr.p_offset = *pgc->pgc_doff;
861*7c478bd9Sstevel@tonic-gate 	phdr.p_filesz = pmp->pr_size;
862*7c478bd9Sstevel@tonic-gate 	*pgc->pgc_doff += roundup(phdr.p_filesz, 8);
863*7c478bd9Sstevel@tonic-gate 
864*7c478bd9Sstevel@tonic-gate exclude:
865*7c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
866*7c478bd9Sstevel@tonic-gate 		if (pwrite64(pgc->pgc_fd, &phdr, sizeof (phdr),
867*7c478bd9Sstevel@tonic-gate 		    *pgc->pgc_poff) != sizeof (phdr))
868*7c478bd9Sstevel@tonic-gate 			return (1);
869*7c478bd9Sstevel@tonic-gate 
870*7c478bd9Sstevel@tonic-gate 		*pgc->pgc_poff += sizeof (phdr);
871*7c478bd9Sstevel@tonic-gate #ifdef _LP64
872*7c478bd9Sstevel@tonic-gate 	} else {
873*7c478bd9Sstevel@tonic-gate 		Elf32_Phdr phdr32;
874*7c478bd9Sstevel@tonic-gate 
875*7c478bd9Sstevel@tonic-gate 		bzero(&phdr32, sizeof (phdr32));
876*7c478bd9Sstevel@tonic-gate 		phdr32.p_type = phdr.p_type;
877*7c478bd9Sstevel@tonic-gate 		phdr32.p_vaddr = (Elf32_Addr)phdr.p_vaddr;
878*7c478bd9Sstevel@tonic-gate 		phdr32.p_memsz = (Elf32_Word)phdr.p_memsz;
879*7c478bd9Sstevel@tonic-gate 		phdr32.p_flags = phdr.p_flags;
880*7c478bd9Sstevel@tonic-gate 		phdr32.p_offset = (Elf32_Off)phdr.p_offset;
881*7c478bd9Sstevel@tonic-gate 		phdr32.p_filesz = (Elf32_Word)phdr.p_filesz;
882*7c478bd9Sstevel@tonic-gate 
883*7c478bd9Sstevel@tonic-gate 		if (pwrite64(pgc->pgc_fd, &phdr32, sizeof (phdr32),
884*7c478bd9Sstevel@tonic-gate 		    *pgc->pgc_poff) != sizeof (phdr32))
885*7c478bd9Sstevel@tonic-gate 			return (1);
886*7c478bd9Sstevel@tonic-gate 
887*7c478bd9Sstevel@tonic-gate 		*pgc->pgc_poff += sizeof (phdr32);
888*7c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
889*7c478bd9Sstevel@tonic-gate 	}
890*7c478bd9Sstevel@tonic-gate 
891*7c478bd9Sstevel@tonic-gate 	return (0);
892*7c478bd9Sstevel@tonic-gate }
893*7c478bd9Sstevel@tonic-gate 
894*7c478bd9Sstevel@tonic-gate int
895*7c478bd9Sstevel@tonic-gate write_shstrtab(struct ps_prochandle *P, pgcore_t *pgc)
896*7c478bd9Sstevel@tonic-gate {
897*7c478bd9Sstevel@tonic-gate 	off64_t off = *pgc->pgc_doff;
898*7c478bd9Sstevel@tonic-gate 	size_t size = 0;
899*7c478bd9Sstevel@tonic-gate 	shstrtab_t *s = &pgc->pgc_shstrtab;
900*7c478bd9Sstevel@tonic-gate 	int i, ndx;
901*7c478bd9Sstevel@tonic-gate 
902*7c478bd9Sstevel@tonic-gate 	if (shstrtab_size(s) == 1)
903*7c478bd9Sstevel@tonic-gate 		return (0);
904*7c478bd9Sstevel@tonic-gate 
905*7c478bd9Sstevel@tonic-gate 	/*
906*7c478bd9Sstevel@tonic-gate 	 * Preemptively stick the name of the shstrtab in the string table.
907*7c478bd9Sstevel@tonic-gate 	 */
908*7c478bd9Sstevel@tonic-gate 	(void) shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);
909*7c478bd9Sstevel@tonic-gate 	size = shstrtab_size(s);
910*7c478bd9Sstevel@tonic-gate 
911*7c478bd9Sstevel@tonic-gate 	if (pwrite64(pgc->pgc_fd, "", 1, off) != 1)
912*7c478bd9Sstevel@tonic-gate 		return (1);
913*7c478bd9Sstevel@tonic-gate 
914*7c478bd9Sstevel@tonic-gate 	/*
915*7c478bd9Sstevel@tonic-gate 	 * Dump all the strings that we used being sure we include the
916*7c478bd9Sstevel@tonic-gate 	 * terminating null character.
917*7c478bd9Sstevel@tonic-gate 	 */
918*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < STR_NUM; i++) {
919*7c478bd9Sstevel@tonic-gate 		if ((ndx = s->sst_ndx[i]) != 0) {
920*7c478bd9Sstevel@tonic-gate 			const char *str = shstrtab_data[i];
921*7c478bd9Sstevel@tonic-gate 			size_t len = strlen(str) + 1;
922*7c478bd9Sstevel@tonic-gate 			if (pwrite64(pgc->pgc_fd, str, len, off + ndx) != len)
923*7c478bd9Sstevel@tonic-gate 				return (1);
924*7c478bd9Sstevel@tonic-gate 		}
925*7c478bd9Sstevel@tonic-gate 	}
926*7c478bd9Sstevel@tonic-gate 
927*7c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
928*7c478bd9Sstevel@tonic-gate 		Elf32_Shdr shdr;
929*7c478bd9Sstevel@tonic-gate 
930*7c478bd9Sstevel@tonic-gate 		bzero(&shdr, sizeof (shdr));
931*7c478bd9Sstevel@tonic-gate 		shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);
932*7c478bd9Sstevel@tonic-gate 		shdr.sh_size = size;
933*7c478bd9Sstevel@tonic-gate 		shdr.sh_offset = *pgc->pgc_doff;
934*7c478bd9Sstevel@tonic-gate 		shdr.sh_addralign = 1;
935*7c478bd9Sstevel@tonic-gate 		shdr.sh_flags = SHF_STRINGS;
936*7c478bd9Sstevel@tonic-gate 		shdr.sh_type = SHT_STRTAB;
937*7c478bd9Sstevel@tonic-gate 
938*7c478bd9Sstevel@tonic-gate 		if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
939*7c478bd9Sstevel@tonic-gate 		    *pgc->pgc_soff) != sizeof (shdr))
940*7c478bd9Sstevel@tonic-gate 			return (1);
941*7c478bd9Sstevel@tonic-gate 
942*7c478bd9Sstevel@tonic-gate 		*pgc->pgc_soff += sizeof (shdr);
943*7c478bd9Sstevel@tonic-gate #ifdef _LP64
944*7c478bd9Sstevel@tonic-gate 	} else {
945*7c478bd9Sstevel@tonic-gate 		Elf64_Shdr shdr;
946*7c478bd9Sstevel@tonic-gate 
947*7c478bd9Sstevel@tonic-gate 		bzero(&shdr, sizeof (shdr));
948*7c478bd9Sstevel@tonic-gate 		shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);
949*7c478bd9Sstevel@tonic-gate 		shdr.sh_size = size;
950*7c478bd9Sstevel@tonic-gate 		shdr.sh_offset = *pgc->pgc_doff;
951*7c478bd9Sstevel@tonic-gate 		shdr.sh_addralign = 1;
952*7c478bd9Sstevel@tonic-gate 		shdr.sh_flags = SHF_STRINGS;
953*7c478bd9Sstevel@tonic-gate 		shdr.sh_type = SHT_STRTAB;
954*7c478bd9Sstevel@tonic-gate 
955*7c478bd9Sstevel@tonic-gate 		if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
956*7c478bd9Sstevel@tonic-gate 		    *pgc->pgc_soff) != sizeof (shdr))
957*7c478bd9Sstevel@tonic-gate 			return (1);
958*7c478bd9Sstevel@tonic-gate 
959*7c478bd9Sstevel@tonic-gate 		*pgc->pgc_soff += sizeof (shdr);
960*7c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
961*7c478bd9Sstevel@tonic-gate 	}
962*7c478bd9Sstevel@tonic-gate 
963*7c478bd9Sstevel@tonic-gate 	*pgc->pgc_doff += roundup(size, 8);
964*7c478bd9Sstevel@tonic-gate 
965*7c478bd9Sstevel@tonic-gate 	return (0);
966*7c478bd9Sstevel@tonic-gate }
967*7c478bd9Sstevel@tonic-gate 
968*7c478bd9Sstevel@tonic-gate /*
969*7c478bd9Sstevel@tonic-gate  * Don't explicity stop the process; that's up to the consumer.
970*7c478bd9Sstevel@tonic-gate  */
971*7c478bd9Sstevel@tonic-gate int
972*7c478bd9Sstevel@tonic-gate Pfgcore(struct ps_prochandle *P, int fd, core_content_t content)
973*7c478bd9Sstevel@tonic-gate {
974*7c478bd9Sstevel@tonic-gate 	char plat[SYS_NMLN];
975*7c478bd9Sstevel@tonic-gate 	char zonename[ZONENAME_MAX];
976*7c478bd9Sstevel@tonic-gate 	int platlen = -1;
977*7c478bd9Sstevel@tonic-gate 	pgcore_t pgc;
978*7c478bd9Sstevel@tonic-gate 	off64_t poff, soff, doff, boff;
979*7c478bd9Sstevel@tonic-gate 	struct utsname uts;
980*7c478bd9Sstevel@tonic-gate 	uint_t nphdrs, nshdrs;
981*7c478bd9Sstevel@tonic-gate 
982*7c478bd9Sstevel@tonic-gate 	if (ftruncate64(fd, 0) != 0)
983*7c478bd9Sstevel@tonic-gate 		return (-1);
984*7c478bd9Sstevel@tonic-gate 
985*7c478bd9Sstevel@tonic-gate 	if (content == CC_CONTENT_INVALID) {
986*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
987*7c478bd9Sstevel@tonic-gate 		return (-1);
988*7c478bd9Sstevel@tonic-gate 	}
989*7c478bd9Sstevel@tonic-gate 
990*7c478bd9Sstevel@tonic-gate 	/*
991*7c478bd9Sstevel@tonic-gate 	 * Cache the mappings and other useful data.
992*7c478bd9Sstevel@tonic-gate 	 */
993*7c478bd9Sstevel@tonic-gate 	(void) Prd_agent(P);
994*7c478bd9Sstevel@tonic-gate 	(void) Ppsinfo(P);
995*7c478bd9Sstevel@tonic-gate 
996*7c478bd9Sstevel@tonic-gate 	pgc.P = P;
997*7c478bd9Sstevel@tonic-gate 	pgc.pgc_fd = fd;
998*7c478bd9Sstevel@tonic-gate 	pgc.pgc_poff = &poff;
999*7c478bd9Sstevel@tonic-gate 	pgc.pgc_soff = &soff;
1000*7c478bd9Sstevel@tonic-gate 	pgc.pgc_doff = &doff;
1001*7c478bd9Sstevel@tonic-gate 	pgc.pgc_content = content;
1002*7c478bd9Sstevel@tonic-gate 	pgc.pgc_chunksz = PAGESIZE;
1003*7c478bd9Sstevel@tonic-gate 	if ((pgc.pgc_chunk = malloc(pgc.pgc_chunksz)) == NULL)
1004*7c478bd9Sstevel@tonic-gate 		return (-1);
1005*7c478bd9Sstevel@tonic-gate 
1006*7c478bd9Sstevel@tonic-gate 	shstrtab_init(&pgc.pgc_shstrtab);
1007*7c478bd9Sstevel@tonic-gate 
1008*7c478bd9Sstevel@tonic-gate 	/*
1009*7c478bd9Sstevel@tonic-gate 	 * There are two PT_NOTE program headers for ancillary data, and
1010*7c478bd9Sstevel@tonic-gate 	 * one for each mapping.
1011*7c478bd9Sstevel@tonic-gate 	 */
1012*7c478bd9Sstevel@tonic-gate 	nphdrs = 2 + P->map_count;
1013*7c478bd9Sstevel@tonic-gate 	nshdrs = count_sections(&pgc);
1014*7c478bd9Sstevel@tonic-gate 
1015*7c478bd9Sstevel@tonic-gate 	(void) Pplatform(P, plat, sizeof (plat));
1016*7c478bd9Sstevel@tonic-gate 	platlen = strlen(plat) + 1;
1017*7c478bd9Sstevel@tonic-gate 	Preadauxvec(P);
1018*7c478bd9Sstevel@tonic-gate 	(void) Puname(P, &uts);
1019*7c478bd9Sstevel@tonic-gate 	if (Pzonename(P, zonename, sizeof (zonename)) == NULL)
1020*7c478bd9Sstevel@tonic-gate 		zonename[0] = '\0';
1021*7c478bd9Sstevel@tonic-gate 
1022*7c478bd9Sstevel@tonic-gate 	/*
1023*7c478bd9Sstevel@tonic-gate 	 * Set up the ELF header.
1024*7c478bd9Sstevel@tonic-gate 	 */
1025*7c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1026*7c478bd9Sstevel@tonic-gate 		Elf32_Ehdr ehdr;
1027*7c478bd9Sstevel@tonic-gate 
1028*7c478bd9Sstevel@tonic-gate 		bzero(&ehdr, sizeof (ehdr));
1029*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG0] = ELFMAG0;
1030*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG1] = ELFMAG1;
1031*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG2] = ELFMAG2;
1032*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG3] = ELFMAG3;
1033*7c478bd9Sstevel@tonic-gate 		ehdr.e_type = ET_CORE;
1034*7c478bd9Sstevel@tonic-gate 
1035*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_CLASS] = ELFCLASS32;
1036*7c478bd9Sstevel@tonic-gate #if defined(__sparc)
1037*7c478bd9Sstevel@tonic-gate 		ehdr.e_machine = EM_SPARC;
1038*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
1039*7c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64)
1040*7c478bd9Sstevel@tonic-gate 		ehdr.e_machine = EM_386;
1041*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
1042*7c478bd9Sstevel@tonic-gate #else
1043*7c478bd9Sstevel@tonic-gate #error "unknown machine type"
1044*7c478bd9Sstevel@tonic-gate #endif
1045*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_VERSION] = EV_CURRENT;
1046*7c478bd9Sstevel@tonic-gate 
1047*7c478bd9Sstevel@tonic-gate 		ehdr.e_version = EV_CURRENT;
1048*7c478bd9Sstevel@tonic-gate 		ehdr.e_ehsize = sizeof (ehdr);
1049*7c478bd9Sstevel@tonic-gate 		ehdr.e_phentsize = sizeof (Elf32_Phdr);
1050*7c478bd9Sstevel@tonic-gate 		ehdr.e_phnum = (unsigned short)nphdrs;
1051*7c478bd9Sstevel@tonic-gate 		ehdr.e_phoff = ehdr.e_ehsize;
1052*7c478bd9Sstevel@tonic-gate 
1053*7c478bd9Sstevel@tonic-gate 		if (nshdrs != 0) {
1054*7c478bd9Sstevel@tonic-gate 			ehdr.e_shentsize = sizeof (Elf32_Shdr);
1055*7c478bd9Sstevel@tonic-gate 			ehdr.e_shnum = (unsigned short)nshdrs;
1056*7c478bd9Sstevel@tonic-gate 			ehdr.e_shoff = ehdr.e_phoff +
1057*7c478bd9Sstevel@tonic-gate 			    ehdr.e_phentsize * ehdr.e_phnum;
1058*7c478bd9Sstevel@tonic-gate 			ehdr.e_shstrndx = nshdrs - 1;
1059*7c478bd9Sstevel@tonic-gate 		}
1060*7c478bd9Sstevel@tonic-gate 
1061*7c478bd9Sstevel@tonic-gate 		if (pwrite64(fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
1062*7c478bd9Sstevel@tonic-gate 			goto err;
1063*7c478bd9Sstevel@tonic-gate 
1064*7c478bd9Sstevel@tonic-gate 		poff = ehdr.e_phoff;
1065*7c478bd9Sstevel@tonic-gate 		soff = ehdr.e_shoff + ehdr.e_shentsize;
1066*7c478bd9Sstevel@tonic-gate 		doff = boff = ehdr.e_ehsize +
1067*7c478bd9Sstevel@tonic-gate 		    ehdr.e_phentsize * ehdr.e_phnum +
1068*7c478bd9Sstevel@tonic-gate 		    ehdr.e_shentsize * ehdr.e_shnum;
1069*7c478bd9Sstevel@tonic-gate 
1070*7c478bd9Sstevel@tonic-gate #ifdef _LP64
1071*7c478bd9Sstevel@tonic-gate 	} else {
1072*7c478bd9Sstevel@tonic-gate 		Elf64_Ehdr ehdr;
1073*7c478bd9Sstevel@tonic-gate 
1074*7c478bd9Sstevel@tonic-gate 		bzero(&ehdr, sizeof (ehdr));
1075*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG0] = ELFMAG0;
1076*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG1] = ELFMAG1;
1077*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG2] = ELFMAG2;
1078*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_MAG3] = ELFMAG3;
1079*7c478bd9Sstevel@tonic-gate 		ehdr.e_type = ET_CORE;
1080*7c478bd9Sstevel@tonic-gate 
1081*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_CLASS] = ELFCLASS64;
1082*7c478bd9Sstevel@tonic-gate #if defined(__sparc)
1083*7c478bd9Sstevel@tonic-gate 		ehdr.e_machine = EM_SPARCV9;
1084*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
1085*7c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64)
1086*7c478bd9Sstevel@tonic-gate 		ehdr.e_machine = EM_AMD64;
1087*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
1088*7c478bd9Sstevel@tonic-gate #else
1089*7c478bd9Sstevel@tonic-gate #error "unknown machine type"
1090*7c478bd9Sstevel@tonic-gate #endif
1091*7c478bd9Sstevel@tonic-gate 		ehdr.e_ident[EI_VERSION] = EV_CURRENT;
1092*7c478bd9Sstevel@tonic-gate 
1093*7c478bd9Sstevel@tonic-gate 		ehdr.e_version = EV_CURRENT;
1094*7c478bd9Sstevel@tonic-gate 		ehdr.e_ehsize = sizeof (ehdr);
1095*7c478bd9Sstevel@tonic-gate 		ehdr.e_phentsize = sizeof (Elf64_Phdr);
1096*7c478bd9Sstevel@tonic-gate 		ehdr.e_phnum = (unsigned short)nphdrs;
1097*7c478bd9Sstevel@tonic-gate 		ehdr.e_phoff = ehdr.e_ehsize;
1098*7c478bd9Sstevel@tonic-gate 
1099*7c478bd9Sstevel@tonic-gate 		if (nshdrs != 0) {
1100*7c478bd9Sstevel@tonic-gate 			ehdr.e_shentsize = sizeof (Elf64_Shdr);
1101*7c478bd9Sstevel@tonic-gate 			ehdr.e_shnum = (unsigned short)nshdrs;
1102*7c478bd9Sstevel@tonic-gate 			ehdr.e_shoff = ehdr.e_phoff +
1103*7c478bd9Sstevel@tonic-gate 			    ehdr.e_phentsize * ehdr.e_phnum;
1104*7c478bd9Sstevel@tonic-gate 			ehdr.e_shstrndx = nshdrs - 1;
1105*7c478bd9Sstevel@tonic-gate 		}
1106*7c478bd9Sstevel@tonic-gate 
1107*7c478bd9Sstevel@tonic-gate 		if (pwrite64(fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
1108*7c478bd9Sstevel@tonic-gate 			goto err;
1109*7c478bd9Sstevel@tonic-gate 
1110*7c478bd9Sstevel@tonic-gate 		poff = ehdr.e_phoff;
1111*7c478bd9Sstevel@tonic-gate 		soff = ehdr.e_shoff + ehdr.e_shentsize;
1112*7c478bd9Sstevel@tonic-gate 		doff = boff = sizeof (ehdr) +
1113*7c478bd9Sstevel@tonic-gate 		    ehdr.e_phentsize * ehdr.e_phnum +
1114*7c478bd9Sstevel@tonic-gate 		    ehdr.e_shentsize * ehdr.e_shnum;
1115*7c478bd9Sstevel@tonic-gate 
1116*7c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
1117*7c478bd9Sstevel@tonic-gate 	}
1118*7c478bd9Sstevel@tonic-gate 
1119*7c478bd9Sstevel@tonic-gate 	/*
1120*7c478bd9Sstevel@tonic-gate 	 * Construct the old-style note header and section.
1121*7c478bd9Sstevel@tonic-gate 	 */
1122*7c478bd9Sstevel@tonic-gate 
1123*7c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
1124*7c478bd9Sstevel@tonic-gate 		prpsinfo_t prpsinfo;
1125*7c478bd9Sstevel@tonic-gate 
1126*7c478bd9Sstevel@tonic-gate 		mkprpsinfo(P, &prpsinfo);
1127*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PRPSINFO, &prpsinfo, sizeof (prpsinfo_t),
1128*7c478bd9Sstevel@tonic-gate 		    &doff) != 0) {
1129*7c478bd9Sstevel@tonic-gate 			goto err;
1130*7c478bd9Sstevel@tonic-gate 		}
1131*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_AUXV, P->auxv,
1132*7c478bd9Sstevel@tonic-gate 		    P->nauxv * sizeof (P->auxv[0]), &doff) != 0) {
1133*7c478bd9Sstevel@tonic-gate 			goto err;
1134*7c478bd9Sstevel@tonic-gate 		}
1135*7c478bd9Sstevel@tonic-gate #ifdef _LP64
1136*7c478bd9Sstevel@tonic-gate 	} else {
1137*7c478bd9Sstevel@tonic-gate 		prpsinfo32_t pi32;
1138*7c478bd9Sstevel@tonic-gate 		auxv32_t *av32;
1139*7c478bd9Sstevel@tonic-gate 		size_t size = sizeof (auxv32_t) * P->nauxv;
1140*7c478bd9Sstevel@tonic-gate 		int i;
1141*7c478bd9Sstevel@tonic-gate 
1142*7c478bd9Sstevel@tonic-gate 		mkprpsinfo32(P, &pi32);
1143*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PRPSINFO, &pi32, sizeof (prpsinfo32_t),
1144*7c478bd9Sstevel@tonic-gate 		    &doff) != 0) {
1145*7c478bd9Sstevel@tonic-gate 			goto err;
1146*7c478bd9Sstevel@tonic-gate 		}
1147*7c478bd9Sstevel@tonic-gate 
1148*7c478bd9Sstevel@tonic-gate 		if ((av32 = malloc(size)) == NULL)
1149*7c478bd9Sstevel@tonic-gate 			goto err;
1150*7c478bd9Sstevel@tonic-gate 
1151*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < P->nauxv; i++) {
1152*7c478bd9Sstevel@tonic-gate 			auxv_n_to_32(&P->auxv[i], &av32[i]);
1153*7c478bd9Sstevel@tonic-gate 		}
1154*7c478bd9Sstevel@tonic-gate 
1155*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) {
1156*7c478bd9Sstevel@tonic-gate 			free(av32);
1157*7c478bd9Sstevel@tonic-gate 			goto err;
1158*7c478bd9Sstevel@tonic-gate 		}
1159*7c478bd9Sstevel@tonic-gate 
1160*7c478bd9Sstevel@tonic-gate 		free(av32);
1161*7c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
1162*7c478bd9Sstevel@tonic-gate 	}
1163*7c478bd9Sstevel@tonic-gate 
1164*7c478bd9Sstevel@tonic-gate 	if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0)
1165*7c478bd9Sstevel@tonic-gate 		goto err;
1166*7c478bd9Sstevel@tonic-gate 
1167*7c478bd9Sstevel@tonic-gate 	if (Plwp_iter_all(P, old_per_lwp, &pgc) != 0)
1168*7c478bd9Sstevel@tonic-gate 		goto err;
1169*7c478bd9Sstevel@tonic-gate 
1170*7c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1171*7c478bd9Sstevel@tonic-gate 		Elf32_Phdr phdr;
1172*7c478bd9Sstevel@tonic-gate 
1173*7c478bd9Sstevel@tonic-gate 		bzero(&phdr, sizeof (phdr));
1174*7c478bd9Sstevel@tonic-gate 		phdr.p_type = PT_NOTE;
1175*7c478bd9Sstevel@tonic-gate 		phdr.p_flags = PF_R;
1176*7c478bd9Sstevel@tonic-gate 		phdr.p_offset = (Elf32_Off)boff;
1177*7c478bd9Sstevel@tonic-gate 		phdr.p_filesz = doff - boff;
1178*7c478bd9Sstevel@tonic-gate 		boff = doff;
1179*7c478bd9Sstevel@tonic-gate 
1180*7c478bd9Sstevel@tonic-gate 		if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
1181*7c478bd9Sstevel@tonic-gate 			goto err;
1182*7c478bd9Sstevel@tonic-gate 		poff += sizeof (phdr);
1183*7c478bd9Sstevel@tonic-gate #ifdef _LP64
1184*7c478bd9Sstevel@tonic-gate 	} else {
1185*7c478bd9Sstevel@tonic-gate 		Elf64_Phdr phdr;
1186*7c478bd9Sstevel@tonic-gate 
1187*7c478bd9Sstevel@tonic-gate 		bzero(&phdr, sizeof (phdr));
1188*7c478bd9Sstevel@tonic-gate 		phdr.p_type = PT_NOTE;
1189*7c478bd9Sstevel@tonic-gate 		phdr.p_flags = PF_R;
1190*7c478bd9Sstevel@tonic-gate 		phdr.p_offset = boff;
1191*7c478bd9Sstevel@tonic-gate 		phdr.p_filesz = doff - boff;
1192*7c478bd9Sstevel@tonic-gate 		boff = doff;
1193*7c478bd9Sstevel@tonic-gate 
1194*7c478bd9Sstevel@tonic-gate 		if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
1195*7c478bd9Sstevel@tonic-gate 			goto err;
1196*7c478bd9Sstevel@tonic-gate 		poff += sizeof (phdr);
1197*7c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
1198*7c478bd9Sstevel@tonic-gate 	}
1199*7c478bd9Sstevel@tonic-gate 
1200*7c478bd9Sstevel@tonic-gate 	/*
1201*7c478bd9Sstevel@tonic-gate 	 * Construct the new-style note header and section.
1202*7c478bd9Sstevel@tonic-gate 	 */
1203*7c478bd9Sstevel@tonic-gate 
1204*7c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
1205*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PSINFO, &P->psinfo, sizeof (psinfo_t),
1206*7c478bd9Sstevel@tonic-gate 		    &doff) != 0) {
1207*7c478bd9Sstevel@tonic-gate 			goto err;
1208*7c478bd9Sstevel@tonic-gate 		}
1209*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PSTATUS, &P->status, sizeof (pstatus_t),
1210*7c478bd9Sstevel@tonic-gate 		    &doff) != 0) {
1211*7c478bd9Sstevel@tonic-gate 			goto err;
1212*7c478bd9Sstevel@tonic-gate 		}
1213*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_AUXV, P->auxv,
1214*7c478bd9Sstevel@tonic-gate 		    P->nauxv * sizeof (P->auxv[0]), &doff) != 0) {
1215*7c478bd9Sstevel@tonic-gate 			goto err;
1216*7c478bd9Sstevel@tonic-gate 		}
1217*7c478bd9Sstevel@tonic-gate #ifdef _LP64
1218*7c478bd9Sstevel@tonic-gate 	} else {
1219*7c478bd9Sstevel@tonic-gate 		psinfo32_t pi32;
1220*7c478bd9Sstevel@tonic-gate 		pstatus32_t ps32;
1221*7c478bd9Sstevel@tonic-gate 		auxv32_t *av32;
1222*7c478bd9Sstevel@tonic-gate 		size_t size = sizeof (auxv32_t) * P->nauxv;
1223*7c478bd9Sstevel@tonic-gate 		int i;
1224*7c478bd9Sstevel@tonic-gate 
1225*7c478bd9Sstevel@tonic-gate 		psinfo_n_to_32(&P->psinfo, &pi32);
1226*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PSINFO, &pi32, sizeof (psinfo32_t),
1227*7c478bd9Sstevel@tonic-gate 			    &doff) != 0) {
1228*7c478bd9Sstevel@tonic-gate 			goto err;
1229*7c478bd9Sstevel@tonic-gate 		}
1230*7c478bd9Sstevel@tonic-gate 		pstatus_n_to_32(&P->status, &ps32);
1231*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PSTATUS, &ps32, sizeof (pstatus32_t),
1232*7c478bd9Sstevel@tonic-gate 			    &doff) != 0) {
1233*7c478bd9Sstevel@tonic-gate 			goto err;
1234*7c478bd9Sstevel@tonic-gate 		}
1235*7c478bd9Sstevel@tonic-gate 		if ((av32 = malloc(size)) == NULL)
1236*7c478bd9Sstevel@tonic-gate 			goto err;
1237*7c478bd9Sstevel@tonic-gate 
1238*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < P->nauxv; i++) {
1239*7c478bd9Sstevel@tonic-gate 			auxv_n_to_32(&P->auxv[i], &av32[i]);
1240*7c478bd9Sstevel@tonic-gate 		}
1241*7c478bd9Sstevel@tonic-gate 
1242*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) {
1243*7c478bd9Sstevel@tonic-gate 			free(av32);
1244*7c478bd9Sstevel@tonic-gate 			goto err;
1245*7c478bd9Sstevel@tonic-gate 		}
1246*7c478bd9Sstevel@tonic-gate 
1247*7c478bd9Sstevel@tonic-gate 		free(av32);
1248*7c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
1249*7c478bd9Sstevel@tonic-gate 	}
1250*7c478bd9Sstevel@tonic-gate 
1251*7c478bd9Sstevel@tonic-gate 	if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0 ||
1252*7c478bd9Sstevel@tonic-gate 	    write_note(fd, NT_UTSNAME, &uts, sizeof (uts), &doff) != 0 ||
1253*7c478bd9Sstevel@tonic-gate 	    write_note(fd, NT_CONTENT, &content, sizeof (content), &doff) != 0)
1254*7c478bd9Sstevel@tonic-gate 		goto err;
1255*7c478bd9Sstevel@tonic-gate 
1256*7c478bd9Sstevel@tonic-gate 	{
1257*7c478bd9Sstevel@tonic-gate 		prcred_t cred, *cp;
1258*7c478bd9Sstevel@tonic-gate 		size_t size = sizeof (prcred_t);
1259*7c478bd9Sstevel@tonic-gate 
1260*7c478bd9Sstevel@tonic-gate 		if (Pcred(P, &cred, 0) != 0)
1261*7c478bd9Sstevel@tonic-gate 			goto err;
1262*7c478bd9Sstevel@tonic-gate 
1263*7c478bd9Sstevel@tonic-gate 		if (cred.pr_ngroups > 0)
1264*7c478bd9Sstevel@tonic-gate 			size += sizeof (gid_t) * (cred.pr_ngroups - 1);
1265*7c478bd9Sstevel@tonic-gate 		if ((cp = malloc(size)) == NULL)
1266*7c478bd9Sstevel@tonic-gate 			goto err;
1267*7c478bd9Sstevel@tonic-gate 
1268*7c478bd9Sstevel@tonic-gate 		if (Pcred(P, cp, cred.pr_ngroups) != 0 ||
1269*7c478bd9Sstevel@tonic-gate 		    write_note(fd, NT_PRCRED, cp, size, &doff) != 0) {
1270*7c478bd9Sstevel@tonic-gate 			free(cp);
1271*7c478bd9Sstevel@tonic-gate 			goto err;
1272*7c478bd9Sstevel@tonic-gate 		}
1273*7c478bd9Sstevel@tonic-gate 
1274*7c478bd9Sstevel@tonic-gate 		free(cp);
1275*7c478bd9Sstevel@tonic-gate 	}
1276*7c478bd9Sstevel@tonic-gate 
1277*7c478bd9Sstevel@tonic-gate 	{
1278*7c478bd9Sstevel@tonic-gate 		prpriv_t *ppriv;
1279*7c478bd9Sstevel@tonic-gate 		const priv_impl_info_t *pinfo;
1280*7c478bd9Sstevel@tonic-gate 		size_t pprivsz, pinfosz;
1281*7c478bd9Sstevel@tonic-gate 
1282*7c478bd9Sstevel@tonic-gate 		if ((ppriv = proc_get_priv(P->pid)) == NULL)
1283*7c478bd9Sstevel@tonic-gate 			goto err;
1284*7c478bd9Sstevel@tonic-gate 		pprivsz = PRIV_PRPRIV_SIZE(ppriv);
1285*7c478bd9Sstevel@tonic-gate 
1286*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PRPRIV, ppriv, pprivsz, &doff) != 0) {
1287*7c478bd9Sstevel@tonic-gate 			free(ppriv);
1288*7c478bd9Sstevel@tonic-gate 			goto err;
1289*7c478bd9Sstevel@tonic-gate 		}
1290*7c478bd9Sstevel@tonic-gate 		free(ppriv);
1291*7c478bd9Sstevel@tonic-gate 
1292*7c478bd9Sstevel@tonic-gate 		if ((pinfo = getprivimplinfo()) == NULL)
1293*7c478bd9Sstevel@tonic-gate 			goto err;
1294*7c478bd9Sstevel@tonic-gate 		pinfosz = PRIV_IMPL_INFO_SIZE(pinfo);
1295*7c478bd9Sstevel@tonic-gate 
1296*7c478bd9Sstevel@tonic-gate 		if (write_note(fd, NT_PRPRIVINFO, pinfo, pinfosz, &doff) != 0)
1297*7c478bd9Sstevel@tonic-gate 			goto err;
1298*7c478bd9Sstevel@tonic-gate 	}
1299*7c478bd9Sstevel@tonic-gate 
1300*7c478bd9Sstevel@tonic-gate 	if (write_note(fd, NT_ZONENAME, zonename, strlen(zonename) + 1,
1301*7c478bd9Sstevel@tonic-gate 	    &doff) != 0)
1302*7c478bd9Sstevel@tonic-gate 		goto err;
1303*7c478bd9Sstevel@tonic-gate 
1304*7c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64)
1305*7c478bd9Sstevel@tonic-gate 	/* CSTYLED */
1306*7c478bd9Sstevel@tonic-gate 	{
1307*7c478bd9Sstevel@tonic-gate 		struct ssd *ldtp;
1308*7c478bd9Sstevel@tonic-gate 		size_t size;
1309*7c478bd9Sstevel@tonic-gate 		int nldt;
1310*7c478bd9Sstevel@tonic-gate 
1311*7c478bd9Sstevel@tonic-gate 		nldt = Pldt(P, NULL, 0);
1312*7c478bd9Sstevel@tonic-gate 		size = sizeof (struct ssd) * nldt;
1313*7c478bd9Sstevel@tonic-gate 		if ((ldtp = malloc(size)) == NULL)
1314*7c478bd9Sstevel@tonic-gate 			goto err;
1315*7c478bd9Sstevel@tonic-gate 
1316*7c478bd9Sstevel@tonic-gate 		if (Pldt(P, ldtp, nldt) == -1 ||
1317*7c478bd9Sstevel@tonic-gate 		    write_note(fd, NT_LDT, ldtp, size, &doff) != 0) {
1318*7c478bd9Sstevel@tonic-gate 			free(ldtp);
1319*7c478bd9Sstevel@tonic-gate 			goto err;
1320*7c478bd9Sstevel@tonic-gate 		}
1321*7c478bd9Sstevel@tonic-gate 
1322*7c478bd9Sstevel@tonic-gate 		free(ldtp);
1323*7c478bd9Sstevel@tonic-gate 	}
1324*7c478bd9Sstevel@tonic-gate #endif	/* __i386 || __amd64 */
1325*7c478bd9Sstevel@tonic-gate 
1326*7c478bd9Sstevel@tonic-gate 	if (Plwp_iter_all(P, new_per_lwp, &pgc) != 0)
1327*7c478bd9Sstevel@tonic-gate 		goto err;
1328*7c478bd9Sstevel@tonic-gate 
1329*7c478bd9Sstevel@tonic-gate 	if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1330*7c478bd9Sstevel@tonic-gate 		Elf32_Phdr phdr;
1331*7c478bd9Sstevel@tonic-gate 
1332*7c478bd9Sstevel@tonic-gate 		bzero(&phdr, sizeof (phdr));
1333*7c478bd9Sstevel@tonic-gate 		phdr.p_type = PT_NOTE;
1334*7c478bd9Sstevel@tonic-gate 		phdr.p_flags = PF_R;
1335*7c478bd9Sstevel@tonic-gate 		phdr.p_offset = (Elf32_Off)boff;
1336*7c478bd9Sstevel@tonic-gate 		phdr.p_filesz = doff - boff;
1337*7c478bd9Sstevel@tonic-gate 		boff = doff;
1338*7c478bd9Sstevel@tonic-gate 
1339*7c478bd9Sstevel@tonic-gate 		if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
1340*7c478bd9Sstevel@tonic-gate 			goto err;
1341*7c478bd9Sstevel@tonic-gate 		poff += sizeof (phdr);
1342*7c478bd9Sstevel@tonic-gate #ifdef _LP64
1343*7c478bd9Sstevel@tonic-gate 	} else {
1344*7c478bd9Sstevel@tonic-gate 		Elf64_Phdr phdr;
1345*7c478bd9Sstevel@tonic-gate 
1346*7c478bd9Sstevel@tonic-gate 		bzero(&phdr, sizeof (phdr));
1347*7c478bd9Sstevel@tonic-gate 		phdr.p_type = PT_NOTE;
1348*7c478bd9Sstevel@tonic-gate 		phdr.p_flags = PF_R;
1349*7c478bd9Sstevel@tonic-gate 		phdr.p_offset = boff;
1350*7c478bd9Sstevel@tonic-gate 		phdr.p_filesz = doff - boff;
1351*7c478bd9Sstevel@tonic-gate 		boff = doff;
1352*7c478bd9Sstevel@tonic-gate 
1353*7c478bd9Sstevel@tonic-gate 		if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
1354*7c478bd9Sstevel@tonic-gate 			goto err;
1355*7c478bd9Sstevel@tonic-gate 		poff += sizeof (phdr);
1356*7c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
1357*7c478bd9Sstevel@tonic-gate 	}
1358*7c478bd9Sstevel@tonic-gate 
1359*7c478bd9Sstevel@tonic-gate 	/*
1360*7c478bd9Sstevel@tonic-gate 	 * Construct the headers for each mapping and write out its data
1361*7c478bd9Sstevel@tonic-gate 	 * if the content parameter indicates that it should be present
1362*7c478bd9Sstevel@tonic-gate 	 * in the core file.
1363*7c478bd9Sstevel@tonic-gate 	 */
1364*7c478bd9Sstevel@tonic-gate 	if (Pmapping_iter(P, dump_map, &pgc) != 0)
1365*7c478bd9Sstevel@tonic-gate 		goto err;
1366*7c478bd9Sstevel@tonic-gate 
1367*7c478bd9Sstevel@tonic-gate 	if (dump_sections(&pgc) != 0)
1368*7c478bd9Sstevel@tonic-gate 		goto err;
1369*7c478bd9Sstevel@tonic-gate 
1370*7c478bd9Sstevel@tonic-gate 	if (write_shstrtab(P, &pgc) != 0)
1371*7c478bd9Sstevel@tonic-gate 		goto err;
1372*7c478bd9Sstevel@tonic-gate 
1373*7c478bd9Sstevel@tonic-gate 	free(pgc.pgc_chunk);
1374*7c478bd9Sstevel@tonic-gate 
1375*7c478bd9Sstevel@tonic-gate 	return (0);
1376*7c478bd9Sstevel@tonic-gate 
1377*7c478bd9Sstevel@tonic-gate err:
1378*7c478bd9Sstevel@tonic-gate 	/*
1379*7c478bd9Sstevel@tonic-gate 	 * Wipe out anything we may have written if there was an error.
1380*7c478bd9Sstevel@tonic-gate 	 */
1381*7c478bd9Sstevel@tonic-gate 	(void) ftruncate64(fd, 0);
1382*7c478bd9Sstevel@tonic-gate 	free(pgc.pgc_chunk);
1383*7c478bd9Sstevel@tonic-gate 	return (-1);
1384*7c478bd9Sstevel@tonic-gate }
1385*7c478bd9Sstevel@tonic-gate 
1386*7c478bd9Sstevel@tonic-gate static const char *content_str[] = {
1387*7c478bd9Sstevel@tonic-gate 	"stack",	/* CC_CONTENT_STACK */
1388*7c478bd9Sstevel@tonic-gate 	"heap",		/* CC_CONTENT_HEAP */
1389*7c478bd9Sstevel@tonic-gate 	"shfile",	/* CC_CONTENT_SHFILE */
1390*7c478bd9Sstevel@tonic-gate 	"shanon",	/* CC_CONTENT_SHANON */
1391*7c478bd9Sstevel@tonic-gate 	"text",		/* CC_CONTENT_TEXT */
1392*7c478bd9Sstevel@tonic-gate 	"data",		/* CC_CONTENT_DATA */
1393*7c478bd9Sstevel@tonic-gate 	"rodata",	/* CC_CONTENT_RODATA */
1394*7c478bd9Sstevel@tonic-gate 	"anon",		/* CC_CONTENT_ANON */
1395*7c478bd9Sstevel@tonic-gate 	"shm",		/* CC_CONTENT_SHM */
1396*7c478bd9Sstevel@tonic-gate 	"ism",		/* CC_CONTENT_ISM */
1397*7c478bd9Sstevel@tonic-gate 	"dism",		/* CC_CONTENT_DISM */
1398*7c478bd9Sstevel@tonic-gate 	"ctf",		/* CC_CONTENT_CTF */
1399*7c478bd9Sstevel@tonic-gate 	"symtab",	/* CC_CONTENT_SYMTAB */
1400*7c478bd9Sstevel@tonic-gate };
1401*7c478bd9Sstevel@tonic-gate 
1402*7c478bd9Sstevel@tonic-gate static uint_t ncontent_str = sizeof (content_str) / sizeof (content_str[0]);
1403*7c478bd9Sstevel@tonic-gate 
1404*7c478bd9Sstevel@tonic-gate #define	STREQ(a, b, n)	(strlen(b) == (n) && strncmp(a, b, n) == 0)
1405*7c478bd9Sstevel@tonic-gate 
1406*7c478bd9Sstevel@tonic-gate int
1407*7c478bd9Sstevel@tonic-gate proc_str2content(const char *str, core_content_t *cp)
1408*7c478bd9Sstevel@tonic-gate {
1409*7c478bd9Sstevel@tonic-gate 	const char *cur = str;
1410*7c478bd9Sstevel@tonic-gate 	int add = 1;
1411*7c478bd9Sstevel@tonic-gate 	core_content_t mask, content = 0;
1412*7c478bd9Sstevel@tonic-gate 
1413*7c478bd9Sstevel@tonic-gate 	for (;;) {
1414*7c478bd9Sstevel@tonic-gate 		for (cur = str; isalpha(*cur); cur++)
1415*7c478bd9Sstevel@tonic-gate 			continue;
1416*7c478bd9Sstevel@tonic-gate 
1417*7c478bd9Sstevel@tonic-gate 		if (STREQ(str, "default", cur - str)) {
1418*7c478bd9Sstevel@tonic-gate 			mask = CC_CONTENT_DEFAULT;
1419*7c478bd9Sstevel@tonic-gate 		} else if (STREQ(str, "all", cur - str)) {
1420*7c478bd9Sstevel@tonic-gate 			mask = CC_CONTENT_ALL;
1421*7c478bd9Sstevel@tonic-gate 		} else if (STREQ(str, "none", cur - str)) {
1422*7c478bd9Sstevel@tonic-gate 			mask = 0;
1423*7c478bd9Sstevel@tonic-gate 		} else {
1424*7c478bd9Sstevel@tonic-gate 			int i = 0;
1425*7c478bd9Sstevel@tonic-gate 
1426*7c478bd9Sstevel@tonic-gate 			while (!STREQ(str, content_str[i], cur - str)) {
1427*7c478bd9Sstevel@tonic-gate 				i++;
1428*7c478bd9Sstevel@tonic-gate 
1429*7c478bd9Sstevel@tonic-gate 				if (i >= ncontent_str)
1430*7c478bd9Sstevel@tonic-gate 					return (-1);
1431*7c478bd9Sstevel@tonic-gate 			}
1432*7c478bd9Sstevel@tonic-gate 
1433*7c478bd9Sstevel@tonic-gate 			mask = (core_content_t)1 << i;
1434*7c478bd9Sstevel@tonic-gate 		}
1435*7c478bd9Sstevel@tonic-gate 
1436*7c478bd9Sstevel@tonic-gate 		if (add)
1437*7c478bd9Sstevel@tonic-gate 			content |= mask;
1438*7c478bd9Sstevel@tonic-gate 		else
1439*7c478bd9Sstevel@tonic-gate 			content &= ~mask;
1440*7c478bd9Sstevel@tonic-gate 
1441*7c478bd9Sstevel@tonic-gate 		switch (*cur) {
1442*7c478bd9Sstevel@tonic-gate 		case '\0':
1443*7c478bd9Sstevel@tonic-gate 			*cp = content;
1444*7c478bd9Sstevel@tonic-gate 			return (0);
1445*7c478bd9Sstevel@tonic-gate 		case '+':
1446*7c478bd9Sstevel@tonic-gate 			add = 1;
1447*7c478bd9Sstevel@tonic-gate 			break;
1448*7c478bd9Sstevel@tonic-gate 		case '-':
1449*7c478bd9Sstevel@tonic-gate 			add = 0;
1450*7c478bd9Sstevel@tonic-gate 			break;
1451*7c478bd9Sstevel@tonic-gate 		default:
1452*7c478bd9Sstevel@tonic-gate 			return (-1);
1453*7c478bd9Sstevel@tonic-gate 		}
1454*7c478bd9Sstevel@tonic-gate 
1455*7c478bd9Sstevel@tonic-gate 		str = cur + 1;
1456*7c478bd9Sstevel@tonic-gate 	}
1457*7c478bd9Sstevel@tonic-gate }
1458*7c478bd9Sstevel@tonic-gate 
1459*7c478bd9Sstevel@tonic-gate static int
1460*7c478bd9Sstevel@tonic-gate popc(core_content_t x)
1461*7c478bd9Sstevel@tonic-gate {
1462*7c478bd9Sstevel@tonic-gate 	int i;
1463*7c478bd9Sstevel@tonic-gate 
1464*7c478bd9Sstevel@tonic-gate 	for (i = 0; x != 0; i++)
1465*7c478bd9Sstevel@tonic-gate 		x &= x - 1;
1466*7c478bd9Sstevel@tonic-gate 
1467*7c478bd9Sstevel@tonic-gate 	return (i);
1468*7c478bd9Sstevel@tonic-gate }
1469*7c478bd9Sstevel@tonic-gate 
1470*7c478bd9Sstevel@tonic-gate int
1471*7c478bd9Sstevel@tonic-gate proc_content2str(core_content_t content, char *buf, size_t size)
1472*7c478bd9Sstevel@tonic-gate {
1473*7c478bd9Sstevel@tonic-gate 	int nonecnt, defcnt, allcnt;
1474*7c478bd9Sstevel@tonic-gate 	core_content_t mask, bit;
1475*7c478bd9Sstevel@tonic-gate 	int first;
1476*7c478bd9Sstevel@tonic-gate 	uint_t index;
1477*7c478bd9Sstevel@tonic-gate 	size_t n, tot = 0;
1478*7c478bd9Sstevel@tonic-gate 
1479*7c478bd9Sstevel@tonic-gate 	if (content == 0)
1480*7c478bd9Sstevel@tonic-gate 		return ((int)strlcpy(buf, "none", size));
1481*7c478bd9Sstevel@tonic-gate 
1482*7c478bd9Sstevel@tonic-gate 	if (content & ~CC_CONTENT_ALL)
1483*7c478bd9Sstevel@tonic-gate 		return ((int)strlcpy(buf, "<invalid>", size));
1484*7c478bd9Sstevel@tonic-gate 
1485*7c478bd9Sstevel@tonic-gate 	nonecnt = popc(content);
1486*7c478bd9Sstevel@tonic-gate 	defcnt = 1 + popc(content ^ CC_CONTENT_DEFAULT);
1487*7c478bd9Sstevel@tonic-gate 	allcnt = 1 + popc(content ^ CC_CONTENT_ALL);
1488*7c478bd9Sstevel@tonic-gate 
1489*7c478bd9Sstevel@tonic-gate 	if (defcnt <= nonecnt && defcnt <= allcnt) {
1490*7c478bd9Sstevel@tonic-gate 		mask = content ^ CC_CONTENT_DEFAULT;
1491*7c478bd9Sstevel@tonic-gate 		first = 0;
1492*7c478bd9Sstevel@tonic-gate 		tot += (n = strlcpy(buf, "default", size));
1493*7c478bd9Sstevel@tonic-gate 		if (n > size)
1494*7c478bd9Sstevel@tonic-gate 			n = size;
1495*7c478bd9Sstevel@tonic-gate 		buf += n;
1496*7c478bd9Sstevel@tonic-gate 		size -= n;
1497*7c478bd9Sstevel@tonic-gate 	} else if (allcnt < nonecnt) {
1498*7c478bd9Sstevel@tonic-gate 		mask = content ^ CC_CONTENT_ALL;
1499*7c478bd9Sstevel@tonic-gate 		first = 0;
1500*7c478bd9Sstevel@tonic-gate 		tot += (n = strlcpy(buf, "all", size));
1501*7c478bd9Sstevel@tonic-gate 		if (n > size)
1502*7c478bd9Sstevel@tonic-gate 			n = size;
1503*7c478bd9Sstevel@tonic-gate 		buf += n;
1504*7c478bd9Sstevel@tonic-gate 		size -= n;
1505*7c478bd9Sstevel@tonic-gate 	} else {
1506*7c478bd9Sstevel@tonic-gate 		mask = content;
1507*7c478bd9Sstevel@tonic-gate 		first = 1;
1508*7c478bd9Sstevel@tonic-gate 	}
1509*7c478bd9Sstevel@tonic-gate 
1510*7c478bd9Sstevel@tonic-gate 	while (mask != 0) {
1511*7c478bd9Sstevel@tonic-gate 		bit = mask ^ (mask & (mask - 1));
1512*7c478bd9Sstevel@tonic-gate 
1513*7c478bd9Sstevel@tonic-gate 		if (!first) {
1514*7c478bd9Sstevel@tonic-gate 			if (size > 1) {
1515*7c478bd9Sstevel@tonic-gate 				*buf = (bit & content) ? '+' : '-';
1516*7c478bd9Sstevel@tonic-gate 				buf++;
1517*7c478bd9Sstevel@tonic-gate 				size--;
1518*7c478bd9Sstevel@tonic-gate 			}
1519*7c478bd9Sstevel@tonic-gate 
1520*7c478bd9Sstevel@tonic-gate 			tot++;
1521*7c478bd9Sstevel@tonic-gate 		}
1522*7c478bd9Sstevel@tonic-gate 		index = popc(bit - 1);
1523*7c478bd9Sstevel@tonic-gate 		tot += (n = strlcpy(buf, content_str[index], size));
1524*7c478bd9Sstevel@tonic-gate 		if (n > size)
1525*7c478bd9Sstevel@tonic-gate 			n = size;
1526*7c478bd9Sstevel@tonic-gate 		buf += n;
1527*7c478bd9Sstevel@tonic-gate 		size -= n;
1528*7c478bd9Sstevel@tonic-gate 
1529*7c478bd9Sstevel@tonic-gate 		mask ^= bit;
1530*7c478bd9Sstevel@tonic-gate 		first = 0;
1531*7c478bd9Sstevel@tonic-gate 	}
1532*7c478bd9Sstevel@tonic-gate 
1533*7c478bd9Sstevel@tonic-gate 	return ((int)tot);
1534*7c478bd9Sstevel@tonic-gate }
1535