10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
53347Sab196087 * Common Development and Distribution License (the "License").
63347Sab196087 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*11135SRoger.Faulkner@Sun.COM
220Sstevel@tonic-gate /*
23*11135SRoger.Faulkner@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
27*11135SRoger.Faulkner@Sun.COM #define _STRUCTURED_PROC 1
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <stdlib.h>
300Sstevel@tonic-gate #include <ctype.h>
310Sstevel@tonic-gate #include <string.h>
320Sstevel@tonic-gate #include <strings.h>
330Sstevel@tonic-gate #include <errno.h>
340Sstevel@tonic-gate #include <procfs.h>
350Sstevel@tonic-gate #include <priv.h>
360Sstevel@tonic-gate #include <sys/elf.h>
370Sstevel@tonic-gate #include <sys/machelf.h>
380Sstevel@tonic-gate #include <sys/sysmacros.h>
390Sstevel@tonic-gate #include <sys/systeminfo.h>
400Sstevel@tonic-gate #include <sys/proc.h>
410Sstevel@tonic-gate #include <sys/utsname.h>
420Sstevel@tonic-gate
430Sstevel@tonic-gate #include <sys/old_procfs.h>
440Sstevel@tonic-gate
450Sstevel@tonic-gate #include "Pcontrol.h"
460Sstevel@tonic-gate #include "P32ton.h"
470Sstevel@tonic-gate
480Sstevel@tonic-gate typedef enum {
49942Sahl STR_NONE,
500Sstevel@tonic-gate STR_CTF,
510Sstevel@tonic-gate STR_SYMTAB,
520Sstevel@tonic-gate STR_DYNSYM,
530Sstevel@tonic-gate STR_STRTAB,
540Sstevel@tonic-gate STR_DYNSTR,
550Sstevel@tonic-gate STR_SHSTRTAB,
560Sstevel@tonic-gate STR_NUM
570Sstevel@tonic-gate } shstrtype_t;
580Sstevel@tonic-gate
590Sstevel@tonic-gate static const char *shstrtab_data[] = {
60942Sahl "",
610Sstevel@tonic-gate ".SUNW_ctf",
620Sstevel@tonic-gate ".symtab",
630Sstevel@tonic-gate ".dynsym",
640Sstevel@tonic-gate ".strtab",
650Sstevel@tonic-gate ".dynstr",
660Sstevel@tonic-gate ".shstrtab"
670Sstevel@tonic-gate };
680Sstevel@tonic-gate
690Sstevel@tonic-gate typedef struct shstrtab {
700Sstevel@tonic-gate int sst_ndx[STR_NUM];
710Sstevel@tonic-gate int sst_cur;
720Sstevel@tonic-gate } shstrtab_t;
730Sstevel@tonic-gate
740Sstevel@tonic-gate typedef struct {
750Sstevel@tonic-gate struct ps_prochandle *P;
760Sstevel@tonic-gate int pgc_fd;
770Sstevel@tonic-gate off64_t *pgc_poff;
780Sstevel@tonic-gate off64_t *pgc_soff;
790Sstevel@tonic-gate off64_t *pgc_doff;
800Sstevel@tonic-gate core_content_t pgc_content;
810Sstevel@tonic-gate void *pgc_chunk;
820Sstevel@tonic-gate size_t pgc_chunksz;
830Sstevel@tonic-gate
840Sstevel@tonic-gate shstrtab_t pgc_shstrtab;
850Sstevel@tonic-gate } pgcore_t;
860Sstevel@tonic-gate
870Sstevel@tonic-gate static void
shstrtab_init(shstrtab_t * s)880Sstevel@tonic-gate shstrtab_init(shstrtab_t *s)
890Sstevel@tonic-gate {
900Sstevel@tonic-gate bzero(&s->sst_ndx, sizeof (s->sst_ndx));
910Sstevel@tonic-gate s->sst_cur = 1;
920Sstevel@tonic-gate }
930Sstevel@tonic-gate
940Sstevel@tonic-gate static int
shstrtab_ndx(shstrtab_t * s,shstrtype_t type)950Sstevel@tonic-gate shstrtab_ndx(shstrtab_t *s, shstrtype_t type)
960Sstevel@tonic-gate {
970Sstevel@tonic-gate int ret;
980Sstevel@tonic-gate
99942Sahl if ((ret = s->sst_ndx[type]) != 0 || type == STR_NONE)
1000Sstevel@tonic-gate return (ret);
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate ret = s->sst_ndx[type] = s->sst_cur;
1030Sstevel@tonic-gate s->sst_cur += strlen(shstrtab_data[type]) + 1;
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate return (ret);
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate static size_t
shstrtab_size(const shstrtab_t * s)1090Sstevel@tonic-gate shstrtab_size(const shstrtab_t *s)
1100Sstevel@tonic-gate {
1110Sstevel@tonic-gate return (s->sst_cur);
1120Sstevel@tonic-gate }
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate int
Pgcore(struct ps_prochandle * P,const char * fname,core_content_t content)1150Sstevel@tonic-gate Pgcore(struct ps_prochandle *P, const char *fname, core_content_t content)
1160Sstevel@tonic-gate {
1170Sstevel@tonic-gate int fd;
1180Sstevel@tonic-gate int err;
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate if ((fd = creat64(fname, 0666)) < 0)
1210Sstevel@tonic-gate return (-1);
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate if ((err = Pfgcore(P, fd, content)) != 0) {
1240Sstevel@tonic-gate (void) close(fd);
1250Sstevel@tonic-gate (void) unlink(fname);
1260Sstevel@tonic-gate return (err);
1270Sstevel@tonic-gate }
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate return (close(fd));
1300Sstevel@tonic-gate }
1310Sstevel@tonic-gate
1320Sstevel@tonic-gate /*
1330Sstevel@tonic-gate * Since we don't want to use the old-school procfs interfaces, we use the
1340Sstevel@tonic-gate * new-style data structures we already have to construct the old-style
1350Sstevel@tonic-gate * data structures. We include these data structures in core files for
1360Sstevel@tonic-gate * backward compatability.
1370Sstevel@tonic-gate */
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate static void
mkprstatus(struct ps_prochandle * P,const lwpstatus_t * lsp,const lwpsinfo_t * lip,prstatus_t * psp)1400Sstevel@tonic-gate mkprstatus(struct ps_prochandle *P, const lwpstatus_t *lsp,
1410Sstevel@tonic-gate const lwpsinfo_t *lip, prstatus_t *psp)
1420Sstevel@tonic-gate {
1430Sstevel@tonic-gate bzero(psp, sizeof (*psp));
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate if (lsp->pr_flags & PR_STOPPED)
1460Sstevel@tonic-gate psp->pr_flags = 0x0001;
1470Sstevel@tonic-gate if (lsp->pr_flags & PR_ISTOP)
1480Sstevel@tonic-gate psp->pr_flags = 0x0002;
1490Sstevel@tonic-gate if (lsp->pr_flags & PR_DSTOP)
1500Sstevel@tonic-gate psp->pr_flags = 0x0004;
1510Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLEEP)
1520Sstevel@tonic-gate psp->pr_flags = 0x0008;
1530Sstevel@tonic-gate if (lsp->pr_flags & PR_FORK)
1540Sstevel@tonic-gate psp->pr_flags = 0x0010;
1550Sstevel@tonic-gate if (lsp->pr_flags & PR_RLC)
1560Sstevel@tonic-gate psp->pr_flags = 0x0020;
1570Sstevel@tonic-gate /*
1580Sstevel@tonic-gate * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
1590Sstevel@tonic-gate * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
1600Sstevel@tonic-gate */
1610Sstevel@tonic-gate if (lsp->pr_flags & PR_PCINVAL)
1620Sstevel@tonic-gate psp->pr_flags = 0x0080;
1630Sstevel@tonic-gate if (lsp->pr_flags & PR_ISSYS)
1640Sstevel@tonic-gate psp->pr_flags = 0x0100;
1650Sstevel@tonic-gate if (lsp->pr_flags & PR_STEP)
1660Sstevel@tonic-gate psp->pr_flags = 0x0200;
1670Sstevel@tonic-gate if (lsp->pr_flags & PR_KLC)
1680Sstevel@tonic-gate psp->pr_flags = 0x0400;
1690Sstevel@tonic-gate if (lsp->pr_flags & PR_ASYNC)
1700Sstevel@tonic-gate psp->pr_flags = 0x0800;
1710Sstevel@tonic-gate if (lsp->pr_flags & PR_PTRACE)
1720Sstevel@tonic-gate psp->pr_flags = 0x1000;
1730Sstevel@tonic-gate if (lsp->pr_flags & PR_MSACCT)
1740Sstevel@tonic-gate psp->pr_flags = 0x2000;
1750Sstevel@tonic-gate if (lsp->pr_flags & PR_BPTADJ)
1760Sstevel@tonic-gate psp->pr_flags = 0x4000;
1770Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLWP)
1780Sstevel@tonic-gate psp->pr_flags = 0x8000;
1790Sstevel@tonic-gate
1800Sstevel@tonic-gate psp->pr_why = lsp->pr_why;
1810Sstevel@tonic-gate psp->pr_what = lsp->pr_what;
1820Sstevel@tonic-gate psp->pr_info = lsp->pr_info;
1830Sstevel@tonic-gate psp->pr_cursig = lsp->pr_cursig;
1840Sstevel@tonic-gate psp->pr_nlwp = P->status.pr_nlwp;
1850Sstevel@tonic-gate psp->pr_sigpend = P->status.pr_sigpend;
1860Sstevel@tonic-gate psp->pr_sighold = lsp->pr_lwphold;
1870Sstevel@tonic-gate psp->pr_altstack = lsp->pr_altstack;
1880Sstevel@tonic-gate psp->pr_action = lsp->pr_action;
1890Sstevel@tonic-gate psp->pr_pid = P->status.pr_pid;
1900Sstevel@tonic-gate psp->pr_ppid = P->status.pr_ppid;
1910Sstevel@tonic-gate psp->pr_pgrp = P->status.pr_pgid;
1920Sstevel@tonic-gate psp->pr_sid = P->status.pr_sid;
1930Sstevel@tonic-gate psp->pr_utime = P->status.pr_utime;
1940Sstevel@tonic-gate psp->pr_stime = P->status.pr_stime;
1950Sstevel@tonic-gate psp->pr_cutime = P->status.pr_cutime;
1960Sstevel@tonic-gate psp->pr_cstime = P->status.pr_cstime;
1970Sstevel@tonic-gate (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
1980Sstevel@tonic-gate psp->pr_syscall = lsp->pr_syscall;
1990Sstevel@tonic-gate psp->pr_nsysarg = lsp->pr_nsysarg;
2000Sstevel@tonic-gate bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg));
2010Sstevel@tonic-gate psp->pr_who = lsp->pr_lwpid;
2020Sstevel@tonic-gate psp->pr_lwppend = lsp->pr_lwppend;
2030Sstevel@tonic-gate psp->pr_oldcontext = (ucontext_t *)lsp->pr_oldcontext;
2040Sstevel@tonic-gate psp->pr_brkbase = (caddr_t)P->status.pr_brkbase;
2050Sstevel@tonic-gate psp->pr_brksize = P->status.pr_brksize;
2060Sstevel@tonic-gate psp->pr_stkbase = (caddr_t)P->status.pr_stkbase;
2070Sstevel@tonic-gate psp->pr_stksize = P->status.pr_stksize;
2080Sstevel@tonic-gate psp->pr_processor = (short)lip->pr_onpro;
2090Sstevel@tonic-gate psp->pr_bind = (short)lip->pr_bindpro;
2100Sstevel@tonic-gate psp->pr_instr = lsp->pr_instr;
2110Sstevel@tonic-gate bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
2120Sstevel@tonic-gate }
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate static void
mkprpsinfo(struct ps_prochandle * P,prpsinfo_t * psp)2150Sstevel@tonic-gate mkprpsinfo(struct ps_prochandle *P, prpsinfo_t *psp)
2160Sstevel@tonic-gate {
2170Sstevel@tonic-gate bzero(psp, sizeof (*psp));
2180Sstevel@tonic-gate psp->pr_state = P->psinfo.pr_lwp.pr_state;
2190Sstevel@tonic-gate psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
2200Sstevel@tonic-gate psp->pr_zomb = (psp->pr_state == SZOMB);
2210Sstevel@tonic-gate psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
2220Sstevel@tonic-gate psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
2230Sstevel@tonic-gate psp->pr_uid = P->psinfo.pr_uid;
2240Sstevel@tonic-gate psp->pr_gid = P->psinfo.pr_gid;
2250Sstevel@tonic-gate psp->pr_pid = P->psinfo.pr_pid;
2260Sstevel@tonic-gate psp->pr_ppid = P->psinfo.pr_ppid;
2270Sstevel@tonic-gate psp->pr_pgrp = P->psinfo.pr_pgid;
2280Sstevel@tonic-gate psp->pr_sid = P->psinfo.pr_sid;
2290Sstevel@tonic-gate psp->pr_addr = (caddr_t)P->psinfo.pr_addr;
2300Sstevel@tonic-gate psp->pr_size = P->psinfo.pr_size;
2310Sstevel@tonic-gate psp->pr_rssize = P->psinfo.pr_rssize;
2320Sstevel@tonic-gate psp->pr_wchan = (caddr_t)P->psinfo.pr_lwp.pr_wchan;
2330Sstevel@tonic-gate psp->pr_start = P->psinfo.pr_start;
2340Sstevel@tonic-gate psp->pr_time = P->psinfo.pr_time;
2350Sstevel@tonic-gate psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
2360Sstevel@tonic-gate psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
2370Sstevel@tonic-gate psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
2380Sstevel@tonic-gate psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
2390Sstevel@tonic-gate psp->pr_lttydev = P->psinfo.pr_ttydev;
2400Sstevel@tonic-gate (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
2410Sstevel@tonic-gate sizeof (psp->pr_clname));
2420Sstevel@tonic-gate (void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
2430Sstevel@tonic-gate sizeof (psp->pr_fname));
2440Sstevel@tonic-gate bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
2450Sstevel@tonic-gate sizeof (psp->pr_psargs));
2460Sstevel@tonic-gate psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
2470Sstevel@tonic-gate psp->pr_ctime = P->psinfo.pr_ctime;
2480Sstevel@tonic-gate psp->pr_bysize = psp->pr_size * PAGESIZE;
2490Sstevel@tonic-gate psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
2500Sstevel@tonic-gate psp->pr_argc = P->psinfo.pr_argc;
2510Sstevel@tonic-gate psp->pr_argv = (char **)P->psinfo.pr_argv;
2520Sstevel@tonic-gate psp->pr_envp = (char **)P->psinfo.pr_envp;
2530Sstevel@tonic-gate psp->pr_wstat = P->psinfo.pr_wstat;
2540Sstevel@tonic-gate psp->pr_pctcpu = P->psinfo.pr_pctcpu;
2550Sstevel@tonic-gate psp->pr_pctmem = P->psinfo.pr_pctmem;
2560Sstevel@tonic-gate psp->pr_euid = P->psinfo.pr_euid;
2570Sstevel@tonic-gate psp->pr_egid = P->psinfo.pr_egid;
2580Sstevel@tonic-gate psp->pr_aslwpid = 0;
2590Sstevel@tonic-gate psp->pr_dmodel = P->psinfo.pr_dmodel;
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate
2620Sstevel@tonic-gate #ifdef _LP64
2630Sstevel@tonic-gate
2640Sstevel@tonic-gate static void
mkprstatus32(struct ps_prochandle * P,const lwpstatus_t * lsp,const lwpsinfo_t * lip,prstatus32_t * psp)2650Sstevel@tonic-gate mkprstatus32(struct ps_prochandle *P, const lwpstatus_t *lsp,
2660Sstevel@tonic-gate const lwpsinfo_t *lip, prstatus32_t *psp)
2670Sstevel@tonic-gate {
2680Sstevel@tonic-gate bzero(psp, sizeof (*psp));
2690Sstevel@tonic-gate
2700Sstevel@tonic-gate if (lsp->pr_flags & PR_STOPPED)
2710Sstevel@tonic-gate psp->pr_flags = 0x0001;
2720Sstevel@tonic-gate if (lsp->pr_flags & PR_ISTOP)
2730Sstevel@tonic-gate psp->pr_flags = 0x0002;
2740Sstevel@tonic-gate if (lsp->pr_flags & PR_DSTOP)
2750Sstevel@tonic-gate psp->pr_flags = 0x0004;
2760Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLEEP)
2770Sstevel@tonic-gate psp->pr_flags = 0x0008;
2780Sstevel@tonic-gate if (lsp->pr_flags & PR_FORK)
2790Sstevel@tonic-gate psp->pr_flags = 0x0010;
2800Sstevel@tonic-gate if (lsp->pr_flags & PR_RLC)
2810Sstevel@tonic-gate psp->pr_flags = 0x0020;
2820Sstevel@tonic-gate /*
2830Sstevel@tonic-gate * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
2840Sstevel@tonic-gate * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
2850Sstevel@tonic-gate */
2860Sstevel@tonic-gate if (lsp->pr_flags & PR_PCINVAL)
2870Sstevel@tonic-gate psp->pr_flags = 0x0080;
2880Sstevel@tonic-gate if (lsp->pr_flags & PR_ISSYS)
2890Sstevel@tonic-gate psp->pr_flags = 0x0100;
2900Sstevel@tonic-gate if (lsp->pr_flags & PR_STEP)
2910Sstevel@tonic-gate psp->pr_flags = 0x0200;
2920Sstevel@tonic-gate if (lsp->pr_flags & PR_KLC)
2930Sstevel@tonic-gate psp->pr_flags = 0x0400;
2940Sstevel@tonic-gate if (lsp->pr_flags & PR_ASYNC)
2950Sstevel@tonic-gate psp->pr_flags = 0x0800;
2960Sstevel@tonic-gate if (lsp->pr_flags & PR_PTRACE)
2970Sstevel@tonic-gate psp->pr_flags = 0x1000;
2980Sstevel@tonic-gate if (lsp->pr_flags & PR_MSACCT)
2990Sstevel@tonic-gate psp->pr_flags = 0x2000;
3000Sstevel@tonic-gate if (lsp->pr_flags & PR_BPTADJ)
3010Sstevel@tonic-gate psp->pr_flags = 0x4000;
3020Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLWP)
3030Sstevel@tonic-gate psp->pr_flags = 0x8000;
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate psp->pr_why = lsp->pr_why;
3060Sstevel@tonic-gate psp->pr_what = lsp->pr_what;
3070Sstevel@tonic-gate siginfo_n_to_32(&lsp->pr_info, &psp->pr_info);
3080Sstevel@tonic-gate psp->pr_cursig = lsp->pr_cursig;
3090Sstevel@tonic-gate psp->pr_nlwp = P->status.pr_nlwp;
3100Sstevel@tonic-gate psp->pr_sigpend = P->status.pr_sigpend;
3110Sstevel@tonic-gate psp->pr_sighold = lsp->pr_lwphold;
3120Sstevel@tonic-gate stack_n_to_32(&lsp->pr_altstack, &psp->pr_altstack);
3130Sstevel@tonic-gate sigaction_n_to_32(&lsp->pr_action, &psp->pr_action);
3140Sstevel@tonic-gate psp->pr_pid = P->status.pr_pid;
3150Sstevel@tonic-gate psp->pr_ppid = P->status.pr_ppid;
3160Sstevel@tonic-gate psp->pr_pgrp = P->status.pr_pgid;
3170Sstevel@tonic-gate psp->pr_sid = P->status.pr_sid;
3180Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_utime, &psp->pr_utime);
3190Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_stime, &psp->pr_stime);
3200Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_cutime, &psp->pr_cutime);
3210Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_cstime, &psp->pr_cstime);
3220Sstevel@tonic-gate (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
3230Sstevel@tonic-gate psp->pr_syscall = lsp->pr_syscall;
3240Sstevel@tonic-gate psp->pr_nsysarg = lsp->pr_nsysarg;
325*11135SRoger.Faulkner@Sun.COM bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg));
326*11135SRoger.Faulkner@Sun.COM psp->pr_who = lsp->pr_lwpid;
3270Sstevel@tonic-gate psp->pr_lwppend = lsp->pr_lwppend;
3280Sstevel@tonic-gate psp->pr_oldcontext = (caddr32_t)lsp->pr_oldcontext;
3290Sstevel@tonic-gate psp->pr_brkbase = (caddr32_t)P->status.pr_brkbase;
3300Sstevel@tonic-gate psp->pr_brksize = P->status.pr_brksize;
3310Sstevel@tonic-gate psp->pr_stkbase = (caddr32_t)P->status.pr_stkbase;
3320Sstevel@tonic-gate psp->pr_stksize = P->status.pr_stksize;
3330Sstevel@tonic-gate psp->pr_processor = (short)lip->pr_onpro;
3340Sstevel@tonic-gate psp->pr_bind = (short)lip->pr_bindpro;
3350Sstevel@tonic-gate psp->pr_instr = lsp->pr_instr;
3360Sstevel@tonic-gate bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
3370Sstevel@tonic-gate }
3380Sstevel@tonic-gate
3390Sstevel@tonic-gate static void
mkprpsinfo32(struct ps_prochandle * P,prpsinfo32_t * psp)3400Sstevel@tonic-gate mkprpsinfo32(struct ps_prochandle *P, prpsinfo32_t *psp)
3410Sstevel@tonic-gate {
3420Sstevel@tonic-gate bzero(psp, sizeof (*psp));
3430Sstevel@tonic-gate psp->pr_state = P->psinfo.pr_lwp.pr_state;
3440Sstevel@tonic-gate psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
3450Sstevel@tonic-gate psp->pr_zomb = (psp->pr_state == SZOMB);
3460Sstevel@tonic-gate psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
3470Sstevel@tonic-gate psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
3480Sstevel@tonic-gate psp->pr_uid = P->psinfo.pr_uid;
3490Sstevel@tonic-gate psp->pr_gid = P->psinfo.pr_gid;
3500Sstevel@tonic-gate psp->pr_pid = P->psinfo.pr_pid;
3510Sstevel@tonic-gate psp->pr_ppid = P->psinfo.pr_ppid;
3520Sstevel@tonic-gate psp->pr_pgrp = P->psinfo.pr_pgid;
3530Sstevel@tonic-gate psp->pr_sid = P->psinfo.pr_sid;
3540Sstevel@tonic-gate psp->pr_addr = (caddr32_t)P->psinfo.pr_addr;
3550Sstevel@tonic-gate psp->pr_size = P->psinfo.pr_size;
3560Sstevel@tonic-gate psp->pr_rssize = P->psinfo.pr_rssize;
3570Sstevel@tonic-gate psp->pr_wchan = (caddr32_t)P->psinfo.pr_lwp.pr_wchan;
3580Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_start, &psp->pr_start);
3590Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_time, &psp->pr_time);
3600Sstevel@tonic-gate psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
3610Sstevel@tonic-gate psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
3620Sstevel@tonic-gate psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
3630Sstevel@tonic-gate psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
3640Sstevel@tonic-gate psp->pr_lttydev = prcmpldev(P->psinfo.pr_ttydev);
3650Sstevel@tonic-gate (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
3660Sstevel@tonic-gate sizeof (psp->pr_clname));
3670Sstevel@tonic-gate (void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
3680Sstevel@tonic-gate sizeof (psp->pr_fname));
3690Sstevel@tonic-gate bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
3700Sstevel@tonic-gate sizeof (psp->pr_psargs));
3710Sstevel@tonic-gate psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
3720Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_ctime, &psp->pr_ctime);
3730Sstevel@tonic-gate psp->pr_bysize = psp->pr_size * PAGESIZE;
3740Sstevel@tonic-gate psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
3750Sstevel@tonic-gate psp->pr_argc = P->psinfo.pr_argc;
3760Sstevel@tonic-gate psp->pr_argv = (caddr32_t)P->psinfo.pr_argv;
3770Sstevel@tonic-gate psp->pr_envp = (caddr32_t)P->psinfo.pr_envp;
3780Sstevel@tonic-gate psp->pr_wstat = P->psinfo.pr_wstat;
3790Sstevel@tonic-gate psp->pr_pctcpu = P->psinfo.pr_pctcpu;
3800Sstevel@tonic-gate psp->pr_pctmem = P->psinfo.pr_pctmem;
3810Sstevel@tonic-gate psp->pr_euid = P->psinfo.pr_euid;
3820Sstevel@tonic-gate psp->pr_egid = P->psinfo.pr_egid;
3830Sstevel@tonic-gate psp->pr_aslwpid = 0;
3840Sstevel@tonic-gate psp->pr_dmodel = P->psinfo.pr_dmodel;
3850Sstevel@tonic-gate }
3860Sstevel@tonic-gate
3870Sstevel@tonic-gate #endif /* _LP64 */
3880Sstevel@tonic-gate
3890Sstevel@tonic-gate static int
write_note(int fd,uint_t type,const void * desc,size_t descsz,off64_t * offp)3900Sstevel@tonic-gate write_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp)
3910Sstevel@tonic-gate {
3920Sstevel@tonic-gate /*
3930Sstevel@tonic-gate * Note headers are the same regardless of the data model of the
3940Sstevel@tonic-gate * ELF file; we arbitrarily use Elf64_Nhdr here.
3950Sstevel@tonic-gate */
3960Sstevel@tonic-gate struct {
3970Sstevel@tonic-gate Elf64_Nhdr nhdr;
3980Sstevel@tonic-gate char name[8];
3990Sstevel@tonic-gate } n;
4000Sstevel@tonic-gate
4010Sstevel@tonic-gate bzero(&n, sizeof (n));
4020Sstevel@tonic-gate bcopy("CORE", n.name, 4);
4030Sstevel@tonic-gate n.nhdr.n_type = type;
4040Sstevel@tonic-gate n.nhdr.n_namesz = 5;
4050Sstevel@tonic-gate n.nhdr.n_descsz = roundup(descsz, 4);
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate if (pwrite64(fd, &n, sizeof (n), *offp) != sizeof (n))
4080Sstevel@tonic-gate return (-1);
4090Sstevel@tonic-gate
4100Sstevel@tonic-gate *offp += sizeof (n);
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate if (pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != n.nhdr.n_descsz)
4130Sstevel@tonic-gate return (-1);
4140Sstevel@tonic-gate
4150Sstevel@tonic-gate *offp += n.nhdr.n_descsz;
4160Sstevel@tonic-gate
4170Sstevel@tonic-gate return (0);
4180Sstevel@tonic-gate }
4190Sstevel@tonic-gate
4200Sstevel@tonic-gate static int
old_per_lwp(void * data,const lwpstatus_t * lsp,const lwpsinfo_t * lip)4210Sstevel@tonic-gate old_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
4220Sstevel@tonic-gate {
4230Sstevel@tonic-gate pgcore_t *pgc = data;
4240Sstevel@tonic-gate struct ps_prochandle *P = pgc->P;
4250Sstevel@tonic-gate
4260Sstevel@tonic-gate /*
4270Sstevel@tonic-gate * Legacy core files don't contain information about zombie LWPs.
4280Sstevel@tonic-gate * We use Plwp_iter_all() so that we get the lwpsinfo_t structure
4290Sstevel@tonic-gate * more cheaply.
4300Sstevel@tonic-gate */
4310Sstevel@tonic-gate if (lsp == NULL)
4320Sstevel@tonic-gate return (0);
4330Sstevel@tonic-gate
4340Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
4350Sstevel@tonic-gate prstatus_t prstatus;
4360Sstevel@tonic-gate mkprstatus(P, lsp, lip, &prstatus);
4370Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRSTATUS, &prstatus,
4380Sstevel@tonic-gate sizeof (prstatus_t), pgc->pgc_doff) != 0)
4390Sstevel@tonic-gate return (0);
4400Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRFPREG, &lsp->pr_fpreg,
4410Sstevel@tonic-gate sizeof (prfpregset_t), pgc->pgc_doff) != 0)
4420Sstevel@tonic-gate return (1);
4430Sstevel@tonic-gate #ifdef _LP64
4440Sstevel@tonic-gate } else {
4450Sstevel@tonic-gate prstatus32_t pr32;
4460Sstevel@tonic-gate prfpregset32_t pf32;
4470Sstevel@tonic-gate mkprstatus32(P, lsp, lip, &pr32);
4480Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRSTATUS, &pr32,
4490Sstevel@tonic-gate sizeof (prstatus32_t), pgc->pgc_doff) != 0)
4500Sstevel@tonic-gate return (1);
4510Sstevel@tonic-gate prfpregset_n_to_32(&lsp->pr_fpreg, &pf32);
4520Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRFPREG, &pf32,
4530Sstevel@tonic-gate sizeof (prfpregset32_t), pgc->pgc_doff) != 0)
4540Sstevel@tonic-gate return (1);
4550Sstevel@tonic-gate #endif /* _LP64 */
4560Sstevel@tonic-gate }
4570Sstevel@tonic-gate
4580Sstevel@tonic-gate #ifdef sparc
4590Sstevel@tonic-gate {
4600Sstevel@tonic-gate prxregset_t xregs;
4610Sstevel@tonic-gate if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0 &&
4620Sstevel@tonic-gate write_note(pgc->pgc_fd, NT_PRXREG, &xregs,
4630Sstevel@tonic-gate sizeof (prxregset_t), pgc->pgc_doff) != 0)
4640Sstevel@tonic-gate return (1);
4650Sstevel@tonic-gate }
4660Sstevel@tonic-gate #endif /* sparc */
4670Sstevel@tonic-gate
4680Sstevel@tonic-gate return (0);
4690Sstevel@tonic-gate }
4700Sstevel@tonic-gate
4710Sstevel@tonic-gate static int
new_per_lwp(void * data,const lwpstatus_t * lsp,const lwpsinfo_t * lip)4720Sstevel@tonic-gate new_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
4730Sstevel@tonic-gate {
4740Sstevel@tonic-gate pgcore_t *pgc = data;
4750Sstevel@tonic-gate struct ps_prochandle *P = pgc->P;
4760Sstevel@tonic-gate
4770Sstevel@tonic-gate /*
4780Sstevel@tonic-gate * If lsp is NULL this indicates that this is a zombie LWP in
4790Sstevel@tonic-gate * which case we dump only the lwpsinfo_t structure and none of
4800Sstevel@tonic-gate * the other ancillary LWP state data.
4810Sstevel@tonic-gate */
4820Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
4830Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip,
4840Sstevel@tonic-gate sizeof (lwpsinfo_t), pgc->pgc_doff) != 0)
4850Sstevel@tonic-gate return (1);
4860Sstevel@tonic-gate if (lsp == NULL)
4870Sstevel@tonic-gate return (0);
4880Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp,
4890Sstevel@tonic-gate sizeof (lwpstatus_t), pgc->pgc_doff) != 0)
4900Sstevel@tonic-gate return (1);
4910Sstevel@tonic-gate #ifdef _LP64
4920Sstevel@tonic-gate } else {
4930Sstevel@tonic-gate lwpsinfo32_t li32;
4940Sstevel@tonic-gate lwpstatus32_t ls32;
4950Sstevel@tonic-gate lwpsinfo_n_to_32(lip, &li32);
4960Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32,
4970Sstevel@tonic-gate sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0)
4980Sstevel@tonic-gate return (1);
4990Sstevel@tonic-gate if (lsp == NULL)
5000Sstevel@tonic-gate return (0);
5010Sstevel@tonic-gate lwpstatus_n_to_32(lsp, &ls32);
5020Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32,
5030Sstevel@tonic-gate sizeof (lwpstatus32_t), pgc->pgc_doff) != 0)
5040Sstevel@tonic-gate return (1);
5050Sstevel@tonic-gate #endif /* _LP64 */
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate
5080Sstevel@tonic-gate #ifdef sparc
5090Sstevel@tonic-gate {
5100Sstevel@tonic-gate prxregset_t xregs;
5110Sstevel@tonic-gate gwindows_t gwins;
5120Sstevel@tonic-gate size_t size;
5130Sstevel@tonic-gate
5140Sstevel@tonic-gate if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0) {
5150Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRXREG, &xregs,
5160Sstevel@tonic-gate sizeof (prxregset_t), pgc->pgc_doff) != 0)
5170Sstevel@tonic-gate return (1);
5180Sstevel@tonic-gate }
5190Sstevel@tonic-gate
5200Sstevel@tonic-gate if (Plwp_getgwindows(P, lsp->pr_lwpid, &gwins) == 0 &&
5210Sstevel@tonic-gate gwins.wbcnt > 0) {
5220Sstevel@tonic-gate size = sizeof (gwins) - sizeof (gwins.wbuf) +
5230Sstevel@tonic-gate gwins.wbcnt * sizeof (gwins.wbuf[0]);
5240Sstevel@tonic-gate
5250Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_GWINDOWS, &gwins, size,
5260Sstevel@tonic-gate pgc->pgc_doff) != 0)
5270Sstevel@tonic-gate return (1);
5280Sstevel@tonic-gate }
5290Sstevel@tonic-gate
5300Sstevel@tonic-gate }
5310Sstevel@tonic-gate #ifdef __sparcv9
5320Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_LP64) {
5330Sstevel@tonic-gate asrset_t asrs;
5340Sstevel@tonic-gate if (Plwp_getasrs(P, lsp->pr_lwpid, asrs) == 0) {
5350Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_ASRS, &asrs,
5360Sstevel@tonic-gate sizeof (asrset_t), pgc->pgc_doff) != 0)
5370Sstevel@tonic-gate return (1);
5380Sstevel@tonic-gate }
5390Sstevel@tonic-gate }
5400Sstevel@tonic-gate #endif /* __sparcv9 */
5410Sstevel@tonic-gate #endif /* sparc */
5420Sstevel@tonic-gate
5430Sstevel@tonic-gate return (0);
5440Sstevel@tonic-gate }
5450Sstevel@tonic-gate
5460Sstevel@tonic-gate static uint_t
count_sections(pgcore_t * pgc)5470Sstevel@tonic-gate count_sections(pgcore_t *pgc)
5480Sstevel@tonic-gate {
5490Sstevel@tonic-gate struct ps_prochandle *P = pgc->P;
5500Sstevel@tonic-gate file_info_t *fptr;
5510Sstevel@tonic-gate uint_t cnt;
5520Sstevel@tonic-gate uint_t nshdrs = 0;
5530Sstevel@tonic-gate
5540Sstevel@tonic-gate if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)))
5550Sstevel@tonic-gate return (0);
5560Sstevel@tonic-gate
5570Sstevel@tonic-gate fptr = list_next(&P->file_head);
5580Sstevel@tonic-gate for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) {
5590Sstevel@tonic-gate int hit_symtab = 0;
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate Pbuild_file_symtab(P, fptr);
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_CTF) &&
5640Sstevel@tonic-gate Pbuild_file_ctf(P, fptr) != NULL) {
5650Sstevel@tonic-gate sym_tbl_t *sym;
5660Sstevel@tonic-gate
5670Sstevel@tonic-gate nshdrs++;
5680Sstevel@tonic-gate
5690Sstevel@tonic-gate if (fptr->file_ctf_dyn) {
5700Sstevel@tonic-gate sym = &fptr->file_dynsym;
5710Sstevel@tonic-gate } else {
5720Sstevel@tonic-gate sym = &fptr->file_symtab;
5730Sstevel@tonic-gate hit_symtab = 1;
5740Sstevel@tonic-gate }
5750Sstevel@tonic-gate
5763347Sab196087 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 &&
5770Sstevel@tonic-gate sym->sym_strs != NULL)
5780Sstevel@tonic-gate nshdrs += 2;
5790Sstevel@tonic-gate }
5800Sstevel@tonic-gate
5810Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
5823347Sab196087 fptr->file_symtab.sym_data_pri != NULL &&
5830Sstevel@tonic-gate fptr->file_symtab.sym_symn != 0 &&
5840Sstevel@tonic-gate fptr->file_symtab.sym_strs != NULL) {
5850Sstevel@tonic-gate nshdrs += 2;
5860Sstevel@tonic-gate }
5870Sstevel@tonic-gate }
5880Sstevel@tonic-gate
5890Sstevel@tonic-gate return (nshdrs == 0 ? 0 : nshdrs + 2);
5900Sstevel@tonic-gate }
5910Sstevel@tonic-gate
5920Sstevel@tonic-gate static int
write_shdr(pgcore_t * pgc,shstrtype_t name,uint_t type,ulong_t flags,uintptr_t addr,ulong_t offset,size_t size,uint_t link,uint_t info,uintptr_t addralign,uintptr_t entsize)5930Sstevel@tonic-gate write_shdr(pgcore_t *pgc, shstrtype_t name, uint_t type, ulong_t flags,
5940Sstevel@tonic-gate uintptr_t addr, ulong_t offset, size_t size, uint_t link, uint_t info,
5950Sstevel@tonic-gate uintptr_t addralign, uintptr_t entsize)
5960Sstevel@tonic-gate {
5970Sstevel@tonic-gate if (pgc->P->status.pr_dmodel == PR_MODEL_ILP32) {
5980Sstevel@tonic-gate Elf32_Shdr shdr;
5990Sstevel@tonic-gate
6000Sstevel@tonic-gate bzero(&shdr, sizeof (shdr));
6010Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name);
6020Sstevel@tonic-gate shdr.sh_type = type;
6030Sstevel@tonic-gate shdr.sh_flags = flags;
6040Sstevel@tonic-gate shdr.sh_addr = (Elf32_Addr)addr;
6050Sstevel@tonic-gate shdr.sh_offset = offset;
6060Sstevel@tonic-gate shdr.sh_size = size;
6070Sstevel@tonic-gate shdr.sh_link = link;
6080Sstevel@tonic-gate shdr.sh_info = info;
6090Sstevel@tonic-gate shdr.sh_addralign = addralign;
6100Sstevel@tonic-gate shdr.sh_entsize = entsize;
6110Sstevel@tonic-gate
6120Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
6130Sstevel@tonic-gate *pgc->pgc_soff) != sizeof (shdr))
6140Sstevel@tonic-gate return (-1);
6150Sstevel@tonic-gate
6160Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr);
6170Sstevel@tonic-gate #ifdef _LP64
6180Sstevel@tonic-gate } else {
6190Sstevel@tonic-gate Elf64_Shdr shdr;
6200Sstevel@tonic-gate
6210Sstevel@tonic-gate bzero(&shdr, sizeof (shdr));
6220Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name);
6230Sstevel@tonic-gate shdr.sh_type = type;
6240Sstevel@tonic-gate shdr.sh_flags = flags;
6250Sstevel@tonic-gate shdr.sh_addr = addr;
6260Sstevel@tonic-gate shdr.sh_offset = offset;
6270Sstevel@tonic-gate shdr.sh_size = size;
6280Sstevel@tonic-gate shdr.sh_link = link;
6290Sstevel@tonic-gate shdr.sh_info = info;
6300Sstevel@tonic-gate shdr.sh_addralign = addralign;
6310Sstevel@tonic-gate shdr.sh_entsize = entsize;
6320Sstevel@tonic-gate
6330Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
6340Sstevel@tonic-gate *pgc->pgc_soff) != sizeof (shdr))
6350Sstevel@tonic-gate return (-1);
6360Sstevel@tonic-gate
6370Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr);
6380Sstevel@tonic-gate #endif /* _LP64 */
6390Sstevel@tonic-gate }
6400Sstevel@tonic-gate
6410Sstevel@tonic-gate return (0);
6420Sstevel@tonic-gate }
6430Sstevel@tonic-gate
6440Sstevel@tonic-gate static int
dump_symtab(pgcore_t * pgc,file_info_t * fptr,uint_t index,int dynsym)6450Sstevel@tonic-gate dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym)
6460Sstevel@tonic-gate {
6470Sstevel@tonic-gate sym_tbl_t *sym = dynsym ? &fptr->file_dynsym : &fptr->file_symtab;
6480Sstevel@tonic-gate shstrtype_t symname = dynsym ? STR_DYNSYM : STR_SYMTAB;
6490Sstevel@tonic-gate shstrtype_t strname = dynsym ? STR_DYNSTR : STR_STRTAB;
6500Sstevel@tonic-gate uint_t symtype = dynsym ? SHT_DYNSYM : SHT_SYMTAB;
6510Sstevel@tonic-gate size_t size;
6520Sstevel@tonic-gate uintptr_t addr = fptr->file_map->map_pmap.pr_vaddr;
6530Sstevel@tonic-gate
6543347Sab196087 if (sym->sym_data_pri == NULL || sym->sym_symn == 0 ||
6550Sstevel@tonic-gate sym->sym_strs == NULL)
6560Sstevel@tonic-gate return (0);
6570Sstevel@tonic-gate
6583347Sab196087 size = sym->sym_hdr_pri.sh_size;
6593347Sab196087 if (pwrite64(pgc->pgc_fd, sym->sym_data_pri->d_buf, size,
6600Sstevel@tonic-gate *pgc->pgc_doff) != size)
6610Sstevel@tonic-gate return (-1);
6620Sstevel@tonic-gate
6630Sstevel@tonic-gate if (write_shdr(pgc, symname, symtype, 0, addr, *pgc->pgc_doff, size,
6643347Sab196087 index + 1, sym->sym_hdr_pri.sh_info, sym->sym_hdr_pri.sh_addralign,
6653347Sab196087 sym->sym_hdr_pri.sh_entsize) != 0)
6660Sstevel@tonic-gate return (-1);
6670Sstevel@tonic-gate
6680Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8);
6690Sstevel@tonic-gate
6700Sstevel@tonic-gate size = sym->sym_strhdr.sh_size;
6710Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != size)
6720Sstevel@tonic-gate return (-1);
6730Sstevel@tonic-gate
6740Sstevel@tonic-gate if (write_shdr(pgc, strname, SHT_STRTAB, SHF_STRINGS, addr,
6750Sstevel@tonic-gate *pgc->pgc_doff, size, 0, 0, 1, 0) != 0)
6760Sstevel@tonic-gate return (-1);
6770Sstevel@tonic-gate
6780Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8);
6790Sstevel@tonic-gate
6800Sstevel@tonic-gate return (0);
6810Sstevel@tonic-gate }
6820Sstevel@tonic-gate
6830Sstevel@tonic-gate static int
dump_sections(pgcore_t * pgc)6840Sstevel@tonic-gate dump_sections(pgcore_t *pgc)
6850Sstevel@tonic-gate {
6860Sstevel@tonic-gate struct ps_prochandle *P = pgc->P;
6870Sstevel@tonic-gate file_info_t *fptr;
6880Sstevel@tonic-gate uint_t cnt;
6890Sstevel@tonic-gate uint_t index = 1;
6900Sstevel@tonic-gate
6910Sstevel@tonic-gate if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)))
6920Sstevel@tonic-gate return (0);
6930Sstevel@tonic-gate
6940Sstevel@tonic-gate fptr = list_next(&P->file_head);
6950Sstevel@tonic-gate for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) {
6960Sstevel@tonic-gate int hit_symtab = 0;
6970Sstevel@tonic-gate
6980Sstevel@tonic-gate Pbuild_file_symtab(P, fptr);
6990Sstevel@tonic-gate
7000Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_CTF) &&
7010Sstevel@tonic-gate Pbuild_file_ctf(P, fptr) != NULL) {
7020Sstevel@tonic-gate sym_tbl_t *sym;
7030Sstevel@tonic-gate uint_t dynsym;
7040Sstevel@tonic-gate uint_t symindex = 0;
7050Sstevel@tonic-gate
7060Sstevel@tonic-gate /*
7070Sstevel@tonic-gate * Write the symtab out first so we can correctly
7080Sstevel@tonic-gate * set the sh_link field in the CTF section header.
7090Sstevel@tonic-gate * symindex will be 0 if there is no corresponding
7100Sstevel@tonic-gate * symbol table section.
7110Sstevel@tonic-gate */
7120Sstevel@tonic-gate if (fptr->file_ctf_dyn) {
7130Sstevel@tonic-gate sym = &fptr->file_dynsym;
7140Sstevel@tonic-gate dynsym = 1;
7150Sstevel@tonic-gate } else {
7160Sstevel@tonic-gate sym = &fptr->file_symtab;
7170Sstevel@tonic-gate dynsym = 0;
7180Sstevel@tonic-gate hit_symtab = 1;
7190Sstevel@tonic-gate }
7200Sstevel@tonic-gate
7213347Sab196087 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 &&
7220Sstevel@tonic-gate sym->sym_strs != NULL) {
7230Sstevel@tonic-gate symindex = index;
7240Sstevel@tonic-gate if (dump_symtab(pgc, fptr, index, dynsym) != 0)
725*11135SRoger.Faulkner@Sun.COM return (-1);
7260Sstevel@tonic-gate index += 2;
7270Sstevel@tonic-gate }
7280Sstevel@tonic-gate
7290Sstevel@tonic-gate /*
7300Sstevel@tonic-gate * Write the CTF data that we've read out of the
7310Sstevel@tonic-gate * file itself into the core file.
7320Sstevel@tonic-gate */
7330Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, fptr->file_ctf_buf,
7340Sstevel@tonic-gate fptr->file_ctf_size, *pgc->pgc_doff) !=
7350Sstevel@tonic-gate fptr->file_ctf_size)
7360Sstevel@tonic-gate return (-1);
7370Sstevel@tonic-gate
7380Sstevel@tonic-gate if (write_shdr(pgc, STR_CTF, SHT_PROGBITS, 0,
7390Sstevel@tonic-gate fptr->file_map->map_pmap.pr_vaddr, *pgc->pgc_doff,
7400Sstevel@tonic-gate fptr->file_ctf_size, symindex, 0, 4, 0) != 0)
7410Sstevel@tonic-gate return (-1);
7420Sstevel@tonic-gate
7430Sstevel@tonic-gate index++;
7440Sstevel@tonic-gate *pgc->pgc_doff += roundup(fptr->file_ctf_size, 8);
7450Sstevel@tonic-gate }
7460Sstevel@tonic-gate
7470Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
7483347Sab196087 fptr->file_symtab.sym_data_pri != NULL &&
7490Sstevel@tonic-gate fptr->file_symtab.sym_symn != 0 &&
7500Sstevel@tonic-gate fptr->file_symtab.sym_strs != NULL) {
7510Sstevel@tonic-gate if (dump_symtab(pgc, fptr, index, 0) != 0)
7520Sstevel@tonic-gate return (-1);
7530Sstevel@tonic-gate index += 2;
7540Sstevel@tonic-gate }
7550Sstevel@tonic-gate }
7560Sstevel@tonic-gate
7570Sstevel@tonic-gate return (0);
7580Sstevel@tonic-gate }
7590Sstevel@tonic-gate
7600Sstevel@tonic-gate /*ARGSUSED*/
7610Sstevel@tonic-gate static int
dump_map(void * data,const prmap_t * pmp,const char * name)7620Sstevel@tonic-gate dump_map(void *data, const prmap_t *pmp, const char *name)
7630Sstevel@tonic-gate {
7640Sstevel@tonic-gate pgcore_t *pgc = data;
7650Sstevel@tonic-gate struct ps_prochandle *P = pgc->P;
7660Sstevel@tonic-gate #ifdef _LP64
7670Sstevel@tonic-gate Elf64_Phdr phdr;
7680Sstevel@tonic-gate #else
7690Sstevel@tonic-gate Elf32_Phdr phdr;
7700Sstevel@tonic-gate #endif
7710Sstevel@tonic-gate size_t n;
7720Sstevel@tonic-gate
7730Sstevel@tonic-gate bzero(&phdr, sizeof (phdr));
7740Sstevel@tonic-gate phdr.p_type = PT_LOAD;
7750Sstevel@tonic-gate phdr.p_vaddr = pmp->pr_vaddr;
7760Sstevel@tonic-gate phdr.p_memsz = pmp->pr_size;
7770Sstevel@tonic-gate if (pmp->pr_mflags & MA_READ)
7780Sstevel@tonic-gate phdr.p_flags |= PF_R;
7790Sstevel@tonic-gate if (pmp->pr_mflags & MA_WRITE)
7800Sstevel@tonic-gate phdr.p_flags |= PF_W;
7810Sstevel@tonic-gate if (pmp->pr_mflags & MA_EXEC)
7820Sstevel@tonic-gate phdr.p_flags |= PF_X;
7830Sstevel@tonic-gate
7840Sstevel@tonic-gate if (pmp->pr_vaddr + pmp->pr_size > P->status.pr_stkbase &&
7850Sstevel@tonic-gate pmp->pr_vaddr < P->status.pr_stkbase + P->status.pr_stksize) {
7860Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_STACK))
7870Sstevel@tonic-gate goto exclude;
7880Sstevel@tonic-gate
7890Sstevel@tonic-gate } else if ((pmp->pr_mflags & MA_ANON) &&
7900Sstevel@tonic-gate pmp->pr_vaddr + pmp->pr_size > P->status.pr_brkbase &&
7910Sstevel@tonic-gate pmp->pr_vaddr < P->status.pr_brkbase + P->status.pr_brksize) {
7920Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_HEAP))
7930Sstevel@tonic-gate goto exclude;
7940Sstevel@tonic-gate
7950Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_ISM) {
7960Sstevel@tonic-gate if (pmp->pr_mflags & MA_NORESERVE) {
7970Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_DISM))
7980Sstevel@tonic-gate goto exclude;
7990Sstevel@tonic-gate } else {
8000Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_ISM))
8010Sstevel@tonic-gate goto exclude;
8020Sstevel@tonic-gate }
8030Sstevel@tonic-gate
8040Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_SHM) {
8050Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHM))
8060Sstevel@tonic-gate goto exclude;
8070Sstevel@tonic-gate
8080Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_SHARED) {
8090Sstevel@tonic-gate if (pmp->pr_mflags & MA_ANON) {
8100Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHANON))
8110Sstevel@tonic-gate goto exclude;
8120Sstevel@tonic-gate } else {
8130Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHFILE))
8140Sstevel@tonic-gate goto exclude;
8150Sstevel@tonic-gate }
8160Sstevel@tonic-gate
8170Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_ANON) {
8180Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_ANON))
8190Sstevel@tonic-gate goto exclude;
8200Sstevel@tonic-gate
8210Sstevel@tonic-gate } else if (phdr.p_flags == (PF_R | PF_X)) {
8220Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_TEXT))
8230Sstevel@tonic-gate goto exclude;
8240Sstevel@tonic-gate
8250Sstevel@tonic-gate } else if (phdr.p_flags == PF_R) {
8260Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_RODATA))
8270Sstevel@tonic-gate goto exclude;
8280Sstevel@tonic-gate
8290Sstevel@tonic-gate } else {
8300Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_DATA))
8310Sstevel@tonic-gate goto exclude;
8320Sstevel@tonic-gate }
8330Sstevel@tonic-gate
8340Sstevel@tonic-gate n = 0;
8350Sstevel@tonic-gate while (n < pmp->pr_size) {
8360Sstevel@tonic-gate size_t csz = MIN(pmp->pr_size - n, pgc->pgc_chunksz);
8370Sstevel@tonic-gate
8380Sstevel@tonic-gate /*
8390Sstevel@tonic-gate * If we can't read out part of the victim's address
8400Sstevel@tonic-gate * space for some reason ignore that failure and try to
8410Sstevel@tonic-gate * emit a partial core file without that mapping's data.
8420Sstevel@tonic-gate * As in the kernel, we mark these failures with the
8430Sstevel@tonic-gate * PF_SUNW_FAILURE flag and store the errno where the
8440Sstevel@tonic-gate * mapping would have been.
8450Sstevel@tonic-gate */
8460Sstevel@tonic-gate if (Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n) != csz ||
8470Sstevel@tonic-gate pwrite64(pgc->pgc_fd, pgc->pgc_chunk, csz,
8480Sstevel@tonic-gate *pgc->pgc_doff + n) != csz) {
8490Sstevel@tonic-gate int err = errno;
8500Sstevel@tonic-gate (void) pwrite64(pgc->pgc_fd, &err, sizeof (err),
8510Sstevel@tonic-gate *pgc->pgc_doff);
8520Sstevel@tonic-gate *pgc->pgc_doff += roundup(sizeof (err), 8);
8530Sstevel@tonic-gate
8540Sstevel@tonic-gate phdr.p_flags |= PF_SUNW_FAILURE;
8550Sstevel@tonic-gate (void) ftruncate64(pgc->pgc_fd, *pgc->pgc_doff);
8560Sstevel@tonic-gate goto exclude;
8570Sstevel@tonic-gate }
8580Sstevel@tonic-gate
8590Sstevel@tonic-gate n += csz;
8600Sstevel@tonic-gate }
8610Sstevel@tonic-gate
8620Sstevel@tonic-gate phdr.p_offset = *pgc->pgc_doff;
8630Sstevel@tonic-gate phdr.p_filesz = pmp->pr_size;
8640Sstevel@tonic-gate *pgc->pgc_doff += roundup(phdr.p_filesz, 8);
8650Sstevel@tonic-gate
8660Sstevel@tonic-gate exclude:
8670Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
8680Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &phdr, sizeof (phdr),
8690Sstevel@tonic-gate *pgc->pgc_poff) != sizeof (phdr))
8700Sstevel@tonic-gate return (1);
8710Sstevel@tonic-gate
8720Sstevel@tonic-gate *pgc->pgc_poff += sizeof (phdr);
8730Sstevel@tonic-gate #ifdef _LP64
8740Sstevel@tonic-gate } else {
8750Sstevel@tonic-gate Elf32_Phdr phdr32;
8760Sstevel@tonic-gate
8770Sstevel@tonic-gate bzero(&phdr32, sizeof (phdr32));
8780Sstevel@tonic-gate phdr32.p_type = phdr.p_type;
8790Sstevel@tonic-gate phdr32.p_vaddr = (Elf32_Addr)phdr.p_vaddr;
8800Sstevel@tonic-gate phdr32.p_memsz = (Elf32_Word)phdr.p_memsz;
8810Sstevel@tonic-gate phdr32.p_flags = phdr.p_flags;
8820Sstevel@tonic-gate phdr32.p_offset = (Elf32_Off)phdr.p_offset;
8830Sstevel@tonic-gate phdr32.p_filesz = (Elf32_Word)phdr.p_filesz;
8840Sstevel@tonic-gate
8850Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &phdr32, sizeof (phdr32),
8860Sstevel@tonic-gate *pgc->pgc_poff) != sizeof (phdr32))
8870Sstevel@tonic-gate return (1);
8880Sstevel@tonic-gate
8890Sstevel@tonic-gate *pgc->pgc_poff += sizeof (phdr32);
8900Sstevel@tonic-gate #endif /* _LP64 */
8910Sstevel@tonic-gate }
8920Sstevel@tonic-gate
8930Sstevel@tonic-gate return (0);
8940Sstevel@tonic-gate }
8950Sstevel@tonic-gate
8960Sstevel@tonic-gate int
write_shstrtab(struct ps_prochandle * P,pgcore_t * pgc)8970Sstevel@tonic-gate write_shstrtab(struct ps_prochandle *P, pgcore_t *pgc)
8980Sstevel@tonic-gate {
8990Sstevel@tonic-gate off64_t off = *pgc->pgc_doff;
9000Sstevel@tonic-gate size_t size = 0;
9010Sstevel@tonic-gate shstrtab_t *s = &pgc->pgc_shstrtab;
9020Sstevel@tonic-gate int i, ndx;
9030Sstevel@tonic-gate
9040Sstevel@tonic-gate if (shstrtab_size(s) == 1)
9050Sstevel@tonic-gate return (0);
9060Sstevel@tonic-gate
9070Sstevel@tonic-gate /*
9080Sstevel@tonic-gate * Preemptively stick the name of the shstrtab in the string table.
9090Sstevel@tonic-gate */
9100Sstevel@tonic-gate (void) shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);
9110Sstevel@tonic-gate size = shstrtab_size(s);
9120Sstevel@tonic-gate
9130Sstevel@tonic-gate /*
9140Sstevel@tonic-gate * Dump all the strings that we used being sure we include the
9150Sstevel@tonic-gate * terminating null character.
9160Sstevel@tonic-gate */
9170Sstevel@tonic-gate for (i = 0; i < STR_NUM; i++) {
918942Sahl if ((ndx = s->sst_ndx[i]) != 0 || i == STR_NONE) {
9190Sstevel@tonic-gate const char *str = shstrtab_data[i];
9200Sstevel@tonic-gate size_t len = strlen(str) + 1;
9210Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, str, len, off + ndx) != len)
9220Sstevel@tonic-gate return (1);
9230Sstevel@tonic-gate }
9240Sstevel@tonic-gate }
9250Sstevel@tonic-gate
9260Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) {
9270Sstevel@tonic-gate Elf32_Shdr shdr;
9280Sstevel@tonic-gate
9290Sstevel@tonic-gate bzero(&shdr, sizeof (shdr));
9300Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);
9310Sstevel@tonic-gate shdr.sh_size = size;
9320Sstevel@tonic-gate shdr.sh_offset = *pgc->pgc_doff;
9330Sstevel@tonic-gate shdr.sh_addralign = 1;
9340Sstevel@tonic-gate shdr.sh_flags = SHF_STRINGS;
9350Sstevel@tonic-gate shdr.sh_type = SHT_STRTAB;
9360Sstevel@tonic-gate
9370Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
9380Sstevel@tonic-gate *pgc->pgc_soff) != sizeof (shdr))
9390Sstevel@tonic-gate return (1);
9400Sstevel@tonic-gate
9410Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr);
9420Sstevel@tonic-gate #ifdef _LP64
9430Sstevel@tonic-gate } else {
9440Sstevel@tonic-gate Elf64_Shdr shdr;
9450Sstevel@tonic-gate
9460Sstevel@tonic-gate bzero(&shdr, sizeof (shdr));
9470Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);
9480Sstevel@tonic-gate shdr.sh_size = size;
9490Sstevel@tonic-gate shdr.sh_offset = *pgc->pgc_doff;
9500Sstevel@tonic-gate shdr.sh_addralign = 1;
9510Sstevel@tonic-gate shdr.sh_flags = SHF_STRINGS;
9520Sstevel@tonic-gate shdr.sh_type = SHT_STRTAB;
9530Sstevel@tonic-gate
9540Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
9550Sstevel@tonic-gate *pgc->pgc_soff) != sizeof (shdr))
9560Sstevel@tonic-gate return (1);
9570Sstevel@tonic-gate
9580Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr);
9590Sstevel@tonic-gate #endif /* _LP64 */
9600Sstevel@tonic-gate }
9610Sstevel@tonic-gate
9620Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8);
9630Sstevel@tonic-gate
9640Sstevel@tonic-gate return (0);
9650Sstevel@tonic-gate }
9660Sstevel@tonic-gate
9670Sstevel@tonic-gate /*
9680Sstevel@tonic-gate * Don't explicity stop the process; that's up to the consumer.
9690Sstevel@tonic-gate */
9700Sstevel@tonic-gate int
Pfgcore(struct ps_prochandle * P,int fd,core_content_t content)9710Sstevel@tonic-gate Pfgcore(struct ps_prochandle *P, int fd, core_content_t content)
9720Sstevel@tonic-gate {
9730Sstevel@tonic-gate char plat[SYS_NMLN];
9740Sstevel@tonic-gate char zonename[ZONENAME_MAX];
9750Sstevel@tonic-gate int platlen = -1;
9760Sstevel@tonic-gate pgcore_t pgc;
9770Sstevel@tonic-gate off64_t poff, soff, doff, boff;
9780Sstevel@tonic-gate struct utsname uts;
9790Sstevel@tonic-gate uint_t nphdrs, nshdrs;
9800Sstevel@tonic-gate
9810Sstevel@tonic-gate if (ftruncate64(fd, 0) != 0)
9820Sstevel@tonic-gate return (-1);
9830Sstevel@tonic-gate
9840Sstevel@tonic-gate if (content == CC_CONTENT_INVALID) {
9850Sstevel@tonic-gate errno = EINVAL;
9860Sstevel@tonic-gate return (-1);
9870Sstevel@tonic-gate }
9880Sstevel@tonic-gate
9890Sstevel@tonic-gate /*
9900Sstevel@tonic-gate * Cache the mappings and other useful data.
9910Sstevel@tonic-gate */
9920Sstevel@tonic-gate (void) Prd_agent(P);
9930Sstevel@tonic-gate (void) Ppsinfo(P);
9940Sstevel@tonic-gate
9950Sstevel@tonic-gate pgc.P = P;
9960Sstevel@tonic-gate pgc.pgc_fd = fd;
9970Sstevel@tonic-gate pgc.pgc_poff = &poff;
9980Sstevel@tonic-gate pgc.pgc_soff = &soff;
9990Sstevel@tonic-gate pgc.pgc_doff = &doff;
10000Sstevel@tonic-gate pgc.pgc_content = content;
10010Sstevel@tonic-gate pgc.pgc_chunksz = PAGESIZE;
10020Sstevel@tonic-gate if ((pgc.pgc_chunk = malloc(pgc.pgc_chunksz)) == NULL)
10030Sstevel@tonic-gate return (-1);
10040Sstevel@tonic-gate
10050Sstevel@tonic-gate shstrtab_init(&pgc.pgc_shstrtab);
10060Sstevel@tonic-gate
10070Sstevel@tonic-gate /*
10080Sstevel@tonic-gate * There are two PT_NOTE program headers for ancillary data, and
10090Sstevel@tonic-gate * one for each mapping.
10100Sstevel@tonic-gate */
10110Sstevel@tonic-gate nphdrs = 2 + P->map_count;
10120Sstevel@tonic-gate nshdrs = count_sections(&pgc);
10130Sstevel@tonic-gate
10140Sstevel@tonic-gate (void) Pplatform(P, plat, sizeof (plat));
10150Sstevel@tonic-gate platlen = strlen(plat) + 1;
10160Sstevel@tonic-gate Preadauxvec(P);
10170Sstevel@tonic-gate (void) Puname(P, &uts);
10180Sstevel@tonic-gate if (Pzonename(P, zonename, sizeof (zonename)) == NULL)
10190Sstevel@tonic-gate zonename[0] = '\0';
10200Sstevel@tonic-gate
10210Sstevel@tonic-gate /*
1022942Sahl * The core file contents may required zero section headers, but if we
1023942Sahl * overflow the 16 bits allotted to the program header count in the ELF
1024942Sahl * header, we'll need that program header at index zero.
1025942Sahl */
1026942Sahl if (nshdrs == 0 && nphdrs >= PN_XNUM)
1027942Sahl nshdrs = 1;
1028942Sahl
1029942Sahl /*
10300Sstevel@tonic-gate * Set up the ELF header.
10310Sstevel@tonic-gate */
10320Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) {
10330Sstevel@tonic-gate Elf32_Ehdr ehdr;
10340Sstevel@tonic-gate
10350Sstevel@tonic-gate bzero(&ehdr, sizeof (ehdr));
10360Sstevel@tonic-gate ehdr.e_ident[EI_MAG0] = ELFMAG0;
10370Sstevel@tonic-gate ehdr.e_ident[EI_MAG1] = ELFMAG1;
10380Sstevel@tonic-gate ehdr.e_ident[EI_MAG2] = ELFMAG2;
10390Sstevel@tonic-gate ehdr.e_ident[EI_MAG3] = ELFMAG3;
10400Sstevel@tonic-gate ehdr.e_type = ET_CORE;
10410Sstevel@tonic-gate
10420Sstevel@tonic-gate ehdr.e_ident[EI_CLASS] = ELFCLASS32;
10430Sstevel@tonic-gate #if defined(__sparc)
10440Sstevel@tonic-gate ehdr.e_machine = EM_SPARC;
10450Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
10460Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64)
10470Sstevel@tonic-gate ehdr.e_machine = EM_386;
10480Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
10490Sstevel@tonic-gate #else
10500Sstevel@tonic-gate #error "unknown machine type"
10510Sstevel@tonic-gate #endif
10520Sstevel@tonic-gate ehdr.e_ident[EI_VERSION] = EV_CURRENT;
10530Sstevel@tonic-gate
10540Sstevel@tonic-gate ehdr.e_version = EV_CURRENT;
10550Sstevel@tonic-gate ehdr.e_ehsize = sizeof (ehdr);
1056942Sahl
1057942Sahl if (nphdrs >= PN_XNUM)
1058942Sahl ehdr.e_phnum = PN_XNUM;
1059942Sahl else
1060942Sahl ehdr.e_phnum = (unsigned short)nphdrs;
1061942Sahl
10620Sstevel@tonic-gate ehdr.e_phentsize = sizeof (Elf32_Phdr);
10630Sstevel@tonic-gate ehdr.e_phoff = ehdr.e_ehsize;
10640Sstevel@tonic-gate
1065942Sahl if (nshdrs > 0) {
1066942Sahl if (nshdrs >= SHN_LORESERVE)
1067942Sahl ehdr.e_shnum = 0;
1068942Sahl else
1069942Sahl ehdr.e_shnum = (unsigned short)nshdrs;
1070942Sahl
1071942Sahl if (nshdrs - 1 >= SHN_LORESERVE)
1072942Sahl ehdr.e_shstrndx = SHN_XINDEX;
1073942Sahl else
1074942Sahl ehdr.e_shstrndx = (unsigned short)(nshdrs - 1);
1075942Sahl
10760Sstevel@tonic-gate ehdr.e_shentsize = sizeof (Elf32_Shdr);
1077942Sahl ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs;
10780Sstevel@tonic-gate }
10790Sstevel@tonic-gate
10800Sstevel@tonic-gate if (pwrite64(fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
10810Sstevel@tonic-gate goto err;
10820Sstevel@tonic-gate
10830Sstevel@tonic-gate poff = ehdr.e_phoff;
1084942Sahl soff = ehdr.e_shoff;
10850Sstevel@tonic-gate doff = boff = ehdr.e_ehsize +
1086942Sahl ehdr.e_phentsize * nphdrs +
1087942Sahl ehdr.e_shentsize * nshdrs;
10880Sstevel@tonic-gate
10890Sstevel@tonic-gate #ifdef _LP64
10900Sstevel@tonic-gate } else {
10910Sstevel@tonic-gate Elf64_Ehdr ehdr;
10920Sstevel@tonic-gate
10930Sstevel@tonic-gate bzero(&ehdr, sizeof (ehdr));
10940Sstevel@tonic-gate ehdr.e_ident[EI_MAG0] = ELFMAG0;
10950Sstevel@tonic-gate ehdr.e_ident[EI_MAG1] = ELFMAG1;
10960Sstevel@tonic-gate ehdr.e_ident[EI_MAG2] = ELFMAG2;
10970Sstevel@tonic-gate ehdr.e_ident[EI_MAG3] = ELFMAG3;
10980Sstevel@tonic-gate ehdr.e_type = ET_CORE;
10990Sstevel@tonic-gate
11000Sstevel@tonic-gate ehdr.e_ident[EI_CLASS] = ELFCLASS64;
11010Sstevel@tonic-gate #if defined(__sparc)
11020Sstevel@tonic-gate ehdr.e_machine = EM_SPARCV9;
11030Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
11040Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64)
11050Sstevel@tonic-gate ehdr.e_machine = EM_AMD64;
11060Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
11070Sstevel@tonic-gate #else
11080Sstevel@tonic-gate #error "unknown machine type"
11090Sstevel@tonic-gate #endif
11100Sstevel@tonic-gate ehdr.e_ident[EI_VERSION] = EV_CURRENT;
11110Sstevel@tonic-gate
11120Sstevel@tonic-gate ehdr.e_version = EV_CURRENT;
11130Sstevel@tonic-gate ehdr.e_ehsize = sizeof (ehdr);
1114942Sahl
1115942Sahl if (nphdrs >= PN_XNUM)
1116942Sahl ehdr.e_phnum = PN_XNUM;
1117942Sahl else
1118942Sahl ehdr.e_phnum = (unsigned short)nphdrs;
1119942Sahl
11200Sstevel@tonic-gate ehdr.e_phentsize = sizeof (Elf64_Phdr);
11210Sstevel@tonic-gate ehdr.e_phoff = ehdr.e_ehsize;
11220Sstevel@tonic-gate
1123942Sahl if (nshdrs > 0) {
1124942Sahl if (nshdrs >= SHN_LORESERVE)
1125942Sahl ehdr.e_shnum = 0;
1126942Sahl else
1127942Sahl ehdr.e_shnum = (unsigned short)nshdrs;
1128942Sahl
1129942Sahl if (nshdrs - 1 >= SHN_LORESERVE)
1130942Sahl ehdr.e_shstrndx = SHN_XINDEX;
1131942Sahl else
1132942Sahl ehdr.e_shstrndx = (unsigned short)(nshdrs - 1);
1133942Sahl
11340Sstevel@tonic-gate ehdr.e_shentsize = sizeof (Elf64_Shdr);
1135942Sahl ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs;
11360Sstevel@tonic-gate }
11370Sstevel@tonic-gate
11380Sstevel@tonic-gate if (pwrite64(fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
11390Sstevel@tonic-gate goto err;
11400Sstevel@tonic-gate
11410Sstevel@tonic-gate poff = ehdr.e_phoff;
1142942Sahl soff = ehdr.e_shoff;
1143942Sahl doff = boff = ehdr.e_ehsize +
1144942Sahl ehdr.e_phentsize * nphdrs +
1145942Sahl ehdr.e_shentsize * nshdrs;
11460Sstevel@tonic-gate
11470Sstevel@tonic-gate #endif /* _LP64 */
11480Sstevel@tonic-gate }
11490Sstevel@tonic-gate
11500Sstevel@tonic-gate /*
1151942Sahl * Write the zero indexed section if it exists.
1152942Sahl */
1153942Sahl if (nshdrs > 0 && write_shdr(&pgc, STR_NONE, 0, 0, 0, 0,
1154942Sahl nshdrs >= SHN_LORESERVE ? nshdrs : 0,
1155942Sahl nshdrs - 1 >= SHN_LORESERVE ? nshdrs - 1 : 0,
1156942Sahl nphdrs >= PN_XNUM ? nphdrs : 0, 0, 0) != 0)
1157942Sahl goto err;
1158942Sahl
1159942Sahl /*
11600Sstevel@tonic-gate * Construct the old-style note header and section.
11610Sstevel@tonic-gate */
11620Sstevel@tonic-gate
11630Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
11640Sstevel@tonic-gate prpsinfo_t prpsinfo;
11650Sstevel@tonic-gate
11660Sstevel@tonic-gate mkprpsinfo(P, &prpsinfo);
11670Sstevel@tonic-gate if (write_note(fd, NT_PRPSINFO, &prpsinfo, sizeof (prpsinfo_t),
11680Sstevel@tonic-gate &doff) != 0) {
11690Sstevel@tonic-gate goto err;
11700Sstevel@tonic-gate }
11710Sstevel@tonic-gate if (write_note(fd, NT_AUXV, P->auxv,
11720Sstevel@tonic-gate P->nauxv * sizeof (P->auxv[0]), &doff) != 0) {
11730Sstevel@tonic-gate goto err;
11740Sstevel@tonic-gate }
11750Sstevel@tonic-gate #ifdef _LP64
11760Sstevel@tonic-gate } else {
11770Sstevel@tonic-gate prpsinfo32_t pi32;
11780Sstevel@tonic-gate auxv32_t *av32;
11790Sstevel@tonic-gate size_t size = sizeof (auxv32_t) * P->nauxv;
11800Sstevel@tonic-gate int i;
11810Sstevel@tonic-gate
11820Sstevel@tonic-gate mkprpsinfo32(P, &pi32);
11830Sstevel@tonic-gate if (write_note(fd, NT_PRPSINFO, &pi32, sizeof (prpsinfo32_t),
11840Sstevel@tonic-gate &doff) != 0) {
11850Sstevel@tonic-gate goto err;
11860Sstevel@tonic-gate }
11870Sstevel@tonic-gate
11880Sstevel@tonic-gate if ((av32 = malloc(size)) == NULL)
11890Sstevel@tonic-gate goto err;
11900Sstevel@tonic-gate
11910Sstevel@tonic-gate for (i = 0; i < P->nauxv; i++) {
11920Sstevel@tonic-gate auxv_n_to_32(&P->auxv[i], &av32[i]);
11930Sstevel@tonic-gate }
11940Sstevel@tonic-gate
11950Sstevel@tonic-gate if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) {
11960Sstevel@tonic-gate free(av32);
11970Sstevel@tonic-gate goto err;
11980Sstevel@tonic-gate }
11990Sstevel@tonic-gate
12000Sstevel@tonic-gate free(av32);
12010Sstevel@tonic-gate #endif /* _LP64 */
12020Sstevel@tonic-gate }
12030Sstevel@tonic-gate
12040Sstevel@tonic-gate if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0)
12050Sstevel@tonic-gate goto err;
12060Sstevel@tonic-gate
12070Sstevel@tonic-gate if (Plwp_iter_all(P, old_per_lwp, &pgc) != 0)
12080Sstevel@tonic-gate goto err;
12090Sstevel@tonic-gate
12100Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) {
12110Sstevel@tonic-gate Elf32_Phdr phdr;
12120Sstevel@tonic-gate
12130Sstevel@tonic-gate bzero(&phdr, sizeof (phdr));
12140Sstevel@tonic-gate phdr.p_type = PT_NOTE;
12150Sstevel@tonic-gate phdr.p_flags = PF_R;
12160Sstevel@tonic-gate phdr.p_offset = (Elf32_Off)boff;
12170Sstevel@tonic-gate phdr.p_filesz = doff - boff;
12180Sstevel@tonic-gate boff = doff;
12190Sstevel@tonic-gate
12200Sstevel@tonic-gate if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
12210Sstevel@tonic-gate goto err;
12220Sstevel@tonic-gate poff += sizeof (phdr);
12230Sstevel@tonic-gate #ifdef _LP64
12240Sstevel@tonic-gate } else {
12250Sstevel@tonic-gate Elf64_Phdr phdr;
12260Sstevel@tonic-gate
12270Sstevel@tonic-gate bzero(&phdr, sizeof (phdr));
12280Sstevel@tonic-gate phdr.p_type = PT_NOTE;
12290Sstevel@tonic-gate phdr.p_flags = PF_R;
12300Sstevel@tonic-gate phdr.p_offset = boff;
12310Sstevel@tonic-gate phdr.p_filesz = doff - boff;
12320Sstevel@tonic-gate boff = doff;
12330Sstevel@tonic-gate
12340Sstevel@tonic-gate if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
12350Sstevel@tonic-gate goto err;
12360Sstevel@tonic-gate poff += sizeof (phdr);
12370Sstevel@tonic-gate #endif /* _LP64 */
12380Sstevel@tonic-gate }
12390Sstevel@tonic-gate
12400Sstevel@tonic-gate /*
12410Sstevel@tonic-gate * Construct the new-style note header and section.
12420Sstevel@tonic-gate */
12430Sstevel@tonic-gate
12440Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
12450Sstevel@tonic-gate if (write_note(fd, NT_PSINFO, &P->psinfo, sizeof (psinfo_t),
12460Sstevel@tonic-gate &doff) != 0) {
12470Sstevel@tonic-gate goto err;
12480Sstevel@tonic-gate }
12490Sstevel@tonic-gate if (write_note(fd, NT_PSTATUS, &P->status, sizeof (pstatus_t),
12500Sstevel@tonic-gate &doff) != 0) {
12510Sstevel@tonic-gate goto err;
12520Sstevel@tonic-gate }
12530Sstevel@tonic-gate if (write_note(fd, NT_AUXV, P->auxv,
12540Sstevel@tonic-gate P->nauxv * sizeof (P->auxv[0]), &doff) != 0) {
12550Sstevel@tonic-gate goto err;
12560Sstevel@tonic-gate }
12570Sstevel@tonic-gate #ifdef _LP64
12580Sstevel@tonic-gate } else {
12590Sstevel@tonic-gate psinfo32_t pi32;
12600Sstevel@tonic-gate pstatus32_t ps32;
12610Sstevel@tonic-gate auxv32_t *av32;
12620Sstevel@tonic-gate size_t size = sizeof (auxv32_t) * P->nauxv;
12630Sstevel@tonic-gate int i;
12640Sstevel@tonic-gate
12650Sstevel@tonic-gate psinfo_n_to_32(&P->psinfo, &pi32);
12660Sstevel@tonic-gate if (write_note(fd, NT_PSINFO, &pi32, sizeof (psinfo32_t),
1267*11135SRoger.Faulkner@Sun.COM &doff) != 0) {
12680Sstevel@tonic-gate goto err;
12690Sstevel@tonic-gate }
12700Sstevel@tonic-gate pstatus_n_to_32(&P->status, &ps32);
12710Sstevel@tonic-gate if (write_note(fd, NT_PSTATUS, &ps32, sizeof (pstatus32_t),
1272*11135SRoger.Faulkner@Sun.COM &doff) != 0) {
12730Sstevel@tonic-gate goto err;
12740Sstevel@tonic-gate }
12750Sstevel@tonic-gate if ((av32 = malloc(size)) == NULL)
12760Sstevel@tonic-gate goto err;
12770Sstevel@tonic-gate
12780Sstevel@tonic-gate for (i = 0; i < P->nauxv; i++) {
12790Sstevel@tonic-gate auxv_n_to_32(&P->auxv[i], &av32[i]);
12800Sstevel@tonic-gate }
12810Sstevel@tonic-gate
12820Sstevel@tonic-gate if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) {
12830Sstevel@tonic-gate free(av32);
12840Sstevel@tonic-gate goto err;
12850Sstevel@tonic-gate }
12860Sstevel@tonic-gate
12870Sstevel@tonic-gate free(av32);
12880Sstevel@tonic-gate #endif /* _LP64 */
12890Sstevel@tonic-gate }
12900Sstevel@tonic-gate
12910Sstevel@tonic-gate if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0 ||
12920Sstevel@tonic-gate write_note(fd, NT_UTSNAME, &uts, sizeof (uts), &doff) != 0 ||
12930Sstevel@tonic-gate write_note(fd, NT_CONTENT, &content, sizeof (content), &doff) != 0)
12940Sstevel@tonic-gate goto err;
12950Sstevel@tonic-gate
12960Sstevel@tonic-gate {
12970Sstevel@tonic-gate prcred_t cred, *cp;
12980Sstevel@tonic-gate size_t size = sizeof (prcred_t);
12990Sstevel@tonic-gate
13000Sstevel@tonic-gate if (Pcred(P, &cred, 0) != 0)
13010Sstevel@tonic-gate goto err;
13020Sstevel@tonic-gate
13030Sstevel@tonic-gate if (cred.pr_ngroups > 0)
13040Sstevel@tonic-gate size += sizeof (gid_t) * (cred.pr_ngroups - 1);
13050Sstevel@tonic-gate if ((cp = malloc(size)) == NULL)
13060Sstevel@tonic-gate goto err;
13070Sstevel@tonic-gate
13080Sstevel@tonic-gate if (Pcred(P, cp, cred.pr_ngroups) != 0 ||
13090Sstevel@tonic-gate write_note(fd, NT_PRCRED, cp, size, &doff) != 0) {
13100Sstevel@tonic-gate free(cp);
13110Sstevel@tonic-gate goto err;
13120Sstevel@tonic-gate }
13130Sstevel@tonic-gate
13140Sstevel@tonic-gate free(cp);
13150Sstevel@tonic-gate }
13160Sstevel@tonic-gate
13170Sstevel@tonic-gate {
13180Sstevel@tonic-gate prpriv_t *ppriv;
13190Sstevel@tonic-gate const priv_impl_info_t *pinfo;
13200Sstevel@tonic-gate size_t pprivsz, pinfosz;
13210Sstevel@tonic-gate
13220Sstevel@tonic-gate if ((ppriv = proc_get_priv(P->pid)) == NULL)
13230Sstevel@tonic-gate goto err;
13240Sstevel@tonic-gate pprivsz = PRIV_PRPRIV_SIZE(ppriv);
13250Sstevel@tonic-gate
13260Sstevel@tonic-gate if (write_note(fd, NT_PRPRIV, ppriv, pprivsz, &doff) != 0) {
13270Sstevel@tonic-gate free(ppriv);
13280Sstevel@tonic-gate goto err;
13290Sstevel@tonic-gate }
13300Sstevel@tonic-gate free(ppriv);
13310Sstevel@tonic-gate
13320Sstevel@tonic-gate if ((pinfo = getprivimplinfo()) == NULL)
13330Sstevel@tonic-gate goto err;
13340Sstevel@tonic-gate pinfosz = PRIV_IMPL_INFO_SIZE(pinfo);
13350Sstevel@tonic-gate
13360Sstevel@tonic-gate if (write_note(fd, NT_PRPRIVINFO, pinfo, pinfosz, &doff) != 0)
13370Sstevel@tonic-gate goto err;
13380Sstevel@tonic-gate }
13390Sstevel@tonic-gate
13400Sstevel@tonic-gate if (write_note(fd, NT_ZONENAME, zonename, strlen(zonename) + 1,
13410Sstevel@tonic-gate &doff) != 0)
13420Sstevel@tonic-gate goto err;
13430Sstevel@tonic-gate
13440Sstevel@tonic-gate #if defined(__i386) || defined(__amd64)
13450Sstevel@tonic-gate /* CSTYLED */
13460Sstevel@tonic-gate {
13470Sstevel@tonic-gate struct ssd *ldtp;
13480Sstevel@tonic-gate size_t size;
13490Sstevel@tonic-gate int nldt;
13500Sstevel@tonic-gate
1351151Sahl /*
1352151Sahl * Only dump out non-zero sized LDT notes.
1353151Sahl */
1354151Sahl if ((nldt = Pldt(P, NULL, 0)) != 0) {
1355151Sahl size = sizeof (struct ssd) * nldt;
1356151Sahl if ((ldtp = malloc(size)) == NULL)
1357151Sahl goto err;
13580Sstevel@tonic-gate
1359151Sahl if (Pldt(P, ldtp, nldt) == -1 ||
1360151Sahl write_note(fd, NT_LDT, ldtp, size, &doff) != 0) {
1361151Sahl free(ldtp);
1362151Sahl goto err;
1363151Sahl }
1364151Sahl
13650Sstevel@tonic-gate free(ldtp);
13660Sstevel@tonic-gate }
13670Sstevel@tonic-gate }
13680Sstevel@tonic-gate #endif /* __i386 || __amd64 */
13690Sstevel@tonic-gate
13700Sstevel@tonic-gate if (Plwp_iter_all(P, new_per_lwp, &pgc) != 0)
13710Sstevel@tonic-gate goto err;
13720Sstevel@tonic-gate
13730Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) {
13740Sstevel@tonic-gate Elf32_Phdr phdr;
13750Sstevel@tonic-gate
13760Sstevel@tonic-gate bzero(&phdr, sizeof (phdr));
13770Sstevel@tonic-gate phdr.p_type = PT_NOTE;
13780Sstevel@tonic-gate phdr.p_flags = PF_R;
13790Sstevel@tonic-gate phdr.p_offset = (Elf32_Off)boff;
13800Sstevel@tonic-gate phdr.p_filesz = doff - boff;
13810Sstevel@tonic-gate boff = doff;
13820Sstevel@tonic-gate
13830Sstevel@tonic-gate if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
13840Sstevel@tonic-gate goto err;
13850Sstevel@tonic-gate poff += sizeof (phdr);
13860Sstevel@tonic-gate #ifdef _LP64
13870Sstevel@tonic-gate } else {
13880Sstevel@tonic-gate Elf64_Phdr phdr;
13890Sstevel@tonic-gate
13900Sstevel@tonic-gate bzero(&phdr, sizeof (phdr));
13910Sstevel@tonic-gate phdr.p_type = PT_NOTE;
13920Sstevel@tonic-gate phdr.p_flags = PF_R;
13930Sstevel@tonic-gate phdr.p_offset = boff;
13940Sstevel@tonic-gate phdr.p_filesz = doff - boff;
13950Sstevel@tonic-gate boff = doff;
13960Sstevel@tonic-gate
13970Sstevel@tonic-gate if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
13980Sstevel@tonic-gate goto err;
13990Sstevel@tonic-gate poff += sizeof (phdr);
14000Sstevel@tonic-gate #endif /* _LP64 */
14010Sstevel@tonic-gate }
14020Sstevel@tonic-gate
14030Sstevel@tonic-gate /*
14040Sstevel@tonic-gate * Construct the headers for each mapping and write out its data
14050Sstevel@tonic-gate * if the content parameter indicates that it should be present
14060Sstevel@tonic-gate * in the core file.
14070Sstevel@tonic-gate */
14080Sstevel@tonic-gate if (Pmapping_iter(P, dump_map, &pgc) != 0)
14090Sstevel@tonic-gate goto err;
14100Sstevel@tonic-gate
14110Sstevel@tonic-gate if (dump_sections(&pgc) != 0)
14120Sstevel@tonic-gate goto err;
14130Sstevel@tonic-gate
14140Sstevel@tonic-gate if (write_shstrtab(P, &pgc) != 0)
14150Sstevel@tonic-gate goto err;
14160Sstevel@tonic-gate
14170Sstevel@tonic-gate free(pgc.pgc_chunk);
14180Sstevel@tonic-gate
14190Sstevel@tonic-gate return (0);
14200Sstevel@tonic-gate
14210Sstevel@tonic-gate err:
14220Sstevel@tonic-gate /*
14230Sstevel@tonic-gate * Wipe out anything we may have written if there was an error.
14240Sstevel@tonic-gate */
14250Sstevel@tonic-gate (void) ftruncate64(fd, 0);
14260Sstevel@tonic-gate free(pgc.pgc_chunk);
14270Sstevel@tonic-gate return (-1);
14280Sstevel@tonic-gate }
14290Sstevel@tonic-gate
14300Sstevel@tonic-gate static const char *content_str[] = {
14310Sstevel@tonic-gate "stack", /* CC_CONTENT_STACK */
14320Sstevel@tonic-gate "heap", /* CC_CONTENT_HEAP */
14330Sstevel@tonic-gate "shfile", /* CC_CONTENT_SHFILE */
14340Sstevel@tonic-gate "shanon", /* CC_CONTENT_SHANON */
14350Sstevel@tonic-gate "text", /* CC_CONTENT_TEXT */
14360Sstevel@tonic-gate "data", /* CC_CONTENT_DATA */
14370Sstevel@tonic-gate "rodata", /* CC_CONTENT_RODATA */
14380Sstevel@tonic-gate "anon", /* CC_CONTENT_ANON */
14390Sstevel@tonic-gate "shm", /* CC_CONTENT_SHM */
14400Sstevel@tonic-gate "ism", /* CC_CONTENT_ISM */
14410Sstevel@tonic-gate "dism", /* CC_CONTENT_DISM */
14420Sstevel@tonic-gate "ctf", /* CC_CONTENT_CTF */
14430Sstevel@tonic-gate "symtab", /* CC_CONTENT_SYMTAB */
14440Sstevel@tonic-gate };
14450Sstevel@tonic-gate
14460Sstevel@tonic-gate static uint_t ncontent_str = sizeof (content_str) / sizeof (content_str[0]);
14470Sstevel@tonic-gate
14480Sstevel@tonic-gate #define STREQ(a, b, n) (strlen(b) == (n) && strncmp(a, b, n) == 0)
14490Sstevel@tonic-gate
14500Sstevel@tonic-gate int
proc_str2content(const char * str,core_content_t * cp)14510Sstevel@tonic-gate proc_str2content(const char *str, core_content_t *cp)
14520Sstevel@tonic-gate {
14530Sstevel@tonic-gate const char *cur = str;
14540Sstevel@tonic-gate int add = 1;
14550Sstevel@tonic-gate core_content_t mask, content = 0;
14560Sstevel@tonic-gate
14570Sstevel@tonic-gate for (;;) {
14580Sstevel@tonic-gate for (cur = str; isalpha(*cur); cur++)
14590Sstevel@tonic-gate continue;
14600Sstevel@tonic-gate
14610Sstevel@tonic-gate if (STREQ(str, "default", cur - str)) {
14620Sstevel@tonic-gate mask = CC_CONTENT_DEFAULT;
14630Sstevel@tonic-gate } else if (STREQ(str, "all", cur - str)) {
14640Sstevel@tonic-gate mask = CC_CONTENT_ALL;
14650Sstevel@tonic-gate } else if (STREQ(str, "none", cur - str)) {
14660Sstevel@tonic-gate mask = 0;
14670Sstevel@tonic-gate } else {
14680Sstevel@tonic-gate int i = 0;
14690Sstevel@tonic-gate
14700Sstevel@tonic-gate while (!STREQ(str, content_str[i], cur - str)) {
14710Sstevel@tonic-gate i++;
14720Sstevel@tonic-gate
14730Sstevel@tonic-gate if (i >= ncontent_str)
14740Sstevel@tonic-gate return (-1);
14750Sstevel@tonic-gate }
14760Sstevel@tonic-gate
14770Sstevel@tonic-gate mask = (core_content_t)1 << i;
14780Sstevel@tonic-gate }
14790Sstevel@tonic-gate
14800Sstevel@tonic-gate if (add)
14810Sstevel@tonic-gate content |= mask;
14820Sstevel@tonic-gate else
14830Sstevel@tonic-gate content &= ~mask;
14840Sstevel@tonic-gate
14850Sstevel@tonic-gate switch (*cur) {
14860Sstevel@tonic-gate case '\0':
14870Sstevel@tonic-gate *cp = content;
14880Sstevel@tonic-gate return (0);
14890Sstevel@tonic-gate case '+':
14900Sstevel@tonic-gate add = 1;
14910Sstevel@tonic-gate break;
14920Sstevel@tonic-gate case '-':
14930Sstevel@tonic-gate add = 0;
14940Sstevel@tonic-gate break;
14950Sstevel@tonic-gate default:
14960Sstevel@tonic-gate return (-1);
14970Sstevel@tonic-gate }
14980Sstevel@tonic-gate
14990Sstevel@tonic-gate str = cur + 1;
15000Sstevel@tonic-gate }
15010Sstevel@tonic-gate }
15020Sstevel@tonic-gate
15030Sstevel@tonic-gate static int
popc(core_content_t x)15040Sstevel@tonic-gate popc(core_content_t x)
15050Sstevel@tonic-gate {
15060Sstevel@tonic-gate int i;
15070Sstevel@tonic-gate
15080Sstevel@tonic-gate for (i = 0; x != 0; i++)
15090Sstevel@tonic-gate x &= x - 1;
15100Sstevel@tonic-gate
15110Sstevel@tonic-gate return (i);
15120Sstevel@tonic-gate }
15130Sstevel@tonic-gate
15140Sstevel@tonic-gate int
proc_content2str(core_content_t content,char * buf,size_t size)15150Sstevel@tonic-gate proc_content2str(core_content_t content, char *buf, size_t size)
15160Sstevel@tonic-gate {
15170Sstevel@tonic-gate int nonecnt, defcnt, allcnt;
15180Sstevel@tonic-gate core_content_t mask, bit;
15190Sstevel@tonic-gate int first;
15200Sstevel@tonic-gate uint_t index;
15210Sstevel@tonic-gate size_t n, tot = 0;
15220Sstevel@tonic-gate
15230Sstevel@tonic-gate if (content == 0)
15240Sstevel@tonic-gate return ((int)strlcpy(buf, "none", size));
15250Sstevel@tonic-gate
15260Sstevel@tonic-gate if (content & ~CC_CONTENT_ALL)
15270Sstevel@tonic-gate return ((int)strlcpy(buf, "<invalid>", size));
15280Sstevel@tonic-gate
15290Sstevel@tonic-gate nonecnt = popc(content);
15300Sstevel@tonic-gate defcnt = 1 + popc(content ^ CC_CONTENT_DEFAULT);
15310Sstevel@tonic-gate allcnt = 1 + popc(content ^ CC_CONTENT_ALL);
15320Sstevel@tonic-gate
15330Sstevel@tonic-gate if (defcnt <= nonecnt && defcnt <= allcnt) {
15340Sstevel@tonic-gate mask = content ^ CC_CONTENT_DEFAULT;
15350Sstevel@tonic-gate first = 0;
15360Sstevel@tonic-gate tot += (n = strlcpy(buf, "default", size));
15370Sstevel@tonic-gate if (n > size)
15380Sstevel@tonic-gate n = size;
15390Sstevel@tonic-gate buf += n;
15400Sstevel@tonic-gate size -= n;
15410Sstevel@tonic-gate } else if (allcnt < nonecnt) {
15420Sstevel@tonic-gate mask = content ^ CC_CONTENT_ALL;
15430Sstevel@tonic-gate first = 0;
15440Sstevel@tonic-gate tot += (n = strlcpy(buf, "all", size));
15450Sstevel@tonic-gate if (n > size)
15460Sstevel@tonic-gate n = size;
15470Sstevel@tonic-gate buf += n;
15480Sstevel@tonic-gate size -= n;
15490Sstevel@tonic-gate } else {
15500Sstevel@tonic-gate mask = content;
15510Sstevel@tonic-gate first = 1;
15520Sstevel@tonic-gate }
15530Sstevel@tonic-gate
15540Sstevel@tonic-gate while (mask != 0) {
15550Sstevel@tonic-gate bit = mask ^ (mask & (mask - 1));
15560Sstevel@tonic-gate
15570Sstevel@tonic-gate if (!first) {
15580Sstevel@tonic-gate if (size > 1) {
15590Sstevel@tonic-gate *buf = (bit & content) ? '+' : '-';
15600Sstevel@tonic-gate buf++;
15610Sstevel@tonic-gate size--;
15620Sstevel@tonic-gate }
15630Sstevel@tonic-gate
15640Sstevel@tonic-gate tot++;
15650Sstevel@tonic-gate }
15660Sstevel@tonic-gate index = popc(bit - 1);
15670Sstevel@tonic-gate tot += (n = strlcpy(buf, content_str[index], size));
15680Sstevel@tonic-gate if (n > size)
15690Sstevel@tonic-gate n = size;
15700Sstevel@tonic-gate buf += n;
15710Sstevel@tonic-gate size -= n;
15720Sstevel@tonic-gate
15730Sstevel@tonic-gate mask ^= bit;
15740Sstevel@tonic-gate first = 0;
15750Sstevel@tonic-gate }
15760Sstevel@tonic-gate
15770Sstevel@tonic-gate return ((int)tot);
15780Sstevel@tonic-gate }
1579