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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
27 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
28 * Copyright (c) 2013 by Delphix. All rights reserved.
29 * Copyright 2015 Gary Mills
32 #include <sys/types.h>
33 #include <sys/utsname.h>
34 #include <sys/sysmacros.h>
35 #include <sys/cfgparam.h>
54 #ifdef CONFIG_LINUX_CORE_SUPPORT
55 #include "Pcore_linux.h"
59 * Pcore.c - Code to initialize a ps_prochandle from a core dump. We
60 * allocate an additional structure to hold information from the core
61 * file, and attach this to the standard ps_prochandle in place of the
62 * ability to examine /proc/<pid>/ files.
66 * Basic i/o function for reading and writing from the process address space
67 * stored in the core file and associated shared libraries. We compute the
68 * appropriate fd and offsets, and let the provided prw function do the rest.
71 core_rw(struct ps_prochandle
*P
, void *buf
, size_t n
, uintptr_t addr
,
72 ssize_t (*prw
)(int, void *, size_t, off64_t
))
77 map_info_t
*mp
= Paddr2mptr(P
, addr
);
85 break; /* No mapping for this address */
87 if (mp
->map_pmap
.pr_mflags
& MA_RESERVED1
) {
88 if (mp
->map_file
== NULL
|| mp
->map_file
->file_fd
< 0)
89 break; /* No file or file not open */
91 fd
= mp
->map_file
->file_fd
;
95 mapoff
= addr
- mp
->map_pmap
.pr_vaddr
;
96 len
= MIN(resid
, mp
->map_pmap
.pr_size
- mapoff
);
97 off
= mp
->map_offset
+ mapoff
;
99 if ((len
= prw(fd
, buf
, len
, off
)) <= 0)
104 buf
= (char *)buf
+ len
;
108 * Important: Be consistent with the behavior of i/o on the as file:
109 * writing to an invalid address yields EIO; reading from an invalid
110 * address falls through to returning success and zero bytes.
112 if (resid
== n
&& n
!= 0 && prw
!= pread64
) {
122 Pread_core(struct ps_prochandle
*P
, void *buf
, size_t n
, uintptr_t addr
,
125 return (core_rw(P
, buf
, n
, addr
, pread64
));
130 Pwrite_core(struct ps_prochandle
*P
, const void *buf
, size_t n
, uintptr_t addr
,
133 return (core_rw(P
, (void *)buf
, n
, addr
,
134 (ssize_t (*)(int, void *, size_t, off64_t
)) pwrite64
));
139 Pcred_core(struct ps_prochandle
*P
, prcred_t
*pcrp
, int ngroups
, void *data
)
141 core_info_t
*core
= data
;
143 if (core
->core_cred
!= NULL
) {
145 * Avoid returning more supplementary group data than the
146 * caller has allocated in their buffer. We expect them to
147 * check pr_ngroups afterward and potentially call us again.
149 ngroups
= MIN(ngroups
, core
->core_cred
->pr_ngroups
);
151 (void) memcpy(pcrp
, core
->core_cred
,
152 sizeof (prcred_t
) + (ngroups
- 1) * sizeof (gid_t
));
163 Psecflags_core(struct ps_prochandle
*P
, prsecflags_t
**psf
, void *data
)
165 core_info_t
*core
= data
;
167 if (core
->core_secflags
== NULL
) {
172 if ((*psf
= calloc(1, sizeof (prsecflags_t
))) == NULL
)
175 (void) memcpy(*psf
, core
->core_secflags
, sizeof (prsecflags_t
));
182 Ppriv_core(struct ps_prochandle
*P
, prpriv_t
**pprv
, void *data
)
184 core_info_t
*core
= data
;
186 if (core
->core_priv
== NULL
) {
191 *pprv
= malloc(core
->core_priv_size
);
196 (void) memcpy(*pprv
, core
->core_priv
, core
->core_priv_size
);
201 static const psinfo_t
*
202 Ppsinfo_core(struct ps_prochandle
*P
, psinfo_t
*psinfo
, void *data
)
209 Pfini_core(struct ps_prochandle
*P
, void *data
)
211 core_info_t
*core
= data
;
214 extern void __priv_free_info(void *);
215 lwp_info_t
*nlwp
, *lwp
= list_next(&core
->core_lwp_head
);
218 for (i
= 0; i
< core
->core_nlwp
; i
++, lwp
= nlwp
) {
219 nlwp
= list_next(lwp
);
223 free(core
->core_platform
);
224 free(core
->core_uts
);
225 free(core
->core_cred
);
226 free(core
->core_priv
);
227 if (core
->core_privinfo
!= NULL
)
228 __priv_free_info(core
->core_privinfo
);
229 free(core
->core_ppii
);
230 free(core
->core_zonename
);
231 free(core
->core_secflags
);
233 free(core
->core_ldt
);
242 Pplatform_core(struct ps_prochandle
*P
, char *s
, size_t n
, void *data
)
244 core_info_t
*core
= data
;
246 if (core
->core_platform
== NULL
) {
250 (void) strncpy(s
, core
->core_platform
, n
- 1);
257 Puname_core(struct ps_prochandle
*P
, struct utsname
*u
, void *data
)
259 core_info_t
*core
= data
;
261 if (core
->core_uts
== NULL
) {
265 (void) memcpy(u
, core
->core_uts
, sizeof (struct utsname
));
271 Pzonename_core(struct ps_prochandle
*P
, char *s
, size_t n
, void *data
)
273 core_info_t
*core
= data
;
275 if (core
->core_zonename
== NULL
) {
279 (void) strlcpy(s
, core
->core_zonename
, n
);
286 Pldt_core(struct ps_prochandle
*P
, struct ssd
*pldt
, int nldt
, void *data
)
288 core_info_t
*core
= data
;
290 if (pldt
== NULL
|| nldt
== 0)
291 return (core
->core_nldt
);
293 if (core
->core_ldt
!= NULL
) {
294 nldt
= MIN(nldt
, core
->core_nldt
);
296 (void) memcpy(pldt
, core
->core_ldt
,
297 nldt
* sizeof (struct ssd
));
307 static const ps_ops_t P_core_ops
= {
308 .pop_pread
= Pread_core
,
309 .pop_pwrite
= Pwrite_core
,
310 .pop_cred
= Pcred_core
,
311 .pop_priv
= Ppriv_core
,
312 .pop_psinfo
= Ppsinfo_core
,
313 .pop_fini
= Pfini_core
,
314 .pop_platform
= Pplatform_core
,
315 .pop_uname
= Puname_core
,
316 .pop_zonename
= Pzonename_core
,
317 .pop_secflags
= Psecflags_core
,
324 * Return the lwp_info_t for the given lwpid. If no such lwpid has been
325 * encountered yet, allocate a new structure and return a pointer to it.
326 * Create a list of lwp_info_t structures sorted in decreasing lwp_id order.
329 lwpid2info(struct ps_prochandle
*P
, lwpid_t id
)
331 core_info_t
*core
= P
->data
;
332 lwp_info_t
*lwp
= list_next(&core
->core_lwp_head
);
336 for (i
= 0; i
< core
->core_nlwp
; i
++, lwp
= list_next(lwp
)) {
337 if (lwp
->lwp_id
== id
) {
338 core
->core_lwp
= lwp
;
341 if (lwp
->lwp_id
< id
) {
347 if ((lwp
= calloc(1, sizeof (lwp_info_t
))) == NULL
)
350 list_link(lwp
, next
);
353 core
->core_lwp
= lwp
;
360 * The core file itself contains a series of NOTE segments containing saved
361 * structures from /proc at the time the process died. For each note we
362 * comprehend, we define a function to read it in from the core file,
363 * convert it to our native data model if necessary, and store it inside
364 * the ps_prochandle. Each function is invoked by Pfgrab_core() with the
365 * seek pointer on P->asfd positioned appropriately. We populate a table
366 * of pointers to these note functions below.
370 note_pstatus(struct ps_prochandle
*P
, size_t nbytes
)
373 core_info_t
*core
= P
->data
;
375 if (core
->core_dmodel
== PR_MODEL_ILP32
) {
378 if (nbytes
< sizeof (pstatus32_t
) ||
379 read(P
->asfd
, &ps32
, sizeof (ps32
)) != sizeof (ps32
))
382 pstatus_32_to_n(&ps32
, &P
->status
);
386 if (nbytes
< sizeof (pstatus_t
) ||
387 read(P
->asfd
, &P
->status
, sizeof (pstatus_t
)) != sizeof (pstatus_t
))
390 P
->orig_status
= P
->status
;
391 P
->pid
= P
->status
.pr_pid
;
396 dprintf("Pgrab_core: failed to read NT_PSTATUS\n");
401 note_lwpstatus(struct ps_prochandle
*P
, size_t nbytes
)
407 core_info_t
*core
= P
->data
;
409 if (core
->core_dmodel
== PR_MODEL_ILP32
) {
412 if (nbytes
< sizeof (lwpstatus32_t
) ||
413 read(P
->asfd
, &l32
, sizeof (l32
)) != sizeof (l32
))
416 lwpstatus_32_to_n(&l32
, &lps
);
419 if (nbytes
< sizeof (lwpstatus_t
) ||
420 read(P
->asfd
, &lps
, sizeof (lps
)) != sizeof (lps
))
423 if ((lwp
= lwpid2info(P
, lps
.pr_lwpid
)) == NULL
) {
424 dprintf("Pgrab_core: failed to add NT_LWPSTATUS\n");
429 * Erase a useless and confusing artifact of the kernel implementation:
430 * the lwps which did *not* create the core will show SIGKILL. We can
431 * be assured this is bogus because SIGKILL can't produce core files.
433 if (lps
.pr_cursig
== SIGKILL
)
436 (void) memcpy(&lwp
->lwp_status
, &lps
, sizeof (lps
));
440 dprintf("Pgrab_core: failed to read NT_LWPSTATUS\n");
444 #ifdef CONFIG_LINUX_CORE_SUPPORT
447 lx_prpsinfo32_to_psinfo(lx_prpsinfo32_t
*p32
, psinfo_t
*psinfo
)
449 psinfo
->pr_flag
= p32
->pr_flag
;
450 psinfo
->pr_pid
= p32
->pr_pid
;
451 psinfo
->pr_ppid
= p32
->pr_ppid
;
452 psinfo
->pr_uid
= p32
->pr_uid
;
453 psinfo
->pr_gid
= p32
->pr_gid
;
454 psinfo
->pr_sid
= p32
->pr_sid
;
455 psinfo
->pr_pgid
= p32
->pr_pgrp
;
457 (void) memcpy(psinfo
->pr_fname
, p32
->pr_fname
,
458 sizeof (psinfo
->pr_fname
));
459 (void) memcpy(psinfo
->pr_psargs
, p32
->pr_psargs
,
460 sizeof (psinfo
->pr_psargs
));
464 lx_prpsinfo64_to_psinfo(lx_prpsinfo64_t
*p64
, psinfo_t
*psinfo
)
466 psinfo
->pr_flag
= p64
->pr_flag
;
467 psinfo
->pr_pid
= p64
->pr_pid
;
468 psinfo
->pr_ppid
= p64
->pr_ppid
;
469 psinfo
->pr_uid
= p64
->pr_uid
;
470 psinfo
->pr_gid
= p64
->pr_gid
;
471 psinfo
->pr_sid
= p64
->pr_sid
;
472 psinfo
->pr_pgid
= p64
->pr_pgrp
;
473 psinfo
->pr_pgid
= p64
->pr_pgrp
;
475 (void) memcpy(psinfo
->pr_fname
, p64
->pr_fname
,
476 sizeof (psinfo
->pr_fname
));
477 (void) memcpy(psinfo
->pr_psargs
, p64
->pr_psargs
,
478 sizeof (psinfo
->pr_psargs
));
482 note_linux_psinfo(struct ps_prochandle
*P
, size_t nbytes
)
484 core_info_t
*core
= P
->data
;
488 if (core
->core_dmodel
== PR_MODEL_ILP32
) {
489 if (nbytes
< sizeof (p32
) ||
490 read(P
->asfd
, &p32
, sizeof (p32
)) != sizeof (p32
))
493 lx_prpsinfo32_to_psinfo(&p32
, &P
->psinfo
);
495 if (nbytes
< sizeof (p64
) ||
496 read(P
->asfd
, &p64
, sizeof (p64
)) != sizeof (p64
))
499 lx_prpsinfo64_to_psinfo(&p64
, &P
->psinfo
);
503 P
->status
.pr_pid
= P
->psinfo
.pr_pid
;
504 P
->status
.pr_ppid
= P
->psinfo
.pr_ppid
;
505 P
->status
.pr_pgid
= P
->psinfo
.pr_pgid
;
506 P
->status
.pr_sid
= P
->psinfo
.pr_sid
;
508 P
->psinfo
.pr_nlwp
= 0;
509 P
->status
.pr_nlwp
= 0;
513 dprintf("Pgrab_core: failed to read NT_PSINFO\n");
518 lx_prstatus64_to_lwp(lx_prstatus64_t
*prs64
, lwp_info_t
*lwp
)
520 LTIME_TO_TIMESPEC(lwp
->lwp_status
.pr_utime
, prs64
->pr_utime
);
521 LTIME_TO_TIMESPEC(lwp
->lwp_status
.pr_stime
, prs64
->pr_stime
);
523 lwp
->lwp_status
.pr_reg
[REG_R15
] = prs64
->pr_reg
.lxr_r15
;
524 lwp
->lwp_status
.pr_reg
[REG_R14
] = prs64
->pr_reg
.lxr_r14
;
525 lwp
->lwp_status
.pr_reg
[REG_R13
] = prs64
->pr_reg
.lxr_r13
;
526 lwp
->lwp_status
.pr_reg
[REG_R12
] = prs64
->pr_reg
.lxr_r12
;
527 lwp
->lwp_status
.pr_reg
[REG_R11
] = prs64
->pr_reg
.lxr_r11
;
528 lwp
->lwp_status
.pr_reg
[REG_R10
] = prs64
->pr_reg
.lxr_r10
;
529 lwp
->lwp_status
.pr_reg
[REG_R9
] = prs64
->pr_reg
.lxr_r9
;
530 lwp
->lwp_status
.pr_reg
[REG_R8
] = prs64
->pr_reg
.lxr_r8
;
532 lwp
->lwp_status
.pr_reg
[REG_RDI
] = prs64
->pr_reg
.lxr_rdi
;
533 lwp
->lwp_status
.pr_reg
[REG_RSI
] = prs64
->pr_reg
.lxr_rsi
;
534 lwp
->lwp_status
.pr_reg
[REG_RBP
] = prs64
->pr_reg
.lxr_rbp
;
535 lwp
->lwp_status
.pr_reg
[REG_RBX
] = prs64
->pr_reg
.lxr_rbx
;
536 lwp
->lwp_status
.pr_reg
[REG_RDX
] = prs64
->pr_reg
.lxr_rdx
;
537 lwp
->lwp_status
.pr_reg
[REG_RCX
] = prs64
->pr_reg
.lxr_rcx
;
538 lwp
->lwp_status
.pr_reg
[REG_RAX
] = prs64
->pr_reg
.lxr_rax
;
540 lwp
->lwp_status
.pr_reg
[REG_RIP
] = prs64
->pr_reg
.lxr_rip
;
541 lwp
->lwp_status
.pr_reg
[REG_CS
] = prs64
->pr_reg
.lxr_cs
;
542 lwp
->lwp_status
.pr_reg
[REG_RSP
] = prs64
->pr_reg
.lxr_rsp
;
543 lwp
->lwp_status
.pr_reg
[REG_FS
] = prs64
->pr_reg
.lxr_fs
;
544 lwp
->lwp_status
.pr_reg
[REG_SS
] = prs64
->pr_reg
.lxr_ss
;
545 lwp
->lwp_status
.pr_reg
[REG_GS
] = prs64
->pr_reg
.lxr_gs
;
546 lwp
->lwp_status
.pr_reg
[REG_ES
] = prs64
->pr_reg
.lxr_es
;
547 lwp
->lwp_status
.pr_reg
[REG_DS
] = prs64
->pr_reg
.lxr_ds
;
549 lwp
->lwp_status
.pr_reg
[REG_GSBASE
] = prs64
->pr_reg
.lxr_gs_base
;
550 lwp
->lwp_status
.pr_reg
[REG_FSBASE
] = prs64
->pr_reg
.lxr_fs_base
;
554 lx_prstatus32_to_lwp(lx_prstatus32_t
*prs32
, lwp_info_t
*lwp
)
556 LTIME_TO_TIMESPEC(lwp
->lwp_status
.pr_utime
, prs32
->pr_utime
);
557 LTIME_TO_TIMESPEC(lwp
->lwp_status
.pr_stime
, prs32
->pr_stime
);
560 lwp
->lwp_status
.pr_reg
[REG_GS
] = prs32
->pr_reg
.lxr_gs
;
561 lwp
->lwp_status
.pr_reg
[REG_FS
] = prs32
->pr_reg
.lxr_fs
;
562 lwp
->lwp_status
.pr_reg
[REG_DS
] = prs32
->pr_reg
.lxr_ds
;
563 lwp
->lwp_status
.pr_reg
[REG_ES
] = prs32
->pr_reg
.lxr_es
;
564 lwp
->lwp_status
.pr_reg
[REG_RDI
] = prs32
->pr_reg
.lxr_di
;
565 lwp
->lwp_status
.pr_reg
[REG_RSI
] = prs32
->pr_reg
.lxr_si
;
566 lwp
->lwp_status
.pr_reg
[REG_RBP
] = prs32
->pr_reg
.lxr_bp
;
567 lwp
->lwp_status
.pr_reg
[REG_RBX
] = prs32
->pr_reg
.lxr_bx
;
568 lwp
->lwp_status
.pr_reg
[REG_RDX
] = prs32
->pr_reg
.lxr_dx
;
569 lwp
->lwp_status
.pr_reg
[REG_RCX
] = prs32
->pr_reg
.lxr_cx
;
570 lwp
->lwp_status
.pr_reg
[REG_RAX
] = prs32
->pr_reg
.lxr_ax
;
571 lwp
->lwp_status
.pr_reg
[REG_RIP
] = prs32
->pr_reg
.lxr_ip
;
572 lwp
->lwp_status
.pr_reg
[REG_CS
] = prs32
->pr_reg
.lxr_cs
;
573 lwp
->lwp_status
.pr_reg
[REG_RFL
] = prs32
->pr_reg
.lxr_flags
;
574 lwp
->lwp_status
.pr_reg
[REG_RSP
] = prs32
->pr_reg
.lxr_sp
;
575 lwp
->lwp_status
.pr_reg
[REG_SS
] = prs32
->pr_reg
.lxr_ss
;
576 #elif defined(__i386)
577 lwp
->lwp_status
.pr_reg
[EBX
] = prs32
->pr_reg
.lxr_bx
;
578 lwp
->lwp_status
.pr_reg
[ECX
] = prs32
->pr_reg
.lxr_cx
;
579 lwp
->lwp_status
.pr_reg
[EDX
] = prs32
->pr_reg
.lxr_dx
;
580 lwp
->lwp_status
.pr_reg
[ESI
] = prs32
->pr_reg
.lxr_si
;
581 lwp
->lwp_status
.pr_reg
[EDI
] = prs32
->pr_reg
.lxr_di
;
582 lwp
->lwp_status
.pr_reg
[EBP
] = prs32
->pr_reg
.lxr_bp
;
583 lwp
->lwp_status
.pr_reg
[EAX
] = prs32
->pr_reg
.lxr_ax
;
584 lwp
->lwp_status
.pr_reg
[EIP
] = prs32
->pr_reg
.lxr_ip
;
585 lwp
->lwp_status
.pr_reg
[UESP
] = prs32
->pr_reg
.lxr_sp
;
587 lwp
->lwp_status
.pr_reg
[DS
] = prs32
->pr_reg
.lxr_ds
;
588 lwp
->lwp_status
.pr_reg
[ES
] = prs32
->pr_reg
.lxr_es
;
589 lwp
->lwp_status
.pr_reg
[FS
] = prs32
->pr_reg
.lxr_fs
;
590 lwp
->lwp_status
.pr_reg
[GS
] = prs32
->pr_reg
.lxr_gs
;
591 lwp
->lwp_status
.pr_reg
[CS
] = prs32
->pr_reg
.lxr_cs
;
592 lwp
->lwp_status
.pr_reg
[SS
] = prs32
->pr_reg
.lxr_ss
;
594 lwp
->lwp_status
.pr_reg
[EFL
] = prs32
->pr_reg
.lxr_flags
;
601 note_linux_prstatus(struct ps_prochandle
*P
, size_t nbytes
)
603 core_info_t
*core
= P
->data
;
605 lx_prstatus64_t prs64
;
606 lx_prstatus32_t prs32
;
610 dprintf("looking for model %d, %ld/%ld\n", core
->core_dmodel
,
611 (ulong_t
)nbytes
, (ulong_t
)sizeof (prs32
));
612 if (core
->core_dmodel
== PR_MODEL_ILP32
) {
613 if (nbytes
< sizeof (prs32
) ||
614 read(P
->asfd
, &prs32
, sizeof (prs32
)) != nbytes
)
618 if (nbytes
< sizeof (prs64
) ||
619 read(P
->asfd
, &prs64
, sizeof (prs64
)) != nbytes
)
624 if ((lwp
= lwpid2info(P
, tid
)) == NULL
) {
625 dprintf("Pgrab_core: failed to add lwpid2info "
633 lwp
->lwp_status
.pr_lwpid
= tid
;
635 if (core
->core_dmodel
== PR_MODEL_ILP32
)
636 lx_prstatus32_to_lwp(&prs32
, lwp
);
638 lx_prstatus64_to_lwp(&prs64
, lwp
);
642 dprintf("Pgrab_core: failed to read NT_PRSTATUS\n");
646 #endif /* CONFIG_LINUX_CORE_SUPPORT */
649 note_psinfo(struct ps_prochandle
*P
, size_t nbytes
)
652 core_info_t
*core
= P
->data
;
654 if (core
->core_dmodel
== PR_MODEL_ILP32
) {
657 if (nbytes
< sizeof (psinfo32_t
) ||
658 read(P
->asfd
, &ps32
, sizeof (ps32
)) != sizeof (ps32
))
661 psinfo_32_to_n(&ps32
, &P
->psinfo
);
664 if (nbytes
< sizeof (psinfo_t
) ||
665 read(P
->asfd
, &P
->psinfo
, sizeof (psinfo_t
)) != sizeof (psinfo_t
))
668 dprintf("pr_fname = <%s>\n", P
->psinfo
.pr_fname
);
669 dprintf("pr_psargs = <%s>\n", P
->psinfo
.pr_psargs
);
670 dprintf("pr_wstat = 0x%x\n", P
->psinfo
.pr_wstat
);
675 dprintf("Pgrab_core: failed to read NT_PSINFO\n");
680 note_lwpsinfo(struct ps_prochandle
*P
, size_t nbytes
)
686 core_info_t
*core
= P
->data
;
688 if (core
->core_dmodel
== PR_MODEL_ILP32
) {
691 if (nbytes
< sizeof (lwpsinfo32_t
) ||
692 read(P
->asfd
, &l32
, sizeof (l32
)) != sizeof (l32
))
695 lwpsinfo_32_to_n(&l32
, &lps
);
698 if (nbytes
< sizeof (lwpsinfo_t
) ||
699 read(P
->asfd
, &lps
, sizeof (lps
)) != sizeof (lps
))
702 if ((lwp
= lwpid2info(P
, lps
.pr_lwpid
)) == NULL
) {
703 dprintf("Pgrab_core: failed to add NT_LWPSINFO\n");
707 (void) memcpy(&lwp
->lwp_psinfo
, &lps
, sizeof (lps
));
711 dprintf("Pgrab_core: failed to read NT_LWPSINFO\n");
716 note_fdinfo(struct ps_prochandle
*P
, size_t nbytes
)
721 if ((nbytes
< sizeof (prfd
)) ||
722 (read(P
->asfd
, &prfd
, sizeof (prfd
)) != sizeof (prfd
))) {
723 dprintf("Pgrab_core: failed to read NT_FDINFO\n");
727 if ((fip
= Pfd2info(P
, prfd
.pr_fd
)) == NULL
) {
728 dprintf("Pgrab_core: failed to add NT_FDINFO\n");
731 (void) memcpy(&fip
->fd_info
, &prfd
, sizeof (prfd
));
736 note_platform(struct ps_prochandle
*P
, size_t nbytes
)
738 core_info_t
*core
= P
->data
;
741 if (core
->core_platform
!= NULL
)
742 return (0); /* Already seen */
744 if (nbytes
!= 0 && ((plat
= malloc(nbytes
+ 1)) != NULL
)) {
745 if (read(P
->asfd
, plat
, nbytes
) != nbytes
) {
746 dprintf("Pgrab_core: failed to read NT_PLATFORM\n");
750 plat
[nbytes
- 1] = '\0';
751 core
->core_platform
= plat
;
758 note_secflags(struct ps_prochandle
*P
, size_t nbytes
)
760 core_info_t
*core
= P
->data
;
763 if (core
->core_secflags
!= NULL
)
764 return (0); /* Already seen */
766 if (sizeof (*psf
) != nbytes
) {
767 dprintf("Pgrab_core: NT_SECFLAGS changed size."
768 " Need to handle a version change?\n");
772 if (nbytes
!= 0 && ((psf
= malloc(nbytes
)) != NULL
)) {
773 if (read(P
->asfd
, psf
, nbytes
) != nbytes
) {
774 dprintf("Pgrab_core: failed to read NT_SECFLAGS\n");
779 core
->core_secflags
= psf
;
786 note_utsname(struct ps_prochandle
*P
, size_t nbytes
)
788 core_info_t
*core
= P
->data
;
789 size_t ubytes
= sizeof (struct utsname
);
790 struct utsname
*utsp
;
792 if (core
->core_uts
!= NULL
|| nbytes
< ubytes
)
793 return (0); /* Already seen or bad size */
795 if ((utsp
= malloc(ubytes
)) == NULL
)
798 if (read(P
->asfd
, utsp
, ubytes
) != ubytes
) {
799 dprintf("Pgrab_core: failed to read NT_UTSNAME\n");
804 if (_libproc_debug
) {
805 dprintf("uts.sysname = \"%s\"\n", utsp
->sysname
);
806 dprintf("uts.nodename = \"%s\"\n", utsp
->nodename
);
807 dprintf("uts.release = \"%s\"\n", utsp
->release
);
808 dprintf("uts.version = \"%s\"\n", utsp
->version
);
809 dprintf("uts.machine = \"%s\"\n", utsp
->machine
);
812 core
->core_uts
= utsp
;
817 note_content(struct ps_prochandle
*P
, size_t nbytes
)
819 core_info_t
*core
= P
->data
;
820 core_content_t content
;
822 if (sizeof (core
->core_content
) != nbytes
)
825 if (read(P
->asfd
, &content
, sizeof (content
)) != sizeof (content
))
828 core
->core_content
= content
;
830 dprintf("core content = %llx\n", content
);
836 note_cred(struct ps_prochandle
*P
, size_t nbytes
)
838 core_info_t
*core
= P
->data
;
841 const size_t min_size
= sizeof (prcred_t
) - sizeof (gid_t
);
844 * We allow for prcred_t notes that are actually smaller than a
845 * prcred_t since the last member isn't essential if there are
846 * no group memberships. This allows for more flexibility when it
847 * comes to slightly malformed -- but still valid -- notes.
849 if (core
->core_cred
!= NULL
|| nbytes
< min_size
)
850 return (0); /* Already seen or bad size */
852 ngroups
= (nbytes
- min_size
) / sizeof (gid_t
);
853 nbytes
= sizeof (prcred_t
) + (ngroups
- 1) * sizeof (gid_t
);
855 if ((pcrp
= malloc(nbytes
)) == NULL
)
858 if (read(P
->asfd
, pcrp
, nbytes
) != nbytes
) {
859 dprintf("Pgrab_core: failed to read NT_PRCRED\n");
864 if (pcrp
->pr_ngroups
> ngroups
) {
865 dprintf("pr_ngroups = %d; resetting to %d based on note size\n",
866 pcrp
->pr_ngroups
, ngroups
);
867 pcrp
->pr_ngroups
= ngroups
;
870 core
->core_cred
= pcrp
;
876 note_ldt(struct ps_prochandle
*P
, size_t nbytes
)
878 core_info_t
*core
= P
->data
;
882 if (core
->core_ldt
!= NULL
|| nbytes
< sizeof (struct ssd
))
883 return (0); /* Already seen or bad size */
885 nldt
= nbytes
/ sizeof (struct ssd
);
886 nbytes
= nldt
* sizeof (struct ssd
);
888 if ((pldt
= malloc(nbytes
)) == NULL
)
891 if (read(P
->asfd
, pldt
, nbytes
) != nbytes
) {
892 dprintf("Pgrab_core: failed to read NT_LDT\n");
897 core
->core_ldt
= pldt
;
898 core
->core_nldt
= nldt
;
904 note_priv(struct ps_prochandle
*P
, size_t nbytes
)
906 core_info_t
*core
= P
->data
;
909 if (core
->core_priv
!= NULL
|| nbytes
< sizeof (prpriv_t
))
910 return (0); /* Already seen or bad size */
912 if ((pprvp
= malloc(nbytes
)) == NULL
)
915 if (read(P
->asfd
, pprvp
, nbytes
) != nbytes
) {
916 dprintf("Pgrab_core: failed to read NT_PRPRIV\n");
921 core
->core_priv
= pprvp
;
922 core
->core_priv_size
= nbytes
;
927 note_priv_info(struct ps_prochandle
*P
, size_t nbytes
)
929 core_info_t
*core
= P
->data
;
930 extern void *__priv_parse_info();
931 priv_impl_info_t
*ppii
;
933 if (core
->core_privinfo
!= NULL
||
934 nbytes
< sizeof (priv_impl_info_t
))
935 return (0); /* Already seen or bad size */
937 if ((ppii
= malloc(nbytes
)) == NULL
)
940 if (read(P
->asfd
, ppii
, nbytes
) != nbytes
||
941 PRIV_IMPL_INFO_SIZE(ppii
) != nbytes
) {
942 dprintf("Pgrab_core: failed to read NT_PRPRIVINFO\n");
947 core
->core_privinfo
= __priv_parse_info(ppii
);
948 core
->core_ppii
= ppii
;
953 note_zonename(struct ps_prochandle
*P
, size_t nbytes
)
955 core_info_t
*core
= P
->data
;
958 if (core
->core_zonename
!= NULL
)
959 return (0); /* Already seen */
962 if ((zonename
= malloc(nbytes
)) == NULL
)
964 if (read(P
->asfd
, zonename
, nbytes
) != nbytes
) {
965 dprintf("Pgrab_core: failed to read NT_ZONENAME\n");
969 zonename
[nbytes
- 1] = '\0';
970 core
->core_zonename
= zonename
;
977 note_auxv(struct ps_prochandle
*P
, size_t nbytes
)
982 core_info_t
*core
= P
->data
;
984 if (core
->core_dmodel
== PR_MODEL_ILP32
) {
987 n
= nbytes
/ sizeof (auxv32_t
);
988 nbytes
= n
* sizeof (auxv32_t
);
989 a32
= alloca(nbytes
);
991 if (read(P
->asfd
, a32
, nbytes
) != nbytes
) {
992 dprintf("Pgrab_core: failed to read NT_AUXV\n");
996 if ((P
->auxv
= malloc(sizeof (auxv_t
) * (n
+ 1))) == NULL
)
999 for (i
= 0; i
< n
; i
++)
1000 auxv_32_to_n(&a32
[i
], &P
->auxv
[i
]);
1004 n
= nbytes
/ sizeof (auxv_t
);
1005 nbytes
= n
* sizeof (auxv_t
);
1007 if ((P
->auxv
= malloc(nbytes
+ sizeof (auxv_t
))) == NULL
)
1010 if (read(P
->asfd
, P
->auxv
, nbytes
) != nbytes
) {
1019 if (_libproc_debug
) {
1020 for (i
= 0; i
< n
; i
++) {
1021 dprintf("P->auxv[%lu] = ( %d, 0x%lx )\n", (ulong_t
)i
,
1022 P
->auxv
[i
].a_type
, P
->auxv
[i
].a_un
.a_val
);
1027 * Defensive coding for loops which depend upon the auxv array being
1028 * terminated by an AT_NULL element; in each case, we've allocated
1029 * P->auxv to have an additional element which we force to be AT_NULL.
1031 P
->auxv
[n
].a_type
= AT_NULL
;
1032 P
->auxv
[n
].a_un
.a_val
= 0L;
1040 note_spymaster(struct ps_prochandle
*P
, size_t nbytes
)
1043 core_info_t
*core
= P
->data
;
1045 if (core
->core_dmodel
== PR_MODEL_ILP32
) {
1048 if (nbytes
< sizeof (psinfo32_t
) ||
1049 read(P
->asfd
, &ps32
, sizeof (ps32
)) != sizeof (ps32
))
1052 psinfo_32_to_n(&ps32
, &P
->spymaster
);
1055 if (nbytes
< sizeof (psinfo_t
) || read(P
->asfd
,
1056 &P
->spymaster
, sizeof (psinfo_t
)) != sizeof (psinfo_t
))
1059 dprintf("spymaster pr_fname = <%s>\n", P
->psinfo
.pr_fname
);
1060 dprintf("spymaster pr_psargs = <%s>\n", P
->psinfo
.pr_psargs
);
1061 dprintf("spymaster pr_wstat = 0x%x\n", P
->psinfo
.pr_wstat
);
1066 dprintf("Pgrab_core: failed to read NT_SPYMASTER\n");
1072 note_notsup(struct ps_prochandle
*P
, size_t nbytes
)
1074 dprintf("skipping unsupported note type of size %ld bytes\n",
1080 * Populate a table of function pointers indexed by Note type with our
1081 * functions to process each type of core file note:
1083 static int (*nhdlrs
[])(struct ps_prochandle
*, size_t) = {
1084 note_notsup
, /* 0 unassigned */
1085 #ifdef CONFIG_LINUX_CORE_SUPPORT
1086 note_linux_prstatus
, /* 1 NT_PRSTATUS (old) */
1088 note_notsup
, /* 1 NT_PRSTATUS (old) */
1090 note_notsup
, /* 2 NT_PRFPREG (old) */
1091 #ifdef CONFIG_LINUX_CORE_SUPPORT
1092 note_linux_psinfo
, /* 3 NT_PRPSINFO (old) */
1094 note_notsup
, /* 3 NT_PRPSINFO (old) */
1096 note_notsup
, /* 4 NT_PRXREG */
1097 note_platform
, /* 5 NT_PLATFORM */
1098 note_auxv
, /* 6 NT_AUXV */
1099 note_notsup
, /* 7 NT_GWINDOWS */
1100 note_notsup
, /* 8 NT_ASRS */
1102 note_ldt
, /* 9 NT_LDT */
1104 note_notsup
, /* 9 NT_LDT */
1106 note_pstatus
, /* 10 NT_PSTATUS */
1107 note_notsup
, /* 11 unassigned */
1108 note_notsup
, /* 12 unassigned */
1109 note_psinfo
, /* 13 NT_PSINFO */
1110 note_cred
, /* 14 NT_PRCRED */
1111 note_utsname
, /* 15 NT_UTSNAME */
1112 note_lwpstatus
, /* 16 NT_LWPSTATUS */
1113 note_lwpsinfo
, /* 17 NT_LWPSINFO */
1114 note_priv
, /* 18 NT_PRPRIV */
1115 note_priv_info
, /* 19 NT_PRPRIVINFO */
1116 note_content
, /* 20 NT_CONTENT */
1117 note_zonename
, /* 21 NT_ZONENAME */
1118 note_fdinfo
, /* 22 NT_FDINFO */
1119 note_spymaster
, /* 23 NT_SPYMASTER */
1120 note_secflags
, /* 24 NT_SECFLAGS */
1124 core_report_mapping(struct ps_prochandle
*P
, GElf_Phdr
*php
)
1126 prkillinfo_t killinfo
;
1127 siginfo_t
*si
= &killinfo
.prk_info
;
1128 char signame
[SIG2STR_MAX
], sig
[64], info
[64];
1129 void *addr
= (void *)(uintptr_t)php
->p_vaddr
;
1131 const char *errfmt
= "core file data for mapping at %p not saved: %s\n";
1132 const char *incfmt
= "core file incomplete due to %s%s\n";
1133 const char *msgfmt
= "mappings at and above %p are missing\n";
1135 if (!(php
->p_flags
& PF_SUNW_KILLED
)) {
1138 (void) pread64(P
->asfd
, &err
,
1139 sizeof (err
), (off64_t
)php
->p_offset
);
1141 Perror_printf(P
, errfmt
, addr
, strerror(err
));
1142 dprintf(errfmt
, addr
, strerror(err
));
1146 if (!(php
->p_flags
& PF_SUNW_SIGINFO
))
1149 (void) memset(&killinfo
, 0, sizeof (killinfo
));
1151 (void) pread64(P
->asfd
, &killinfo
,
1152 sizeof (killinfo
), (off64_t
)php
->p_offset
);
1155 * While there is (or at least should be) only one segment that has
1156 * PF_SUNW_SIGINFO set, the signal information there is globally
1157 * useful (even if only to those debugging libproc consumers); we hang
1158 * the signal information gleaned here off of the ps_prochandle.
1160 P
->map_missing
= php
->p_vaddr
;
1161 P
->killinfo
= killinfo
.prk_info
;
1163 if (sig2str(si
->si_signo
, signame
) == -1) {
1164 (void) snprintf(sig
, sizeof (sig
),
1165 "<Unknown signal: 0x%x>, ", si
->si_signo
);
1167 (void) snprintf(sig
, sizeof (sig
), "SIG%s, ", signame
);
1170 if (si
->si_code
== SI_USER
|| si
->si_code
== SI_QUEUE
) {
1171 (void) snprintf(info
, sizeof (info
),
1172 "pid=%d uid=%d zone=%d ctid=%d",
1173 si
->si_pid
, si
->si_uid
, si
->si_zoneid
, si
->si_ctid
);
1175 (void) snprintf(info
, sizeof (info
),
1176 "code=%d", si
->si_code
);
1179 Perror_printf(P
, incfmt
, sig
, info
);
1180 Perror_printf(P
, msgfmt
, addr
);
1182 dprintf(incfmt
, sig
, info
);
1183 dprintf(msgfmt
, addr
);
1187 * Add information on the address space mapping described by the given
1188 * PT_LOAD program header. We fill in more information on the mapping later.
1191 core_add_mapping(struct ps_prochandle
*P
, GElf_Phdr
*php
)
1193 core_info_t
*core
= P
->data
;
1196 dprintf("mapping base %llx filesz %llx memsz %llx offset %llx\n",
1197 (u_longlong_t
)php
->p_vaddr
, (u_longlong_t
)php
->p_filesz
,
1198 (u_longlong_t
)php
->p_memsz
, (u_longlong_t
)php
->p_offset
);
1200 pmap
.pr_vaddr
= (uintptr_t)php
->p_vaddr
;
1201 pmap
.pr_size
= php
->p_memsz
;
1204 * If Pgcore() or elfcore() fail to write a mapping, they will set
1205 * PF_SUNW_FAILURE in the Phdr and try to stash away the errno for us.
1207 if (php
->p_flags
& PF_SUNW_FAILURE
) {
1208 core_report_mapping(P
, php
);
1209 } else if (php
->p_filesz
!= 0 && php
->p_offset
>= core
->core_size
) {
1210 Perror_printf(P
, "core file may be corrupt -- data for mapping "
1211 "at %p is missing\n", (void *)(uintptr_t)php
->p_vaddr
);
1212 dprintf("core file may be corrupt -- data for mapping "
1213 "at %p is missing\n", (void *)(uintptr_t)php
->p_vaddr
);
1217 * The mapping name and offset will hopefully be filled in
1218 * by the librtld_db agent. Unfortunately, if it isn't a
1219 * shared library mapping, this information is gone forever.
1221 pmap
.pr_mapname
[0] = '\0';
1225 if (php
->p_flags
& PF_R
)
1226 pmap
.pr_mflags
|= MA_READ
;
1227 if (php
->p_flags
& PF_W
)
1228 pmap
.pr_mflags
|= MA_WRITE
;
1229 if (php
->p_flags
& PF_X
)
1230 pmap
.pr_mflags
|= MA_EXEC
;
1232 if (php
->p_filesz
== 0)
1233 pmap
.pr_mflags
|= MA_RESERVED1
;
1236 * At the time of adding this mapping, we just zero the pagesize.
1237 * Once we've processed more of the core file, we'll have the
1238 * pagesize from the auxv's AT_PAGESZ element and we can fill this in.
1240 pmap
.pr_pagesize
= 0;
1243 * Unfortunately whether or not the mapping was a System V
1244 * shared memory segment is lost. We use -1 to mark it as not shm.
1248 return (Padd_mapping(P
, php
->p_offset
, NULL
, &pmap
));
1252 * Given a virtual address, name the mapping at that address using the
1253 * specified name, and return the map_info_t pointer.
1256 core_name_mapping(struct ps_prochandle
*P
, uintptr_t addr
, const char *name
)
1258 map_info_t
*mp
= Paddr2mptr(P
, addr
);
1261 (void) strncpy(mp
->map_pmap
.pr_mapname
, name
, PRMAPSZ
);
1262 mp
->map_pmap
.pr_mapname
[PRMAPSZ
- 1] = '\0';
1269 * libproc uses libelf for all of its symbol table manipulation. This function
1270 * takes a symbol table and string table from a core file and places them
1271 * in a memory backed elf file.
1274 fake_up_symtab(struct ps_prochandle
*P
, const elf_file_header_t
*ehdr
,
1275 GElf_Shdr
*symtab
, GElf_Shdr
*strtab
)
1284 if (symtab
->sh_addr
== 0 ||
1285 (mp
= Paddr2mptr(P
, symtab
->sh_addr
)) == NULL
||
1286 (fp
= mp
->map_file
) == NULL
) {
1287 dprintf("fake_up_symtab: invalid section\n");
1291 if (fp
->file_symtab
.sym_data_pri
!= NULL
) {
1292 dprintf("Symbol table already loaded (sh_addr 0x%lx)\n",
1293 (long)symtab
->sh_addr
);
1297 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
1304 base
= sizeof (b
->ehdr
) + sizeof (b
->shdr
);
1305 size
= base
+ symtab
->sh_size
+ strtab
->sh_size
;
1307 if ((b
= calloc(1, size
)) == NULL
)
1310 (void) memcpy(b
->ehdr
.e_ident
, ehdr
->e_ident
,
1311 sizeof (ehdr
->e_ident
));
1312 b
->ehdr
.e_type
= ehdr
->e_type
;
1313 b
->ehdr
.e_machine
= ehdr
->e_machine
;
1314 b
->ehdr
.e_version
= ehdr
->e_version
;
1315 b
->ehdr
.e_flags
= ehdr
->e_flags
;
1316 b
->ehdr
.e_ehsize
= sizeof (b
->ehdr
);
1317 b
->ehdr
.e_shoff
= sizeof (b
->ehdr
);
1318 b
->ehdr
.e_shentsize
= sizeof (b
->shdr
[0]);
1319 b
->ehdr
.e_shnum
= 3;
1322 b
->shdr
[1].sh_size
= symtab
->sh_size
;
1323 b
->shdr
[1].sh_type
= SHT_SYMTAB
;
1324 b
->shdr
[1].sh_offset
= off
+ base
;
1325 b
->shdr
[1].sh_entsize
= sizeof (Elf32_Sym
);
1326 b
->shdr
[1].sh_link
= 2;
1327 b
->shdr
[1].sh_info
= symtab
->sh_info
;
1328 b
->shdr
[1].sh_addralign
= symtab
->sh_addralign
;
1330 if (pread64(P
->asfd
, &b
->data
[off
], b
->shdr
[1].sh_size
,
1331 symtab
->sh_offset
) != b
->shdr
[1].sh_size
) {
1332 dprintf("fake_up_symtab: pread of symtab[1] failed\n");
1337 off
+= b
->shdr
[1].sh_size
;
1339 b
->shdr
[2].sh_flags
= SHF_STRINGS
;
1340 b
->shdr
[2].sh_size
= strtab
->sh_size
;
1341 b
->shdr
[2].sh_type
= SHT_STRTAB
;
1342 b
->shdr
[2].sh_offset
= off
+ base
;
1343 b
->shdr
[2].sh_info
= strtab
->sh_info
;
1344 b
->shdr
[2].sh_addralign
= 1;
1346 if (pread64(P
->asfd
, &b
->data
[off
], b
->shdr
[2].sh_size
,
1347 strtab
->sh_offset
) != b
->shdr
[2].sh_size
) {
1348 dprintf("fake_up_symtab: pread of symtab[2] failed\n");
1353 off
+= b
->shdr
[2].sh_size
;
1355 fp
->file_symtab
.sym_elf
= elf_memory((char *)b
, size
);
1356 if (fp
->file_symtab
.sym_elf
== NULL
) {
1361 fp
->file_symtab
.sym_elfmem
= b
;
1370 base
= sizeof (b
->ehdr
) + sizeof (b
->shdr
);
1371 size
= base
+ symtab
->sh_size
+ strtab
->sh_size
;
1373 if ((b
= calloc(1, size
)) == NULL
)
1376 (void) memcpy(b
->ehdr
.e_ident
, ehdr
->e_ident
,
1377 sizeof (ehdr
->e_ident
));
1378 b
->ehdr
.e_type
= ehdr
->e_type
;
1379 b
->ehdr
.e_machine
= ehdr
->e_machine
;
1380 b
->ehdr
.e_version
= ehdr
->e_version
;
1381 b
->ehdr
.e_flags
= ehdr
->e_flags
;
1382 b
->ehdr
.e_ehsize
= sizeof (b
->ehdr
);
1383 b
->ehdr
.e_shoff
= sizeof (b
->ehdr
);
1384 b
->ehdr
.e_shentsize
= sizeof (b
->shdr
[0]);
1385 b
->ehdr
.e_shnum
= 3;
1388 b
->shdr
[1].sh_size
= symtab
->sh_size
;
1389 b
->shdr
[1].sh_type
= SHT_SYMTAB
;
1390 b
->shdr
[1].sh_offset
= off
+ base
;
1391 b
->shdr
[1].sh_entsize
= sizeof (Elf64_Sym
);
1392 b
->shdr
[1].sh_link
= 2;
1393 b
->shdr
[1].sh_info
= symtab
->sh_info
;
1394 b
->shdr
[1].sh_addralign
= symtab
->sh_addralign
;
1396 if (pread64(P
->asfd
, &b
->data
[off
], b
->shdr
[1].sh_size
,
1397 symtab
->sh_offset
) != b
->shdr
[1].sh_size
) {
1402 off
+= b
->shdr
[1].sh_size
;
1404 b
->shdr
[2].sh_flags
= SHF_STRINGS
;
1405 b
->shdr
[2].sh_size
= strtab
->sh_size
;
1406 b
->shdr
[2].sh_type
= SHT_STRTAB
;
1407 b
->shdr
[2].sh_offset
= off
+ base
;
1408 b
->shdr
[2].sh_info
= strtab
->sh_info
;
1409 b
->shdr
[2].sh_addralign
= 1;
1411 if (pread64(P
->asfd
, &b
->data
[off
], b
->shdr
[2].sh_size
,
1412 strtab
->sh_offset
) != b
->shdr
[2].sh_size
) {
1417 off
+= b
->shdr
[2].sh_size
;
1419 fp
->file_symtab
.sym_elf
= elf_memory((char *)b
, size
);
1420 if (fp
->file_symtab
.sym_elf
== NULL
) {
1425 fp
->file_symtab
.sym_elfmem
= b
;
1429 if ((scn
= elf_getscn(fp
->file_symtab
.sym_elf
, 1)) == NULL
||
1430 (fp
->file_symtab
.sym_data_pri
= elf_getdata(scn
, NULL
)) == NULL
||
1431 (scn
= elf_getscn(fp
->file_symtab
.sym_elf
, 2)) == NULL
||
1432 (data
= elf_getdata(scn
, NULL
)) == NULL
) {
1433 dprintf("fake_up_symtab: failed to get section data at %p\n",
1438 fp
->file_symtab
.sym_strs
= data
->d_buf
;
1439 fp
->file_symtab
.sym_strsz
= data
->d_size
;
1440 fp
->file_symtab
.sym_symn
= symtab
->sh_size
/ symtab
->sh_entsize
;
1441 fp
->file_symtab
.sym_hdr_pri
= *symtab
;
1442 fp
->file_symtab
.sym_strhdr
= *strtab
;
1444 optimize_symtab(&fp
->file_symtab
);
1448 (void) elf_end(fp
->file_symtab
.sym_elf
);
1449 free(fp
->file_symtab
.sym_elfmem
);
1450 fp
->file_symtab
.sym_elf
= NULL
;
1451 fp
->file_symtab
.sym_elfmem
= NULL
;
1455 core_phdr_to_gelf(const Elf32_Phdr
*src
, GElf_Phdr
*dst
)
1457 dst
->p_type
= src
->p_type
;
1458 dst
->p_flags
= src
->p_flags
;
1459 dst
->p_offset
= (Elf64_Off
)src
->p_offset
;
1460 dst
->p_vaddr
= (Elf64_Addr
)src
->p_vaddr
;
1461 dst
->p_paddr
= (Elf64_Addr
)src
->p_paddr
;
1462 dst
->p_filesz
= (Elf64_Xword
)src
->p_filesz
;
1463 dst
->p_memsz
= (Elf64_Xword
)src
->p_memsz
;
1464 dst
->p_align
= (Elf64_Xword
)src
->p_align
;
1468 core_shdr_to_gelf(const Elf32_Shdr
*src
, GElf_Shdr
*dst
)
1470 dst
->sh_name
= src
->sh_name
;
1471 dst
->sh_type
= src
->sh_type
;
1472 dst
->sh_flags
= (Elf64_Xword
)src
->sh_flags
;
1473 dst
->sh_addr
= (Elf64_Addr
)src
->sh_addr
;
1474 dst
->sh_offset
= (Elf64_Off
)src
->sh_offset
;
1475 dst
->sh_size
= (Elf64_Xword
)src
->sh_size
;
1476 dst
->sh_link
= src
->sh_link
;
1477 dst
->sh_info
= src
->sh_info
;
1478 dst
->sh_addralign
= (Elf64_Xword
)src
->sh_addralign
;
1479 dst
->sh_entsize
= (Elf64_Xword
)src
->sh_entsize
;
1483 * Perform elf_begin on efp->e_fd and verify the ELF file's type and class.
1486 core_elf_fdopen(elf_file_t
*efp
, GElf_Half type
, int *perr
)
1489 uchar_t order
= ELFDATA2MSB
;
1491 uchar_t order
= ELFDATA2LSB
;
1498 * Because 32-bit libelf cannot deal with large files, we need to read,
1499 * check, and convert the file header manually in case type == ET_CORE.
1501 if (pread64(efp
->e_fd
, &e32
, sizeof (e32
), 0) != sizeof (e32
)) {
1506 if ((is_noelf
= memcmp(&e32
.e_ident
[EI_MAG0
], ELFMAG
, SELFMAG
)) != 0 ||
1507 e32
.e_type
!= type
|| (isa_err
= (e32
.e_ident
[EI_DATA
] != order
)) ||
1508 e32
.e_version
!= EV_CURRENT
) {
1510 if (is_noelf
== 0 && isa_err
) {
1520 * If the file is 64-bit and we are 32-bit, fail with G_LP64. If the
1521 * file is 64-bit and we are 64-bit, re-read the header as a Elf64_Ehdr,
1522 * and convert it to a elf_file_header_t. Otherwise, the file is
1523 * 32-bit, so convert e32 to a elf_file_header_t.
1525 if (e32
.e_ident
[EI_CLASS
] == ELFCLASS64
) {
1529 if (pread64(efp
->e_fd
, &e64
, sizeof (e64
), 0) != sizeof (e64
)) {
1535 (void) memcpy(efp
->e_hdr
.e_ident
, e64
.e_ident
, EI_NIDENT
);
1536 efp
->e_hdr
.e_type
= e64
.e_type
;
1537 efp
->e_hdr
.e_machine
= e64
.e_machine
;
1538 efp
->e_hdr
.e_version
= e64
.e_version
;
1539 efp
->e_hdr
.e_entry
= e64
.e_entry
;
1540 efp
->e_hdr
.e_phoff
= e64
.e_phoff
;
1541 efp
->e_hdr
.e_shoff
= e64
.e_shoff
;
1542 efp
->e_hdr
.e_flags
= e64
.e_flags
;
1543 efp
->e_hdr
.e_ehsize
= e64
.e_ehsize
;
1544 efp
->e_hdr
.e_phentsize
= e64
.e_phentsize
;
1545 efp
->e_hdr
.e_phnum
= (Elf64_Word
)e64
.e_phnum
;
1546 efp
->e_hdr
.e_shentsize
= e64
.e_shentsize
;
1547 efp
->e_hdr
.e_shnum
= (Elf64_Word
)e64
.e_shnum
;
1548 efp
->e_hdr
.e_shstrndx
= (Elf64_Word
)e64
.e_shstrndx
;
1555 (void) memcpy(efp
->e_hdr
.e_ident
, e32
.e_ident
, EI_NIDENT
);
1556 efp
->e_hdr
.e_type
= e32
.e_type
;
1557 efp
->e_hdr
.e_machine
= e32
.e_machine
;
1558 efp
->e_hdr
.e_version
= e32
.e_version
;
1559 efp
->e_hdr
.e_entry
= (Elf64_Addr
)e32
.e_entry
;
1560 efp
->e_hdr
.e_phoff
= (Elf64_Off
)e32
.e_phoff
;
1561 efp
->e_hdr
.e_shoff
= (Elf64_Off
)e32
.e_shoff
;
1562 efp
->e_hdr
.e_flags
= e32
.e_flags
;
1563 efp
->e_hdr
.e_ehsize
= e32
.e_ehsize
;
1564 efp
->e_hdr
.e_phentsize
= e32
.e_phentsize
;
1565 efp
->e_hdr
.e_phnum
= (Elf64_Word
)e32
.e_phnum
;
1566 efp
->e_hdr
.e_shentsize
= e32
.e_shentsize
;
1567 efp
->e_hdr
.e_shnum
= (Elf64_Word
)e32
.e_shnum
;
1568 efp
->e_hdr
.e_shstrndx
= (Elf64_Word
)e32
.e_shstrndx
;
1572 * If the number of section headers or program headers or the section
1573 * header string table index would overflow their respective fields
1574 * in the ELF header, they're stored in the section header at index
1575 * zero. To simplify use elsewhere, we look for those sentinel values
1578 if ((efp
->e_hdr
.e_shnum
== 0 && efp
->e_hdr
.e_shoff
!= 0) ||
1579 efp
->e_hdr
.e_shstrndx
== SHN_XINDEX
||
1580 efp
->e_hdr
.e_phnum
== PN_XNUM
) {
1583 dprintf("extended ELF header\n");
1585 if (efp
->e_hdr
.e_shoff
== 0) {
1591 if (efp
->e_hdr
.e_ident
[EI_CLASS
] == ELFCLASS32
) {
1594 if (pread64(efp
->e_fd
, &shdr32
, sizeof (shdr32
),
1595 efp
->e_hdr
.e_shoff
) != sizeof (shdr32
)) {
1601 core_shdr_to_gelf(&shdr32
, &shdr
);
1603 if (pread64(efp
->e_fd
, &shdr
, sizeof (shdr
),
1604 efp
->e_hdr
.e_shoff
) != sizeof (shdr
)) {
1611 if (efp
->e_hdr
.e_shnum
== 0) {
1612 efp
->e_hdr
.e_shnum
= shdr
.sh_size
;
1613 dprintf("section header count %lu\n",
1614 (ulong_t
)shdr
.sh_size
);
1617 if (efp
->e_hdr
.e_shstrndx
== SHN_XINDEX
) {
1618 efp
->e_hdr
.e_shstrndx
= shdr
.sh_link
;
1619 dprintf("section string index %u\n", shdr
.sh_link
);
1622 if (efp
->e_hdr
.e_phnum
== PN_XNUM
&& shdr
.sh_info
!= 0) {
1623 efp
->e_hdr
.e_phnum
= shdr
.sh_info
;
1624 dprintf("program header count %u\n", shdr
.sh_info
);
1627 } else if (efp
->e_hdr
.e_phoff
!= 0) {
1632 * It's possible this core file came from a system that
1633 * accidentally truncated the e_phnum field without correctly
1634 * using the extended format in the section header at index
1635 * zero. We try to detect and correct that specific type of
1636 * corruption by using the knowledge that the core dump
1637 * routines usually place the data referenced by the first
1638 * program header immediately after the last header element.
1640 if (efp
->e_hdr
.e_ident
[EI_CLASS
] == ELFCLASS32
) {
1643 if (pread64(efp
->e_fd
, &phdr32
, sizeof (phdr32
),
1644 efp
->e_hdr
.e_phoff
) != sizeof (phdr32
)) {
1650 core_phdr_to_gelf(&phdr32
, &phdr
);
1652 if (pread64(efp
->e_fd
, &phdr
, sizeof (phdr
),
1653 efp
->e_hdr
.e_phoff
) != sizeof (phdr
)) {
1660 phnum
= phdr
.p_offset
- efp
->e_hdr
.e_ehsize
-
1661 (uint64_t)efp
->e_hdr
.e_shnum
* efp
->e_hdr
.e_shentsize
;
1662 phnum
/= efp
->e_hdr
.e_phentsize
;
1664 if (phdr
.p_offset
!= 0 && phnum
!= efp
->e_hdr
.e_phnum
) {
1665 dprintf("suspicious program header count %u %u\n",
1666 (uint_t
)phnum
, efp
->e_hdr
.e_phnum
);
1669 * If the new program header count we computed doesn't
1670 * jive with count in the ELF header, we'll use the
1671 * data that's there and hope for the best.
1673 * If it does, it's also possible that the section
1674 * header offset is incorrect; we'll check that and
1675 * possibly try to fix it.
1677 if (phnum
<= INT_MAX
&&
1678 (uint16_t)phnum
== efp
->e_hdr
.e_phnum
) {
1680 if (efp
->e_hdr
.e_shoff
== efp
->e_hdr
.e_phoff
+
1681 efp
->e_hdr
.e_phentsize
*
1682 (uint_t
)efp
->e_hdr
.e_phnum
) {
1683 efp
->e_hdr
.e_shoff
=
1684 efp
->e_hdr
.e_phoff
+
1685 efp
->e_hdr
.e_phentsize
* phnum
;
1688 efp
->e_hdr
.e_phnum
= (Elf64_Word
)phnum
;
1689 dprintf("using new program header count\n");
1691 dprintf("inconsistent program header count\n");
1697 * The libelf implementation was never ported to be large-file aware.
1698 * This is typically not a problem for your average executable or
1699 * shared library, but a large 32-bit core file can exceed 2GB in size.
1700 * So if type is ET_CORE, we don't bother doing elf_begin; the code
1701 * in Pfgrab_core() below will do its own i/o and struct conversion.
1704 if (type
== ET_CORE
) {
1709 if ((efp
->e_elf
= elf_begin(efp
->e_fd
, ELF_C_READ
, NULL
)) == NULL
) {
1723 * Open the specified file and then do a core_elf_fdopen on it.
1726 core_elf_open(elf_file_t
*efp
, const char *path
, GElf_Half type
, int *perr
)
1728 (void) memset(efp
, 0, sizeof (elf_file_t
));
1730 if ((efp
->e_fd
= open64(path
, O_RDONLY
)) >= 0) {
1731 if (core_elf_fdopen(efp
, type
, perr
) == 0)
1734 (void) close(efp
->e_fd
);
1742 * Close the ELF handle and file descriptor.
1745 core_elf_close(elf_file_t
*efp
)
1747 if (efp
->e_elf
!= NULL
) {
1748 (void) elf_end(efp
->e_elf
);
1752 if (efp
->e_fd
!= -1) {
1753 (void) close(efp
->e_fd
);
1759 * Given an ELF file for a statically linked executable, locate the likely
1760 * primary text section and fill in rl_base with its virtual address.
1763 core_find_text(struct ps_prochandle
*P
, Elf
*elf
, rd_loadobj_t
*rlp
)
1769 if (elf_getphdrnum(elf
, &nphdrs
) == -1)
1772 for (i
= 0; i
< nphdrs
; i
++) {
1773 if (gelf_getphdr(elf
, i
, &phdr
) != NULL
&&
1774 phdr
.p_type
== PT_LOAD
&& (phdr
.p_flags
& PF_X
)) {
1775 rlp
->rl_base
= phdr
.p_vaddr
;
1776 return (Paddr2mptr(P
, rlp
->rl_base
));
1784 * Given an ELF file and the librtld_db structure corresponding to its primary
1785 * text mapping, deduce where its data segment was loaded and fill in
1786 * rl_data_base and prmap_t.pr_offset accordingly.
1789 core_find_data(struct ps_prochandle
*P
, Elf
*elf
, rd_loadobj_t
*rlp
)
1797 rlp
->rl_data_base
= 0;
1800 * Find the first loadable, writeable Phdr and compute rl_data_base
1801 * as the virtual address at which is was loaded.
1803 if (gelf_getehdr(elf
, &ehdr
) == NULL
||
1804 elf_getphdrnum(elf
, &nphdrs
) == -1)
1807 for (i
= 0; i
< nphdrs
; i
++) {
1808 if (gelf_getphdr(elf
, i
, &phdr
) != NULL
&&
1809 phdr
.p_type
== PT_LOAD
&& (phdr
.p_flags
& PF_W
)) {
1810 rlp
->rl_data_base
= phdr
.p_vaddr
;
1811 if (ehdr
.e_type
== ET_DYN
)
1812 rlp
->rl_data_base
+= rlp
->rl_base
;
1818 * If we didn't find an appropriate phdr or if the address we
1819 * computed has no mapping, return NULL.
1821 if (rlp
->rl_data_base
== 0 ||
1822 (mp
= Paddr2mptr(P
, rlp
->rl_data_base
)) == NULL
)
1826 * It wouldn't be procfs-related code if we didn't make use of
1827 * unclean knowledge of segvn, even in userland ... the prmap_t's
1828 * pr_offset field will be the segvn offset from mmap(2)ing the
1829 * data section, which will be the file offset & PAGEMASK.
1831 pagemask
= ~(mp
->map_pmap
.pr_pagesize
- 1);
1832 mp
->map_pmap
.pr_offset
= phdr
.p_offset
& pagemask
;
1838 * Librtld_db agent callback for iterating over load object mappings.
1839 * For each load object, we allocate a new file_info_t, perform naming,
1840 * and attempt to construct a symbol table for the load object.
1843 core_iter_mapping(const rd_loadobj_t
*rlp
, struct ps_prochandle
*P
)
1845 core_info_t
*core
= P
->data
;
1846 char lname
[PATH_MAX
], buf
[PATH_MAX
];
1850 if (Pread_string(P
, lname
, PATH_MAX
, (off_t
)rlp
->rl_nameaddr
) <= 0) {
1851 dprintf("failed to read name %p\n", (void *)rlp
->rl_nameaddr
);
1852 return (1); /* Keep going; forget this if we can't get a name */
1855 dprintf("rd_loadobj name = \"%s\" rl_base = %p\n",
1856 lname
, (void *)rlp
->rl_base
);
1858 if ((mp
= Paddr2mptr(P
, rlp
->rl_base
)) == NULL
) {
1859 dprintf("no mapping for %p\n", (void *)rlp
->rl_base
);
1860 return (1); /* No mapping; advance to next mapping */
1864 * Create a new file_info_t for this mapping, and therefore for
1867 * If there's an ELF header at the beginning of this mapping,
1868 * file_info_new() will try to use its section headers to
1869 * identify any other mappings that belong to this load object.
1871 if ((fp
= mp
->map_file
) == NULL
&&
1872 (fp
= file_info_new(P
, mp
)) == NULL
) {
1873 core
->core_errno
= errno
;
1874 dprintf("failed to malloc mapping data\n");
1875 return (0); /* Abort */
1879 /* Create a local copy of the load object representation */
1880 if ((fp
->file_lo
= calloc(1, sizeof (rd_loadobj_t
))) == NULL
) {
1881 core
->core_errno
= errno
;
1882 dprintf("failed to malloc mapping data\n");
1883 return (0); /* Abort */
1885 *fp
->file_lo
= *rlp
;
1887 if (lname
[0] != '\0') {
1889 * Naming dance part 1: if we got a name from librtld_db, then
1890 * copy this name to the prmap_t if it is unnamed. If the
1891 * file_info_t is unnamed, name it after the lname.
1893 if (mp
->map_pmap
.pr_mapname
[0] == '\0') {
1894 (void) strncpy(mp
->map_pmap
.pr_mapname
, lname
, PRMAPSZ
);
1895 mp
->map_pmap
.pr_mapname
[PRMAPSZ
- 1] = '\0';
1898 if (fp
->file_lname
== NULL
)
1899 fp
->file_lname
= strdup(lname
);
1901 } else if (fp
->file_lname
== NULL
&&
1902 mp
->map_pmap
.pr_mapname
[0] != '\0') {
1904 * Naming dance part 2: if the mapping is named and the
1905 * file_info_t is not, name the file after the mapping.
1907 fp
->file_lname
= strdup(mp
->map_pmap
.pr_mapname
);
1910 if ((fp
->file_rname
== NULL
) &&
1911 (Pfindmap(P
, mp
, buf
, sizeof (buf
)) != NULL
))
1912 fp
->file_rname
= strdup(buf
);
1914 if (fp
->file_lname
!= NULL
)
1915 fp
->file_lbase
= basename(fp
->file_lname
);
1916 if (fp
->file_rname
!= NULL
)
1917 fp
->file_rbase
= basename(fp
->file_rname
);
1919 /* Associate the file and the mapping. */
1920 (void) strncpy(fp
->file_pname
, mp
->map_pmap
.pr_mapname
, PRMAPSZ
);
1921 fp
->file_pname
[PRMAPSZ
- 1] = '\0';
1924 * If no section headers were available then we'll have to
1925 * identify this load object's other mappings with what we've
1926 * got: the start and end of the object's corresponding
1929 if (fp
->file_saddrs
== NULL
) {
1930 for (mp
= fp
->file_map
+ 1; mp
< P
->mappings
+ P
->map_count
&&
1931 mp
->map_pmap
.pr_vaddr
< rlp
->rl_bend
; mp
++) {
1933 if (mp
->map_file
== NULL
) {
1934 dprintf("core_iter_mapping %s: associating "
1937 (void *)mp
->map_pmap
.pr_vaddr
);
1941 dprintf("core_iter_mapping %s: segment at "
1942 "%p already associated with %s\n",
1944 (void *)mp
->map_pmap
.pr_vaddr
,
1945 (mp
== fp
->file_map
? "this file" :
1946 mp
->map_file
->file_pname
));
1951 /* Ensure that all this file's mappings are named. */
1952 for (mp
= fp
->file_map
; mp
< P
->mappings
+ P
->map_count
&&
1953 mp
->map_file
== fp
; mp
++) {
1954 if (mp
->map_pmap
.pr_mapname
[0] == '\0' &&
1955 !(mp
->map_pmap
.pr_mflags
& MA_BREAK
)) {
1956 (void) strncpy(mp
->map_pmap
.pr_mapname
, fp
->file_pname
,
1958 mp
->map_pmap
.pr_mapname
[PRMAPSZ
- 1] = '\0';
1962 /* Attempt to build a symbol table for this file. */
1963 Pbuild_file_symtab(P
, fp
);
1964 if (fp
->file_elf
== NULL
)
1965 dprintf("core_iter_mapping: no symtab for %s\n",
1968 /* Locate the start of a data segment associated with this file. */
1969 if ((mp
= core_find_data(P
, fp
->file_elf
, fp
->file_lo
)) != NULL
) {
1970 dprintf("found data for %s at %p (pr_offset 0x%llx)\n",
1971 fp
->file_pname
, (void *)fp
->file_lo
->rl_data_base
,
1972 mp
->map_pmap
.pr_offset
);
1974 dprintf("core_iter_mapping: no data found for %s\n",
1978 return (1); /* Advance to next mapping */
1982 * Callback function for Pfindexec(). In order to confirm a given pathname,
1983 * we verify that we can open it as an ELF file of type ET_EXEC or ET_DYN.
1986 core_exec_open(const char *path
, void *efp
)
1988 if (core_elf_open(efp
, path
, ET_EXEC
, NULL
) == 0)
1990 if (core_elf_open(efp
, path
, ET_DYN
, NULL
) == 0)
1996 * Attempt to load any section headers found in the core file. If present,
1997 * this will refer to non-loadable data added to the core file by the kernel
1998 * based on coreadm(1M) settings, including CTF data and the symbol table.
2001 core_load_shdrs(struct ps_prochandle
*P
, elf_file_t
*efp
)
2003 GElf_Shdr
*shp
, *shdrs
= NULL
;
2004 char *shstrtab
= NULL
;
2013 if (efp
->e_hdr
.e_shstrndx
>= efp
->e_hdr
.e_shnum
) {
2014 dprintf("corrupt shstrndx (%u) exceeds shnum (%u)\n",
2015 efp
->e_hdr
.e_shstrndx
, efp
->e_hdr
.e_shnum
);
2020 * Read the section header table from the core file and then iterate
2021 * over the section headers, converting each to a GElf_Shdr.
2023 if ((shdrs
= malloc(efp
->e_hdr
.e_shnum
* sizeof (GElf_Shdr
))) == NULL
) {
2024 dprintf("failed to malloc %u section headers: %s\n",
2025 (uint_t
)efp
->e_hdr
.e_shnum
, strerror(errno
));
2029 nbytes
= efp
->e_hdr
.e_shnum
* efp
->e_hdr
.e_shentsize
;
2030 if ((buf
= malloc(nbytes
)) == NULL
) {
2031 dprintf("failed to malloc %d bytes: %s\n", (int)nbytes
,
2037 if (pread64(efp
->e_fd
, buf
, nbytes
, efp
->e_hdr
.e_shoff
) != nbytes
) {
2038 dprintf("failed to read section headers at off %lld: %s\n",
2039 (longlong_t
)efp
->e_hdr
.e_shoff
, strerror(errno
));
2044 for (i
= 0; i
< efp
->e_hdr
.e_shnum
; i
++) {
2045 void *p
= (uchar_t
*)buf
+ efp
->e_hdr
.e_shentsize
* i
;
2047 if (efp
->e_hdr
.e_ident
[EI_CLASS
] == ELFCLASS32
)
2048 core_shdr_to_gelf(p
, &shdrs
[i
]);
2050 (void) memcpy(&shdrs
[i
], p
, sizeof (GElf_Shdr
));
2057 * Read the .shstrtab section from the core file, terminating it with
2058 * an extra \0 so that a corrupt section will not cause us to die.
2060 shp
= &shdrs
[efp
->e_hdr
.e_shstrndx
];
2061 shstrtabsz
= shp
->sh_size
;
2063 if ((shstrtab
= malloc(shstrtabsz
+ 1)) == NULL
) {
2064 dprintf("failed to allocate %lu bytes for shstrtab\n",
2065 (ulong_t
)shstrtabsz
);
2069 if (pread64(efp
->e_fd
, shstrtab
, shstrtabsz
,
2070 shp
->sh_offset
) != shstrtabsz
) {
2071 dprintf("failed to read %lu bytes of shstrs at off %lld: %s\n",
2072 shstrtabsz
, (longlong_t
)shp
->sh_offset
, strerror(errno
));
2076 shstrtab
[shstrtabsz
] = '\0';
2079 * Now iterate over each section in the section header table, locating
2080 * sections of interest and initializing more of the ps_prochandle.
2082 for (i
= 0; i
< efp
->e_hdr
.e_shnum
; i
++) {
2084 name
= shstrtab
+ shp
->sh_name
;
2086 if (shp
->sh_name
>= shstrtabsz
) {
2087 dprintf("skipping section [%d]: corrupt sh_name\n", i
);
2091 if (shp
->sh_link
>= efp
->e_hdr
.e_shnum
) {
2092 dprintf("skipping section [%d]: corrupt sh_link\n", i
);
2096 dprintf("found section header %s (sh_addr 0x%llx)\n",
2097 name
, (u_longlong_t
)shp
->sh_addr
);
2099 if (strcmp(name
, ".SUNW_ctf") == 0) {
2100 if ((mp
= Paddr2mptr(P
, shp
->sh_addr
)) == NULL
) {
2101 dprintf("no map at addr 0x%llx for %s [%d]\n",
2102 (u_longlong_t
)shp
->sh_addr
, name
, i
);
2106 if (mp
->map_file
== NULL
||
2107 mp
->map_file
->file_ctf_buf
!= NULL
) {
2108 dprintf("no mapping file or duplicate buffer "
2109 "for %s [%d]\n", name
, i
);
2113 if ((buf
= malloc(shp
->sh_size
)) == NULL
||
2114 pread64(efp
->e_fd
, buf
, shp
->sh_size
,
2115 shp
->sh_offset
) != shp
->sh_size
) {
2116 dprintf("skipping section %s [%d]: %s\n",
2117 name
, i
, strerror(errno
));
2122 mp
->map_file
->file_ctf_size
= shp
->sh_size
;
2123 mp
->map_file
->file_ctf_buf
= buf
;
2125 if (shdrs
[shp
->sh_link
].sh_type
== SHT_DYNSYM
)
2126 mp
->map_file
->file_ctf_dyn
= 1;
2128 } else if (strcmp(name
, ".symtab") == 0) {
2129 fake_up_symtab(P
, &efp
->e_hdr
,
2130 shp
, &shdrs
[shp
->sh_link
]);
2139 * Main engine for core file initialization: given an fd for the core file
2140 * and an optional pathname, construct the ps_prochandle. The aout_path can
2141 * either be a suggested executable pathname, or a suggested directory to
2142 * use as a possible current working directory.
2144 struct ps_prochandle
*
2145 Pfgrab_core(int core_fd
, const char *aout_path
, int *perr
)
2147 struct ps_prochandle
*P
;
2148 core_info_t
*core_info
;
2149 map_info_t
*stk_mp
, *brk_mp
;
2150 const char *execname
;
2152 int i
, notes
, pagesize
;
2153 uintptr_t addr
, base_addr
;
2154 struct stat64 stbuf
;
2157 #ifdef CONFIG_LINUX_CORE_SUPPORT
2158 boolean_t from_linux
= B_FALSE
;
2164 Elf_Scn
*scn
, *intp_scn
= NULL
;
2167 GElf_Phdr phdr
, note_phdr
;
2171 if (elf_version(EV_CURRENT
) == EV_NONE
) {
2172 dprintf("libproc ELF version is more recent than libelf\n");
2181 core
.e_fd
= core_fd
;
2184 * Allocate and initialize a ps_prochandle structure for the core.
2185 * There are several key pieces of initialization here:
2187 * 1. The PS_DEAD state flag marks this prochandle as a core file.
2188 * PS_DEAD also thus prevents all operations which require state
2189 * to be PS_STOP from operating on this handle.
2191 * 2. We keep the core file fd in P->asfd since the core file contains
2192 * the remnants of the process address space.
2194 * 3. We set the P->info_valid bit because all information about the
2195 * core is determined by the end of this function; there is no need
2196 * for proc_update_maps() to reload mappings at any later point.
2198 * 4. The read/write ops vector uses our core_rw() function defined
2199 * above to handle i/o requests.
2201 if ((P
= malloc(sizeof (struct ps_prochandle
))) == NULL
) {
2206 (void) memset(P
, 0, sizeof (struct ps_prochandle
));
2207 (void) mutex_init(&P
->proc_lock
, USYNC_THREAD
, NULL
);
2210 P
->asfd
= core
.e_fd
;
2214 P
->agentstatfd
= -1;
2217 Pinit_ops(&P
->ops
, &P_core_ops
);
2222 * Fstat and open the core file and make sure it is a valid ELF core.
2224 if (fstat64(P
->asfd
, &stbuf
) == -1) {
2229 if (core_elf_fdopen(&core
, ET_CORE
, perr
) == -1)
2233 * Allocate and initialize a core_info_t to hang off the ps_prochandle
2234 * structure. We keep all core-specific information in this structure.
2236 if ((core_info
= calloc(1, sizeof (core_info_t
))) == NULL
) {
2241 P
->data
= core_info
;
2242 list_link(&core_info
->core_lwp_head
, NULL
);
2243 core_info
->core_size
= stbuf
.st_size
;
2245 * In the days before adjustable core file content, this was the
2246 * default core file content. For new core files, this value will
2247 * be overwritten by the NT_CONTENT note section.
2249 core_info
->core_content
= CC_CONTENT_STACK
| CC_CONTENT_HEAP
|
2250 CC_CONTENT_DATA
| CC_CONTENT_RODATA
| CC_CONTENT_ANON
|
2253 switch (core
.e_hdr
.e_ident
[EI_CLASS
]) {
2255 core_info
->core_dmodel
= PR_MODEL_ILP32
;
2258 core_info
->core_dmodel
= PR_MODEL_LP64
;
2264 core_info
->core_osabi
= core
.e_hdr
.e_ident
[EI_OSABI
];
2267 * Because the core file may be a large file, we can't use libelf to
2268 * read the Phdrs. We use e_phnum and e_phentsize to simplify things.
2270 nbytes
= core
.e_hdr
.e_phnum
* core
.e_hdr
.e_phentsize
;
2272 if ((phbuf
= malloc(nbytes
)) == NULL
) {
2277 if (pread64(core_fd
, phbuf
, nbytes
, core
.e_hdr
.e_phoff
) != nbytes
) {
2284 * Iterate through the program headers in the core file.
2285 * We're interested in two types of Phdrs: PT_NOTE (which
2286 * contains a set of saved /proc structures), and PT_LOAD (which
2287 * represents a memory mapping from the process's address space).
2288 * In the case of PT_NOTE, we're interested in the last PT_NOTE
2289 * in the core file; currently the first PT_NOTE (if present)
2290 * contains /proc structs in the pre-2.6 unstructured /proc format.
2292 for (php
= phbuf
, notes
= 0, i
= 0; i
< core
.e_hdr
.e_phnum
; i
++) {
2293 if (core
.e_hdr
.e_ident
[EI_CLASS
] == ELFCLASS64
)
2294 (void) memcpy(&phdr
, php
, sizeof (GElf_Phdr
));
2296 core_phdr_to_gelf(php
, &phdr
);
2298 switch (phdr
.p_type
) {
2305 if (core_add_mapping(P
, &phdr
) == -1) {
2312 dprintf("Pgrab_core: unknown phdr %d\n", phdr
.p_type
);
2316 php
= (char *)php
+ core
.e_hdr
.e_phentsize
;
2324 * If we couldn't find anything of type PT_NOTE, or only one PT_NOTE
2325 * was present, abort. The core file is either corrupt or too old.
2327 if (notes
== 0 || (notes
== 1 && core_info
->core_osabi
==
2328 ELFOSABI_SOLARIS
)) {
2334 * Advance the seek pointer to the start of the PT_NOTE data
2336 if (lseek64(P
->asfd
, note_phdr
.p_offset
, SEEK_SET
) == (off64_t
)-1) {
2337 dprintf("Pgrab_core: failed to lseek to PT_NOTE data\n");
2343 * Now process the PT_NOTE structures. Each one is preceded by
2344 * an Elf{32/64}_Nhdr structure describing its type and size.
2356 for (nleft
= note_phdr
.p_filesz
; nleft
> 0; ) {
2358 off64_t off
, namesz
, descsz
;
2361 * Although <sys/elf.h> defines both Elf32_Nhdr and Elf64_Nhdr
2362 * as different types, they are both of the same content and
2363 * size, so we don't need to worry about 32/64 conversion here.
2365 if (read(P
->asfd
, &nhdr
, sizeof (nhdr
)) != sizeof (nhdr
)) {
2366 dprintf("Pgrab_core: failed to read ELF note header\n");
2372 * According to the System V ABI, the amount of padding
2373 * following the name field should align the description
2374 * field on a 4 byte boundary for 32-bit binaries or on an 8
2375 * byte boundary for 64-bit binaries. However, this change
2376 * was not made correctly during the 64-bit port so all
2377 * descriptions can assume only 4-byte alignment. We ignore
2378 * the name field and the padding to 4-byte alignment.
2380 namesz
= P2ROUNDUP((off64_t
)nhdr
.n_namesz
, (off64_t
)4);
2382 if (lseek64(P
->asfd
, namesz
, SEEK_CUR
) == (off64_t
)-1) {
2383 dprintf("failed to seek past name and padding\n");
2388 dprintf("Note hdr n_type=%u n_namesz=%u n_descsz=%u\n",
2389 nhdr
.n_type
, nhdr
.n_namesz
, nhdr
.n_descsz
);
2391 off
= lseek64(P
->asfd
, (off64_t
)0L, SEEK_CUR
);
2394 * Invoke the note handler function from our table
2396 if (nhdr
.n_type
< sizeof (nhdlrs
) / sizeof (nhdlrs
[0])) {
2397 if (nhdlrs
[nhdr
.n_type
](P
, nhdr
.n_descsz
) < 0) {
2398 dprintf("handler for type %d returned < 0",
2403 #ifdef CONFIG_LINUX_CORE_SUPPORT
2405 * The presence of either of these notes indicates that
2406 * the dump was generated on Linux.
2408 if (nhdr
.n_type
== NT_PRSTATUS
||
2409 nhdr
.n_type
== NT_PRPSINFO
)
2410 from_linux
= B_TRUE
;
2413 (void) note_notsup(P
, nhdr
.n_descsz
);
2417 * Seek past the current note data to the next Elf_Nhdr
2419 descsz
= P2ROUNDUP((off64_t
)nhdr
.n_descsz
, (off64_t
)4);
2420 if (lseek64(P
->asfd
, off
+ descsz
, SEEK_SET
) == (off64_t
)-1) {
2421 dprintf("Pgrab_core: failed to seek to next nhdr\n");
2427 * Subtract the size of the header and its data from what
2428 * we have left to process.
2430 nleft
-= sizeof (nhdr
) + namesz
+ descsz
;
2433 #ifdef CONFIG_LINUX_CORE_SUPPORT
2438 P
->status
.pr_dmodel
= core_info
->core_dmodel
;
2440 lwp
= list_next(&core_info
->core_lwp_head
);
2442 pid
= P
->status
.pr_pid
;
2444 for (tcount
= 0; tcount
< core_info
->core_nlwp
;
2445 tcount
++, lwp
= list_next(lwp
)) {
2446 dprintf("Linux thread with id %d\n", lwp
->lwp_id
);
2449 * In the case we don't have a valid psinfo (i.e. pid is
2450 * 0, probably because of gdb creating the core) assume
2451 * lowest pid count is the first thread (what if the
2452 * next thread wraps the pid around?)
2454 if (P
->status
.pr_pid
== 0 &&
2455 ((pid
== 0 && lwp
->lwp_id
> 0) ||
2456 (lwp
->lwp_id
< pid
))) {
2461 if (P
->status
.pr_pid
!= pid
) {
2462 dprintf("No valid pid, setting to %ld\n", (ulong_t
)pid
);
2463 P
->status
.pr_pid
= pid
;
2464 P
->psinfo
.pr_pid
= pid
;
2468 * Consumers like mdb expect the first thread to actually have
2469 * an id of 1, on linux that is actually the pid. Find the the
2470 * thread with our process id, and set the id to 1
2472 if ((lwp
= lwpid2info(P
, pid
)) == NULL
) {
2473 dprintf("Couldn't find first thread\n");
2478 dprintf("setting representative thread: %d\n", lwp
->lwp_id
);
2481 lwp
->lwp_status
.pr_lwpid
= 1;
2483 /* set representative thread */
2484 (void) memcpy(&P
->status
.pr_lwp
, &lwp
->lwp_status
,
2485 sizeof (P
->status
.pr_lwp
));
2487 #endif /* CONFIG_LINUX_CORE_SUPPORT */
2490 dprintf("Pgrab_core: note section malformed\n");
2495 if ((pagesize
= Pgetauxval(P
, AT_PAGESZ
)) == -1) {
2496 pagesize
= getpagesize();
2497 dprintf("AT_PAGESZ missing; defaulting to %d\n", pagesize
);
2501 * Locate and label the mappings corresponding to the end of the
2502 * heap (MA_BREAK) and the base of the stack (MA_STACK).
2504 if ((P
->status
.pr_brkbase
!= 0 || P
->status
.pr_brksize
!= 0) &&
2505 (brk_mp
= Paddr2mptr(P
, P
->status
.pr_brkbase
+
2506 P
->status
.pr_brksize
- 1)) != NULL
)
2507 brk_mp
->map_pmap
.pr_mflags
|= MA_BREAK
;
2511 if ((stk_mp
= Paddr2mptr(P
, P
->status
.pr_stkbase
)) != NULL
)
2512 stk_mp
->map_pmap
.pr_mflags
|= MA_STACK
;
2515 * At this point, we have enough information to look for the
2516 * executable and open it: we have access to the auxv, a psinfo_t,
2517 * and the ability to read from mappings provided by the core file.
2519 (void) Pfindexec(P
, aout_path
, core_exec_open
, &aout
);
2520 dprintf("P->execname = \"%s\"\n", P
->execname
? P
->execname
: "NULL");
2521 execname
= P
->execname
? P
->execname
: "a.out";
2524 * Iterate through the sections, looking for the .dynamic and .interp
2525 * sections. If we encounter them, remember their section pointers.
2527 for (scn
= NULL
; (scn
= elf_nextscn(aout
.e_elf
, scn
)) != NULL
; ) {
2530 if ((gelf_getshdr(scn
, &shdr
) == NULL
) ||
2531 (sname
= elf_strptr(aout
.e_elf
, aout
.e_hdr
.e_shstrndx
,
2532 (size_t)shdr
.sh_name
)) == NULL
)
2535 if (strcmp(sname
, ".interp") == 0)
2540 * Get the AT_BASE auxv element. If this is missing (-1), then
2541 * we assume this is a statically-linked executable.
2543 base_addr
= Pgetauxval(P
, AT_BASE
);
2546 * In order to get librtld_db initialized, we'll need to identify
2547 * and name the mapping corresponding to the run-time linker. The
2548 * AT_BASE auxv element tells us the address where it was mapped,
2549 * and the .interp section of the executable tells us its path.
2550 * If for some reason that doesn't pan out, just use ld.so.1.
2552 if (intp_scn
!= NULL
&& (dp
= elf_getdata(intp_scn
, NULL
)) != NULL
&&
2554 dprintf(".interp = <%s>\n", (char *)dp
->d_buf
);
2557 } else if (base_addr
!= (uintptr_t)-1L) {
2558 if (core_info
->core_dmodel
== PR_MODEL_LP64
)
2559 interp
= "/usr/lib/64/ld.so.1";
2561 interp
= "/usr/lib/ld.so.1";
2563 dprintf(".interp section is missing or could not be read; "
2564 "defaulting to %s\n", interp
);
2566 dprintf("detected statically linked executable\n");
2569 * If we have an AT_BASE element, name the mapping at that address
2570 * using the interpreter pathname. Name the corresponding data
2571 * mapping after the interpreter as well.
2573 if (base_addr
!= (uintptr_t)-1L) {
2576 P
->map_ldso
= core_name_mapping(P
, base_addr
, interp
);
2578 if (core_elf_open(&intf
, interp
, ET_DYN
, NULL
) == 0) {
2582 rl
.rl_base
= base_addr
;
2583 dmp
= core_find_data(P
, intf
.e_elf
, &rl
);
2586 dprintf("renamed data at %p to %s\n",
2587 (void *)rl
.rl_data_base
, interp
);
2588 (void) strncpy(dmp
->map_pmap
.pr_mapname
,
2590 dmp
->map_pmap
.pr_mapname
[PRMAPSZ
- 1] = '\0';
2594 core_elf_close(&intf
);
2598 * If we have an AT_ENTRY element, name the mapping at that address
2599 * using the special name "a.out" just like /proc does.
2601 if ((addr
= Pgetauxval(P
, AT_ENTRY
)) != (uintptr_t)-1L)
2602 P
->map_exec
= core_name_mapping(P
, addr
, "a.out");
2605 * If we're a statically linked executable (or we're looking at a
2606 * Linux core dump), then just locate the executable's text and data
2607 * and name them after the executable.
2609 #ifndef CONFIG_LINUX_CORE_SUPPORT
2610 if (base_addr
== (uintptr_t)-1L) {
2612 if (base_addr
== (uintptr_t)-1L || from_linux
) {
2614 dprintf("looking for text and data: %s\n", execname
);
2615 map_info_t
*tmp
, *dmp
;
2619 if ((tmp
= core_find_text(P
, aout
.e_elf
, &rl
)) != NULL
&&
2620 (dmp
= core_find_data(P
, aout
.e_elf
, &rl
)) != NULL
) {
2621 (void) strncpy(tmp
->map_pmap
.pr_mapname
,
2623 tmp
->map_pmap
.pr_mapname
[PRMAPSZ
- 1] = '\0';
2624 (void) strncpy(dmp
->map_pmap
.pr_mapname
,
2626 dmp
->map_pmap
.pr_mapname
[PRMAPSZ
- 1] = '\0';
2629 if ((P
->map_exec
= tmp
) != NULL
&&
2630 (fp
= malloc(sizeof (file_info_t
))) != NULL
) {
2632 (void) memset(fp
, 0, sizeof (file_info_t
));
2634 list_link(fp
, &P
->file_head
);
2641 fp
->file_lo
= malloc(sizeof (rd_loadobj_t
));
2642 fp
->file_lname
= strdup(execname
);
2647 fp
->file_lbase
= basename(fp
->file_lname
);
2649 fp
->file_rbase
= basename(fp
->file_rname
);
2651 (void) strcpy(fp
->file_pname
,
2652 P
->mappings
[0].map_pmap
.pr_mapname
);
2655 Pbuild_file_symtab(P
, fp
);
2664 core_elf_close(&aout
);
2667 * We now have enough information to initialize librtld_db.
2668 * After it warms up, we can iterate through the load object chain
2669 * in the core, which will allow us to construct the file info
2670 * we need to provide symbol information for the other shared
2671 * libraries, and also to fill in the missing mapping names.
2673 rd_log(_libproc_debug
);
2675 if ((P
->rap
= rd_new(P
)) != NULL
) {
2676 (void) rd_loadobj_iter(P
->rap
, (rl_iter_f
*)
2677 core_iter_mapping
, P
);
2679 if (core_info
->core_errno
!= 0) {
2680 errno
= core_info
->core_errno
;
2685 dprintf("failed to initialize rtld_db agent\n");
2688 * If there are sections, load them and process the data from any
2689 * sections that we can use to annotate the file_info_t's.
2691 core_load_shdrs(P
, &core
);
2694 * If we previously located a stack or break mapping, and they are
2695 * still anonymous, we now assume that they were MAP_ANON mappings.
2696 * If brk_mp turns out to now have a name, then the heap is still
2697 * sitting at the end of the executable's data+bss mapping: remove
2698 * the previous MA_BREAK setting to be consistent with /proc.
2700 if (stk_mp
!= NULL
&& stk_mp
->map_pmap
.pr_mapname
[0] == '\0')
2701 stk_mp
->map_pmap
.pr_mflags
|= MA_ANON
;
2702 if (brk_mp
!= NULL
&& brk_mp
->map_pmap
.pr_mapname
[0] == '\0')
2703 brk_mp
->map_pmap
.pr_mflags
|= MA_ANON
;
2704 else if (brk_mp
!= NULL
)
2705 brk_mp
->map_pmap
.pr_mflags
&= ~MA_BREAK
;
2712 core_elf_close(&aout
);
2717 * Grab a core file using a pathname. We just open it and call Pfgrab_core().
2719 struct ps_prochandle
*
2720 Pgrab_core(const char *core
, const char *aout
, int gflag
, int *perr
)
2722 int fd
, oflag
= (gflag
& PGRAB_RDONLY
) ? O_RDONLY
: O_RDWR
;
2724 if ((fd
= open64(core
, oflag
)) >= 0)
2725 return (Pfgrab_core(fd
, aout
, perr
));
2727 if (errno
!= ENOENT
)