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