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