4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
28 * Copyright 2018 Joyent, Inc.
29 * Copyright (c) 2013 by Delphix. All rights reserved.
32 #define _STRUCTURED_PROC 1
42 #include <sys/machelf.h>
43 #include <sys/sysmacros.h>
44 #include <sys/systeminfo.h>
46 #include <sys/utsname.h>
48 #include <sys/old_procfs.h>
64 static const char *shstrtab_data
[] = {
74 typedef struct shstrtab
{
80 struct ps_prochandle
*P
;
85 core_content_t pgc_content
;
89 shstrtab_t pgc_shstrtab
;
98 gc_pwrite64(int fd
, const void *buf
, size_t len
, off64_t off
)
102 err
= pwrite64(fd
, buf
, len
, off
);
108 * We will take a page from ZFS's book here and use the otherwise
109 * unused EBADE to mean a short write. Typically this will actually
110 * result from ENOSPC or EDQUOT, but we can't be sure.
121 shstrtab_init(shstrtab_t
*s
)
123 bzero(&s
->sst_ndx
, sizeof (s
->sst_ndx
));
128 shstrtab_ndx(shstrtab_t
*s
, shstrtype_t type
)
132 if ((ret
= s
->sst_ndx
[type
]) != 0 || type
== STR_NONE
)
135 ret
= s
->sst_ndx
[type
] = s
->sst_cur
;
136 s
->sst_cur
+= strlen(shstrtab_data
[type
]) + 1;
142 shstrtab_size(const shstrtab_t
*s
)
148 Pgcore(struct ps_prochandle
*P
, const char *fname
, core_content_t content
)
154 if ((fd
= creat64(fname
, 0666)) < 0)
157 if ((err
= Pfgcore(P
, fd
, content
)) != 0) {
160 (void) unlink(fname
);
169 * Since we don't want to use the old-school procfs interfaces, we use the
170 * new-style data structures we already have to construct the old-style
171 * data structures. We include these data structures in core files for
172 * backward compatability.
176 mkprstatus(struct ps_prochandle
*P
, const lwpstatus_t
*lsp
,
177 const lwpsinfo_t
*lip
, prstatus_t
*psp
)
179 bzero(psp
, sizeof (*psp
));
181 if (lsp
->pr_flags
& PR_STOPPED
)
182 psp
->pr_flags
= 0x0001;
183 if (lsp
->pr_flags
& PR_ISTOP
)
184 psp
->pr_flags
= 0x0002;
185 if (lsp
->pr_flags
& PR_DSTOP
)
186 psp
->pr_flags
= 0x0004;
187 if (lsp
->pr_flags
& PR_ASLEEP
)
188 psp
->pr_flags
= 0x0008;
189 if (lsp
->pr_flags
& PR_FORK
)
190 psp
->pr_flags
= 0x0010;
191 if (lsp
->pr_flags
& PR_RLC
)
192 psp
->pr_flags
= 0x0020;
194 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
195 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
197 if (lsp
->pr_flags
& PR_PCINVAL
)
198 psp
->pr_flags
= 0x0080;
199 if (lsp
->pr_flags
& PR_ISSYS
)
200 psp
->pr_flags
= 0x0100;
201 if (lsp
->pr_flags
& PR_STEP
)
202 psp
->pr_flags
= 0x0200;
203 if (lsp
->pr_flags
& PR_KLC
)
204 psp
->pr_flags
= 0x0400;
205 if (lsp
->pr_flags
& PR_ASYNC
)
206 psp
->pr_flags
= 0x0800;
207 if (lsp
->pr_flags
& PR_PTRACE
)
208 psp
->pr_flags
= 0x1000;
209 if (lsp
->pr_flags
& PR_MSACCT
)
210 psp
->pr_flags
= 0x2000;
211 if (lsp
->pr_flags
& PR_BPTADJ
)
212 psp
->pr_flags
= 0x4000;
213 if (lsp
->pr_flags
& PR_ASLWP
)
214 psp
->pr_flags
= 0x8000;
216 psp
->pr_why
= lsp
->pr_why
;
217 psp
->pr_what
= lsp
->pr_what
;
218 psp
->pr_info
= lsp
->pr_info
;
219 psp
->pr_cursig
= lsp
->pr_cursig
;
220 psp
->pr_nlwp
= P
->status
.pr_nlwp
;
221 psp
->pr_sigpend
= P
->status
.pr_sigpend
;
222 psp
->pr_sighold
= lsp
->pr_lwphold
;
223 psp
->pr_altstack
= lsp
->pr_altstack
;
224 psp
->pr_action
= lsp
->pr_action
;
225 psp
->pr_pid
= P
->status
.pr_pid
;
226 psp
->pr_ppid
= P
->status
.pr_ppid
;
227 psp
->pr_pgrp
= P
->status
.pr_pgid
;
228 psp
->pr_sid
= P
->status
.pr_sid
;
229 psp
->pr_utime
= P
->status
.pr_utime
;
230 psp
->pr_stime
= P
->status
.pr_stime
;
231 psp
->pr_cutime
= P
->status
.pr_cutime
;
232 psp
->pr_cstime
= P
->status
.pr_cstime
;
233 (void) strncpy(psp
->pr_clname
, lsp
->pr_clname
, sizeof (psp
->pr_clname
));
234 psp
->pr_syscall
= lsp
->pr_syscall
;
235 psp
->pr_nsysarg
= lsp
->pr_nsysarg
;
236 bcopy(lsp
->pr_sysarg
, psp
->pr_sysarg
, sizeof (psp
->pr_sysarg
));
237 psp
->pr_who
= lsp
->pr_lwpid
;
238 psp
->pr_lwppend
= lsp
->pr_lwppend
;
239 psp
->pr_oldcontext
= (ucontext_t
*)lsp
->pr_oldcontext
;
240 psp
->pr_brkbase
= (caddr_t
)P
->status
.pr_brkbase
;
241 psp
->pr_brksize
= P
->status
.pr_brksize
;
242 psp
->pr_stkbase
= (caddr_t
)P
->status
.pr_stkbase
;
243 psp
->pr_stksize
= P
->status
.pr_stksize
;
244 psp
->pr_processor
= (short)lip
->pr_onpro
;
245 psp
->pr_bind
= (short)lip
->pr_bindpro
;
246 psp
->pr_instr
= lsp
->pr_instr
;
247 bcopy(lsp
->pr_reg
, psp
->pr_reg
, sizeof (psp
->pr_sysarg
));
251 mkprpsinfo(struct ps_prochandle
*P
, prpsinfo_t
*psp
)
253 bzero(psp
, sizeof (*psp
));
254 psp
->pr_state
= P
->psinfo
.pr_lwp
.pr_state
;
255 psp
->pr_sname
= P
->psinfo
.pr_lwp
.pr_sname
;
256 psp
->pr_zomb
= (psp
->pr_state
== SZOMB
);
257 psp
->pr_nice
= P
->psinfo
.pr_lwp
.pr_nice
;
258 psp
->pr_flag
= P
->psinfo
.pr_lwp
.pr_flag
;
259 psp
->pr_uid
= P
->psinfo
.pr_uid
;
260 psp
->pr_gid
= P
->psinfo
.pr_gid
;
261 psp
->pr_pid
= P
->psinfo
.pr_pid
;
262 psp
->pr_ppid
= P
->psinfo
.pr_ppid
;
263 psp
->pr_pgrp
= P
->psinfo
.pr_pgid
;
264 psp
->pr_sid
= P
->psinfo
.pr_sid
;
265 psp
->pr_addr
= (caddr_t
)P
->psinfo
.pr_addr
;
266 psp
->pr_size
= P
->psinfo
.pr_size
;
267 psp
->pr_rssize
= P
->psinfo
.pr_rssize
;
268 psp
->pr_wchan
= (caddr_t
)P
->psinfo
.pr_lwp
.pr_wchan
;
269 psp
->pr_start
= P
->psinfo
.pr_start
;
270 psp
->pr_time
= P
->psinfo
.pr_time
;
271 psp
->pr_pri
= P
->psinfo
.pr_lwp
.pr_pri
;
272 psp
->pr_oldpri
= P
->psinfo
.pr_lwp
.pr_oldpri
;
273 psp
->pr_cpu
= P
->psinfo
.pr_lwp
.pr_cpu
;
274 psp
->pr_ottydev
= cmpdev(P
->psinfo
.pr_ttydev
);
275 psp
->pr_lttydev
= P
->psinfo
.pr_ttydev
;
276 (void) strncpy(psp
->pr_clname
, P
->psinfo
.pr_lwp
.pr_clname
,
277 sizeof (psp
->pr_clname
));
278 (void) strncpy(psp
->pr_fname
, P
->psinfo
.pr_fname
,
279 sizeof (psp
->pr_fname
));
280 bcopy(&P
->psinfo
.pr_psargs
, &psp
->pr_psargs
,
281 sizeof (psp
->pr_psargs
));
282 psp
->pr_syscall
= P
->psinfo
.pr_lwp
.pr_syscall
;
283 psp
->pr_ctime
= P
->psinfo
.pr_ctime
;
284 psp
->pr_bysize
= psp
->pr_size
* PAGESIZE
;
285 psp
->pr_byrssize
= psp
->pr_rssize
* PAGESIZE
;
286 psp
->pr_argc
= P
->psinfo
.pr_argc
;
287 psp
->pr_argv
= (char **)P
->psinfo
.pr_argv
;
288 psp
->pr_envp
= (char **)P
->psinfo
.pr_envp
;
289 psp
->pr_wstat
= P
->psinfo
.pr_wstat
;
290 psp
->pr_pctcpu
= P
->psinfo
.pr_pctcpu
;
291 psp
->pr_pctmem
= P
->psinfo
.pr_pctmem
;
292 psp
->pr_euid
= P
->psinfo
.pr_euid
;
293 psp
->pr_egid
= P
->psinfo
.pr_egid
;
295 psp
->pr_dmodel
= P
->psinfo
.pr_dmodel
;
301 mkprstatus32(struct ps_prochandle
*P
, const lwpstatus_t
*lsp
,
302 const lwpsinfo_t
*lip
, prstatus32_t
*psp
)
304 bzero(psp
, sizeof (*psp
));
306 if (lsp
->pr_flags
& PR_STOPPED
)
307 psp
->pr_flags
= 0x0001;
308 if (lsp
->pr_flags
& PR_ISTOP
)
309 psp
->pr_flags
= 0x0002;
310 if (lsp
->pr_flags
& PR_DSTOP
)
311 psp
->pr_flags
= 0x0004;
312 if (lsp
->pr_flags
& PR_ASLEEP
)
313 psp
->pr_flags
= 0x0008;
314 if (lsp
->pr_flags
& PR_FORK
)
315 psp
->pr_flags
= 0x0010;
316 if (lsp
->pr_flags
& PR_RLC
)
317 psp
->pr_flags
= 0x0020;
319 * Note that PR_PTRACE (0x0040) from <sys/old_procfs.h> is never set;
320 * PR_PCOMPAT corresponds to PR_PTRACE in the newer <sys/procfs.h>.
322 if (lsp
->pr_flags
& PR_PCINVAL
)
323 psp
->pr_flags
= 0x0080;
324 if (lsp
->pr_flags
& PR_ISSYS
)
325 psp
->pr_flags
= 0x0100;
326 if (lsp
->pr_flags
& PR_STEP
)
327 psp
->pr_flags
= 0x0200;
328 if (lsp
->pr_flags
& PR_KLC
)
329 psp
->pr_flags
= 0x0400;
330 if (lsp
->pr_flags
& PR_ASYNC
)
331 psp
->pr_flags
= 0x0800;
332 if (lsp
->pr_flags
& PR_PTRACE
)
333 psp
->pr_flags
= 0x1000;
334 if (lsp
->pr_flags
& PR_MSACCT
)
335 psp
->pr_flags
= 0x2000;
336 if (lsp
->pr_flags
& PR_BPTADJ
)
337 psp
->pr_flags
= 0x4000;
338 if (lsp
->pr_flags
& PR_ASLWP
)
339 psp
->pr_flags
= 0x8000;
341 psp
->pr_why
= lsp
->pr_why
;
342 psp
->pr_what
= lsp
->pr_what
;
343 siginfo_n_to_32(&lsp
->pr_info
, &psp
->pr_info
);
344 psp
->pr_cursig
= lsp
->pr_cursig
;
345 psp
->pr_nlwp
= P
->status
.pr_nlwp
;
346 psp
->pr_sigpend
= P
->status
.pr_sigpend
;
347 psp
->pr_sighold
= lsp
->pr_lwphold
;
348 stack_n_to_32(&lsp
->pr_altstack
, &psp
->pr_altstack
);
349 sigaction_n_to_32(&lsp
->pr_action
, &psp
->pr_action
);
350 psp
->pr_pid
= P
->status
.pr_pid
;
351 psp
->pr_ppid
= P
->status
.pr_ppid
;
352 psp
->pr_pgrp
= P
->status
.pr_pgid
;
353 psp
->pr_sid
= P
->status
.pr_sid
;
354 timestruc_n_to_32(&P
->status
.pr_utime
, &psp
->pr_utime
);
355 timestruc_n_to_32(&P
->status
.pr_stime
, &psp
->pr_stime
);
356 timestruc_n_to_32(&P
->status
.pr_cutime
, &psp
->pr_cutime
);
357 timestruc_n_to_32(&P
->status
.pr_cstime
, &psp
->pr_cstime
);
358 (void) strncpy(psp
->pr_clname
, lsp
->pr_clname
, sizeof (psp
->pr_clname
));
359 psp
->pr_syscall
= lsp
->pr_syscall
;
360 psp
->pr_nsysarg
= lsp
->pr_nsysarg
;
361 bcopy(lsp
->pr_sysarg
, psp
->pr_sysarg
, sizeof (psp
->pr_sysarg
));
362 psp
->pr_who
= lsp
->pr_lwpid
;
363 psp
->pr_lwppend
= lsp
->pr_lwppend
;
364 psp
->pr_oldcontext
= (caddr32_t
)lsp
->pr_oldcontext
;
365 psp
->pr_brkbase
= (caddr32_t
)P
->status
.pr_brkbase
;
366 psp
->pr_brksize
= P
->status
.pr_brksize
;
367 psp
->pr_stkbase
= (caddr32_t
)P
->status
.pr_stkbase
;
368 psp
->pr_stksize
= P
->status
.pr_stksize
;
369 psp
->pr_processor
= (short)lip
->pr_onpro
;
370 psp
->pr_bind
= (short)lip
->pr_bindpro
;
371 psp
->pr_instr
= lsp
->pr_instr
;
372 bcopy(lsp
->pr_reg
, psp
->pr_reg
, sizeof (psp
->pr_sysarg
));
376 mkprpsinfo32(struct ps_prochandle
*P
, prpsinfo32_t
*psp
)
378 bzero(psp
, sizeof (*psp
));
379 psp
->pr_state
= P
->psinfo
.pr_lwp
.pr_state
;
380 psp
->pr_sname
= P
->psinfo
.pr_lwp
.pr_sname
;
381 psp
->pr_zomb
= (psp
->pr_state
== SZOMB
);
382 psp
->pr_nice
= P
->psinfo
.pr_lwp
.pr_nice
;
383 psp
->pr_flag
= P
->psinfo
.pr_lwp
.pr_flag
;
384 psp
->pr_uid
= P
->psinfo
.pr_uid
;
385 psp
->pr_gid
= P
->psinfo
.pr_gid
;
386 psp
->pr_pid
= P
->psinfo
.pr_pid
;
387 psp
->pr_ppid
= P
->psinfo
.pr_ppid
;
388 psp
->pr_pgrp
= P
->psinfo
.pr_pgid
;
389 psp
->pr_sid
= P
->psinfo
.pr_sid
;
390 psp
->pr_addr
= (caddr32_t
)P
->psinfo
.pr_addr
;
391 psp
->pr_size
= P
->psinfo
.pr_size
;
392 psp
->pr_rssize
= P
->psinfo
.pr_rssize
;
393 psp
->pr_wchan
= (caddr32_t
)P
->psinfo
.pr_lwp
.pr_wchan
;
394 timestruc_n_to_32(&P
->psinfo
.pr_start
, &psp
->pr_start
);
395 timestruc_n_to_32(&P
->psinfo
.pr_time
, &psp
->pr_time
);
396 psp
->pr_pri
= P
->psinfo
.pr_lwp
.pr_pri
;
397 psp
->pr_oldpri
= P
->psinfo
.pr_lwp
.pr_oldpri
;
398 psp
->pr_cpu
= P
->psinfo
.pr_lwp
.pr_cpu
;
399 psp
->pr_ottydev
= cmpdev(P
->psinfo
.pr_ttydev
);
400 psp
->pr_lttydev
= prcmpldev(P
->psinfo
.pr_ttydev
);
401 (void) strncpy(psp
->pr_clname
, P
->psinfo
.pr_lwp
.pr_clname
,
402 sizeof (psp
->pr_clname
));
403 (void) strncpy(psp
->pr_fname
, P
->psinfo
.pr_fname
,
404 sizeof (psp
->pr_fname
));
405 bcopy(&P
->psinfo
.pr_psargs
, &psp
->pr_psargs
,
406 sizeof (psp
->pr_psargs
));
407 psp
->pr_syscall
= P
->psinfo
.pr_lwp
.pr_syscall
;
408 timestruc_n_to_32(&P
->psinfo
.pr_ctime
, &psp
->pr_ctime
);
409 psp
->pr_bysize
= psp
->pr_size
* PAGESIZE
;
410 psp
->pr_byrssize
= psp
->pr_rssize
* PAGESIZE
;
411 psp
->pr_argc
= P
->psinfo
.pr_argc
;
412 psp
->pr_argv
= (caddr32_t
)P
->psinfo
.pr_argv
;
413 psp
->pr_envp
= (caddr32_t
)P
->psinfo
.pr_envp
;
414 psp
->pr_wstat
= P
->psinfo
.pr_wstat
;
415 psp
->pr_pctcpu
= P
->psinfo
.pr_pctcpu
;
416 psp
->pr_pctmem
= P
->psinfo
.pr_pctmem
;
417 psp
->pr_euid
= P
->psinfo
.pr_euid
;
418 psp
->pr_egid
= P
->psinfo
.pr_egid
;
420 psp
->pr_dmodel
= P
->psinfo
.pr_dmodel
;
426 write_note(int fd
, uint_t type
, const void *desc
, size_t descsz
, off64_t
*offp
)
429 * Note headers are the same regardless of the data model of the
430 * ELF file; we arbitrarily use Elf64_Nhdr here.
437 bzero(&n
, sizeof (n
));
438 bcopy("CORE", n
.name
, 4);
439 n
.nhdr
.n_type
= type
;
441 n
.nhdr
.n_descsz
= roundup(descsz
, 4);
443 if (gc_pwrite64(fd
, &n
, sizeof (n
), *offp
) != 0)
448 if (gc_pwrite64(fd
, desc
, n
.nhdr
.n_descsz
, *offp
) != 0)
451 *offp
+= n
.nhdr
.n_descsz
;
457 old_per_lwp(void *data
, const lwpstatus_t
*lsp
, const lwpsinfo_t
*lip
)
459 pgcore_t
*pgc
= data
;
460 struct ps_prochandle
*P
= pgc
->P
;
463 * Legacy core files don't contain information about zombie LWPs.
464 * We use Plwp_iter_all() so that we get the lwpsinfo_t structure
470 if (P
->status
.pr_dmodel
== PR_MODEL_NATIVE
) {
472 mkprstatus(P
, lsp
, lip
, &prstatus
);
473 if (write_note(pgc
->pgc_fd
, NT_PRSTATUS
, &prstatus
,
474 sizeof (prstatus_t
), pgc
->pgc_doff
) != 0)
476 if (write_note(pgc
->pgc_fd
, NT_PRFPREG
, &lsp
->pr_fpreg
,
477 sizeof (prfpregset_t
), pgc
->pgc_doff
) != 0)
483 mkprstatus32(P
, lsp
, lip
, &pr32
);
484 if (write_note(pgc
->pgc_fd
, NT_PRSTATUS
, &pr32
,
485 sizeof (prstatus32_t
), pgc
->pgc_doff
) != 0)
487 prfpregset_n_to_32(&lsp
->pr_fpreg
, &pf32
);
488 if (write_note(pgc
->pgc_fd
, NT_PRFPREG
, &pf32
,
489 sizeof (prfpregset32_t
), pgc
->pgc_doff
) != 0)
497 if (Plwp_getxregs(P
, lsp
->pr_lwpid
, &xregs
) == 0 &&
498 write_note(pgc
->pgc_fd
, NT_PRXREG
, &xregs
,
499 sizeof (prxregset_t
), pgc
->pgc_doff
) != 0)
508 new_per_lwp(void *data
, const lwpstatus_t
*lsp
, const lwpsinfo_t
*lip
)
510 pgcore_t
*pgc
= data
;
511 struct ps_prochandle
*P
= pgc
->P
;
512 prlwpname_t name
= { 0, "" };
516 * If lsp is NULL this indicates that this is a zombie LWP in
517 * which case we dump only the lwpsinfo_t structure and none of
518 * the other ancillary LWP state data.
520 if (P
->status
.pr_dmodel
== PR_MODEL_NATIVE
) {
521 if (write_note(pgc
->pgc_fd
, NT_LWPSINFO
, lip
,
522 sizeof (lwpsinfo_t
), pgc
->pgc_doff
) != 0)
526 if (write_note(pgc
->pgc_fd
, NT_LWPSTATUS
, lsp
,
527 sizeof (lwpstatus_t
), pgc
->pgc_doff
) != 0)
533 lwpsinfo_n_to_32(lip
, &li32
);
534 if (write_note(pgc
->pgc_fd
, NT_LWPSINFO
, &li32
,
535 sizeof (lwpsinfo32_t
), pgc
->pgc_doff
) != 0)
539 lwpstatus_n_to_32(lsp
, &ls32
);
540 if (write_note(pgc
->pgc_fd
, NT_LWPSTATUS
, &ls32
,
541 sizeof (lwpstatus32_t
), pgc
->pgc_doff
) != 0)
552 if (Plwp_getxregs(P
, lsp
->pr_lwpid
, &xregs
) == 0) {
553 if (write_note(pgc
->pgc_fd
, NT_PRXREG
, &xregs
,
554 sizeof (prxregset_t
), pgc
->pgc_doff
) != 0)
558 if (Plwp_getgwindows(P
, lsp
->pr_lwpid
, &gwins
) == 0 &&
560 size
= sizeof (gwins
) - sizeof (gwins
.wbuf
) +
561 gwins
.wbcnt
* sizeof (gwins
.wbuf
[0]);
563 if (write_note(pgc
->pgc_fd
, NT_GWINDOWS
, &gwins
, size
,
570 if (P
->status
.pr_dmodel
== PR_MODEL_LP64
) {
572 if (Plwp_getasrs(P
, lsp
->pr_lwpid
, asrs
) == 0) {
573 if (write_note(pgc
->pgc_fd
, NT_ASRS
, &asrs
,
574 sizeof (asrset_t
), pgc
->pgc_doff
) != 0)
578 #endif /* __sparcv9 */
581 if (Plwp_getname(P
, lsp
->pr_lwpid
, name
.pr_lwpname
,
582 sizeof (name
.pr_lwpname
)) == 0) {
583 name
.pr_lwpid
= lsp
->pr_lwpid
;
584 if (write_note(pgc
->pgc_fd
, NT_LWPNAME
, &name
,
585 sizeof (name
), pgc
->pgc_doff
) != 0)
589 if (!(lsp
->pr_flags
& PR_AGENT
))
592 if (Plwp_getspymaster(P
, lsp
->pr_lwpid
, &ps
) != 0)
595 if (P
->status
.pr_dmodel
== PR_MODEL_NATIVE
) {
596 if (write_note(pgc
->pgc_fd
, NT_SPYMASTER
, &ps
,
597 sizeof (psinfo_t
), pgc
->pgc_doff
) != 0)
602 psinfo_n_to_32(&ps
, &ps32
);
603 if (write_note(pgc
->pgc_fd
, NT_SPYMASTER
, &ps32
,
604 sizeof (psinfo32_t
), pgc
->pgc_doff
) != 0)
614 iter_fd(void *data
, prfdinfo_t
*fdinfo
)
616 fditer_t
*iter
= data
;
618 if (write_note(iter
->fd_fd
, NT_FDINFO
, fdinfo
,
619 sizeof (*fdinfo
), iter
->fd_doff
) != 0)
625 count_sections(pgcore_t
*pgc
)
627 struct ps_prochandle
*P
= pgc
->P
;
632 if (!(pgc
->pgc_content
& (CC_CONTENT_CTF
| CC_CONTENT_SYMTAB
)))
635 fptr
= list_next(&P
->file_head
);
636 for (cnt
= P
->num_files
; cnt
> 0; cnt
--, fptr
= list_next(fptr
)) {
639 Pbuild_file_symtab(P
, fptr
);
641 if ((pgc
->pgc_content
& CC_CONTENT_CTF
) &&
642 Pbuild_file_ctf(P
, fptr
) != NULL
) {
647 if (fptr
->file_ctf_dyn
) {
648 sym
= &fptr
->file_dynsym
;
650 sym
= &fptr
->file_symtab
;
654 if (sym
->sym_data_pri
!= NULL
&& sym
->sym_symn
!= 0 &&
655 sym
->sym_strs
!= NULL
)
659 if ((pgc
->pgc_content
& CC_CONTENT_SYMTAB
) && !hit_symtab
&&
660 fptr
->file_symtab
.sym_data_pri
!= NULL
&&
661 fptr
->file_symtab
.sym_symn
!= 0 &&
662 fptr
->file_symtab
.sym_strs
!= NULL
) {
667 return (nshdrs
== 0 ? 0 : nshdrs
+ 2);
671 write_shdr(pgcore_t
*pgc
, shstrtype_t name
, uint_t type
, ulong_t flags
,
672 uintptr_t addr
, ulong_t offset
, size_t size
, uint_t link
, uint_t info
,
673 uintptr_t addralign
, uintptr_t entsize
)
675 if (pgc
->P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
678 bzero(&shdr
, sizeof (shdr
));
679 shdr
.sh_name
= shstrtab_ndx(&pgc
->pgc_shstrtab
, name
);
681 shdr
.sh_flags
= flags
;
682 shdr
.sh_addr
= (Elf32_Addr
)addr
;
683 shdr
.sh_offset
= offset
;
687 shdr
.sh_addralign
= addralign
;
688 shdr
.sh_entsize
= entsize
;
690 if (gc_pwrite64(pgc
->pgc_fd
, &shdr
, sizeof (shdr
),
691 *pgc
->pgc_soff
) != 0)
694 *pgc
->pgc_soff
+= sizeof (shdr
);
699 bzero(&shdr
, sizeof (shdr
));
700 shdr
.sh_name
= shstrtab_ndx(&pgc
->pgc_shstrtab
, name
);
702 shdr
.sh_flags
= flags
;
704 shdr
.sh_offset
= offset
;
708 shdr
.sh_addralign
= addralign
;
709 shdr
.sh_entsize
= entsize
;
711 if (gc_pwrite64(pgc
->pgc_fd
, &shdr
, sizeof (shdr
),
712 *pgc
->pgc_soff
) != 0)
715 *pgc
->pgc_soff
+= sizeof (shdr
);
723 dump_symtab(pgcore_t
*pgc
, file_info_t
*fptr
, uint_t index
, int dynsym
)
725 sym_tbl_t
*sym
= dynsym
? &fptr
->file_dynsym
: &fptr
->file_symtab
;
726 shstrtype_t symname
= dynsym
? STR_DYNSYM
: STR_SYMTAB
;
727 shstrtype_t strname
= dynsym
? STR_DYNSTR
: STR_STRTAB
;
728 uint_t symtype
= dynsym
? SHT_DYNSYM
: SHT_SYMTAB
;
730 uintptr_t addr
= fptr
->file_map
->map_pmap
.pr_vaddr
;
732 if (sym
->sym_data_pri
== NULL
|| sym
->sym_symn
== 0 ||
733 sym
->sym_strs
== NULL
)
736 size
= sym
->sym_hdr_pri
.sh_size
;
737 if (gc_pwrite64(pgc
->pgc_fd
, sym
->sym_data_pri
->d_buf
, size
,
738 *pgc
->pgc_doff
) != 0)
741 if (write_shdr(pgc
, symname
, symtype
, 0, addr
, *pgc
->pgc_doff
, size
,
742 index
+ 1, sym
->sym_hdr_pri
.sh_info
, sym
->sym_hdr_pri
.sh_addralign
,
743 sym
->sym_hdr_pri
.sh_entsize
) != 0)
746 *pgc
->pgc_doff
+= roundup(size
, 8);
748 size
= sym
->sym_strhdr
.sh_size
;
749 if (gc_pwrite64(pgc
->pgc_fd
, sym
->sym_strs
, size
, *pgc
->pgc_doff
) != 0)
752 if (write_shdr(pgc
, strname
, SHT_STRTAB
, SHF_STRINGS
, addr
,
753 *pgc
->pgc_doff
, size
, 0, 0, 1, 0) != 0)
756 *pgc
->pgc_doff
+= roundup(size
, 8);
762 dump_sections(pgcore_t
*pgc
)
764 struct ps_prochandle
*P
= pgc
->P
;
769 if (!(pgc
->pgc_content
& (CC_CONTENT_CTF
| CC_CONTENT_SYMTAB
)))
772 fptr
= list_next(&P
->file_head
);
773 for (cnt
= P
->num_files
; cnt
> 0; cnt
--, fptr
= list_next(fptr
)) {
776 Pbuild_file_symtab(P
, fptr
);
778 if ((pgc
->pgc_content
& CC_CONTENT_CTF
) &&
779 Pbuild_file_ctf(P
, fptr
) != NULL
) {
785 * Write the symtab out first so we can correctly
786 * set the sh_link field in the CTF section header.
787 * symindex will be 0 if there is no corresponding
788 * symbol table section.
790 if (fptr
->file_ctf_dyn
) {
791 sym
= &fptr
->file_dynsym
;
794 sym
= &fptr
->file_symtab
;
799 if (sym
->sym_data_pri
!= NULL
&& sym
->sym_symn
!= 0 &&
800 sym
->sym_strs
!= NULL
) {
802 if (dump_symtab(pgc
, fptr
, index
, dynsym
) != 0)
808 * Write the CTF data that we've read out of the
809 * file itself into the core file.
811 if (gc_pwrite64(pgc
->pgc_fd
, fptr
->file_ctf_buf
,
812 fptr
->file_ctf_size
, *pgc
->pgc_doff
) != 0)
815 if (write_shdr(pgc
, STR_CTF
, SHT_PROGBITS
, 0,
816 fptr
->file_map
->map_pmap
.pr_vaddr
, *pgc
->pgc_doff
,
817 fptr
->file_ctf_size
, symindex
, 0, 4, 0) != 0)
821 *pgc
->pgc_doff
+= roundup(fptr
->file_ctf_size
, 8);
824 if ((pgc
->pgc_content
& CC_CONTENT_SYMTAB
) && !hit_symtab
&&
825 fptr
->file_symtab
.sym_data_pri
!= NULL
&&
826 fptr
->file_symtab
.sym_symn
!= 0 &&
827 fptr
->file_symtab
.sym_strs
!= NULL
) {
828 if (dump_symtab(pgc
, fptr
, index
, 0) != 0)
839 dump_map(void *data
, const prmap_t
*pmp
, const char *name
)
841 pgcore_t
*pgc
= data
;
842 struct ps_prochandle
*P
= pgc
->P
;
850 bzero(&phdr
, sizeof (phdr
));
851 phdr
.p_type
= PT_LOAD
;
852 phdr
.p_vaddr
= pmp
->pr_vaddr
;
853 phdr
.p_memsz
= pmp
->pr_size
;
854 if (pmp
->pr_mflags
& MA_READ
)
855 phdr
.p_flags
|= PF_R
;
856 if (pmp
->pr_mflags
& MA_WRITE
)
857 phdr
.p_flags
|= PF_W
;
858 if (pmp
->pr_mflags
& MA_EXEC
)
859 phdr
.p_flags
|= PF_X
;
861 if (pmp
->pr_vaddr
+ pmp
->pr_size
> P
->status
.pr_stkbase
&&
862 pmp
->pr_vaddr
< P
->status
.pr_stkbase
+ P
->status
.pr_stksize
) {
863 if (!(pgc
->pgc_content
& CC_CONTENT_STACK
))
866 } else if ((pmp
->pr_mflags
& MA_ANON
) &&
867 pmp
->pr_vaddr
+ pmp
->pr_size
> P
->status
.pr_brkbase
&&
868 pmp
->pr_vaddr
< P
->status
.pr_brkbase
+ P
->status
.pr_brksize
) {
869 if (!(pgc
->pgc_content
& CC_CONTENT_HEAP
))
872 } else if (pmp
->pr_mflags
& MA_ISM
) {
873 if (pmp
->pr_mflags
& MA_NORESERVE
) {
874 if (!(pgc
->pgc_content
& CC_CONTENT_DISM
))
877 if (!(pgc
->pgc_content
& CC_CONTENT_ISM
))
881 } else if (pmp
->pr_mflags
& MA_SHM
) {
882 if (!(pgc
->pgc_content
& CC_CONTENT_SHM
))
885 } else if (pmp
->pr_mflags
& MA_SHARED
) {
886 if (pmp
->pr_mflags
& MA_ANON
) {
887 if (!(pgc
->pgc_content
& CC_CONTENT_SHANON
))
890 if (!(pgc
->pgc_content
& CC_CONTENT_SHFILE
))
894 } else if (pmp
->pr_mflags
& MA_ANON
) {
895 if (!(pgc
->pgc_content
& CC_CONTENT_ANON
))
898 } else if (phdr
.p_flags
== (PF_R
| PF_X
)) {
899 if (!(pgc
->pgc_content
& CC_CONTENT_TEXT
))
902 } else if (phdr
.p_flags
== PF_R
) {
903 if (!(pgc
->pgc_content
& CC_CONTENT_RODATA
))
907 if (!(pgc
->pgc_content
& CC_CONTENT_DATA
))
912 while (n
< pmp
->pr_size
) {
913 size_t csz
= MIN(pmp
->pr_size
- n
, pgc
->pgc_chunksz
);
916 * If we can't read out part of the victim's address
917 * space for some reason ignore that failure and try to
918 * emit a partial core file without that mapping's data.
919 * As in the kernel, we mark these failures with the
920 * PF_SUNW_FAILURE flag and store the errno where the
921 * mapping would have been.
923 if (Pread(P
, pgc
->pgc_chunk
, csz
, pmp
->pr_vaddr
+ n
) != csz
||
924 gc_pwrite64(pgc
->pgc_fd
, pgc
->pgc_chunk
, csz
,
925 *pgc
->pgc_doff
+ n
) != 0) {
927 (void) gc_pwrite64(pgc
->pgc_fd
, &err
, sizeof (err
),
929 *pgc
->pgc_doff
+= roundup(sizeof (err
), 8);
931 phdr
.p_flags
|= PF_SUNW_FAILURE
;
932 (void) ftruncate64(pgc
->pgc_fd
, *pgc
->pgc_doff
);
939 phdr
.p_offset
= *pgc
->pgc_doff
;
940 phdr
.p_filesz
= pmp
->pr_size
;
941 *pgc
->pgc_doff
+= roundup(phdr
.p_filesz
, 8);
944 if (P
->status
.pr_dmodel
== PR_MODEL_NATIVE
) {
945 if (gc_pwrite64(pgc
->pgc_fd
, &phdr
, sizeof (phdr
),
946 *pgc
->pgc_poff
) != 0)
949 *pgc
->pgc_poff
+= sizeof (phdr
);
954 bzero(&phdr32
, sizeof (phdr32
));
955 phdr32
.p_type
= phdr
.p_type
;
956 phdr32
.p_vaddr
= (Elf32_Addr
)phdr
.p_vaddr
;
957 phdr32
.p_memsz
= (Elf32_Word
)phdr
.p_memsz
;
958 phdr32
.p_flags
= phdr
.p_flags
;
959 phdr32
.p_offset
= (Elf32_Off
)phdr
.p_offset
;
960 phdr32
.p_filesz
= (Elf32_Word
)phdr
.p_filesz
;
962 if (gc_pwrite64(pgc
->pgc_fd
, &phdr32
, sizeof (phdr32
),
963 *pgc
->pgc_poff
) != 0)
966 *pgc
->pgc_poff
+= sizeof (phdr32
);
974 write_shstrtab(struct ps_prochandle
*P
, pgcore_t
*pgc
)
976 off64_t off
= *pgc
->pgc_doff
;
978 shstrtab_t
*s
= &pgc
->pgc_shstrtab
;
981 if (shstrtab_size(s
) == 1)
985 * Preemptively stick the name of the shstrtab in the string table.
987 (void) shstrtab_ndx(&pgc
->pgc_shstrtab
, STR_SHSTRTAB
);
988 size
= shstrtab_size(s
);
991 * Dump all the strings that we used being sure we include the
992 * terminating null character.
994 for (i
= 0; i
< STR_NUM
; i
++) {
995 if ((ndx
= s
->sst_ndx
[i
]) != 0 || i
== STR_NONE
) {
996 const char *str
= shstrtab_data
[i
];
997 size_t len
= strlen(str
) + 1;
998 if (gc_pwrite64(pgc
->pgc_fd
, str
, len
, off
+ ndx
) != 0)
1003 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
1006 bzero(&shdr
, sizeof (shdr
));
1007 shdr
.sh_name
= shstrtab_ndx(&pgc
->pgc_shstrtab
, STR_SHSTRTAB
);
1008 shdr
.sh_size
= size
;
1009 shdr
.sh_offset
= *pgc
->pgc_doff
;
1010 shdr
.sh_addralign
= 1;
1011 shdr
.sh_flags
= SHF_STRINGS
;
1012 shdr
.sh_type
= SHT_STRTAB
;
1014 if (gc_pwrite64(pgc
->pgc_fd
, &shdr
, sizeof (shdr
),
1015 *pgc
->pgc_soff
) != 0)
1018 *pgc
->pgc_soff
+= sizeof (shdr
);
1023 bzero(&shdr
, sizeof (shdr
));
1024 shdr
.sh_name
= shstrtab_ndx(&pgc
->pgc_shstrtab
, STR_SHSTRTAB
);
1025 shdr
.sh_size
= size
;
1026 shdr
.sh_offset
= *pgc
->pgc_doff
;
1027 shdr
.sh_addralign
= 1;
1028 shdr
.sh_flags
= SHF_STRINGS
;
1029 shdr
.sh_type
= SHT_STRTAB
;
1031 if (gc_pwrite64(pgc
->pgc_fd
, &shdr
, sizeof (shdr
),
1032 *pgc
->pgc_soff
) != 0)
1035 *pgc
->pgc_soff
+= sizeof (shdr
);
1039 *pgc
->pgc_doff
+= roundup(size
, 8);
1045 * Don't explicity stop the process; that's up to the consumer.
1048 Pfgcore(struct ps_prochandle
*P
, int fd
, core_content_t content
)
1050 char plat
[SYS_NMLN
];
1051 char zonename
[ZONENAME_MAX
];
1054 off64_t poff
, soff
, doff
, boff
;
1056 uint_t nphdrs
, nshdrs
;
1058 if (ftruncate64(fd
, 0) != 0)
1061 if (content
== CC_CONTENT_INVALID
) {
1067 * Cache the mappings and other useful data.
1069 (void) Prd_agent(P
);
1074 pgc
.pgc_poff
= &poff
;
1075 pgc
.pgc_soff
= &soff
;
1076 pgc
.pgc_doff
= &doff
;
1077 pgc
.pgc_content
= content
;
1078 pgc
.pgc_chunksz
= PAGESIZE
;
1079 if ((pgc
.pgc_chunk
= malloc(pgc
.pgc_chunksz
)) == NULL
)
1082 shstrtab_init(&pgc
.pgc_shstrtab
);
1085 * There are two PT_NOTE program headers for ancillary data, and
1086 * one for each mapping.
1088 nphdrs
= 2 + P
->map_count
;
1089 nshdrs
= count_sections(&pgc
);
1091 (void) Pplatform(P
, plat
, sizeof (plat
));
1092 platlen
= strlen(plat
) + 1;
1094 (void) Puname(P
, &uts
);
1095 if (Pzonename(P
, zonename
, sizeof (zonename
)) == NULL
)
1099 * The core file contents may required zero section headers, but if we
1100 * overflow the 16 bits allotted to the program header count in the ELF
1101 * header, we'll need that program header at index zero.
1103 if (nshdrs
== 0 && nphdrs
>= PN_XNUM
)
1107 * Set up the ELF header.
1109 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
1112 bzero(&ehdr
, sizeof (ehdr
));
1113 ehdr
.e_ident
[EI_MAG0
] = ELFMAG0
;
1114 ehdr
.e_ident
[EI_MAG1
] = ELFMAG1
;
1115 ehdr
.e_ident
[EI_MAG2
] = ELFMAG2
;
1116 ehdr
.e_ident
[EI_MAG3
] = ELFMAG3
;
1117 ehdr
.e_type
= ET_CORE
;
1119 ehdr
.e_ident
[EI_CLASS
] = ELFCLASS32
;
1120 #if defined(__sparc)
1121 ehdr
.e_machine
= EM_SPARC
;
1122 ehdr
.e_ident
[EI_DATA
] = ELFDATA2MSB
;
1123 #elif defined(__i386) || defined(__amd64)
1124 ehdr
.e_machine
= EM_386
;
1125 ehdr
.e_ident
[EI_DATA
] = ELFDATA2LSB
;
1127 #error "unknown machine type"
1129 ehdr
.e_ident
[EI_VERSION
] = EV_CURRENT
;
1131 ehdr
.e_version
= EV_CURRENT
;
1132 ehdr
.e_ehsize
= sizeof (ehdr
);
1134 if (nphdrs
>= PN_XNUM
)
1135 ehdr
.e_phnum
= PN_XNUM
;
1137 ehdr
.e_phnum
= (unsigned short)nphdrs
;
1139 ehdr
.e_phentsize
= sizeof (Elf32_Phdr
);
1140 ehdr
.e_phoff
= ehdr
.e_ehsize
;
1143 if (nshdrs
>= SHN_LORESERVE
)
1146 ehdr
.e_shnum
= (unsigned short)nshdrs
;
1148 if (nshdrs
- 1 >= SHN_LORESERVE
)
1149 ehdr
.e_shstrndx
= SHN_XINDEX
;
1151 ehdr
.e_shstrndx
= (unsigned short)(nshdrs
- 1);
1153 ehdr
.e_shentsize
= sizeof (Elf32_Shdr
);
1154 ehdr
.e_shoff
= ehdr
.e_phoff
+ ehdr
.e_phentsize
* nphdrs
;
1157 if (gc_pwrite64(fd
, &ehdr
, sizeof (ehdr
), 0) != 0)
1160 poff
= ehdr
.e_phoff
;
1161 soff
= ehdr
.e_shoff
;
1162 doff
= boff
= ehdr
.e_ehsize
+
1163 ehdr
.e_phentsize
* nphdrs
+
1164 ehdr
.e_shentsize
* nshdrs
;
1170 bzero(&ehdr
, sizeof (ehdr
));
1171 ehdr
.e_ident
[EI_MAG0
] = ELFMAG0
;
1172 ehdr
.e_ident
[EI_MAG1
] = ELFMAG1
;
1173 ehdr
.e_ident
[EI_MAG2
] = ELFMAG2
;
1174 ehdr
.e_ident
[EI_MAG3
] = ELFMAG3
;
1175 ehdr
.e_type
= ET_CORE
;
1177 ehdr
.e_ident
[EI_CLASS
] = ELFCLASS64
;
1178 #if defined(__sparc)
1179 ehdr
.e_machine
= EM_SPARCV9
;
1180 ehdr
.e_ident
[EI_DATA
] = ELFDATA2MSB
;
1181 #elif defined(__i386) || defined(__amd64)
1182 ehdr
.e_machine
= EM_AMD64
;
1183 ehdr
.e_ident
[EI_DATA
] = ELFDATA2LSB
;
1185 #error "unknown machine type"
1187 ehdr
.e_ident
[EI_VERSION
] = EV_CURRENT
;
1189 ehdr
.e_version
= EV_CURRENT
;
1190 ehdr
.e_ehsize
= sizeof (ehdr
);
1192 if (nphdrs
>= PN_XNUM
)
1193 ehdr
.e_phnum
= PN_XNUM
;
1195 ehdr
.e_phnum
= (unsigned short)nphdrs
;
1197 ehdr
.e_phentsize
= sizeof (Elf64_Phdr
);
1198 ehdr
.e_phoff
= ehdr
.e_ehsize
;
1201 if (nshdrs
>= SHN_LORESERVE
)
1204 ehdr
.e_shnum
= (unsigned short)nshdrs
;
1206 if (nshdrs
- 1 >= SHN_LORESERVE
)
1207 ehdr
.e_shstrndx
= SHN_XINDEX
;
1209 ehdr
.e_shstrndx
= (unsigned short)(nshdrs
- 1);
1211 ehdr
.e_shentsize
= sizeof (Elf64_Shdr
);
1212 ehdr
.e_shoff
= ehdr
.e_phoff
+ ehdr
.e_phentsize
* nphdrs
;
1215 if (gc_pwrite64(fd
, &ehdr
, sizeof (ehdr
), 0) != 0)
1218 poff
= ehdr
.e_phoff
;
1219 soff
= ehdr
.e_shoff
;
1220 doff
= boff
= ehdr
.e_ehsize
+
1221 ehdr
.e_phentsize
* nphdrs
+
1222 ehdr
.e_shentsize
* nshdrs
;
1228 * Write the zero indexed section if it exists.
1230 if (nshdrs
> 0 && write_shdr(&pgc
, STR_NONE
, 0, 0, 0, 0,
1231 nshdrs
>= SHN_LORESERVE
? nshdrs
: 0,
1232 nshdrs
- 1 >= SHN_LORESERVE
? nshdrs
- 1 : 0,
1233 nphdrs
>= PN_XNUM
? nphdrs
: 0, 0, 0) != 0)
1237 * Construct the old-style note header and section.
1240 if (P
->status
.pr_dmodel
== PR_MODEL_NATIVE
) {
1241 prpsinfo_t prpsinfo
;
1243 mkprpsinfo(P
, &prpsinfo
);
1244 if (write_note(fd
, NT_PRPSINFO
, &prpsinfo
, sizeof (prpsinfo_t
),
1248 if (write_note(fd
, NT_AUXV
, P
->auxv
,
1249 P
->nauxv
* sizeof (P
->auxv
[0]), &doff
) != 0) {
1256 size_t size
= sizeof (auxv32_t
) * P
->nauxv
;
1259 mkprpsinfo32(P
, &pi32
);
1260 if (write_note(fd
, NT_PRPSINFO
, &pi32
, sizeof (prpsinfo32_t
),
1265 if ((av32
= malloc(size
)) == NULL
)
1268 for (i
= 0; i
< P
->nauxv
; i
++) {
1269 auxv_n_to_32(&P
->auxv
[i
], &av32
[i
]);
1272 if (write_note(fd
, NT_AUXV
, av32
, size
, &doff
) != 0) {
1281 if (write_note(fd
, NT_PLATFORM
, plat
, platlen
, &doff
) != 0)
1284 if (Plwp_iter_all(P
, old_per_lwp
, &pgc
) != 0)
1287 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
1290 bzero(&phdr
, sizeof (phdr
));
1291 phdr
.p_type
= PT_NOTE
;
1292 phdr
.p_flags
= PF_R
;
1293 phdr
.p_offset
= (Elf32_Off
)boff
;
1294 phdr
.p_filesz
= doff
- boff
;
1297 if (gc_pwrite64(fd
, &phdr
, sizeof (phdr
), poff
) != 0)
1299 poff
+= sizeof (phdr
);
1304 bzero(&phdr
, sizeof (phdr
));
1305 phdr
.p_type
= PT_NOTE
;
1306 phdr
.p_flags
= PF_R
;
1307 phdr
.p_offset
= boff
;
1308 phdr
.p_filesz
= doff
- boff
;
1311 if (gc_pwrite64(fd
, &phdr
, sizeof (phdr
), poff
) != 0)
1313 poff
+= sizeof (phdr
);
1318 * Construct the new-style note header and section.
1321 if (P
->status
.pr_dmodel
== PR_MODEL_NATIVE
) {
1322 if (write_note(fd
, NT_PSINFO
, &P
->psinfo
, sizeof (psinfo_t
),
1326 if (write_note(fd
, NT_PSTATUS
, &P
->status
, sizeof (pstatus_t
),
1330 if (write_note(fd
, NT_AUXV
, P
->auxv
,
1331 P
->nauxv
* sizeof (P
->auxv
[0]), &doff
) != 0) {
1339 size_t size
= sizeof (auxv32_t
) * P
->nauxv
;
1342 psinfo_n_to_32(&P
->psinfo
, &pi32
);
1343 if (write_note(fd
, NT_PSINFO
, &pi32
, sizeof (psinfo32_t
),
1347 pstatus_n_to_32(&P
->status
, &ps32
);
1348 if (write_note(fd
, NT_PSTATUS
, &ps32
, sizeof (pstatus32_t
),
1352 if ((av32
= malloc(size
)) == NULL
)
1355 for (i
= 0; i
< P
->nauxv
; i
++) {
1356 auxv_n_to_32(&P
->auxv
[i
], &av32
[i
]);
1359 if (write_note(fd
, NT_AUXV
, av32
, size
, &doff
) != 0) {
1368 if (write_note(fd
, NT_PLATFORM
, plat
, platlen
, &doff
) != 0 ||
1369 write_note(fd
, NT_UTSNAME
, &uts
, sizeof (uts
), &doff
) != 0 ||
1370 write_note(fd
, NT_CONTENT
, &content
, sizeof (content
), &doff
) != 0)
1375 size_t size
= sizeof (prcred_t
);
1377 if (Pcred(P
, &cred
, 0) != 0)
1380 if (cred
.pr_ngroups
> 0)
1381 size
+= sizeof (gid_t
) * (cred
.pr_ngroups
- 1);
1382 if ((cp
= malloc(size
)) == NULL
)
1385 if (Pcred(P
, cp
, cred
.pr_ngroups
) != 0 ||
1386 write_note(fd
, NT_PRCRED
, cp
, size
, &doff
) != 0) {
1395 prpriv_t
*ppriv
= NULL
;
1396 const priv_impl_info_t
*pinfo
;
1397 size_t pprivsz
, pinfosz
;
1399 if (Ppriv(P
, &ppriv
) == -1)
1401 pprivsz
= PRIV_PRPRIV_SIZE(ppriv
);
1403 if (write_note(fd
, NT_PRPRIV
, ppriv
, pprivsz
, &doff
) != 0) {
1404 Ppriv_free(P
, ppriv
);
1407 Ppriv_free(P
, ppriv
);
1409 if ((pinfo
= getprivimplinfo()) == NULL
)
1411 pinfosz
= PRIV_IMPL_INFO_SIZE(pinfo
);
1413 if (write_note(fd
, NT_PRPRIVINFO
, pinfo
, pinfosz
, &doff
) != 0)
1417 if (write_note(fd
, NT_ZONENAME
, zonename
, strlen(zonename
) + 1,
1424 iter
.fd_doff
= &doff
;
1426 if (Pfdinfo_iter(P
, iter_fd
, &iter
) != 0)
1432 prsecflags_t
*psf
= NULL
;
1434 if (Psecflags(P
, &psf
) != 0)
1437 if (write_note(fd
, NT_SECFLAGS
, psf
,
1438 sizeof (prsecflags_t
), &doff
) != 0) {
1439 Psecflags_free(psf
);
1443 Psecflags_free(psf
);
1446 #if defined(__i386) || defined(__amd64)
1454 * Only dump out non-zero sized LDT notes.
1456 if ((nldt
= Pldt(P
, NULL
, 0)) != 0) {
1457 size
= sizeof (struct ssd
) * nldt
;
1458 if ((ldtp
= malloc(size
)) == NULL
)
1461 if (Pldt(P
, ldtp
, nldt
) == -1 ||
1462 write_note(fd
, NT_LDT
, ldtp
, size
, &doff
) != 0) {
1470 #endif /* __i386 || __amd64 */
1472 if (Plwp_iter_all(P
, new_per_lwp
, &pgc
) != 0)
1475 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
1478 bzero(&phdr
, sizeof (phdr
));
1479 phdr
.p_type
= PT_NOTE
;
1480 phdr
.p_flags
= PF_R
;
1481 phdr
.p_offset
= (Elf32_Off
)boff
;
1482 phdr
.p_filesz
= doff
- boff
;
1485 if (gc_pwrite64(fd
, &phdr
, sizeof (phdr
), poff
) != 0)
1487 poff
+= sizeof (phdr
);
1492 bzero(&phdr
, sizeof (phdr
));
1493 phdr
.p_type
= PT_NOTE
;
1494 phdr
.p_flags
= PF_R
;
1495 phdr
.p_offset
= boff
;
1496 phdr
.p_filesz
= doff
- boff
;
1499 if (gc_pwrite64(fd
, &phdr
, sizeof (phdr
), poff
) != 0)
1501 poff
+= sizeof (phdr
);
1506 * Construct the headers for each mapping and write out its data
1507 * if the content parameter indicates that it should be present
1510 if (Pmapping_iter(P
, dump_map
, &pgc
) != 0)
1513 if (dump_sections(&pgc
) != 0)
1516 if (write_shstrtab(P
, &pgc
) != 0)
1519 free(pgc
.pgc_chunk
);
1525 * Wipe out anything we may have written if there was an error.
1527 (void) ftruncate64(fd
, 0);
1528 free(pgc
.pgc_chunk
);
1533 static const char *content_str
[] = {
1534 "stack", /* CC_CONTENT_STACK */
1535 "heap", /* CC_CONTENT_HEAP */
1536 "shfile", /* CC_CONTENT_SHFILE */
1537 "shanon", /* CC_CONTENT_SHANON */
1538 "text", /* CC_CONTENT_TEXT */
1539 "data", /* CC_CONTENT_DATA */
1540 "rodata", /* CC_CONTENT_RODATA */
1541 "anon", /* CC_CONTENT_ANON */
1542 "shm", /* CC_CONTENT_SHM */
1543 "ism", /* CC_CONTENT_ISM */
1544 "dism", /* CC_CONTENT_DISM */
1545 "ctf", /* CC_CONTENT_CTF */
1546 "symtab", /* CC_CONTENT_SYMTAB */
1549 static uint_t ncontent_str
= sizeof (content_str
) / sizeof (content_str
[0]);
1551 #define STREQ(a, b, n) (strlen(b) == (n) && strncmp(a, b, n) == 0)
1554 proc_str2content(const char *str
, core_content_t
*cp
)
1556 const char *cur
= str
;
1558 core_content_t mask
, content
= 0;
1561 for (cur
= str
; isalpha(*cur
); cur
++)
1564 if (STREQ(str
, "default", cur
- str
)) {
1565 mask
= CC_CONTENT_DEFAULT
;
1566 } else if (STREQ(str
, "all", cur
- str
)) {
1567 mask
= CC_CONTENT_ALL
;
1568 } else if (STREQ(str
, "none", cur
- str
)) {
1573 while (!STREQ(str
, content_str
[i
], cur
- str
)) {
1576 if (i
>= ncontent_str
)
1580 mask
= (core_content_t
)1 << i
;
1607 popc(core_content_t x
)
1611 for (i
= 0; x
!= 0; i
++)
1618 proc_content2str(core_content_t content
, char *buf
, size_t size
)
1620 int nonecnt
, defcnt
, allcnt
;
1621 core_content_t mask
, bit
;
1627 return ((int)strlcpy(buf
, "none", size
));
1629 if (content
& ~CC_CONTENT_ALL
)
1630 return ((int)strlcpy(buf
, "<invalid>", size
));
1632 nonecnt
= popc(content
);
1633 defcnt
= 1 + popc(content
^ CC_CONTENT_DEFAULT
);
1634 allcnt
= 1 + popc(content
^ CC_CONTENT_ALL
);
1636 if (defcnt
<= nonecnt
&& defcnt
<= allcnt
) {
1637 mask
= content
^ CC_CONTENT_DEFAULT
;
1639 tot
+= (n
= strlcpy(buf
, "default", size
));
1644 } else if (allcnt
< nonecnt
) {
1645 mask
= content
^ CC_CONTENT_ALL
;
1647 tot
+= (n
= strlcpy(buf
, "all", size
));
1658 bit
= mask
^ (mask
& (mask
- 1));
1662 *buf
= (bit
& content
) ? '+' : '-';
1669 index
= popc(bit
- 1);
1670 tot
+= (n
= strlcpy(buf
, content_str
[index
], size
));