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