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