8158 Want named threads API
[unleashed.git] / usr / src / lib / libproc / common / Pgcore.c
blob64ef98065bcc1208624193e00962fe3c8545f502
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
28 * Copyright 2018 Joyent, Inc.
29 * Copyright (c) 2013 by Delphix. All rights reserved.
32 #define _STRUCTURED_PROC 1
34 #include <stdlib.h>
35 #include <ctype.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <errno.h>
39 #include <procfs.h>
40 #include <priv.h>
41 #include <sys/elf.h>
42 #include <sys/machelf.h>
43 #include <sys/sysmacros.h>
44 #include <sys/systeminfo.h>
45 #include <sys/proc.h>
46 #include <sys/utsname.h>
48 #include <sys/old_procfs.h>
50 #include "Pcontrol.h"
51 #include "P32ton.h"
53 typedef enum {
54 STR_NONE,
55 STR_CTF,
56 STR_SYMTAB,
57 STR_DYNSYM,
58 STR_STRTAB,
59 STR_DYNSTR,
60 STR_SHSTRTAB,
61 STR_NUM
62 } shstrtype_t;
64 static const char *shstrtab_data[] = {
65 "",
66 ".SUNW_ctf",
67 ".symtab",
68 ".dynsym",
69 ".strtab",
70 ".dynstr",
71 ".shstrtab"
74 typedef struct shstrtab {
75 int sst_ndx[STR_NUM];
76 int sst_cur;
77 } shstrtab_t;
79 typedef struct {
80 struct ps_prochandle *P;
81 int pgc_fd;
82 off64_t *pgc_poff;
83 off64_t *pgc_soff;
84 off64_t *pgc_doff;
85 core_content_t pgc_content;
86 void *pgc_chunk;
87 size_t pgc_chunksz;
89 shstrtab_t pgc_shstrtab;
90 } pgcore_t;
92 typedef struct {
93 int fd_fd;
94 off64_t *fd_doff;
95 } fditer_t;
97 static int
98 gc_pwrite64(int fd, const void *buf, size_t len, off64_t off)
100 int err;
102 err = pwrite64(fd, buf, len, off);
104 if (err < 0)
105 return (err);
108 * We will take a page from ZFS's book here and use the otherwise
109 * unused EBADE to mean a short write. Typically this will actually
110 * result from ENOSPC or EDQUOT, but we can't be sure.
112 if (err < len) {
113 errno = EBADE;
114 return (-1);
117 return (0);
120 static void
121 shstrtab_init(shstrtab_t *s)
123 bzero(&s->sst_ndx, sizeof (s->sst_ndx));
124 s->sst_cur = 1;
127 static int
128 shstrtab_ndx(shstrtab_t *s, shstrtype_t type)
130 int ret;
132 if ((ret = s->sst_ndx[type]) != 0 || type == STR_NONE)
133 return (ret);
135 ret = s->sst_ndx[type] = s->sst_cur;
136 s->sst_cur += strlen(shstrtab_data[type]) + 1;
138 return (ret);
141 static size_t
142 shstrtab_size(const shstrtab_t *s)
144 return (s->sst_cur);
148 Pgcore(struct ps_prochandle *P, const char *fname, core_content_t content)
150 int fd;
151 int err;
152 int saved_errno;
154 if ((fd = creat64(fname, 0666)) < 0)
155 return (-1);
157 if ((err = Pfgcore(P, fd, content)) != 0) {
158 saved_errno = errno;
159 (void) close(fd);
160 (void) unlink(fname);
161 errno = saved_errno;
162 return (err);
165 return (close(fd));
169 * Since we don't want to use the old-school procfs interfaces, we use the
170 * new-style data structures we already have to construct the old-style
171 * data structures. We include these data structures in core files for
172 * backward compatability.
175 static void
176 mkprstatus(struct ps_prochandle *P, const lwpstatus_t *lsp,
177 const lwpsinfo_t *lip, prstatus_t *psp)
179 bzero(psp, sizeof (*psp));
181 if (lsp->pr_flags & PR_STOPPED)
182 psp->pr_flags = 0x0001;
183 if (lsp->pr_flags & PR_ISTOP)
184 psp->pr_flags = 0x0002;
185 if (lsp->pr_flags & PR_DSTOP)
186 psp->pr_flags = 0x0004;
187 if (lsp->pr_flags & PR_ASLEEP)
188 psp->pr_flags = 0x0008;
189 if (lsp->pr_flags & PR_FORK)
190 psp->pr_flags = 0x0010;
191 if (lsp->pr_flags & PR_RLC)
192 psp->pr_flags = 0x0020;
194 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
195 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
197 if (lsp->pr_flags & PR_PCINVAL)
198 psp->pr_flags = 0x0080;
199 if (lsp->pr_flags & PR_ISSYS)
200 psp->pr_flags = 0x0100;
201 if (lsp->pr_flags & PR_STEP)
202 psp->pr_flags = 0x0200;
203 if (lsp->pr_flags & PR_KLC)
204 psp->pr_flags = 0x0400;
205 if (lsp->pr_flags & PR_ASYNC)
206 psp->pr_flags = 0x0800;
207 if (lsp->pr_flags & PR_PTRACE)
208 psp->pr_flags = 0x1000;
209 if (lsp->pr_flags & PR_MSACCT)
210 psp->pr_flags = 0x2000;
211 if (lsp->pr_flags & PR_BPTADJ)
212 psp->pr_flags = 0x4000;
213 if (lsp->pr_flags & PR_ASLWP)
214 psp->pr_flags = 0x8000;
216 psp->pr_why = lsp->pr_why;
217 psp->pr_what = lsp->pr_what;
218 psp->pr_info = lsp->pr_info;
219 psp->pr_cursig = lsp->pr_cursig;
220 psp->pr_nlwp = P->status.pr_nlwp;
221 psp->pr_sigpend = P->status.pr_sigpend;
222 psp->pr_sighold = lsp->pr_lwphold;
223 psp->pr_altstack = lsp->pr_altstack;
224 psp->pr_action = lsp->pr_action;
225 psp->pr_pid = P->status.pr_pid;
226 psp->pr_ppid = P->status.pr_ppid;
227 psp->pr_pgrp = P->status.pr_pgid;
228 psp->pr_sid = P->status.pr_sid;
229 psp->pr_utime = P->status.pr_utime;
230 psp->pr_stime = P->status.pr_stime;
231 psp->pr_cutime = P->status.pr_cutime;
232 psp->pr_cstime = P->status.pr_cstime;
233 (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
234 psp->pr_syscall = lsp->pr_syscall;
235 psp->pr_nsysarg = lsp->pr_nsysarg;
236 bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg));
237 psp->pr_who = lsp->pr_lwpid;
238 psp->pr_lwppend = lsp->pr_lwppend;
239 psp->pr_oldcontext = (ucontext_t *)lsp->pr_oldcontext;
240 psp->pr_brkbase = (caddr_t)P->status.pr_brkbase;
241 psp->pr_brksize = P->status.pr_brksize;
242 psp->pr_stkbase = (caddr_t)P->status.pr_stkbase;
243 psp->pr_stksize = P->status.pr_stksize;
244 psp->pr_processor = (short)lip->pr_onpro;
245 psp->pr_bind = (short)lip->pr_bindpro;
246 psp->pr_instr = lsp->pr_instr;
247 bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
250 static void
251 mkprpsinfo(struct ps_prochandle *P, prpsinfo_t *psp)
253 bzero(psp, sizeof (*psp));
254 psp->pr_state = P->psinfo.pr_lwp.pr_state;
255 psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
256 psp->pr_zomb = (psp->pr_state == SZOMB);
257 psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
258 psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
259 psp->pr_uid = P->psinfo.pr_uid;
260 psp->pr_gid = P->psinfo.pr_gid;
261 psp->pr_pid = P->psinfo.pr_pid;
262 psp->pr_ppid = P->psinfo.pr_ppid;
263 psp->pr_pgrp = P->psinfo.pr_pgid;
264 psp->pr_sid = P->psinfo.pr_sid;
265 psp->pr_addr = (caddr_t)P->psinfo.pr_addr;
266 psp->pr_size = P->psinfo.pr_size;
267 psp->pr_rssize = P->psinfo.pr_rssize;
268 psp->pr_wchan = (caddr_t)P->psinfo.pr_lwp.pr_wchan;
269 psp->pr_start = P->psinfo.pr_start;
270 psp->pr_time = P->psinfo.pr_time;
271 psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
272 psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
273 psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
274 psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
275 psp->pr_lttydev = P->psinfo.pr_ttydev;
276 (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
277 sizeof (psp->pr_clname));
278 (void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
279 sizeof (psp->pr_fname));
280 bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
281 sizeof (psp->pr_psargs));
282 psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
283 psp->pr_ctime = P->psinfo.pr_ctime;
284 psp->pr_bysize = psp->pr_size * PAGESIZE;
285 psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
286 psp->pr_argc = P->psinfo.pr_argc;
287 psp->pr_argv = (char **)P->psinfo.pr_argv;
288 psp->pr_envp = (char **)P->psinfo.pr_envp;
289 psp->pr_wstat = P->psinfo.pr_wstat;
290 psp->pr_pctcpu = P->psinfo.pr_pctcpu;
291 psp->pr_pctmem = P->psinfo.pr_pctmem;
292 psp->pr_euid = P->psinfo.pr_euid;
293 psp->pr_egid = P->psinfo.pr_egid;
294 psp->pr_aslwpid = 0;
295 psp->pr_dmodel = P->psinfo.pr_dmodel;
298 #ifdef _LP64
300 static void
301 mkprstatus32(struct ps_prochandle *P, const lwpstatus_t *lsp,
302 const lwpsinfo_t *lip, prstatus32_t *psp)
304 bzero(psp, sizeof (*psp));
306 if (lsp->pr_flags & PR_STOPPED)
307 psp->pr_flags = 0x0001;
308 if (lsp->pr_flags & PR_ISTOP)
309 psp->pr_flags = 0x0002;
310 if (lsp->pr_flags & PR_DSTOP)
311 psp->pr_flags = 0x0004;
312 if (lsp->pr_flags & PR_ASLEEP)
313 psp->pr_flags = 0x0008;
314 if (lsp->pr_flags & PR_FORK)
315 psp->pr_flags = 0x0010;
316 if (lsp->pr_flags & PR_RLC)
317 psp->pr_flags = 0x0020;
319 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
320 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
322 if (lsp->pr_flags & PR_PCINVAL)
323 psp->pr_flags = 0x0080;
324 if (lsp->pr_flags & PR_ISSYS)
325 psp->pr_flags = 0x0100;
326 if (lsp->pr_flags & PR_STEP)
327 psp->pr_flags = 0x0200;
328 if (lsp->pr_flags & PR_KLC)
329 psp->pr_flags = 0x0400;
330 if (lsp->pr_flags & PR_ASYNC)
331 psp->pr_flags = 0x0800;
332 if (lsp->pr_flags & PR_PTRACE)
333 psp->pr_flags = 0x1000;
334 if (lsp->pr_flags & PR_MSACCT)
335 psp->pr_flags = 0x2000;
336 if (lsp->pr_flags & PR_BPTADJ)
337 psp->pr_flags = 0x4000;
338 if (lsp->pr_flags & PR_ASLWP)
339 psp->pr_flags = 0x8000;
341 psp->pr_why = lsp->pr_why;
342 psp->pr_what = lsp->pr_what;
343 siginfo_n_to_32(&lsp->pr_info, &psp->pr_info);
344 psp->pr_cursig = lsp->pr_cursig;
345 psp->pr_nlwp = P->status.pr_nlwp;
346 psp->pr_sigpend = P->status.pr_sigpend;
347 psp->pr_sighold = lsp->pr_lwphold;
348 stack_n_to_32(&lsp->pr_altstack, &psp->pr_altstack);
349 sigaction_n_to_32(&lsp->pr_action, &psp->pr_action);
350 psp->pr_pid = P->status.pr_pid;
351 psp->pr_ppid = P->status.pr_ppid;
352 psp->pr_pgrp = P->status.pr_pgid;
353 psp->pr_sid = P->status.pr_sid;
354 timestruc_n_to_32(&P->status.pr_utime, &psp->pr_utime);
355 timestruc_n_to_32(&P->status.pr_stime, &psp->pr_stime);
356 timestruc_n_to_32(&P->status.pr_cutime, &psp->pr_cutime);
357 timestruc_n_to_32(&P->status.pr_cstime, &psp->pr_cstime);
358 (void) strncpy(psp->pr_clname, lsp->pr_clname, sizeof (psp->pr_clname));
359 psp->pr_syscall = lsp->pr_syscall;
360 psp->pr_nsysarg = lsp->pr_nsysarg;
361 bcopy(lsp->pr_sysarg, psp->pr_sysarg, sizeof (psp->pr_sysarg));
362 psp->pr_who = lsp->pr_lwpid;
363 psp->pr_lwppend = lsp->pr_lwppend;
364 psp->pr_oldcontext = (caddr32_t)lsp->pr_oldcontext;
365 psp->pr_brkbase = (caddr32_t)P->status.pr_brkbase;
366 psp->pr_brksize = P->status.pr_brksize;
367 psp->pr_stkbase = (caddr32_t)P->status.pr_stkbase;
368 psp->pr_stksize = P->status.pr_stksize;
369 psp->pr_processor = (short)lip->pr_onpro;
370 psp->pr_bind = (short)lip->pr_bindpro;
371 psp->pr_instr = lsp->pr_instr;
372 bcopy(lsp->pr_reg, psp->pr_reg, sizeof (psp->pr_sysarg));
375 static void
376 mkprpsinfo32(struct ps_prochandle *P, prpsinfo32_t *psp)
378 bzero(psp, sizeof (*psp));
379 psp->pr_state = P->psinfo.pr_lwp.pr_state;
380 psp->pr_sname = P->psinfo.pr_lwp.pr_sname;
381 psp->pr_zomb = (psp->pr_state == SZOMB);
382 psp->pr_nice = P->psinfo.pr_lwp.pr_nice;
383 psp->pr_flag = P->psinfo.pr_lwp.pr_flag;
384 psp->pr_uid = P->psinfo.pr_uid;
385 psp->pr_gid = P->psinfo.pr_gid;
386 psp->pr_pid = P->psinfo.pr_pid;
387 psp->pr_ppid = P->psinfo.pr_ppid;
388 psp->pr_pgrp = P->psinfo.pr_pgid;
389 psp->pr_sid = P->psinfo.pr_sid;
390 psp->pr_addr = (caddr32_t)P->psinfo.pr_addr;
391 psp->pr_size = P->psinfo.pr_size;
392 psp->pr_rssize = P->psinfo.pr_rssize;
393 psp->pr_wchan = (caddr32_t)P->psinfo.pr_lwp.pr_wchan;
394 timestruc_n_to_32(&P->psinfo.pr_start, &psp->pr_start);
395 timestruc_n_to_32(&P->psinfo.pr_time, &psp->pr_time);
396 psp->pr_pri = P->psinfo.pr_lwp.pr_pri;
397 psp->pr_oldpri = P->psinfo.pr_lwp.pr_oldpri;
398 psp->pr_cpu = P->psinfo.pr_lwp.pr_cpu;
399 psp->pr_ottydev = cmpdev(P->psinfo.pr_ttydev);
400 psp->pr_lttydev = prcmpldev(P->psinfo.pr_ttydev);
401 (void) strncpy(psp->pr_clname, P->psinfo.pr_lwp.pr_clname,
402 sizeof (psp->pr_clname));
403 (void) strncpy(psp->pr_fname, P->psinfo.pr_fname,
404 sizeof (psp->pr_fname));
405 bcopy(&P->psinfo.pr_psargs, &psp->pr_psargs,
406 sizeof (psp->pr_psargs));
407 psp->pr_syscall = P->psinfo.pr_lwp.pr_syscall;
408 timestruc_n_to_32(&P->psinfo.pr_ctime, &psp->pr_ctime);
409 psp->pr_bysize = psp->pr_size * PAGESIZE;
410 psp->pr_byrssize = psp->pr_rssize * PAGESIZE;
411 psp->pr_argc = P->psinfo.pr_argc;
412 psp->pr_argv = (caddr32_t)P->psinfo.pr_argv;
413 psp->pr_envp = (caddr32_t)P->psinfo.pr_envp;
414 psp->pr_wstat = P->psinfo.pr_wstat;
415 psp->pr_pctcpu = P->psinfo.pr_pctcpu;
416 psp->pr_pctmem = P->psinfo.pr_pctmem;
417 psp->pr_euid = P->psinfo.pr_euid;
418 psp->pr_egid = P->psinfo.pr_egid;
419 psp->pr_aslwpid = 0;
420 psp->pr_dmodel = P->psinfo.pr_dmodel;
423 #endif /* _LP64 */
425 static int
426 write_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp)
429 * Note headers are the same regardless of the data model of the
430 * ELF file; we arbitrarily use Elf64_Nhdr here.
432 struct {
433 Elf64_Nhdr nhdr;
434 char name[8];
435 } n;
437 bzero(&n, sizeof (n));
438 bcopy("CORE", n.name, 4);
439 n.nhdr.n_type = type;
440 n.nhdr.n_namesz = 5;
441 n.nhdr.n_descsz = roundup(descsz, 4);
443 if (gc_pwrite64(fd, &n, sizeof (n), *offp) != 0)
444 return (-1);
446 *offp += sizeof (n);
448 if (gc_pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != 0)
449 return (-1);
451 *offp += n.nhdr.n_descsz;
453 return (0);
456 static int
457 old_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
459 pgcore_t *pgc = data;
460 struct ps_prochandle *P = pgc->P;
463 * Legacy core files don't contain information about zombie LWPs.
464 * We use Plwp_iter_all() so that we get the lwpsinfo_t structure
465 * more cheaply.
467 if (lsp == NULL)
468 return (0);
470 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
471 prstatus_t prstatus;
472 mkprstatus(P, lsp, lip, &prstatus);
473 if (write_note(pgc->pgc_fd, NT_PRSTATUS, &prstatus,
474 sizeof (prstatus_t), pgc->pgc_doff) != 0)
475 return (0);
476 if (write_note(pgc->pgc_fd, NT_PRFPREG, &lsp->pr_fpreg,
477 sizeof (prfpregset_t), pgc->pgc_doff) != 0)
478 return (1);
479 #ifdef _LP64
480 } else {
481 prstatus32_t pr32;
482 prfpregset32_t pf32;
483 mkprstatus32(P, lsp, lip, &pr32);
484 if (write_note(pgc->pgc_fd, NT_PRSTATUS, &pr32,
485 sizeof (prstatus32_t), pgc->pgc_doff) != 0)
486 return (1);
487 prfpregset_n_to_32(&lsp->pr_fpreg, &pf32);
488 if (write_note(pgc->pgc_fd, NT_PRFPREG, &pf32,
489 sizeof (prfpregset32_t), pgc->pgc_doff) != 0)
490 return (1);
491 #endif /* _LP64 */
494 #ifdef sparc
496 prxregset_t xregs;
497 if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0 &&
498 write_note(pgc->pgc_fd, NT_PRXREG, &xregs,
499 sizeof (prxregset_t), pgc->pgc_doff) != 0)
500 return (1);
502 #endif /* sparc */
504 return (0);
507 static int
508 new_per_lwp(void *data, const lwpstatus_t *lsp, const lwpsinfo_t *lip)
510 pgcore_t *pgc = data;
511 struct ps_prochandle *P = pgc->P;
512 prlwpname_t name = { 0, "" };
513 psinfo_t ps;
516 * If lsp is NULL this indicates that this is a zombie LWP in
517 * which case we dump only the lwpsinfo_t structure and none of
518 * the other ancillary LWP state data.
520 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
521 if (write_note(pgc->pgc_fd, NT_LWPSINFO, lip,
522 sizeof (lwpsinfo_t), pgc->pgc_doff) != 0)
523 return (1);
524 if (lsp == NULL)
525 return (0);
526 if (write_note(pgc->pgc_fd, NT_LWPSTATUS, lsp,
527 sizeof (lwpstatus_t), pgc->pgc_doff) != 0)
528 return (1);
529 #ifdef _LP64
530 } else {
531 lwpsinfo32_t li32;
532 lwpstatus32_t ls32;
533 lwpsinfo_n_to_32(lip, &li32);
534 if (write_note(pgc->pgc_fd, NT_LWPSINFO, &li32,
535 sizeof (lwpsinfo32_t), pgc->pgc_doff) != 0)
536 return (1);
537 if (lsp == NULL)
538 return (0);
539 lwpstatus_n_to_32(lsp, &ls32);
540 if (write_note(pgc->pgc_fd, NT_LWPSTATUS, &ls32,
541 sizeof (lwpstatus32_t), pgc->pgc_doff) != 0)
542 return (1);
543 #endif /* _LP64 */
546 #ifdef sparc
548 prxregset_t xregs;
549 gwindows_t gwins;
550 size_t size;
552 if (Plwp_getxregs(P, lsp->pr_lwpid, &xregs) == 0) {
553 if (write_note(pgc->pgc_fd, NT_PRXREG, &xregs,
554 sizeof (prxregset_t), pgc->pgc_doff) != 0)
555 return (1);
558 if (Plwp_getgwindows(P, lsp->pr_lwpid, &gwins) == 0 &&
559 gwins.wbcnt > 0) {
560 size = sizeof (gwins) - sizeof (gwins.wbuf) +
561 gwins.wbcnt * sizeof (gwins.wbuf[0]);
563 if (write_note(pgc->pgc_fd, NT_GWINDOWS, &gwins, size,
564 pgc->pgc_doff) != 0)
565 return (1);
569 #ifdef __sparcv9
570 if (P->status.pr_dmodel == PR_MODEL_LP64) {
571 asrset_t asrs;
572 if (Plwp_getasrs(P, lsp->pr_lwpid, asrs) == 0) {
573 if (write_note(pgc->pgc_fd, NT_ASRS, &asrs,
574 sizeof (asrset_t), pgc->pgc_doff) != 0)
575 return (1);
578 #endif /* __sparcv9 */
579 #endif /* sparc */
581 if (Plwp_getname(P, lsp->pr_lwpid, name.pr_lwpname,
582 sizeof (name.pr_lwpname)) == 0) {
583 name.pr_lwpid = lsp->pr_lwpid;
584 if (write_note(pgc->pgc_fd, NT_LWPNAME, &name,
585 sizeof (name), pgc->pgc_doff) != 0)
586 return (1);
589 if (!(lsp->pr_flags & PR_AGENT))
590 return (0);
592 if (Plwp_getspymaster(P, lsp->pr_lwpid, &ps) != 0)
593 return (0);
595 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
596 if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps,
597 sizeof (psinfo_t), pgc->pgc_doff) != 0)
598 return (1);
599 #ifdef _LP64
600 } else {
601 psinfo32_t ps32;
602 psinfo_n_to_32(&ps, &ps32);
603 if (write_note(pgc->pgc_fd, NT_SPYMASTER, &ps32,
604 sizeof (psinfo32_t), pgc->pgc_doff) != 0)
605 return (1);
606 #endif /* _LP64 */
610 return (0);
613 static int
614 iter_fd(void *data, prfdinfo_t *fdinfo)
616 fditer_t *iter = data;
618 if (write_note(iter->fd_fd, NT_FDINFO, fdinfo,
619 sizeof (*fdinfo), iter->fd_doff) != 0)
620 return (1);
621 return (0);
624 static uint_t
625 count_sections(pgcore_t *pgc)
627 struct ps_prochandle *P = pgc->P;
628 file_info_t *fptr;
629 uint_t cnt;
630 uint_t nshdrs = 0;
632 if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)))
633 return (0);
635 fptr = list_next(&P->file_head);
636 for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) {
637 int hit_symtab = 0;
639 Pbuild_file_symtab(P, fptr);
641 if ((pgc->pgc_content & CC_CONTENT_CTF) &&
642 Pbuild_file_ctf(P, fptr) != NULL) {
643 sym_tbl_t *sym;
645 nshdrs++;
647 if (fptr->file_ctf_dyn) {
648 sym = &fptr->file_dynsym;
649 } else {
650 sym = &fptr->file_symtab;
651 hit_symtab = 1;
654 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 &&
655 sym->sym_strs != NULL)
656 nshdrs += 2;
659 if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
660 fptr->file_symtab.sym_data_pri != NULL &&
661 fptr->file_symtab.sym_symn != 0 &&
662 fptr->file_symtab.sym_strs != NULL) {
663 nshdrs += 2;
667 return (nshdrs == 0 ? 0 : nshdrs + 2);
670 static int
671 write_shdr(pgcore_t *pgc, shstrtype_t name, uint_t type, ulong_t flags,
672 uintptr_t addr, ulong_t offset, size_t size, uint_t link, uint_t info,
673 uintptr_t addralign, uintptr_t entsize)
675 if (pgc->P->status.pr_dmodel == PR_MODEL_ILP32) {
676 Elf32_Shdr shdr;
678 bzero(&shdr, sizeof (shdr));
679 shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name);
680 shdr.sh_type = type;
681 shdr.sh_flags = flags;
682 shdr.sh_addr = (Elf32_Addr)addr;
683 shdr.sh_offset = offset;
684 shdr.sh_size = size;
685 shdr.sh_link = link;
686 shdr.sh_info = info;
687 shdr.sh_addralign = addralign;
688 shdr.sh_entsize = entsize;
690 if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
691 *pgc->pgc_soff) != 0)
692 return (-1);
694 *pgc->pgc_soff += sizeof (shdr);
695 #ifdef _LP64
696 } else {
697 Elf64_Shdr shdr;
699 bzero(&shdr, sizeof (shdr));
700 shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, name);
701 shdr.sh_type = type;
702 shdr.sh_flags = flags;
703 shdr.sh_addr = addr;
704 shdr.sh_offset = offset;
705 shdr.sh_size = size;
706 shdr.sh_link = link;
707 shdr.sh_info = info;
708 shdr.sh_addralign = addralign;
709 shdr.sh_entsize = entsize;
711 if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
712 *pgc->pgc_soff) != 0)
713 return (-1);
715 *pgc->pgc_soff += sizeof (shdr);
716 #endif /* _LP64 */
719 return (0);
722 static int
723 dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym)
725 sym_tbl_t *sym = dynsym ? &fptr->file_dynsym : &fptr->file_symtab;
726 shstrtype_t symname = dynsym ? STR_DYNSYM : STR_SYMTAB;
727 shstrtype_t strname = dynsym ? STR_DYNSTR : STR_STRTAB;
728 uint_t symtype = dynsym ? SHT_DYNSYM : SHT_SYMTAB;
729 size_t size;
730 uintptr_t addr = fptr->file_map->map_pmap.pr_vaddr;
732 if (sym->sym_data_pri == NULL || sym->sym_symn == 0 ||
733 sym->sym_strs == NULL)
734 return (0);
736 size = sym->sym_hdr_pri.sh_size;
737 if (gc_pwrite64(pgc->pgc_fd, sym->sym_data_pri->d_buf, size,
738 *pgc->pgc_doff) != 0)
739 return (-1);
741 if (write_shdr(pgc, symname, symtype, 0, addr, *pgc->pgc_doff, size,
742 index + 1, sym->sym_hdr_pri.sh_info, sym->sym_hdr_pri.sh_addralign,
743 sym->sym_hdr_pri.sh_entsize) != 0)
744 return (-1);
746 *pgc->pgc_doff += roundup(size, 8);
748 size = sym->sym_strhdr.sh_size;
749 if (gc_pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != 0)
750 return (-1);
752 if (write_shdr(pgc, strname, SHT_STRTAB, SHF_STRINGS, addr,
753 *pgc->pgc_doff, size, 0, 0, 1, 0) != 0)
754 return (-1);
756 *pgc->pgc_doff += roundup(size, 8);
758 return (0);
761 static int
762 dump_sections(pgcore_t *pgc)
764 struct ps_prochandle *P = pgc->P;
765 file_info_t *fptr;
766 uint_t cnt;
767 uint_t index = 1;
769 if (!(pgc->pgc_content & (CC_CONTENT_CTF | CC_CONTENT_SYMTAB)))
770 return (0);
772 fptr = list_next(&P->file_head);
773 for (cnt = P->num_files; cnt > 0; cnt--, fptr = list_next(fptr)) {
774 int hit_symtab = 0;
776 Pbuild_file_symtab(P, fptr);
778 if ((pgc->pgc_content & CC_CONTENT_CTF) &&
779 Pbuild_file_ctf(P, fptr) != NULL) {
780 sym_tbl_t *sym;
781 uint_t dynsym;
782 uint_t symindex = 0;
785 * Write the symtab out first so we can correctly
786 * set the sh_link field in the CTF section header.
787 * symindex will be 0 if there is no corresponding
788 * symbol table section.
790 if (fptr->file_ctf_dyn) {
791 sym = &fptr->file_dynsym;
792 dynsym = 1;
793 } else {
794 sym = &fptr->file_symtab;
795 dynsym = 0;
796 hit_symtab = 1;
799 if (sym->sym_data_pri != NULL && sym->sym_symn != 0 &&
800 sym->sym_strs != NULL) {
801 symindex = index;
802 if (dump_symtab(pgc, fptr, index, dynsym) != 0)
803 return (-1);
804 index += 2;
808 * Write the CTF data that we've read out of the
809 * file itself into the core file.
811 if (gc_pwrite64(pgc->pgc_fd, fptr->file_ctf_buf,
812 fptr->file_ctf_size, *pgc->pgc_doff) != 0)
813 return (-1);
815 if (write_shdr(pgc, STR_CTF, SHT_PROGBITS, 0,
816 fptr->file_map->map_pmap.pr_vaddr, *pgc->pgc_doff,
817 fptr->file_ctf_size, symindex, 0, 4, 0) != 0)
818 return (-1);
820 index++;
821 *pgc->pgc_doff += roundup(fptr->file_ctf_size, 8);
824 if ((pgc->pgc_content & CC_CONTENT_SYMTAB) && !hit_symtab &&
825 fptr->file_symtab.sym_data_pri != NULL &&
826 fptr->file_symtab.sym_symn != 0 &&
827 fptr->file_symtab.sym_strs != NULL) {
828 if (dump_symtab(pgc, fptr, index, 0) != 0)
829 return (-1);
830 index += 2;
834 return (0);
837 /*ARGSUSED*/
838 static int
839 dump_map(void *data, const prmap_t *pmp, const char *name)
841 pgcore_t *pgc = data;
842 struct ps_prochandle *P = pgc->P;
843 #ifdef _LP64
844 Elf64_Phdr phdr;
845 #else
846 Elf32_Phdr phdr;
847 #endif
848 size_t n;
850 bzero(&phdr, sizeof (phdr));
851 phdr.p_type = PT_LOAD;
852 phdr.p_vaddr = pmp->pr_vaddr;
853 phdr.p_memsz = pmp->pr_size;
854 if (pmp->pr_mflags & MA_READ)
855 phdr.p_flags |= PF_R;
856 if (pmp->pr_mflags & MA_WRITE)
857 phdr.p_flags |= PF_W;
858 if (pmp->pr_mflags & MA_EXEC)
859 phdr.p_flags |= PF_X;
861 if (pmp->pr_vaddr + pmp->pr_size > P->status.pr_stkbase &&
862 pmp->pr_vaddr < P->status.pr_stkbase + P->status.pr_stksize) {
863 if (!(pgc->pgc_content & CC_CONTENT_STACK))
864 goto exclude;
866 } else if ((pmp->pr_mflags & MA_ANON) &&
867 pmp->pr_vaddr + pmp->pr_size > P->status.pr_brkbase &&
868 pmp->pr_vaddr < P->status.pr_brkbase + P->status.pr_brksize) {
869 if (!(pgc->pgc_content & CC_CONTENT_HEAP))
870 goto exclude;
872 } else if (pmp->pr_mflags & MA_ISM) {
873 if (pmp->pr_mflags & MA_NORESERVE) {
874 if (!(pgc->pgc_content & CC_CONTENT_DISM))
875 goto exclude;
876 } else {
877 if (!(pgc->pgc_content & CC_CONTENT_ISM))
878 goto exclude;
881 } else if (pmp->pr_mflags & MA_SHM) {
882 if (!(pgc->pgc_content & CC_CONTENT_SHM))
883 goto exclude;
885 } else if (pmp->pr_mflags & MA_SHARED) {
886 if (pmp->pr_mflags & MA_ANON) {
887 if (!(pgc->pgc_content & CC_CONTENT_SHANON))
888 goto exclude;
889 } else {
890 if (!(pgc->pgc_content & CC_CONTENT_SHFILE))
891 goto exclude;
894 } else if (pmp->pr_mflags & MA_ANON) {
895 if (!(pgc->pgc_content & CC_CONTENT_ANON))
896 goto exclude;
898 } else if (phdr.p_flags == (PF_R | PF_X)) {
899 if (!(pgc->pgc_content & CC_CONTENT_TEXT))
900 goto exclude;
902 } else if (phdr.p_flags == PF_R) {
903 if (!(pgc->pgc_content & CC_CONTENT_RODATA))
904 goto exclude;
906 } else {
907 if (!(pgc->pgc_content & CC_CONTENT_DATA))
908 goto exclude;
911 n = 0;
912 while (n < pmp->pr_size) {
913 size_t csz = MIN(pmp->pr_size - n, pgc->pgc_chunksz);
916 * If we can't read out part of the victim's address
917 * space for some reason ignore that failure and try to
918 * emit a partial core file without that mapping's data.
919 * As in the kernel, we mark these failures with the
920 * PF_SUNW_FAILURE flag and store the errno where the
921 * mapping would have been.
923 if (Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n) != csz ||
924 gc_pwrite64(pgc->pgc_fd, pgc->pgc_chunk, csz,
925 *pgc->pgc_doff + n) != 0) {
926 int err = errno;
927 (void) gc_pwrite64(pgc->pgc_fd, &err, sizeof (err),
928 *pgc->pgc_doff);
929 *pgc->pgc_doff += roundup(sizeof (err), 8);
931 phdr.p_flags |= PF_SUNW_FAILURE;
932 (void) ftruncate64(pgc->pgc_fd, *pgc->pgc_doff);
933 goto exclude;
936 n += csz;
939 phdr.p_offset = *pgc->pgc_doff;
940 phdr.p_filesz = pmp->pr_size;
941 *pgc->pgc_doff += roundup(phdr.p_filesz, 8);
943 exclude:
944 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
945 if (gc_pwrite64(pgc->pgc_fd, &phdr, sizeof (phdr),
946 *pgc->pgc_poff) != 0)
947 return (1);
949 *pgc->pgc_poff += sizeof (phdr);
950 #ifdef _LP64
951 } else {
952 Elf32_Phdr phdr32;
954 bzero(&phdr32, sizeof (phdr32));
955 phdr32.p_type = phdr.p_type;
956 phdr32.p_vaddr = (Elf32_Addr)phdr.p_vaddr;
957 phdr32.p_memsz = (Elf32_Word)phdr.p_memsz;
958 phdr32.p_flags = phdr.p_flags;
959 phdr32.p_offset = (Elf32_Off)phdr.p_offset;
960 phdr32.p_filesz = (Elf32_Word)phdr.p_filesz;
962 if (gc_pwrite64(pgc->pgc_fd, &phdr32, sizeof (phdr32),
963 *pgc->pgc_poff) != 0)
964 return (1);
966 *pgc->pgc_poff += sizeof (phdr32);
967 #endif /* _LP64 */
970 return (0);
974 write_shstrtab(struct ps_prochandle *P, pgcore_t *pgc)
976 off64_t off = *pgc->pgc_doff;
977 size_t size = 0;
978 shstrtab_t *s = &pgc->pgc_shstrtab;
979 int i, ndx;
981 if (shstrtab_size(s) == 1)
982 return (0);
985 * Preemptively stick the name of the shstrtab in the string table.
987 (void) shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);
988 size = shstrtab_size(s);
991 * Dump all the strings that we used being sure we include the
992 * terminating null character.
994 for (i = 0; i < STR_NUM; i++) {
995 if ((ndx = s->sst_ndx[i]) != 0 || i == STR_NONE) {
996 const char *str = shstrtab_data[i];
997 size_t len = strlen(str) + 1;
998 if (gc_pwrite64(pgc->pgc_fd, str, len, off + ndx) != 0)
999 return (1);
1003 if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1004 Elf32_Shdr shdr;
1006 bzero(&shdr, sizeof (shdr));
1007 shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);
1008 shdr.sh_size = size;
1009 shdr.sh_offset = *pgc->pgc_doff;
1010 shdr.sh_addralign = 1;
1011 shdr.sh_flags = SHF_STRINGS;
1012 shdr.sh_type = SHT_STRTAB;
1014 if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
1015 *pgc->pgc_soff) != 0)
1016 return (1);
1018 *pgc->pgc_soff += sizeof (shdr);
1019 #ifdef _LP64
1020 } else {
1021 Elf64_Shdr shdr;
1023 bzero(&shdr, sizeof (shdr));
1024 shdr.sh_name = shstrtab_ndx(&pgc->pgc_shstrtab, STR_SHSTRTAB);
1025 shdr.sh_size = size;
1026 shdr.sh_offset = *pgc->pgc_doff;
1027 shdr.sh_addralign = 1;
1028 shdr.sh_flags = SHF_STRINGS;
1029 shdr.sh_type = SHT_STRTAB;
1031 if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
1032 *pgc->pgc_soff) != 0)
1033 return (1);
1035 *pgc->pgc_soff += sizeof (shdr);
1036 #endif /* _LP64 */
1039 *pgc->pgc_doff += roundup(size, 8);
1041 return (0);
1045 * Don't explicity stop the process; that's up to the consumer.
1048 Pfgcore(struct ps_prochandle *P, int fd, core_content_t content)
1050 char plat[SYS_NMLN];
1051 char zonename[ZONENAME_MAX];
1052 int platlen = -1;
1053 pgcore_t pgc;
1054 off64_t poff, soff, doff, boff;
1055 struct utsname uts;
1056 uint_t nphdrs, nshdrs;
1058 if (ftruncate64(fd, 0) != 0)
1059 return (-1);
1061 if (content == CC_CONTENT_INVALID) {
1062 errno = EINVAL;
1063 return (-1);
1067 * Cache the mappings and other useful data.
1069 (void) Prd_agent(P);
1070 (void) Ppsinfo(P);
1072 pgc.P = P;
1073 pgc.pgc_fd = fd;
1074 pgc.pgc_poff = &poff;
1075 pgc.pgc_soff = &soff;
1076 pgc.pgc_doff = &doff;
1077 pgc.pgc_content = content;
1078 pgc.pgc_chunksz = PAGESIZE;
1079 if ((pgc.pgc_chunk = malloc(pgc.pgc_chunksz)) == NULL)
1080 return (-1);
1082 shstrtab_init(&pgc.pgc_shstrtab);
1085 * There are two PT_NOTE program headers for ancillary data, and
1086 * one for each mapping.
1088 nphdrs = 2 + P->map_count;
1089 nshdrs = count_sections(&pgc);
1091 (void) Pplatform(P, plat, sizeof (plat));
1092 platlen = strlen(plat) + 1;
1093 Preadauxvec(P);
1094 (void) Puname(P, &uts);
1095 if (Pzonename(P, zonename, sizeof (zonename)) == NULL)
1096 zonename[0] = '\0';
1099 * The core file contents may required zero section headers, but if we
1100 * overflow the 16 bits allotted to the program header count in the ELF
1101 * header, we'll need that program header at index zero.
1103 if (nshdrs == 0 && nphdrs >= PN_XNUM)
1104 nshdrs = 1;
1107 * Set up the ELF header.
1109 if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1110 Elf32_Ehdr ehdr;
1112 bzero(&ehdr, sizeof (ehdr));
1113 ehdr.e_ident[EI_MAG0] = ELFMAG0;
1114 ehdr.e_ident[EI_MAG1] = ELFMAG1;
1115 ehdr.e_ident[EI_MAG2] = ELFMAG2;
1116 ehdr.e_ident[EI_MAG3] = ELFMAG3;
1117 ehdr.e_type = ET_CORE;
1119 ehdr.e_ident[EI_CLASS] = ELFCLASS32;
1120 #if defined(__sparc)
1121 ehdr.e_machine = EM_SPARC;
1122 ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
1123 #elif defined(__i386) || defined(__amd64)
1124 ehdr.e_machine = EM_386;
1125 ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
1126 #else
1127 #error "unknown machine type"
1128 #endif
1129 ehdr.e_ident[EI_VERSION] = EV_CURRENT;
1131 ehdr.e_version = EV_CURRENT;
1132 ehdr.e_ehsize = sizeof (ehdr);
1134 if (nphdrs >= PN_XNUM)
1135 ehdr.e_phnum = PN_XNUM;
1136 else
1137 ehdr.e_phnum = (unsigned short)nphdrs;
1139 ehdr.e_phentsize = sizeof (Elf32_Phdr);
1140 ehdr.e_phoff = ehdr.e_ehsize;
1142 if (nshdrs > 0) {
1143 if (nshdrs >= SHN_LORESERVE)
1144 ehdr.e_shnum = 0;
1145 else
1146 ehdr.e_shnum = (unsigned short)nshdrs;
1148 if (nshdrs - 1 >= SHN_LORESERVE)
1149 ehdr.e_shstrndx = SHN_XINDEX;
1150 else
1151 ehdr.e_shstrndx = (unsigned short)(nshdrs - 1);
1153 ehdr.e_shentsize = sizeof (Elf32_Shdr);
1154 ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs;
1157 if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0)
1158 goto err;
1160 poff = ehdr.e_phoff;
1161 soff = ehdr.e_shoff;
1162 doff = boff = ehdr.e_ehsize +
1163 ehdr.e_phentsize * nphdrs +
1164 ehdr.e_shentsize * nshdrs;
1166 #ifdef _LP64
1167 } else {
1168 Elf64_Ehdr ehdr;
1170 bzero(&ehdr, sizeof (ehdr));
1171 ehdr.e_ident[EI_MAG0] = ELFMAG0;
1172 ehdr.e_ident[EI_MAG1] = ELFMAG1;
1173 ehdr.e_ident[EI_MAG2] = ELFMAG2;
1174 ehdr.e_ident[EI_MAG3] = ELFMAG3;
1175 ehdr.e_type = ET_CORE;
1177 ehdr.e_ident[EI_CLASS] = ELFCLASS64;
1178 #if defined(__sparc)
1179 ehdr.e_machine = EM_SPARCV9;
1180 ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
1181 #elif defined(__i386) || defined(__amd64)
1182 ehdr.e_machine = EM_AMD64;
1183 ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
1184 #else
1185 #error "unknown machine type"
1186 #endif
1187 ehdr.e_ident[EI_VERSION] = EV_CURRENT;
1189 ehdr.e_version = EV_CURRENT;
1190 ehdr.e_ehsize = sizeof (ehdr);
1192 if (nphdrs >= PN_XNUM)
1193 ehdr.e_phnum = PN_XNUM;
1194 else
1195 ehdr.e_phnum = (unsigned short)nphdrs;
1197 ehdr.e_phentsize = sizeof (Elf64_Phdr);
1198 ehdr.e_phoff = ehdr.e_ehsize;
1200 if (nshdrs > 0) {
1201 if (nshdrs >= SHN_LORESERVE)
1202 ehdr.e_shnum = 0;
1203 else
1204 ehdr.e_shnum = (unsigned short)nshdrs;
1206 if (nshdrs - 1 >= SHN_LORESERVE)
1207 ehdr.e_shstrndx = SHN_XINDEX;
1208 else
1209 ehdr.e_shstrndx = (unsigned short)(nshdrs - 1);
1211 ehdr.e_shentsize = sizeof (Elf64_Shdr);
1212 ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs;
1215 if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0)
1216 goto err;
1218 poff = ehdr.e_phoff;
1219 soff = ehdr.e_shoff;
1220 doff = boff = ehdr.e_ehsize +
1221 ehdr.e_phentsize * nphdrs +
1222 ehdr.e_shentsize * nshdrs;
1224 #endif /* _LP64 */
1228 * Write the zero indexed section if it exists.
1230 if (nshdrs > 0 && write_shdr(&pgc, STR_NONE, 0, 0, 0, 0,
1231 nshdrs >= SHN_LORESERVE ? nshdrs : 0,
1232 nshdrs - 1 >= SHN_LORESERVE ? nshdrs - 1 : 0,
1233 nphdrs >= PN_XNUM ? nphdrs : 0, 0, 0) != 0)
1234 goto err;
1237 * Construct the old-style note header and section.
1240 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
1241 prpsinfo_t prpsinfo;
1243 mkprpsinfo(P, &prpsinfo);
1244 if (write_note(fd, NT_PRPSINFO, &prpsinfo, sizeof (prpsinfo_t),
1245 &doff) != 0) {
1246 goto err;
1248 if (write_note(fd, NT_AUXV, P->auxv,
1249 P->nauxv * sizeof (P->auxv[0]), &doff) != 0) {
1250 goto err;
1252 #ifdef _LP64
1253 } else {
1254 prpsinfo32_t pi32;
1255 auxv32_t *av32;
1256 size_t size = sizeof (auxv32_t) * P->nauxv;
1257 int i;
1259 mkprpsinfo32(P, &pi32);
1260 if (write_note(fd, NT_PRPSINFO, &pi32, sizeof (prpsinfo32_t),
1261 &doff) != 0) {
1262 goto err;
1265 if ((av32 = malloc(size)) == NULL)
1266 goto err;
1268 for (i = 0; i < P->nauxv; i++) {
1269 auxv_n_to_32(&P->auxv[i], &av32[i]);
1272 if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) {
1273 free(av32);
1274 goto err;
1277 free(av32);
1278 #endif /* _LP64 */
1281 if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0)
1282 goto err;
1284 if (Plwp_iter_all(P, old_per_lwp, &pgc) != 0)
1285 goto err;
1287 if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1288 Elf32_Phdr phdr;
1290 bzero(&phdr, sizeof (phdr));
1291 phdr.p_type = PT_NOTE;
1292 phdr.p_flags = PF_R;
1293 phdr.p_offset = (Elf32_Off)boff;
1294 phdr.p_filesz = doff - boff;
1295 boff = doff;
1297 if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
1298 goto err;
1299 poff += sizeof (phdr);
1300 #ifdef _LP64
1301 } else {
1302 Elf64_Phdr phdr;
1304 bzero(&phdr, sizeof (phdr));
1305 phdr.p_type = PT_NOTE;
1306 phdr.p_flags = PF_R;
1307 phdr.p_offset = boff;
1308 phdr.p_filesz = doff - boff;
1309 boff = doff;
1311 if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
1312 goto err;
1313 poff += sizeof (phdr);
1314 #endif /* _LP64 */
1318 * Construct the new-style note header and section.
1321 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
1322 if (write_note(fd, NT_PSINFO, &P->psinfo, sizeof (psinfo_t),
1323 &doff) != 0) {
1324 goto err;
1326 if (write_note(fd, NT_PSTATUS, &P->status, sizeof (pstatus_t),
1327 &doff) != 0) {
1328 goto err;
1330 if (write_note(fd, NT_AUXV, P->auxv,
1331 P->nauxv * sizeof (P->auxv[0]), &doff) != 0) {
1332 goto err;
1334 #ifdef _LP64
1335 } else {
1336 psinfo32_t pi32;
1337 pstatus32_t ps32;
1338 auxv32_t *av32;
1339 size_t size = sizeof (auxv32_t) * P->nauxv;
1340 int i;
1342 psinfo_n_to_32(&P->psinfo, &pi32);
1343 if (write_note(fd, NT_PSINFO, &pi32, sizeof (psinfo32_t),
1344 &doff) != 0) {
1345 goto err;
1347 pstatus_n_to_32(&P->status, &ps32);
1348 if (write_note(fd, NT_PSTATUS, &ps32, sizeof (pstatus32_t),
1349 &doff) != 0) {
1350 goto err;
1352 if ((av32 = malloc(size)) == NULL)
1353 goto err;
1355 for (i = 0; i < P->nauxv; i++) {
1356 auxv_n_to_32(&P->auxv[i], &av32[i]);
1359 if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) {
1360 free(av32);
1361 goto err;
1364 free(av32);
1365 #endif /* _LP64 */
1368 if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0 ||
1369 write_note(fd, NT_UTSNAME, &uts, sizeof (uts), &doff) != 0 ||
1370 write_note(fd, NT_CONTENT, &content, sizeof (content), &doff) != 0)
1371 goto err;
1374 prcred_t cred, *cp;
1375 size_t size = sizeof (prcred_t);
1377 if (Pcred(P, &cred, 0) != 0)
1378 goto err;
1380 if (cred.pr_ngroups > 0)
1381 size += sizeof (gid_t) * (cred.pr_ngroups - 1);
1382 if ((cp = malloc(size)) == NULL)
1383 goto err;
1385 if (Pcred(P, cp, cred.pr_ngroups) != 0 ||
1386 write_note(fd, NT_PRCRED, cp, size, &doff) != 0) {
1387 free(cp);
1388 goto err;
1391 free(cp);
1395 prpriv_t *ppriv = NULL;
1396 const priv_impl_info_t *pinfo;
1397 size_t pprivsz, pinfosz;
1399 if (Ppriv(P, &ppriv) == -1)
1400 goto err;
1401 pprivsz = PRIV_PRPRIV_SIZE(ppriv);
1403 if (write_note(fd, NT_PRPRIV, ppriv, pprivsz, &doff) != 0) {
1404 Ppriv_free(P, ppriv);
1405 goto err;
1407 Ppriv_free(P, ppriv);
1409 if ((pinfo = getprivimplinfo()) == NULL)
1410 goto err;
1411 pinfosz = PRIV_IMPL_INFO_SIZE(pinfo);
1413 if (write_note(fd, NT_PRPRIVINFO, pinfo, pinfosz, &doff) != 0)
1414 goto err;
1417 if (write_note(fd, NT_ZONENAME, zonename, strlen(zonename) + 1,
1418 &doff) != 0)
1419 goto err;
1422 fditer_t iter;
1423 iter.fd_fd = fd;
1424 iter.fd_doff = &doff;
1426 if (Pfdinfo_iter(P, iter_fd, &iter) != 0)
1427 goto err;
1432 prsecflags_t *psf = NULL;
1434 if (Psecflags(P, &psf) != 0)
1435 goto err;
1437 if (write_note(fd, NT_SECFLAGS, psf,
1438 sizeof (prsecflags_t), &doff) != 0) {
1439 Psecflags_free(psf);
1440 goto err;
1443 Psecflags_free(psf);
1446 #if defined(__i386) || defined(__amd64)
1447 /* CSTYLED */
1449 struct ssd *ldtp;
1450 size_t size;
1451 int nldt;
1454 * Only dump out non-zero sized LDT notes.
1456 if ((nldt = Pldt(P, NULL, 0)) != 0) {
1457 size = sizeof (struct ssd) * nldt;
1458 if ((ldtp = malloc(size)) == NULL)
1459 goto err;
1461 if (Pldt(P, ldtp, nldt) == -1 ||
1462 write_note(fd, NT_LDT, ldtp, size, &doff) != 0) {
1463 free(ldtp);
1464 goto err;
1467 free(ldtp);
1470 #endif /* __i386 || __amd64 */
1472 if (Plwp_iter_all(P, new_per_lwp, &pgc) != 0)
1473 goto err;
1475 if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1476 Elf32_Phdr phdr;
1478 bzero(&phdr, sizeof (phdr));
1479 phdr.p_type = PT_NOTE;
1480 phdr.p_flags = PF_R;
1481 phdr.p_offset = (Elf32_Off)boff;
1482 phdr.p_filesz = doff - boff;
1483 boff = doff;
1485 if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
1486 goto err;
1487 poff += sizeof (phdr);
1488 #ifdef _LP64
1489 } else {
1490 Elf64_Phdr phdr;
1492 bzero(&phdr, sizeof (phdr));
1493 phdr.p_type = PT_NOTE;
1494 phdr.p_flags = PF_R;
1495 phdr.p_offset = boff;
1496 phdr.p_filesz = doff - boff;
1497 boff = doff;
1499 if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
1500 goto err;
1501 poff += sizeof (phdr);
1502 #endif /* _LP64 */
1506 * Construct the headers for each mapping and write out its data
1507 * if the content parameter indicates that it should be present
1508 * in the core file.
1510 if (Pmapping_iter(P, dump_map, &pgc) != 0)
1511 goto err;
1513 if (dump_sections(&pgc) != 0)
1514 goto err;
1516 if (write_shstrtab(P, &pgc) != 0)
1517 goto err;
1519 free(pgc.pgc_chunk);
1521 return (0);
1523 err:
1525 * Wipe out anything we may have written if there was an error.
1527 (void) ftruncate64(fd, 0);
1528 free(pgc.pgc_chunk);
1530 return (-1);
1533 static const char *content_str[] = {
1534 "stack", /* CC_CONTENT_STACK */
1535 "heap", /* CC_CONTENT_HEAP */
1536 "shfile", /* CC_CONTENT_SHFILE */
1537 "shanon", /* CC_CONTENT_SHANON */
1538 "text", /* CC_CONTENT_TEXT */
1539 "data", /* CC_CONTENT_DATA */
1540 "rodata", /* CC_CONTENT_RODATA */
1541 "anon", /* CC_CONTENT_ANON */
1542 "shm", /* CC_CONTENT_SHM */
1543 "ism", /* CC_CONTENT_ISM */
1544 "dism", /* CC_CONTENT_DISM */
1545 "ctf", /* CC_CONTENT_CTF */
1546 "symtab", /* CC_CONTENT_SYMTAB */
1549 static uint_t ncontent_str = sizeof (content_str) / sizeof (content_str[0]);
1551 #define STREQ(a, b, n) (strlen(b) == (n) && strncmp(a, b, n) == 0)
1554 proc_str2content(const char *str, core_content_t *cp)
1556 const char *cur = str;
1557 int add = 1;
1558 core_content_t mask, content = 0;
1560 for (;;) {
1561 for (cur = str; isalpha(*cur); cur++)
1562 continue;
1564 if (STREQ(str, "default", cur - str)) {
1565 mask = CC_CONTENT_DEFAULT;
1566 } else if (STREQ(str, "all", cur - str)) {
1567 mask = CC_CONTENT_ALL;
1568 } else if (STREQ(str, "none", cur - str)) {
1569 mask = 0;
1570 } else {
1571 int i = 0;
1573 while (!STREQ(str, content_str[i], cur - str)) {
1574 i++;
1576 if (i >= ncontent_str)
1577 return (-1);
1580 mask = (core_content_t)1 << i;
1583 if (add)
1584 content |= mask;
1585 else
1586 content &= ~mask;
1588 switch (*cur) {
1589 case '\0':
1590 *cp = content;
1591 return (0);
1592 case '+':
1593 add = 1;
1594 break;
1595 case '-':
1596 add = 0;
1597 break;
1598 default:
1599 return (-1);
1602 str = cur + 1;
1606 static int
1607 popc(core_content_t x)
1609 int i;
1611 for (i = 0; x != 0; i++)
1612 x &= x - 1;
1614 return (i);
1618 proc_content2str(core_content_t content, char *buf, size_t size)
1620 int nonecnt, defcnt, allcnt;
1621 core_content_t mask, bit;
1622 int first;
1623 uint_t index;
1624 size_t n, tot = 0;
1626 if (content == 0)
1627 return ((int)strlcpy(buf, "none", size));
1629 if (content & ~CC_CONTENT_ALL)
1630 return ((int)strlcpy(buf, "<invalid>", size));
1632 nonecnt = popc(content);
1633 defcnt = 1 + popc(content ^ CC_CONTENT_DEFAULT);
1634 allcnt = 1 + popc(content ^ CC_CONTENT_ALL);
1636 if (defcnt <= nonecnt && defcnt <= allcnt) {
1637 mask = content ^ CC_CONTENT_DEFAULT;
1638 first = 0;
1639 tot += (n = strlcpy(buf, "default", size));
1640 if (n > size)
1641 n = size;
1642 buf += n;
1643 size -= n;
1644 } else if (allcnt < nonecnt) {
1645 mask = content ^ CC_CONTENT_ALL;
1646 first = 0;
1647 tot += (n = strlcpy(buf, "all", size));
1648 if (n > size)
1649 n = size;
1650 buf += n;
1651 size -= n;
1652 } else {
1653 mask = content;
1654 first = 1;
1657 while (mask != 0) {
1658 bit = mask ^ (mask & (mask - 1));
1660 if (!first) {
1661 if (size > 1) {
1662 *buf = (bit & content) ? '+' : '-';
1663 buf++;
1664 size--;
1667 tot++;
1669 index = popc(bit - 1);
1670 tot += (n = strlcpy(buf, content_str[index], size));
1671 if (n > size)
1672 n = size;
1673 buf += n;
1674 size -= n;
1676 mask ^= bit;
1677 first = 0;
1680 return ((int)tot);