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