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