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