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