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