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