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. 28*f971a346SBryan Cantrill * Copyright (c) 2013, Joyent, Inc. All rights reserved. 2934bdffbfSGarrett D'Amore */ 307c478bd9Sstevel@tonic-gate 312c797a4eSRoger A. Faulkner #define _STRUCTURED_PROC 1 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include <stdlib.h> 347c478bd9Sstevel@tonic-gate #include <ctype.h> 357c478bd9Sstevel@tonic-gate #include <string.h> 367c478bd9Sstevel@tonic-gate #include <strings.h> 377c478bd9Sstevel@tonic-gate #include <errno.h> 387c478bd9Sstevel@tonic-gate #include <procfs.h> 397c478bd9Sstevel@tonic-gate #include <priv.h> 407c478bd9Sstevel@tonic-gate #include <sys/elf.h> 417c478bd9Sstevel@tonic-gate #include <sys/machelf.h> 427c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 437c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 447c478bd9Sstevel@tonic-gate #include <sys/proc.h> 457c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate #include <sys/old_procfs.h> 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #include "Pcontrol.h" 507c478bd9Sstevel@tonic-gate #include "P32ton.h" 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate typedef enum { 5330da1432Sahl STR_NONE, 547c478bd9Sstevel@tonic-gate STR_CTF, 557c478bd9Sstevel@tonic-gate STR_SYMTAB, 567c478bd9Sstevel@tonic-gate STR_DYNSYM, 577c478bd9Sstevel@tonic-gate STR_STRTAB, 587c478bd9Sstevel@tonic-gate STR_DYNSTR, 597c478bd9Sstevel@tonic-gate STR_SHSTRTAB, 607c478bd9Sstevel@tonic-gate STR_NUM 617c478bd9Sstevel@tonic-gate } shstrtype_t; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate static const char *shstrtab_data[] = { 6430da1432Sahl "", 657c478bd9Sstevel@tonic-gate ".SUNW_ctf", 667c478bd9Sstevel@tonic-gate ".symtab", 677c478bd9Sstevel@tonic-gate ".dynsym", 687c478bd9Sstevel@tonic-gate ".strtab", 697c478bd9Sstevel@tonic-gate ".dynstr", 707c478bd9Sstevel@tonic-gate ".shstrtab" 717c478bd9Sstevel@tonic-gate }; 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate typedef struct shstrtab { 747c478bd9Sstevel@tonic-gate int sst_ndx[STR_NUM]; 757c478bd9Sstevel@tonic-gate int sst_cur; 767c478bd9Sstevel@tonic-gate } shstrtab_t; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate typedef struct { 797c478bd9Sstevel@tonic-gate struct ps_prochandle *P; 807c478bd9Sstevel@tonic-gate int pgc_fd; 817c478bd9Sstevel@tonic-gate off64_t *pgc_poff; 827c478bd9Sstevel@tonic-gate off64_t *pgc_soff; 837c478bd9Sstevel@tonic-gate off64_t *pgc_doff; 847c478bd9Sstevel@tonic-gate core_content_t pgc_content; 857c478bd9Sstevel@tonic-gate void *pgc_chunk; 867c478bd9Sstevel@tonic-gate size_t pgc_chunksz; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate shstrtab_t pgc_shstrtab; 897c478bd9Sstevel@tonic-gate } pgcore_t; 907c478bd9Sstevel@tonic-gate 9134bdffbfSGarrett D'Amore typedef struct { 9234bdffbfSGarrett D'Amore int fd_fd; 9334bdffbfSGarrett D'Amore off64_t *fd_doff; 9434bdffbfSGarrett D'Amore } fditer_t; 9534bdffbfSGarrett D'Amore 967c478bd9Sstevel@tonic-gate static void 977c478bd9Sstevel@tonic-gate shstrtab_init(shstrtab_t *s) 987c478bd9Sstevel@tonic-gate { 997c478bd9Sstevel@tonic-gate bzero(&s->sst_ndx, sizeof (s->sst_ndx)); 1007c478bd9Sstevel@tonic-gate s->sst_cur = 1; 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate static int 1047c478bd9Sstevel@tonic-gate shstrtab_ndx(shstrtab_t *s, shstrtype_t type) 1057c478bd9Sstevel@tonic-gate { 1067c478bd9Sstevel@tonic-gate int ret; 1077c478bd9Sstevel@tonic-gate 10830da1432Sahl if ((ret = s->sst_ndx[type]) != 0 || type == STR_NONE) 1097c478bd9Sstevel@tonic-gate return (ret); 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate ret = s->sst_ndx[type] = s->sst_cur; 1127c478bd9Sstevel@tonic-gate s->sst_cur += strlen(shstrtab_data[type]) + 1; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate return (ret); 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate static size_t 1187c478bd9Sstevel@tonic-gate shstrtab_size(const shstrtab_t *s) 1197c478bd9Sstevel@tonic-gate { 1207c478bd9Sstevel@tonic-gate return (s->sst_cur); 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate int 1247c478bd9Sstevel@tonic-gate Pgcore(struct ps_prochandle *P, const char *fname, core_content_t content) 1257c478bd9Sstevel@tonic-gate { 1267c478bd9Sstevel@tonic-gate int fd; 1277c478bd9Sstevel@tonic-gate int err; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate if ((fd = creat64(fname, 0666)) < 0) 1307c478bd9Sstevel@tonic-gate return (-1); 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate if ((err = Pfgcore(P, fd, content)) != 0) { 1337c478bd9Sstevel@tonic-gate (void) close(fd); 1347c478bd9Sstevel@tonic-gate (void) unlink(fname); 1357c478bd9Sstevel@tonic-gate return (err); 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate return (close(fd)); 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate /* 1427c478bd9Sstevel@tonic-gate * Since we don't want to use the old-school procfs interfaces, we use the 1437c478bd9Sstevel@tonic-gate * new-style data structures we already have to construct the old-style 1447c478bd9Sstevel@tonic-gate * data structures. We include these data structures in core files for 1457c478bd9Sstevel@tonic-gate * backward compatability. 1467c478bd9Sstevel@tonic-gate */ 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate static void 1497c478bd9Sstevel@tonic-gate mkprstatus(struct ps_prochandle *P, const lwpstatus_t *lsp, 1507c478bd9Sstevel@tonic-gate const lwpsinfo_t *lip, prstatus_t *psp) 1517c478bd9Sstevel@tonic-gate { 1527c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STOPPED) 1557c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0001; 1567c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISTOP) 1577c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0002; 1587c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_DSTOP) 1597c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0004; 1607c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLEEP) 1617c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0008; 1627c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_FORK) 1637c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0010; 1647c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_RLC) 1657c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0020; 1667c478bd9Sstevel@tonic-gate /* 1677c478bd9Sstevel@tonic-gate * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set; 1687c478bd9Sstevel@tonic-gate * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>. 1697c478bd9Sstevel@tonic-gate */ 1707c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PCINVAL) 1717c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0080; 1727c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISSYS) 1737c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0100; 1747c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STEP) 1757c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0200; 1767c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_KLC) 1777c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0400; 1787c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASYNC) 1797c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0800; 1807c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PTRACE) 1817c478bd9Sstevel@tonic-gate psp->pr_flags = 0x1000; 1827c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_MSACCT) 1837c478bd9Sstevel@tonic-gate psp->pr_flags = 0x2000; 1847c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_BPTADJ) 1857c478bd9Sstevel@tonic-gate psp->pr_flags = 0x4000; 1867c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLWP) 1877c478bd9Sstevel@tonic-gate psp->pr_flags = 0x8000; 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate psp->pr_why = lsp->pr_why; 1907c478bd9Sstevel@tonic-gate psp->pr_what = lsp->pr_what; 1917c478bd9Sstevel@tonic-gate psp->pr_info = lsp->pr_info; 1927c478bd9Sstevel@tonic-gate psp->pr_cursig = lsp->pr_cursig; 1937c478bd9Sstevel@tonic-gate psp->pr_nlwp = P->status.pr_nlwp; 1947c478bd9Sstevel@tonic-gate psp->pr_sigpend = P->status.pr_sigpend; 1957c478bd9Sstevel@tonic-gate psp->pr_sighold = lsp->pr_lwphold; 1967c478bd9Sstevel@tonic-gate psp->pr_altstack = lsp->pr_altstack; 1977c478bd9Sstevel@tonic-gate psp->pr_action = lsp->pr_action; 1987c478bd9Sstevel@tonic-gate psp->pr_pid = P->status.pr_pid; 1997c478bd9Sstevel@tonic-gate psp->pr_ppid = P->status.pr_ppid; 2007c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->status.pr_pgid; 2017c478bd9Sstevel@tonic-gate psp->pr_sid = P->status.pr_sid; 2027c478bd9Sstevel@tonic-gate psp->pr_utime = P->status.pr_utime; 2037c478bd9Sstevel@tonic-gate psp->pr_stime = P->status.pr_stime; 2047c478bd9Sstevel@tonic-gate psp->pr_cutime = P->status.pr_cutime; 2057c478bd9Sstevel@tonic-gate psp->pr_cstime = P->status.pr_cstime; 2067c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname)); 2077c478bd9Sstevel@tonic-gate psp->pr_syscall = lsp->pr_syscall; 2087c478bd9Sstevel@tonic-gate psp->pr_nsysarg = lsp->pr_nsysarg; 2097c478bd9Sstevel@tonic-gate bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg)); 2107c478bd9Sstevel@tonic-gate psp->pr_who = lsp->pr_lwpid; 2117c478bd9Sstevel@tonic-gate psp->pr_lwppend = lsp->pr_lwppend; 2127c478bd9Sstevel@tonic-gate psp->pr_oldcontext = (ucontext_t *)lsp->pr_oldcontext; 2137c478bd9Sstevel@tonic-gate psp->pr_brkbase = (caddr_t)P->status.pr_brkbase; 2147c478bd9Sstevel@tonic-gate psp->pr_brksize = P->status.pr_brksize; 2157c478bd9Sstevel@tonic-gate psp->pr_stkbase = (caddr_t)P->status.pr_stkbase; 2167c478bd9Sstevel@tonic-gate psp->pr_stksize = P->status.pr_stksize; 2177c478bd9Sstevel@tonic-gate psp->pr_processor = (short)lip->pr_onpro; 2187c478bd9Sstevel@tonic-gate psp->pr_bind = (short)lip->pr_bindpro; 2197c478bd9Sstevel@tonic-gate psp->pr_instr = lsp->pr_instr; 2207c478bd9Sstevel@tonic-gate bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg)); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate static void 2247c478bd9Sstevel@tonic-gate mkprpsinfo(struct ps_prochandle *P, prpsinfo_t *psp) 2257c478bd9Sstevel@tonic-gate { 2267c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 2277c478bd9Sstevel@tonic-gate psp->pr_state = P->psinfo.pr_lwp.pr_state; 2287c478bd9Sstevel@tonic-gate psp->pr_sname = P->psinfo.pr_lwp.pr_sname; 2297c478bd9Sstevel@tonic-gate psp->pr_zomb = (psp->pr_state == SZOMB); 2307c478bd9Sstevel@tonic-gate psp->pr_nice = P->psinfo.pr_lwp.pr_nice; 2317c478bd9Sstevel@tonic-gate psp->pr_flag = P->psinfo.pr_lwp.pr_flag; 2327c478bd9Sstevel@tonic-gate psp->pr_uid = P->psinfo.pr_uid; 2337c478bd9Sstevel@tonic-gate psp->pr_gid = P->psinfo.pr_gid; 2347c478bd9Sstevel@tonic-gate psp->pr_pid = P->psinfo.pr_pid; 2357c478bd9Sstevel@tonic-gate psp->pr_ppid = P->psinfo.pr_ppid; 2367c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->psinfo.pr_pgid; 2377c478bd9Sstevel@tonic-gate psp->pr_sid = P->psinfo.pr_sid; 2387c478bd9Sstevel@tonic-gate psp->pr_addr = (caddr_t)P->psinfo.pr_addr; 2397c478bd9Sstevel@tonic-gate psp->pr_size = P->psinfo.pr_size; 2407c478bd9Sstevel@tonic-gate psp->pr_rssize = P->psinfo.pr_rssize; 2417c478bd9Sstevel@tonic-gate psp->pr_wchan = (caddr_t)P->psinfo.pr_lwp.pr_wchan; 2427c478bd9Sstevel@tonic-gate psp->pr_start = P->psinfo.pr_start; 2437c478bd9Sstevel@tonic-gate psp->pr_time = P->psinfo.pr_time; 2447c478bd9Sstevel@tonic-gate psp->pr_pri = P->psinfo.pr_lwp.pr_pri; 2457c478bd9Sstevel@tonic-gate psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri; 2467c478bd9Sstevel@tonic-gate psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu; 2477c478bd9Sstevel@tonic-gate psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev); 2487c478bd9Sstevel@tonic-gate psp->pr_lttydev = P->psinfo.pr_ttydev; 2497c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname, 2507c478bd9Sstevel@tonic-gate sizeof (psp->pr_clname)); 2517c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_fname, P->psinfo.pr_fname, 2527c478bd9Sstevel@tonic-gate sizeof (psp->pr_fname)); 2537c478bd9Sstevel@tonic-gate bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs, 2547c478bd9Sstevel@tonic-gate sizeof (psp->pr_psargs)); 2557c478bd9Sstevel@tonic-gate psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall; 2567c478bd9Sstevel@tonic-gate psp->pr_ctime = P->psinfo.pr_ctime; 2577c478bd9Sstevel@tonic-gate psp->pr_bysize = psp->pr_size * PAGESIZE; 2587c478bd9Sstevel@tonic-gate psp->pr_byrssize = psp->pr_rssize * PAGESIZE; 2597c478bd9Sstevel@tonic-gate psp->pr_argc = P->psinfo.pr_argc; 2607c478bd9Sstevel@tonic-gate psp->pr_argv = (char **)P->psinfo.pr_argv; 2617c478bd9Sstevel@tonic-gate psp->pr_envp = (char **)P->psinfo.pr_envp; 2627c478bd9Sstevel@tonic-gate psp->pr_wstat = P->psinfo.pr_wstat; 2637c478bd9Sstevel@tonic-gate psp->pr_pctcpu = P->psinfo.pr_pctcpu; 2647c478bd9Sstevel@tonic-gate psp->pr_pctmem = P->psinfo.pr_pctmem; 2657c478bd9Sstevel@tonic-gate psp->pr_euid = P->psinfo.pr_euid; 2667c478bd9Sstevel@tonic-gate psp->pr_egid = P->psinfo.pr_egid; 2677c478bd9Sstevel@tonic-gate psp->pr_aslwpid = 0; 2687c478bd9Sstevel@tonic-gate psp->pr_dmodel = P->psinfo.pr_dmodel; 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate #ifdef _LP64 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate static void 2747c478bd9Sstevel@tonic-gate mkprstatus32(struct ps_prochandle *P, const lwpstatus_t *lsp, 2757c478bd9Sstevel@tonic-gate const lwpsinfo_t *lip, prstatus32_t *psp) 2767c478bd9Sstevel@tonic-gate { 2777c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STOPPED) 2807c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0001; 2817c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISTOP) 2827c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0002; 2837c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_DSTOP) 2847c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0004; 2857c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLEEP) 2867c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0008; 2877c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_FORK) 2887c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0010; 2897c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_RLC) 2907c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0020; 2917c478bd9Sstevel@tonic-gate /* 2927c478bd9Sstevel@tonic-gate * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set; 2937c478bd9Sstevel@tonic-gate * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>. 2947c478bd9Sstevel@tonic-gate */ 2957c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PCINVAL) 2967c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0080; 2977c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ISSYS) 2987c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0100; 2997c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_STEP) 3007c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0200; 3017c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_KLC) 3027c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0400; 3037c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASYNC) 3047c478bd9Sstevel@tonic-gate psp->pr_flags = 0x0800; 3057c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_PTRACE) 3067c478bd9Sstevel@tonic-gate psp->pr_flags = 0x1000; 3077c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_MSACCT) 3087c478bd9Sstevel@tonic-gate psp->pr_flags = 0x2000; 3097c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_BPTADJ) 3107c478bd9Sstevel@tonic-gate psp->pr_flags = 0x4000; 3117c478bd9Sstevel@tonic-gate if (lsp->pr_flags & PR_ASLWP) 3127c478bd9Sstevel@tonic-gate psp->pr_flags = 0x8000; 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate psp->pr_why = lsp->pr_why; 3157c478bd9Sstevel@tonic-gate psp->pr_what = lsp->pr_what; 3167c478bd9Sstevel@tonic-gate siginfo_n_to_32(&lsp->pr_info, &psp->pr_info); 3177c478bd9Sstevel@tonic-gate psp->pr_cursig = lsp->pr_cursig; 3187c478bd9Sstevel@tonic-gate psp->pr_nlwp = P->status.pr_nlwp; 3197c478bd9Sstevel@tonic-gate psp->pr_sigpend = P->status.pr_sigpend; 3207c478bd9Sstevel@tonic-gate psp->pr_sighold = lsp->pr_lwphold; 3217c478bd9Sstevel@tonic-gate stack_n_to_32(&lsp->pr_altstack, &psp->pr_altstack); 3227c478bd9Sstevel@tonic-gate sigaction_n_to_32(&lsp->pr_action, &psp->pr_action); 3237c478bd9Sstevel@tonic-gate psp->pr_pid = P->status.pr_pid; 3247c478bd9Sstevel@tonic-gate psp->pr_ppid = P->status.pr_ppid; 3257c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->status.pr_pgid; 3267c478bd9Sstevel@tonic-gate psp->pr_sid = P->status.pr_sid; 3277c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_utime, &psp->pr_utime); 3287c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_stime, &psp->pr_stime); 3297c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_cutime, &psp->pr_cutime); 3307c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->status.pr_cstime, &psp->pr_cstime); 3317c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname)); 3327c478bd9Sstevel@tonic-gate psp->pr_syscall = lsp->pr_syscall; 3337c478bd9Sstevel@tonic-gate psp->pr_nsysarg = lsp->pr_nsysarg; 3342c797a4eSRoger A. Faulkner bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg)); 3352c797a4eSRoger A. Faulkner psp->pr_who = lsp->pr_lwpid; 3367c478bd9Sstevel@tonic-gate psp->pr_lwppend = lsp->pr_lwppend; 3377c478bd9Sstevel@tonic-gate psp->pr_oldcontext = (caddr32_t)lsp->pr_oldcontext; 3387c478bd9Sstevel@tonic-gate psp->pr_brkbase = (caddr32_t)P->status.pr_brkbase; 3397c478bd9Sstevel@tonic-gate psp->pr_brksize = P->status.pr_brksize; 3407c478bd9Sstevel@tonic-gate psp->pr_stkbase = (caddr32_t)P->status.pr_stkbase; 3417c478bd9Sstevel@tonic-gate psp->pr_stksize = P->status.pr_stksize; 3427c478bd9Sstevel@tonic-gate psp->pr_processor = (short)lip->pr_onpro; 3437c478bd9Sstevel@tonic-gate psp->pr_bind = (short)lip->pr_bindpro; 3447c478bd9Sstevel@tonic-gate psp->pr_instr = lsp->pr_instr; 3457c478bd9Sstevel@tonic-gate bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg)); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate static void 3497c478bd9Sstevel@tonic-gate mkprpsinfo32(struct ps_prochandle *P, prpsinfo32_t *psp) 3507c478bd9Sstevel@tonic-gate { 3517c478bd9Sstevel@tonic-gate bzero(psp, sizeof (*psp)); 3527c478bd9Sstevel@tonic-gate psp->pr_state = P->psinfo.pr_lwp.pr_state; 3537c478bd9Sstevel@tonic-gate psp->pr_sname = P->psinfo.pr_lwp.pr_sname; 3547c478bd9Sstevel@tonic-gate psp->pr_zomb = (psp->pr_state == SZOMB); 3557c478bd9Sstevel@tonic-gate psp->pr_nice = P->psinfo.pr_lwp.pr_nice; 3567c478bd9Sstevel@tonic-gate psp->pr_flag = P->psinfo.pr_lwp.pr_flag; 3577c478bd9Sstevel@tonic-gate psp->pr_uid = P->psinfo.pr_uid; 3587c478bd9Sstevel@tonic-gate psp->pr_gid = P->psinfo.pr_gid; 3597c478bd9Sstevel@tonic-gate psp->pr_pid = P->psinfo.pr_pid; 3607c478bd9Sstevel@tonic-gate psp->pr_ppid = P->psinfo.pr_ppid; 3617c478bd9Sstevel@tonic-gate psp->pr_pgrp = P->psinfo.pr_pgid; 3627c478bd9Sstevel@tonic-gate psp->pr_sid = P->psinfo.pr_sid; 3637c478bd9Sstevel@tonic-gate psp->pr_addr = (caddr32_t)P->psinfo.pr_addr; 3647c478bd9Sstevel@tonic-gate psp->pr_size = P->psinfo.pr_size; 3657c478bd9Sstevel@tonic-gate psp->pr_rssize = P->psinfo.pr_rssize; 3667c478bd9Sstevel@tonic-gate psp->pr_wchan = (caddr32_t)P->psinfo.pr_lwp.pr_wchan; 3677c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_start, &psp->pr_start); 3687c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_time, &psp->pr_time); 3697c478bd9Sstevel@tonic-gate psp->pr_pri = P->psinfo.pr_lwp.pr_pri; 3707c478bd9Sstevel@tonic-gate psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri; 3717c478bd9Sstevel@tonic-gate psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu; 3727c478bd9Sstevel@tonic-gate psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev); 3737c478bd9Sstevel@tonic-gate psp->pr_lttydev = prcmpldev(P->psinfo.pr_ttydev); 3747c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname, 3757c478bd9Sstevel@tonic-gate sizeof (psp->pr_clname)); 3767c478bd9Sstevel@tonic-gate (void) strncpy(psp->pr_fname, P->psinfo.pr_fname, 3777c478bd9Sstevel@tonic-gate sizeof (psp->pr_fname)); 3787c478bd9Sstevel@tonic-gate bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs, 3797c478bd9Sstevel@tonic-gate sizeof (psp->pr_psargs)); 3807c478bd9Sstevel@tonic-gate psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall; 3817c478bd9Sstevel@tonic-gate timestruc_n_to_32(&P->psinfo.pr_ctime, &psp->pr_ctime); 3827c478bd9Sstevel@tonic-gate psp->pr_bysize = psp->pr_size * PAGESIZE; 3837c478bd9Sstevel@tonic-gate psp->pr_byrssize = psp->pr_rssize * PAGESIZE; 3847c478bd9Sstevel@tonic-gate psp->pr_argc = P->psinfo.pr_argc; 3857c478bd9Sstevel@tonic-gate psp->pr_argv = (caddr32_t)P->psinfo.pr_argv; 3867c478bd9Sstevel@tonic-gate psp->pr_envp = (caddr32_t)P->psinfo.pr_envp; 3877c478bd9Sstevel@tonic-gate psp->pr_wstat = P->psinfo.pr_wstat; 3887c478bd9Sstevel@tonic-gate psp->pr_pctcpu = P->psinfo.pr_pctcpu; 3897c478bd9Sstevel@tonic-gate psp->pr_pctmem = P->psinfo.pr_pctmem; 3907c478bd9Sstevel@tonic-gate psp->pr_euid = P->psinfo.pr_euid; 3917c478bd9Sstevel@tonic-gate psp->pr_egid = P->psinfo.pr_egid; 3927c478bd9Sstevel@tonic-gate psp->pr_aslwpid = 0; 3937c478bd9Sstevel@tonic-gate psp->pr_dmodel = P->psinfo.pr_dmodel; 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate static int 3997c478bd9Sstevel@tonic-gate write_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp) 4007c478bd9Sstevel@tonic-gate { 4017c478bd9Sstevel@tonic-gate /* 4027c478bd9Sstevel@tonic-gate * Note headers are the same regardless of the data model of the 4037c478bd9Sstevel@tonic-gate * ELF file; we arbitrarily use Elf64_Nhdr here. 4047c478bd9Sstevel@tonic-gate */ 4057c478bd9Sstevel@tonic-gate struct { 4067c478bd9Sstevel@tonic-gate Elf64_Nhdr nhdr; 4077c478bd9Sstevel@tonic-gate char name[8]; 4087c478bd9Sstevel@tonic-gate } n; 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate bzero(&n, sizeof (n)); 4117c478bd9Sstevel@tonic-gate bcopy("CORE", n.name, 4); 4127c478bd9Sstevel@tonic-gate n.nhdr.n_type = type; 4137c478bd9Sstevel@tonic-gate n.nhdr.n_namesz = 5; 4147c478bd9Sstevel@tonic-gate n.nhdr.n_descsz = roundup(descsz, 4); 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate if (pwrite64(fd, &n, sizeof (n), *offp) != sizeof (n)) 4177c478bd9Sstevel@tonic-gate return (-1); 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate *offp += sizeof (n); 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate if (pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != n.nhdr.n_descsz) 4227c478bd9Sstevel@tonic-gate return (-1); 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate *offp += n.nhdr.n_descsz; 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate return (0); 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate static int 4307c478bd9Sstevel@tonic-gate old_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip) 4317c478bd9Sstevel@tonic-gate { 4327c478bd9Sstevel@tonic-gate pgcore_t *pgc = data; 4337c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate /* 4367c478bd9Sstevel@tonic-gate * Legacy core files don't contain information about zombie LWPs. 4377c478bd9Sstevel@tonic-gate * We use Plwp_iter_all() so that we get the lwpsinfo_t structure 4387c478bd9Sstevel@tonic-gate * more cheaply. 4397c478bd9Sstevel@tonic-gate */ 4407c478bd9Sstevel@tonic-gate if (lsp == NULL) 4417c478bd9Sstevel@tonic-gate return (0); 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 4447c478bd9Sstevel@tonic-gate prstatus_t prstatus; 4457c478bd9Sstevel@tonic-gate mkprstatus(P, lsp, lip, &prstatus); 4467c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRSTATUS, &prstatus, 4477c478bd9Sstevel@tonic-gate sizeof (prstatus_t), pgc->pgc_doff) != 0) 4487c478bd9Sstevel@tonic-gate return (0); 4497c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRFPREG, &lsp->pr_fpreg, 4507c478bd9Sstevel@tonic-gate sizeof (prfpregset_t), pgc->pgc_doff) != 0) 4517c478bd9Sstevel@tonic-gate return (1); 4527c478bd9Sstevel@tonic-gate #ifdef _LP64 4537c478bd9Sstevel@tonic-gate } else { 4547c478bd9Sstevel@tonic-gate prstatus32_t pr32; 4557c478bd9Sstevel@tonic-gate prfpregset32_t pf32; 4567c478bd9Sstevel@tonic-gate mkprstatus32(P, lsp, lip, &pr32); 4577c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRSTATUS, &pr32, 4587c478bd9Sstevel@tonic-gate sizeof (prstatus32_t), pgc->pgc_doff) != 0) 4597c478bd9Sstevel@tonic-gate return (1); 4607c478bd9Sstevel@tonic-gate prfpregset_n_to_32(&lsp->pr_fpreg, &pf32); 4617c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRFPREG, &pf32, 4627c478bd9Sstevel@tonic-gate sizeof (prfpregset32_t), pgc->pgc_doff) != 0) 4637c478bd9Sstevel@tonic-gate return (1); 4647c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 4657c478bd9Sstevel@tonic-gate } 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate #ifdef sparc 4687c478bd9Sstevel@tonic-gate { 4697c478bd9Sstevel@tonic-gate prxregset_t xregs; 4707c478bd9Sstevel@tonic-gate if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0 && 4717c478bd9Sstevel@tonic-gate write_note(pgc->pgc_fd, NT_PRXREG, &xregs, 4727c478bd9Sstevel@tonic-gate sizeof (prxregset_t), pgc->pgc_doff) != 0) 4737c478bd9Sstevel@tonic-gate return (1); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate #endif /* sparc */ 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate return (0); 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate static int 4817c478bd9Sstevel@tonic-gate new_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip) 4827c478bd9Sstevel@tonic-gate { 4837c478bd9Sstevel@tonic-gate pgcore_t *pgc = data; 4847c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 485*f971a346SBryan Cantrill psinfo_t ps; 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate /* 4887c478bd9Sstevel@tonic-gate * If lsp is NULL this indicates that this is a zombie LWP in 4897c478bd9Sstevel@tonic-gate * which case we dump only the lwpsinfo_t structure and none of 4907c478bd9Sstevel@tonic-gate * the other ancillary LWP state data. 4917c478bd9Sstevel@tonic-gate */ 4927c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 4937c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip, 4947c478bd9Sstevel@tonic-gate sizeof (lwpsinfo_t), pgc->pgc_doff) != 0) 4957c478bd9Sstevel@tonic-gate return (1); 4967c478bd9Sstevel@tonic-gate if (lsp == NULL) 4977c478bd9Sstevel@tonic-gate return (0); 4987c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp, 4997c478bd9Sstevel@tonic-gate sizeof (lwpstatus_t), pgc->pgc_doff) != 0) 5007c478bd9Sstevel@tonic-gate return (1); 5017c478bd9Sstevel@tonic-gate #ifdef _LP64 5027c478bd9Sstevel@tonic-gate } else { 5037c478bd9Sstevel@tonic-gate lwpsinfo32_t li32; 5047c478bd9Sstevel@tonic-gate lwpstatus32_t ls32; 5057c478bd9Sstevel@tonic-gate lwpsinfo_n_to_32(lip, &li32); 5067c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32, 5077c478bd9Sstevel@tonic-gate sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0) 5087c478bd9Sstevel@tonic-gate return (1); 5097c478bd9Sstevel@tonic-gate if (lsp == NULL) 5107c478bd9Sstevel@tonic-gate return (0); 5117c478bd9Sstevel@tonic-gate lwpstatus_n_to_32(lsp, &ls32); 5127c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32, 5137c478bd9Sstevel@tonic-gate sizeof (lwpstatus32_t), pgc->pgc_doff) != 0) 5147c478bd9Sstevel@tonic-gate return (1); 5157c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 5167c478bd9Sstevel@tonic-gate } 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate #ifdef sparc 5197c478bd9Sstevel@tonic-gate { 5207c478bd9Sstevel@tonic-gate prxregset_t xregs; 5217c478bd9Sstevel@tonic-gate gwindows_t gwins; 5227c478bd9Sstevel@tonic-gate size_t size; 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0) { 5257c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_PRXREG, &xregs, 5267c478bd9Sstevel@tonic-gate sizeof (prxregset_t), pgc->pgc_doff) != 0) 5277c478bd9Sstevel@tonic-gate return (1); 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate if (Plwp_getgwindows(P, lsp->pr_lwpid, &gwins) == 0 && 5317c478bd9Sstevel@tonic-gate gwins.wbcnt > 0) { 5327c478bd9Sstevel@tonic-gate size = sizeof (gwins) - sizeof (gwins.wbuf) + 5337c478bd9Sstevel@tonic-gate gwins.wbcnt * sizeof (gwins.wbuf[0]); 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_GWINDOWS, &gwins, size, 5367c478bd9Sstevel@tonic-gate pgc->pgc_doff) != 0) 5377c478bd9Sstevel@tonic-gate return (1); 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate } 5417c478bd9Sstevel@tonic-gate #ifdef __sparcv9 5427c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_LP64) { 5437c478bd9Sstevel@tonic-gate asrset_t asrs; 5447c478bd9Sstevel@tonic-gate if (Plwp_getasrs(P, lsp->pr_lwpid, asrs) == 0) { 5457c478bd9Sstevel@tonic-gate if (write_note(pgc->pgc_fd, NT_ASRS, &asrs, 5467c478bd9Sstevel@tonic-gate sizeof (asrset_t), pgc->pgc_doff) != 0) 5477c478bd9Sstevel@tonic-gate return (1); 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate #endif /* __sparcv9 */ 5517c478bd9Sstevel@tonic-gate #endif /* sparc */ 5527c478bd9Sstevel@tonic-gate 553*f971a346SBryan Cantrill if (!(lsp->pr_flags & PR_AGENT)) 554*f971a346SBryan Cantrill return (0); 555*f971a346SBryan Cantrill 556*f971a346SBryan Cantrill if (Plwp_getspymaster(P, lsp->pr_lwpid, &ps) != 0) 557*f971a346SBryan Cantrill return (0); 558*f971a346SBryan Cantrill 559*f971a346SBryan Cantrill if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 560*f971a346SBryan Cantrill if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps, 561*f971a346SBryan Cantrill sizeof (psinfo_t), pgc->pgc_doff) != 0) 562*f971a346SBryan Cantrill return (1); 563*f971a346SBryan Cantrill #ifdef _LP64 564*f971a346SBryan Cantrill } else { 565*f971a346SBryan Cantrill psinfo32_t ps32; 566*f971a346SBryan Cantrill psinfo_n_to_32(&ps, &ps32); 567*f971a346SBryan Cantrill if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps32, 568*f971a346SBryan Cantrill sizeof (psinfo32_t), pgc->pgc_doff) != 0) 569*f971a346SBryan Cantrill return (1); 570*f971a346SBryan Cantrill #endif /* _LP64 */ 571*f971a346SBryan Cantrill } 572*f971a346SBryan Cantrill 573*f971a346SBryan Cantrill 5747c478bd9Sstevel@tonic-gate return (0); 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate 57734bdffbfSGarrett D'Amore static int 57834bdffbfSGarrett D'Amore iter_fd(void *data, prfdinfo_t *fdinfo) 57934bdffbfSGarrett D'Amore { 58034bdffbfSGarrett D'Amore fditer_t *iter = data; 58134bdffbfSGarrett D'Amore 58234bdffbfSGarrett D'Amore if (write_note(iter->fd_fd, NT_FDINFO, fdinfo, 58334bdffbfSGarrett D'Amore sizeof (*fdinfo), iter->fd_doff) != 0) 58434bdffbfSGarrett D'Amore return (1); 58534bdffbfSGarrett D'Amore return (0); 58634bdffbfSGarrett D'Amore } 58734bdffbfSGarrett D'Amore 5887c478bd9Sstevel@tonic-gate static uint_t 5897c478bd9Sstevel@tonic-gate count_sections(pgcore_t *pgc) 5907c478bd9Sstevel@tonic-gate { 5917c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 5927c478bd9Sstevel@tonic-gate file_info_t *fptr; 5937c478bd9Sstevel@tonic-gate uint_t cnt; 5947c478bd9Sstevel@tonic-gate uint_t nshdrs = 0; 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB))) 5977c478bd9Sstevel@tonic-gate return (0); 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate fptr = list_next(&P->file_head); 6007c478bd9Sstevel@tonic-gate for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) { 6017c478bd9Sstevel@tonic-gate int hit_symtab = 0; 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate Pbuild_file_symtab(P, fptr); 6047c478bd9Sstevel@tonic-gate 6057c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_CTF) && 6067c478bd9Sstevel@tonic-gate Pbuild_file_ctf(P, fptr) != NULL) { 6077c478bd9Sstevel@tonic-gate sym_tbl_t *sym; 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate nshdrs++; 6107c478bd9Sstevel@tonic-gate 6117c478bd9Sstevel@tonic-gate if (fptr->file_ctf_dyn) { 6127c478bd9Sstevel@tonic-gate sym = &fptr->file_dynsym; 6137c478bd9Sstevel@tonic-gate } else { 6147c478bd9Sstevel@tonic-gate sym = &fptr->file_symtab; 6157c478bd9Sstevel@tonic-gate hit_symtab = 1; 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate 618d51e9074Sab196087 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 && 6197c478bd9Sstevel@tonic-gate sym->sym_strs != NULL) 6207c478bd9Sstevel@tonic-gate nshdrs += 2; 6217c478bd9Sstevel@tonic-gate } 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab && 624d51e9074Sab196087 fptr->file_symtab.sym_data_pri != NULL && 6257c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_symn != 0 && 6267c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_strs != NULL) { 6277c478bd9Sstevel@tonic-gate nshdrs += 2; 6287c478bd9Sstevel@tonic-gate } 6297c478bd9Sstevel@tonic-gate } 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate return (nshdrs == 0 ? 0 : nshdrs + 2); 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate static int 6357c478bd9Sstevel@tonic-gate write_shdr(pgcore_t *pgc, shstrtype_t name, uint_t type, ulong_t flags, 6367c478bd9Sstevel@tonic-gate uintptr_t addr, ulong_t offset, size_t size, uint_t link, uint_t info, 6377c478bd9Sstevel@tonic-gate uintptr_t addralign, uintptr_t entsize) 6387c478bd9Sstevel@tonic-gate { 6397c478bd9Sstevel@tonic-gate if (pgc->P->status.pr_dmodel == PR_MODEL_ILP32) { 6407c478bd9Sstevel@tonic-gate Elf32_Shdr shdr; 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 6437c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name); 6447c478bd9Sstevel@tonic-gate shdr.sh_type = type; 6457c478bd9Sstevel@tonic-gate shdr.sh_flags = flags; 6467c478bd9Sstevel@tonic-gate shdr.sh_addr = (Elf32_Addr)addr; 6477c478bd9Sstevel@tonic-gate shdr.sh_offset = offset; 6487c478bd9Sstevel@tonic-gate shdr.sh_size = size; 6497c478bd9Sstevel@tonic-gate shdr.sh_link = link; 6507c478bd9Sstevel@tonic-gate shdr.sh_info = info; 6517c478bd9Sstevel@tonic-gate shdr.sh_addralign = addralign; 6527c478bd9Sstevel@tonic-gate shdr.sh_entsize = entsize; 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 6557c478bd9Sstevel@tonic-gate *pgc->pgc_soff) != sizeof (shdr)) 6567c478bd9Sstevel@tonic-gate return (-1); 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 6597c478bd9Sstevel@tonic-gate #ifdef _LP64 6607c478bd9Sstevel@tonic-gate } else { 6617c478bd9Sstevel@tonic-gate Elf64_Shdr shdr; 6627c478bd9Sstevel@tonic-gate 6637c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 6647c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name); 6657c478bd9Sstevel@tonic-gate shdr.sh_type = type; 6667c478bd9Sstevel@tonic-gate shdr.sh_flags = flags; 6677c478bd9Sstevel@tonic-gate shdr.sh_addr = addr; 6687c478bd9Sstevel@tonic-gate shdr.sh_offset = offset; 6697c478bd9Sstevel@tonic-gate shdr.sh_size = size; 6707c478bd9Sstevel@tonic-gate shdr.sh_link = link; 6717c478bd9Sstevel@tonic-gate shdr.sh_info = info; 6727c478bd9Sstevel@tonic-gate shdr.sh_addralign = addralign; 6737c478bd9Sstevel@tonic-gate shdr.sh_entsize = entsize; 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 6767c478bd9Sstevel@tonic-gate *pgc->pgc_soff) != sizeof (shdr)) 6777c478bd9Sstevel@tonic-gate return (-1); 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 6807c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 6817c478bd9Sstevel@tonic-gate } 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate return (0); 6847c478bd9Sstevel@tonic-gate } 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate static int 6877c478bd9Sstevel@tonic-gate dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym) 6887c478bd9Sstevel@tonic-gate { 6897c478bd9Sstevel@tonic-gate sym_tbl_t *sym = dynsym ? &fptr->file_dynsym : &fptr->file_symtab; 6907c478bd9Sstevel@tonic-gate shstrtype_t symname = dynsym ? STR_DYNSYM : STR_SYMTAB; 6917c478bd9Sstevel@tonic-gate shstrtype_t strname = dynsym ? STR_DYNSTR : STR_STRTAB; 6927c478bd9Sstevel@tonic-gate uint_t symtype = dynsym ? SHT_DYNSYM : SHT_SYMTAB; 6937c478bd9Sstevel@tonic-gate size_t size; 6947c478bd9Sstevel@tonic-gate uintptr_t addr = fptr->file_map->map_pmap.pr_vaddr; 6957c478bd9Sstevel@tonic-gate 696d51e9074Sab196087 if (sym->sym_data_pri == NULL || sym->sym_symn == 0 || 6977c478bd9Sstevel@tonic-gate sym->sym_strs == NULL) 6987c478bd9Sstevel@tonic-gate return (0); 6997c478bd9Sstevel@tonic-gate 700d51e9074Sab196087 size = sym->sym_hdr_pri.sh_size; 701d51e9074Sab196087 if (pwrite64(pgc->pgc_fd, sym->sym_data_pri->d_buf, size, 7027c478bd9Sstevel@tonic-gate *pgc->pgc_doff) != size) 7037c478bd9Sstevel@tonic-gate return (-1); 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate if (write_shdr(pgc, symname, symtype, 0, addr, *pgc->pgc_doff, size, 706d51e9074Sab196087 index + 1, sym->sym_hdr_pri.sh_info, sym->sym_hdr_pri.sh_addralign, 707d51e9074Sab196087 sym->sym_hdr_pri.sh_entsize) != 0) 7087c478bd9Sstevel@tonic-gate return (-1); 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8); 7117c478bd9Sstevel@tonic-gate 7127c478bd9Sstevel@tonic-gate size = sym->sym_strhdr.sh_size; 7137c478bd9Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != size) 7147c478bd9Sstevel@tonic-gate return (-1); 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate if (write_shdr(pgc, strname, SHT_STRTAB, SHF_STRINGS, addr, 7177c478bd9Sstevel@tonic-gate *pgc->pgc_doff, size, 0, 0, 1, 0) != 0) 7187c478bd9Sstevel@tonic-gate return (-1); 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8); 7217c478bd9Sstevel@tonic-gate 7227c478bd9Sstevel@tonic-gate return (0); 7237c478bd9Sstevel@tonic-gate } 7247c478bd9Sstevel@tonic-gate 7257c478bd9Sstevel@tonic-gate static int 7267c478bd9Sstevel@tonic-gate dump_sections(pgcore_t *pgc) 7277c478bd9Sstevel@tonic-gate { 7287c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 7297c478bd9Sstevel@tonic-gate file_info_t *fptr; 7307c478bd9Sstevel@tonic-gate uint_t cnt; 7317c478bd9Sstevel@tonic-gate uint_t index = 1; 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB))) 7347c478bd9Sstevel@tonic-gate return (0); 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate fptr = list_next(&P->file_head); 7377c478bd9Sstevel@tonic-gate for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) { 7387c478bd9Sstevel@tonic-gate int hit_symtab = 0; 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate Pbuild_file_symtab(P, fptr); 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_CTF) && 7437c478bd9Sstevel@tonic-gate Pbuild_file_ctf(P, fptr) != NULL) { 7447c478bd9Sstevel@tonic-gate sym_tbl_t *sym; 7457c478bd9Sstevel@tonic-gate uint_t dynsym; 7467c478bd9Sstevel@tonic-gate uint_t symindex = 0; 7477c478bd9Sstevel@tonic-gate 7487c478bd9Sstevel@tonic-gate /* 7497c478bd9Sstevel@tonic-gate * Write the symtab out first so we can correctly 7507c478bd9Sstevel@tonic-gate * set the sh_link field in the CTF section header. 7517c478bd9Sstevel@tonic-gate * symindex will be 0 if there is no corresponding 7527c478bd9Sstevel@tonic-gate * symbol table section. 7537c478bd9Sstevel@tonic-gate */ 7547c478bd9Sstevel@tonic-gate if (fptr->file_ctf_dyn) { 7557c478bd9Sstevel@tonic-gate sym = &fptr->file_dynsym; 7567c478bd9Sstevel@tonic-gate dynsym = 1; 7577c478bd9Sstevel@tonic-gate } else { 7587c478bd9Sstevel@tonic-gate sym = &fptr->file_symtab; 7597c478bd9Sstevel@tonic-gate dynsym = 0; 7607c478bd9Sstevel@tonic-gate hit_symtab = 1; 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate 763d51e9074Sab196087 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 && 7647c478bd9Sstevel@tonic-gate sym->sym_strs != NULL) { 7657c478bd9Sstevel@tonic-gate symindex = index; 7667c478bd9Sstevel@tonic-gate if (dump_symtab(pgc, fptr, index, dynsym) != 0) 7677c478bd9Sstevel@tonic-gate return (-1); 7687c478bd9Sstevel@tonic-gate index += 2; 7697c478bd9Sstevel@tonic-gate } 7707c478bd9Sstevel@tonic-gate 7717c478bd9Sstevel@tonic-gate /* 7727c478bd9Sstevel@tonic-gate * Write the CTF data that we've read out of the 7737c478bd9Sstevel@tonic-gate * file itself into the core file. 7747c478bd9Sstevel@tonic-gate */ 7757c478bd9Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, fptr->file_ctf_buf, 7767c478bd9Sstevel@tonic-gate fptr->file_ctf_size, *pgc->pgc_doff) != 7777c478bd9Sstevel@tonic-gate fptr->file_ctf_size) 7787c478bd9Sstevel@tonic-gate return (-1); 7797c478bd9Sstevel@tonic-gate 7807c478bd9Sstevel@tonic-gate if (write_shdr(pgc, STR_CTF, SHT_PROGBITS, 0, 7817c478bd9Sstevel@tonic-gate fptr->file_map->map_pmap.pr_vaddr, *pgc->pgc_doff, 7827c478bd9Sstevel@tonic-gate fptr->file_ctf_size, symindex, 0, 4, 0) != 0) 7837c478bd9Sstevel@tonic-gate return (-1); 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate index++; 7867c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(fptr->file_ctf_size, 8); 7877c478bd9Sstevel@tonic-gate } 7887c478bd9Sstevel@tonic-gate 7897c478bd9Sstevel@tonic-gate if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab && 790d51e9074Sab196087 fptr->file_symtab.sym_data_pri != NULL && 7917c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_symn != 0 && 7927c478bd9Sstevel@tonic-gate fptr->file_symtab.sym_strs != NULL) { 7937c478bd9Sstevel@tonic-gate if (dump_symtab(pgc, fptr, index, 0) != 0) 7947c478bd9Sstevel@tonic-gate return (-1); 7957c478bd9Sstevel@tonic-gate index += 2; 7967c478bd9Sstevel@tonic-gate } 7977c478bd9Sstevel@tonic-gate } 7987c478bd9Sstevel@tonic-gate 7997c478bd9Sstevel@tonic-gate return (0); 8007c478bd9Sstevel@tonic-gate } 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8037c478bd9Sstevel@tonic-gate static int 8047c478bd9Sstevel@tonic-gate dump_map(void *data, const prmap_t *pmp, const char *name) 8057c478bd9Sstevel@tonic-gate { 8067c478bd9Sstevel@tonic-gate pgcore_t *pgc = data; 8077c478bd9Sstevel@tonic-gate struct ps_prochandle *P = pgc->P; 8087c478bd9Sstevel@tonic-gate #ifdef _LP64 8097c478bd9Sstevel@tonic-gate Elf64_Phdr phdr; 8107c478bd9Sstevel@tonic-gate #else 8117c478bd9Sstevel@tonic-gate Elf32_Phdr phdr; 8127c478bd9Sstevel@tonic-gate #endif 8137c478bd9Sstevel@tonic-gate size_t n; 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 8167c478bd9Sstevel@tonic-gate phdr.p_type = PT_LOAD; 8177c478bd9Sstevel@tonic-gate phdr.p_vaddr = pmp->pr_vaddr; 8187c478bd9Sstevel@tonic-gate phdr.p_memsz = pmp->pr_size; 8197c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_READ) 8207c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_R; 8217c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_WRITE) 8227c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_W; 8237c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_EXEC) 8247c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_X; 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate if (pmp->pr_vaddr + pmp->pr_size > P->status.pr_stkbase && 8277c478bd9Sstevel@tonic-gate pmp->pr_vaddr < P->status.pr_stkbase + P->status.pr_stksize) { 8287c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_STACK)) 8297c478bd9Sstevel@tonic-gate goto exclude; 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate } else if ((pmp->pr_mflags & MA_ANON) && 8327c478bd9Sstevel@tonic-gate pmp->pr_vaddr + pmp->pr_size > P->status.pr_brkbase && 8337c478bd9Sstevel@tonic-gate pmp->pr_vaddr < P->status.pr_brkbase + P->status.pr_brksize) { 8347c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_HEAP)) 8357c478bd9Sstevel@tonic-gate goto exclude; 8367c478bd9Sstevel@tonic-gate 8377c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_ISM) { 8387c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_NORESERVE) { 8397c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_DISM)) 8407c478bd9Sstevel@tonic-gate goto exclude; 8417c478bd9Sstevel@tonic-gate } else { 8427c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_ISM)) 8437c478bd9Sstevel@tonic-gate goto exclude; 8447c478bd9Sstevel@tonic-gate } 8457c478bd9Sstevel@tonic-gate 8467c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_SHM) { 8477c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHM)) 8487c478bd9Sstevel@tonic-gate goto exclude; 8497c478bd9Sstevel@tonic-gate 8507c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_SHARED) { 8517c478bd9Sstevel@tonic-gate if (pmp->pr_mflags & MA_ANON) { 8527c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHANON)) 8537c478bd9Sstevel@tonic-gate goto exclude; 8547c478bd9Sstevel@tonic-gate } else { 8557c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_SHFILE)) 8567c478bd9Sstevel@tonic-gate goto exclude; 8577c478bd9Sstevel@tonic-gate } 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate } else if (pmp->pr_mflags & MA_ANON) { 8607c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_ANON)) 8617c478bd9Sstevel@tonic-gate goto exclude; 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gate } else if (phdr.p_flags == (PF_R | PF_X)) { 8647c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_TEXT)) 8657c478bd9Sstevel@tonic-gate goto exclude; 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate } else if (phdr.p_flags == PF_R) { 8687c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_RODATA)) 8697c478bd9Sstevel@tonic-gate goto exclude; 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate } else { 8727c478bd9Sstevel@tonic-gate if (!(pgc->pgc_content & CC_CONTENT_DATA)) 8737c478bd9Sstevel@tonic-gate goto exclude; 8747c478bd9Sstevel@tonic-gate } 8757c478bd9Sstevel@tonic-gate 8767c478bd9Sstevel@tonic-gate n = 0; 8777c478bd9Sstevel@tonic-gate while (n < pmp->pr_size) { 8787c478bd9Sstevel@tonic-gate size_t csz = MIN(pmp->pr_size - n, pgc->pgc_chunksz); 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate /* 8817c478bd9Sstevel@tonic-gate * If we can't read out part of the victim's address 8827c478bd9Sstevel@tonic-gate * space for some reason ignore that failure and try to 8837c478bd9Sstevel@tonic-gate * emit a partial core file without that mapping's data. 8847c478bd9Sstevel@tonic-gate * As in the kernel, we mark these failures with the 8857c478bd9Sstevel@tonic-gate * PF_SUNW_FAILURE flag and store the errno where the 8867c478bd9Sstevel@tonic-gate * mapping would have been. 8877c478bd9Sstevel@tonic-gate */ 8887c478bd9Sstevel@tonic-gate if (Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n) != csz || 8897c478bd9Sstevel@tonic-gate pwrite64(pgc->pgc_fd, pgc->pgc_chunk, csz, 8907c478bd9Sstevel@tonic-gate *pgc->pgc_doff + n) != csz) { 8917c478bd9Sstevel@tonic-gate int err = errno; 8927c478bd9Sstevel@tonic-gate (void) pwrite64(pgc->pgc_fd, &err, sizeof (err), 8937c478bd9Sstevel@tonic-gate *pgc->pgc_doff); 8947c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(sizeof (err), 8); 8957c478bd9Sstevel@tonic-gate 8967c478bd9Sstevel@tonic-gate phdr.p_flags |= PF_SUNW_FAILURE; 8977c478bd9Sstevel@tonic-gate (void) ftruncate64(pgc->pgc_fd, *pgc->pgc_doff); 8987c478bd9Sstevel@tonic-gate goto exclude; 8997c478bd9Sstevel@tonic-gate } 9007c478bd9Sstevel@tonic-gate 9017c478bd9Sstevel@tonic-gate n += csz; 9027c478bd9Sstevel@tonic-gate } 9037c478bd9Sstevel@tonic-gate 9047c478bd9Sstevel@tonic-gate phdr.p_offset = *pgc->pgc_doff; 9057c478bd9Sstevel@tonic-gate phdr.p_filesz = pmp->pr_size; 9067c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(phdr.p_filesz, 8); 9077c478bd9Sstevel@tonic-gate 9087c478bd9Sstevel@tonic-gate exclude: 9097c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 9107c478bd9Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &phdr, sizeof (phdr), 9117c478bd9Sstevel@tonic-gate *pgc->pgc_poff) != sizeof (phdr)) 9127c478bd9Sstevel@tonic-gate return (1); 9137c478bd9Sstevel@tonic-gate 9147c478bd9Sstevel@tonic-gate *pgc->pgc_poff += sizeof (phdr); 9157c478bd9Sstevel@tonic-gate #ifdef _LP64 9167c478bd9Sstevel@tonic-gate } else { 9177c478bd9Sstevel@tonic-gate Elf32_Phdr phdr32; 9187c478bd9Sstevel@tonic-gate 9197c478bd9Sstevel@tonic-gate bzero(&phdr32, sizeof (phdr32)); 9207c478bd9Sstevel@tonic-gate phdr32.p_type = phdr.p_type; 9217c478bd9Sstevel@tonic-gate phdr32.p_vaddr = (Elf32_Addr)phdr.p_vaddr; 9227c478bd9Sstevel@tonic-gate phdr32.p_memsz = (Elf32_Word)phdr.p_memsz; 9237c478bd9Sstevel@tonic-gate phdr32.p_flags = phdr.p_flags; 9247c478bd9Sstevel@tonic-gate phdr32.p_offset = (Elf32_Off)phdr.p_offset; 9257c478bd9Sstevel@tonic-gate phdr32.p_filesz = (Elf32_Word)phdr.p_filesz; 9267c478bd9Sstevel@tonic-gate 9277c478bd9Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &phdr32, sizeof (phdr32), 9287c478bd9Sstevel@tonic-gate *pgc->pgc_poff) != sizeof (phdr32)) 9297c478bd9Sstevel@tonic-gate return (1); 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate *pgc->pgc_poff += sizeof (phdr32); 9327c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 9337c478bd9Sstevel@tonic-gate } 9347c478bd9Sstevel@tonic-gate 9357c478bd9Sstevel@tonic-gate return (0); 9367c478bd9Sstevel@tonic-gate } 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate int 9397c478bd9Sstevel@tonic-gate write_shstrtab(struct ps_prochandle *P, pgcore_t *pgc) 9407c478bd9Sstevel@tonic-gate { 9417c478bd9Sstevel@tonic-gate off64_t off = *pgc->pgc_doff; 9427c478bd9Sstevel@tonic-gate size_t size = 0; 9437c478bd9Sstevel@tonic-gate shstrtab_t *s = &pgc->pgc_shstrtab; 9447c478bd9Sstevel@tonic-gate int i, ndx; 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate if (shstrtab_size(s) == 1) 9477c478bd9Sstevel@tonic-gate return (0); 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate /* 9507c478bd9Sstevel@tonic-gate * Preemptively stick the name of the shstrtab in the string table. 9517c478bd9Sstevel@tonic-gate */ 9527c478bd9Sstevel@tonic-gate (void) shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB); 9537c478bd9Sstevel@tonic-gate size = shstrtab_size(s); 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate /* 9567c478bd9Sstevel@tonic-gate * Dump all the strings that we used being sure we include the 9577c478bd9Sstevel@tonic-gate * terminating null character. 9587c478bd9Sstevel@tonic-gate */ 9597c478bd9Sstevel@tonic-gate for (i = 0; i < STR_NUM; i++) { 96030da1432Sahl if ((ndx = s->sst_ndx[i]) != 0 || i == STR_NONE) { 9617c478bd9Sstevel@tonic-gate const char *str = shstrtab_data[i]; 9627c478bd9Sstevel@tonic-gate size_t len = strlen(str) + 1; 9637c478bd9Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, str, len, off + ndx) != len) 9647c478bd9Sstevel@tonic-gate return (1); 9657c478bd9Sstevel@tonic-gate } 9667c478bd9Sstevel@tonic-gate } 9677c478bd9Sstevel@tonic-gate 9687c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 9697c478bd9Sstevel@tonic-gate Elf32_Shdr shdr; 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 9727c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB); 9737c478bd9Sstevel@tonic-gate shdr.sh_size = size; 9747c478bd9Sstevel@tonic-gate shdr.sh_offset = *pgc->pgc_doff; 9757c478bd9Sstevel@tonic-gate shdr.sh_addralign = 1; 9767c478bd9Sstevel@tonic-gate shdr.sh_flags = SHF_STRINGS; 9777c478bd9Sstevel@tonic-gate shdr.sh_type = SHT_STRTAB; 9787c478bd9Sstevel@tonic-gate 9797c478bd9Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 9807c478bd9Sstevel@tonic-gate *pgc->pgc_soff) != sizeof (shdr)) 9817c478bd9Sstevel@tonic-gate return (1); 9827c478bd9Sstevel@tonic-gate 9837c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 9847c478bd9Sstevel@tonic-gate #ifdef _LP64 9857c478bd9Sstevel@tonic-gate } else { 9867c478bd9Sstevel@tonic-gate Elf64_Shdr shdr; 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate bzero(&shdr, sizeof (shdr)); 9897c478bd9Sstevel@tonic-gate shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB); 9907c478bd9Sstevel@tonic-gate shdr.sh_size = size; 9917c478bd9Sstevel@tonic-gate shdr.sh_offset = *pgc->pgc_doff; 9927c478bd9Sstevel@tonic-gate shdr.sh_addralign = 1; 9937c478bd9Sstevel@tonic-gate shdr.sh_flags = SHF_STRINGS; 9947c478bd9Sstevel@tonic-gate shdr.sh_type = SHT_STRTAB; 9957c478bd9Sstevel@tonic-gate 9967c478bd9Sstevel@tonic-gate if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 9977c478bd9Sstevel@tonic-gate *pgc->pgc_soff) != sizeof (shdr)) 9987c478bd9Sstevel@tonic-gate return (1); 9997c478bd9Sstevel@tonic-gate 10007c478bd9Sstevel@tonic-gate *pgc->pgc_soff += sizeof (shdr); 10017c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 10027c478bd9Sstevel@tonic-gate } 10037c478bd9Sstevel@tonic-gate 10047c478bd9Sstevel@tonic-gate *pgc->pgc_doff += roundup(size, 8); 10057c478bd9Sstevel@tonic-gate 10067c478bd9Sstevel@tonic-gate return (0); 10077c478bd9Sstevel@tonic-gate } 10087c478bd9Sstevel@tonic-gate 10097c478bd9Sstevel@tonic-gate /* 10107c478bd9Sstevel@tonic-gate * Don't explicity stop the process; that's up to the consumer. 10117c478bd9Sstevel@tonic-gate */ 10127c478bd9Sstevel@tonic-gate int 10137c478bd9Sstevel@tonic-gate Pfgcore(struct ps_prochandle *P, int fd, core_content_t content) 10147c478bd9Sstevel@tonic-gate { 10157c478bd9Sstevel@tonic-gate char plat[SYS_NMLN]; 10167c478bd9Sstevel@tonic-gate char zonename[ZONENAME_MAX]; 10177c478bd9Sstevel@tonic-gate int platlen = -1; 10187c478bd9Sstevel@tonic-gate pgcore_t pgc; 10197c478bd9Sstevel@tonic-gate off64_t poff, soff, doff, boff; 10207c478bd9Sstevel@tonic-gate struct utsname uts; 10217c478bd9Sstevel@tonic-gate uint_t nphdrs, nshdrs; 10227c478bd9Sstevel@tonic-gate 10237c478bd9Sstevel@tonic-gate if (ftruncate64(fd, 0) != 0) 10247c478bd9Sstevel@tonic-gate return (-1); 10257c478bd9Sstevel@tonic-gate 10267c478bd9Sstevel@tonic-gate if (content == CC_CONTENT_INVALID) { 10277c478bd9Sstevel@tonic-gate errno = EINVAL; 10287c478bd9Sstevel@tonic-gate return (-1); 10297c478bd9Sstevel@tonic-gate } 10307c478bd9Sstevel@tonic-gate 10317c478bd9Sstevel@tonic-gate /* 10327c478bd9Sstevel@tonic-gate * Cache the mappings and other useful data. 10337c478bd9Sstevel@tonic-gate */ 10347c478bd9Sstevel@tonic-gate (void) Prd_agent(P); 10357c478bd9Sstevel@tonic-gate (void) Ppsinfo(P); 10367c478bd9Sstevel@tonic-gate 10377c478bd9Sstevel@tonic-gate pgc.P = P; 10387c478bd9Sstevel@tonic-gate pgc.pgc_fd = fd; 10397c478bd9Sstevel@tonic-gate pgc.pgc_poff = &poff; 10407c478bd9Sstevel@tonic-gate pgc.pgc_soff = &soff; 10417c478bd9Sstevel@tonic-gate pgc.pgc_doff = &doff; 10427c478bd9Sstevel@tonic-gate pgc.pgc_content = content; 10437c478bd9Sstevel@tonic-gate pgc.pgc_chunksz = PAGESIZE; 10447c478bd9Sstevel@tonic-gate if ((pgc.pgc_chunk = malloc(pgc.pgc_chunksz)) == NULL) 10457c478bd9Sstevel@tonic-gate return (-1); 10467c478bd9Sstevel@tonic-gate 10477c478bd9Sstevel@tonic-gate shstrtab_init(&pgc.pgc_shstrtab); 10487c478bd9Sstevel@tonic-gate 10497c478bd9Sstevel@tonic-gate /* 10507c478bd9Sstevel@tonic-gate * There are two PT_NOTE program headers for ancillary data, and 10517c478bd9Sstevel@tonic-gate * one for each mapping. 10527c478bd9Sstevel@tonic-gate */ 10537c478bd9Sstevel@tonic-gate nphdrs = 2 + P->map_count; 10547c478bd9Sstevel@tonic-gate nshdrs = count_sections(&pgc); 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate (void) Pplatform(P, plat, sizeof (plat)); 10577c478bd9Sstevel@tonic-gate platlen = strlen(plat) + 1; 10587c478bd9Sstevel@tonic-gate Preadauxvec(P); 10597c478bd9Sstevel@tonic-gate (void) Puname(P, &uts); 10607c478bd9Sstevel@tonic-gate if (Pzonename(P, zonename, sizeof (zonename)) == NULL) 10617c478bd9Sstevel@tonic-gate zonename[0] = '\0'; 10627c478bd9Sstevel@tonic-gate 10637c478bd9Sstevel@tonic-gate /* 106430da1432Sahl * The core file contents may required zero section headers, but if we 106530da1432Sahl * overflow the 16 bits allotted to the program header count in the ELF 106630da1432Sahl * header, we'll need that program header at index zero. 106730da1432Sahl */ 106830da1432Sahl if (nshdrs == 0 && nphdrs >= PN_XNUM) 106930da1432Sahl nshdrs = 1; 107030da1432Sahl 107130da1432Sahl /* 10727c478bd9Sstevel@tonic-gate * Set up the ELF header. 10737c478bd9Sstevel@tonic-gate */ 10747c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 10757c478bd9Sstevel@tonic-gate Elf32_Ehdr ehdr; 10767c478bd9Sstevel@tonic-gate 10777c478bd9Sstevel@tonic-gate bzero(&ehdr, sizeof (ehdr)); 10787c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG0] = ELFMAG0; 10797c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG1] = ELFMAG1; 10807c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG2] = ELFMAG2; 10817c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG3] = ELFMAG3; 10827c478bd9Sstevel@tonic-gate ehdr.e_type = ET_CORE; 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_CLASS] = ELFCLASS32; 10857c478bd9Sstevel@tonic-gate #if defined(__sparc) 10867c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_SPARC; 10877c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2MSB; 10887c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64) 10897c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_386; 10907c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 10917c478bd9Sstevel@tonic-gate #else 10927c478bd9Sstevel@tonic-gate #error "unknown machine type" 10937c478bd9Sstevel@tonic-gate #endif 10947c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_VERSION] = EV_CURRENT; 10957c478bd9Sstevel@tonic-gate 10967c478bd9Sstevel@tonic-gate ehdr.e_version = EV_CURRENT; 10977c478bd9Sstevel@tonic-gate ehdr.e_ehsize = sizeof (ehdr); 109830da1432Sahl 109930da1432Sahl if (nphdrs >= PN_XNUM) 110030da1432Sahl ehdr.e_phnum = PN_XNUM; 110130da1432Sahl else 11027c478bd9Sstevel@tonic-gate ehdr.e_phnum = (unsigned short)nphdrs; 110330da1432Sahl 110430da1432Sahl ehdr.e_phentsize = sizeof (Elf32_Phdr); 11057c478bd9Sstevel@tonic-gate ehdr.e_phoff = ehdr.e_ehsize; 11067c478bd9Sstevel@tonic-gate 110730da1432Sahl if (nshdrs > 0) { 110830da1432Sahl if (nshdrs >= SHN_LORESERVE) 110930da1432Sahl ehdr.e_shnum = 0; 111030da1432Sahl else 11117c478bd9Sstevel@tonic-gate ehdr.e_shnum = (unsigned short)nshdrs; 111230da1432Sahl 111330da1432Sahl if (nshdrs - 1 >= SHN_LORESERVE) 111430da1432Sahl ehdr.e_shstrndx = SHN_XINDEX; 111530da1432Sahl else 111630da1432Sahl ehdr.e_shstrndx = (unsigned short)(nshdrs - 1); 111730da1432Sahl 111830da1432Sahl ehdr.e_shentsize = sizeof (Elf32_Shdr); 111930da1432Sahl ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs; 11207c478bd9Sstevel@tonic-gate } 11217c478bd9Sstevel@tonic-gate 11227c478bd9Sstevel@tonic-gate if (pwrite64(fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr)) 11237c478bd9Sstevel@tonic-gate goto err; 11247c478bd9Sstevel@tonic-gate 11257c478bd9Sstevel@tonic-gate poff = ehdr.e_phoff; 112630da1432Sahl soff = ehdr.e_shoff; 11277c478bd9Sstevel@tonic-gate doff = boff = ehdr.e_ehsize + 112830da1432Sahl ehdr.e_phentsize * nphdrs + 112930da1432Sahl ehdr.e_shentsize * nshdrs; 11307c478bd9Sstevel@tonic-gate 11317c478bd9Sstevel@tonic-gate #ifdef _LP64 11327c478bd9Sstevel@tonic-gate } else { 11337c478bd9Sstevel@tonic-gate Elf64_Ehdr ehdr; 11347c478bd9Sstevel@tonic-gate 11357c478bd9Sstevel@tonic-gate bzero(&ehdr, sizeof (ehdr)); 11367c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG0] = ELFMAG0; 11377c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG1] = ELFMAG1; 11387c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG2] = ELFMAG2; 11397c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_MAG3] = ELFMAG3; 11407c478bd9Sstevel@tonic-gate ehdr.e_type = ET_CORE; 11417c478bd9Sstevel@tonic-gate 11427c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_CLASS] = ELFCLASS64; 11437c478bd9Sstevel@tonic-gate #if defined(__sparc) 11447c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_SPARCV9; 11457c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2MSB; 11467c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64) 11477c478bd9Sstevel@tonic-gate ehdr.e_machine = EM_AMD64; 11487c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 11497c478bd9Sstevel@tonic-gate #else 11507c478bd9Sstevel@tonic-gate #error "unknown machine type" 11517c478bd9Sstevel@tonic-gate #endif 11527c478bd9Sstevel@tonic-gate ehdr.e_ident[EI_VERSION] = EV_CURRENT; 11537c478bd9Sstevel@tonic-gate 11547c478bd9Sstevel@tonic-gate ehdr.e_version = EV_CURRENT; 11557c478bd9Sstevel@tonic-gate ehdr.e_ehsize = sizeof (ehdr); 115630da1432Sahl 115730da1432Sahl if (nphdrs >= PN_XNUM) 115830da1432Sahl ehdr.e_phnum = PN_XNUM; 115930da1432Sahl else 11607c478bd9Sstevel@tonic-gate ehdr.e_phnum = (unsigned short)nphdrs; 116130da1432Sahl 116230da1432Sahl ehdr.e_phentsize = sizeof (Elf64_Phdr); 11637c478bd9Sstevel@tonic-gate ehdr.e_phoff = ehdr.e_ehsize; 11647c478bd9Sstevel@tonic-gate 116530da1432Sahl if (nshdrs > 0) { 116630da1432Sahl if (nshdrs >= SHN_LORESERVE) 116730da1432Sahl ehdr.e_shnum = 0; 116830da1432Sahl else 11697c478bd9Sstevel@tonic-gate ehdr.e_shnum = (unsigned short)nshdrs; 117030da1432Sahl 117130da1432Sahl if (nshdrs - 1 >= SHN_LORESERVE) 117230da1432Sahl ehdr.e_shstrndx = SHN_XINDEX; 117330da1432Sahl else 117430da1432Sahl ehdr.e_shstrndx = (unsigned short)(nshdrs - 1); 117530da1432Sahl 117630da1432Sahl ehdr.e_shentsize = sizeof (Elf64_Shdr); 117730da1432Sahl ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs; 11787c478bd9Sstevel@tonic-gate } 11797c478bd9Sstevel@tonic-gate 11807c478bd9Sstevel@tonic-gate if (pwrite64(fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr)) 11817c478bd9Sstevel@tonic-gate goto err; 11827c478bd9Sstevel@tonic-gate 11837c478bd9Sstevel@tonic-gate poff = ehdr.e_phoff; 118430da1432Sahl soff = ehdr.e_shoff; 118530da1432Sahl doff = boff = ehdr.e_ehsize + 118630da1432Sahl ehdr.e_phentsize * nphdrs + 118730da1432Sahl ehdr.e_shentsize * nshdrs; 11887c478bd9Sstevel@tonic-gate 11897c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 11907c478bd9Sstevel@tonic-gate } 11917c478bd9Sstevel@tonic-gate 11927c478bd9Sstevel@tonic-gate /* 119330da1432Sahl * Write the zero indexed section if it exists. 119430da1432Sahl */ 119530da1432Sahl if (nshdrs > 0 && write_shdr(&pgc, STR_NONE, 0, 0, 0, 0, 119630da1432Sahl nshdrs >= SHN_LORESERVE ? nshdrs : 0, 119730da1432Sahl nshdrs - 1 >= SHN_LORESERVE ? nshdrs - 1 : 0, 119830da1432Sahl nphdrs >= PN_XNUM ? nphdrs : 0, 0, 0) != 0) 119930da1432Sahl goto err; 120030da1432Sahl 120130da1432Sahl /* 12027c478bd9Sstevel@tonic-gate * Construct the old-style note header and section. 12037c478bd9Sstevel@tonic-gate */ 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 12067c478bd9Sstevel@tonic-gate prpsinfo_t prpsinfo; 12077c478bd9Sstevel@tonic-gate 12087c478bd9Sstevel@tonic-gate mkprpsinfo(P, &prpsinfo); 12097c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPSINFO, &prpsinfo, sizeof (prpsinfo_t), 12107c478bd9Sstevel@tonic-gate &doff) != 0) { 12117c478bd9Sstevel@tonic-gate goto err; 12127c478bd9Sstevel@tonic-gate } 12137c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, P->auxv, 12147c478bd9Sstevel@tonic-gate P->nauxv * sizeof (P->auxv[0]), &doff) != 0) { 12157c478bd9Sstevel@tonic-gate goto err; 12167c478bd9Sstevel@tonic-gate } 12177c478bd9Sstevel@tonic-gate #ifdef _LP64 12187c478bd9Sstevel@tonic-gate } else { 12197c478bd9Sstevel@tonic-gate prpsinfo32_t pi32; 12207c478bd9Sstevel@tonic-gate auxv32_t *av32; 12217c478bd9Sstevel@tonic-gate size_t size = sizeof (auxv32_t) * P->nauxv; 12227c478bd9Sstevel@tonic-gate int i; 12237c478bd9Sstevel@tonic-gate 12247c478bd9Sstevel@tonic-gate mkprpsinfo32(P, &pi32); 12257c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPSINFO, &pi32, sizeof (prpsinfo32_t), 12267c478bd9Sstevel@tonic-gate &doff) != 0) { 12277c478bd9Sstevel@tonic-gate goto err; 12287c478bd9Sstevel@tonic-gate } 12297c478bd9Sstevel@tonic-gate 12307c478bd9Sstevel@tonic-gate if ((av32 = malloc(size)) == NULL) 12317c478bd9Sstevel@tonic-gate goto err; 12327c478bd9Sstevel@tonic-gate 12337c478bd9Sstevel@tonic-gate for (i = 0; i < P->nauxv; i++) { 12347c478bd9Sstevel@tonic-gate auxv_n_to_32(&P->auxv[i], &av32[i]); 12357c478bd9Sstevel@tonic-gate } 12367c478bd9Sstevel@tonic-gate 12377c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) { 12387c478bd9Sstevel@tonic-gate free(av32); 12397c478bd9Sstevel@tonic-gate goto err; 12407c478bd9Sstevel@tonic-gate } 12417c478bd9Sstevel@tonic-gate 12427c478bd9Sstevel@tonic-gate free(av32); 12437c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 12447c478bd9Sstevel@tonic-gate } 12457c478bd9Sstevel@tonic-gate 12467c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0) 12477c478bd9Sstevel@tonic-gate goto err; 12487c478bd9Sstevel@tonic-gate 12497c478bd9Sstevel@tonic-gate if (Plwp_iter_all(P, old_per_lwp, &pgc) != 0) 12507c478bd9Sstevel@tonic-gate goto err; 12517c478bd9Sstevel@tonic-gate 12527c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 12537c478bd9Sstevel@tonic-gate Elf32_Phdr phdr; 12547c478bd9Sstevel@tonic-gate 12557c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 12567c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 12577c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 12587c478bd9Sstevel@tonic-gate phdr.p_offset = (Elf32_Off)boff; 12597c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 12607c478bd9Sstevel@tonic-gate boff = doff; 12617c478bd9Sstevel@tonic-gate 12627c478bd9Sstevel@tonic-gate if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr)) 12637c478bd9Sstevel@tonic-gate goto err; 12647c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 12657c478bd9Sstevel@tonic-gate #ifdef _LP64 12667c478bd9Sstevel@tonic-gate } else { 12677c478bd9Sstevel@tonic-gate Elf64_Phdr phdr; 12687c478bd9Sstevel@tonic-gate 12697c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 12707c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 12717c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 12727c478bd9Sstevel@tonic-gate phdr.p_offset = boff; 12737c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 12747c478bd9Sstevel@tonic-gate boff = doff; 12757c478bd9Sstevel@tonic-gate 12767c478bd9Sstevel@tonic-gate if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr)) 12777c478bd9Sstevel@tonic-gate goto err; 12787c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 12797c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 12807c478bd9Sstevel@tonic-gate } 12817c478bd9Sstevel@tonic-gate 12827c478bd9Sstevel@tonic-gate /* 12837c478bd9Sstevel@tonic-gate * Construct the new-style note header and section. 12847c478bd9Sstevel@tonic-gate */ 12857c478bd9Sstevel@tonic-gate 12867c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 12877c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSINFO, &P->psinfo, sizeof (psinfo_t), 12887c478bd9Sstevel@tonic-gate &doff) != 0) { 12897c478bd9Sstevel@tonic-gate goto err; 12907c478bd9Sstevel@tonic-gate } 12917c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSTATUS, &P->status, sizeof (pstatus_t), 12927c478bd9Sstevel@tonic-gate &doff) != 0) { 12937c478bd9Sstevel@tonic-gate goto err; 12947c478bd9Sstevel@tonic-gate } 12957c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, P->auxv, 12967c478bd9Sstevel@tonic-gate P->nauxv * sizeof (P->auxv[0]), &doff) != 0) { 12977c478bd9Sstevel@tonic-gate goto err; 12987c478bd9Sstevel@tonic-gate } 12997c478bd9Sstevel@tonic-gate #ifdef _LP64 13007c478bd9Sstevel@tonic-gate } else { 13017c478bd9Sstevel@tonic-gate psinfo32_t pi32; 13027c478bd9Sstevel@tonic-gate pstatus32_t ps32; 13037c478bd9Sstevel@tonic-gate auxv32_t *av32; 13047c478bd9Sstevel@tonic-gate size_t size = sizeof (auxv32_t) * P->nauxv; 13057c478bd9Sstevel@tonic-gate int i; 13067c478bd9Sstevel@tonic-gate 13077c478bd9Sstevel@tonic-gate psinfo_n_to_32(&P->psinfo, &pi32); 13087c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSINFO, &pi32, sizeof (psinfo32_t), 13097c478bd9Sstevel@tonic-gate &doff) != 0) { 13107c478bd9Sstevel@tonic-gate goto err; 13117c478bd9Sstevel@tonic-gate } 13127c478bd9Sstevel@tonic-gate pstatus_n_to_32(&P->status, &ps32); 13137c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PSTATUS, &ps32, sizeof (pstatus32_t), 13147c478bd9Sstevel@tonic-gate &doff) != 0) { 13157c478bd9Sstevel@tonic-gate goto err; 13167c478bd9Sstevel@tonic-gate } 13177c478bd9Sstevel@tonic-gate if ((av32 = malloc(size)) == NULL) 13187c478bd9Sstevel@tonic-gate goto err; 13197c478bd9Sstevel@tonic-gate 13207c478bd9Sstevel@tonic-gate for (i = 0; i < P->nauxv; i++) { 13217c478bd9Sstevel@tonic-gate auxv_n_to_32(&P->auxv[i], &av32[i]); 13227c478bd9Sstevel@tonic-gate } 13237c478bd9Sstevel@tonic-gate 13247c478bd9Sstevel@tonic-gate if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) { 13257c478bd9Sstevel@tonic-gate free(av32); 13267c478bd9Sstevel@tonic-gate goto err; 13277c478bd9Sstevel@tonic-gate } 13287c478bd9Sstevel@tonic-gate 13297c478bd9Sstevel@tonic-gate free(av32); 13307c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 13317c478bd9Sstevel@tonic-gate } 13327c478bd9Sstevel@tonic-gate 13337c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0 || 13347c478bd9Sstevel@tonic-gate write_note(fd, NT_UTSNAME, &uts, sizeof (uts), &doff) != 0 || 13357c478bd9Sstevel@tonic-gate write_note(fd, NT_CONTENT, &content, sizeof (content), &doff) != 0) 13367c478bd9Sstevel@tonic-gate goto err; 13377c478bd9Sstevel@tonic-gate 13387c478bd9Sstevel@tonic-gate { 13397c478bd9Sstevel@tonic-gate prcred_t cred, *cp; 13407c478bd9Sstevel@tonic-gate size_t size = sizeof (prcred_t); 13417c478bd9Sstevel@tonic-gate 13427c478bd9Sstevel@tonic-gate if (Pcred(P, &cred, 0) != 0) 13437c478bd9Sstevel@tonic-gate goto err; 13447c478bd9Sstevel@tonic-gate 13457c478bd9Sstevel@tonic-gate if (cred.pr_ngroups > 0) 13467c478bd9Sstevel@tonic-gate size += sizeof (gid_t) * (cred.pr_ngroups - 1); 13477c478bd9Sstevel@tonic-gate if ((cp = malloc(size)) == NULL) 13487c478bd9Sstevel@tonic-gate goto err; 13497c478bd9Sstevel@tonic-gate 13507c478bd9Sstevel@tonic-gate if (Pcred(P, cp, cred.pr_ngroups) != 0 || 13517c478bd9Sstevel@tonic-gate write_note(fd, NT_PRCRED, cp, size, &doff) != 0) { 13527c478bd9Sstevel@tonic-gate free(cp); 13537c478bd9Sstevel@tonic-gate goto err; 13547c478bd9Sstevel@tonic-gate } 13557c478bd9Sstevel@tonic-gate 13567c478bd9Sstevel@tonic-gate free(cp); 13577c478bd9Sstevel@tonic-gate } 13587c478bd9Sstevel@tonic-gate 13597c478bd9Sstevel@tonic-gate { 13607c478bd9Sstevel@tonic-gate prpriv_t *ppriv; 13617c478bd9Sstevel@tonic-gate const priv_impl_info_t *pinfo; 13627c478bd9Sstevel@tonic-gate size_t pprivsz, pinfosz; 13637c478bd9Sstevel@tonic-gate 13647c478bd9Sstevel@tonic-gate if ((ppriv = proc_get_priv(P->pid)) == NULL) 13657c478bd9Sstevel@tonic-gate goto err; 13667c478bd9Sstevel@tonic-gate pprivsz = PRIV_PRPRIV_SIZE(ppriv); 13677c478bd9Sstevel@tonic-gate 13687c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPRIV, ppriv, pprivsz, &doff) != 0) { 13697c478bd9Sstevel@tonic-gate free(ppriv); 13707c478bd9Sstevel@tonic-gate goto err; 13717c478bd9Sstevel@tonic-gate } 13727c478bd9Sstevel@tonic-gate free(ppriv); 13737c478bd9Sstevel@tonic-gate 13747c478bd9Sstevel@tonic-gate if ((pinfo = getprivimplinfo()) == NULL) 13757c478bd9Sstevel@tonic-gate goto err; 13767c478bd9Sstevel@tonic-gate pinfosz = PRIV_IMPL_INFO_SIZE(pinfo); 13777c478bd9Sstevel@tonic-gate 13787c478bd9Sstevel@tonic-gate if (write_note(fd, NT_PRPRIVINFO, pinfo, pinfosz, &doff) != 0) 13797c478bd9Sstevel@tonic-gate goto err; 13807c478bd9Sstevel@tonic-gate } 13817c478bd9Sstevel@tonic-gate 13827c478bd9Sstevel@tonic-gate if (write_note(fd, NT_ZONENAME, zonename, strlen(zonename) + 1, 13837c478bd9Sstevel@tonic-gate &doff) != 0) 13847c478bd9Sstevel@tonic-gate goto err; 13857c478bd9Sstevel@tonic-gate 138634bdffbfSGarrett D'Amore { 138734bdffbfSGarrett D'Amore fditer_t iter; 138834bdffbfSGarrett D'Amore iter.fd_fd = fd; 138934bdffbfSGarrett D'Amore iter.fd_doff = &doff; 139034bdffbfSGarrett D'Amore 139134bdffbfSGarrett D'Amore if (Pfdinfo_iter(P, iter_fd, &iter) != 0) 139234bdffbfSGarrett D'Amore goto err; 139334bdffbfSGarrett D'Amore } 139434bdffbfSGarrett D'Amore 13957c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 13967c478bd9Sstevel@tonic-gate /* CSTYLED */ 13977c478bd9Sstevel@tonic-gate { 13987c478bd9Sstevel@tonic-gate struct ssd *ldtp; 13997c478bd9Sstevel@tonic-gate size_t size; 14007c478bd9Sstevel@tonic-gate int nldt; 14017c478bd9Sstevel@tonic-gate 140240c00cd7Sahl /* 140340c00cd7Sahl * Only dump out non-zero sized LDT notes. 140440c00cd7Sahl */ 140540c00cd7Sahl if ((nldt = Pldt(P, NULL, 0)) != 0) { 14067c478bd9Sstevel@tonic-gate size = sizeof (struct ssd) * nldt; 14077c478bd9Sstevel@tonic-gate if ((ldtp = malloc(size)) == NULL) 14087c478bd9Sstevel@tonic-gate goto err; 14097c478bd9Sstevel@tonic-gate 14107c478bd9Sstevel@tonic-gate if (Pldt(P, ldtp, nldt) == -1 || 14117c478bd9Sstevel@tonic-gate write_note(fd, NT_LDT, ldtp, size, &doff) != 0) { 14127c478bd9Sstevel@tonic-gate free(ldtp); 14137c478bd9Sstevel@tonic-gate goto err; 14147c478bd9Sstevel@tonic-gate } 14157c478bd9Sstevel@tonic-gate 14167c478bd9Sstevel@tonic-gate free(ldtp); 14177c478bd9Sstevel@tonic-gate } 141840c00cd7Sahl } 14197c478bd9Sstevel@tonic-gate #endif /* __i386 || __amd64 */ 14207c478bd9Sstevel@tonic-gate 14217c478bd9Sstevel@tonic-gate if (Plwp_iter_all(P, new_per_lwp, &pgc) != 0) 14227c478bd9Sstevel@tonic-gate goto err; 14237c478bd9Sstevel@tonic-gate 14247c478bd9Sstevel@tonic-gate if (P->status.pr_dmodel == PR_MODEL_ILP32) { 14257c478bd9Sstevel@tonic-gate Elf32_Phdr phdr; 14267c478bd9Sstevel@tonic-gate 14277c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 14287c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 14297c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 14307c478bd9Sstevel@tonic-gate phdr.p_offset = (Elf32_Off)boff; 14317c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 14327c478bd9Sstevel@tonic-gate boff = doff; 14337c478bd9Sstevel@tonic-gate 14347c478bd9Sstevel@tonic-gate if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr)) 14357c478bd9Sstevel@tonic-gate goto err; 14367c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 14377c478bd9Sstevel@tonic-gate #ifdef _LP64 14387c478bd9Sstevel@tonic-gate } else { 14397c478bd9Sstevel@tonic-gate Elf64_Phdr phdr; 14407c478bd9Sstevel@tonic-gate 14417c478bd9Sstevel@tonic-gate bzero(&phdr, sizeof (phdr)); 14427c478bd9Sstevel@tonic-gate phdr.p_type = PT_NOTE; 14437c478bd9Sstevel@tonic-gate phdr.p_flags = PF_R; 14447c478bd9Sstevel@tonic-gate phdr.p_offset = boff; 14457c478bd9Sstevel@tonic-gate phdr.p_filesz = doff - boff; 14467c478bd9Sstevel@tonic-gate boff = doff; 14477c478bd9Sstevel@tonic-gate 14487c478bd9Sstevel@tonic-gate if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr)) 14497c478bd9Sstevel@tonic-gate goto err; 14507c478bd9Sstevel@tonic-gate poff += sizeof (phdr); 14517c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 14527c478bd9Sstevel@tonic-gate } 14537c478bd9Sstevel@tonic-gate 14547c478bd9Sstevel@tonic-gate /* 14557c478bd9Sstevel@tonic-gate * Construct the headers for each mapping and write out its data 14567c478bd9Sstevel@tonic-gate * if the content parameter indicates that it should be present 14577c478bd9Sstevel@tonic-gate * in the core file. 14587c478bd9Sstevel@tonic-gate */ 14597c478bd9Sstevel@tonic-gate if (Pmapping_iter(P, dump_map, &pgc) != 0) 14607c478bd9Sstevel@tonic-gate goto err; 14617c478bd9Sstevel@tonic-gate 14627c478bd9Sstevel@tonic-gate if (dump_sections(&pgc) != 0) 14637c478bd9Sstevel@tonic-gate goto err; 14647c478bd9Sstevel@tonic-gate 14657c478bd9Sstevel@tonic-gate if (write_shstrtab(P, &pgc) != 0) 14667c478bd9Sstevel@tonic-gate goto err; 14677c478bd9Sstevel@tonic-gate 14687c478bd9Sstevel@tonic-gate free(pgc.pgc_chunk); 14697c478bd9Sstevel@tonic-gate 14707c478bd9Sstevel@tonic-gate return (0); 14717c478bd9Sstevel@tonic-gate 14727c478bd9Sstevel@tonic-gate err: 14737c478bd9Sstevel@tonic-gate /* 14747c478bd9Sstevel@tonic-gate * Wipe out anything we may have written if there was an error. 14757c478bd9Sstevel@tonic-gate */ 14767c478bd9Sstevel@tonic-gate (void) ftruncate64(fd, 0); 14777c478bd9Sstevel@tonic-gate free(pgc.pgc_chunk); 14787c478bd9Sstevel@tonic-gate return (-1); 14797c478bd9Sstevel@tonic-gate } 14807c478bd9Sstevel@tonic-gate 14817c478bd9Sstevel@tonic-gate static const char *content_str[] = { 14827c478bd9Sstevel@tonic-gate "stack", /* CC_CONTENT_STACK */ 14837c478bd9Sstevel@tonic-gate "heap", /* CC_CONTENT_HEAP */ 14847c478bd9Sstevel@tonic-gate "shfile", /* CC_CONTENT_SHFILE */ 14857c478bd9Sstevel@tonic-gate "shanon", /* CC_CONTENT_SHANON */ 14867c478bd9Sstevel@tonic-gate "text", /* CC_CONTENT_TEXT */ 14877c478bd9Sstevel@tonic-gate "data", /* CC_CONTENT_DATA */ 14887c478bd9Sstevel@tonic-gate "rodata", /* CC_CONTENT_RODATA */ 14897c478bd9Sstevel@tonic-gate "anon", /* CC_CONTENT_ANON */ 14907c478bd9Sstevel@tonic-gate "shm", /* CC_CONTENT_SHM */ 14917c478bd9Sstevel@tonic-gate "ism", /* CC_CONTENT_ISM */ 14927c478bd9Sstevel@tonic-gate "dism", /* CC_CONTENT_DISM */ 14937c478bd9Sstevel@tonic-gate "ctf", /* CC_CONTENT_CTF */ 14947c478bd9Sstevel@tonic-gate "symtab", /* CC_CONTENT_SYMTAB */ 14957c478bd9Sstevel@tonic-gate }; 14967c478bd9Sstevel@tonic-gate 14977c478bd9Sstevel@tonic-gate static uint_t ncontent_str = sizeof (content_str) / sizeof (content_str[0]); 14987c478bd9Sstevel@tonic-gate 14997c478bd9Sstevel@tonic-gate #define STREQ(a, b, n) (strlen(b) == (n) && strncmp(a, b, n) == 0) 15007c478bd9Sstevel@tonic-gate 15017c478bd9Sstevel@tonic-gate int 15027c478bd9Sstevel@tonic-gate proc_str2content(const char *str, core_content_t *cp) 15037c478bd9Sstevel@tonic-gate { 15047c478bd9Sstevel@tonic-gate const char *cur = str; 15057c478bd9Sstevel@tonic-gate int add = 1; 15067c478bd9Sstevel@tonic-gate core_content_t mask, content = 0; 15077c478bd9Sstevel@tonic-gate 15087c478bd9Sstevel@tonic-gate for (;;) { 15097c478bd9Sstevel@tonic-gate for (cur = str; isalpha(*cur); cur++) 15107c478bd9Sstevel@tonic-gate continue; 15117c478bd9Sstevel@tonic-gate 15127c478bd9Sstevel@tonic-gate if (STREQ(str, "default", cur - str)) { 15137c478bd9Sstevel@tonic-gate mask = CC_CONTENT_DEFAULT; 15147c478bd9Sstevel@tonic-gate } else if (STREQ(str, "all", cur - str)) { 15157c478bd9Sstevel@tonic-gate mask = CC_CONTENT_ALL; 15167c478bd9Sstevel@tonic-gate } else if (STREQ(str, "none", cur - str)) { 15177c478bd9Sstevel@tonic-gate mask = 0; 15187c478bd9Sstevel@tonic-gate } else { 15197c478bd9Sstevel@tonic-gate int i = 0; 15207c478bd9Sstevel@tonic-gate 15217c478bd9Sstevel@tonic-gate while (!STREQ(str, content_str[i], cur - str)) { 15227c478bd9Sstevel@tonic-gate i++; 15237c478bd9Sstevel@tonic-gate 15247c478bd9Sstevel@tonic-gate if (i >= ncontent_str) 15257c478bd9Sstevel@tonic-gate return (-1); 15267c478bd9Sstevel@tonic-gate } 15277c478bd9Sstevel@tonic-gate 15287c478bd9Sstevel@tonic-gate mask = (core_content_t)1 << i; 15297c478bd9Sstevel@tonic-gate } 15307c478bd9Sstevel@tonic-gate 15317c478bd9Sstevel@tonic-gate if (add) 15327c478bd9Sstevel@tonic-gate content |= mask; 15337c478bd9Sstevel@tonic-gate else 15347c478bd9Sstevel@tonic-gate content &= ~mask; 15357c478bd9Sstevel@tonic-gate 15367c478bd9Sstevel@tonic-gate switch (*cur) { 15377c478bd9Sstevel@tonic-gate case '\0': 15387c478bd9Sstevel@tonic-gate *cp = content; 15397c478bd9Sstevel@tonic-gate return (0); 15407c478bd9Sstevel@tonic-gate case '+': 15417c478bd9Sstevel@tonic-gate add = 1; 15427c478bd9Sstevel@tonic-gate break; 15437c478bd9Sstevel@tonic-gate case '-': 15447c478bd9Sstevel@tonic-gate add = 0; 15457c478bd9Sstevel@tonic-gate break; 15467c478bd9Sstevel@tonic-gate default: 15477c478bd9Sstevel@tonic-gate return (-1); 15487c478bd9Sstevel@tonic-gate } 15497c478bd9Sstevel@tonic-gate 15507c478bd9Sstevel@tonic-gate str = cur + 1; 15517c478bd9Sstevel@tonic-gate } 15527c478bd9Sstevel@tonic-gate } 15537c478bd9Sstevel@tonic-gate 15547c478bd9Sstevel@tonic-gate static int 15557c478bd9Sstevel@tonic-gate popc(core_content_t x) 15567c478bd9Sstevel@tonic-gate { 15577c478bd9Sstevel@tonic-gate int i; 15587c478bd9Sstevel@tonic-gate 15597c478bd9Sstevel@tonic-gate for (i = 0; x != 0; i++) 15607c478bd9Sstevel@tonic-gate x &= x - 1; 15617c478bd9Sstevel@tonic-gate 15627c478bd9Sstevel@tonic-gate return (i); 15637c478bd9Sstevel@tonic-gate } 15647c478bd9Sstevel@tonic-gate 15657c478bd9Sstevel@tonic-gate int 15667c478bd9Sstevel@tonic-gate proc_content2str(core_content_t content, char *buf, size_t size) 15677c478bd9Sstevel@tonic-gate { 15687c478bd9Sstevel@tonic-gate int nonecnt, defcnt, allcnt; 15697c478bd9Sstevel@tonic-gate core_content_t mask, bit; 15707c478bd9Sstevel@tonic-gate int first; 15717c478bd9Sstevel@tonic-gate uint_t index; 15727c478bd9Sstevel@tonic-gate size_t n, tot = 0; 15737c478bd9Sstevel@tonic-gate 15747c478bd9Sstevel@tonic-gate if (content == 0) 15757c478bd9Sstevel@tonic-gate return ((int)strlcpy(buf, "none", size)); 15767c478bd9Sstevel@tonic-gate 15777c478bd9Sstevel@tonic-gate if (content & ~CC_CONTENT_ALL) 15787c478bd9Sstevel@tonic-gate return ((int)strlcpy(buf, "<invalid>", size)); 15797c478bd9Sstevel@tonic-gate 15807c478bd9Sstevel@tonic-gate nonecnt = popc(content); 15817c478bd9Sstevel@tonic-gate defcnt = 1 + popc(content ^ CC_CONTENT_DEFAULT); 15827c478bd9Sstevel@tonic-gate allcnt = 1 + popc(content ^ CC_CONTENT_ALL); 15837c478bd9Sstevel@tonic-gate 15847c478bd9Sstevel@tonic-gate if (defcnt <= nonecnt && defcnt <= allcnt) { 15857c478bd9Sstevel@tonic-gate mask = content ^ CC_CONTENT_DEFAULT; 15867c478bd9Sstevel@tonic-gate first = 0; 15877c478bd9Sstevel@tonic-gate tot += (n = strlcpy(buf, "default", size)); 15887c478bd9Sstevel@tonic-gate if (n > size) 15897c478bd9Sstevel@tonic-gate n = size; 15907c478bd9Sstevel@tonic-gate buf += n; 15917c478bd9Sstevel@tonic-gate size -= n; 15927c478bd9Sstevel@tonic-gate } else if (allcnt < nonecnt) { 15937c478bd9Sstevel@tonic-gate mask = content ^ CC_CONTENT_ALL; 15947c478bd9Sstevel@tonic-gate first = 0; 15957c478bd9Sstevel@tonic-gate tot += (n = strlcpy(buf, "all", size)); 15967c478bd9Sstevel@tonic-gate if (n > size) 15977c478bd9Sstevel@tonic-gate n = size; 15987c478bd9Sstevel@tonic-gate buf += n; 15997c478bd9Sstevel@tonic-gate size -= n; 16007c478bd9Sstevel@tonic-gate } else { 16017c478bd9Sstevel@tonic-gate mask = content; 16027c478bd9Sstevel@tonic-gate first = 1; 16037c478bd9Sstevel@tonic-gate } 16047c478bd9Sstevel@tonic-gate 16057c478bd9Sstevel@tonic-gate while (mask != 0) { 16067c478bd9Sstevel@tonic-gate bit = mask ^ (mask & (mask - 1)); 16077c478bd9Sstevel@tonic-gate 16087c478bd9Sstevel@tonic-gate if (!first) { 16097c478bd9Sstevel@tonic-gate if (size > 1) { 16107c478bd9Sstevel@tonic-gate *buf = (bit & content) ? '+' : '-'; 16117c478bd9Sstevel@tonic-gate buf++; 16127c478bd9Sstevel@tonic-gate size--; 16137c478bd9Sstevel@tonic-gate } 16147c478bd9Sstevel@tonic-gate 16157c478bd9Sstevel@tonic-gate tot++; 16167c478bd9Sstevel@tonic-gate } 16177c478bd9Sstevel@tonic-gate index = popc(bit - 1); 16187c478bd9Sstevel@tonic-gate tot += (n = strlcpy(buf, content_str[index], size)); 16197c478bd9Sstevel@tonic-gate if (n > size) 16207c478bd9Sstevel@tonic-gate n = size; 16217c478bd9Sstevel@tonic-gate buf += n; 16227c478bd9Sstevel@tonic-gate size -= n; 16237c478bd9Sstevel@tonic-gate 16247c478bd9Sstevel@tonic-gate mask ^= bit; 16257c478bd9Sstevel@tonic-gate first = 0; 16267c478bd9Sstevel@tonic-gate } 16277c478bd9Sstevel@tonic-gate 16287c478bd9Sstevel@tonic-gate return ((int)tot); 16297c478bd9Sstevel@tonic-gate } 1630