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