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