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