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. 2843051d27SRobert Mustacchi * Copyright 2015 Joyent, Inc. 292a12f85aSJeremy Jones * Copyright (c) 2013 by Delphix. All rights reserved. 3034bdffbfSGarrett D'Amore */ 317c478bd9Sstevel@tonic-gate 322c797a4eSRoger A. Faulkner #define _STRUCTURED_PROC 1 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include <stdlib.h> 357c478bd9Sstevel@tonic-gate #include <ctype.h> 367c478bd9Sstevel@tonic-gate #include <string.h> 377c478bd9Sstevel@tonic-gate #include <strings.h> 387c478bd9Sstevel@tonic-gate #include <errno.h> 397c478bd9Sstevel@tonic-gate #include <procfs.h> 407c478bd9Sstevel@tonic-gate #include <priv.h> 417c478bd9Sstevel@tonic-gate #include <sys/elf.h> 427c478bd9Sstevel@tonic-gate #include <sys/machelf.h> 437c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 447c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 457c478bd9Sstevel@tonic-gate #include <sys/proc.h> 467c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate #include <sys/old_procfs.h> 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #include "Pcontrol.h" 517c478bd9Sstevel@tonic-gate #include "P32ton.h" 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate typedef enum { 5430da1432Sahl STR_NONE, 557c478bd9Sstevel@tonic-gate STR_CTF, 567c478bd9Sstevel@tonic-gate STR_SYMTAB, 577c478bd9Sstevel@tonic-gate STR_DYNSYM, 587c478bd9Sstevel@tonic-gate STR_STRTAB, 597c478bd9Sstevel@tonic-gate STR_DYNSTR, 607c478bd9Sstevel@tonic-gate STR_SHSTRTAB, 617c478bd9Sstevel@tonic-gate STR_NUM 627c478bd9Sstevel@tonic-gate } shstrtype_t; 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate static const char *shstrtab_data[] = { 6530da1432Sahl "", 667c478bd9Sstevel@tonic-gate ".SUNW_ctf", 677c478bd9Sstevel@tonic-gate ".symtab", 687c478bd9Sstevel@tonic-gate ".dynsym", 697c478bd9Sstevel@tonic-gate ".strtab", 707c478bd9Sstevel@tonic-gate ".dynstr", 717c478bd9Sstevel@tonic-gate ".shstrtab" 727c478bd9Sstevel@tonic-gate }; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate typedef struct shstrtab { 757c478bd9Sstevel@tonic-gate int sst_ndx[STR_NUM]; 767c478bd9Sstevel@tonic-gate int sst_cur; 777c478bd9Sstevel@tonic-gate } shstrtab_t; 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate typedef struct { 807c478bd9Sstevel@tonic-gate struct ps_prochandle *P; 817c478bd9Sstevel@tonic-gate int pgc_fd; 827c478bd9Sstevel@tonic-gate off64_t *pgc_poff; 837c478bd9Sstevel@tonic-gate off64_t *pgc_soff; 847c478bd9Sstevel@tonic-gate off64_t *pgc_doff; 857c478bd9Sstevel@tonic-gate core_content_t pgc_content; 867c478bd9Sstevel@tonic-gate void *pgc_chunk; 877c478bd9Sstevel@tonic-gate size_t pgc_chunksz; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate shstrtab_t pgc_shstrtab; 907c478bd9Sstevel@tonic-gate } pgcore_t; 917c478bd9Sstevel@tonic-gate 9234bdffbfSGarrett D'Amore typedef struct { 9334bdffbfSGarrett D'Amore int fd_fd; 9434bdffbfSGarrett D'Amore off64_t *fd_doff; 9534bdffbfSGarrett D'Amore } fditer_t; 9634bdffbfSGarrett D'Amore 9764e4e50aSKeith M Wesolowski static int 9864e4e50aSKeith M Wesolowski gc_pwrite64(int fd, const void *buf, size_t len, off64_t off) 9964e4e50aSKeith M Wesolowski { 10064e4e50aSKeith M Wesolowski int err; 10164e4e50aSKeith M Wesolowski 10264e4e50aSKeith M Wesolowski err = pwrite64(fd, buf, len, off); 10364e4e50aSKeith M Wesolowski 10464e4e50aSKeith M Wesolowski if (err < 0) 10564e4e50aSKeith M Wesolowski return (err); 10664e4e50aSKeith M Wesolowski 10764e4e50aSKeith M Wesolowski /* 10864e4e50aSKeith M Wesolowski * We will take a page from ZFS's book here and use the otherwise 10964e4e50aSKeith M Wesolowski * unused EBADE to mean a short write. Typically this will actually 11064e4e50aSKeith M Wesolowski * result from ENOSPC or EDQUOT, but we can't be sure. 11164e4e50aSKeith M Wesolowski */ 11264e4e50aSKeith M Wesolowski if (err < len) { 11364e4e50aSKeith M Wesolowski errno = EBADE; 11464e4e50aSKeith M Wesolowski return (-1); 11564e4e50aSKeith M Wesolowski } 11664e4e50aSKeith M Wesolowski 11764e4e50aSKeith M Wesolowski return (0); 11864e4e50aSKeith M Wesolowski } 11964e4e50aSKeith M Wesolowski 1207c478bd9Sstevel@tonic-gate static void 1217c478bd9Sstevel@tonic-gate shstrtab_init(shstrtab_t *s) 1227c478bd9Sstevel@tonic-gate { 1237c478bd9Sstevel@tonic-gate bzero(&s->sst_ndx, sizeof (s->sst_ndx)); 1247c478bd9Sstevel@tonic-gate s->sst_cur = 1; 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate static int 1287c478bd9Sstevel@tonic-gate shstrtab_ndx(shstrtab_t *s, shstrtype_t type) 1297c478bd9Sstevel@tonic-gate { 1307c478bd9Sstevel@tonic-gate int ret; 1317c478bd9Sstevel@tonic-gate 13230da1432Sahl if ((ret = s->sst_ndx[type]) != 0 || type == STR_NONE) 1337c478bd9Sstevel@tonic-gate return (ret); 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate ret = s->sst_ndx[type] = s->sst_cur; 1367c478bd9Sstevel@tonic-gate s->sst_cur += strlen(shstrtab_data[type]) + 1; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate return (ret); 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate static size_t 1427c478bd9Sstevel@tonic-gate shstrtab_size(const shstrtab_t *s) 1437c478bd9Sstevel@tonic-gate { 1447c478bd9Sstevel@tonic-gate return (s->sst_cur); 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate int 1487c478bd9Sstevel@tonic-gate Pgcore(struct ps_prochandle *P, const char *fname, core_content_t content) 1497c478bd9Sstevel@tonic-gate { 1507c478bd9Sstevel@tonic-gate int fd; 1517c478bd9Sstevel@tonic-gate int err; 15264e4e50aSKeith M Wesolowski int saved_errno; 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate if ((fd = creat64(fname, 0666)) < 0) 1557c478bd9Sstevel@tonic-gate return (-1); 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate if ((err = Pfgcore(P, fd, content)) != 0) { 15864e4e50aSKeith M Wesolowski saved_errno = errno; 1597c478bd9Sstevel@tonic-gate (void) close(fd); 1607c478bd9Sstevel@tonic-gate (void) unlink(fname); 16164e4e50aSKeith M Wesolowski errno = saved_errno; 1627c478bd9Sstevel@tonic-gate return (err); 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate return (close(fd)); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate /* 1697c478bd9Sstevel@tonic-gate * Since we don't want to use the old-school procfs interfaces, we use the 1707c478bd9Sstevel@tonic-gate * new-style data structures we already have to construct the old-style 1717c478bd9Sstevel@tonic-gate * data structures. We include these data structures in core files for 1727c478bd9Sstevel@tonic-gate * backward compatability. 1737c478bd9Sstevel@tonic-gate */ 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate static void 1767c478bd9Sstevel@tonic-gate mkprstatus(struct ps_prochandle *P, const lwpstatus_t *lsp, 1777c478bd9Sstevel@tonic-gate const lwpsinfo_t *lip, prstatus_t *psp) 1787c478bd9Sstevel@tonic-gate { 1797c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STOPPED) 1827c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0001; 1837c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISTOP) 1847c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0002; 1857c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_DSTOP) 1867c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0004; 1877c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLEEP) 1887c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0008; 1897c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_FORK) 1907c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0010; 1917c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_RLC) 1927c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0020; 1937c478bd9Sstevel@tonic-gate /* 1947c478bd9Sstevel@tonic-gate * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set; 1957c478bd9Sstevel@tonic-gate * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>. 1967c478bd9Sstevel@tonic-gate */ 1977c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PCINVAL) 1987c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0080; 1997c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISSYS) 2007c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0100; 2017c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STEP) 2027c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0200; 2037c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_KLC) 2047c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0400; 2057c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASYNC) 2067c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0800; 2077c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PTRACE) 2087c478bd9Sstevel@tonic-gate psp->pr_flags = 0x1000; 2097c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_MSACCT) 2107c478bd9Sstevel@tonic-gate psp->pr_flags = 0x2000; 2117c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_BPTADJ) 2127c478bd9Sstevel@tonic-gate psp->pr_flags = 0x4000; 2137c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLWP) 2147c478bd9Sstevel@tonic-gate psp->pr_flags = 0x8000; 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate psp->pr_why = lsp->pr_why; 2177c478bd9Sstevel@tonic-gate psp->pr_what = lsp->pr_what; 2187c478bd9Sstevel@tonic-gate psp->pr_info = lsp->pr_info; 2197c478bd9Sstevel@tonic-gate psp->pr_cursig = lsp->pr_cursig; 2207c478bd9Sstevel@tonic-gate psp->pr_nlwp = P->status.pr_nlwp; 2217c478bd9Sstevel@tonic-gate psp->pr_sigpend = P->status.pr_sigpend; 2227c478bd9Sstevel@tonic-gate psp->pr_sighold = lsp->pr_lwphold; 2237c478bd9Sstevel@tonic-gate psp->pr_altstack = lsp->pr_altstack; 2247c478bd9Sstevel@tonic-gate psp->pr_action = lsp->pr_action; 2257c478bd9Sstevel@tonic-gate psp->pr_pid = P->status.pr_pid; 2267c478bd9Sstevel@tonic-gate psp->pr_ppid = P->status.pr_ppid; 2277c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->status.pr_pgid; 2287c478bd9Sstevel@tonic-gate psp->pr_sid = P->status.pr_sid; 2297c478bd9Sstevel@tonic-gate psp->pr_utime = P->status.pr_utime; 2307c478bd9Sstevel@tonic-gate psp->pr_stime = P->status.pr_stime; 2317c478bd9Sstevel@tonic-gate psp->pr_cutime = P->status.pr_cutime; 2327c478bd9Sstevel@tonic-gate psp->pr_cstime = P->status.pr_cstime; 2337c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname)); 2347c478bd9Sstevel@tonic-gate psp->pr_syscall = lsp->pr_syscall; 2357c478bd9Sstevel@tonic-gate psp->pr_nsysarg = lsp->pr_nsysarg; 2367c478bd9Sstevel@tonic-gate bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg)); 2377c478bd9Sstevel@tonic-gate psp->pr_who = lsp->pr_lwpid; 2387c478bd9Sstevel@tonic-gate psp->pr_lwppend = lsp->pr_lwppend; 2397c478bd9Sstevel@tonic-gate psp->pr_oldcontext = (ucontext_t *)lsp->pr_oldcontext; 2407c478bd9Sstevel@tonic-gate psp->pr_brkbase = (caddr_t)P->status.pr_brkbase; 2417c478bd9Sstevel@tonic-gate psp->pr_brksize = P->status.pr_brksize; 2427c478bd9Sstevel@tonic-gate psp->pr_stkbase = (caddr_t)P->status.pr_stkbase; 2437c478bd9Sstevel@tonic-gate psp->pr_stksize = P->status.pr_stksize; 2447c478bd9Sstevel@tonic-gate psp->pr_processor = (short)lip->pr_onpro; 2457c478bd9Sstevel@tonic-gate psp->pr_bind = (short)lip->pr_bindpro; 2467c478bd9Sstevel@tonic-gate psp->pr_instr = lsp->pr_instr; 2477c478bd9Sstevel@tonic-gate bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg)); 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate static void 2517c478bd9Sstevel@tonic-gate mkprpsinfo(struct ps_prochandle *P, prpsinfo_t *psp) 2527c478bd9Sstevel@tonic-gate { 2537c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 2547c478bd9Sstevel@tonic-gate psp->pr_state = P->psinfo.pr_lwp.pr_state; 2557c478bd9Sstevel@tonic-gate psp->pr_sname = P->psinfo.pr_lwp.pr_sname; 2567c478bd9Sstevel@tonic-gate psp->pr_zomb = (psp->pr_state == SZOMB); 2577c478bd9Sstevel@tonic-gate psp->pr_nice = P->psinfo.pr_lwp.pr_nice; 2587c478bd9Sstevel@tonic-gate psp->pr_flag = P->psinfo.pr_lwp.pr_flag; 2597c478bd9Sstevel@tonic-gate psp->pr_uid = P->psinfo.pr_uid; 2607c478bd9Sstevel@tonic-gate psp->pr_gid = P->psinfo.pr_gid; 2617c478bd9Sstevel@tonic-gate psp->pr_pid = P->psinfo.pr_pid; 2627c478bd9Sstevel@tonic-gate psp->pr_ppid = P->psinfo.pr_ppid; 2637c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->psinfo.pr_pgid; 2647c478bd9Sstevel@tonic-gate psp->pr_sid = P->psinfo.pr_sid; 2657c478bd9Sstevel@tonic-gate psp->pr_addr = (caddr_t)P->psinfo.pr_addr; 2667c478bd9Sstevel@tonic-gate psp->pr_size = P->psinfo.pr_size; 2677c478bd9Sstevel@tonic-gate psp->pr_rssize = P->psinfo.pr_rssize; 2687c478bd9Sstevel@tonic-gate psp->pr_wchan = (caddr_t)P->psinfo.pr_lwp.pr_wchan; 2697c478bd9Sstevel@tonic-gate psp->pr_start = P->psinfo.pr_start; 2707c478bd9Sstevel@tonic-gate psp->pr_time = P->psinfo.pr_time; 2717c478bd9Sstevel@tonic-gate psp->pr_pri = P->psinfo.pr_lwp.pr_pri; 2727c478bd9Sstevel@tonic-gate psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri; 2737c478bd9Sstevel@tonic-gate psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu; 2747c478bd9Sstevel@tonic-gate psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev); 2757c478bd9Sstevel@tonic-gate psp->pr_lttydev = P->psinfo.pr_ttydev; 2767c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname, 2777c478bd9Sstevel@tonic-gate sizeof (psp->pr_clname)); 2787c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_fname, P->psinfo.pr_fname, 2797c478bd9Sstevel@tonic-gate sizeof (psp->pr_fname)); 2807c478bd9Sstevel@tonic-gate bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs, 2817c478bd9Sstevel@tonic-gate sizeof (psp->pr_psargs)); 2827c478bd9Sstevel@tonic-gate psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall; 2837c478bd9Sstevel@tonic-gate psp->pr_ctime = P->psinfo.pr_ctime; 2847c478bd9Sstevel@tonic-gate psp->pr_bysize = psp->pr_size * PAGESIZE; 2857c478bd9Sstevel@tonic-gate psp->pr_byrssize = psp->pr_rssize * PAGESIZE; 2867c478bd9Sstevel@tonic-gate psp->pr_argc = P->psinfo.pr_argc; 2877c478bd9Sstevel@tonic-gate psp->pr_argv = (char **)P->psinfo.pr_argv; 2887c478bd9Sstevel@tonic-gate psp->pr_envp = (char **)P->psinfo.pr_envp; 2897c478bd9Sstevel@tonic-gate psp->pr_wstat = P->psinfo.pr_wstat; 2907c478bd9Sstevel@tonic-gate psp->pr_pctcpu = P->psinfo.pr_pctcpu; 2917c478bd9Sstevel@tonic-gate psp->pr_pctmem = P->psinfo.pr_pctmem; 2927c478bd9Sstevel@tonic-gate psp->pr_euid = P->psinfo.pr_euid; 2937c478bd9Sstevel@tonic-gate psp->pr_egid = P->psinfo.pr_egid; 2947c478bd9Sstevel@tonic-gate psp->pr_aslwpid = 0; 2957c478bd9Sstevel@tonic-gate psp->pr_dmodel = P->psinfo.pr_dmodel; 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate #ifdef _LP64 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate static void 3017c478bd9Sstevel@tonic-gate mkprstatus32(struct ps_prochandle *P, const lwpstatus_t *lsp, 3027c478bd9Sstevel@tonic-gate const lwpsinfo_t *lip, prstatus32_t *psp) 3037c478bd9Sstevel@tonic-gate { 3047c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STOPPED) 3077c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0001; 3087c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISTOP) 3097c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0002; 3107c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_DSTOP) 3117c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0004; 3127c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLEEP) 3137c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0008; 3147c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_FORK) 3157c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0010; 3167c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_RLC) 3177c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0020; 3187c478bd9Sstevel@tonic-gate /* 3197c478bd9Sstevel@tonic-gate * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set; 3207c478bd9Sstevel@tonic-gate * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>. 3217c478bd9Sstevel@tonic-gate */ 3227c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PCINVAL) 3237c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0080; 3247c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISSYS) 3257c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0100; 3267c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STEP) 3277c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0200; 3287c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_KLC) 3297c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0400; 3307c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASYNC) 3317c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0800; 3327c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PTRACE) 3337c478bd9Sstevel@tonic-gate psp->pr_flags = 0x1000; 3347c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_MSACCT) 3357c478bd9Sstevel@tonic-gate psp->pr_flags = 0x2000; 3367c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_BPTADJ) 3377c478bd9Sstevel@tonic-gate psp->pr_flags = 0x4000; 3387c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLWP) 3397c478bd9Sstevel@tonic-gate psp->pr_flags = 0x8000; 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate psp->pr_why = lsp->pr_why; 3427c478bd9Sstevel@tonic-gate psp->pr_what = lsp->pr_what; 3437c478bd9Sstevel@tonic-gate siginfo_n_to_32(&lsp->pr_info, &psp->pr_info); 3447c478bd9Sstevel@tonic-gate psp->pr_cursig = lsp->pr_cursig; 3457c478bd9Sstevel@tonic-gate psp->pr_nlwp = P->status.pr_nlwp; 3467c478bd9Sstevel@tonic-gate psp->pr_sigpend = P->status.pr_sigpend; 3477c478bd9Sstevel@tonic-gate psp->pr_sighold = lsp->pr_lwphold; 3487c478bd9Sstevel@tonic-gate stack_n_to_32(&lsp->pr_altstack, &psp->pr_altstack); 3497c478bd9Sstevel@tonic-gate sigaction_n_to_32(&lsp->pr_action, &psp->pr_action); 3507c478bd9Sstevel@tonic-gate psp->pr_pid = P->status.pr_pid; 3517c478bd9Sstevel@tonic-gate psp->pr_ppid = P->status.pr_ppid; 3527c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->status.pr_pgid; 3537c478bd9Sstevel@tonic-gate psp->pr_sid = P->status.pr_sid; 3547c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_utime, &psp->pr_utime); 3557c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_stime, &psp->pr_stime); 3567c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_cutime, &psp->pr_cutime); 3577c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_cstime, &psp->pr_cstime); 3587c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname)); 3597c478bd9Sstevel@tonic-gate psp->pr_syscall = lsp->pr_syscall; 3607c478bd9Sstevel@tonic-gate psp->pr_nsysarg = lsp->pr_nsysarg; 3612c797a4eSRoger A. Faulkner bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg)); 3622c797a4eSRoger A. Faulkner psp->pr_who = lsp->pr_lwpid; 3637c478bd9Sstevel@tonic-gate psp->pr_lwppend = lsp->pr_lwppend; 3647c478bd9Sstevel@tonic-gate psp->pr_oldcontext = (caddr32_t)lsp->pr_oldcontext; 3657c478bd9Sstevel@tonic-gate psp->pr_brkbase = (caddr32_t)P->status.pr_brkbase; 3667c478bd9Sstevel@tonic-gate psp->pr_brksize = P->status.pr_brksize; 3677c478bd9Sstevel@tonic-gate psp->pr_stkbase = (caddr32_t)P->status.pr_stkbase; 3687c478bd9Sstevel@tonic-gate psp->pr_stksize = P->status.pr_stksize; 3697c478bd9Sstevel@tonic-gate psp->pr_processor = (short)lip->pr_onpro; 3707c478bd9Sstevel@tonic-gate psp->pr_bind = (short)lip->pr_bindpro; 3717c478bd9Sstevel@tonic-gate psp->pr_instr = lsp->pr_instr; 3727c478bd9Sstevel@tonic-gate bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg)); 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate static void 3767c478bd9Sstevel@tonic-gate mkprpsinfo32(struct ps_prochandle *P, prpsinfo32_t *psp) 3777c478bd9Sstevel@tonic-gate { 3787c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 3797c478bd9Sstevel@tonic-gate psp->pr_state = P->psinfo.pr_lwp.pr_state; 3807c478bd9Sstevel@tonic-gate psp->pr_sname = P->psinfo.pr_lwp.pr_sname; 3817c478bd9Sstevel@tonic-gate psp->pr_zomb = (psp->pr_state == SZOMB); 3827c478bd9Sstevel@tonic-gate psp->pr_nice = P->psinfo.pr_lwp.pr_nice; 3837c478bd9Sstevel@tonic-gate psp->pr_flag = P->psinfo.pr_lwp.pr_flag; 3847c478bd9Sstevel@tonic-gate psp->pr_uid = P->psinfo.pr_uid; 3857c478bd9Sstevel@tonic-gate psp->pr_gid = P->psinfo.pr_gid; 3867c478bd9Sstevel@tonic-gate psp->pr_pid = P->psinfo.pr_pid; 3877c478bd9Sstevel@tonic-gate psp->pr_ppid = P->psinfo.pr_ppid; 3887c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->psinfo.pr_pgid; 3897c478bd9Sstevel@tonic-gate psp->pr_sid = P->psinfo.pr_sid; 3907c478bd9Sstevel@tonic-gate psp->pr_addr = (caddr32_t)P->psinfo.pr_addr; 3917c478bd9Sstevel@tonic-gate psp->pr_size = P->psinfo.pr_size; 3927c478bd9Sstevel@tonic-gate psp->pr_rssize = P->psinfo.pr_rssize; 3937c478bd9Sstevel@tonic-gate psp->pr_wchan = (caddr32_t)P->psinfo.pr_lwp.pr_wchan; 3947c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_start, &psp->pr_start); 3957c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_time, &psp->pr_time); 3967c478bd9Sstevel@tonic-gate psp->pr_pri = P->psinfo.pr_lwp.pr_pri; 3977c478bd9Sstevel@tonic-gate psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri; 3987c478bd9Sstevel@tonic-gate psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu; 3997c478bd9Sstevel@tonic-gate psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev); 4007c478bd9Sstevel@tonic-gate psp->pr_lttydev = prcmpldev(P->psinfo.pr_ttydev); 4017c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname, 4027c478bd9Sstevel@tonic-gate sizeof (psp->pr_clname)); 4037c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_fname, P->psinfo.pr_fname, 4047c478bd9Sstevel@tonic-gate sizeof (psp->pr_fname)); 4057c478bd9Sstevel@tonic-gate bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs, 4067c478bd9Sstevel@tonic-gate sizeof (psp->pr_psargs)); 4077c478bd9Sstevel@tonic-gate psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall; 4087c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_ctime, &psp->pr_ctime); 4097c478bd9Sstevel@tonic-gate psp->pr_bysize = psp->pr_size * PAGESIZE; 4107c478bd9Sstevel@tonic-gate psp->pr_byrssize = psp->pr_rssize * PAGESIZE; 4117c478bd9Sstevel@tonic-gate psp->pr_argc = P->psinfo.pr_argc; 4127c478bd9Sstevel@tonic-gate psp->pr_argv = (caddr32_t)P->psinfo.pr_argv; 4137c478bd9Sstevel@tonic-gate psp->pr_envp = (caddr32_t)P->psinfo.pr_envp; 4147c478bd9Sstevel@tonic-gate psp->pr_wstat = P->psinfo.pr_wstat; 4157c478bd9Sstevel@tonic-gate psp->pr_pctcpu = P->psinfo.pr_pctcpu; 4167c478bd9Sstevel@tonic-gate psp->pr_pctmem = P->psinfo.pr_pctmem; 4177c478bd9Sstevel@tonic-gate psp->pr_euid = P->psinfo.pr_euid; 4187c478bd9Sstevel@tonic-gate psp->pr_egid = P->psinfo.pr_egid; 4197c478bd9Sstevel@tonic-gate psp->pr_aslwpid = 0; 4207c478bd9Sstevel@tonic-gate psp->pr_dmodel = P->psinfo.pr_dmodel; 4217c478bd9Sstevel@tonic-gate } 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate static int 4267c478bd9Sstevel@tonic-gate write_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp) 4277c478bd9Sstevel@tonic-gate { 4287c478bd9Sstevel@tonic-gate /* 4297c478bd9Sstevel@tonic-gate * Note headers are the same regardless of the data model of the 4307c478bd9Sstevel@tonic-gate * ELF file; we arbitrarily use Elf64_Nhdr here. 4317c478bd9Sstevel@tonic-gate */ 4327c478bd9Sstevel@tonic-gate struct { 4337c478bd9Sstevel@tonic-gate Elf64_Nhdr nhdr; 4347c478bd9Sstevel@tonic-gate char name[8]; 4357c478bd9Sstevel@tonic-gate } n; 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate bzero(&n, sizeof (n)); 4387c478bd9Sstevel@tonic-gate bcopy("CORE", n.name, 4); 4397c478bd9Sstevel@tonic-gate n.nhdr.n_type = type; 4407c478bd9Sstevel@tonic-gate n.nhdr.n_namesz = 5; 4417c478bd9Sstevel@tonic-gate n.nhdr.n_descsz = roundup(descsz, 4); 4427c478bd9Sstevel@tonic-gate 44364e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &n, sizeof (n), *offp) != 0) 4447c478bd9Sstevel@tonic-gate return (-1); 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate *offp += sizeof (n); 4477c478bd9Sstevel@tonic-gate 44864e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != 0) 4497c478bd9Sstevel@tonic-gate return (-1); 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate *offp += n.nhdr.n_descsz; 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate return (0); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate static int 4577c478bd9Sstevel@tonic-gate old_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip) 4587c478bd9Sstevel@tonic-gate { 4597c478bd9Sstevel@tonic-gate pgcore_t *pgc = data; 4607c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate /* 4637c478bd9Sstevel@tonic-gate * Legacy core files don't contain information about zombie LWPs. 4647c478bd9Sstevel@tonic-gate * We use Plwp_iter_all() so that we get the lwpsinfo_t structure 4657c478bd9Sstevel@tonic-gate * more cheaply. 4667c478bd9Sstevel@tonic-gate */ 4677c478bd9Sstevel@tonic-gate if (lsp == NULL) 4687c478bd9Sstevel@tonic-gate return (0); 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 4717c478bd9Sstevel@tonic-gate prstatus_t prstatus; 4727c478bd9Sstevel@tonic-gate mkprstatus(P, lsp, lip, &prstatus); 4737c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRSTATUS, &prstatus, 4747c478bd9Sstevel@tonic-gate sizeof (prstatus_t), pgc->pgc_doff) != 0) 4757c478bd9Sstevel@tonic-gate return (0); 4767c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRFPREG, &lsp->pr_fpreg, 4777c478bd9Sstevel@tonic-gate sizeof (prfpregset_t), pgc->pgc_doff) != 0) 4787c478bd9Sstevel@tonic-gate return (1); 4797c478bd9Sstevel@tonic-gate #ifdef _LP64 4807c478bd9Sstevel@tonic-gate } else { 4817c478bd9Sstevel@tonic-gate prstatus32_t pr32; 4827c478bd9Sstevel@tonic-gate prfpregset32_t pf32; 4837c478bd9Sstevel@tonic-gate mkprstatus32(P, lsp, lip, &pr32); 4847c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRSTATUS, &pr32, 4857c478bd9Sstevel@tonic-gate sizeof (prstatus32_t), pgc->pgc_doff) != 0) 4867c478bd9Sstevel@tonic-gate return (1); 4877c478bd9Sstevel@tonic-gate prfpregset_n_to_32(&lsp->pr_fpreg, &pf32); 4887c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRFPREG, &pf32, 4897c478bd9Sstevel@tonic-gate sizeof (prfpregset32_t), pgc->pgc_doff) != 0) 4907c478bd9Sstevel@tonic-gate return (1); 4917c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate #ifdef sparc 4957c478bd9Sstevel@tonic-gate { 4967c478bd9Sstevel@tonic-gate prxregset_t xregs; 4977c478bd9Sstevel@tonic-gate if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0 && 4987c478bd9Sstevel@tonic-gate write_note(pgc->pgc_fd, NT_PRXREG, &xregs, 4997c478bd9Sstevel@tonic-gate sizeof (prxregset_t), pgc->pgc_doff) != 0) 5007c478bd9Sstevel@tonic-gate return (1); 5017c478bd9Sstevel@tonic-gate } 5027c478bd9Sstevel@tonic-gate #endif /* sparc */ 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate return (0); 5057c478bd9Sstevel@tonic-gate } 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate static int 5087c478bd9Sstevel@tonic-gate new_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip) 5097c478bd9Sstevel@tonic-gate { 5107c478bd9Sstevel@tonic-gate pgcore_t *pgc = data; 5117c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 512f971a346SBryan Cantrill psinfo_t ps; 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate /* 5157c478bd9Sstevel@tonic-gate * If lsp is NULL this indicates that this is a zombie LWP in 5167c478bd9Sstevel@tonic-gate * which case we dump only the lwpsinfo_t structure and none of 5177c478bd9Sstevel@tonic-gate * the other ancillary LWP state data. 5187c478bd9Sstevel@tonic-gate */ 5197c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 5207c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip, 5217c478bd9Sstevel@tonic-gate sizeof (lwpsinfo_t), pgc->pgc_doff) != 0) 5227c478bd9Sstevel@tonic-gate return (1); 5237c478bd9Sstevel@tonic-gate if (lsp == NULL) 5247c478bd9Sstevel@tonic-gate return (0); 5257c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp, 5267c478bd9Sstevel@tonic-gate sizeof (lwpstatus_t), pgc->pgc_doff) != 0) 5277c478bd9Sstevel@tonic-gate return (1); 5287c478bd9Sstevel@tonic-gate #ifdef _LP64 5297c478bd9Sstevel@tonic-gate } else { 5307c478bd9Sstevel@tonic-gate lwpsinfo32_t li32; 5317c478bd9Sstevel@tonic-gate lwpstatus32_t ls32; 5327c478bd9Sstevel@tonic-gate lwpsinfo_n_to_32(lip, &li32); 5337c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32, 5347c478bd9Sstevel@tonic-gate sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0) 5357c478bd9Sstevel@tonic-gate return (1); 5367c478bd9Sstevel@tonic-gate if (lsp == NULL) 5377c478bd9Sstevel@tonic-gate return (0); 5387c478bd9Sstevel@tonic-gate lwpstatus_n_to_32(lsp, &ls32); 5397c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32, 5407c478bd9Sstevel@tonic-gate sizeof (lwpstatus32_t), pgc->pgc_doff) != 0) 5417c478bd9Sstevel@tonic-gate return (1); 5427c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate #ifdef sparc 5467c478bd9Sstevel@tonic-gate { 5477c478bd9Sstevel@tonic-gate prxregset_t xregs; 5487c478bd9Sstevel@tonic-gate gwindows_t gwins; 5497c478bd9Sstevel@tonic-gate size_t size; 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0) { 5527c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRXREG, &xregs, 5537c478bd9Sstevel@tonic-gate sizeof (prxregset_t), pgc->pgc_doff) != 0) 5547c478bd9Sstevel@tonic-gate return (1); 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate if (Plwp_getgwindows(P, lsp->pr_lwpid, &gwins) == 0 && 5587c478bd9Sstevel@tonic-gate gwins.wbcnt > 0) { 5597c478bd9Sstevel@tonic-gate size = sizeof (gwins) - sizeof (gwins.wbuf) + 5607c478bd9Sstevel@tonic-gate gwins.wbcnt * sizeof (gwins.wbuf[0]); 5617c478bd9Sstevel@tonic-gate 5627c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_GWINDOWS, &gwins, size, 5637c478bd9Sstevel@tonic-gate pgc->pgc_doff) != 0) 5647c478bd9Sstevel@tonic-gate return (1); 5657c478bd9Sstevel@tonic-gate } 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate #ifdef __sparcv9 5697c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_LP64) { 5707c478bd9Sstevel@tonic-gate asrset_t asrs; 5717c478bd9Sstevel@tonic-gate if (Plwp_getasrs(P, lsp->pr_lwpid, asrs) == 0) { 5727c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_ASRS, &asrs, 5737c478bd9Sstevel@tonic-gate sizeof (asrset_t), pgc->pgc_doff) != 0) 5747c478bd9Sstevel@tonic-gate return (1); 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate #endif /* __sparcv9 */ 5787c478bd9Sstevel@tonic-gate #endif /* sparc */ 5797c478bd9Sstevel@tonic-gate 580f971a346SBryan Cantrill if (!(lsp->pr_flags & PR_AGENT)) 581f971a346SBryan Cantrill return (0); 582f971a346SBryan Cantrill 583f971a346SBryan Cantrill if (Plwp_getspymaster(P, lsp->pr_lwpid, &ps) != 0) 584f971a346SBryan Cantrill return (0); 585f971a346SBryan Cantrill 586f971a346SBryan Cantrill if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 587f971a346SBryan Cantrill if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps, 588f971a346SBryan Cantrill sizeof (psinfo_t), pgc->pgc_doff) != 0) 589f971a346SBryan Cantrill return (1); 590f971a346SBryan Cantrill #ifdef _LP64 591f971a346SBryan Cantrill } else { 592f971a346SBryan Cantrill psinfo32_t ps32; 593f971a346SBryan Cantrill psinfo_n_to_32(&ps, &ps32); 594f971a346SBryan Cantrill if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps32, 595f971a346SBryan Cantrill sizeof (psinfo32_t), pgc->pgc_doff) != 0) 596f971a346SBryan Cantrill return (1); 597f971a346SBryan Cantrill #endif /* _LP64 */ 598f971a346SBryan Cantrill } 599f971a346SBryan Cantrill 600f971a346SBryan Cantrill 6017c478bd9Sstevel@tonic-gate return (0); 6027c478bd9Sstevel@tonic-gate } 6037c478bd9Sstevel@tonic-gate 60434bdffbfSGarrett D'Amore static int 60534bdffbfSGarrett D'Amore iter_fd(void *data, prfdinfo_t *fdinfo) 60634bdffbfSGarrett D'Amore { 60734bdffbfSGarrett D'Amore fditer_t *iter = data; 60834bdffbfSGarrett D'Amore 60934bdffbfSGarrett D'Amore if (write_note(iter->fd_fd, NT_FDINFO, fdinfo, 61034bdffbfSGarrett D'Amore sizeof (*fdinfo), iter->fd_doff) != 0) 61134bdffbfSGarrett D'Amore return (1); 61234bdffbfSGarrett D'Amore return (0); 61334bdffbfSGarrett D'Amore } 61434bdffbfSGarrett D'Amore 6157c478bd9Sstevel@tonic-gate static uint_t 6167c478bd9Sstevel@tonic-gate count_sections(pgcore_t *pgc) 6177c478bd9Sstevel@tonic-gate { 6187c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 6197c478bd9Sstevel@tonic-gate file_info_t *fptr; 6207c478bd9Sstevel@tonic-gate uint_t cnt; 6217c478bd9Sstevel@tonic-gate uint_t nshdrs = 0; 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB))) 6247c478bd9Sstevel@tonic-gate return (0); 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate fptr = list_next(&P->file_head); 6277c478bd9Sstevel@tonic-gate for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) { 6287c478bd9Sstevel@tonic-gate int hit_symtab = 0; 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate Pbuild_file_symtab(P, fptr); 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_CTF) && 6337c478bd9Sstevel@tonic-gate Pbuild_file_ctf(P, fptr) != NULL) { 6347c478bd9Sstevel@tonic-gate sym_tbl_t *sym; 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate nshdrs++; 6377c478bd9Sstevel@tonic-gate 6387c478bd9Sstevel@tonic-gate if (fptr->file_ctf_dyn) { 6397c478bd9Sstevel@tonic-gate sym = &fptr->file_dynsym; 6407c478bd9Sstevel@tonic-gate } else { 6417c478bd9Sstevel@tonic-gate sym = &fptr->file_symtab; 6427c478bd9Sstevel@tonic-gate hit_symtab = 1; 6437c478bd9Sstevel@tonic-gate } 6447c478bd9Sstevel@tonic-gate 645d51e9074Sab196087 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 && 6467c478bd9Sstevel@tonic-gate sym->sym_strs != NULL) 6477c478bd9Sstevel@tonic-gate nshdrs += 2; 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab && 651d51e9074Sab196087 fptr->file_symtab.sym_data_pri != NULL && 6527c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_symn != 0 && 6537c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_strs != NULL) { 6547c478bd9Sstevel@tonic-gate nshdrs += 2; 6557c478bd9Sstevel@tonic-gate } 6567c478bd9Sstevel@tonic-gate } 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate return (nshdrs == 0 ? 0 : nshdrs + 2); 6597c478bd9Sstevel@tonic-gate } 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate static int 6627c478bd9Sstevel@tonic-gate write_shdr(pgcore_t *pgc, shstrtype_t name, uint_t type, ulong_t flags, 6637c478bd9Sstevel@tonic-gate uintptr_t addr, ulong_t offset, size_t size, uint_t link, uint_t info, 6647c478bd9Sstevel@tonic-gate uintptr_t addralign, uintptr_t entsize) 6657c478bd9Sstevel@tonic-gate { 6667c478bd9Sstevel@tonic-gate if (pgc->P->status.pr_dmodel == PR_MODEL_ILP32) { 6677c478bd9Sstevel@tonic-gate Elf32_Shdr shdr; 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 6707c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name); 6717c478bd9Sstevel@tonic-gate shdr.sh_type = type; 6727c478bd9Sstevel@tonic-gate shdr.sh_flags = flags; 6737c478bd9Sstevel@tonic-gate shdr.sh_addr = (Elf32_Addr)addr; 6747c478bd9Sstevel@tonic-gate shdr.sh_offset = offset; 6757c478bd9Sstevel@tonic-gate shdr.sh_size = size; 6767c478bd9Sstevel@tonic-gate shdr.sh_link = link; 6777c478bd9Sstevel@tonic-gate shdr.sh_info = info; 6787c478bd9Sstevel@tonic-gate shdr.sh_addralign = addralign; 6797c478bd9Sstevel@tonic-gate shdr.sh_entsize = entsize; 6807c478bd9Sstevel@tonic-gate 68164e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 68264e4e50aSKeith M Wesolowski *pgc->pgc_soff) != 0) 6837c478bd9Sstevel@tonic-gate return (-1); 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 6867c478bd9Sstevel@tonic-gate #ifdef _LP64 6877c478bd9Sstevel@tonic-gate } else { 6887c478bd9Sstevel@tonic-gate Elf64_Shdr shdr; 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 6917c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name); 6927c478bd9Sstevel@tonic-gate shdr.sh_type = type; 6937c478bd9Sstevel@tonic-gate shdr.sh_flags = flags; 6947c478bd9Sstevel@tonic-gate shdr.sh_addr = addr; 6957c478bd9Sstevel@tonic-gate shdr.sh_offset = offset; 6967c478bd9Sstevel@tonic-gate shdr.sh_size = size; 6977c478bd9Sstevel@tonic-gate shdr.sh_link = link; 6987c478bd9Sstevel@tonic-gate shdr.sh_info = info; 6997c478bd9Sstevel@tonic-gate shdr.sh_addralign = addralign; 7007c478bd9Sstevel@tonic-gate shdr.sh_entsize = entsize; 7017c478bd9Sstevel@tonic-gate 70264e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 70364e4e50aSKeith M Wesolowski *pgc->pgc_soff) != 0) 7047c478bd9Sstevel@tonic-gate return (-1); 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 7077c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 7087c478bd9Sstevel@tonic-gate } 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate return (0); 7117c478bd9Sstevel@tonic-gate } 7127c478bd9Sstevel@tonic-gate 7137c478bd9Sstevel@tonic-gate static int 7147c478bd9Sstevel@tonic-gate dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym) 7157c478bd9Sstevel@tonic-gate { 7167c478bd9Sstevel@tonic-gate sym_tbl_t *sym = dynsym ? &fptr->file_dynsym : &fptr->file_symtab; 7177c478bd9Sstevel@tonic-gate shstrtype_t symname = dynsym ? STR_DYNSYM : STR_SYMTAB; 7187c478bd9Sstevel@tonic-gate shstrtype_t strname = dynsym ? STR_DYNSTR : STR_STRTAB; 7197c478bd9Sstevel@tonic-gate uint_t symtype = dynsym ? SHT_DYNSYM : SHT_SYMTAB; 7207c478bd9Sstevel@tonic-gate size_t size; 7217c478bd9Sstevel@tonic-gate uintptr_t addr = fptr->file_map->map_pmap.pr_vaddr; 7227c478bd9Sstevel@tonic-gate 723d51e9074Sab196087 if (sym->sym_data_pri == NULL || sym->sym_symn == 0 || 7247c478bd9Sstevel@tonic-gate sym->sym_strs == NULL) 7257c478bd9Sstevel@tonic-gate return (0); 7267c478bd9Sstevel@tonic-gate 727d51e9074Sab196087 size = sym->sym_hdr_pri.sh_size; 72864e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, sym->sym_data_pri->d_buf, size, 72964e4e50aSKeith M Wesolowski *pgc->pgc_doff) != 0) 7307c478bd9Sstevel@tonic-gate return (-1); 7317c478bd9Sstevel@tonic-gate 7327c478bd9Sstevel@tonic-gate if (write_shdr(pgc, symname, symtype, 0, addr, *pgc->pgc_doff, size, 733d51e9074Sab196087 index + 1, sym->sym_hdr_pri.sh_info, sym->sym_hdr_pri.sh_addralign, 734d51e9074Sab196087 sym->sym_hdr_pri.sh_entsize) != 0) 7357c478bd9Sstevel@tonic-gate return (-1); 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8); 7387c478bd9Sstevel@tonic-gate 7397c478bd9Sstevel@tonic-gate size = sym->sym_strhdr.sh_size; 74064e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != 0) 7417c478bd9Sstevel@tonic-gate return (-1); 7427c478bd9Sstevel@tonic-gate 7437c478bd9Sstevel@tonic-gate if (write_shdr(pgc, strname, SHT_STRTAB, SHF_STRINGS, addr, 7447c478bd9Sstevel@tonic-gate *pgc->pgc_doff, size, 0, 0, 1, 0) != 0) 7457c478bd9Sstevel@tonic-gate return (-1); 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8); 7487c478bd9Sstevel@tonic-gate 7497c478bd9Sstevel@tonic-gate return (0); 7507c478bd9Sstevel@tonic-gate } 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate static int 7537c478bd9Sstevel@tonic-gate dump_sections(pgcore_t *pgc) 7547c478bd9Sstevel@tonic-gate { 7557c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 7567c478bd9Sstevel@tonic-gate file_info_t *fptr; 7577c478bd9Sstevel@tonic-gate uint_t cnt; 7587c478bd9Sstevel@tonic-gate uint_t index = 1; 7597c478bd9Sstevel@tonic-gate 7607c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB))) 7617c478bd9Sstevel@tonic-gate return (0); 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate fptr = list_next(&P->file_head); 7647c478bd9Sstevel@tonic-gate for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) { 7657c478bd9Sstevel@tonic-gate int hit_symtab = 0; 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate Pbuild_file_symtab(P, fptr); 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_CTF) && 7707c478bd9Sstevel@tonic-gate Pbuild_file_ctf(P, fptr) != NULL) { 7717c478bd9Sstevel@tonic-gate sym_tbl_t *sym; 7727c478bd9Sstevel@tonic-gate uint_t dynsym; 7737c478bd9Sstevel@tonic-gate uint_t symindex = 0; 7747c478bd9Sstevel@tonic-gate 7757c478bd9Sstevel@tonic-gate /* 7767c478bd9Sstevel@tonic-gate * Write the symtab out first so we can correctly 7777c478bd9Sstevel@tonic-gate * set the sh_link field in the CTF section header. 7787c478bd9Sstevel@tonic-gate * symindex will be 0 if there is no corresponding 7797c478bd9Sstevel@tonic-gate * symbol table section. 7807c478bd9Sstevel@tonic-gate */ 7817c478bd9Sstevel@tonic-gate if (fptr->file_ctf_dyn) { 7827c478bd9Sstevel@tonic-gate sym = &fptr->file_dynsym; 7837c478bd9Sstevel@tonic-gate dynsym = 1; 7847c478bd9Sstevel@tonic-gate } else { 7857c478bd9Sstevel@tonic-gate sym = &fptr->file_symtab; 7867c478bd9Sstevel@tonic-gate dynsym = 0; 7877c478bd9Sstevel@tonic-gate hit_symtab = 1; 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate 790d51e9074Sab196087 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 && 7917c478bd9Sstevel@tonic-gate sym->sym_strs != NULL) { 7927c478bd9Sstevel@tonic-gate symindex = index; 7937c478bd9Sstevel@tonic-gate if (dump_symtab(pgc, fptr, index, dynsym) != 0) 7947c478bd9Sstevel@tonic-gate return (-1); 7957c478bd9Sstevel@tonic-gate index += 2; 7967c478bd9Sstevel@tonic-gate } 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate /* 7997c478bd9Sstevel@tonic-gate * Write the CTF data that we've read out of the 8007c478bd9Sstevel@tonic-gate * file itself into the core file. 8017c478bd9Sstevel@tonic-gate */ 80264e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, fptr->file_ctf_buf, 80364e4e50aSKeith M Wesolowski fptr->file_ctf_size, *pgc->pgc_doff) != 0) 8047c478bd9Sstevel@tonic-gate return (-1); 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate if (write_shdr(pgc, STR_CTF, SHT_PROGBITS, 0, 8077c478bd9Sstevel@tonic-gate fptr->file_map->map_pmap.pr_vaddr, *pgc->pgc_doff, 8087c478bd9Sstevel@tonic-gate fptr->file_ctf_size, symindex, 0, 4, 0) != 0) 8097c478bd9Sstevel@tonic-gate return (-1); 8107c478bd9Sstevel@tonic-gate 8117c478bd9Sstevel@tonic-gate index++; 8127c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(fptr->file_ctf_size, 8); 8137c478bd9Sstevel@tonic-gate } 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab && 816d51e9074Sab196087 fptr->file_symtab.sym_data_pri != NULL && 8177c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_symn != 0 && 8187c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_strs != NULL) { 8197c478bd9Sstevel@tonic-gate if (dump_symtab(pgc, fptr, index, 0) != 0) 8207c478bd9Sstevel@tonic-gate return (-1); 8217c478bd9Sstevel@tonic-gate index += 2; 8227c478bd9Sstevel@tonic-gate } 8237c478bd9Sstevel@tonic-gate } 8247c478bd9Sstevel@tonic-gate 8257c478bd9Sstevel@tonic-gate return (0); 8267c478bd9Sstevel@tonic-gate } 8277c478bd9Sstevel@tonic-gate 8287c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8297c478bd9Sstevel@tonic-gate static int 8307c478bd9Sstevel@tonic-gate dump_map(void *data, const prmap_t *pmp, const char *name) 8317c478bd9Sstevel@tonic-gate { 8327c478bd9Sstevel@tonic-gate pgcore_t *pgc = data; 8337c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 8347c478bd9Sstevel@tonic-gate #ifdef _LP64 8357c478bd9Sstevel@tonic-gate Elf64_Phdr phdr; 8367c478bd9Sstevel@tonic-gate #else 8377c478bd9Sstevel@tonic-gate Elf32_Phdr phdr; 8387c478bd9Sstevel@tonic-gate #endif 8397c478bd9Sstevel@tonic-gate size_t n; 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 8427c478bd9Sstevel@tonic-gate phdr.p_type = PT_LOAD; 8437c478bd9Sstevel@tonic-gate phdr.p_vaddr = pmp->pr_vaddr; 8447c478bd9Sstevel@tonic-gate phdr.p_memsz = pmp->pr_size; 8457c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_READ) 8467c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_R; 8477c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_WRITE) 8487c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_W; 8497c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_EXEC) 8507c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_X; 8517c478bd9Sstevel@tonic-gate 8527c478bd9Sstevel@tonic-gate if (pmp->pr_vaddr + pmp->pr_size > P->status.pr_stkbase && 8537c478bd9Sstevel@tonic-gate pmp->pr_vaddr < P->status.pr_stkbase + P->status.pr_stksize) { 8547c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_STACK)) 8557c478bd9Sstevel@tonic-gate goto exclude; 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate } else if ((pmp->pr_mflags & MA_ANON) && 8587c478bd9Sstevel@tonic-gate pmp->pr_vaddr + pmp->pr_size > P->status.pr_brkbase && 8597c478bd9Sstevel@tonic-gate pmp->pr_vaddr < P->status.pr_brkbase + P->status.pr_brksize) { 8607c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_HEAP)) 8617c478bd9Sstevel@tonic-gate goto exclude; 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_ISM) { 8647c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_NORESERVE) { 8657c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_DISM)) 8667c478bd9Sstevel@tonic-gate goto exclude; 8677c478bd9Sstevel@tonic-gate } else { 8687c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_ISM)) 8697c478bd9Sstevel@tonic-gate goto exclude; 8707c478bd9Sstevel@tonic-gate } 8717c478bd9Sstevel@tonic-gate 8727c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_SHM) { 8737c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHM)) 8747c478bd9Sstevel@tonic-gate goto exclude; 8757c478bd9Sstevel@tonic-gate 8767c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_SHARED) { 8777c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_ANON) { 8787c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHANON)) 8797c478bd9Sstevel@tonic-gate goto exclude; 8807c478bd9Sstevel@tonic-gate } else { 8817c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHFILE)) 8827c478bd9Sstevel@tonic-gate goto exclude; 8837c478bd9Sstevel@tonic-gate } 8847c478bd9Sstevel@tonic-gate 8857c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_ANON) { 8867c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_ANON)) 8877c478bd9Sstevel@tonic-gate goto exclude; 8887c478bd9Sstevel@tonic-gate 8897c478bd9Sstevel@tonic-gate } else if (phdr.p_flags == (PF_R | PF_X)) { 8907c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_TEXT)) 8917c478bd9Sstevel@tonic-gate goto exclude; 8927c478bd9Sstevel@tonic-gate 8937c478bd9Sstevel@tonic-gate } else if (phdr.p_flags == PF_R) { 8947c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_RODATA)) 8957c478bd9Sstevel@tonic-gate goto exclude; 8967c478bd9Sstevel@tonic-gate 8977c478bd9Sstevel@tonic-gate } else { 8987c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_DATA)) 8997c478bd9Sstevel@tonic-gate goto exclude; 9007c478bd9Sstevel@tonic-gate } 9017c478bd9Sstevel@tonic-gate 9027c478bd9Sstevel@tonic-gate n = 0; 9037c478bd9Sstevel@tonic-gate while (n < pmp->pr_size) { 9047c478bd9Sstevel@tonic-gate size_t csz = MIN(pmp->pr_size - n, pgc->pgc_chunksz); 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate /* 9077c478bd9Sstevel@tonic-gate * If we can't read out part of the victim's address 9087c478bd9Sstevel@tonic-gate * space for some reason ignore that failure and try to 9097c478bd9Sstevel@tonic-gate * emit a partial core file without that mapping's data. 9107c478bd9Sstevel@tonic-gate * As in the kernel, we mark these failures with the 9117c478bd9Sstevel@tonic-gate * PF_SUNW_FAILURE flag and store the errno where the 9127c478bd9Sstevel@tonic-gate * mapping would have been. 9137c478bd9Sstevel@tonic-gate */ 9147c478bd9Sstevel@tonic-gate if (Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n) != csz || 91564e4e50aSKeith M Wesolowski gc_pwrite64(pgc->pgc_fd, pgc->pgc_chunk, csz, 91664e4e50aSKeith M Wesolowski *pgc->pgc_doff + n) != 0) { 9177c478bd9Sstevel@tonic-gate int err = errno; 91864e4e50aSKeith M Wesolowski (void) gc_pwrite64(pgc->pgc_fd, &err, sizeof (err), 9197c478bd9Sstevel@tonic-gate *pgc->pgc_doff); 9207c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(sizeof (err), 8); 9217c478bd9Sstevel@tonic-gate 9227c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_SUNW_FAILURE; 9237c478bd9Sstevel@tonic-gate (void) ftruncate64(pgc->pgc_fd, *pgc->pgc_doff); 9247c478bd9Sstevel@tonic-gate goto exclude; 9257c478bd9Sstevel@tonic-gate } 9267c478bd9Sstevel@tonic-gate 9277c478bd9Sstevel@tonic-gate n += csz; 9287c478bd9Sstevel@tonic-gate } 9297c478bd9Sstevel@tonic-gate 9307c478bd9Sstevel@tonic-gate phdr.p_offset = *pgc->pgc_doff; 9317c478bd9Sstevel@tonic-gate phdr.p_filesz = pmp->pr_size; 9327c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(phdr.p_filesz, 8); 9337c478bd9Sstevel@tonic-gate 9347c478bd9Sstevel@tonic-gate exclude: 9357c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 93664e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &phdr, sizeof (phdr), 93764e4e50aSKeith M Wesolowski *pgc->pgc_poff) != 0) 9387c478bd9Sstevel@tonic-gate return (1); 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate *pgc->pgc_poff += sizeof (phdr); 9417c478bd9Sstevel@tonic-gate #ifdef _LP64 9427c478bd9Sstevel@tonic-gate } else { 9437c478bd9Sstevel@tonic-gate Elf32_Phdr phdr32; 9447c478bd9Sstevel@tonic-gate 9457c478bd9Sstevel@tonic-gate bzero(&phdr32, sizeof (phdr32)); 9467c478bd9Sstevel@tonic-gate phdr32.p_type = phdr.p_type; 9477c478bd9Sstevel@tonic-gate phdr32.p_vaddr = (Elf32_Addr)phdr.p_vaddr; 9487c478bd9Sstevel@tonic-gate phdr32.p_memsz = (Elf32_Word)phdr.p_memsz; 9497c478bd9Sstevel@tonic-gate phdr32.p_flags = phdr.p_flags; 9507c478bd9Sstevel@tonic-gate phdr32.p_offset = (Elf32_Off)phdr.p_offset; 9517c478bd9Sstevel@tonic-gate phdr32.p_filesz = (Elf32_Word)phdr.p_filesz; 9527c478bd9Sstevel@tonic-gate 95364e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &phdr32, sizeof (phdr32), 95464e4e50aSKeith M Wesolowski *pgc->pgc_poff) != 0) 9557c478bd9Sstevel@tonic-gate return (1); 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate *pgc->pgc_poff += sizeof (phdr32); 9587c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 9597c478bd9Sstevel@tonic-gate } 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate return (0); 9627c478bd9Sstevel@tonic-gate } 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate int 9657c478bd9Sstevel@tonic-gate write_shstrtab(struct ps_prochandle *P, pgcore_t *pgc) 9667c478bd9Sstevel@tonic-gate { 9677c478bd9Sstevel@tonic-gate off64_t off = *pgc->pgc_doff; 9687c478bd9Sstevel@tonic-gate size_t size = 0; 9697c478bd9Sstevel@tonic-gate shstrtab_t *s = &pgc->pgc_shstrtab; 9707c478bd9Sstevel@tonic-gate int i, ndx; 9717c478bd9Sstevel@tonic-gate 9727c478bd9Sstevel@tonic-gate if (shstrtab_size(s) == 1) 9737c478bd9Sstevel@tonic-gate return (0); 9747c478bd9Sstevel@tonic-gate 9757c478bd9Sstevel@tonic-gate /* 9767c478bd9Sstevel@tonic-gate * Preemptively stick the name of the shstrtab in the string table. 9777c478bd9Sstevel@tonic-gate */ 9787c478bd9Sstevel@tonic-gate (void) shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB); 9797c478bd9Sstevel@tonic-gate size = shstrtab_size(s); 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate /* 9827c478bd9Sstevel@tonic-gate * Dump all the strings that we used being sure we include the 9837c478bd9Sstevel@tonic-gate * terminating null character. 9847c478bd9Sstevel@tonic-gate */ 9857c478bd9Sstevel@tonic-gate for (i = 0; i < STR_NUM; i++) { 98630da1432Sahl if ((ndx = s->sst_ndx[i]) != 0 || i == STR_NONE) { 9877c478bd9Sstevel@tonic-gate const char *str = shstrtab_data[i]; 9887c478bd9Sstevel@tonic-gate size_t len = strlen(str) + 1; 98964e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, str, len, off + ndx) != 0) 9907c478bd9Sstevel@tonic-gate return (1); 9917c478bd9Sstevel@tonic-gate } 9927c478bd9Sstevel@tonic-gate } 9937c478bd9Sstevel@tonic-gate 9947c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 9957c478bd9Sstevel@tonic-gate Elf32_Shdr shdr; 9967c478bd9Sstevel@tonic-gate 9977c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 9987c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB); 9997c478bd9Sstevel@tonic-gate shdr.sh_size = size; 10007c478bd9Sstevel@tonic-gate shdr.sh_offset = *pgc->pgc_doff; 10017c478bd9Sstevel@tonic-gate shdr.sh_addralign = 1; 10027c478bd9Sstevel@tonic-gate shdr.sh_flags = SHF_STRINGS; 10037c478bd9Sstevel@tonic-gate shdr.sh_type = SHT_STRTAB; 10047c478bd9Sstevel@tonic-gate 100564e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 100664e4e50aSKeith M Wesolowski *pgc->pgc_soff) != 0) 10077c478bd9Sstevel@tonic-gate return (1); 10087c478bd9Sstevel@tonic-gate 10097c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 10107c478bd9Sstevel@tonic-gate #ifdef _LP64 10117c478bd9Sstevel@tonic-gate } else { 10127c478bd9Sstevel@tonic-gate Elf64_Shdr shdr; 10137c478bd9Sstevel@tonic-gate 10147c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 10157c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB); 10167c478bd9Sstevel@tonic-gate shdr.sh_size = size; 10177c478bd9Sstevel@tonic-gate shdr.sh_offset = *pgc->pgc_doff; 10187c478bd9Sstevel@tonic-gate shdr.sh_addralign = 1; 10197c478bd9Sstevel@tonic-gate shdr.sh_flags = SHF_STRINGS; 10207c478bd9Sstevel@tonic-gate shdr.sh_type = SHT_STRTAB; 10217c478bd9Sstevel@tonic-gate 102264e4e50aSKeith M Wesolowski if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 102364e4e50aSKeith M Wesolowski *pgc->pgc_soff) != 0) 10247c478bd9Sstevel@tonic-gate return (1); 10257c478bd9Sstevel@tonic-gate 10267c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 10277c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 10287c478bd9Sstevel@tonic-gate } 10297c478bd9Sstevel@tonic-gate 10307c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8); 10317c478bd9Sstevel@tonic-gate 10327c478bd9Sstevel@tonic-gate return (0); 10337c478bd9Sstevel@tonic-gate } 10347c478bd9Sstevel@tonic-gate 10357c478bd9Sstevel@tonic-gate /* 10367c478bd9Sstevel@tonic-gate * Don't explicity stop the process; that's up to the consumer. 10377c478bd9Sstevel@tonic-gate */ 10387c478bd9Sstevel@tonic-gate int 10397c478bd9Sstevel@tonic-gate Pfgcore(struct ps_prochandle *P, int fd, core_content_t content) 10407c478bd9Sstevel@tonic-gate { 10417c478bd9Sstevel@tonic-gate char plat[SYS_NMLN]; 10427c478bd9Sstevel@tonic-gate char zonename[ZONENAME_MAX]; 10437c478bd9Sstevel@tonic-gate int platlen = -1; 10447c478bd9Sstevel@tonic-gate pgcore_t pgc; 10457c478bd9Sstevel@tonic-gate off64_t poff, soff, doff, boff; 10467c478bd9Sstevel@tonic-gate struct utsname uts; 10477c478bd9Sstevel@tonic-gate uint_t nphdrs, nshdrs; 10487c478bd9Sstevel@tonic-gate 10497c478bd9Sstevel@tonic-gate if (ftruncate64(fd, 0) != 0) 10507c478bd9Sstevel@tonic-gate return (-1); 10517c478bd9Sstevel@tonic-gate 10527c478bd9Sstevel@tonic-gate if (content == CC_CONTENT_INVALID) { 10537c478bd9Sstevel@tonic-gate errno = EINVAL; 10547c478bd9Sstevel@tonic-gate return (-1); 10557c478bd9Sstevel@tonic-gate } 10567c478bd9Sstevel@tonic-gate 10577c478bd9Sstevel@tonic-gate /* 10587c478bd9Sstevel@tonic-gate * Cache the mappings and other useful data. 10597c478bd9Sstevel@tonic-gate */ 10607c478bd9Sstevel@tonic-gate (void) Prd_agent(P); 10617c478bd9Sstevel@tonic-gate (void) Ppsinfo(P); 10627c478bd9Sstevel@tonic-gate 10637c478bd9Sstevel@tonic-gate pgc.P = P; 10647c478bd9Sstevel@tonic-gate pgc.pgc_fd = fd; 10657c478bd9Sstevel@tonic-gate pgc.pgc_poff = &poff; 10667c478bd9Sstevel@tonic-gate pgc.pgc_soff = &soff; 10677c478bd9Sstevel@tonic-gate pgc.pgc_doff = &doff; 10687c478bd9Sstevel@tonic-gate pgc.pgc_content = content; 10697c478bd9Sstevel@tonic-gate pgc.pgc_chunksz = PAGESIZE; 10707c478bd9Sstevel@tonic-gate if ((pgc.pgc_chunk = malloc(pgc.pgc_chunksz)) == NULL) 10717c478bd9Sstevel@tonic-gate return (-1); 10727c478bd9Sstevel@tonic-gate 10737c478bd9Sstevel@tonic-gate shstrtab_init(&pgc.pgc_shstrtab); 10747c478bd9Sstevel@tonic-gate 10757c478bd9Sstevel@tonic-gate /* 10767c478bd9Sstevel@tonic-gate * There are two PT_NOTE program headers for ancillary data, and 10777c478bd9Sstevel@tonic-gate * one for each mapping. 10787c478bd9Sstevel@tonic-gate */ 10797c478bd9Sstevel@tonic-gate nphdrs = 2 + P->map_count; 10807c478bd9Sstevel@tonic-gate nshdrs = count_sections(&pgc); 10817c478bd9Sstevel@tonic-gate 10827c478bd9Sstevel@tonic-gate (void) Pplatform(P, plat, sizeof (plat)); 10837c478bd9Sstevel@tonic-gate platlen = strlen(plat) + 1; 10847c478bd9Sstevel@tonic-gate Preadauxvec(P); 10857c478bd9Sstevel@tonic-gate (void) Puname(P, &uts); 10867c478bd9Sstevel@tonic-gate if (Pzonename(P, zonename, sizeof (zonename)) == NULL) 10877c478bd9Sstevel@tonic-gate zonename[0] = '\0'; 10887c478bd9Sstevel@tonic-gate 10897c478bd9Sstevel@tonic-gate /* 109030da1432Sahl * The core file contents may required zero section headers, but if we 109130da1432Sahl * overflow the 16 bits allotted to the program header count in the ELF 109230da1432Sahl * header, we'll need that program header at index zero. 109330da1432Sahl */ 109430da1432Sahl if (nshdrs == 0 && nphdrs >= PN_XNUM) 109530da1432Sahl nshdrs = 1; 109630da1432Sahl 109730da1432Sahl /* 10987c478bd9Sstevel@tonic-gate * Set up the ELF header. 10997c478bd9Sstevel@tonic-gate */ 11007c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 11017c478bd9Sstevel@tonic-gate Elf32_Ehdr ehdr; 11027c478bd9Sstevel@tonic-gate 11037c478bd9Sstevel@tonic-gate bzero(&ehdr, sizeof (ehdr)); 11047c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG0] = ELFMAG0; 11057c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG1] = ELFMAG1; 11067c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG2] = ELFMAG2; 11077c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG3] = ELFMAG3; 11087c478bd9Sstevel@tonic-gate ehdr.e_type = ET_CORE; 11097c478bd9Sstevel@tonic-gate 11107c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_CLASS] = ELFCLASS32; 11117c478bd9Sstevel@tonic-gate #if defined(__sparc) 11127c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_SPARC; 11137c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2MSB; 11147c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64) 11157c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_386; 11167c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 11177c478bd9Sstevel@tonic-gate #else 11187c478bd9Sstevel@tonic-gate #error "unknown machine type" 11197c478bd9Sstevel@tonic-gate #endif 11207c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_VERSION] = EV_CURRENT; 11217c478bd9Sstevel@tonic-gate 11227c478bd9Sstevel@tonic-gate ehdr.e_version = EV_CURRENT; 11237c478bd9Sstevel@tonic-gate ehdr.e_ehsize = sizeof (ehdr); 112430da1432Sahl 112530da1432Sahl if (nphdrs >= PN_XNUM) 112630da1432Sahl ehdr.e_phnum = PN_XNUM; 112730da1432Sahl else 11287c478bd9Sstevel@tonic-gate ehdr.e_phnum = (unsigned short)nphdrs; 112930da1432Sahl 113030da1432Sahl ehdr.e_phentsize = sizeof (Elf32_Phdr); 11317c478bd9Sstevel@tonic-gate ehdr.e_phoff = ehdr.e_ehsize; 11327c478bd9Sstevel@tonic-gate 113330da1432Sahl if (nshdrs > 0) { 113430da1432Sahl if (nshdrs >= SHN_LORESERVE) 113530da1432Sahl ehdr.e_shnum = 0; 113630da1432Sahl else 11377c478bd9Sstevel@tonic-gate ehdr.e_shnum = (unsigned short)nshdrs; 113830da1432Sahl 113930da1432Sahl if (nshdrs - 1 >= SHN_LORESERVE) 114030da1432Sahl ehdr.e_shstrndx = SHN_XINDEX; 114130da1432Sahl else 114230da1432Sahl ehdr.e_shstrndx = (unsigned short)(nshdrs - 1); 114330da1432Sahl 114430da1432Sahl ehdr.e_shentsize = sizeof (Elf32_Shdr); 114530da1432Sahl ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs; 11467c478bd9Sstevel@tonic-gate } 11477c478bd9Sstevel@tonic-gate 114864e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0) 11497c478bd9Sstevel@tonic-gate goto err; 11507c478bd9Sstevel@tonic-gate 11517c478bd9Sstevel@tonic-gate poff = ehdr.e_phoff; 115230da1432Sahl soff = ehdr.e_shoff; 11537c478bd9Sstevel@tonic-gate doff = boff = ehdr.e_ehsize + 115430da1432Sahl ehdr.e_phentsize * nphdrs + 115530da1432Sahl ehdr.e_shentsize * nshdrs; 11567c478bd9Sstevel@tonic-gate 11577c478bd9Sstevel@tonic-gate #ifdef _LP64 11587c478bd9Sstevel@tonic-gate } else { 11597c478bd9Sstevel@tonic-gate Elf64_Ehdr ehdr; 11607c478bd9Sstevel@tonic-gate 11617c478bd9Sstevel@tonic-gate bzero(&ehdr, sizeof (ehdr)); 11627c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG0] = ELFMAG0; 11637c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG1] = ELFMAG1; 11647c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG2] = ELFMAG2; 11657c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG3] = ELFMAG3; 11667c478bd9Sstevel@tonic-gate ehdr.e_type = ET_CORE; 11677c478bd9Sstevel@tonic-gate 11687c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_CLASS] = ELFCLASS64; 11697c478bd9Sstevel@tonic-gate #if defined(__sparc) 11707c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_SPARCV9; 11717c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2MSB; 11727c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64) 11737c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_AMD64; 11747c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 11757c478bd9Sstevel@tonic-gate #else 11767c478bd9Sstevel@tonic-gate #error "unknown machine type" 11777c478bd9Sstevel@tonic-gate #endif 11787c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_VERSION] = EV_CURRENT; 11797c478bd9Sstevel@tonic-gate 11807c478bd9Sstevel@tonic-gate ehdr.e_version = EV_CURRENT; 11817c478bd9Sstevel@tonic-gate ehdr.e_ehsize = sizeof (ehdr); 118230da1432Sahl 118330da1432Sahl if (nphdrs >= PN_XNUM) 118430da1432Sahl ehdr.e_phnum = PN_XNUM; 118530da1432Sahl else 11867c478bd9Sstevel@tonic-gate ehdr.e_phnum = (unsigned short)nphdrs; 118730da1432Sahl 118830da1432Sahl ehdr.e_phentsize = sizeof (Elf64_Phdr); 11897c478bd9Sstevel@tonic-gate ehdr.e_phoff = ehdr.e_ehsize; 11907c478bd9Sstevel@tonic-gate 119130da1432Sahl if (nshdrs > 0) { 119230da1432Sahl if (nshdrs >= SHN_LORESERVE) 119330da1432Sahl ehdr.e_shnum = 0; 119430da1432Sahl else 11957c478bd9Sstevel@tonic-gate ehdr.e_shnum = (unsigned short)nshdrs; 119630da1432Sahl 119730da1432Sahl if (nshdrs - 1 >= SHN_LORESERVE) 119830da1432Sahl ehdr.e_shstrndx = SHN_XINDEX; 119930da1432Sahl else 120030da1432Sahl ehdr.e_shstrndx = (unsigned short)(nshdrs - 1); 120130da1432Sahl 120230da1432Sahl ehdr.e_shentsize = sizeof (Elf64_Shdr); 120330da1432Sahl ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs; 12047c478bd9Sstevel@tonic-gate } 12057c478bd9Sstevel@tonic-gate 120664e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0) 12077c478bd9Sstevel@tonic-gate goto err; 12087c478bd9Sstevel@tonic-gate 12097c478bd9Sstevel@tonic-gate poff = ehdr.e_phoff; 121030da1432Sahl soff = ehdr.e_shoff; 121130da1432Sahl doff = boff = ehdr.e_ehsize + 121230da1432Sahl ehdr.e_phentsize * nphdrs + 121330da1432Sahl ehdr.e_shentsize * nshdrs; 12147c478bd9Sstevel@tonic-gate 12157c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 12167c478bd9Sstevel@tonic-gate } 12177c478bd9Sstevel@tonic-gate 12187c478bd9Sstevel@tonic-gate /* 121930da1432Sahl * Write the zero indexed section if it exists. 122030da1432Sahl */ 122130da1432Sahl if (nshdrs > 0 && write_shdr(&pgc, STR_NONE, 0, 0, 0, 0, 122230da1432Sahl nshdrs >= SHN_LORESERVE ? nshdrs : 0, 122330da1432Sahl nshdrs - 1 >= SHN_LORESERVE ? nshdrs - 1 : 0, 122430da1432Sahl nphdrs >= PN_XNUM ? nphdrs : 0, 0, 0) != 0) 122530da1432Sahl goto err; 122630da1432Sahl 122730da1432Sahl /* 12287c478bd9Sstevel@tonic-gate * Construct the old-style note header and section. 12297c478bd9Sstevel@tonic-gate */ 12307c478bd9Sstevel@tonic-gate 12317c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 12327c478bd9Sstevel@tonic-gate prpsinfo_t prpsinfo; 12337c478bd9Sstevel@tonic-gate 12347c478bd9Sstevel@tonic-gate mkprpsinfo(P, &prpsinfo); 12357c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPSINFO, &prpsinfo, sizeof (prpsinfo_t), 12367c478bd9Sstevel@tonic-gate &doff) != 0) { 12377c478bd9Sstevel@tonic-gate goto err; 12387c478bd9Sstevel@tonic-gate } 12397c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, P->auxv, 12407c478bd9Sstevel@tonic-gate P->nauxv * sizeof (P->auxv[0]), &doff) != 0) { 12417c478bd9Sstevel@tonic-gate goto err; 12427c478bd9Sstevel@tonic-gate } 12437c478bd9Sstevel@tonic-gate #ifdef _LP64 12447c478bd9Sstevel@tonic-gate } else { 12457c478bd9Sstevel@tonic-gate prpsinfo32_t pi32; 12467c478bd9Sstevel@tonic-gate auxv32_t *av32; 12477c478bd9Sstevel@tonic-gate size_t size = sizeof (auxv32_t) * P->nauxv; 12487c478bd9Sstevel@tonic-gate int i; 12497c478bd9Sstevel@tonic-gate 12507c478bd9Sstevel@tonic-gate mkprpsinfo32(P, &pi32); 12517c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPSINFO, &pi32, sizeof (prpsinfo32_t), 12527c478bd9Sstevel@tonic-gate &doff) != 0) { 12537c478bd9Sstevel@tonic-gate goto err; 12547c478bd9Sstevel@tonic-gate } 12557c478bd9Sstevel@tonic-gate 12567c478bd9Sstevel@tonic-gate if ((av32 = malloc(size)) == NULL) 12577c478bd9Sstevel@tonic-gate goto err; 12587c478bd9Sstevel@tonic-gate 12597c478bd9Sstevel@tonic-gate for (i = 0; i < P->nauxv; i++) { 12607c478bd9Sstevel@tonic-gate auxv_n_to_32(&P->auxv[i], &av32[i]); 12617c478bd9Sstevel@tonic-gate } 12627c478bd9Sstevel@tonic-gate 12637c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) { 12647c478bd9Sstevel@tonic-gate free(av32); 12657c478bd9Sstevel@tonic-gate goto err; 12667c478bd9Sstevel@tonic-gate } 12677c478bd9Sstevel@tonic-gate 12687c478bd9Sstevel@tonic-gate free(av32); 12697c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 12707c478bd9Sstevel@tonic-gate } 12717c478bd9Sstevel@tonic-gate 12727c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0) 12737c478bd9Sstevel@tonic-gate goto err; 12747c478bd9Sstevel@tonic-gate 12757c478bd9Sstevel@tonic-gate if (Plwp_iter_all(P, old_per_lwp, &pgc) != 0) 12767c478bd9Sstevel@tonic-gate goto err; 12777c478bd9Sstevel@tonic-gate 12787c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 12797c478bd9Sstevel@tonic-gate Elf32_Phdr phdr; 12807c478bd9Sstevel@tonic-gate 12817c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 12827c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 12837c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 12847c478bd9Sstevel@tonic-gate phdr.p_offset = (Elf32_Off)boff; 12857c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 12867c478bd9Sstevel@tonic-gate boff = doff; 12877c478bd9Sstevel@tonic-gate 128864e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) 12897c478bd9Sstevel@tonic-gate goto err; 12907c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 12917c478bd9Sstevel@tonic-gate #ifdef _LP64 12927c478bd9Sstevel@tonic-gate } else { 12937c478bd9Sstevel@tonic-gate Elf64_Phdr phdr; 12947c478bd9Sstevel@tonic-gate 12957c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 12967c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 12977c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 12987c478bd9Sstevel@tonic-gate phdr.p_offset = boff; 12997c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 13007c478bd9Sstevel@tonic-gate boff = doff; 13017c478bd9Sstevel@tonic-gate 130264e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) 13037c478bd9Sstevel@tonic-gate goto err; 13047c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 13057c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 13067c478bd9Sstevel@tonic-gate } 13077c478bd9Sstevel@tonic-gate 13087c478bd9Sstevel@tonic-gate /* 13097c478bd9Sstevel@tonic-gate * Construct the new-style note header and section. 13107c478bd9Sstevel@tonic-gate */ 13117c478bd9Sstevel@tonic-gate 13127c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 13137c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSINFO, &P->psinfo, sizeof (psinfo_t), 13147c478bd9Sstevel@tonic-gate &doff) != 0) { 13157c478bd9Sstevel@tonic-gate goto err; 13167c478bd9Sstevel@tonic-gate } 13177c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSTATUS, &P->status, sizeof (pstatus_t), 13187c478bd9Sstevel@tonic-gate &doff) != 0) { 13197c478bd9Sstevel@tonic-gate goto err; 13207c478bd9Sstevel@tonic-gate } 13217c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, P->auxv, 13227c478bd9Sstevel@tonic-gate P->nauxv * sizeof (P->auxv[0]), &doff) != 0) { 13237c478bd9Sstevel@tonic-gate goto err; 13247c478bd9Sstevel@tonic-gate } 13257c478bd9Sstevel@tonic-gate #ifdef _LP64 13267c478bd9Sstevel@tonic-gate } else { 13277c478bd9Sstevel@tonic-gate psinfo32_t pi32; 13287c478bd9Sstevel@tonic-gate pstatus32_t ps32; 13297c478bd9Sstevel@tonic-gate auxv32_t *av32; 13307c478bd9Sstevel@tonic-gate size_t size = sizeof (auxv32_t) * P->nauxv; 13317c478bd9Sstevel@tonic-gate int i; 13327c478bd9Sstevel@tonic-gate 13337c478bd9Sstevel@tonic-gate psinfo_n_to_32(&P->psinfo, &pi32); 13347c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSINFO, &pi32, sizeof (psinfo32_t), 13357c478bd9Sstevel@tonic-gate &doff) != 0) { 13367c478bd9Sstevel@tonic-gate goto err; 13377c478bd9Sstevel@tonic-gate } 13387c478bd9Sstevel@tonic-gate pstatus_n_to_32(&P->status, &ps32); 13397c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSTATUS, &ps32, sizeof (pstatus32_t), 13407c478bd9Sstevel@tonic-gate &doff) != 0) { 13417c478bd9Sstevel@tonic-gate goto err; 13427c478bd9Sstevel@tonic-gate } 13437c478bd9Sstevel@tonic-gate if ((av32 = malloc(size)) == NULL) 13447c478bd9Sstevel@tonic-gate goto err; 13457c478bd9Sstevel@tonic-gate 13467c478bd9Sstevel@tonic-gate for (i = 0; i < P->nauxv; i++) { 13477c478bd9Sstevel@tonic-gate auxv_n_to_32(&P->auxv[i], &av32[i]); 13487c478bd9Sstevel@tonic-gate } 13497c478bd9Sstevel@tonic-gate 13507c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) { 13517c478bd9Sstevel@tonic-gate free(av32); 13527c478bd9Sstevel@tonic-gate goto err; 13537c478bd9Sstevel@tonic-gate } 13547c478bd9Sstevel@tonic-gate 13557c478bd9Sstevel@tonic-gate free(av32); 13567c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 13577c478bd9Sstevel@tonic-gate } 13587c478bd9Sstevel@tonic-gate 13597c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0 || 13607c478bd9Sstevel@tonic-gate write_note(fd, NT_UTSNAME, &uts, sizeof (uts), &doff) != 0 || 13617c478bd9Sstevel@tonic-gate write_note(fd, NT_CONTENT, &content, sizeof (content), &doff) != 0) 13627c478bd9Sstevel@tonic-gate goto err; 13637c478bd9Sstevel@tonic-gate 13647c478bd9Sstevel@tonic-gate { 13657c478bd9Sstevel@tonic-gate prcred_t cred, *cp; 13667c478bd9Sstevel@tonic-gate size_t size = sizeof (prcred_t); 13677c478bd9Sstevel@tonic-gate 13687c478bd9Sstevel@tonic-gate if (Pcred(P, &cred, 0) != 0) 13697c478bd9Sstevel@tonic-gate goto err; 13707c478bd9Sstevel@tonic-gate 13717c478bd9Sstevel@tonic-gate if (cred.pr_ngroups > 0) 13727c478bd9Sstevel@tonic-gate size += sizeof (gid_t) * (cred.pr_ngroups - 1); 13737c478bd9Sstevel@tonic-gate if ((cp = malloc(size)) == NULL) 13747c478bd9Sstevel@tonic-gate goto err; 13757c478bd9Sstevel@tonic-gate 13767c478bd9Sstevel@tonic-gate if (Pcred(P, cp, cred.pr_ngroups) != 0 || 13777c478bd9Sstevel@tonic-gate write_note(fd, NT_PRCRED, cp, size, &doff) != 0) { 13787c478bd9Sstevel@tonic-gate free(cp); 13797c478bd9Sstevel@tonic-gate goto err; 13807c478bd9Sstevel@tonic-gate } 13817c478bd9Sstevel@tonic-gate 13827c478bd9Sstevel@tonic-gate free(cp); 13837c478bd9Sstevel@tonic-gate } 13847c478bd9Sstevel@tonic-gate 13857c478bd9Sstevel@tonic-gate { 13862a12f85aSJeremy Jones prpriv_t *ppriv = NULL; 13877c478bd9Sstevel@tonic-gate const priv_impl_info_t *pinfo; 13887c478bd9Sstevel@tonic-gate size_t pprivsz, pinfosz; 13897c478bd9Sstevel@tonic-gate 13902a12f85aSJeremy Jones if (Ppriv(P, &ppriv) == -1) 13917c478bd9Sstevel@tonic-gate goto err; 13927c478bd9Sstevel@tonic-gate pprivsz = PRIV_PRPRIV_SIZE(ppriv); 13937c478bd9Sstevel@tonic-gate 13947c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPRIV, ppriv, pprivsz, &doff) != 0) { 139543051d27SRobert Mustacchi Ppriv_free(P, ppriv); 13967c478bd9Sstevel@tonic-gate goto err; 13977c478bd9Sstevel@tonic-gate } 139843051d27SRobert Mustacchi Ppriv_free(P, ppriv); 13997c478bd9Sstevel@tonic-gate 14007c478bd9Sstevel@tonic-gate if ((pinfo = getprivimplinfo()) == NULL) 14017c478bd9Sstevel@tonic-gate goto err; 14027c478bd9Sstevel@tonic-gate pinfosz = PRIV_IMPL_INFO_SIZE(pinfo); 14037c478bd9Sstevel@tonic-gate 14047c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPRIVINFO, pinfo, pinfosz, &doff) != 0) 14057c478bd9Sstevel@tonic-gate goto err; 14067c478bd9Sstevel@tonic-gate } 14077c478bd9Sstevel@tonic-gate 14087c478bd9Sstevel@tonic-gate if (write_note(fd, NT_ZONENAME, zonename, strlen(zonename) + 1, 14097c478bd9Sstevel@tonic-gate &doff) != 0) 14107c478bd9Sstevel@tonic-gate goto err; 14117c478bd9Sstevel@tonic-gate 141234bdffbfSGarrett D'Amore { 141334bdffbfSGarrett D'Amore fditer_t iter; 141434bdffbfSGarrett D'Amore iter.fd_fd = fd; 141534bdffbfSGarrett D'Amore iter.fd_doff = &doff; 141634bdffbfSGarrett D'Amore 141734bdffbfSGarrett D'Amore if (Pfdinfo_iter(P, iter_fd, &iter) != 0) 141834bdffbfSGarrett D'Amore goto err; 141934bdffbfSGarrett D'Amore } 142034bdffbfSGarrett D'Amore 1421*d2a70789SRichard Lowe 1422*d2a70789SRichard Lowe { 1423*d2a70789SRichard Lowe prsecflags_t *psf = NULL; 1424*d2a70789SRichard Lowe 1425*d2a70789SRichard Lowe if (Psecflags(P, &psf) != 0) 1426*d2a70789SRichard Lowe goto err; 1427*d2a70789SRichard Lowe 1428*d2a70789SRichard Lowe if (write_note(fd, NT_SECFLAGS, psf, 1429*d2a70789SRichard Lowe sizeof (prsecflags_t), &doff) != 0) { 1430*d2a70789SRichard Lowe Psecflags_free(psf); 1431*d2a70789SRichard Lowe goto err; 1432*d2a70789SRichard Lowe } 1433*d2a70789SRichard Lowe 1434*d2a70789SRichard Lowe Psecflags_free(psf); 1435*d2a70789SRichard Lowe } 1436*d2a70789SRichard Lowe 14377c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 14387c478bd9Sstevel@tonic-gate /* CSTYLED */ 14397c478bd9Sstevel@tonic-gate { 14407c478bd9Sstevel@tonic-gate struct ssd *ldtp; 14417c478bd9Sstevel@tonic-gate size_t size; 14427c478bd9Sstevel@tonic-gate int nldt; 14437c478bd9Sstevel@tonic-gate 144440c00cd7Sahl /* 144540c00cd7Sahl * Only dump out non-zero sized LDT notes. 144640c00cd7Sahl */ 144740c00cd7Sahl if ((nldt = Pldt(P, NULL, 0)) != 0) { 14487c478bd9Sstevel@tonic-gate size = sizeof (struct ssd) * nldt; 14497c478bd9Sstevel@tonic-gate if ((ldtp = malloc(size)) == NULL) 14507c478bd9Sstevel@tonic-gate goto err; 14517c478bd9Sstevel@tonic-gate 14527c478bd9Sstevel@tonic-gate if (Pldt(P, ldtp, nldt) == -1 || 14537c478bd9Sstevel@tonic-gate write_note(fd, NT_LDT, ldtp, size, &doff) != 0) { 14547c478bd9Sstevel@tonic-gate free(ldtp); 14557c478bd9Sstevel@tonic-gate goto err; 14567c478bd9Sstevel@tonic-gate } 14577c478bd9Sstevel@tonic-gate 14587c478bd9Sstevel@tonic-gate free(ldtp); 14597c478bd9Sstevel@tonic-gate } 146040c00cd7Sahl } 14617c478bd9Sstevel@tonic-gate #endif /* __i386 || __amd64 */ 14627c478bd9Sstevel@tonic-gate 14637c478bd9Sstevel@tonic-gate if (Plwp_iter_all(P, new_per_lwp, &pgc) != 0) 14647c478bd9Sstevel@tonic-gate goto err; 14657c478bd9Sstevel@tonic-gate 14667c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 14677c478bd9Sstevel@tonic-gate Elf32_Phdr phdr; 14687c478bd9Sstevel@tonic-gate 14697c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 14707c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 14717c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 14727c478bd9Sstevel@tonic-gate phdr.p_offset = (Elf32_Off)boff; 14737c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 14747c478bd9Sstevel@tonic-gate boff = doff; 14757c478bd9Sstevel@tonic-gate 147664e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) 14777c478bd9Sstevel@tonic-gate goto err; 14787c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 14797c478bd9Sstevel@tonic-gate #ifdef _LP64 14807c478bd9Sstevel@tonic-gate } else { 14817c478bd9Sstevel@tonic-gate Elf64_Phdr phdr; 14827c478bd9Sstevel@tonic-gate 14837c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 14847c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 14857c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 14867c478bd9Sstevel@tonic-gate phdr.p_offset = boff; 14877c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 14887c478bd9Sstevel@tonic-gate boff = doff; 14897c478bd9Sstevel@tonic-gate 149064e4e50aSKeith M Wesolowski if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) 14917c478bd9Sstevel@tonic-gate goto err; 14927c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 14937c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 14947c478bd9Sstevel@tonic-gate } 14957c478bd9Sstevel@tonic-gate 14967c478bd9Sstevel@tonic-gate /* 14977c478bd9Sstevel@tonic-gate * Construct the headers for each mapping and write out its data 14987c478bd9Sstevel@tonic-gate * if the content parameter indicates that it should be present 14997c478bd9Sstevel@tonic-gate * in the core file. 15007c478bd9Sstevel@tonic-gate */ 15017c478bd9Sstevel@tonic-gate if (Pmapping_iter(P, dump_map, &pgc) != 0) 15027c478bd9Sstevel@tonic-gate goto err; 15037c478bd9Sstevel@tonic-gate 15047c478bd9Sstevel@tonic-gate if (dump_sections(&pgc) != 0) 15057c478bd9Sstevel@tonic-gate goto err; 15067c478bd9Sstevel@tonic-gate 15077c478bd9Sstevel@tonic-gate if (write_shstrtab(P, &pgc) != 0) 15087c478bd9Sstevel@tonic-gate goto err; 15097c478bd9Sstevel@tonic-gate 15107c478bd9Sstevel@tonic-gate free(pgc.pgc_chunk); 15117c478bd9Sstevel@tonic-gate 15127c478bd9Sstevel@tonic-gate return (0); 15137c478bd9Sstevel@tonic-gate 15147c478bd9Sstevel@tonic-gate err: 15157c478bd9Sstevel@tonic-gate /* 15167c478bd9Sstevel@tonic-gate * Wipe out anything we may have written if there was an error. 15177c478bd9Sstevel@tonic-gate */ 15187c478bd9Sstevel@tonic-gate (void) ftruncate64(fd, 0); 15197c478bd9Sstevel@tonic-gate free(pgc.pgc_chunk); 1520*d2a70789SRichard Lowe 15217c478bd9Sstevel@tonic-gate return (-1); 15227c478bd9Sstevel@tonic-gate } 15237c478bd9Sstevel@tonic-gate 15247c478bd9Sstevel@tonic-gate static const char *content_str[] = { 15257c478bd9Sstevel@tonic-gate "stack", /* CC_CONTENT_STACK */ 15267c478bd9Sstevel@tonic-gate "heap", /* CC_CONTENT_HEAP */ 15277c478bd9Sstevel@tonic-gate "shfile", /* CC_CONTENT_SHFILE */ 15287c478bd9Sstevel@tonic-gate "shanon", /* CC_CONTENT_SHANON */ 15297c478bd9Sstevel@tonic-gate "text", /* CC_CONTENT_TEXT */ 15307c478bd9Sstevel@tonic-gate "data", /* CC_CONTENT_DATA */ 15317c478bd9Sstevel@tonic-gate "rodata", /* CC_CONTENT_RODATA */ 15327c478bd9Sstevel@tonic-gate "anon", /* CC_CONTENT_ANON */ 15337c478bd9Sstevel@tonic-gate "shm", /* CC_CONTENT_SHM */ 15347c478bd9Sstevel@tonic-gate "ism", /* CC_CONTENT_ISM */ 15357c478bd9Sstevel@tonic-gate "dism", /* CC_CONTENT_DISM */ 15367c478bd9Sstevel@tonic-gate "ctf", /* CC_CONTENT_CTF */ 15377c478bd9Sstevel@tonic-gate "symtab", /* CC_CONTENT_SYMTAB */ 15387c478bd9Sstevel@tonic-gate }; 15397c478bd9Sstevel@tonic-gate 15407c478bd9Sstevel@tonic-gate static uint_t ncontent_str = sizeof (content_str) / sizeof (content_str[0]); 15417c478bd9Sstevel@tonic-gate 15427c478bd9Sstevel@tonic-gate #define STREQ(a, b, n) (strlen(b) == (n) && strncmp(a, b, n) == 0) 15437c478bd9Sstevel@tonic-gate 15447c478bd9Sstevel@tonic-gate int 15457c478bd9Sstevel@tonic-gate proc_str2content(const char *str, core_content_t *cp) 15467c478bd9Sstevel@tonic-gate { 15477c478bd9Sstevel@tonic-gate const char *cur = str; 15487c478bd9Sstevel@tonic-gate int add = 1; 15497c478bd9Sstevel@tonic-gate core_content_t mask, content = 0; 15507c478bd9Sstevel@tonic-gate 15517c478bd9Sstevel@tonic-gate for (;;) { 15527c478bd9Sstevel@tonic-gate for (cur = str; isalpha(*cur); cur++) 15537c478bd9Sstevel@tonic-gate continue; 15547c478bd9Sstevel@tonic-gate 15557c478bd9Sstevel@tonic-gate if (STREQ(str, "default", cur - str)) { 15567c478bd9Sstevel@tonic-gate mask = CC_CONTENT_DEFAULT; 15577c478bd9Sstevel@tonic-gate } else if (STREQ(str, "all", cur - str)) { 15587c478bd9Sstevel@tonic-gate mask = CC_CONTENT_ALL; 15597c478bd9Sstevel@tonic-gate } else if (STREQ(str, "none", cur - str)) { 15607c478bd9Sstevel@tonic-gate mask = 0; 15617c478bd9Sstevel@tonic-gate } else { 15627c478bd9Sstevel@tonic-gate int i = 0; 15637c478bd9Sstevel@tonic-gate 15647c478bd9Sstevel@tonic-gate while (!STREQ(str, content_str[i], cur - str)) { 15657c478bd9Sstevel@tonic-gate i++; 15667c478bd9Sstevel@tonic-gate 15677c478bd9Sstevel@tonic-gate if (i >= ncontent_str) 15687c478bd9Sstevel@tonic-gate return (-1); 15697c478bd9Sstevel@tonic-gate } 15707c478bd9Sstevel@tonic-gate 15717c478bd9Sstevel@tonic-gate mask = (core_content_t)1 << i; 15727c478bd9Sstevel@tonic-gate } 15737c478bd9Sstevel@tonic-gate 15747c478bd9Sstevel@tonic-gate if (add) 15757c478bd9Sstevel@tonic-gate content |= mask; 15767c478bd9Sstevel@tonic-gate else 15777c478bd9Sstevel@tonic-gate content &= ~mask; 15787c478bd9Sstevel@tonic-gate 15797c478bd9Sstevel@tonic-gate switch (*cur) { 15807c478bd9Sstevel@tonic-gate case '\0': 15817c478bd9Sstevel@tonic-gate *cp = content; 15827c478bd9Sstevel@tonic-gate return (0); 15837c478bd9Sstevel@tonic-gate case '+': 15847c478bd9Sstevel@tonic-gate add = 1; 15857c478bd9Sstevel@tonic-gate break; 15867c478bd9Sstevel@tonic-gate case '-': 15877c478bd9Sstevel@tonic-gate add = 0; 15887c478bd9Sstevel@tonic-gate break; 15897c478bd9Sstevel@tonic-gate default: 15907c478bd9Sstevel@tonic-gate return (-1); 15917c478bd9Sstevel@tonic-gate } 15927c478bd9Sstevel@tonic-gate 15937c478bd9Sstevel@tonic-gate str = cur + 1; 15947c478bd9Sstevel@tonic-gate } 15957c478bd9Sstevel@tonic-gate } 15967c478bd9Sstevel@tonic-gate 15977c478bd9Sstevel@tonic-gate static int 15987c478bd9Sstevel@tonic-gate popc(core_content_t x) 15997c478bd9Sstevel@tonic-gate { 16007c478bd9Sstevel@tonic-gate int i; 16017c478bd9Sstevel@tonic-gate 16027c478bd9Sstevel@tonic-gate for (i = 0; x != 0; i++) 16037c478bd9Sstevel@tonic-gate x &= x - 1; 16047c478bd9Sstevel@tonic-gate 16057c478bd9Sstevel@tonic-gate return (i); 16067c478bd9Sstevel@tonic-gate } 16077c478bd9Sstevel@tonic-gate 16087c478bd9Sstevel@tonic-gate int 16097c478bd9Sstevel@tonic-gate proc_content2str(core_content_t content, char *buf, size_t size) 16107c478bd9Sstevel@tonic-gate { 16117c478bd9Sstevel@tonic-gate int nonecnt, defcnt, allcnt; 16127c478bd9Sstevel@tonic-gate core_content_t mask, bit; 16137c478bd9Sstevel@tonic-gate int first; 16147c478bd9Sstevel@tonic-gate uint_t index; 16157c478bd9Sstevel@tonic-gate size_t n, tot = 0; 16167c478bd9Sstevel@tonic-gate 16177c478bd9Sstevel@tonic-gate if (content == 0) 16187c478bd9Sstevel@tonic-gate return ((int)strlcpy(buf, "none", size)); 16197c478bd9Sstevel@tonic-gate 16207c478bd9Sstevel@tonic-gate if (content & ~CC_CONTENT_ALL) 16217c478bd9Sstevel@tonic-gate return ((int)strlcpy(buf, "<invalid>", size)); 16227c478bd9Sstevel@tonic-gate 16237c478bd9Sstevel@tonic-gate nonecnt = popc(content); 16247c478bd9Sstevel@tonic-gate defcnt = 1 + popc(content ^ CC_CONTENT_DEFAULT); 16257c478bd9Sstevel@tonic-gate allcnt = 1 + popc(content ^ CC_CONTENT_ALL); 16267c478bd9Sstevel@tonic-gate 16277c478bd9Sstevel@tonic-gate if (defcnt <= nonecnt && defcnt <= allcnt) { 16287c478bd9Sstevel@tonic-gate mask = content ^ CC_CONTENT_DEFAULT; 16297c478bd9Sstevel@tonic-gate first = 0; 16307c478bd9Sstevel@tonic-gate tot += (n = strlcpy(buf, "default", size)); 16317c478bd9Sstevel@tonic-gate if (n > size) 16327c478bd9Sstevel@tonic-gate n = size; 16337c478bd9Sstevel@tonic-gate buf += n; 16347c478bd9Sstevel@tonic-gate size -= n; 16357c478bd9Sstevel@tonic-gate } else if (allcnt < nonecnt) { 16367c478bd9Sstevel@tonic-gate mask = content ^ CC_CONTENT_ALL; 16377c478bd9Sstevel@tonic-gate first = 0; 16387c478bd9Sstevel@tonic-gate tot += (n = strlcpy(buf, "all", size)); 16397c478bd9Sstevel@tonic-gate if (n > size) 16407c478bd9Sstevel@tonic-gate n = size; 16417c478bd9Sstevel@tonic-gate buf += n; 16427c478bd9Sstevel@tonic-gate size -= n; 16437c478bd9Sstevel@tonic-gate } else { 16447c478bd9Sstevel@tonic-gate mask = content; 16457c478bd9Sstevel@tonic-gate first = 1; 16467c478bd9Sstevel@tonic-gate } 16477c478bd9Sstevel@tonic-gate 16487c478bd9Sstevel@tonic-gate while (mask != 0) { 16497c478bd9Sstevel@tonic-gate bit = mask ^ (mask & (mask - 1)); 16507c478bd9Sstevel@tonic-gate 16517c478bd9Sstevel@tonic-gate if (!first) { 16527c478bd9Sstevel@tonic-gate if (size > 1) { 16537c478bd9Sstevel@tonic-gate *buf = (bit & content) ? '+' : '-'; 16547c478bd9Sstevel@tonic-gate buf++; 16557c478bd9Sstevel@tonic-gate size--; 16567c478bd9Sstevel@tonic-gate } 16577c478bd9Sstevel@tonic-gate 16587c478bd9Sstevel@tonic-gate tot++; 16597c478bd9Sstevel@tonic-gate } 16607c478bd9Sstevel@tonic-gate index = popc(bit - 1); 16617c478bd9Sstevel@tonic-gate tot += (n = strlcpy(buf, content_str[index], size)); 16627c478bd9Sstevel@tonic-gate if (n > size) 16637c478bd9Sstevel@tonic-gate n = size; 16647c478bd9Sstevel@tonic-gate buf += n; 16657c478bd9Sstevel@tonic-gate size -= n; 16667c478bd9Sstevel@tonic-gate 16677c478bd9Sstevel@tonic-gate mask ^= bit; 16687c478bd9Sstevel@tonic-gate first = 0; 16697c478bd9Sstevel@tonic-gate } 16707c478bd9Sstevel@tonic-gate 16717c478bd9Sstevel@tonic-gate return ((int)tot); 16727c478bd9Sstevel@tonic-gate } 1673