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