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