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