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