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