17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5d51e9074Sab196087 * Common Development and Distribution License (the "License"). 6d51e9074Sab196087 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 212c797a4eSRoger A. Faulkner 227c478bd9Sstevel@tonic-gate /* 232c797a4eSRoger A. Faulkner * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 2634bdffbfSGarrett D'Amore /* 2734bdffbfSGarrett D'Amore * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. 28ab618543SJohn Levon * Copyright 2018 Joyent, Inc. 292a12f85aSJeremy Jones * Copyright (c) 2013 by Delphix. All rights reserved. 30a02120c4SAndy Fiddaman * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. 31*5d228828SRobert Mustacchi * Copyright 2021 Oxide Computer Company 3234bdffbfSGarrett D'Amore */ 337c478bd9Sstevel@tonic-gate 342c797a4eSRoger A. Faulkner #define _STRUCTURED_PROC 1 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <stdlib.h> 377c478bd9Sstevel@tonic-gate #include <ctype.h> 387c478bd9Sstevel@tonic-gate #include <string.h> 397c478bd9Sstevel@tonic-gate #include <strings.h> 407c478bd9Sstevel@tonic-gate #include <errno.h> 417c478bd9Sstevel@tonic-gate #include <procfs.h> 427c478bd9Sstevel@tonic-gate #include <priv.h> 437c478bd9Sstevel@tonic-gate #include <sys/elf.h> 447c478bd9Sstevel@tonic-gate #include <sys/machelf.h> 457c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 467c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 477c478bd9Sstevel@tonic-gate #include <sys/proc.h> 487c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #include <sys/old_procfs.h> 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate #include "Pcontrol.h" 537c478bd9Sstevel@tonic-gate #include "P32ton.h" 54a02120c4SAndy Fiddaman #include "proc_fd.h" 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate typedef enum { 5730da1432Sahl STR_NONE, 587c478bd9Sstevel@tonic-gate STR_CTF, 597c478bd9Sstevel@tonic-gate STR_SYMTAB, 607c478bd9Sstevel@tonic-gate STR_DYNSYM, 617c478bd9Sstevel@tonic-gate STR_STRTAB, 627c478bd9Sstevel@tonic-gate STR_DYNSTR, 637c478bd9Sstevel@tonic-gate STR_SHSTRTAB, 647c478bd9Sstevel@tonic-gate STR_NUM 657c478bd9Sstevel@tonic-gate } shstrtype_t; 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate static const char *shstrtab_data[] = { 6830da1432Sahl "", 697c478bd9Sstevel@tonic-gate ".SUNW_ctf", 707c478bd9Sstevel@tonic-gate ".symtab", 717c478bd9Sstevel@tonic-gate ".dynsym", 727c478bd9Sstevel@tonic-gate ".strtab", 737c478bd9Sstevel@tonic-gate ".dynstr", 747c478bd9Sstevel@tonic-gate ".shstrtab" 757c478bd9Sstevel@tonic-gate }; 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate typedef struct shstrtab { 787c478bd9Sstevel@tonic-gate int sst_ndx[STR_NUM]; 797c478bd9Sstevel@tonic-gate int sst_cur; 807c478bd9Sstevel@tonic-gate } shstrtab_t; 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate typedef struct { 837c478bd9Sstevel@tonic-gate struct ps_prochandle *P; 847c478bd9Sstevel@tonic-gate int pgc_fd; 857c478bd9Sstevel@tonic-gate off64_t *pgc_poff; 867c478bd9Sstevel@tonic-gate off64_t *pgc_soff; 877c478bd9Sstevel@tonic-gate off64_t *pgc_doff; 887c478bd9Sstevel@tonic-gate core_content_t pgc_content; 897c478bd9Sstevel@tonic-gate void *pgc_chunk; 907c478bd9Sstevel@tonic-gate size_t pgc_chunksz; 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate shstrtab_t pgc_shstrtab; 937c478bd9Sstevel@tonic-gate } pgcore_t; 947c478bd9Sstevel@tonic-gate 9534bdffbfSGarrett D'Amore typedef struct { 9634bdffbfSGarrett D'Amore int fd_fd; 9734bdffbfSGarrett D'Amore off64_t *fd_doff; 9834bdffbfSGarrett D'Amore } fditer_t; 9934bdffbfSGarrett D'Amore 10064e4e50aSKeith M Wesolowski static int 10164e4e50aSKeith M Wesolowski gc_pwrite64(int fd, const void *buf, size_t len, off64_t off) 10264e4e50aSKeith M Wesolowski { 10364e4e50aSKeith M Wesolowski int err; 10464e4e50aSKeith M Wesolowski 10564e4e50aSKeith M Wesolowski err = pwrite64(fd, buf, len, off); 10664e4e50aSKeith M Wesolowski 10764e4e50aSKeith M Wesolowski if (err < 0) 10864e4e50aSKeith M Wesolowski return (err); 10964e4e50aSKeith M Wesolowski 11064e4e50aSKeith M Wesolowski /* 11164e4e50aSKeith M Wesolowski * We will take a page from ZFS's book here and use the otherwise 11264e4e50aSKeith M Wesolowski * unused EBADE to mean a short write. Typically this will actually 11364e4e50aSKeith M Wesolowski * result from ENOSPC or EDQUOT, but we can't be sure. 11464e4e50aSKeith M Wesolowski */ 11564e4e50aSKeith M Wesolowski if (err < len) { 11664e4e50aSKeith M Wesolowski errno = EBADE; 11764e4e50aSKeith M Wesolowski return (-1); 11864e4e50aSKeith M Wesolowski } 11964e4e50aSKeith M Wesolowski 12064e4e50aSKeith M Wesolowski return (0); 12164e4e50aSKeith M Wesolowski } 12264e4e50aSKeith M Wesolowski 1237c478bd9Sstevel@tonic-gate static void 1247c478bd9Sstevel@tonic-gate shstrtab_init(shstrtab_t *s) 1257c478bd9Sstevel@tonic-gate { 1267c478bd9Sstevel@tonic-gate bzero(&s->sst_ndx, sizeof (s->sst_ndx)); 1277c478bd9Sstevel@tonic-gate s->sst_cur = 1; 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate static int 1317c478bd9Sstevel@tonic-gate shstrtab_ndx(shstrtab_t *s, shstrtype_t type) 1327c478bd9Sstevel@tonic-gate { 1337c478bd9Sstevel@tonic-gate int ret; 1347c478bd9Sstevel@tonic-gate 13530da1432Sahl if ((ret = s->sst_ndx[type]) != 0 || type == STR_NONE) 1367c478bd9Sstevel@tonic-gate return (ret); 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate ret = s->sst_ndx[type] = s->sst_cur; 1397c478bd9Sstevel@tonic-gate s->sst_cur += strlen(shstrtab_data[type]) + 1; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate return (ret); 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate static size_t 1457c478bd9Sstevel@tonic-gate shstrtab_size(const shstrtab_t *s) 1467c478bd9Sstevel@tonic-gate { 1477c478bd9Sstevel@tonic-gate return (s->sst_cur); 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate int 1517c478bd9Sstevel@tonic-gate Pgcore(struct ps_prochandle *P, const char *fname, core_content_t content) 1527c478bd9Sstevel@tonic-gate { 1537c478bd9Sstevel@tonic-gate int fd; 1547c478bd9Sstevel@tonic-gate int err; 15564e4e50aSKeith M Wesolowski int saved_errno; 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate if ((fd = creat64(fname, 0666)) < 0) 1587c478bd9Sstevel@tonic-gate return (-1); 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate if ((err = Pfgcore(P, fd, content)) != 0) { 16164e4e50aSKeith M Wesolowski saved_errno = errno; 1627c478bd9Sstevel@tonic-gate (void) close(fd); 1637c478bd9Sstevel@tonic-gate (void) unlink(fname); 16464e4e50aSKeith M Wesolowski errno = saved_errno; 1657c478bd9Sstevel@tonic-gate return (err); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate return (close(fd)); 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate /* 1727c478bd9Sstevel@tonic-gate * Since we don't want to use the old-school procfs interfaces, we use the 1737c478bd9Sstevel@tonic-gate * new-style data structures we already have to construct the old-style 1747c478bd9Sstevel@tonic-gate * data structures. We include these data structures in core files for 1757c478bd9Sstevel@tonic-gate * backward compatability. 1767c478bd9Sstevel@tonic-gate */ 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate static void 1797c478bd9Sstevel@tonic-gate mkprstatus(struct ps_prochandle *P, const lwpstatus_t *lsp, 1807c478bd9Sstevel@tonic-gate const lwpsinfo_t *lip, prstatus_t *psp) 1817c478bd9Sstevel@tonic-gate { 1827c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STOPPED) 1857c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0001; 1867c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISTOP) 1877c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0002; 1887c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_DSTOP) 1897c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0004; 1907c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLEEP) 1917c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0008; 1927c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_FORK) 1937c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0010; 1947c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_RLC) 1957c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0020; 1967c478bd9Sstevel@tonic-gate /* 1977c478bd9Sstevel@tonic-gate * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set; 1987c478bd9Sstevel@tonic-gate * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>. 1997c478bd9Sstevel@tonic-gate */ 2007c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PCINVAL) 2017c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0080; 2027c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISSYS) 2037c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0100; 2047c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STEP) 2057c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0200; 2067c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_KLC) 2077c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0400; 2087c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASYNC) 2097c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0800; 2107c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PTRACE) 2117c478bd9Sstevel@tonic-gate psp->pr_flags = 0x1000; 2127c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_MSACCT) 2137c478bd9Sstevel@tonic-gate psp->pr_flags = 0x2000; 2147c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_BPTADJ) 2157c478bd9Sstevel@tonic-gate psp->pr_flags = 0x4000; 2167c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLWP) 2177c478bd9Sstevel@tonic-gate psp->pr_flags = 0x8000; 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate psp->pr_why = lsp->pr_why; 2207c478bd9Sstevel@tonic-gate psp->pr_what = lsp->pr_what; 2217c478bd9Sstevel@tonic-gate psp->pr_info = lsp->pr_info; 2227c478bd9Sstevel@tonic-gate psp->pr_cursig = lsp->pr_cursig; 2237c478bd9Sstevel@tonic-gate psp->pr_nlwp = P->status.pr_nlwp; 2247c478bd9Sstevel@tonic-gate psp->pr_sigpend = P->status.pr_sigpend; 2257c478bd9Sstevel@tonic-gate psp->pr_sighold = lsp->pr_lwphold; 2267c478bd9Sstevel@tonic-gate psp->pr_altstack = lsp->pr_altstack; 2277c478bd9Sstevel@tonic-gate psp->pr_action = lsp->pr_action; 2287c478bd9Sstevel@tonic-gate psp->pr_pid = P->status.pr_pid; 2297c478bd9Sstevel@tonic-gate psp->pr_ppid = P->status.pr_ppid; 2307c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->status.pr_pgid; 2317c478bd9Sstevel@tonic-gate psp->pr_sid = P->status.pr_sid; 2327c478bd9Sstevel@tonic-gate psp->pr_utime = P->status.pr_utime; 2337c478bd9Sstevel@tonic-gate psp->pr_stime = P->status.pr_stime; 2347c478bd9Sstevel@tonic-gate psp->pr_cutime = P->status.pr_cutime; 2357c478bd9Sstevel@tonic-gate psp->pr_cstime = P->status.pr_cstime; 2367c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname)); 2377c478bd9Sstevel@tonic-gate psp->pr_syscall = lsp->pr_syscall; 2387c478bd9Sstevel@tonic-gate psp->pr_nsysarg = lsp->pr_nsysarg; 2397c478bd9Sstevel@tonic-gate bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg)); 2407c478bd9Sstevel@tonic-gate psp->pr_who = lsp->pr_lwpid; 2417c478bd9Sstevel@tonic-gate psp->pr_lwppend = lsp->pr_lwppend; 2427c478bd9Sstevel@tonic-gate psp->pr_oldcontext = (ucontext_t *)lsp->pr_oldcontext; 2437c478bd9Sstevel@tonic-gate psp->pr_brkbase = (caddr_t)P->status.pr_brkbase; 2447c478bd9Sstevel@tonic-gate psp->pr_brksize = P->status.pr_brksize; 2457c478bd9Sstevel@tonic-gate psp->pr_stkbase = (caddr_t)P->status.pr_stkbase; 2467c478bd9Sstevel@tonic-gate psp->pr_stksize = P->status.pr_stksize; 2477c478bd9Sstevel@tonic-gate psp->pr_processor = (short)lip->pr_onpro; 2487c478bd9Sstevel@tonic-gate psp->pr_bind = (short)lip->pr_bindpro; 2497c478bd9Sstevel@tonic-gate psp->pr_instr = lsp->pr_instr; 2507c478bd9Sstevel@tonic-gate bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg)); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate static void 2547c478bd9Sstevel@tonic-gate mkprpsinfo(struct ps_prochandle *P, prpsinfo_t *psp) 2557c478bd9Sstevel@tonic-gate { 2567c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 2577c478bd9Sstevel@tonic-gate psp->pr_state = P->psinfo.pr_lwp.pr_state; 2587c478bd9Sstevel@tonic-gate psp->pr_sname = P->psinfo.pr_lwp.pr_sname; 2597c478bd9Sstevel@tonic-gate psp->pr_zomb = (psp->pr_state == SZOMB); 2607c478bd9Sstevel@tonic-gate psp->pr_nice = P->psinfo.pr_lwp.pr_nice; 2617c478bd9Sstevel@tonic-gate psp->pr_flag = P->psinfo.pr_lwp.pr_flag; 2627c478bd9Sstevel@tonic-gate psp->pr_uid = P->psinfo.pr_uid; 2637c478bd9Sstevel@tonic-gate psp->pr_gid = P->psinfo.pr_gid; 2647c478bd9Sstevel@tonic-gate psp->pr_pid = P->psinfo.pr_pid; 2657c478bd9Sstevel@tonic-gate psp->pr_ppid = P->psinfo.pr_ppid; 2667c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->psinfo.pr_pgid; 2677c478bd9Sstevel@tonic-gate psp->pr_sid = P->psinfo.pr_sid; 2687c478bd9Sstevel@tonic-gate psp->pr_addr = (caddr_t)P->psinfo.pr_addr; 2697c478bd9Sstevel@tonic-gate psp->pr_size = P->psinfo.pr_size; 2707c478bd9Sstevel@tonic-gate psp->pr_rssize = P->psinfo.pr_rssize; 2717c478bd9Sstevel@tonic-gate psp->pr_wchan = (caddr_t)P->psinfo.pr_lwp.pr_wchan; 2727c478bd9Sstevel@tonic-gate psp->pr_start = P->psinfo.pr_start; 2737c478bd9Sstevel@tonic-gate psp->pr_time = P->psinfo.pr_time; 2747c478bd9Sstevel@tonic-gate psp->pr_pri = P->psinfo.pr_lwp.pr_pri; 2757c478bd9Sstevel@tonic-gate psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri; 2767c478bd9Sstevel@tonic-gate psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu; 2777c478bd9Sstevel@tonic-gate psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev); 2787c478bd9Sstevel@tonic-gate psp->pr_lttydev = P->psinfo.pr_ttydev; 2797c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname, 2807c478bd9Sstevel@tonic-gate sizeof (psp->pr_clname)); 2817c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_fname, P->psinfo.pr_fname, 2827c478bd9Sstevel@tonic-gate sizeof (psp->pr_fname)); 2837c478bd9Sstevel@tonic-gate bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs, 2847c478bd9Sstevel@tonic-gate sizeof (psp->pr_psargs)); 2857c478bd9Sstevel@tonic-gate psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall; 2867c478bd9Sstevel@tonic-gate psp->pr_ctime = P->psinfo.pr_ctime; 2877c478bd9Sstevel@tonic-gate psp->pr_bysize = psp->pr_size * PAGESIZE; 2887c478bd9Sstevel@tonic-gate psp->pr_byrssize = psp->pr_rssize * PAGESIZE; 2897c478bd9Sstevel@tonic-gate psp->pr_argc = P->psinfo.pr_argc; 2907c478bd9Sstevel@tonic-gate psp->pr_argv = (char **)P->psinfo.pr_argv; 2917c478bd9Sstevel@tonic-gate psp->pr_envp = (char **)P->psinfo.pr_envp; 2927c478bd9Sstevel@tonic-gate psp->pr_wstat = P->psinfo.pr_wstat; 2937c478bd9Sstevel@tonic-gate psp->pr_pctcpu = P->psinfo.pr_pctcpu; 2947c478bd9Sstevel@tonic-gate psp->pr_pctmem = P->psinfo.pr_pctmem; 2957c478bd9Sstevel@tonic-gate psp->pr_euid = P->psinfo.pr_euid; 2967c478bd9Sstevel@tonic-gate psp->pr_egid = P->psinfo.pr_egid; 2977c478bd9Sstevel@tonic-gate psp->pr_aslwpid = 0; 2987c478bd9Sstevel@tonic-gate psp->pr_dmodel = P->psinfo.pr_dmodel; 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate #ifdef _LP64 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate static void 3047c478bd9Sstevel@tonic-gate mkprstatus32(struct ps_prochandle *P, const lwpstatus_t *lsp, 3057c478bd9Sstevel@tonic-gate const lwpsinfo_t *lip, prstatus32_t *psp) 3067c478bd9Sstevel@tonic-gate { 3077c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STOPPED) 3107c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0001; 3117c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISTOP) 3127c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0002; 3137c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_DSTOP) 3147c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0004; 3157c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLEEP) 3167c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0008; 3177c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_FORK) 3187c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0010; 3197c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_RLC) 3207c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0020; 3217c478bd9Sstevel@tonic-gate /* 3227c478bd9Sstevel@tonic-gate * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set; 3237c478bd9Sstevel@tonic-gate * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>. 3247c478bd9Sstevel@tonic-gate */ 3257c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PCINVAL) 3267c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0080; 3277c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISSYS) 3287c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0100; 3297c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STEP) 3307c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0200; 3317c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_KLC) 3327c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0400; 3337c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASYNC) 3347c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0800; 3357c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PTRACE) 3367c478bd9Sstevel@tonic-gate psp->pr_flags = 0x1000; 3377c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_MSACCT) 3387c478bd9Sstevel@tonic-gate psp->pr_flags = 0x2000; 3397c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_BPTADJ) 3407c478bd9Sstevel@tonic-gate psp->pr_flags = 0x4000; 3417c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLWP) 3427c478bd9Sstevel@tonic-gate psp->pr_flags = 0x8000; 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate psp->pr_why = lsp->pr_why; 3457c478bd9Sstevel@tonic-gate psp->pr_what = lsp->pr_what; 3467c478bd9Sstevel@tonic-gate siginfo_n_to_32(&lsp->pr_info, &psp->pr_info); 3477c478bd9Sstevel@tonic-gate psp->pr_cursig = lsp->pr_cursig; 3487c478bd9Sstevel@tonic-gate psp->pr_nlwp = P->status.pr_nlwp; 3497c478bd9Sstevel@tonic-gate psp->pr_sigpend = P->status.pr_sigpend; 3507c478bd9Sstevel@tonic-gate psp->pr_sighold = lsp->pr_lwphold; 3517c478bd9Sstevel@tonic-gate stack_n_to_32(&lsp->pr_altstack, &psp->pr_altstack); 3527c478bd9Sstevel@tonic-gate sigaction_n_to_32(&lsp->pr_action, &psp->pr_action); 3537c478bd9Sstevel@tonic-gate psp->pr_pid = P->status.pr_pid; 3547c478bd9Sstevel@tonic-gate psp->pr_ppid = P->status.pr_ppid; 3557c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->status.pr_pgid; 3567c478bd9Sstevel@tonic-gate psp->pr_sid = P->status.pr_sid; 3577c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_utime, &psp->pr_utime); 3587c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_stime, &psp->pr_stime); 3597c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_cutime, &psp->pr_cutime); 3607c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_cstime, &psp->pr_cstime); 3617c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname)); 3627c478bd9Sstevel@tonic-gate psp->pr_syscall = lsp->pr_syscall; 3637c478bd9Sstevel@tonic-gate psp->pr_nsysarg = lsp->pr_nsysarg; 3642c797a4eSRoger A. Faulkner bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg)); 3652c797a4eSRoger A. Faulkner psp->pr_who = lsp->pr_lwpid; 3667c478bd9Sstevel@tonic-gate psp->pr_lwppend = lsp->pr_lwppend; 3677c478bd9Sstevel@tonic-gate psp->pr_oldcontext = (caddr32_t)lsp->pr_oldcontext; 3687c478bd9Sstevel@tonic-gate psp->pr_brkbase = (caddr32_t)P->status.pr_brkbase; 3697c478bd9Sstevel@tonic-gate psp->pr_brksize = P->status.pr_brksize; 3707c478bd9Sstevel@tonic-gate psp->pr_stkbase = (caddr32_t)P->status.pr_stkbase; 3717c478bd9Sstevel@tonic-gate psp->pr_stksize = P->status.pr_stksize; 3727c478bd9Sstevel@tonic-gate psp->pr_processor = (short)lip->pr_onpro; 3737c478bd9Sstevel@tonic-gate psp->pr_bind = (short)lip->pr_bindpro; 3747c478bd9Sstevel@tonic-gate psp->pr_instr = lsp->pr_instr; 3757c478bd9Sstevel@tonic-gate bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg)); 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate static void 3797c478bd9Sstevel@tonic-gate mkprpsinfo32(struct ps_prochandle *P, prpsinfo32_t *psp) 3807c478bd9Sstevel@tonic-gate { 3817c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 3827c478bd9Sstevel@tonic-gate psp->pr_state = P->psinfo.pr_lwp.pr_state; 3837c478bd9Sstevel@tonic-gate psp->pr_sname = P->psinfo.pr_lwp.pr_sname; 3847c478bd9Sstevel@tonic-gate psp->pr_zomb = (psp->pr_state == SZOMB); 3857c478bd9Sstevel@tonic-gate psp->pr_nice = P->psinfo.pr_lwp.pr_nice; 3867c478bd9Sstevel@tonic-gate psp->pr_flag = P->psinfo.pr_lwp.pr_flag; 3877c478bd9Sstevel@tonic-gate psp->pr_uid = P->psinfo.pr_uid; 3887c478bd9Sstevel@tonic-gate psp->pr_gid = P->psinfo.pr_gid; 3897c478bd9Sstevel@tonic-gate psp->pr_pid = P->psinfo.pr_pid; 3907c478bd9Sstevel@tonic-gate psp->pr_ppid = P->psinfo.pr_ppid; 3917c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->psinfo.pr_pgid; 3927c478bd9Sstevel@tonic-gate psp->pr_sid = P->psinfo.pr_sid; 3937c478bd9Sstevel@tonic-gate psp->pr_addr = (caddr32_t)P->psinfo.pr_addr; 3947c478bd9Sstevel@tonic-gate psp->pr_size = P->psinfo.pr_size; 3957c478bd9Sstevel@tonic-gate psp->pr_rssize = P->psinfo.pr_rssize; 3967c478bd9Sstevel@tonic-gate psp->pr_wchan = (caddr32_t)P->psinfo.pr_lwp.pr_wchan; 3977c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_start, &psp->pr_start); 3987c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_time, &psp->pr_time); 3997c478bd9Sstevel@tonic-gate psp->pr_pri = P->psinfo.pr_lwp.pr_pri; 4007c478bd9Sstevel@tonic-gate psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri; 4017c478bd9Sstevel@tonic-gate psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu; 4027c478bd9Sstevel@tonic-gate psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev); 4037c478bd9Sstevel@tonic-gate psp->pr_lttydev = prcmpldev(P->psinfo.pr_ttydev); 4047c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname, 4057c478bd9Sstevel@tonic-gate sizeof (psp->pr_clname)); 4067c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_fname, P->psinfo.pr_fname, 4077c478bd9Sstevel@tonic-gate sizeof (psp->pr_fname)); 4087c478bd9Sstevel@tonic-gate bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs, 4097c478bd9Sstevel@tonic-gate sizeof (psp->pr_psargs)); 4107c478bd9Sstevel@tonic-gate psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall; 4117c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_ctime, &psp->pr_ctime); 4127c478bd9Sstevel@tonic-gate psp->pr_bysize = psp->pr_size * PAGESIZE; 4137c478bd9Sstevel@tonic-gate psp->pr_byrssize = psp->pr_rssize * PAGESIZE; 4147c478bd9Sstevel@tonic-gate psp->pr_argc = P->psinfo.pr_argc; 4157c478bd9Sstevel@tonic-gate psp->pr_argv = (caddr32_t)P->psinfo.pr_argv; 4167c478bd9Sstevel@tonic-gate psp->pr_envp = (caddr32_t)P->psinfo.pr_envp; 4177c478bd9Sstevel@tonic-gate psp->pr_wstat = P->psinfo.pr_wstat; 4187c478bd9Sstevel@tonic-gate psp->pr_pctcpu = P->psinfo.pr_pctcpu; 4197c478bd9Sstevel@tonic-gate psp->pr_pctmem = P->psinfo.pr_pctmem; 4207c478bd9Sstevel@tonic-gate psp->pr_euid = P->psinfo.pr_euid; 4217c478bd9Sstevel@tonic-gate psp->pr_egid = P->psinfo.pr_egid; 4227c478bd9Sstevel@tonic-gate psp->pr_aslwpid = 0; 4237c478bd9Sstevel@tonic-gate psp->pr_dmodel = P->psinfo.pr_dmodel; 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate static int 4297c478bd9Sstevel@tonic-gate write_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp) 4307c478bd9Sstevel@tonic-gate { 4317c478bd9Sstevel@tonic-gate /* 4327c478bd9Sstevel@tonic-gate * Note headers are the same regardless of the data model of the 4337c478bd9Sstevel@tonic-gate * ELF file; we arbitrarily use Elf64_Nhdr here. 4347c478bd9Sstevel@tonic-gate */ 4357c478bd9Sstevel@tonic-gate struct { 4367c478bd9Sstevel@tonic-gate Elf64_Nhdr nhdr; 4377c478bd9Sstevel@tonic-gate char name[8]; 4387c478bd9Sstevel@tonic-gate } n; 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate bzero(&n, sizeof (n)); 4417c478bd9Sstevel@tonic-gate bcopy("CORE", n.name, 4); 4427c478bd9Sstevel@tonic-gate n.nhdr.n_type = type; 4437c478bd9Sstevel@tonic-gate n.nhdr.n_namesz = 5; 4447c478bd9Sstevel@tonic-gate n.nhdr.n_descsz = roundup(descsz, 4); 4457c478bd9Sstevel@tonic-gate 44664e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &n, sizeof (n), *offp) != 0) 4477c478bd9Sstevel@tonic-gate return (-1); 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate *offp += sizeof (n); 4507c478bd9Sstevel@tonic-gate 45164e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != 0) 4527c478bd9Sstevel@tonic-gate return (-1); 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate *offp += n.nhdr.n_descsz; 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate return (0); 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate static int 4607c478bd9Sstevel@tonic-gate old_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip) 4617c478bd9Sstevel@tonic-gate { 4627c478bd9Sstevel@tonic-gate pgcore_t *pgc = data; 4637c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate /* 4667c478bd9Sstevel@tonic-gate * Legacy core files don't contain information about zombie LWPs. 4677c478bd9Sstevel@tonic-gate * We use Plwp_iter_all() so that we get the lwpsinfo_t structure 4687c478bd9Sstevel@tonic-gate * more cheaply. 4697c478bd9Sstevel@tonic-gate */ 4707c478bd9Sstevel@tonic-gate if (lsp == NULL) 4717c478bd9Sstevel@tonic-gate return (0); 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 4747c478bd9Sstevel@tonic-gate prstatus_t prstatus; 4757c478bd9Sstevel@tonic-gate mkprstatus(P, lsp, lip, &prstatus); 4767c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRSTATUS, &prstatus, 4777c478bd9Sstevel@tonic-gate sizeof (prstatus_t), pgc->pgc_doff) != 0) 4787c478bd9Sstevel@tonic-gate return (0); 4797c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRFPREG, &lsp->pr_fpreg, 4807c478bd9Sstevel@tonic-gate sizeof (prfpregset_t), pgc->pgc_doff) != 0) 4817c478bd9Sstevel@tonic-gate return (1); 4827c478bd9Sstevel@tonic-gate #ifdef _LP64 4837c478bd9Sstevel@tonic-gate } else { 4847c478bd9Sstevel@tonic-gate prstatus32_t pr32; 4857c478bd9Sstevel@tonic-gate prfpregset32_t pf32; 4867c478bd9Sstevel@tonic-gate mkprstatus32(P, lsp, lip, &pr32); 4877c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRSTATUS, &pr32, 4887c478bd9Sstevel@tonic-gate sizeof (prstatus32_t), pgc->pgc_doff) != 0) 4897c478bd9Sstevel@tonic-gate return (1); 4907c478bd9Sstevel@tonic-gate prfpregset_n_to_32(&lsp->pr_fpreg, &pf32); 4917c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRFPREG, &pf32, 4927c478bd9Sstevel@tonic-gate sizeof (prfpregset32_t), pgc->pgc_doff) != 0) 4937c478bd9Sstevel@tonic-gate return (1); 4947c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate #ifdef sparc 4987c478bd9Sstevel@tonic-gate { 4997c478bd9Sstevel@tonic-gate prxregset_t xregs; 5007c478bd9Sstevel@tonic-gate if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0 && 5017c478bd9Sstevel@tonic-gate write_note(pgc->pgc_fd, NT_PRXREG, &xregs, 5027c478bd9Sstevel@tonic-gate sizeof (prxregset_t), pgc->pgc_doff) != 0) 5037c478bd9Sstevel@tonic-gate return (1); 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate #endif /* sparc */ 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate return (0); 5087c478bd9Sstevel@tonic-gate } 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate static int 5117c478bd9Sstevel@tonic-gate new_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip) 5127c478bd9Sstevel@tonic-gate { 5137c478bd9Sstevel@tonic-gate pgcore_t *pgc = data; 5147c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 515ab618543SJohn Levon prlwpname_t name = { 0, "" }; 516f971a346SBryan Cantrill psinfo_t ps; 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate /* 5197c478bd9Sstevel@tonic-gate * If lsp is NULL this indicates that this is a zombie LWP in 5207c478bd9Sstevel@tonic-gate * which case we dump only the lwpsinfo_t structure and none of 5217c478bd9Sstevel@tonic-gate * the other ancillary LWP state data. 5227c478bd9Sstevel@tonic-gate */ 5237c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 5247c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip, 5257c478bd9Sstevel@tonic-gate sizeof (lwpsinfo_t), pgc->pgc_doff) != 0) 5267c478bd9Sstevel@tonic-gate return (1); 5277c478bd9Sstevel@tonic-gate if (lsp == NULL) 5287c478bd9Sstevel@tonic-gate return (0); 5297c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp, 5307c478bd9Sstevel@tonic-gate sizeof (lwpstatus_t), pgc->pgc_doff) != 0) 5317c478bd9Sstevel@tonic-gate return (1); 5327c478bd9Sstevel@tonic-gate #ifdef _LP64 5337c478bd9Sstevel@tonic-gate } else { 5347c478bd9Sstevel@tonic-gate lwpsinfo32_t li32; 5357c478bd9Sstevel@tonic-gate lwpstatus32_t ls32; 5367c478bd9Sstevel@tonic-gate lwpsinfo_n_to_32(lip, &li32); 5377c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32, 5387c478bd9Sstevel@tonic-gate sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0) 5397c478bd9Sstevel@tonic-gate return (1); 5407c478bd9Sstevel@tonic-gate if (lsp == NULL) 5417c478bd9Sstevel@tonic-gate return (0); 5427c478bd9Sstevel@tonic-gate lwpstatus_n_to_32(lsp, &ls32); 5437c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32, 5447c478bd9Sstevel@tonic-gate sizeof (lwpstatus32_t), pgc->pgc_doff) != 0) 5457c478bd9Sstevel@tonic-gate return (1); 5467c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 5477c478bd9Sstevel@tonic-gate } 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gate #ifdef sparc 5507c478bd9Sstevel@tonic-gate { 5517c478bd9Sstevel@tonic-gate prxregset_t xregs; 5527c478bd9Sstevel@tonic-gate gwindows_t gwins; 5537c478bd9Sstevel@tonic-gate size_t size; 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0) { 5567c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRXREG, &xregs, 5577c478bd9Sstevel@tonic-gate sizeof (prxregset_t), pgc->pgc_doff) != 0) 5587c478bd9Sstevel@tonic-gate return (1); 5597c478bd9Sstevel@tonic-gate } 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate if (Plwp_getgwindows(P, lsp->pr_lwpid, &gwins) == 0 && 5627c478bd9Sstevel@tonic-gate gwins.wbcnt > 0) { 5637c478bd9Sstevel@tonic-gate size = sizeof (gwins) - sizeof (gwins.wbuf) + 5647c478bd9Sstevel@tonic-gate gwins.wbcnt * sizeof (gwins.wbuf[0]); 5657c478bd9Sstevel@tonic-gate 5667c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_GWINDOWS, &gwins, size, 5677c478bd9Sstevel@tonic-gate pgc->pgc_doff) != 0) 5687c478bd9Sstevel@tonic-gate return (1); 5697c478bd9Sstevel@tonic-gate } 5707c478bd9Sstevel@tonic-gate 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate #ifdef __sparcv9 5737c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_LP64) { 5747c478bd9Sstevel@tonic-gate asrset_t asrs; 5757c478bd9Sstevel@tonic-gate if (Plwp_getasrs(P, lsp->pr_lwpid, asrs) == 0) { 5767c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_ASRS, &asrs, 5777c478bd9Sstevel@tonic-gate sizeof (asrset_t), pgc->pgc_doff) != 0) 5787c478bd9Sstevel@tonic-gate return (1); 5797c478bd9Sstevel@tonic-gate } 5807c478bd9Sstevel@tonic-gate } 5817c478bd9Sstevel@tonic-gate #endif /* __sparcv9 */ 5827c478bd9Sstevel@tonic-gate #endif /* sparc */ 5837c478bd9Sstevel@tonic-gate 584ab618543SJohn Levon if (Plwp_getname(P, lsp->pr_lwpid, name.pr_lwpname, 585ab618543SJohn Levon sizeof (name.pr_lwpname)) == 0) { 586ab618543SJohn Levon name.pr_lwpid = lsp->pr_lwpid; 587ab618543SJohn Levon if (write_note(pgc->pgc_fd, NT_LWPNAME, &name, 588ab618543SJohn Levon sizeof (name), pgc->pgc_doff) != 0) 589ab618543SJohn Levon return (1); 590ab618543SJohn Levon } 591ab618543SJohn Levon 592f971a346SBryan Cantrill if (!(lsp->pr_flags & PR_AGENT)) 593f971a346SBryan Cantrill return (0); 594f971a346SBryan Cantrill 595f971a346SBryan Cantrill if (Plwp_getspymaster(P, lsp->pr_lwpid, &ps) != 0) 596f971a346SBryan Cantrill return (0); 597f971a346SBryan Cantrill 598f971a346SBryan Cantrill if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 599f971a346SBryan Cantrill if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps, 600f971a346SBryan Cantrill sizeof (psinfo_t), pgc->pgc_doff) != 0) 601f971a346SBryan Cantrill return (1); 602f971a346SBryan Cantrill #ifdef _LP64 603f971a346SBryan Cantrill } else { 604f971a346SBryan Cantrill psinfo32_t ps32; 605f971a346SBryan Cantrill psinfo_n_to_32(&ps, &ps32); 606f971a346SBryan Cantrill if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps32, 607f971a346SBryan Cantrill sizeof (psinfo32_t), pgc->pgc_doff) != 0) 608f971a346SBryan Cantrill return (1); 609f971a346SBryan Cantrill #endif /* _LP64 */ 610f971a346SBryan Cantrill } 611f971a346SBryan Cantrill 612f971a346SBryan Cantrill 6137c478bd9Sstevel@tonic-gate return (0); 6147c478bd9Sstevel@tonic-gate } 6157c478bd9Sstevel@tonic-gate 61634bdffbfSGarrett D'Amore static int 617a02120c4SAndy Fiddaman iter_fd(void *data, const prfdinfo_t *fdinfo) 61834bdffbfSGarrett D'Amore { 61934bdffbfSGarrett D'Amore fditer_t *iter = data; 620a02120c4SAndy Fiddaman prfdinfo_core_t core; 621a02120c4SAndy Fiddaman int ret = 0; 62234bdffbfSGarrett D'Amore 623a02120c4SAndy Fiddaman if (proc_fdinfo_to_core(fdinfo, &core) != 0) 624a02120c4SAndy Fiddaman return (1); 625a02120c4SAndy Fiddaman 626a02120c4SAndy Fiddaman ret = write_note(iter->fd_fd, NT_FDINFO, &core, 627a02120c4SAndy Fiddaman sizeof (core), iter->fd_doff); 628a02120c4SAndy Fiddaman 629a02120c4SAndy Fiddaman if (ret != 0) 63034bdffbfSGarrett D'Amore return (1); 63134bdffbfSGarrett D'Amore return (0); 63234bdffbfSGarrett D'Amore } 63334bdffbfSGarrett D'Amore 6347c478bd9Sstevel@tonic-gate static uint_t 6357c478bd9Sstevel@tonic-gate count_sections(pgcore_t *pgc) 6367c478bd9Sstevel@tonic-gate { 6377c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 6387c478bd9Sstevel@tonic-gate file_info_t *fptr; 6397c478bd9Sstevel@tonic-gate uint_t cnt; 6407c478bd9Sstevel@tonic-gate uint_t nshdrs = 0; 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB))) 6437c478bd9Sstevel@tonic-gate return (0); 6447c478bd9Sstevel@tonic-gate 6457c478bd9Sstevel@tonic-gate fptr = list_next(&P->file_head); 6467c478bd9Sstevel@tonic-gate for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) { 6477c478bd9Sstevel@tonic-gate int hit_symtab = 0; 6487c478bd9Sstevel@tonic-gate 6497c478bd9Sstevel@tonic-gate Pbuild_file_symtab(P, fptr); 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_CTF) && 6527c478bd9Sstevel@tonic-gate Pbuild_file_ctf(P, fptr) != NULL) { 6537c478bd9Sstevel@tonic-gate sym_tbl_t *sym; 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate nshdrs++; 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate if (fptr->file_ctf_dyn) { 6587c478bd9Sstevel@tonic-gate sym = &fptr->file_dynsym; 6597c478bd9Sstevel@tonic-gate } else { 6607c478bd9Sstevel@tonic-gate sym = &fptr->file_symtab; 6617c478bd9Sstevel@tonic-gate hit_symtab = 1; 6627c478bd9Sstevel@tonic-gate } 6637c478bd9Sstevel@tonic-gate 664d51e9074Sab196087 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 && 6657c478bd9Sstevel@tonic-gate sym->sym_strs != NULL) 6667c478bd9Sstevel@tonic-gate nshdrs += 2; 6677c478bd9Sstevel@tonic-gate } 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab && 670d51e9074Sab196087 fptr->file_symtab.sym_data_pri != NULL && 6717c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_symn != 0 && 6727c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_strs != NULL) { 6737c478bd9Sstevel@tonic-gate nshdrs += 2; 6747c478bd9Sstevel@tonic-gate } 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate 6777c478bd9Sstevel@tonic-gate return (nshdrs == 0 ? 0 : nshdrs + 2); 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate static int 6817c478bd9Sstevel@tonic-gate write_shdr(pgcore_t *pgc, shstrtype_t name, uint_t type, ulong_t flags, 6827c478bd9Sstevel@tonic-gate uintptr_t addr, ulong_t offset, size_t size, uint_t link, uint_t info, 6837c478bd9Sstevel@tonic-gate uintptr_t addralign, uintptr_t entsize) 6847c478bd9Sstevel@tonic-gate { 6857c478bd9Sstevel@tonic-gate if (pgc->P->status.pr_dmodel == PR_MODEL_ILP32) { 6867c478bd9Sstevel@tonic-gate Elf32_Shdr shdr; 6877c478bd9Sstevel@tonic-gate 6887c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 6897c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name); 6907c478bd9Sstevel@tonic-gate shdr.sh_type = type; 6917c478bd9Sstevel@tonic-gate shdr.sh_flags = flags; 6927c478bd9Sstevel@tonic-gate shdr.sh_addr = (Elf32_Addr)addr; 6937c478bd9Sstevel@tonic-gate shdr.sh_offset = offset; 6947c478bd9Sstevel@tonic-gate shdr.sh_size = size; 6957c478bd9Sstevel@tonic-gate shdr.sh_link = link; 6967c478bd9Sstevel@tonic-gate shdr.sh_info = info; 6977c478bd9Sstevel@tonic-gate shdr.sh_addralign = addralign; 6987c478bd9Sstevel@tonic-gate shdr.sh_entsize = entsize; 6997c478bd9Sstevel@tonic-gate 70064e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 70164e4e50aSKeith M Wesolowski *pgc->pgc_soff) != 0) 7027c478bd9Sstevel@tonic-gate return (-1); 7037c478bd9Sstevel@tonic-gate 7047c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 7057c478bd9Sstevel@tonic-gate #ifdef _LP64 7067c478bd9Sstevel@tonic-gate } else { 7077c478bd9Sstevel@tonic-gate Elf64_Shdr shdr; 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 7107c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name); 7117c478bd9Sstevel@tonic-gate shdr.sh_type = type; 7127c478bd9Sstevel@tonic-gate shdr.sh_flags = flags; 7137c478bd9Sstevel@tonic-gate shdr.sh_addr = addr; 7147c478bd9Sstevel@tonic-gate shdr.sh_offset = offset; 7157c478bd9Sstevel@tonic-gate shdr.sh_size = size; 7167c478bd9Sstevel@tonic-gate shdr.sh_link = link; 7177c478bd9Sstevel@tonic-gate shdr.sh_info = info; 7187c478bd9Sstevel@tonic-gate shdr.sh_addralign = addralign; 7197c478bd9Sstevel@tonic-gate shdr.sh_entsize = entsize; 7207c478bd9Sstevel@tonic-gate 72164e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 72264e4e50aSKeith M Wesolowski *pgc->pgc_soff) != 0) 7237c478bd9Sstevel@tonic-gate return (-1); 7247c478bd9Sstevel@tonic-gate 7257c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 7267c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate return (0); 7307c478bd9Sstevel@tonic-gate } 7317c478bd9Sstevel@tonic-gate 7327c478bd9Sstevel@tonic-gate static int 7337c478bd9Sstevel@tonic-gate dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym) 7347c478bd9Sstevel@tonic-gate { 7357c478bd9Sstevel@tonic-gate sym_tbl_t *sym = dynsym ? &fptr->file_dynsym : &fptr->file_symtab; 7367c478bd9Sstevel@tonic-gate shstrtype_t symname = dynsym ? STR_DYNSYM : STR_SYMTAB; 7377c478bd9Sstevel@tonic-gate shstrtype_t strname = dynsym ? STR_DYNSTR : STR_STRTAB; 7387c478bd9Sstevel@tonic-gate uint_t symtype = dynsym ? SHT_DYNSYM : SHT_SYMTAB; 7397c478bd9Sstevel@tonic-gate size_t size; 7407c478bd9Sstevel@tonic-gate uintptr_t addr = fptr->file_map->map_pmap.pr_vaddr; 7417c478bd9Sstevel@tonic-gate 742d51e9074Sab196087 if (sym->sym_data_pri == NULL || sym->sym_symn == 0 || 7437c478bd9Sstevel@tonic-gate sym->sym_strs == NULL) 7447c478bd9Sstevel@tonic-gate return (0); 7457c478bd9Sstevel@tonic-gate 746d51e9074Sab196087 size = sym->sym_hdr_pri.sh_size; 74764e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, sym->sym_data_pri->d_buf, size, 74864e4e50aSKeith M Wesolowski *pgc->pgc_doff) != 0) 7497c478bd9Sstevel@tonic-gate return (-1); 7507c478bd9Sstevel@tonic-gate 7517c478bd9Sstevel@tonic-gate if (write_shdr(pgc, symname, symtype, 0, addr, *pgc->pgc_doff, size, 752d51e9074Sab196087 index + 1, sym->sym_hdr_pri.sh_info, sym->sym_hdr_pri.sh_addralign, 753d51e9074Sab196087 sym->sym_hdr_pri.sh_entsize) != 0) 7547c478bd9Sstevel@tonic-gate return (-1); 7557c478bd9Sstevel@tonic-gate 7567c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8); 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate size = sym->sym_strhdr.sh_size; 75964e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != 0) 7607c478bd9Sstevel@tonic-gate return (-1); 7617c478bd9Sstevel@tonic-gate 7627c478bd9Sstevel@tonic-gate if (write_shdr(pgc, strname, SHT_STRTAB, SHF_STRINGS, addr, 7637c478bd9Sstevel@tonic-gate *pgc->pgc_doff, size, 0, 0, 1, 0) != 0) 7647c478bd9Sstevel@tonic-gate return (-1); 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8); 7677c478bd9Sstevel@tonic-gate 7687c478bd9Sstevel@tonic-gate return (0); 7697c478bd9Sstevel@tonic-gate } 7707c478bd9Sstevel@tonic-gate 7717c478bd9Sstevel@tonic-gate static int 7727c478bd9Sstevel@tonic-gate dump_sections(pgcore_t *pgc) 7737c478bd9Sstevel@tonic-gate { 7747c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 7757c478bd9Sstevel@tonic-gate file_info_t *fptr; 7767c478bd9Sstevel@tonic-gate uint_t cnt; 7777c478bd9Sstevel@tonic-gate uint_t index = 1; 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB))) 7807c478bd9Sstevel@tonic-gate return (0); 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate fptr = list_next(&P->file_head); 7837c478bd9Sstevel@tonic-gate for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) { 7847c478bd9Sstevel@tonic-gate int hit_symtab = 0; 7857c478bd9Sstevel@tonic-gate 7867c478bd9Sstevel@tonic-gate Pbuild_file_symtab(P, fptr); 7877c478bd9Sstevel@tonic-gate 7887c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_CTF) && 7897c478bd9Sstevel@tonic-gate Pbuild_file_ctf(P, fptr) != NULL) { 7907c478bd9Sstevel@tonic-gate sym_tbl_t *sym; 7917c478bd9Sstevel@tonic-gate uint_t dynsym; 7927c478bd9Sstevel@tonic-gate uint_t symindex = 0; 7937c478bd9Sstevel@tonic-gate 7947c478bd9Sstevel@tonic-gate /* 7957c478bd9Sstevel@tonic-gate * Write the symtab out first so we can correctly 7967c478bd9Sstevel@tonic-gate * set the sh_link field in the CTF section header. 7977c478bd9Sstevel@tonic-gate * symindex will be 0 if there is no corresponding 7987c478bd9Sstevel@tonic-gate * symbol table section. 7997c478bd9Sstevel@tonic-gate */ 8007c478bd9Sstevel@tonic-gate if (fptr->file_ctf_dyn) { 8017c478bd9Sstevel@tonic-gate sym = &fptr->file_dynsym; 8027c478bd9Sstevel@tonic-gate dynsym = 1; 8037c478bd9Sstevel@tonic-gate } else { 8047c478bd9Sstevel@tonic-gate sym = &fptr->file_symtab; 8057c478bd9Sstevel@tonic-gate dynsym = 0; 8067c478bd9Sstevel@tonic-gate hit_symtab = 1; 8077c478bd9Sstevel@tonic-gate } 8087c478bd9Sstevel@tonic-gate 809d51e9074Sab196087 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 && 8107c478bd9Sstevel@tonic-gate sym->sym_strs != NULL) { 8117c478bd9Sstevel@tonic-gate symindex = index; 8127c478bd9Sstevel@tonic-gate if (dump_symtab(pgc, fptr, index, dynsym) != 0) 8137c478bd9Sstevel@tonic-gate return (-1); 8147c478bd9Sstevel@tonic-gate index += 2; 8157c478bd9Sstevel@tonic-gate } 8167c478bd9Sstevel@tonic-gate 8177c478bd9Sstevel@tonic-gate /* 8187c478bd9Sstevel@tonic-gate * Write the CTF data that we've read out of the 8197c478bd9Sstevel@tonic-gate * file itself into the core file. 8207c478bd9Sstevel@tonic-gate */ 82164e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, fptr->file_ctf_buf, 82264e4e50aSKeith M Wesolowski fptr->file_ctf_size, *pgc->pgc_doff) != 0) 8237c478bd9Sstevel@tonic-gate return (-1); 8247c478bd9Sstevel@tonic-gate 8257c478bd9Sstevel@tonic-gate if (write_shdr(pgc, STR_CTF, SHT_PROGBITS, 0, 8267c478bd9Sstevel@tonic-gate fptr->file_map->map_pmap.pr_vaddr, *pgc->pgc_doff, 8277c478bd9Sstevel@tonic-gate fptr->file_ctf_size, symindex, 0, 4, 0) != 0) 8287c478bd9Sstevel@tonic-gate return (-1); 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate index++; 8317c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(fptr->file_ctf_size, 8); 8327c478bd9Sstevel@tonic-gate } 8337c478bd9Sstevel@tonic-gate 8347c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab && 835d51e9074Sab196087 fptr->file_symtab.sym_data_pri != NULL && 8367c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_symn != 0 && 8377c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_strs != NULL) { 8387c478bd9Sstevel@tonic-gate if (dump_symtab(pgc, fptr, index, 0) != 0) 8397c478bd9Sstevel@tonic-gate return (-1); 8407c478bd9Sstevel@tonic-gate index += 2; 8417c478bd9Sstevel@tonic-gate } 8427c478bd9Sstevel@tonic-gate } 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate return (0); 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8487c478bd9Sstevel@tonic-gate static int 8497c478bd9Sstevel@tonic-gate dump_map(void *data, const prmap_t *pmp, const char *name) 8507c478bd9Sstevel@tonic-gate { 8517c478bd9Sstevel@tonic-gate pgcore_t *pgc = data; 8527c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 8537c478bd9Sstevel@tonic-gate #ifdef _LP64 8547c478bd9Sstevel@tonic-gate Elf64_Phdr phdr; 8557c478bd9Sstevel@tonic-gate #else 8567c478bd9Sstevel@tonic-gate Elf32_Phdr phdr; 8577c478bd9Sstevel@tonic-gate #endif 8587c478bd9Sstevel@tonic-gate size_t n; 8597c478bd9Sstevel@tonic-gate 8607c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 8617c478bd9Sstevel@tonic-gate phdr.p_type = PT_LOAD; 8627c478bd9Sstevel@tonic-gate phdr.p_vaddr = pmp->pr_vaddr; 8637c478bd9Sstevel@tonic-gate phdr.p_memsz = pmp->pr_size; 8647c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_READ) 8657c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_R; 8667c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_WRITE) 8677c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_W; 8687c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_EXEC) 8697c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_X; 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate if (pmp->pr_vaddr + pmp->pr_size > P->status.pr_stkbase && 8727c478bd9Sstevel@tonic-gate pmp->pr_vaddr < P->status.pr_stkbase + P->status.pr_stksize) { 8737c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_STACK)) 8747c478bd9Sstevel@tonic-gate goto exclude; 8757c478bd9Sstevel@tonic-gate 8767c478bd9Sstevel@tonic-gate } else if ((pmp->pr_mflags & MA_ANON) && 8777c478bd9Sstevel@tonic-gate pmp->pr_vaddr + pmp->pr_size > P->status.pr_brkbase && 8787c478bd9Sstevel@tonic-gate pmp->pr_vaddr < P->status.pr_brkbase + P->status.pr_brksize) { 8797c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_HEAP)) 8807c478bd9Sstevel@tonic-gate goto exclude; 8817c478bd9Sstevel@tonic-gate 8827c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_ISM) { 8837c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_NORESERVE) { 8847c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_DISM)) 8857c478bd9Sstevel@tonic-gate goto exclude; 8867c478bd9Sstevel@tonic-gate } else { 8877c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_ISM)) 8887c478bd9Sstevel@tonic-gate goto exclude; 8897c478bd9Sstevel@tonic-gate } 8907c478bd9Sstevel@tonic-gate 8917c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_SHM) { 8927c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHM)) 8937c478bd9Sstevel@tonic-gate goto exclude; 8947c478bd9Sstevel@tonic-gate 8957c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_SHARED) { 8967c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_ANON) { 8977c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHANON)) 8987c478bd9Sstevel@tonic-gate goto exclude; 8997c478bd9Sstevel@tonic-gate } else { 9007c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHFILE)) 9017c478bd9Sstevel@tonic-gate goto exclude; 9027c478bd9Sstevel@tonic-gate } 9037c478bd9Sstevel@tonic-gate 9047c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_ANON) { 9057c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_ANON)) 9067c478bd9Sstevel@tonic-gate goto exclude; 9077c478bd9Sstevel@tonic-gate 9087c478bd9Sstevel@tonic-gate } else if (phdr.p_flags == (PF_R | PF_X)) { 9097c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_TEXT)) 9107c478bd9Sstevel@tonic-gate goto exclude; 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate } else if (phdr.p_flags == PF_R) { 9137c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_RODATA)) 9147c478bd9Sstevel@tonic-gate goto exclude; 9157c478bd9Sstevel@tonic-gate 9167c478bd9Sstevel@tonic-gate } else { 9177c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_DATA)) 9187c478bd9Sstevel@tonic-gate goto exclude; 9197c478bd9Sstevel@tonic-gate } 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate n = 0; 9227c478bd9Sstevel@tonic-gate while (n < pmp->pr_size) { 9237c478bd9Sstevel@tonic-gate size_t csz = MIN(pmp->pr_size - n, pgc->pgc_chunksz); 924*5d228828SRobert Mustacchi ssize_t ret; 925*5d228828SRobert Mustacchi 926*5d228828SRobert Mustacchi /* 927*5d228828SRobert Mustacchi * If we happen to have a PROT_NONE mapping, don't try to read 928*5d228828SRobert Mustacchi * from the address space. 929*5d228828SRobert Mustacchi */ 930*5d228828SRobert Mustacchi if ((pmp->pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) == 0) { 931*5d228828SRobert Mustacchi bzero(pgc->pgc_chunk, csz); 932*5d228828SRobert Mustacchi ret = csz; 933*5d228828SRobert Mustacchi } else { 934*5d228828SRobert Mustacchi ret = Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n); 935*5d228828SRobert Mustacchi } 9367c478bd9Sstevel@tonic-gate 9377c478bd9Sstevel@tonic-gate /* 9387c478bd9Sstevel@tonic-gate * If we can't read out part of the victim's address 9397c478bd9Sstevel@tonic-gate * space for some reason ignore that failure and try to 9407c478bd9Sstevel@tonic-gate * emit a partial core file without that mapping's data. 9417c478bd9Sstevel@tonic-gate * As in the kernel, we mark these failures with the 9427c478bd9Sstevel@tonic-gate * PF_SUNW_FAILURE flag and store the errno where the 9437c478bd9Sstevel@tonic-gate * mapping would have been. 9447c478bd9Sstevel@tonic-gate */ 945*5d228828SRobert Mustacchi if (ret != csz || gc_pwrite64(pgc->pgc_fd, pgc->pgc_chunk, csz, 94664e4e50aSKeith M Wesolowski *pgc->pgc_doff + n) != 0) { 9477c478bd9Sstevel@tonic-gate int err = errno; 94864e4e50aSKeith M Wesolowski (void) gc_pwrite64(pgc->pgc_fd, &err, sizeof (err), 9497c478bd9Sstevel@tonic-gate *pgc->pgc_doff); 9507c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(sizeof (err), 8); 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_SUNW_FAILURE; 9537c478bd9Sstevel@tonic-gate (void) ftruncate64(pgc->pgc_fd, *pgc->pgc_doff); 9547c478bd9Sstevel@tonic-gate goto exclude; 9557c478bd9Sstevel@tonic-gate } 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate n += csz; 9587c478bd9Sstevel@tonic-gate } 9597c478bd9Sstevel@tonic-gate 9607c478bd9Sstevel@tonic-gate phdr.p_offset = *pgc->pgc_doff; 9617c478bd9Sstevel@tonic-gate phdr.p_filesz = pmp->pr_size; 9627c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(phdr.p_filesz, 8); 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate exclude: 9657c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 96664e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &phdr, sizeof (phdr), 96764e4e50aSKeith M Wesolowski *pgc->pgc_poff) != 0) 9687c478bd9Sstevel@tonic-gate return (1); 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate *pgc->pgc_poff += sizeof (phdr); 9717c478bd9Sstevel@tonic-gate #ifdef _LP64 9727c478bd9Sstevel@tonic-gate } else { 9737c478bd9Sstevel@tonic-gate Elf32_Phdr phdr32; 9747c478bd9Sstevel@tonic-gate 9757c478bd9Sstevel@tonic-gate bzero(&phdr32, sizeof (phdr32)); 9767c478bd9Sstevel@tonic-gate phdr32.p_type = phdr.p_type; 9777c478bd9Sstevel@tonic-gate phdr32.p_vaddr = (Elf32_Addr)phdr.p_vaddr; 9787c478bd9Sstevel@tonic-gate phdr32.p_memsz = (Elf32_Word)phdr.p_memsz; 9797c478bd9Sstevel@tonic-gate phdr32.p_flags = phdr.p_flags; 9807c478bd9Sstevel@tonic-gate phdr32.p_offset = (Elf32_Off)phdr.p_offset; 9817c478bd9Sstevel@tonic-gate phdr32.p_filesz = (Elf32_Word)phdr.p_filesz; 9827c478bd9Sstevel@tonic-gate 98364e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &phdr32, sizeof (phdr32), 98464e4e50aSKeith M Wesolowski *pgc->pgc_poff) != 0) 9857c478bd9Sstevel@tonic-gate return (1); 9867c478bd9Sstevel@tonic-gate 9877c478bd9Sstevel@tonic-gate *pgc->pgc_poff += sizeof (phdr32); 9887c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 9897c478bd9Sstevel@tonic-gate } 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate return (0); 9927c478bd9Sstevel@tonic-gate } 9937c478bd9Sstevel@tonic-gate 9947c478bd9Sstevel@tonic-gate int 9957c478bd9Sstevel@tonic-gate write_shstrtab(struct ps_prochandle *P, pgcore_t *pgc) 9967c478bd9Sstevel@tonic-gate { 9977c478bd9Sstevel@tonic-gate off64_t off = *pgc->pgc_doff; 9987c478bd9Sstevel@tonic-gate size_t size = 0; 9997c478bd9Sstevel@tonic-gate shstrtab_t *s = &pgc->pgc_shstrtab; 10007c478bd9Sstevel@tonic-gate int i, ndx; 10017c478bd9Sstevel@tonic-gate 10027c478bd9Sstevel@tonic-gate if (shstrtab_size(s) == 1) 10037c478bd9Sstevel@tonic-gate return (0); 10047c478bd9Sstevel@tonic-gate 10057c478bd9Sstevel@tonic-gate /* 10067c478bd9Sstevel@tonic-gate * Preemptively stick the name of the shstrtab in the string table. 10077c478bd9Sstevel@tonic-gate */ 10087c478bd9Sstevel@tonic-gate (void) shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB); 10097c478bd9Sstevel@tonic-gate size = shstrtab_size(s); 10107c478bd9Sstevel@tonic-gate 10117c478bd9Sstevel@tonic-gate /* 10127c478bd9Sstevel@tonic-gate * Dump all the strings that we used being sure we include the 10137c478bd9Sstevel@tonic-gate * terminating null character. 10147c478bd9Sstevel@tonic-gate */ 10157c478bd9Sstevel@tonic-gate for (i = 0; i < STR_NUM; i++) { 101630da1432Sahl if ((ndx = s->sst_ndx[i]) != 0 || i == STR_NONE) { 10177c478bd9Sstevel@tonic-gate const char *str = shstrtab_data[i]; 10187c478bd9Sstevel@tonic-gate size_t len = strlen(str) + 1; 101964e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, str, len, off + ndx) != 0) 10207c478bd9Sstevel@tonic-gate return (1); 10217c478bd9Sstevel@tonic-gate } 10227c478bd9Sstevel@tonic-gate } 10237c478bd9Sstevel@tonic-gate 10247c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 10257c478bd9Sstevel@tonic-gate Elf32_Shdr shdr; 10267c478bd9Sstevel@tonic-gate 10277c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 10287c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB); 10297c478bd9Sstevel@tonic-gate shdr.sh_size = size; 10307c478bd9Sstevel@tonic-gate shdr.sh_offset = *pgc->pgc_doff; 10317c478bd9Sstevel@tonic-gate shdr.sh_addralign = 1; 10327c478bd9Sstevel@tonic-gate shdr.sh_flags = SHF_STRINGS; 10337c478bd9Sstevel@tonic-gate shdr.sh_type = SHT_STRTAB; 10347c478bd9Sstevel@tonic-gate 103564e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 103664e4e50aSKeith M Wesolowski *pgc->pgc_soff) != 0) 10377c478bd9Sstevel@tonic-gate return (1); 10387c478bd9Sstevel@tonic-gate 10397c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 10407c478bd9Sstevel@tonic-gate #ifdef _LP64 10417c478bd9Sstevel@tonic-gate } else { 10427c478bd9Sstevel@tonic-gate Elf64_Shdr shdr; 10437c478bd9Sstevel@tonic-gate 10447c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 10457c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB); 10467c478bd9Sstevel@tonic-gate shdr.sh_size = size; 10477c478bd9Sstevel@tonic-gate shdr.sh_offset = *pgc->pgc_doff; 10487c478bd9Sstevel@tonic-gate shdr.sh_addralign = 1; 10497c478bd9Sstevel@tonic-gate shdr.sh_flags = SHF_STRINGS; 10507c478bd9Sstevel@tonic-gate shdr.sh_type = SHT_STRTAB; 10517c478bd9Sstevel@tonic-gate 105264e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 105364e4e50aSKeith M Wesolowski *pgc->pgc_soff) != 0) 10547c478bd9Sstevel@tonic-gate return (1); 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 10577c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 10587c478bd9Sstevel@tonic-gate } 10597c478bd9Sstevel@tonic-gate 10607c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8); 10617c478bd9Sstevel@tonic-gate 10627c478bd9Sstevel@tonic-gate return (0); 10637c478bd9Sstevel@tonic-gate } 10647c478bd9Sstevel@tonic-gate 10657c478bd9Sstevel@tonic-gate /* 10667c478bd9Sstevel@tonic-gate * Don't explicity stop the process; that's up to the consumer. 10677c478bd9Sstevel@tonic-gate */ 10687c478bd9Sstevel@tonic-gate int 10697c478bd9Sstevel@tonic-gate Pfgcore(struct ps_prochandle *P, int fd, core_content_t content) 10707c478bd9Sstevel@tonic-gate { 10717c478bd9Sstevel@tonic-gate char plat[SYS_NMLN]; 10727c478bd9Sstevel@tonic-gate char zonename[ZONENAME_MAX]; 10737c478bd9Sstevel@tonic-gate int platlen = -1; 10747c478bd9Sstevel@tonic-gate pgcore_t pgc; 10757c478bd9Sstevel@tonic-gate off64_t poff, soff, doff, boff; 10767c478bd9Sstevel@tonic-gate struct utsname uts; 10777c478bd9Sstevel@tonic-gate uint_t nphdrs, nshdrs; 10787c478bd9Sstevel@tonic-gate 10797c478bd9Sstevel@tonic-gate if (ftruncate64(fd, 0) != 0) 10807c478bd9Sstevel@tonic-gate return (-1); 10817c478bd9Sstevel@tonic-gate 10827c478bd9Sstevel@tonic-gate if (content == CC_CONTENT_INVALID) { 10837c478bd9Sstevel@tonic-gate errno = EINVAL; 10847c478bd9Sstevel@tonic-gate return (-1); 10857c478bd9Sstevel@tonic-gate } 10867c478bd9Sstevel@tonic-gate 10877c478bd9Sstevel@tonic-gate /* 10887c478bd9Sstevel@tonic-gate * Cache the mappings and other useful data. 10897c478bd9Sstevel@tonic-gate */ 10907c478bd9Sstevel@tonic-gate (void) Prd_agent(P); 10917c478bd9Sstevel@tonic-gate (void) Ppsinfo(P); 10927c478bd9Sstevel@tonic-gate 10937c478bd9Sstevel@tonic-gate pgc.P = P; 10947c478bd9Sstevel@tonic-gate pgc.pgc_fd = fd; 10957c478bd9Sstevel@tonic-gate pgc.pgc_poff = &poff; 10967c478bd9Sstevel@tonic-gate pgc.pgc_soff = &soff; 10977c478bd9Sstevel@tonic-gate pgc.pgc_doff = &doff; 10987c478bd9Sstevel@tonic-gate pgc.pgc_content = content; 10997c478bd9Sstevel@tonic-gate pgc.pgc_chunksz = PAGESIZE; 11007c478bd9Sstevel@tonic-gate if ((pgc.pgc_chunk = malloc(pgc.pgc_chunksz)) == NULL) 11017c478bd9Sstevel@tonic-gate return (-1); 11027c478bd9Sstevel@tonic-gate 11037c478bd9Sstevel@tonic-gate shstrtab_init(&pgc.pgc_shstrtab); 11047c478bd9Sstevel@tonic-gate 11057c478bd9Sstevel@tonic-gate /* 11067c478bd9Sstevel@tonic-gate * There are two PT_NOTE program headers for ancillary data, and 11077c478bd9Sstevel@tonic-gate * one for each mapping. 11087c478bd9Sstevel@tonic-gate */ 11097c478bd9Sstevel@tonic-gate nphdrs = 2 + P->map_count; 11107c478bd9Sstevel@tonic-gate nshdrs = count_sections(&pgc); 11117c478bd9Sstevel@tonic-gate 11127c478bd9Sstevel@tonic-gate (void) Pplatform(P, plat, sizeof (plat)); 11137c478bd9Sstevel@tonic-gate platlen = strlen(plat) + 1; 11147c478bd9Sstevel@tonic-gate Preadauxvec(P); 11157c478bd9Sstevel@tonic-gate (void) Puname(P, &uts); 11167c478bd9Sstevel@tonic-gate if (Pzonename(P, zonename, sizeof (zonename)) == NULL) 11177c478bd9Sstevel@tonic-gate zonename[0] = '\0'; 11187c478bd9Sstevel@tonic-gate 11197c478bd9Sstevel@tonic-gate /* 112030da1432Sahl * The core file contents may required zero section headers, but if we 112130da1432Sahl * overflow the 16 bits allotted to the program header count in the ELF 112230da1432Sahl * header, we'll need that program header at index zero. 112330da1432Sahl */ 112430da1432Sahl if (nshdrs == 0 && nphdrs >= PN_XNUM) 112530da1432Sahl nshdrs = 1; 112630da1432Sahl 112730da1432Sahl /* 11287c478bd9Sstevel@tonic-gate * Set up the ELF header. 11297c478bd9Sstevel@tonic-gate */ 11307c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 11317c478bd9Sstevel@tonic-gate Elf32_Ehdr ehdr; 11327c478bd9Sstevel@tonic-gate 11337c478bd9Sstevel@tonic-gate bzero(&ehdr, sizeof (ehdr)); 11347c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG0] = ELFMAG0; 11357c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG1] = ELFMAG1; 11367c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG2] = ELFMAG2; 11377c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG3] = ELFMAG3; 11387c478bd9Sstevel@tonic-gate ehdr.e_type = ET_CORE; 11397c478bd9Sstevel@tonic-gate 11407c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_CLASS] = ELFCLASS32; 11417c478bd9Sstevel@tonic-gate #if defined(__sparc) 11427c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_SPARC; 11437c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2MSB; 11447c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64) 11457c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_386; 11467c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 11477c478bd9Sstevel@tonic-gate #else 11487c478bd9Sstevel@tonic-gate #error "unknown machine type" 11497c478bd9Sstevel@tonic-gate #endif 11507c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_VERSION] = EV_CURRENT; 11517c478bd9Sstevel@tonic-gate 11527c478bd9Sstevel@tonic-gate ehdr.e_version = EV_CURRENT; 11537c478bd9Sstevel@tonic-gate ehdr.e_ehsize = sizeof (ehdr); 115430da1432Sahl 115530da1432Sahl if (nphdrs >= PN_XNUM) 115630da1432Sahl ehdr.e_phnum = PN_XNUM; 115730da1432Sahl else 11587c478bd9Sstevel@tonic-gate ehdr.e_phnum = (unsigned short)nphdrs; 115930da1432Sahl 116030da1432Sahl ehdr.e_phentsize = sizeof (Elf32_Phdr); 11617c478bd9Sstevel@tonic-gate ehdr.e_phoff = ehdr.e_ehsize; 11627c478bd9Sstevel@tonic-gate 116330da1432Sahl if (nshdrs > 0) { 116430da1432Sahl if (nshdrs >= SHN_LORESERVE) 116530da1432Sahl ehdr.e_shnum = 0; 116630da1432Sahl else 11677c478bd9Sstevel@tonic-gate ehdr.e_shnum = (unsigned short)nshdrs; 116830da1432Sahl 116930da1432Sahl if (nshdrs - 1 >= SHN_LORESERVE) 117030da1432Sahl ehdr.e_shstrndx = SHN_XINDEX; 117130da1432Sahl else 117230da1432Sahl ehdr.e_shstrndx = (unsigned short)(nshdrs - 1); 117330da1432Sahl 117430da1432Sahl ehdr.e_shentsize = sizeof (Elf32_Shdr); 117530da1432Sahl ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs; 11767c478bd9Sstevel@tonic-gate } 11777c478bd9Sstevel@tonic-gate 117864e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0) 11797c478bd9Sstevel@tonic-gate goto err; 11807c478bd9Sstevel@tonic-gate 11817c478bd9Sstevel@tonic-gate poff = ehdr.e_phoff; 118230da1432Sahl soff = ehdr.e_shoff; 11837c478bd9Sstevel@tonic-gate doff = boff = ehdr.e_ehsize + 118430da1432Sahl ehdr.e_phentsize * nphdrs + 118530da1432Sahl ehdr.e_shentsize * nshdrs; 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate #ifdef _LP64 11887c478bd9Sstevel@tonic-gate } else { 11897c478bd9Sstevel@tonic-gate Elf64_Ehdr ehdr; 11907c478bd9Sstevel@tonic-gate 11917c478bd9Sstevel@tonic-gate bzero(&ehdr, sizeof (ehdr)); 11927c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG0] = ELFMAG0; 11937c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG1] = ELFMAG1; 11947c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG2] = ELFMAG2; 11957c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG3] = ELFMAG3; 11967c478bd9Sstevel@tonic-gate ehdr.e_type = ET_CORE; 11977c478bd9Sstevel@tonic-gate 11987c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_CLASS] = ELFCLASS64; 11997c478bd9Sstevel@tonic-gate #if defined(__sparc) 12007c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_SPARCV9; 12017c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2MSB; 12027c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64) 12037c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_AMD64; 12047c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 12057c478bd9Sstevel@tonic-gate #else 12067c478bd9Sstevel@tonic-gate #error "unknown machine type" 12077c478bd9Sstevel@tonic-gate #endif 12087c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_VERSION] = EV_CURRENT; 12097c478bd9Sstevel@tonic-gate 12107c478bd9Sstevel@tonic-gate ehdr.e_version = EV_CURRENT; 12117c478bd9Sstevel@tonic-gate ehdr.e_ehsize = sizeof (ehdr); 121230da1432Sahl 121330da1432Sahl if (nphdrs >= PN_XNUM) 121430da1432Sahl ehdr.e_phnum = PN_XNUM; 121530da1432Sahl else 12167c478bd9Sstevel@tonic-gate ehdr.e_phnum = (unsigned short)nphdrs; 121730da1432Sahl 121830da1432Sahl ehdr.e_phentsize = sizeof (Elf64_Phdr); 12197c478bd9Sstevel@tonic-gate ehdr.e_phoff = ehdr.e_ehsize; 12207c478bd9Sstevel@tonic-gate 122130da1432Sahl if (nshdrs > 0) { 122230da1432Sahl if (nshdrs >= SHN_LORESERVE) 122330da1432Sahl ehdr.e_shnum = 0; 122430da1432Sahl else 12257c478bd9Sstevel@tonic-gate ehdr.e_shnum = (unsigned short)nshdrs; 122630da1432Sahl 122730da1432Sahl if (nshdrs - 1 >= SHN_LORESERVE) 122830da1432Sahl ehdr.e_shstrndx = SHN_XINDEX; 122930da1432Sahl else 123030da1432Sahl ehdr.e_shstrndx = (unsigned short)(nshdrs - 1); 123130da1432Sahl 123230da1432Sahl ehdr.e_shentsize = sizeof (Elf64_Shdr); 123330da1432Sahl ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs; 12347c478bd9Sstevel@tonic-gate } 12357c478bd9Sstevel@tonic-gate 123664e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0) 12377c478bd9Sstevel@tonic-gate goto err; 12387c478bd9Sstevel@tonic-gate 12397c478bd9Sstevel@tonic-gate poff = ehdr.e_phoff; 124030da1432Sahl soff = ehdr.e_shoff; 124130da1432Sahl doff = boff = ehdr.e_ehsize + 124230da1432Sahl ehdr.e_phentsize * nphdrs + 124330da1432Sahl ehdr.e_shentsize * nshdrs; 12447c478bd9Sstevel@tonic-gate 12457c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 12467c478bd9Sstevel@tonic-gate } 12477c478bd9Sstevel@tonic-gate 12487c478bd9Sstevel@tonic-gate /* 124930da1432Sahl * Write the zero indexed section if it exists. 125030da1432Sahl */ 125130da1432Sahl if (nshdrs > 0 && write_shdr(&pgc, STR_NONE, 0, 0, 0, 0, 125230da1432Sahl nshdrs >= SHN_LORESERVE ? nshdrs : 0, 125330da1432Sahl nshdrs - 1 >= SHN_LORESERVE ? nshdrs - 1 : 0, 125430da1432Sahl nphdrs >= PN_XNUM ? nphdrs : 0, 0, 0) != 0) 125530da1432Sahl goto err; 125630da1432Sahl 125730da1432Sahl /* 12587c478bd9Sstevel@tonic-gate * Construct the old-style note header and section. 12597c478bd9Sstevel@tonic-gate */ 12607c478bd9Sstevel@tonic-gate 12617c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 12627c478bd9Sstevel@tonic-gate prpsinfo_t prpsinfo; 12637c478bd9Sstevel@tonic-gate 12647c478bd9Sstevel@tonic-gate mkprpsinfo(P, &prpsinfo); 12657c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPSINFO, &prpsinfo, sizeof (prpsinfo_t), 12667c478bd9Sstevel@tonic-gate &doff) != 0) { 12677c478bd9Sstevel@tonic-gate goto err; 12687c478bd9Sstevel@tonic-gate } 12697c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, P->auxv, 12707c478bd9Sstevel@tonic-gate P->nauxv * sizeof (P->auxv[0]), &doff) != 0) { 12717c478bd9Sstevel@tonic-gate goto err; 12727c478bd9Sstevel@tonic-gate } 12737c478bd9Sstevel@tonic-gate #ifdef _LP64 12747c478bd9Sstevel@tonic-gate } else { 12757c478bd9Sstevel@tonic-gate prpsinfo32_t pi32; 12767c478bd9Sstevel@tonic-gate auxv32_t *av32; 12777c478bd9Sstevel@tonic-gate size_t size = sizeof (auxv32_t) * P->nauxv; 12787c478bd9Sstevel@tonic-gate int i; 12797c478bd9Sstevel@tonic-gate 12807c478bd9Sstevel@tonic-gate mkprpsinfo32(P, &pi32); 12817c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPSINFO, &pi32, sizeof (prpsinfo32_t), 12827c478bd9Sstevel@tonic-gate &doff) != 0) { 12837c478bd9Sstevel@tonic-gate goto err; 12847c478bd9Sstevel@tonic-gate } 12857c478bd9Sstevel@tonic-gate 12867c478bd9Sstevel@tonic-gate if ((av32 = malloc(size)) == NULL) 12877c478bd9Sstevel@tonic-gate goto err; 12887c478bd9Sstevel@tonic-gate 12897c478bd9Sstevel@tonic-gate for (i = 0; i < P->nauxv; i++) { 12907c478bd9Sstevel@tonic-gate auxv_n_to_32(&P->auxv[i], &av32[i]); 12917c478bd9Sstevel@tonic-gate } 12927c478bd9Sstevel@tonic-gate 12937c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) { 12947c478bd9Sstevel@tonic-gate free(av32); 12957c478bd9Sstevel@tonic-gate goto err; 12967c478bd9Sstevel@tonic-gate } 12977c478bd9Sstevel@tonic-gate 12987c478bd9Sstevel@tonic-gate free(av32); 12997c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 13007c478bd9Sstevel@tonic-gate } 13017c478bd9Sstevel@tonic-gate 13027c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0) 13037c478bd9Sstevel@tonic-gate goto err; 13047c478bd9Sstevel@tonic-gate 13057c478bd9Sstevel@tonic-gate if (Plwp_iter_all(P, old_per_lwp, &pgc) != 0) 13067c478bd9Sstevel@tonic-gate goto err; 13077c478bd9Sstevel@tonic-gate 13087c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 13097c478bd9Sstevel@tonic-gate Elf32_Phdr phdr; 13107c478bd9Sstevel@tonic-gate 13117c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 13127c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 13137c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 13147c478bd9Sstevel@tonic-gate phdr.p_offset = (Elf32_Off)boff; 13157c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 13167c478bd9Sstevel@tonic-gate boff = doff; 13177c478bd9Sstevel@tonic-gate 131864e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) 13197c478bd9Sstevel@tonic-gate goto err; 13207c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 13217c478bd9Sstevel@tonic-gate #ifdef _LP64 13227c478bd9Sstevel@tonic-gate } else { 13237c478bd9Sstevel@tonic-gate Elf64_Phdr phdr; 13247c478bd9Sstevel@tonic-gate 13257c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 13267c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 13277c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 13287c478bd9Sstevel@tonic-gate phdr.p_offset = boff; 13297c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 13307c478bd9Sstevel@tonic-gate boff = doff; 13317c478bd9Sstevel@tonic-gate 133264e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) 13337c478bd9Sstevel@tonic-gate goto err; 13347c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 13357c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 13367c478bd9Sstevel@tonic-gate } 13377c478bd9Sstevel@tonic-gate 13387c478bd9Sstevel@tonic-gate /* 13397c478bd9Sstevel@tonic-gate * Construct the new-style note header and section. 13407c478bd9Sstevel@tonic-gate */ 13417c478bd9Sstevel@tonic-gate 13427c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 13437c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSINFO, &P->psinfo, sizeof (psinfo_t), 13447c478bd9Sstevel@tonic-gate &doff) != 0) { 13457c478bd9Sstevel@tonic-gate goto err; 13467c478bd9Sstevel@tonic-gate } 13477c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSTATUS, &P->status, sizeof (pstatus_t), 13487c478bd9Sstevel@tonic-gate &doff) != 0) { 13497c478bd9Sstevel@tonic-gate goto err; 13507c478bd9Sstevel@tonic-gate } 13517c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, P->auxv, 13527c478bd9Sstevel@tonic-gate P->nauxv * sizeof (P->auxv[0]), &doff) != 0) { 13537c478bd9Sstevel@tonic-gate goto err; 13547c478bd9Sstevel@tonic-gate } 13557c478bd9Sstevel@tonic-gate #ifdef _LP64 13567c478bd9Sstevel@tonic-gate } else { 13577c478bd9Sstevel@tonic-gate psinfo32_t pi32; 13587c478bd9Sstevel@tonic-gate pstatus32_t ps32; 13597c478bd9Sstevel@tonic-gate auxv32_t *av32; 13607c478bd9Sstevel@tonic-gate size_t size = sizeof (auxv32_t) * P->nauxv; 13617c478bd9Sstevel@tonic-gate int i; 13627c478bd9Sstevel@tonic-gate 13637c478bd9Sstevel@tonic-gate psinfo_n_to_32(&P->psinfo, &pi32); 13647c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSINFO, &pi32, sizeof (psinfo32_t), 13657c478bd9Sstevel@tonic-gate &doff) != 0) { 13667c478bd9Sstevel@tonic-gate goto err; 13677c478bd9Sstevel@tonic-gate } 13687c478bd9Sstevel@tonic-gate pstatus_n_to_32(&P->status, &ps32); 13697c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSTATUS, &ps32, sizeof (pstatus32_t), 13707c478bd9Sstevel@tonic-gate &doff) != 0) { 13717c478bd9Sstevel@tonic-gate goto err; 13727c478bd9Sstevel@tonic-gate } 13737c478bd9Sstevel@tonic-gate if ((av32 = malloc(size)) == NULL) 13747c478bd9Sstevel@tonic-gate goto err; 13757c478bd9Sstevel@tonic-gate 13767c478bd9Sstevel@tonic-gate for (i = 0; i < P->nauxv; i++) { 13777c478bd9Sstevel@tonic-gate auxv_n_to_32(&P->auxv[i], &av32[i]); 13787c478bd9Sstevel@tonic-gate } 13797c478bd9Sstevel@tonic-gate 13807c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) { 13817c478bd9Sstevel@tonic-gate free(av32); 13827c478bd9Sstevel@tonic-gate goto err; 13837c478bd9Sstevel@tonic-gate } 13847c478bd9Sstevel@tonic-gate 13857c478bd9Sstevel@tonic-gate free(av32); 13867c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 13877c478bd9Sstevel@tonic-gate } 13887c478bd9Sstevel@tonic-gate 13897c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0 || 13907c478bd9Sstevel@tonic-gate write_note(fd, NT_UTSNAME, &uts, sizeof (uts), &doff) != 0 || 13917c478bd9Sstevel@tonic-gate write_note(fd, NT_CONTENT, &content, sizeof (content), &doff) != 0) 13927c478bd9Sstevel@tonic-gate goto err; 13937c478bd9Sstevel@tonic-gate 13947c478bd9Sstevel@tonic-gate { 13957c478bd9Sstevel@tonic-gate prcred_t cred, *cp; 13967c478bd9Sstevel@tonic-gate size_t size = sizeof (prcred_t); 13977c478bd9Sstevel@tonic-gate 13987c478bd9Sstevel@tonic-gate if (Pcred(P, &cred, 0) != 0) 13997c478bd9Sstevel@tonic-gate goto err; 14007c478bd9Sstevel@tonic-gate 14017c478bd9Sstevel@tonic-gate if (cred.pr_ngroups > 0) 14027c478bd9Sstevel@tonic-gate size += sizeof (gid_t) * (cred.pr_ngroups - 1); 14037c478bd9Sstevel@tonic-gate if ((cp = malloc(size)) == NULL) 14047c478bd9Sstevel@tonic-gate goto err; 14057c478bd9Sstevel@tonic-gate 14067c478bd9Sstevel@tonic-gate if (Pcred(P, cp, cred.pr_ngroups) != 0 || 14077c478bd9Sstevel@tonic-gate write_note(fd, NT_PRCRED, cp, size, &doff) != 0) { 14087c478bd9Sstevel@tonic-gate free(cp); 14097c478bd9Sstevel@tonic-gate goto err; 14107c478bd9Sstevel@tonic-gate } 14117c478bd9Sstevel@tonic-gate 14127c478bd9Sstevel@tonic-gate free(cp); 14137c478bd9Sstevel@tonic-gate } 14147c478bd9Sstevel@tonic-gate 14157c478bd9Sstevel@tonic-gate { 14162a12f85aSJeremy Jones prpriv_t *ppriv = NULL; 14177c478bd9Sstevel@tonic-gate const priv_impl_info_t *pinfo; 14187c478bd9Sstevel@tonic-gate size_t pprivsz, pinfosz; 14197c478bd9Sstevel@tonic-gate 14202a12f85aSJeremy Jones if (Ppriv(P, &ppriv) == -1) 14217c478bd9Sstevel@tonic-gate goto err; 14227c478bd9Sstevel@tonic-gate pprivsz = PRIV_PRPRIV_SIZE(ppriv); 14237c478bd9Sstevel@tonic-gate 14247c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPRIV, ppriv, pprivsz, &doff) != 0) { 142543051d27SRobert Mustacchi Ppriv_free(P, ppriv); 14267c478bd9Sstevel@tonic-gate goto err; 14277c478bd9Sstevel@tonic-gate } 142843051d27SRobert Mustacchi Ppriv_free(P, ppriv); 14297c478bd9Sstevel@tonic-gate 14307c478bd9Sstevel@tonic-gate if ((pinfo = getprivimplinfo()) == NULL) 14317c478bd9Sstevel@tonic-gate goto err; 14327c478bd9Sstevel@tonic-gate pinfosz = PRIV_IMPL_INFO_SIZE(pinfo); 14337c478bd9Sstevel@tonic-gate 14347c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPRIVINFO, pinfo, pinfosz, &doff) != 0) 14357c478bd9Sstevel@tonic-gate goto err; 14367c478bd9Sstevel@tonic-gate } 14377c478bd9Sstevel@tonic-gate 14387c478bd9Sstevel@tonic-gate if (write_note(fd, NT_ZONENAME, zonename, strlen(zonename) + 1, 14397c478bd9Sstevel@tonic-gate &doff) != 0) 14407c478bd9Sstevel@tonic-gate goto err; 14417c478bd9Sstevel@tonic-gate 144234bdffbfSGarrett D'Amore { 144334bdffbfSGarrett D'Amore fditer_t iter; 144434bdffbfSGarrett D'Amore iter.fd_fd = fd; 144534bdffbfSGarrett D'Amore iter.fd_doff = &doff; 144634bdffbfSGarrett D'Amore 144734bdffbfSGarrett D'Amore if (Pfdinfo_iter(P, iter_fd, &iter) != 0) 144834bdffbfSGarrett D'Amore goto err; 144934bdffbfSGarrett D'Amore } 145034bdffbfSGarrett D'Amore 1451d2a70789SRichard Lowe 1452d2a70789SRichard Lowe { 1453d2a70789SRichard Lowe prsecflags_t *psf = NULL; 1454d2a70789SRichard Lowe 1455d2a70789SRichard Lowe if (Psecflags(P, &psf) != 0) 1456d2a70789SRichard Lowe goto err; 1457d2a70789SRichard Lowe 1458d2a70789SRichard Lowe if (write_note(fd, NT_SECFLAGS, psf, 1459d2a70789SRichard Lowe sizeof (prsecflags_t), &doff) != 0) { 1460d2a70789SRichard Lowe Psecflags_free(psf); 1461d2a70789SRichard Lowe goto err; 1462d2a70789SRichard Lowe } 1463d2a70789SRichard Lowe 1464d2a70789SRichard Lowe Psecflags_free(psf); 1465d2a70789SRichard Lowe } 1466d2a70789SRichard Lowe 14677c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 14687c478bd9Sstevel@tonic-gate /* CSTYLED */ 14697c478bd9Sstevel@tonic-gate { 14707c478bd9Sstevel@tonic-gate struct ssd *ldtp; 14717c478bd9Sstevel@tonic-gate size_t size; 14727c478bd9Sstevel@tonic-gate int nldt; 14737c478bd9Sstevel@tonic-gate 147440c00cd7Sahl /* 147540c00cd7Sahl * Only dump out non-zero sized LDT notes. 147640c00cd7Sahl */ 147740c00cd7Sahl if ((nldt = Pldt(P, NULL, 0)) != 0) { 14787c478bd9Sstevel@tonic-gate size = sizeof (struct ssd) * nldt; 14797c478bd9Sstevel@tonic-gate if ((ldtp = malloc(size)) == NULL) 14807c478bd9Sstevel@tonic-gate goto err; 14817c478bd9Sstevel@tonic-gate 14827c478bd9Sstevel@tonic-gate if (Pldt(P, ldtp, nldt) == -1 || 14837c478bd9Sstevel@tonic-gate write_note(fd, NT_LDT, ldtp, size, &doff) != 0) { 14847c478bd9Sstevel@tonic-gate free(ldtp); 14857c478bd9Sstevel@tonic-gate goto err; 14867c478bd9Sstevel@tonic-gate } 14877c478bd9Sstevel@tonic-gate 14887c478bd9Sstevel@tonic-gate free(ldtp); 14897c478bd9Sstevel@tonic-gate } 149040c00cd7Sahl } 14917c478bd9Sstevel@tonic-gate #endif /* __i386 || __amd64 */ 14927c478bd9Sstevel@tonic-gate 14937c478bd9Sstevel@tonic-gate if (Plwp_iter_all(P, new_per_lwp, &pgc) != 0) 14947c478bd9Sstevel@tonic-gate goto err; 14957c478bd9Sstevel@tonic-gate 14967c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 14977c478bd9Sstevel@tonic-gate Elf32_Phdr phdr; 14987c478bd9Sstevel@tonic-gate 14997c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 15007c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 15017c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 15027c478bd9Sstevel@tonic-gate phdr.p_offset = (Elf32_Off)boff; 15037c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 15047c478bd9Sstevel@tonic-gate boff = doff; 15057c478bd9Sstevel@tonic-gate 150664e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) 15077c478bd9Sstevel@tonic-gate goto err; 15087c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 15097c478bd9Sstevel@tonic-gate #ifdef _LP64 15107c478bd9Sstevel@tonic-gate } else { 15117c478bd9Sstevel@tonic-gate Elf64_Phdr phdr; 15127c478bd9Sstevel@tonic-gate 15137c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 15147c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 15157c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 15167c478bd9Sstevel@tonic-gate phdr.p_offset = boff; 15177c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 15187c478bd9Sstevel@tonic-gate boff = doff; 15197c478bd9Sstevel@tonic-gate 152064e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) 15217c478bd9Sstevel@tonic-gate goto err; 15227c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 15237c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 15247c478bd9Sstevel@tonic-gate } 15257c478bd9Sstevel@tonic-gate 15267c478bd9Sstevel@tonic-gate /* 15277c478bd9Sstevel@tonic-gate * Construct the headers for each mapping and write out its data 15287c478bd9Sstevel@tonic-gate * if the content parameter indicates that it should be present 15297c478bd9Sstevel@tonic-gate * in the core file. 15307c478bd9Sstevel@tonic-gate */ 15317c478bd9Sstevel@tonic-gate if (Pmapping_iter(P, dump_map, &pgc) != 0) 15327c478bd9Sstevel@tonic-gate goto err; 15337c478bd9Sstevel@tonic-gate 15347c478bd9Sstevel@tonic-gate if (dump_sections(&pgc) != 0) 15357c478bd9Sstevel@tonic-gate goto err; 15367c478bd9Sstevel@tonic-gate 15377c478bd9Sstevel@tonic-gate if (write_shstrtab(P, &pgc) != 0) 15387c478bd9Sstevel@tonic-gate goto err; 15397c478bd9Sstevel@tonic-gate 15407c478bd9Sstevel@tonic-gate free(pgc.pgc_chunk); 15417c478bd9Sstevel@tonic-gate 15427c478bd9Sstevel@tonic-gate return (0); 15437c478bd9Sstevel@tonic-gate 15447c478bd9Sstevel@tonic-gate err: 15457c478bd9Sstevel@tonic-gate /* 15467c478bd9Sstevel@tonic-gate * Wipe out anything we may have written if there was an error. 15477c478bd9Sstevel@tonic-gate */ 15487c478bd9Sstevel@tonic-gate (void) ftruncate64(fd, 0); 15497c478bd9Sstevel@tonic-gate free(pgc.pgc_chunk); 1550d2a70789SRichard Lowe 15517c478bd9Sstevel@tonic-gate return (-1); 15527c478bd9Sstevel@tonic-gate } 15537c478bd9Sstevel@tonic-gate 15547c478bd9Sstevel@tonic-gate static const char *content_str[] = { 15557c478bd9Sstevel@tonic-gate "stack", /* CC_CONTENT_STACK */ 15567c478bd9Sstevel@tonic-gate "heap", /* CC_CONTENT_HEAP */ 15577c478bd9Sstevel@tonic-gate "shfile", /* CC_CONTENT_SHFILE */ 15587c478bd9Sstevel@tonic-gate "shanon", /* CC_CONTENT_SHANON */ 15597c478bd9Sstevel@tonic-gate "text", /* CC_CONTENT_TEXT */ 15607c478bd9Sstevel@tonic-gate "data", /* CC_CONTENT_DATA */ 15617c478bd9Sstevel@tonic-gate "rodata", /* CC_CONTENT_RODATA */ 15627c478bd9Sstevel@tonic-gate "anon", /* CC_CONTENT_ANON */ 15637c478bd9Sstevel@tonic-gate "shm", /* CC_CONTENT_SHM */ 15647c478bd9Sstevel@tonic-gate "ism", /* CC_CONTENT_ISM */ 15657c478bd9Sstevel@tonic-gate "dism", /* CC_CONTENT_DISM */ 15667c478bd9Sstevel@tonic-gate "ctf", /* CC_CONTENT_CTF */ 15677c478bd9Sstevel@tonic-gate "symtab", /* CC_CONTENT_SYMTAB */ 15687c478bd9Sstevel@tonic-gate }; 15697c478bd9Sstevel@tonic-gate 15707c478bd9Sstevel@tonic-gate static uint_t ncontent_str = sizeof (content_str) / sizeof (content_str[0]); 15717c478bd9Sstevel@tonic-gate 15727c478bd9Sstevel@tonic-gate #define STREQ(a, b, n) (strlen(b) == (n) && strncmp(a, b, n) == 0) 15737c478bd9Sstevel@tonic-gate 15747c478bd9Sstevel@tonic-gate int 15757c478bd9Sstevel@tonic-gate proc_str2content(const char *str, core_content_t *cp) 15767c478bd9Sstevel@tonic-gate { 15777c478bd9Sstevel@tonic-gate const char *cur = str; 15787c478bd9Sstevel@tonic-gate int add = 1; 15797c478bd9Sstevel@tonic-gate core_content_t mask, content = 0; 15807c478bd9Sstevel@tonic-gate 15817c478bd9Sstevel@tonic-gate for (;;) { 15827c478bd9Sstevel@tonic-gate for (cur = str; isalpha(*cur); cur++) 15837c478bd9Sstevel@tonic-gate continue; 15847c478bd9Sstevel@tonic-gate 15857c478bd9Sstevel@tonic-gate if (STREQ(str, "default", cur - str)) { 15867c478bd9Sstevel@tonic-gate mask = CC_CONTENT_DEFAULT; 15877c478bd9Sstevel@tonic-gate } else if (STREQ(str, "all", cur - str)) { 15887c478bd9Sstevel@tonic-gate mask = CC_CONTENT_ALL; 15897c478bd9Sstevel@tonic-gate } else if (STREQ(str, "none", cur - str)) { 15907c478bd9Sstevel@tonic-gate mask = 0; 15917c478bd9Sstevel@tonic-gate } else { 15927c478bd9Sstevel@tonic-gate int i = 0; 15937c478bd9Sstevel@tonic-gate 15947c478bd9Sstevel@tonic-gate while (!STREQ(str, content_str[i], cur - str)) { 15957c478bd9Sstevel@tonic-gate i++; 15967c478bd9Sstevel@tonic-gate 15977c478bd9Sstevel@tonic-gate if (i >= ncontent_str) 15987c478bd9Sstevel@tonic-gate return (-1); 15997c478bd9Sstevel@tonic-gate } 16007c478bd9Sstevel@tonic-gate 16017c478bd9Sstevel@tonic-gate mask = (core_content_t)1 << i; 16027c478bd9Sstevel@tonic-gate } 16037c478bd9Sstevel@tonic-gate 16047c478bd9Sstevel@tonic-gate if (add) 16057c478bd9Sstevel@tonic-gate content |= mask; 16067c478bd9Sstevel@tonic-gate else 16077c478bd9Sstevel@tonic-gate content &= ~mask; 16087c478bd9Sstevel@tonic-gate 16097c478bd9Sstevel@tonic-gate switch (*cur) { 16107c478bd9Sstevel@tonic-gate case '\0': 16117c478bd9Sstevel@tonic-gate *cp = content; 16127c478bd9Sstevel@tonic-gate return (0); 16137c478bd9Sstevel@tonic-gate case '+': 16147c478bd9Sstevel@tonic-gate add = 1; 16157c478bd9Sstevel@tonic-gate break; 16167c478bd9Sstevel@tonic-gate case '-': 16177c478bd9Sstevel@tonic-gate add = 0; 16187c478bd9Sstevel@tonic-gate break; 16197c478bd9Sstevel@tonic-gate default: 16207c478bd9Sstevel@tonic-gate return (-1); 16217c478bd9Sstevel@tonic-gate } 16227c478bd9Sstevel@tonic-gate 16237c478bd9Sstevel@tonic-gate str = cur + 1; 16247c478bd9Sstevel@tonic-gate } 16257c478bd9Sstevel@tonic-gate } 16267c478bd9Sstevel@tonic-gate 16277c478bd9Sstevel@tonic-gate static int 16287c478bd9Sstevel@tonic-gate popc(core_content_t x) 16297c478bd9Sstevel@tonic-gate { 16307c478bd9Sstevel@tonic-gate int i; 16317c478bd9Sstevel@tonic-gate 16327c478bd9Sstevel@tonic-gate for (i = 0; x != 0; i++) 16337c478bd9Sstevel@tonic-gate x &= x - 1; 16347c478bd9Sstevel@tonic-gate 16357c478bd9Sstevel@tonic-gate return (i); 16367c478bd9Sstevel@tonic-gate } 16377c478bd9Sstevel@tonic-gate 16387c478bd9Sstevel@tonic-gate int 16397c478bd9Sstevel@tonic-gate proc_content2str(core_content_t content, char *buf, size_t size) 16407c478bd9Sstevel@tonic-gate { 16417c478bd9Sstevel@tonic-gate int nonecnt, defcnt, allcnt; 16427c478bd9Sstevel@tonic-gate core_content_t mask, bit; 16437c478bd9Sstevel@tonic-gate int first; 16447c478bd9Sstevel@tonic-gate uint_t index; 16457c478bd9Sstevel@tonic-gate size_t n, tot = 0; 16467c478bd9Sstevel@tonic-gate 16477c478bd9Sstevel@tonic-gate if (content == 0) 16487c478bd9Sstevel@tonic-gate return ((int)strlcpy(buf, "none", size)); 16497c478bd9Sstevel@tonic-gate 16507c478bd9Sstevel@tonic-gate if (content & ~CC_CONTENT_ALL) 16517c478bd9Sstevel@tonic-gate return ((int)strlcpy(buf, "<invalid>", size)); 16527c478bd9Sstevel@tonic-gate 16537c478bd9Sstevel@tonic-gate nonecnt = popc(content); 16547c478bd9Sstevel@tonic-gate defcnt = 1 + popc(content ^ CC_CONTENT_DEFAULT); 16557c478bd9Sstevel@tonic-gate allcnt = 1 + popc(content ^ CC_CONTENT_ALL); 16567c478bd9Sstevel@tonic-gate 16577c478bd9Sstevel@tonic-gate if (defcnt <= nonecnt && defcnt <= allcnt) { 16587c478bd9Sstevel@tonic-gate mask = content ^ CC_CONTENT_DEFAULT; 16597c478bd9Sstevel@tonic-gate first = 0; 16607c478bd9Sstevel@tonic-gate tot += (n = strlcpy(buf, "default", size)); 16617c478bd9Sstevel@tonic-gate if (n > size) 16627c478bd9Sstevel@tonic-gate n = size; 16637c478bd9Sstevel@tonic-gate buf += n; 16647c478bd9Sstevel@tonic-gate size -= n; 16657c478bd9Sstevel@tonic-gate } else if (allcnt < nonecnt) { 16667c478bd9Sstevel@tonic-gate mask = content ^ CC_CONTENT_ALL; 16677c478bd9Sstevel@tonic-gate first = 0; 16687c478bd9Sstevel@tonic-gate tot += (n = strlcpy(buf, "all", size)); 16697c478bd9Sstevel@tonic-gate if (n > size) 16707c478bd9Sstevel@tonic-gate n = size; 16717c478bd9Sstevel@tonic-gate buf += n; 16727c478bd9Sstevel@tonic-gate size -= n; 16737c478bd9Sstevel@tonic-gate } else { 16747c478bd9Sstevel@tonic-gate mask = content; 16757c478bd9Sstevel@tonic-gate first = 1; 16767c478bd9Sstevel@tonic-gate } 16777c478bd9Sstevel@tonic-gate 16787c478bd9Sstevel@tonic-gate while (mask != 0) { 16797c478bd9Sstevel@tonic-gate bit = mask ^ (mask & (mask - 1)); 16807c478bd9Sstevel@tonic-gate 16817c478bd9Sstevel@tonic-gate if (!first) { 16827c478bd9Sstevel@tonic-gate if (size > 1) { 16837c478bd9Sstevel@tonic-gate *buf = (bit & content) ? '+' : '-'; 16847c478bd9Sstevel@tonic-gate buf++; 16857c478bd9Sstevel@tonic-gate size--; 16867c478bd9Sstevel@tonic-gate } 16877c478bd9Sstevel@tonic-gate 16887c478bd9Sstevel@tonic-gate tot++; 16897c478bd9Sstevel@tonic-gate } 16907c478bd9Sstevel@tonic-gate index = popc(bit - 1); 16917c478bd9Sstevel@tonic-gate tot += (n = strlcpy(buf, content_str[index], size)); 16927c478bd9Sstevel@tonic-gate if (n > size) 16937c478bd9Sstevel@tonic-gate n = size; 16947c478bd9Sstevel@tonic-gate buf += n; 16957c478bd9Sstevel@tonic-gate size -= n; 16967c478bd9Sstevel@tonic-gate 16977c478bd9Sstevel@tonic-gate mask ^= bit; 16987c478bd9Sstevel@tonic-gate first = 0; 16997c478bd9Sstevel@tonic-gate } 17007c478bd9Sstevel@tonic-gate 17017c478bd9Sstevel@tonic-gate return ((int)tot); 17027c478bd9Sstevel@tonic-gate } 1703