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 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdlib.h> 29 #include <ctype.h> 30 #include <string.h> 31 #include <strings.h> 32 #include <errno.h> 33 #include <procfs.h> 34 #include <priv.h> 35 #include <sys/elf.h> 36 #include <sys/machelf.h> 37 #include <sys/sysmacros.h> 38 #include <sys/systeminfo.h> 39 #include <sys/proc.h> 40 #include <sys/utsname.h> 41 42 #include <sys/old_procfs.h> 43 44 #include "Pcontrol.h" 45 #include "P32ton.h" 46 47 typedef enum { 48 STR_NONE, 49 STR_CTF, 50 STR_SYMTAB, 51 STR_DYNSYM, 52 STR_STRTAB, 53 STR_DYNSTR, 54 STR_SHSTRTAB, 55 STR_NUM 56 } shstrtype_t; 57 58 static const char *shstrtab_data[] = { 59 "", 60 ".SUNW_ctf", 61 ".symtab", 62 ".dynsym", 63 ".strtab", 64 ".dynstr", 65 ".shstrtab" 66 }; 67 68 typedef struct shstrtab { 69 int sst_ndx[STR_NUM]; 70 int sst_cur; 71 } shstrtab_t; 72 73 typedef struct { 74 struct ps_prochandle *P; 75 int pgc_fd; 76 off64_t *pgc_poff; 77 off64_t *pgc_soff; 78 off64_t *pgc_doff; 79 core_content_t pgc_content; 80 void *pgc_chunk; 81 size_t pgc_chunksz; 82 83 shstrtab_t pgc_shstrtab; 84 } pgcore_t; 85 86 static void 87 shstrtab_init(shstrtab_t *s) 88 { 89 bzero(&s->sst_ndx, sizeof (s->sst_ndx)); 90 s->sst_cur = 1; 91 } 92 93 static int 94 shstrtab_ndx(shstrtab_t *s, shstrtype_t type) 95 { 96 int ret; 97 98 if ((ret = s->sst_ndx[type]) != 0 || type == STR_NONE) 99 return (ret); 100 101 ret = s->sst_ndx[type] = s->sst_cur; 102 s->sst_cur += strlen(shstrtab_data[type]) + 1; 103 104 return (ret); 105 } 106 107 static size_t 108 shstrtab_size(const shstrtab_t *s) 109 { 110 return (s->sst_cur); 111 } 112 113 int 114 Pgcore(struct ps_prochandle *P, const char *fname, core_content_t content) 115 { 116 int fd; 117 int err; 118 119 if ((fd = creat64(fname, 0666)) < 0) 120 return (-1); 121 122 if ((err = Pfgcore(P, fd, content)) != 0) { 123 (void) close(fd); 124 (void) unlink(fname); 125 return (err); 126 } 127 128 return (close(fd)); 129 } 130 131 /* 132 * Since we don't want to use the old-school procfs interfaces, we use the 133 * new-style data structures we already have to construct the old-style 134 * data structures. We include these data structures in core files for 135 * backward compatability. 136 */ 137 138 static void 139 mkprstatus(struct ps_prochandle *P, const lwpstatus_t *lsp, 140 const lwpsinfo_t *lip, prstatus_t *psp) 141 { 142 bzero(psp, sizeof (*psp)); 143 144 if (lsp->pr_flags & PR_STOPPED) 145 psp->pr_flags = 0x0001; 146 if (lsp->pr_flags & PR_ISTOP) 147 psp->pr_flags = 0x0002; 148 if (lsp->pr_flags & PR_DSTOP) 149 psp->pr_flags = 0x0004; 150 if (lsp->pr_flags & PR_ASLEEP) 151 psp->pr_flags = 0x0008; 152 if (lsp->pr_flags & PR_FORK) 153 psp->pr_flags = 0x0010; 154 if (lsp->pr_flags & PR_RLC) 155 psp->pr_flags = 0x0020; 156 /* 157 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set; 158 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>. 159 */ 160 if (lsp->pr_flags & PR_PCINVAL) 161 psp->pr_flags = 0x0080; 162 if (lsp->pr_flags & PR_ISSYS) 163 psp->pr_flags = 0x0100; 164 if (lsp->pr_flags & PR_STEP) 165 psp->pr_flags = 0x0200; 166 if (lsp->pr_flags & PR_KLC) 167 psp->pr_flags = 0x0400; 168 if (lsp->pr_flags & PR_ASYNC) 169 psp->pr_flags = 0x0800; 170 if (lsp->pr_flags & PR_PTRACE) 171 psp->pr_flags = 0x1000; 172 if (lsp->pr_flags & PR_MSACCT) 173 psp->pr_flags = 0x2000; 174 if (lsp->pr_flags & PR_BPTADJ) 175 psp->pr_flags = 0x4000; 176 if (lsp->pr_flags & PR_ASLWP) 177 psp->pr_flags = 0x8000; 178 179 psp->pr_why = lsp->pr_why; 180 psp->pr_what = lsp->pr_what; 181 psp->pr_info = lsp->pr_info; 182 psp->pr_cursig = lsp->pr_cursig; 183 psp->pr_nlwp = P->status.pr_nlwp; 184 psp->pr_sigpend = P->status.pr_sigpend; 185 psp->pr_sighold = lsp->pr_lwphold; 186 psp->pr_altstack = lsp->pr_altstack; 187 psp->pr_action = lsp->pr_action; 188 psp->pr_pid = P->status.pr_pid; 189 psp->pr_ppid = P->status.pr_ppid; 190 psp->pr_pgrp = P->status.pr_pgid; 191 psp->pr_sid = P->status.pr_sid; 192 psp->pr_utime = P->status.pr_utime; 193 psp->pr_stime = P->status.pr_stime; 194 psp->pr_cutime = P->status.pr_cutime; 195 psp->pr_cstime = P->status.pr_cstime; 196 (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname)); 197 psp->pr_syscall = lsp->pr_syscall; 198 psp->pr_nsysarg = lsp->pr_nsysarg; 199 bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg)); 200 psp->pr_who = lsp->pr_lwpid; 201 psp->pr_lwppend = lsp->pr_lwppend; 202 psp->pr_oldcontext = (ucontext_t *)lsp->pr_oldcontext; 203 psp->pr_brkbase = (caddr_t)P->status.pr_brkbase; 204 psp->pr_brksize = P->status.pr_brksize; 205 psp->pr_stkbase = (caddr_t)P->status.pr_stkbase; 206 psp->pr_stksize = P->status.pr_stksize; 207 psp->pr_processor = (short)lip->pr_onpro; 208 psp->pr_bind = (short)lip->pr_bindpro; 209 psp->pr_instr = lsp->pr_instr; 210 bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg)); 211 } 212 213 static void 214 mkprpsinfo(struct ps_prochandle *P, prpsinfo_t *psp) 215 { 216 bzero(psp, sizeof (*psp)); 217 psp->pr_state = P->psinfo.pr_lwp.pr_state; 218 psp->pr_sname = P->psinfo.pr_lwp.pr_sname; 219 psp->pr_zomb = (psp->pr_state == SZOMB); 220 psp->pr_nice = P->psinfo.pr_lwp.pr_nice; 221 psp->pr_flag = P->psinfo.pr_lwp.pr_flag; 222 psp->pr_uid = P->psinfo.pr_uid; 223 psp->pr_gid = P->psinfo.pr_gid; 224 psp->pr_pid = P->psinfo.pr_pid; 225 psp->pr_ppid = P->psinfo.pr_ppid; 226 psp->pr_pgrp = P->psinfo.pr_pgid; 227 psp->pr_sid = P->psinfo.pr_sid; 228 psp->pr_addr = (caddr_t)P->psinfo.pr_addr; 229 psp->pr_size = P->psinfo.pr_size; 230 psp->pr_rssize = P->psinfo.pr_rssize; 231 psp->pr_wchan = (caddr_t)P->psinfo.pr_lwp.pr_wchan; 232 psp->pr_start = P->psinfo.pr_start; 233 psp->pr_time = P->psinfo.pr_time; 234 psp->pr_pri = P->psinfo.pr_lwp.pr_pri; 235 psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri; 236 psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu; 237 psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev); 238 psp->pr_lttydev = P->psinfo.pr_ttydev; 239 (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname, 240 sizeof (psp->pr_clname)); 241 (void) strncpy(psp->pr_fname, P->psinfo.pr_fname, 242 sizeof (psp->pr_fname)); 243 bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs, 244 sizeof (psp->pr_psargs)); 245 psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall; 246 psp->pr_ctime = P->psinfo.pr_ctime; 247 psp->pr_bysize = psp->pr_size * PAGESIZE; 248 psp->pr_byrssize = psp->pr_rssize * PAGESIZE; 249 psp->pr_argc = P->psinfo.pr_argc; 250 psp->pr_argv = (char **)P->psinfo.pr_argv; 251 psp->pr_envp = (char **)P->psinfo.pr_envp; 252 psp->pr_wstat = P->psinfo.pr_wstat; 253 psp->pr_pctcpu = P->psinfo.pr_pctcpu; 254 psp->pr_pctmem = P->psinfo.pr_pctmem; 255 psp->pr_euid = P->psinfo.pr_euid; 256 psp->pr_egid = P->psinfo.pr_egid; 257 psp->pr_aslwpid = 0; 258 psp->pr_dmodel = P->psinfo.pr_dmodel; 259 } 260 261 #ifdef _LP64 262 263 static void 264 mkprstatus32(struct ps_prochandle *P, const lwpstatus_t *lsp, 265 const lwpsinfo_t *lip, prstatus32_t *psp) 266 { 267 bzero(psp, sizeof (*psp)); 268 269 if (lsp->pr_flags & PR_STOPPED) 270 psp->pr_flags = 0x0001; 271 if (lsp->pr_flags & PR_ISTOP) 272 psp->pr_flags = 0x0002; 273 if (lsp->pr_flags & PR_DSTOP) 274 psp->pr_flags = 0x0004; 275 if (lsp->pr_flags & PR_ASLEEP) 276 psp->pr_flags = 0x0008; 277 if (lsp->pr_flags & PR_FORK) 278 psp->pr_flags = 0x0010; 279 if (lsp->pr_flags & PR_RLC) 280 psp->pr_flags = 0x0020; 281 /* 282 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set; 283 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>. 284 */ 285 if (lsp->pr_flags & PR_PCINVAL) 286 psp->pr_flags = 0x0080; 287 if (lsp->pr_flags & PR_ISSYS) 288 psp->pr_flags = 0x0100; 289 if (lsp->pr_flags & PR_STEP) 290 psp->pr_flags = 0x0200; 291 if (lsp->pr_flags & PR_KLC) 292 psp->pr_flags = 0x0400; 293 if (lsp->pr_flags & PR_ASYNC) 294 psp->pr_flags = 0x0800; 295 if (lsp->pr_flags & PR_PTRACE) 296 psp->pr_flags = 0x1000; 297 if (lsp->pr_flags & PR_MSACCT) 298 psp->pr_flags = 0x2000; 299 if (lsp->pr_flags & PR_BPTADJ) 300 psp->pr_flags = 0x4000; 301 if (lsp->pr_flags & PR_ASLWP) 302 psp->pr_flags = 0x8000; 303 304 psp->pr_why = lsp->pr_why; 305 psp->pr_what = lsp->pr_what; 306 siginfo_n_to_32(&lsp->pr_info, &psp->pr_info); 307 psp->pr_cursig = lsp->pr_cursig; 308 psp->pr_nlwp = P->status.pr_nlwp; 309 psp->pr_sigpend = P->status.pr_sigpend; 310 psp->pr_sighold = lsp->pr_lwphold; 311 stack_n_to_32(&lsp->pr_altstack, &psp->pr_altstack); 312 sigaction_n_to_32(&lsp->pr_action, &psp->pr_action); 313 psp->pr_pid = P->status.pr_pid; 314 psp->pr_ppid = P->status.pr_ppid; 315 psp->pr_pgrp = P->status.pr_pgid; 316 psp->pr_sid = P->status.pr_sid; 317 timestruc_n_to_32(&P->status.pr_utime, &psp->pr_utime); 318 timestruc_n_to_32(&P->status.pr_stime, &psp->pr_stime); 319 timestruc_n_to_32(&P->status.pr_cutime, &psp->pr_cutime); 320 timestruc_n_to_32(&P->status.pr_cstime, &psp->pr_cstime); 321 (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname)); 322 psp->pr_syscall = lsp->pr_syscall; 323 psp->pr_nsysarg = lsp->pr_nsysarg; 324 bcopy(lsp->pr_sysarg, psp->pr_sysarg, 325 sizeof (psp->pr_sysarg)); psp->pr_who = lsp->pr_lwpid; 326 psp->pr_lwppend = lsp->pr_lwppend; 327 psp->pr_oldcontext = (caddr32_t)lsp->pr_oldcontext; 328 psp->pr_brkbase = (caddr32_t)P->status.pr_brkbase; 329 psp->pr_brksize = P->status.pr_brksize; 330 psp->pr_stkbase = (caddr32_t)P->status.pr_stkbase; 331 psp->pr_stksize = P->status.pr_stksize; 332 psp->pr_processor = (short)lip->pr_onpro; 333 psp->pr_bind = (short)lip->pr_bindpro; 334 psp->pr_instr = lsp->pr_instr; 335 bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg)); 336 } 337 338 static void 339 mkprpsinfo32(struct ps_prochandle *P, prpsinfo32_t *psp) 340 { 341 bzero(psp, sizeof (*psp)); 342 psp->pr_state = P->psinfo.pr_lwp.pr_state; 343 psp->pr_sname = P->psinfo.pr_lwp.pr_sname; 344 psp->pr_zomb = (psp->pr_state == SZOMB); 345 psp->pr_nice = P->psinfo.pr_lwp.pr_nice; 346 psp->pr_flag = P->psinfo.pr_lwp.pr_flag; 347 psp->pr_uid = P->psinfo.pr_uid; 348 psp->pr_gid = P->psinfo.pr_gid; 349 psp->pr_pid = P->psinfo.pr_pid; 350 psp->pr_ppid = P->psinfo.pr_ppid; 351 psp->pr_pgrp = P->psinfo.pr_pgid; 352 psp->pr_sid = P->psinfo.pr_sid; 353 psp->pr_addr = (caddr32_t)P->psinfo.pr_addr; 354 psp->pr_size = P->psinfo.pr_size; 355 psp->pr_rssize = P->psinfo.pr_rssize; 356 psp->pr_wchan = (caddr32_t)P->psinfo.pr_lwp.pr_wchan; 357 timestruc_n_to_32(&P->psinfo.pr_start, &psp->pr_start); 358 timestruc_n_to_32(&P->psinfo.pr_time, &psp->pr_time); 359 psp->pr_pri = P->psinfo.pr_lwp.pr_pri; 360 psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri; 361 psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu; 362 psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev); 363 psp->pr_lttydev = prcmpldev(P->psinfo.pr_ttydev); 364 (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname, 365 sizeof (psp->pr_clname)); 366 (void) strncpy(psp->pr_fname, P->psinfo.pr_fname, 367 sizeof (psp->pr_fname)); 368 bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs, 369 sizeof (psp->pr_psargs)); 370 psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall; 371 timestruc_n_to_32(&P->psinfo.pr_ctime, &psp->pr_ctime); 372 psp->pr_bysize = psp->pr_size * PAGESIZE; 373 psp->pr_byrssize = psp->pr_rssize * PAGESIZE; 374 psp->pr_argc = P->psinfo.pr_argc; 375 psp->pr_argv = (caddr32_t)P->psinfo.pr_argv; 376 psp->pr_envp = (caddr32_t)P->psinfo.pr_envp; 377 psp->pr_wstat = P->psinfo.pr_wstat; 378 psp->pr_pctcpu = P->psinfo.pr_pctcpu; 379 psp->pr_pctmem = P->psinfo.pr_pctmem; 380 psp->pr_euid = P->psinfo.pr_euid; 381 psp->pr_egid = P->psinfo.pr_egid; 382 psp->pr_aslwpid = 0; 383 psp->pr_dmodel = P->psinfo.pr_dmodel; 384 } 385 386 #endif /* _LP64 */ 387 388 static int 389 write_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp) 390 { 391 /* 392 * Note headers are the same regardless of the data model of the 393 * ELF file; we arbitrarily use Elf64_Nhdr here. 394 */ 395 struct { 396 Elf64_Nhdr nhdr; 397 char name[8]; 398 } n; 399 400 bzero(&n, sizeof (n)); 401 bcopy("CORE", n.name, 4); 402 n.nhdr.n_type = type; 403 n.nhdr.n_namesz = 5; 404 n.nhdr.n_descsz = roundup(descsz, 4); 405 406 if (pwrite64(fd, &n, sizeof (n), *offp) != sizeof (n)) 407 return (-1); 408 409 *offp += sizeof (n); 410 411 if (pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != n.nhdr.n_descsz) 412 return (-1); 413 414 *offp += n.nhdr.n_descsz; 415 416 return (0); 417 } 418 419 static int 420 old_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip) 421 { 422 pgcore_t *pgc = data; 423 struct ps_prochandle *P = pgc->P; 424 425 /* 426 * Legacy core files don't contain information about zombie LWPs. 427 * We use Plwp_iter_all() so that we get the lwpsinfo_t structure 428 * more cheaply. 429 */ 430 if (lsp == NULL) 431 return (0); 432 433 if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 434 prstatus_t prstatus; 435 mkprstatus(P, lsp, lip, &prstatus); 436 if (write_note(pgc->pgc_fd, NT_PRSTATUS, &prstatus, 437 sizeof (prstatus_t), pgc->pgc_doff) != 0) 438 return (0); 439 if (write_note(pgc->pgc_fd, NT_PRFPREG, &lsp->pr_fpreg, 440 sizeof (prfpregset_t), pgc->pgc_doff) != 0) 441 return (1); 442 #ifdef _LP64 443 } else { 444 prstatus32_t pr32; 445 prfpregset32_t pf32; 446 mkprstatus32(P, lsp, lip, &pr32); 447 if (write_note(pgc->pgc_fd, NT_PRSTATUS, &pr32, 448 sizeof (prstatus32_t), pgc->pgc_doff) != 0) 449 return (1); 450 prfpregset_n_to_32(&lsp->pr_fpreg, &pf32); 451 if (write_note(pgc->pgc_fd, NT_PRFPREG, &pf32, 452 sizeof (prfpregset32_t), pgc->pgc_doff) != 0) 453 return (1); 454 #endif /* _LP64 */ 455 } 456 457 #ifdef sparc 458 { 459 prxregset_t xregs; 460 if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0 && 461 write_note(pgc->pgc_fd, NT_PRXREG, &xregs, 462 sizeof (prxregset_t), pgc->pgc_doff) != 0) 463 return (1); 464 } 465 #endif /* sparc */ 466 467 return (0); 468 } 469 470 static int 471 new_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip) 472 { 473 pgcore_t *pgc = data; 474 struct ps_prochandle *P = pgc->P; 475 476 /* 477 * If lsp is NULL this indicates that this is a zombie LWP in 478 * which case we dump only the lwpsinfo_t structure and none of 479 * the other ancillary LWP state data. 480 */ 481 if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 482 if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip, 483 sizeof (lwpsinfo_t), pgc->pgc_doff) != 0) 484 return (1); 485 if (lsp == NULL) 486 return (0); 487 if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp, 488 sizeof (lwpstatus_t), pgc->pgc_doff) != 0) 489 return (1); 490 #ifdef _LP64 491 } else { 492 lwpsinfo32_t li32; 493 lwpstatus32_t ls32; 494 lwpsinfo_n_to_32(lip, &li32); 495 if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32, 496 sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0) 497 return (1); 498 if (lsp == NULL) 499 return (0); 500 lwpstatus_n_to_32(lsp, &ls32); 501 if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32, 502 sizeof (lwpstatus32_t), pgc->pgc_doff) != 0) 503 return (1); 504 #endif /* _LP64 */ 505 } 506 507 #ifdef sparc 508 { 509 prxregset_t xregs; 510 gwindows_t gwins; 511 size_t size; 512 513 if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0) { 514 if (write_note(pgc->pgc_fd, NT_PRXREG, &xregs, 515 sizeof (prxregset_t), pgc->pgc_doff) != 0) 516 return (1); 517 } 518 519 if (Plwp_getgwindows(P, lsp->pr_lwpid, &gwins) == 0 && 520 gwins.wbcnt > 0) { 521 size = sizeof (gwins) - sizeof (gwins.wbuf) + 522 gwins.wbcnt * sizeof (gwins.wbuf[0]); 523 524 if (write_note(pgc->pgc_fd, NT_GWINDOWS, &gwins, size, 525 pgc->pgc_doff) != 0) 526 return (1); 527 } 528 529 } 530 #ifdef __sparcv9 531 if (P->status.pr_dmodel == PR_MODEL_LP64) { 532 asrset_t asrs; 533 if (Plwp_getasrs(P, lsp->pr_lwpid, asrs) == 0) { 534 if (write_note(pgc->pgc_fd, NT_ASRS, &asrs, 535 sizeof (asrset_t), pgc->pgc_doff) != 0) 536 return (1); 537 } 538 } 539 #endif /* __sparcv9 */ 540 #endif /* sparc */ 541 542 return (0); 543 } 544 545 static uint_t 546 count_sections(pgcore_t *pgc) 547 { 548 struct ps_prochandle *P = pgc->P; 549 file_info_t *fptr; 550 uint_t cnt; 551 uint_t nshdrs = 0; 552 553 if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB))) 554 return (0); 555 556 fptr = list_next(&P->file_head); 557 for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) { 558 int hit_symtab = 0; 559 560 Pbuild_file_symtab(P, fptr); 561 562 if ((pgc->pgc_content & CC_CONTENT_CTF) && 563 Pbuild_file_ctf(P, fptr) != NULL) { 564 sym_tbl_t *sym; 565 566 nshdrs++; 567 568 if (fptr->file_ctf_dyn) { 569 sym = &fptr->file_dynsym; 570 } else { 571 sym = &fptr->file_symtab; 572 hit_symtab = 1; 573 } 574 575 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 && 576 sym->sym_strs != NULL) 577 nshdrs += 2; 578 } 579 580 if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab && 581 fptr->file_symtab.sym_data_pri != NULL && 582 fptr->file_symtab.sym_symn != 0 && 583 fptr->file_symtab.sym_strs != NULL) { 584 nshdrs += 2; 585 } 586 } 587 588 return (nshdrs == 0 ? 0 : nshdrs + 2); 589 } 590 591 static int 592 write_shdr(pgcore_t *pgc, shstrtype_t name, uint_t type, ulong_t flags, 593 uintptr_t addr, ulong_t offset, size_t size, uint_t link, uint_t info, 594 uintptr_t addralign, uintptr_t entsize) 595 { 596 if (pgc->P->status.pr_dmodel == PR_MODEL_ILP32) { 597 Elf32_Shdr shdr; 598 599 bzero(&shdr, sizeof (shdr)); 600 shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name); 601 shdr.sh_type = type; 602 shdr.sh_flags = flags; 603 shdr.sh_addr = (Elf32_Addr)addr; 604 shdr.sh_offset = offset; 605 shdr.sh_size = size; 606 shdr.sh_link = link; 607 shdr.sh_info = info; 608 shdr.sh_addralign = addralign; 609 shdr.sh_entsize = entsize; 610 611 if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 612 *pgc->pgc_soff) != sizeof (shdr)) 613 return (-1); 614 615 *pgc->pgc_soff += sizeof (shdr); 616 #ifdef _LP64 617 } else { 618 Elf64_Shdr shdr; 619 620 bzero(&shdr, sizeof (shdr)); 621 shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name); 622 shdr.sh_type = type; 623 shdr.sh_flags = flags; 624 shdr.sh_addr = addr; 625 shdr.sh_offset = offset; 626 shdr.sh_size = size; 627 shdr.sh_link = link; 628 shdr.sh_info = info; 629 shdr.sh_addralign = addralign; 630 shdr.sh_entsize = entsize; 631 632 if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr), 633 *pgc->pgc_soff) != sizeof (shdr)) 634 return (-1); 635 636 *pgc->pgc_soff += sizeof (shdr); 637 #endif /* _LP64 */ 638 } 639 640 return (0); 641 } 642 643 static int 644 dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym) 645 { 646 sym_tbl_t *sym = dynsym ? &fptr->file_dynsym : &fptr->file_symtab; 647 shstrtype_t symname = dynsym ? STR_DYNSYM : STR_SYMTAB; 648 shstrtype_t strname = dynsym ? STR_DYNSTR : STR_STRTAB; 649 uint_t symtype = dynsym ? SHT_DYNSYM : SHT_SYMTAB; 650 size_t size; 651 uintptr_t addr = fptr->file_map->map_pmap.pr_vaddr; 652 653 if (sym->sym_data_pri == NULL || sym->sym_symn == 0 || 654 sym->sym_strs == NULL) 655 return (0); 656 657 size = sym->sym_hdr_pri.sh_size; 658 if (pwrite64(pgc->pgc_fd, sym->sym_data_pri->d_buf, size, 659 *pgc->pgc_doff) != size) 660 return (-1); 661 662 if (write_shdr(pgc, symname, symtype, 0, addr, *pgc->pgc_doff, size, 663 index + 1, sym->sym_hdr_pri.sh_info, sym->sym_hdr_pri.sh_addralign, 664 sym->sym_hdr_pri.sh_entsize) != 0) 665 return (-1); 666 667 *pgc->pgc_doff += roundup(size, 8); 668 669 size = sym->sym_strhdr.sh_size; 670 if (pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != size) 671 return (-1); 672 673 if (write_shdr(pgc, strname, SHT_STRTAB, SHF_STRINGS, addr, 674 *pgc->pgc_doff, size, 0, 0, 1, 0) != 0) 675 return (-1); 676 677 *pgc->pgc_doff += roundup(size, 8); 678 679 return (0); 680 } 681 682 static int 683 dump_sections(pgcore_t *pgc) 684 { 685 struct ps_prochandle *P = pgc->P; 686 file_info_t *fptr; 687 uint_t cnt; 688 uint_t index = 1; 689 690 if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB))) 691 return (0); 692 693 fptr = list_next(&P->file_head); 694 for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) { 695 int hit_symtab = 0; 696 697 Pbuild_file_symtab(P, fptr); 698 699 if ((pgc->pgc_content & CC_CONTENT_CTF) && 700 Pbuild_file_ctf(P, fptr) != NULL) { 701 sym_tbl_t *sym; 702 uint_t dynsym; 703 uint_t symindex = 0; 704 705 /* 706 * Write the symtab out first so we can correctly 707 * set the sh_link field in the CTF section header. 708 * symindex will be 0 if there is no corresponding 709 * symbol table section. 710 */ 711 if (fptr->file_ctf_dyn) { 712 sym = &fptr->file_dynsym; 713 dynsym = 1; 714 } else { 715 sym = &fptr->file_symtab; 716 dynsym = 0; 717 hit_symtab = 1; 718 } 719 720 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 && 721 sym->sym_strs != NULL) { 722 symindex = index; 723 if (dump_symtab(pgc, fptr, index, dynsym) != 0) 724 return (-1); 725 index += 2; 726 } 727 728 /* 729 * Write the CTF data that we've read out of the 730 * file itself into the core file. 731 */ 732 if (pwrite64(pgc->pgc_fd, fptr->file_ctf_buf, 733 fptr->file_ctf_size, *pgc->pgc_doff) != 734 fptr->file_ctf_size) 735 return (-1); 736 737 if (write_shdr(pgc, STR_CTF, SHT_PROGBITS, 0, 738 fptr->file_map->map_pmap.pr_vaddr, *pgc->pgc_doff, 739 fptr->file_ctf_size, symindex, 0, 4, 0) != 0) 740 return (-1); 741 742 index++; 743 *pgc->pgc_doff += roundup(fptr->file_ctf_size, 8); 744 } 745 746 if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab && 747 fptr->file_symtab.sym_data_pri != NULL && 748 fptr->file_symtab.sym_symn != 0 && 749 fptr->file_symtab.sym_strs != NULL) { 750 if (dump_symtab(pgc, fptr, index, 0) != 0) 751 return (-1); 752 index += 2; 753 } 754 } 755 756 return (0); 757 } 758 759 /*ARGSUSED*/ 760 static int 761 dump_map(void *data, const prmap_t *pmp, const char *name) 762 { 763 pgcore_t *pgc = data; 764 struct ps_prochandle *P = pgc->P; 765 #ifdef _LP64 766 Elf64_Phdr phdr; 767 #else 768 Elf32_Phdr phdr; 769 #endif 770 size_t n; 771 772 bzero(&phdr, sizeof (phdr)); 773 phdr.p_type = PT_LOAD; 774 phdr.p_vaddr = pmp->pr_vaddr; 775 phdr.p_memsz = pmp->pr_size; 776 if (pmp->pr_mflags & MA_READ) 777 phdr.p_flags |= PF_R; 778 if (pmp->pr_mflags & MA_WRITE) 779 phdr.p_flags |= PF_W; 780 if (pmp->pr_mflags & MA_EXEC) 781 phdr.p_flags |= PF_X; 782 783 if (pmp->pr_vaddr + pmp->pr_size > P->status.pr_stkbase && 784 pmp->pr_vaddr < P->status.pr_stkbase + P->status.pr_stksize) { 785 if (!(pgc->pgc_content & CC_CONTENT_STACK)) 786 goto exclude; 787 788 } else if ((pmp->pr_mflags & MA_ANON) && 789 pmp->pr_vaddr + pmp->pr_size > P->status.pr_brkbase && 790 pmp->pr_vaddr < P->status.pr_brkbase + P->status.pr_brksize) { 791 if (!(pgc->pgc_content & CC_CONTENT_HEAP)) 792 goto exclude; 793 794 } else if (pmp->pr_mflags & MA_ISM) { 795 if (pmp->pr_mflags & MA_NORESERVE) { 796 if (!(pgc->pgc_content & CC_CONTENT_DISM)) 797 goto exclude; 798 } else { 799 if (!(pgc->pgc_content & CC_CONTENT_ISM)) 800 goto exclude; 801 } 802 803 } else if (pmp->pr_mflags & MA_SHM) { 804 if (!(pgc->pgc_content & CC_CONTENT_SHM)) 805 goto exclude; 806 807 } else if (pmp->pr_mflags & MA_SHARED) { 808 if (pmp->pr_mflags & MA_ANON) { 809 if (!(pgc->pgc_content & CC_CONTENT_SHANON)) 810 goto exclude; 811 } else { 812 if (!(pgc->pgc_content & CC_CONTENT_SHFILE)) 813 goto exclude; 814 } 815 816 } else if (pmp->pr_mflags & MA_ANON) { 817 if (!(pgc->pgc_content & CC_CONTENT_ANON)) 818 goto exclude; 819 820 } else if (phdr.p_flags == (PF_R | PF_X)) { 821 if (!(pgc->pgc_content & CC_CONTENT_TEXT)) 822 goto exclude; 823 824 } else if (phdr.p_flags == PF_R) { 825 if (!(pgc->pgc_content & CC_CONTENT_RODATA)) 826 goto exclude; 827 828 } else { 829 if (!(pgc->pgc_content & CC_CONTENT_DATA)) 830 goto exclude; 831 } 832 833 n = 0; 834 while (n < pmp->pr_size) { 835 size_t csz = MIN(pmp->pr_size - n, pgc->pgc_chunksz); 836 837 /* 838 * If we can't read out part of the victim's address 839 * space for some reason ignore that failure and try to 840 * emit a partial core file without that mapping's data. 841 * As in the kernel, we mark these failures with the 842 * PF_SUNW_FAILURE flag and store the errno where the 843 * mapping would have been. 844 */ 845 if (Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n) !=