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