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