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