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