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