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