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