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