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  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 #include <stdlib.h>
     29 #include <ctype.h>
     30 #include <string.h>
     31 #include <strings.h>
     32 #include <errno.h>
     33 #include <procfs.h>
     34 #include <priv.h>
     35 #include <sys/elf.h>
     36 #include <sys/machelf.h>
     37 #include <sys/sysmacros.h>
     38 #include <sys/systeminfo.h>
     39 #include <sys/proc.h>
     40 #include <sys/utsname.h>
     41 
     42 #include <sys/old_procfs.h>
     43 
     44 #include "Pcontrol.h"
     45 #include "P32ton.h"
     46 
     47 typedef enum {
     48 	STR_NONE,
     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 	"",
     60 	".SUNW_ctf",
     61 	".symtab",
     62 	".dynsym",
     63 	".strtab",
     64 	".dynstr",
     65 	".shstrtab"
     66 };
     67 
     68 typedef struct shstrtab {
     69 	int	sst_ndx[STR_NUM];
     70 	int	sst_cur;
     71 } shstrtab_t;
     72 
     73 typedef struct {
     74 	struct ps_prochandle *P;
     75 	int		pgc_fd;
     76 	off64_t		*pgc_poff;
     77 	off64_t		*pgc_soff;
     78 	off64_t		*pgc_doff;
     79 	core_content_t	pgc_content;
     80 	void		*pgc_chunk;
     81 	size_t		pgc_chunksz;
     82 
     83 	shstrtab_t	pgc_shstrtab;
     84 } pgcore_t;
     85 
     86 static void
     87 shstrtab_init(shstrtab_t *s)
     88 {
     89 	bzero(&s->sst_ndx, sizeof (s->sst_ndx));
     90 	s->sst_cur = 1;
     91 }
     92 
     93 static int
     94 shstrtab_ndx(shstrtab_t *s, shstrtype_t type)
     95 {
     96 	int ret;
     97 
     98 	if ((ret = s->sst_ndx[type]) != 0 || type == STR_NONE)
     99 		return (ret);
    100 
    101 	ret = s->sst_ndx[type] = s->sst_cur;
    102 	s->sst_cur += strlen(shstrtab_data[type]) + 1;
    103 
    104 	return (ret);
    105 }
    106 
    107 static size_t
    108 shstrtab_size(const shstrtab_t *s)
    109 {
    110 	return (s->sst_cur);
    111 }
    112 
    113 int
    114 Pgcore(struct ps_prochandle *P, const char *fname, core_content_t content)
    115 {
    116 	int fd;
    117 	int err;
    118 
    119 	if ((fd = creat64(fname, 0666)) < 0)
    120 		return (-1);
    121 
    122 	if ((err = Pfgcore(P, fd, content)) != 0) {
    123 		(void) close(fd);
    124 		(void) unlink(fname);
    125 		return (err);
    126 	}
    127 
    128 	return (close(fd));
    129 }
    130 
    131 /*
    132  * Since we don't want to use the old-school procfs interfaces, we use the
    133  * new-style data structures we already have to construct the old-style
    134  * data structures. We include these data structures in core files for
    135  * backward compatability.
    136  */
    137 
    138 static void
    139 mkprstatus(struct ps_prochandle *P, const lwpstatus_t *lsp,
    140     const lwpsinfo_t *lip, prstatus_t *psp)
    141 {
    142 	bzero(psp, sizeof (*psp));
    143 
    144 	if (lsp->pr_flags & PR_STOPPED)
    145 		psp->pr_flags = 0x0001;
    146 	if (lsp->pr_flags & PR_ISTOP)
    147 		psp->pr_flags = 0x0002;
    148 	if (lsp->pr_flags & PR_DSTOP)
    149 		psp->pr_flags = 0x0004;
    150 	if (lsp->pr_flags & PR_ASLEEP)
    151 		psp->pr_flags = 0x0008;
    152 	if (lsp->pr_flags & PR_FORK)
    153 		psp->pr_flags = 0x0010;
    154 	if (lsp->pr_flags & PR_RLC)
    155 		psp->pr_flags = 0x0020;
    156 	/*
    157 	 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
    158 	 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
    159 	 */
    160 	if (lsp->pr_flags & PR_PCINVAL)
    161 		psp->pr_flags = 0x0080;
    162 	if (lsp->pr_flags & PR_ISSYS)
    163 		psp->pr_flags = 0x0100;
    164 	if (lsp->pr_flags & PR_STEP)
    165 		psp->pr_flags = 0x0200;
    166 	if (lsp->pr_flags & PR_KLC)
    167 		psp->pr_flags = 0x0400;
    168 	if (lsp->pr_flags & PR_ASYNC)
    169 		psp->pr_flags = 0x0800;
    170 	if (lsp->pr_flags & PR_PTRACE)
    171 		psp->pr_flags = 0x1000;
    172 	if (lsp->pr_flags & PR_MSACCT)
    173 		psp->pr_flags = 0x2000;
    174 	if (lsp->pr_flags & PR_BPTADJ)
    175 		psp->pr_flags = 0x4000;
    176 	if (lsp->pr_flags & PR_ASLWP)
    177 		psp->pr_flags = 0x8000;
    178 
    179 	psp->pr_why = lsp->pr_why;
    180 	psp->pr_what = lsp->pr_what;
    181 	psp->pr_info = lsp->pr_info;
    182 	psp->pr_cursig = lsp->pr_cursig;
    183 	psp->pr_nlwp = P->status.pr_nlwp;
    184 	psp->pr_sigpend = P->status.pr_sigpend;
    185 	psp->pr_sighold = lsp->pr_lwphold;
    186 	psp->pr_altstack = lsp->pr_altstack;
    187 	psp->pr_action = lsp->pr_action;
    188 	psp->pr_pid = P->status.pr_pid;
    189 	psp->pr_ppid = P->status.pr_ppid;
    190 	psp->pr_pgrp = P->status.pr_pgid;
    191 	psp->pr_sid = P->status.pr_sid;
    192 	psp->pr_utime = P->status.pr_utime;
    193 	psp->pr_stime = P->status.pr_stime;
    194 	psp->pr_cutime = P->status.pr_cutime;
    195 	psp->pr_cstime = P->status.pr_cstime;
    196 	(void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
    197 	psp->pr_syscall = lsp->pr_syscall;
    198 	psp->pr_nsysarg = lsp->pr_nsysarg;
    199 	bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg));
    200 	psp->pr_who = lsp->pr_lwpid;
    201 	psp->pr_lwppend = lsp->pr_lwppend;
    202 	psp->pr_oldcontext = (ucontext_t *)lsp->pr_oldcontext;
    203 	psp->pr_brkbase = (caddr_t)P->status.pr_brkbase;
    204 	psp->pr_brksize = P->status.pr_brksize;
    205 	psp->pr_stkbase = (caddr_t)P->status.pr_stkbase;
    206 	psp->pr_stksize = P->status.pr_stksize;
    207 	psp->pr_processor = (short)lip->pr_onpro;
    208 	psp->pr_bind = (short)lip->pr_bindpro;
    209 	psp->pr_instr = lsp->pr_instr;
    210 	bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
    211 }
    212 
    213 static void
    214 mkprpsinfo(struct ps_prochandle *P, prpsinfo_t *psp)
    215 {
    216 	bzero(psp, sizeof (*psp));
    217 	psp->pr_state = P->psinfo.pr_lwp.pr_state;
    218 	psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
    219 	psp->pr_zomb = (psp->pr_state == SZOMB);
    220 	psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
    221 	psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
    222 	psp->pr_uid = P->psinfo.pr_uid;
    223 	psp->pr_gid = P->psinfo.pr_gid;
    224 	psp->pr_pid = P->psinfo.pr_pid;
    225 	psp->pr_ppid = P->psinfo.pr_ppid;
    226 	psp->pr_pgrp = P->psinfo.pr_pgid;
    227 	psp->pr_sid = P->psinfo.pr_sid;
    228 	psp->pr_addr = (caddr_t)P->psinfo.pr_addr;
    229 	psp->pr_size = P->psinfo.pr_size;
    230 	psp->pr_rssize = P->psinfo.pr_rssize;
    231 	psp->pr_wchan = (caddr_t)P->psinfo.pr_lwp.pr_wchan;
    232 	psp->pr_start = P->psinfo.pr_start;
    233 	psp->pr_time = P->psinfo.pr_time;
    234 	psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
    235 	psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
    236 	psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
    237 	psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
    238 	psp->pr_lttydev = P->psinfo.pr_ttydev;
    239 	(void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
    240 	    sizeof (psp->pr_clname));
    241 	(void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
    242 	    sizeof (psp->pr_fname));
    243 	bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
    244 	    sizeof (psp->pr_psargs));
    245 	psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
    246 	psp->pr_ctime = P->psinfo.pr_ctime;
    247 	psp->pr_bysize = psp->pr_size * PAGESIZE;
    248 	psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
    249 	psp->pr_argc = P->psinfo.pr_argc;
    250 	psp->pr_argv = (char **)P->psinfo.pr_argv;
    251 	psp->pr_envp = (char **)P->psinfo.pr_envp;
    252 	psp->pr_wstat = P->psinfo.pr_wstat;
    253 	psp->pr_pctcpu = P->psinfo.pr_pctcpu;
    254 	psp->pr_pctmem = P->psinfo.pr_pctmem;
    255 	psp->pr_euid = P->psinfo.pr_euid;
    256 	psp->pr_egid = P->psinfo.pr_egid;
    257 	psp->pr_aslwpid = 0;
    258 	psp->pr_dmodel = P->psinfo.pr_dmodel;
    259 }
    260 
    261 #ifdef _LP64
    262 
    263 static void
    264 mkprstatus32(struct ps_prochandle *P, const lwpstatus_t *lsp,
    265     const lwpsinfo_t *lip, prstatus32_t *psp)
    266 {
    267 	bzero(psp, sizeof (*psp));
    268 
    269 	if (lsp->pr_flags & PR_STOPPED)
    270 		psp->pr_flags = 0x0001;
    271 	if (lsp->pr_flags & PR_ISTOP)
    272 		psp->pr_flags = 0x0002;
    273 	if (lsp->pr_flags & PR_DSTOP)
    274 		psp->pr_flags = 0x0004;
    275 	if (lsp->pr_flags & PR_ASLEEP)
    276 		psp->pr_flags = 0x0008;
    277 	if (lsp->pr_flags & PR_FORK)
    278 		psp->pr_flags = 0x0010;
    279 	if (lsp->pr_flags & PR_RLC)
    280 		psp->pr_flags = 0x0020;
    281 	/*
    282 	 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
    283 	 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
    284 	 */
    285 	if (lsp->pr_flags & PR_PCINVAL)
    286 		psp->pr_flags = 0x0080;
    287 	if (lsp->pr_flags & PR_ISSYS)
    288 		psp->pr_flags = 0x0100;
    289 	if (lsp->pr_flags & PR_STEP)
    290 		psp->pr_flags = 0x0200;
    291 	if (lsp->pr_flags & PR_KLC)
    292 		psp->pr_flags = 0x0400;
    293 	if (lsp->pr_flags & PR_ASYNC)
    294 		psp->pr_flags = 0x0800;
    295 	if (lsp->pr_flags & PR_PTRACE)
    296 		psp->pr_flags = 0x1000;
    297 	if (lsp->pr_flags & PR_MSACCT)
    298 		psp->pr_flags = 0x2000;
    299 	if (lsp->pr_flags & PR_BPTADJ)
    300 		psp->pr_flags = 0x4000;
    301 	if (lsp->pr_flags & PR_ASLWP)
    302 		psp->pr_flags = 0x8000;
    303 
    304 	psp->pr_why = lsp->pr_why;
    305 	psp->pr_what = lsp->pr_what;
    306 	siginfo_n_to_32(&lsp->pr_info, &psp->pr_info);
    307 	psp->pr_cursig = lsp->pr_cursig;
    308 	psp->pr_nlwp = P->status.pr_nlwp;
    309 	psp->pr_sigpend = P->status.pr_sigpend;
    310 	psp->pr_sighold = lsp->pr_lwphold;
    311 	stack_n_to_32(&lsp->pr_altstack, &psp->pr_altstack);
    312 	sigaction_n_to_32(&lsp->pr_action, &psp->pr_action);
    313 	psp->pr_pid = P->status.pr_pid;
    314 	psp->pr_ppid = P->status.pr_ppid;
    315 	psp->pr_pgrp = P->status.pr_pgid;
    316 	psp->pr_sid = P->status.pr_sid;
    317 	timestruc_n_to_32(&P->status.pr_utime, &psp->pr_utime);
    318 	timestruc_n_to_32(&P->status.pr_stime, &psp->pr_stime);
    319 	timestruc_n_to_32(&P->status.pr_cutime, &psp->pr_cutime);
    320 	timestruc_n_to_32(&P->status.pr_cstime, &psp->pr_cstime);
    321 	(void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
    322 	psp->pr_syscall = lsp->pr_syscall;
    323 	psp->pr_nsysarg = lsp->pr_nsysarg;
    324 	bcopy(lsp->pr_sysarg, psp->pr_sysarg,
    325 	    sizeof (psp->pr_sysarg)); psp->pr_who = lsp->pr_lwpid;
    326 	psp->pr_lwppend = lsp->pr_lwppend;
    327 	psp->pr_oldcontext = (caddr32_t)lsp->pr_oldcontext;
    328 	psp->pr_brkbase = (caddr32_t)P->status.pr_brkbase;
    329 	psp->pr_brksize = P->status.pr_brksize;
    330 	psp->pr_stkbase = (caddr32_t)P->status.pr_stkbase;
    331 	psp->pr_stksize = P->status.pr_stksize;
    332 	psp->pr_processor = (short)lip->pr_onpro;
    333 	psp->pr_bind = (short)lip->pr_bindpro;
    334 	psp->pr_instr = lsp->pr_instr;
    335 	bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
    336 }
    337 
    338 static void
    339 mkprpsinfo32(struct ps_prochandle *P, prpsinfo32_t *psp)
    340 {
    341 	bzero(psp, sizeof (*psp));
    342 	psp->pr_state = P->psinfo.pr_lwp.pr_state;
    343 	psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
    344 	psp->pr_zomb = (psp->pr_state == SZOMB);
    345 	psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
    346 	psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
    347 	psp->pr_uid = P->psinfo.pr_uid;
    348 	psp->pr_gid = P->psinfo.pr_gid;
    349 	psp->pr_pid = P->psinfo.pr_pid;
    350 	psp->pr_ppid = P->psinfo.pr_ppid;
    351 	psp->pr_pgrp = P->psinfo.pr_pgid;
    352 	psp->pr_sid = P->psinfo.pr_sid;
    353 	psp->pr_addr = (caddr32_t)P->psinfo.pr_addr;
    354 	psp->pr_size = P->psinfo.pr_size;
    355 	psp->pr_rssize = P->psinfo.pr_rssize;
    356 	psp->pr_wchan = (caddr32_t)P->psinfo.pr_lwp.pr_wchan;
    357 	timestruc_n_to_32(&P->psinfo.pr_start, &psp->pr_start);
    358 	timestruc_n_to_32(&P->psinfo.pr_time, &psp->pr_time);
    359 	psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
    360 	psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
    361 	psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
    362 	psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
    363 	psp->pr_lttydev = prcmpldev(P->psinfo.pr_ttydev);
    364 	(void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
    365 	    sizeof (psp->pr_clname));
    366 	(void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
    367 	    sizeof (psp->pr_fname));
    368 	bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
    369 	    sizeof (psp->pr_psargs));
    370 	psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
    371 	timestruc_n_to_32(&P->psinfo.pr_ctime, &psp->pr_ctime);
    372 	psp->pr_bysize = psp->pr_size * PAGESIZE;
    373 	psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
    374 	psp->pr_argc = P->psinfo.pr_argc;
    375 	psp->pr_argv = (caddr32_t)P->psinfo.pr_argv;
    376 	psp->pr_envp = (caddr32_t)P->psinfo.pr_envp;
    377 	psp->pr_wstat = P->psinfo.pr_wstat;
    378 	psp->pr_pctcpu = P->psinfo.pr_pctcpu;
    379 	psp->pr_pctmem = P->psinfo.pr_pctmem;
    380 	psp->pr_euid = P->psinfo.pr_euid;
    381 	psp->pr_egid = P->psinfo.pr_egid;
    382 	psp->pr_aslwpid = 0;
    383 	psp->pr_dmodel = P->psinfo.pr_dmodel;
    384 }
    385 
    386 #endif	/* _LP64 */
    387 
    388 static int
    389 write_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp)
    390 {
    391 	/*
    392 	 * Note headers are the same regardless of the data model of the
    393 	 * ELF file; we arbitrarily use Elf64_Nhdr here.
    394 	 */
    395 	struct {
    396 		Elf64_Nhdr nhdr;
    397 		char name[8];
    398 	} n;
    399 
    400 	bzero(&n, sizeof (n));
    401 	bcopy("CORE", n.name, 4);
    402 	n.nhdr.n_type = type;
    403 	n.nhdr.n_namesz = 5;
    404 	n.nhdr.n_descsz = roundup(descsz, 4);
    405 
    406 	if (pwrite64(fd, &n, sizeof (n), *offp) != sizeof (n))
    407 		return (-1);
    408 
    409 	*offp += sizeof (n);
    410 
    411 	if (pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != n.nhdr.n_descsz)
    412 		return (-1);
    413 
    414 	*offp += n.nhdr.n_descsz;
    415 
    416 	return (0);
    417 }
    418 
    419 static int
    420 old_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
    421 {
    422 	pgcore_t *pgc = data;
    423 	struct ps_prochandle *P = pgc->P;
    424 
    425 	/*
    426 	 * Legacy core files don't contain information about zombie LWPs.
    427 	 * We use Plwp_iter_all() so that we get the lwpsinfo_t structure
    428 	 * more cheaply.
    429 	 */
    430 	if (lsp == NULL)
    431 		return (0);
    432 
    433 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
    434 		prstatus_t prstatus;
    435 		mkprstatus(P, lsp, lip, &prstatus);
    436 		if (write_note(pgc->pgc_fd, NT_PRSTATUS, &prstatus,
    437 		    sizeof (prstatus_t), pgc->pgc_doff) != 0)
    438 			return (0);
    439 		if (write_note(pgc->pgc_fd, NT_PRFPREG, &lsp->pr_fpreg,
    440 		    sizeof (prfpregset_t), pgc->pgc_doff) != 0)
    441 			return (1);
    442 #ifdef _LP64
    443 	} else {
    444 		prstatus32_t pr32;
    445 		prfpregset32_t pf32;
    446 		mkprstatus32(P, lsp, lip, &pr32);
    447 		if (write_note(pgc->pgc_fd, NT_PRSTATUS, &pr32,
    448 		    sizeof (prstatus32_t), pgc->pgc_doff) != 0)
    449 			return (1);
    450 		prfpregset_n_to_32(&lsp->pr_fpreg, &pf32);
    451 		if (write_note(pgc->pgc_fd, NT_PRFPREG, &pf32,
    452 		    sizeof (prfpregset32_t), pgc->pgc_doff) != 0)
    453 			return (1);
    454 #endif	/* _LP64 */
    455 	}
    456 
    457 #ifdef sparc
    458 	{
    459 		prxregset_t xregs;
    460 		if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0 &&
    461 		    write_note(pgc->pgc_fd, NT_PRXREG, &xregs,
    462 		    sizeof (prxregset_t), pgc->pgc_doff) != 0)
    463 			return (1);
    464 	}
    465 #endif	/* sparc */
    466 
    467 	return (0);
    468 }
    469 
    470 static int
    471 new_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
    472 {
    473 	pgcore_t *pgc = data;
    474 	struct ps_prochandle *P = pgc->P;
    475 
    476 	/*
    477 	 * If lsp is NULL this indicates that this is a zombie LWP in
    478 	 * which case we dump only the lwpsinfo_t structure and none of
    479 	 * the other ancillary LWP state data.
    480 	 */
    481 	if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
    482 		if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip,
    483 		    sizeof (lwpsinfo_t), pgc->pgc_doff) != 0)
    484 			return (1);
    485 		if (lsp == NULL)
    486 			return (0);
    487 		if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp,
    488 		    sizeof (lwpstatus_t), pgc->pgc_doff) != 0)
    489 			return (1);
    490 #ifdef _LP64
    491 	} else {
    492 		lwpsinfo32_t li32;
    493 		lwpstatus32_t ls32;
    494 		lwpsinfo_n_to_32(lip, &li32);
    495 		if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32,
    496 		    sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0)
    497 			return (1);
    498 		if (lsp == NULL)
    499 			return (0);
    500 		lwpstatus_n_to_32(lsp, &ls32);
    501 		if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32,
    502 		    sizeof (lwpstatus32_t), pgc->pgc_doff) != 0)
    503 			return (1);
    504 #endif	/* _LP64 */
    505 	}
    506 
    507 #ifdef sparc
    508 	{
    509 		prxregset_t xregs;
    510 		gwindows_t gwins;
    511 		size_t size;
    512 
    513 		if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0) {
    514 			if (write_note(pgc->pgc_fd, NT_PRXREG, &xregs,
    515 			    sizeof (prxregset_t), pgc->pgc_doff) != 0)
    516 				return (1);
    517 		}
    518 
    519 		if (Plwp_getgwindows(P, lsp->pr_lwpid, &gwins) == 0 &&
    520 		    gwins.wbcnt > 0) {
    521 			size = sizeof (gwins) - sizeof (gwins.wbuf) +
    522 			    gwins.wbcnt * sizeof (gwins.wbuf[0]);
    523 
    524 			if (write_note(pgc->pgc_fd, NT_GWINDOWS, &gwins, size,
    525 			    pgc->pgc_doff) != 0)
    526 				return (1);
    527 		}
    528 
    529 	}
    530 #ifdef __sparcv9
    531 	if (P->status.pr_dmodel == PR_MODEL_LP64) {
    532 		asrset_t asrs;
    533 		if (Plwp_getasrs(P, lsp->pr_lwpid, asrs) == 0) {
    534 			if (write_note(pgc->pgc_fd, NT_ASRS, &asrs,
    535 			    sizeof (asrset_t), pgc->pgc_doff) != 0)
    536 				return (1);
    537 		}
    538 	}
    539 #endif	/* __sparcv9 */
    540 #endif	/* sparc */
    541 
    542 	return (0);
    543 }
    544 
    545 static uint_t
    546 count_sections(pgcore_t *pgc)
    547 {
    548 	struct ps_prochandle *P = pgc->P;
    549 	file_info_t *fptr;
    550 	uint_t cnt;
    551 	uint_t nshdrs = 0;
    552 
    553 	if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)))
    554 		return (0);
    555 
    556 	fptr = list_next(&P->file_head);
    557 	for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) {
    558 		int hit_symtab = 0;
    559 
    560 		Pbuild_file_symtab(P, fptr);
    561 
    562 		if ((pgc->pgc_content & CC_CONTENT_CTF) &&
    563 		    Pbuild_file_ctf(P, fptr) != NULL) {
    564 			sym_tbl_t *sym;
    565 
    566 			nshdrs++;
    567 
    568 			if (fptr->file_ctf_dyn) {
    569 				sym = &fptr->file_dynsym;
    570 			} else {
    571 				sym = &fptr->file_symtab;
    572 				hit_symtab = 1;
    573 			}
    574 
    575 			if (sym->sym_data_pri != NULL && sym->sym_symn != 0 &&
    576 			    sym->sym_strs != NULL)
    577 				nshdrs += 2;
    578 		}
    579 
    580 		if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
    581 		    fptr->file_symtab.sym_data_pri != NULL &&
    582 		    fptr->file_symtab.sym_symn != 0 &&
    583 		    fptr->file_symtab.sym_strs != NULL) {
    584 			nshdrs += 2;
    585 		}
    586 	}
    587 
    588 	return (nshdrs == 0 ? 0 : nshdrs + 2);
    589 }
    590 
    591 static int
    592 write_shdr(pgcore_t *pgc, shstrtype_t name, uint_t type, ulong_t flags,
    593     uintptr_t addr, ulong_t offset, size_t size, uint_t link, uint_t info,
    594     uintptr_t addralign, uintptr_t entsize)
    595 {
    596 	if (pgc->P->status.pr_dmodel == PR_MODEL_ILP32) {
    597 		Elf32_Shdr shdr;
    598 
    599 		bzero(&shdr, sizeof (shdr));
    600 		shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name);
    601 		shdr.sh_type = type;
    602 		shdr.sh_flags = flags;
    603 		shdr.sh_addr = (Elf32_Addr)addr;
    604 		shdr.sh_offset = offset;
    605 		shdr.sh_size = size;
    606 		shdr.sh_link = link;
    607 		shdr.sh_info = info;
    608 		shdr.sh_addralign = addralign;
    609 		shdr.sh_entsize = entsize;
    610 
    611 		if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
    612 		    *pgc->pgc_soff) != sizeof (shdr))
    613 			return (-1);
    614 
    615 		*pgc->pgc_soff += sizeof (shdr);
    616 #ifdef _LP64
    617 	} else {
    618 		Elf64_Shdr shdr;
    619 
    620 		bzero(&shdr, sizeof (shdr));
    621 		shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name);
    622 		shdr.sh_type = type;
    623 		shdr.sh_flags = flags;
    624 		shdr.sh_addr = addr;
    625 		shdr.sh_offset = offset;
    626 		shdr.sh_size = size;
    627 		shdr.sh_link = link;
    628 		shdr.sh_info = info;
    629 		shdr.sh_addralign = addralign;
    630 		shdr.sh_entsize = entsize;
    631 
    632 		if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
    633 		    *pgc->pgc_soff) != sizeof (shdr))
    634 			return (-1);
    635 
    636 		*pgc->pgc_soff += sizeof (shdr);
    637 #endif	/* _LP64 */
    638 	}
    639 
    640 	return (0);
    641 }
    642 
    643 static int
    644 dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym)
    645 {
    646 	sym_tbl_t *sym = dynsym ? &fptr->file_dynsym : &fptr->file_symtab;
    647 	shstrtype_t symname = dynsym ? STR_DYNSYM : STR_SYMTAB;
    648 	shstrtype_t strname = dynsym ? STR_DYNSTR : STR_STRTAB;
    649 	uint_t symtype = dynsym ? SHT_DYNSYM : SHT_SYMTAB;
    650 	size_t size;
    651 	uintptr_t addr = fptr->file_map->map_pmap.pr_vaddr;
    652 
    653 	if (sym->sym_data_pri == NULL || sym->sym_symn == 0 ||
    654 	    sym->sym_strs == NULL)
    655 		return (0);
    656 
    657 	size = sym->sym_hdr_pri.sh_size;
    658 	if (pwrite64(pgc->pgc_fd, sym->sym_data_pri->d_buf, size,
    659 	    *pgc->pgc_doff) != size)
    660 		return (-1);
    661 
    662 	if (write_shdr(pgc, symname, symtype, 0, addr, *pgc->pgc_doff, size,
    663 	    index + 1, sym->sym_hdr_pri.sh_info, sym->sym_hdr_pri.sh_addralign,
    664 	    sym->sym_hdr_pri.sh_entsize) != 0)
    665 		return (-1);
    666 
    667 	*pgc->pgc_doff += roundup(size, 8);
    668 
    669 	size = sym->sym_strhdr.sh_size;
    670 	if (pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != size)
    671 		return (-1);
    672 
    673 	if (write_shdr(pgc, strname, SHT_STRTAB, SHF_STRINGS, addr,
    674 	    *pgc->pgc_doff, size, 0, 0, 1, 0) != 0)
    675 		return (-1);
    676 
    677 	*pgc->pgc_doff += roundup(size, 8);
    678 
    679 	return (0);
    680 }
    681 
    682 static int
    683 dump_sections(pgcore_t *pgc)
    684 {
    685 	struct ps_prochandle *P = pgc->P;
    686 	file_info_t *fptr;
    687 	uint_t cnt;
    688 	uint_t index = 1;
    689 
    690 	if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)))
    691 		return (0);
    692 
    693 	fptr = list_next(&P->file_head);
    694 	for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) {
    695 		int hit_symtab = 0;
    696 
    697 		Pbuild_file_symtab(P, fptr);
    698 
    699 		if ((pgc->pgc_content & CC_CONTENT_CTF) &&
    700 		    Pbuild_file_ctf(P, fptr) != NULL) {
    701 			sym_tbl_t *sym;
    702 			uint_t dynsym;
    703 			uint_t symindex = 0;
    704 
    705 			/*
    706 			 * Write the symtab out first so we can correctly
    707 			 * set the sh_link field in the CTF section header.
    708 			 * symindex will be 0 if there is no corresponding
    709 			 * symbol table section.
    710 			 */
    711 			if (fptr->file_ctf_dyn) {
    712 				sym = &fptr->file_dynsym;
    713 				dynsym = 1;
    714 			} else {
    715 				sym = &fptr->file_symtab;
    716 				dynsym = 0;
    717 				hit_symtab = 1;
    718 			}
    719 
    720 			if (sym->sym_data_pri != NULL && sym->sym_symn != 0 &&
    721 			    sym->sym_strs != NULL) {
    722 				symindex = index;
    723 				if (dump_symtab(pgc, fptr, index, dynsym) != 0)
    724 				    return (-1);
    725 				index += 2;
    726 			}
    727 
    728 			/*
    729 			 * Write the CTF data that we've read out of the
    730 			 * file itself into the core file.
    731 			 */
    732 			if (pwrite64(pgc->pgc_fd, fptr->file_ctf_buf,
    733 			    fptr->file_ctf_size, *pgc->pgc_doff) !=
    734 			    fptr->file_ctf_size)
    735 				return (-1);
    736 
    737 			if (write_shdr(pgc, STR_CTF, SHT_PROGBITS, 0,
    738 			    fptr->file_map->map_pmap.pr_vaddr, *pgc->pgc_doff,
    739 			    fptr->file_ctf_size, symindex, 0, 4, 0) != 0)
    740 				return (-1);
    741 
    742 			index++;
    743 			*pgc->pgc_doff += roundup(fptr->file_ctf_size, 8);
    744 		}
    745 
    746 		if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
    747 		    fptr->file_symtab.sym_data_pri != NULL &&
    748 		    fptr->file_symtab.sym_symn != 0 &&
    749 		    fptr->file_symtab.sym_strs != NULL) {
    750 			if (dump_symtab(pgc, fptr, index, 0) != 0)
    751 				return (-1);
    752 			index += 2;
    753 		}
    754 	}
    755 
    756 	return (0);
    757 }
    758 
    759 /*ARGSUSED*/
    760 static int
    761 dump_map(void *data, const prmap_t *pmp, const char *name)
    762 {
    763 	pgcore_t *pgc = data;
    764 	struct ps_prochandle *P = pgc->P;
    765 #ifdef _LP64
    766 	Elf64_Phdr phdr;
    767 #else
    768 	Elf32_Phdr phdr;
    769 #endif
    770 	size_t n;
    771 
    772 	bzero(&phdr, sizeof (phdr));
    773 	phdr.p_type = PT_LOAD;
    774 	phdr.p_vaddr = pmp->pr_vaddr;
    775 	phdr.p_memsz = pmp->pr_size;
    776 	if (pmp->pr_mflags & MA_READ)
    777 		phdr.p_flags |= PF_R;
    778 	if (pmp->pr_mflags & MA_WRITE)
    779 		phdr.p_flags |= PF_W;
    780 	if (pmp->pr_mflags & MA_EXEC)
    781 		phdr.p_flags |= PF_X;
    782 
    783 	if (pmp->pr_vaddr + pmp->pr_size > P->status.pr_stkbase &&
    784 	    pmp->pr_vaddr < P->status.pr_stkbase + P->status.pr_stksize) {
    785 		if (!(pgc->pgc_content & CC_CONTENT_STACK))
    786 			goto exclude;
    787 
    788 	} else if ((pmp->pr_mflags & MA_ANON) &&
    789 	    pmp->pr_vaddr + pmp->pr_size > P->status.pr_brkbase &&
    790 	    pmp->pr_vaddr < P->status.pr_brkbase + P->status.pr_brksize) {
    791 		if (!(pgc->pgc_content & CC_CONTENT_HEAP))
    792 			goto exclude;
    793 
    794 	} else if (pmp->pr_mflags & MA_ISM) {
    795 		if (pmp->pr_mflags & MA_NORESERVE) {
    796 			if (!(pgc->pgc_content & CC_CONTENT_DISM))
    797 				goto exclude;
    798 		} else {
    799 			if (!(pgc->pgc_content & CC_CONTENT_ISM))
    800 				goto exclude;
    801 		}
    802 
    803 	} else if (pmp->pr_mflags & MA_SHM) {
    804 		if (!(pgc->pgc_content & CC_CONTENT_SHM))
    805 			goto exclude;
    806 
    807 	} else if (pmp->pr_mflags & MA_SHARED) {
    808 		if (pmp->pr_mflags & MA_ANON) {
    809 			if (!(pgc->pgc_content & CC_CONTENT_SHANON))
    810 				goto exclude;
    811 		} else {
    812 			if (!(pgc->pgc_content & CC_CONTENT_SHFILE))
    813 				goto exclude;
    814 		}
    815 
    816 	} else if (pmp->pr_mflags & MA_ANON) {
    817 		if (!(pgc->pgc_content & CC_CONTENT_ANON))
    818 			goto exclude;
    819 
    820 	} else if (phdr.p_flags == (PF_R | PF_X)) {
    821 		if (!(pgc->pgc_content & CC_CONTENT_TEXT))
    822 			goto exclude;
    823 
    824 	} else if (phdr.p_flags == PF_R) {
    825 		if (!(pgc->pgc_content & CC_CONTENT_RODATA))
    826 			goto exclude;
    827 
    828 	} else {
    829 		if (!(pgc->pgc_content & CC_CONTENT_DATA))
    830 			goto exclude;
    831 	}
    832 
    833 	n = 0;
    834 	while (n < pmp->pr_size) {
    835 		size_t csz = MIN(pmp->pr_size - n, pgc->pgc_chunksz);
    836 
    837 		/*
    838 		 * If we can't read out part of the victim's address
    839 		 * space for some reason ignore that failure and try to
    840 		 * emit a partial core file without that mapping's data.
    841 		 * As in the kernel, we mark these failures with the
    842 		 * PF_SUNW_FAILURE flag and store the errno where the
    843 		 * mapping would have been.
    844 		 */
    845 		if (Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n) !=