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 (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2013 by Delphix. All rights reserved.
25 * Copyright 2016 Joyent, Inc.
43 #include <sys/types.h>
45 #include <sys/sysmacros.h>
50 #include "Psymtab_machelf.h"
52 static file_info_t
*build_map_symtab(struct ps_prochandle
*, map_info_t
*);
53 static map_info_t
*exec_map(struct ps_prochandle
*);
54 static map_info_t
*object_to_map(struct ps_prochandle
*, Lmid_t
, const char *);
55 static map_info_t
*object_name_to_map(struct ps_prochandle
*,
56 Lmid_t
, const char *);
57 static GElf_Sym
*sym_by_name(sym_tbl_t
*, const char *, GElf_Sym
*, uint_t
*);
58 static int read_ehdr32(struct ps_prochandle
*, Elf32_Ehdr
*, uint_t
*,
61 static int read_ehdr64(struct ps_prochandle
*, Elf64_Ehdr
*, uint_t
*,
66 ((1 << STT_OBJECT) | (1 << STT_FUNC) | \
67 (1 << STT_COMMON) | (1 << STT_TLS))
68 #define IS_DATA_TYPE(tp) (((1 << (tp)) & DATA_TYPES) != 0)
70 #define MA_RWX (MA_READ | MA_WRITE | MA_EXEC)
79 addr_cmp(const void *aa
, const void *bb
)
81 uintptr_t a
= *((uintptr_t *)aa
);
82 uintptr_t b
= *((uintptr_t *)bb
);
92 * This function creates a list of addresses for a load object's sections.
93 * The list is in ascending address order and alternates start address
94 * then end address for each section we're interested in. The function
95 * returns a pointer to the list, which must be freed by the caller.
98 get_saddrs(struct ps_prochandle
*P
, uintptr_t ehdr_start
, uint_t
*n
)
100 uintptr_t a
, addr
, *addrs
, last
= 0;
101 uint_t i
, naddrs
= 0, unordered
= 0;
103 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
108 if (read_ehdr32(P
, &ehdr
, &phnum
, ehdr_start
) != 0)
111 addrs
= malloc(sizeof (uintptr_t) * phnum
* 2);
112 a
= ehdr_start
+ ehdr
.e_phoff
;
113 for (i
= 0; i
< phnum
; i
++, a
+= ehdr
.e_phentsize
) {
114 if (Pread(P
, &phdr
, sizeof (phdr
), a
) !=
119 if (phdr
.p_type
!= PT_LOAD
|| phdr
.p_memsz
== 0)
123 if (ehdr
.e_type
== ET_DYN
)
127 addrs
[naddrs
++] = addr
;
128 addrs
[naddrs
++] = last
= addr
+ phdr
.p_memsz
- 1;
136 if (read_ehdr64(P
, &ehdr
, &phnum
, ehdr_start
) != 0)
139 addrs
= malloc(sizeof (uintptr_t) * phnum
* 2);
140 a
= ehdr_start
+ ehdr
.e_phoff
;
141 for (i
= 0; i
< phnum
; i
++, a
+= ehdr
.e_phentsize
) {
142 if (Pread(P
, &phdr
, sizeof (phdr
), a
) !=
147 if (phdr
.p_type
!= PT_LOAD
|| phdr
.p_memsz
== 0)
151 if (ehdr
.e_type
== ET_DYN
)
155 addrs
[naddrs
++] = addr
;
156 addrs
[naddrs
++] = last
= addr
+ phdr
.p_memsz
- 1;
162 qsort(addrs
, naddrs
, sizeof (uintptr_t), addr_cmp
);
169 * Allocation function for a new file_info_t
172 file_info_new(struct ps_prochandle
*P
, map_info_t
*mptr
)
176 uintptr_t mstart
, mend
, sstart
, send
;
179 if ((fptr
= calloc(1, sizeof (file_info_t
))) == NULL
)
182 list_link(fptr
, &P
->file_head
);
183 (void) strcpy(fptr
->file_pname
, mptr
->map_pmap
.pr_mapname
);
184 mptr
->map_file
= fptr
;
190 * To figure out which map_info_t instances correspond to the mappings
191 * for this load object we try to obtain the start and end address
192 * for each section of our in-memory ELF image. If successful, we
193 * walk down the list of addresses and the list of map_info_t
194 * instances in lock step to correctly find the mappings that
195 * correspond to this load object.
197 if ((fptr
->file_saddrs
= get_saddrs(P
, mptr
->map_pmap
.pr_vaddr
,
198 &fptr
->file_nsaddrs
)) == NULL
)
203 while (mp
< P
->mappings
+ P
->map_count
&& i
< fptr
->file_nsaddrs
) {
205 /* Calculate the start and end of the mapping and section */
206 mstart
= mp
->map_pmap
.pr_vaddr
;
207 mend
= mp
->map_pmap
.pr_vaddr
+ mp
->map_pmap
.pr_size
;
208 sstart
= fptr
->file_saddrs
[i
];
209 send
= fptr
->file_saddrs
[i
+ 1];
211 if (mend
<= sstart
) {
212 /* This mapping is below the current section */
214 } else if (mstart
>= send
) {
215 /* This mapping is above the current section */
218 /* This mapping overlaps the current section */
219 if (mp
->map_file
== NULL
) {
220 dprintf("file_info_new: associating "
222 (void *)mp
->map_pmap
.pr_vaddr
);
226 dprintf("file_info_new: segment at %p "
227 "already associated with %s\n",
228 (void *)mp
->map_pmap
.pr_vaddr
,
229 (mp
== mptr
? "this file" :
230 mp
->map_file
->file_pname
));
240 * Deallocation function for a file_info_t
243 file_info_free(struct ps_prochandle
*P
, file_info_t
*fptr
)
245 if (--fptr
->file_ref
== 0) {
247 if (fptr
->file_symtab
.sym_elf
) {
248 (void) elf_end(fptr
->file_symtab
.sym_elf
);
249 free(fptr
->file_symtab
.sym_elfmem
);
251 free(fptr
->file_symtab
.sym_byname
);
252 free(fptr
->file_symtab
.sym_byaddr
);
254 if (fptr
->file_dynsym
.sym_elf
) {
255 (void) elf_end(fptr
->file_dynsym
.sym_elf
);
256 free(fptr
->file_dynsym
.sym_elfmem
);
258 free(fptr
->file_dynsym
.sym_byname
);
259 free(fptr
->file_dynsym
.sym_byaddr
);
262 free(fptr
->file_lname
);
263 free(fptr
->file_rname
);
265 (void) elf_end(fptr
->file_elf
);
266 free(fptr
->file_elfmem
);
267 if (fptr
->file_fd
>= 0)
268 (void) close(fptr
->file_fd
);
269 if (fptr
->file_ctfp
) {
270 ctf_close(fptr
->file_ctfp
);
271 free(fptr
->file_ctf_buf
);
273 free(fptr
->file_saddrs
);
280 * Deallocation function for a map_info_t
283 map_info_free(struct ps_prochandle
*P
, map_info_t
*mptr
)
287 if ((fptr
= mptr
->map_file
) != NULL
) {
288 if (fptr
->file_map
== mptr
)
289 fptr
->file_map
= NULL
;
290 file_info_free(P
, fptr
);
292 if (P
->execname
&& mptr
== P
->map_exec
) {
296 if (P
->auxv
&& (mptr
== P
->map_exec
|| mptr
== P
->map_ldso
)) {
301 if (mptr
== P
->map_exec
)
303 if (mptr
== P
->map_ldso
)
308 * Call-back function for librtld_db to iterate through all of its shared
309 * libraries. We use this to get the load object names for the mappings.
312 map_iter(const rd_loadobj_t
*lop
, void *cd
)
315 struct ps_prochandle
*P
= cd
;
319 dprintf("encountered rd object at %p\n", (void *)lop
->rl_base
);
321 if ((mptr
= Paddr2mptr(P
, lop
->rl_base
)) == NULL
) {
322 dprintf("map_iter: base address doesn't match any mapping\n");
323 return (1); /* Base address does not match any mapping */
326 if ((fptr
= mptr
->map_file
) == NULL
&&
327 (fptr
= file_info_new(P
, mptr
)) == NULL
) {
328 dprintf("map_iter: failed to allocate a new file_info_t\n");
329 return (1); /* Failed to allocate a new file_info_t */
332 if ((fptr
->file_lo
== NULL
) &&
333 (fptr
->file_lo
= malloc(sizeof (rd_loadobj_t
))) == NULL
) {
334 dprintf("map_iter: failed to allocate rd_loadobj_t\n");
335 file_info_free(P
, fptr
);
336 return (1); /* Failed to allocate rd_loadobj_t */
339 fptr
->file_map
= mptr
;
340 *fptr
->file_lo
= *lop
;
342 fptr
->file_lo
->rl_plt_base
= fptr
->file_plt_base
;
343 fptr
->file_lo
->rl_plt_size
= fptr
->file_plt_size
;
345 if (fptr
->file_lname
) {
346 free(fptr
->file_lname
);
347 fptr
->file_lname
= NULL
;
348 fptr
->file_lbase
= NULL
;
350 if (fptr
->file_rname
) {
351 free(fptr
->file_rname
);
352 fptr
->file_rname
= NULL
;
353 fptr
->file_rbase
= NULL
;
356 if (Pread_string(P
, buf
, sizeof (buf
), lop
->rl_nameaddr
) > 0) {
357 if ((fptr
->file_lname
= strdup(buf
)) != NULL
)
358 fptr
->file_lbase
= basename(fptr
->file_lname
);
360 dprintf("map_iter: failed to read string at %p\n",
361 (void *)lop
->rl_nameaddr
);
364 if ((Pfindmap(P
, mptr
, buf
, sizeof (buf
)) != NULL
) &&
365 ((fptr
->file_rname
= strdup(buf
)) != NULL
))
366 fptr
->file_rbase
= basename(fptr
->file_rname
);
368 dprintf("loaded rd object %s lmid %lx\n",
369 fptr
->file_lname
? buf
: "<NULL>", lop
->rl_lmident
);
374 map_set(struct ps_prochandle
*P
, map_info_t
*mptr
, const char *lname
)
379 if ((fptr
= mptr
->map_file
) == NULL
&&
380 (fptr
= file_info_new(P
, mptr
)) == NULL
)
381 return; /* Failed to allocate a new file_info_t */
383 fptr
->file_map
= mptr
;
385 if ((fptr
->file_lo
== NULL
) &&
386 (fptr
->file_lo
= malloc(sizeof (rd_loadobj_t
))) == NULL
) {
387 file_info_free(P
, fptr
);
388 return; /* Failed to allocate rd_loadobj_t */
391 (void) memset(fptr
->file_lo
, 0, sizeof (rd_loadobj_t
));
392 fptr
->file_lo
->rl_base
= mptr
->map_pmap
.pr_vaddr
;
393 fptr
->file_lo
->rl_bend
=
394 mptr
->map_pmap
.pr_vaddr
+ mptr
->map_pmap
.pr_size
;
396 fptr
->file_lo
->rl_plt_base
= fptr
->file_plt_base
;
397 fptr
->file_lo
->rl_plt_size
= fptr
->file_plt_size
;
399 if ((fptr
->file_lname
== NULL
) &&
400 (fptr
->file_lname
= strdup(lname
)) != NULL
)
401 fptr
->file_lbase
= basename(fptr
->file_lname
);
403 if ((Pfindmap(P
, mptr
, buf
, sizeof (buf
)) != NULL
) &&
404 ((fptr
->file_rname
= strdup(buf
)) != NULL
))
405 fptr
->file_rbase
= basename(fptr
->file_rname
);
409 load_static_maps(struct ps_prochandle
*P
)
414 * Construct the map for the a.out.
416 if ((mptr
= object_name_to_map(P
, PR_LMID_EVERY
, PR_OBJ_EXEC
)) != NULL
)
417 map_set(P
, mptr
, "a.out");
420 * If the dynamic linker exists for this process,
421 * construct the map for it.
423 if (Pgetauxval(P
, AT_BASE
) != -1L &&
424 (mptr
= object_name_to_map(P
, PR_LMID_EVERY
, PR_OBJ_LDSO
)) != NULL
)
425 map_set(P
, mptr
, "ld.so.1");
429 Preadmaps(struct ps_prochandle
*P
, prmap_t
**Pmapp
, ssize_t
*nmapp
)
431 return (P
->ops
.pop_read_maps(P
, Pmapp
, nmapp
, P
->data
));
435 * Go through all the address space mappings, validating or updating
436 * the information already gathered, or gathering new information.
438 * This function is only called when we suspect that the mappings have changed
439 * because this is the first time we're calling it or because of rtld activity.
442 Pupdate_maps(struct ps_prochandle
*P
)
444 prmap_t
*Pmap
= NULL
;
449 map_info_t
*newmap
, *newp
;
452 if (P
->info_valid
|| P
->state
== PS_UNDEAD
)
457 if (Preadmaps(P
, &Pmap
, &nmap
) != 0)
460 if ((newmap
= calloc(1, nmap
* sizeof (map_info_t
))) == NULL
)
464 * We try to merge any file information we may have for existing
465 * mappings, to avoid having to rebuild the file info.
470 oldmapcount
= P
->map_count
;
471 for (i
= 0; i
< nmap
; i
++, pmap
++, newp
++) {
473 if (oldmapcount
== 0) {
475 * We've exhausted all the old mappings. Every new
476 * mapping should be added.
478 newp
->map_pmap
= *pmap
;
480 } else if (pmap
->pr_vaddr
== mptr
->map_pmap
.pr_vaddr
&&
481 pmap
->pr_size
== mptr
->map_pmap
.pr_size
&&
482 pmap
->pr_offset
== mptr
->map_pmap
.pr_offset
&&
483 (pmap
->pr_mflags
& ~(MA_BREAK
| MA_STACK
)) ==
484 (mptr
->map_pmap
.pr_mflags
& ~(MA_BREAK
| MA_STACK
)) &&
485 pmap
->pr_pagesize
== mptr
->map_pmap
.pr_pagesize
&&
486 pmap
->pr_shmid
== mptr
->map_pmap
.pr_shmid
&&
487 strcmp(pmap
->pr_mapname
, mptr
->map_pmap
.pr_mapname
) == 0) {
490 * This mapping matches exactly. Copy over the old
491 * mapping, taking care to get the latest flags.
492 * Make sure the associated file_info_t is updated
496 if (P
->map_exec
== mptr
)
498 if (P
->map_ldso
== mptr
)
500 newp
->map_pmap
.pr_mflags
= pmap
->pr_mflags
;
501 if (mptr
->map_file
!= NULL
&&
502 mptr
->map_file
->file_map
== mptr
)
503 mptr
->map_file
->file_map
= newp
;
507 } else if (pmap
->pr_vaddr
+ pmap
->pr_size
>
508 mptr
->map_pmap
.pr_vaddr
) {
511 * The old mapping doesn't exist any more, remove it
514 map_info_free(P
, mptr
);
524 * This is a new mapping, add it directly.
526 newp
->map_pmap
= *pmap
;
533 while (oldmapcount
) {
534 map_info_free(P
, mptr
);
541 P
->mappings
= newmap
;
542 P
->map_count
= P
->map_alloc
= nmap
;
546 * Consult librtld_db to get the load object
547 * names for all of the shared libraries.
550 (void) rd_loadobj_iter(P
->rap
, map_iter
, P
);
554 * Update all of the mappings and rtld_db as if by Pupdate_maps(), and then
555 * forcibly cache all of the symbol tables associated with all object files.
558 Pupdate_syms(struct ps_prochandle
*P
)
565 for (i
= 0, fptr
= list_next(&P
->file_head
); i
< P
->num_files
;
566 i
++, fptr
= list_next(fptr
)) {
567 Pbuild_file_symtab(P
, fptr
);
568 (void) Pbuild_file_ctf(P
, fptr
);
573 * Return the librtld_db agent handle for the victim process.
574 * The handle will become invalid at the next successful exec() and the
575 * client (caller of proc_rd_agent()) must not use it beyond that point.
576 * If the process is already dead, we've already tried our best to
577 * create the agent during core file initialization.
580 Prd_agent(struct ps_prochandle
*P
)
582 if (P
->rap
== NULL
&& P
->state
!= PS_DEAD
&& P
->state
!= PS_IDLE
) {
584 if (P
->num_files
== 0)
586 rd_log(_libproc_debug
);
587 if ((P
->rap
= rd_new(P
)) != NULL
)
588 (void) rd_loadobj_iter(P
->rap
, map_iter
, P
);
594 * Return the prmap_t structure containing 'addr', but only if it
595 * is in the dynamic linker's link map and is the text section.
598 Paddr_to_text_map(struct ps_prochandle
*P
, uintptr_t addr
)
605 if ((mptr
= Paddr2mptr(P
, addr
)) != NULL
) {
606 file_info_t
*fptr
= build_map_symtab(P
, mptr
);
607 const prmap_t
*pmp
= &mptr
->map_pmap
;
610 * Assume that if rl_data_base is NULL, it means that no
611 * data section was found for this load object, and that
612 * a section must be text. Otherwise, a section will be
613 * text unless it ends above the start of the data
616 if (fptr
!= NULL
&& fptr
->file_lo
!= NULL
&&
617 (fptr
->file_lo
->rl_data_base
== 0 ||
618 pmp
->pr_vaddr
+ pmp
->pr_size
<=
619 fptr
->file_lo
->rl_data_base
))
627 * Return the prmap_t structure containing 'addr' (no restrictions on
628 * the type of mapping).
631 Paddr_to_map(struct ps_prochandle
*P
, uintptr_t addr
)
638 if ((mptr
= Paddr2mptr(P
, addr
)) != NULL
)
639 return (&mptr
->map_pmap
);
645 * Convert a full or partial load object name to the prmap_t for its
646 * corresponding primary text mapping.
649 Plmid_to_map(struct ps_prochandle
*P
, Lmid_t lmid
, const char *name
)
653 if (name
== PR_OBJ_EVERY
)
654 return (NULL
); /* A reasonable mistake */
656 if ((mptr
= object_name_to_map(P
, lmid
, name
)) != NULL
)
657 return (&mptr
->map_pmap
);
663 Pname_to_map(struct ps_prochandle
*P
, const char *name
)
665 return (Plmid_to_map(P
, PR_LMID_EVERY
, name
));
669 Paddr_to_loadobj(struct ps_prochandle
*P
, uintptr_t addr
)
676 if ((mptr
= Paddr2mptr(P
, addr
)) == NULL
)
680 * By building the symbol table, we implicitly bring the PLT
681 * information up to date in the load object.
683 (void) build_map_symtab(P
, mptr
);
685 return (mptr
->map_file
->file_lo
);
689 Plmid_to_loadobj(struct ps_prochandle
*P
, Lmid_t lmid
, const char *name
)
693 if (name
== PR_OBJ_EVERY
)
696 if ((mptr
= object_name_to_map(P
, lmid
, name
)) == NULL
)
700 * By building the symbol table, we implicitly bring the PLT
701 * information up to date in the load object.
703 (void) build_map_symtab(P
, mptr
);
705 return (mptr
->map_file
->file_lo
);
709 Pname_to_loadobj(struct ps_prochandle
*P
, const char *name
)
711 return (Plmid_to_loadobj(P
, PR_LMID_EVERY
, name
));
715 * We've been given a file_info_t which doesn't have any CTF. However, it may
716 * have information that's in a format that we could convert if on the fly.
719 Pconvert_file_ctf(file_info_t
*fptr
)
728 if (getenv("LIBPROC_CTFCONVERT") == NULL
)
732 * If we've already attempted to call this, then that's it. No reason to
733 * pretend we'll be more successful again another time.
735 if (fptr
->file_cvt
== B_TRUE
)
737 fptr
->file_cvt
= B_TRUE
;
739 fp
= ctf_elfconvert(fptr
->file_fd
, fptr
->file_elf
, NULL
, 1,
740 0, &err
, errmsg
, sizeof (errmsg
));
742 dprintf("failed to convert %s: %s\n", fptr
->file_pname
,
743 err
== ECTF_CONVBKERR
? errmsg
: ctf_errmsg(err
));
745 fptr
->file_ctfp
= fp
;
751 Pbuild_file_ctf(struct ps_prochandle
*P
, file_info_t
*fptr
)
753 ctf_sect_t ctdata
, symtab
, strtab
;
757 if (fptr
->file_ctfp
!= NULL
)
758 return (fptr
->file_ctfp
);
760 Pbuild_file_symtab(P
, fptr
);
762 if (fptr
->file_ctf_size
== 0) {
763 return (Pconvert_file_ctf(fptr
));
766 symp
= fptr
->file_ctf_dyn
? &fptr
->file_dynsym
: &fptr
->file_symtab
;
767 if (symp
->sym_data_pri
== NULL
)
771 * The buffer may alread be allocated if this is a core file that
772 * contained CTF data for this file.
774 if (fptr
->file_ctf_buf
== NULL
) {
775 fptr
->file_ctf_buf
= malloc(fptr
->file_ctf_size
);
776 if (fptr
->file_ctf_buf
== NULL
) {
777 dprintf("failed to allocate ctf buffer\n");
781 if (pread(fptr
->file_fd
, fptr
->file_ctf_buf
,
782 fptr
->file_ctf_size
, fptr
->file_ctf_off
) !=
783 fptr
->file_ctf_size
) {
784 free(fptr
->file_ctf_buf
);
785 fptr
->file_ctf_buf
= NULL
;
786 dprintf("failed to read ctf data\n");
791 ctdata
.cts_name
= ".SUNW_ctf";
792 ctdata
.cts_type
= SHT_PROGBITS
;
793 ctdata
.cts_flags
= 0;
794 ctdata
.cts_data
= fptr
->file_ctf_buf
;
795 ctdata
.cts_size
= fptr
->file_ctf_size
;
796 ctdata
.cts_entsize
= 1;
797 ctdata
.cts_offset
= 0;
799 symtab
.cts_name
= fptr
->file_ctf_dyn
? ".dynsym" : ".symtab";
800 symtab
.cts_type
= symp
->sym_hdr_pri
.sh_type
;
801 symtab
.cts_flags
= symp
->sym_hdr_pri
.sh_flags
;
802 symtab
.cts_data
= symp
->sym_data_pri
->d_buf
;
803 symtab
.cts_size
= symp
->sym_hdr_pri
.sh_size
;
804 symtab
.cts_entsize
= symp
->sym_hdr_pri
.sh_entsize
;
805 symtab
.cts_offset
= symp
->sym_hdr_pri
.sh_offset
;
807 strtab
.cts_name
= fptr
->file_ctf_dyn
? ".dynstr" : ".strtab";
808 strtab
.cts_type
= symp
->sym_strhdr
.sh_type
;
809 strtab
.cts_flags
= symp
->sym_strhdr
.sh_flags
;
810 strtab
.cts_data
= symp
->sym_strs
;
811 strtab
.cts_size
= symp
->sym_strhdr
.sh_size
;
812 strtab
.cts_entsize
= symp
->sym_strhdr
.sh_entsize
;
813 strtab
.cts_offset
= symp
->sym_strhdr
.sh_offset
;
815 fptr
->file_ctfp
= ctf_bufopen(&ctdata
, &symtab
, &strtab
, &err
);
816 if (fptr
->file_ctfp
== NULL
) {
817 dprintf("ctf_bufopen() failed, error code %d\n", err
);
818 free(fptr
->file_ctf_buf
);
819 fptr
->file_ctf_buf
= NULL
;
823 dprintf("loaded %lu bytes of CTF data for %s\n",
824 (ulong_t
)fptr
->file_ctf_size
, fptr
->file_pname
);
826 return (fptr
->file_ctfp
);
830 Paddr_to_ctf(struct ps_prochandle
*P
, uintptr_t addr
)
838 if ((mptr
= Paddr2mptr(P
, addr
)) == NULL
||
839 (fptr
= mptr
->map_file
) == NULL
)
842 return (Pbuild_file_ctf(P
, fptr
));
846 Plmid_to_ctf(struct ps_prochandle
*P
, Lmid_t lmid
, const char *name
)
849 file_info_t
*fptr
= NULL
;
851 if (name
== PR_OBJ_EVERY
)
855 * While most idle files are all ELF objects, not all of them have
856 * mapping information available. There's nothing which would make
857 * sense to fake up for ET_REL. Instead, if we're being asked for their
858 * executable object and we know that the information is valid and they
859 * only have a single file, we jump straight to that file pointer.
861 if (P
->state
== PS_IDLE
&& name
== PR_OBJ_EXEC
&& P
->info_valid
== 1 &&
862 P
->num_files
== 1 && P
->mappings
== NULL
) {
863 fptr
= list_next(&P
->file_head
);
867 if ((mptr
= object_name_to_map(P
, lmid
, name
)) == NULL
||
868 (fptr
= mptr
->map_file
) == NULL
)
872 return (Pbuild_file_ctf(P
, fptr
));
876 Pname_to_ctf(struct ps_prochandle
*P
, const char *name
)
878 return (Plmid_to_ctf(P
, PR_LMID_EVERY
, name
));
882 Preadauxvec(struct ps_prochandle
*P
)
884 if (P
->auxv
!= NULL
) {
890 P
->ops
.pop_read_aux(P
, &P
->auxv
, &P
->nauxv
, P
->data
);
894 * Return a requested element from the process's aux vector.
895 * Return -1 on failure (this is adequate for our purposes).
898 Pgetauxval(struct ps_prochandle
*P
, int type
)
908 for (auxv
= P
->auxv
; auxv
->a_type
!= AT_NULL
; auxv
++) {
909 if (auxv
->a_type
== type
)
910 return (auxv
->a_un
.a_val
);
917 * Return a pointer to our internal copy of the process's aux vector.
918 * The caller should not hold on to this pointer across any libproc calls.
921 Pgetauxvec(struct ps_prochandle
*P
)
923 static const auxv_t empty
= { AT_NULL
, 0L };
935 * Return 1 if the given mapping corresponds to the given file_info_t's
936 * load object; return 0 otherwise.
939 is_mapping_in_file(struct ps_prochandle
*P
, map_info_t
*mptr
, file_info_t
*fptr
)
941 prmap_t
*pmap
= &mptr
->map_pmap
;
942 rd_loadobj_t
*lop
= fptr
->file_lo
;
944 uintptr_t mstart
, mend
, sstart
, send
;
947 * We can get for free the start address of the text and data
948 * sections of the load object. Start by seeing if the mapping
949 * encloses either of these.
951 if ((pmap
->pr_vaddr
<= lop
->rl_base
&&
952 lop
->rl_base
< pmap
->pr_vaddr
+ pmap
->pr_size
) ||
953 (pmap
->pr_vaddr
<= lop
->rl_data_base
&&
954 lop
->rl_data_base
< pmap
->pr_vaddr
+ pmap
->pr_size
))
958 * It's still possible that this mapping correponds to the load
959 * object. Consider the example of a mapping whose start and end
960 * addresses correspond to those of the load object's text section.
961 * If the mapping splits, e.g. as a result of a segment demotion,
962 * then although both mappings are still backed by the same section,
963 * only one will be seen to enclose that section's start address.
964 * Thus, to be rigorous, we ask not whether this mapping encloses
965 * the start of a section, but whether there exists a section that
966 * overlaps this mapping.
968 * If we don't already have the section addresses, and we successfully
969 * get them, then we cache them in case we come here again.
971 if (fptr
->file_saddrs
== NULL
&&
972 (fptr
->file_saddrs
= get_saddrs(P
,
973 fptr
->file_map
->map_pmap
.pr_vaddr
, &fptr
->file_nsaddrs
)) == NULL
)
976 mstart
= mptr
->map_pmap
.pr_vaddr
;
977 mend
= mptr
->map_pmap
.pr_vaddr
+ mptr
->map_pmap
.pr_size
;
978 for (i
= 0; i
< fptr
->file_nsaddrs
; i
+= 2) {
979 /* Does this section overlap the mapping? */
980 sstart
= fptr
->file_saddrs
[i
];
981 send
= fptr
->file_saddrs
[i
+ 1];
982 if (!(mend
<= sstart
|| mstart
>= send
))
990 * Find or build the symbol table for the given mapping.
993 build_map_symtab(struct ps_prochandle
*P
, map_info_t
*mptr
)
995 prmap_t
*pmap
= &mptr
->map_pmap
;
999 if ((fptr
= mptr
->map_file
) != NULL
) {
1000 Pbuild_file_symtab(P
, fptr
);
1004 if (pmap
->pr_mapname
[0] == '\0')
1008 * Attempt to find a matching file.
1009 * (A file can be mapped at several different addresses.)
1011 for (i
= 0, fptr
= list_next(&P
->file_head
); i
< P
->num_files
;
1012 i
++, fptr
= list_next(fptr
)) {
1013 if (strcmp(fptr
->file_pname
, pmap
->pr_mapname
) == 0 &&
1014 fptr
->file_lo
&& is_mapping_in_file(P
, mptr
, fptr
)) {
1015 mptr
->map_file
= fptr
;
1017 Pbuild_file_symtab(P
, fptr
);
1023 * If we need to create a new file_info structure, iterate
1024 * through the load objects in order to attempt to connect
1025 * this new file with its primary text mapping. We again
1026 * need to handle ld.so as a special case because we need
1027 * to be able to bootstrap librtld_db.
1029 if ((fptr
= file_info_new(P
, mptr
)) == NULL
)
1032 if (P
->map_ldso
!= mptr
) {
1034 (void) rd_loadobj_iter(P
->rap
, map_iter
, P
);
1036 (void) Prd_agent(P
);
1038 fptr
->file_map
= mptr
;
1042 * If librtld_db wasn't able to help us connect the file to a primary
1043 * text mapping, set file_map to the current mapping because we require
1044 * fptr->file_map to be set in Pbuild_file_symtab. librtld_db may be
1045 * unaware of what's going on in the rare case that a legitimate ELF
1046 * file has been mmap(2)ed into the process address space *without*
1047 * the use of dlopen(3x).
1049 if (fptr
->file_map
== NULL
)
1050 fptr
->file_map
= mptr
;
1052 Pbuild_file_symtab(P
, fptr
);
1058 read_ehdr32(struct ps_prochandle
*P
, Elf32_Ehdr
*ehdr
, uint_t
*phnum
,
1061 if (Pread(P
, ehdr
, sizeof (*ehdr
), addr
) != sizeof (*ehdr
))
1064 if (ehdr
->e_ident
[EI_MAG0
] != ELFMAG0
||
1065 ehdr
->e_ident
[EI_MAG1
] != ELFMAG1
||
1066 ehdr
->e_ident
[EI_MAG2
] != ELFMAG2
||
1067 ehdr
->e_ident
[EI_MAG3
] != ELFMAG3
||
1068 ehdr
->e_ident
[EI_CLASS
] != ELFCLASS32
||
1070 ehdr
->e_ident
[EI_DATA
] != ELFDATA2MSB
||
1072 ehdr
->e_ident
[EI_DATA
] != ELFDATA2LSB
||
1074 ehdr
->e_ident
[EI_VERSION
] != EV_CURRENT
)
1077 if ((*phnum
= ehdr
->e_phnum
) == PN_XNUM
) {
1080 if (ehdr
->e_shoff
== 0 || ehdr
->e_shentsize
< sizeof (shdr0
) ||
1081 Pread(P
, &shdr0
, sizeof (shdr0
), addr
+ ehdr
->e_shoff
) !=
1085 if (shdr0
.sh_info
!= 0)
1086 *phnum
= shdr0
.sh_info
;
1093 read_dynamic_phdr32(struct ps_prochandle
*P
, const Elf32_Ehdr
*ehdr
,
1094 uint_t phnum
, Elf32_Phdr
*phdr
, uintptr_t addr
)
1098 for (i
= 0; i
< phnum
; i
++) {
1099 uintptr_t a
= addr
+ ehdr
->e_phoff
+ i
* ehdr
->e_phentsize
;
1100 if (Pread(P
, phdr
, sizeof (*phdr
), a
) != sizeof (*phdr
))
1103 if (phdr
->p_type
== PT_DYNAMIC
)
1112 read_ehdr64(struct ps_prochandle
*P
, Elf64_Ehdr
*ehdr
, uint_t
*phnum
,
1115 if (Pread(P
, ehdr
, sizeof (Elf64_Ehdr
), addr
) != sizeof (Elf64_Ehdr
))
1118 if (ehdr
->e_ident
[EI_MAG0
] != ELFMAG0
||
1119 ehdr
->e_ident
[EI_MAG1
] != ELFMAG1
||
1120 ehdr
->e_ident
[EI_MAG2
] != ELFMAG2
||
1121 ehdr
->e_ident
[EI_MAG3
] != ELFMAG3
||
1122 ehdr
->e_ident
[EI_CLASS
] != ELFCLASS64
||
1124 ehdr
->e_ident
[EI_DATA
] != ELFDATA2MSB
||
1126 ehdr
->e_ident
[EI_DATA
] != ELFDATA2LSB
||
1128 ehdr
->e_ident
[EI_VERSION
] != EV_CURRENT
)
1131 if ((*phnum
= ehdr
->e_phnum
) == PN_XNUM
) {
1134 if (ehdr
->e_shoff
== 0 || ehdr
->e_shentsize
< sizeof (shdr0
) ||
1135 Pread(P
, &shdr0
, sizeof (shdr0
), addr
+ ehdr
->e_shoff
) !=
1139 if (shdr0
.sh_info
!= 0)
1140 *phnum
= shdr0
.sh_info
;
1147 read_dynamic_phdr64(struct ps_prochandle
*P
, const Elf64_Ehdr
*ehdr
,
1148 uint_t phnum
, Elf64_Phdr
*phdr
, uintptr_t addr
)
1152 for (i
= 0; i
< phnum
; i
++) {
1153 uintptr_t a
= addr
+ ehdr
->e_phoff
+ i
* ehdr
->e_phentsize
;
1154 if (Pread(P
, phdr
, sizeof (*phdr
), a
) != sizeof (*phdr
))
1157 if (phdr
->p_type
== PT_DYNAMIC
)
1166 * The text segment for each load object contains the elf header and
1167 * program headers. We can use this information to determine if the
1168 * file that corresponds to the load object is the same file that
1169 * was loaded into the process's address space. There can be a discrepency
1170 * if a file is recompiled after the process is started or if the target
1171 * represents a core file from a differently configured system -- two
1172 * common examples. The DT_CHECKSUM entry in the dynamic section
1173 * provides an easy method of comparison. It is important to note that
1174 * the dynamic section usually lives in the data segment, but the meta
1175 * data we use to find the dynamic section lives in the text segment so
1176 * if either of those segments is absent we can't proceed.
1178 * We're looking through the elf file for several items: the symbol tables
1179 * (both dynsym and symtab), the procedure linkage table (PLT) base,
1180 * size, and relocation base, and the CTF information. Most of this can
1181 * be recovered from the loaded image of the file itself, the exceptions
1182 * being the symtab and CTF data.
1184 * First we try to open the file that we think corresponds to the load
1185 * object, if the DT_CHECKSUM values match, we're all set, and can simply
1186 * recover all the information we need from the file. If the values of
1187 * DT_CHECKSUM don't match, or if we can't access the file for whatever
1188 * reasaon, we fake up a elf file to use in its stead. If we can't read
1189 * the elf data in the process's address space, we fall back to using
1190 * the file even though it may give inaccurate information.
1192 * The elf file that we fake up has to consist of sections for the
1193 * dynsym, the PLT and the dynamic section. Note that in the case of a
1194 * core file, we'll get the CTF data in the file_info_t later on from
1195 * a section embedded the core file (if it's present).
1197 * file_differs() conservatively looks for mismatched files, identifying
1198 * a match when there is any ambiguity (since that's the legacy behavior).
1201 file_differs(struct ps_prochandle
*P
, Elf
*elf
, file_info_t
*fptr
)
1211 if (fptr
->file_map
== NULL
)
1214 if ((Pcontent(P
) & (CC_CONTENT_TEXT
| CC_CONTENT_DATA
)) !=
1215 (CC_CONTENT_TEXT
| CC_CONTENT_DATA
))
1219 * First, we find the checksum value in the elf file.
1222 while ((scn
= elf_nextscn(elf
, scn
)) != NULL
) {
1223 if (gelf_getshdr(scn
, &shdr
) != NULL
&&
1224 shdr
.sh_type
== SHT_DYNAMIC
)
1230 if ((data
= elf_getdata(scn
, NULL
)) == NULL
)
1233 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
)
1234 ndyn
= shdr
.sh_size
/ sizeof (Elf32_Dyn
);
1236 else if (P
->status
.pr_dmodel
== PR_MODEL_LP64
)
1237 ndyn
= shdr
.sh_size
/ sizeof (Elf64_Dyn
);
1242 for (i
= 0; i
< ndyn
; i
++) {
1243 if (gelf_getdyn(data
, i
, &dyn
) != NULL
&&
1244 dyn
.d_tag
== DT_CHECKSUM
)
1249 * The in-memory ELF has no DT_CHECKSUM section, but we will report it
1250 * as matching the file anyhow.
1255 cksum
= dyn
.d_un
.d_val
;
1256 dprintf("elf cksum value is %llx\n", (u_longlong_t
)cksum
);
1259 * Get the base of the text mapping that corresponds to this file.
1261 addr
= fptr
->file_map
->map_pmap
.pr_vaddr
;
1263 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
1266 Elf32_Dyn dync
, *dynp
;
1269 if (read_ehdr32(P
, &ehdr
, &phnum
, addr
) != 0 ||
1270 read_dynamic_phdr32(P
, &ehdr
, phnum
, &phdr
, addr
) != 0)
1273 if (ehdr
.e_type
== ET_DYN
)
1274 phdr
.p_vaddr
+= addr
;
1275 if ((dynp
= malloc(phdr
.p_filesz
)) == NULL
)
1277 dync
.d_tag
= DT_NULL
;
1278 if (Pread(P
, dynp
, phdr
.p_filesz
, phdr
.p_vaddr
) !=
1284 for (i
= 0; i
< phdr
.p_filesz
/ sizeof (Elf32_Dyn
); i
++) {
1285 if (dynp
[i
].d_tag
== DT_CHECKSUM
)
1291 if (dync
.d_tag
!= DT_CHECKSUM
)
1294 dprintf("image cksum value is %llx\n",
1295 (u_longlong_t
)dync
.d_un
.d_val
);
1296 return (dync
.d_un
.d_val
!= cksum
);
1298 } else if (P
->status
.pr_dmodel
== PR_MODEL_LP64
) {
1301 Elf64_Dyn dync
, *dynp
;
1304 if (read_ehdr64(P
, &ehdr
, &phnum
, addr
) != 0 ||
1305 read_dynamic_phdr64(P
, &ehdr
, phnum
, &phdr
, addr
) != 0)
1308 if (ehdr
.e_type
== ET_DYN
)
1309 phdr
.p_vaddr
+= addr
;
1310 if ((dynp
= malloc(phdr
.p_filesz
)) == NULL
)
1312 dync
.d_tag
= DT_NULL
;
1313 if (Pread(P
, dynp
, phdr
.p_filesz
, phdr
.p_vaddr
) !=
1319 for (i
= 0; i
< phdr
.p_filesz
/ sizeof (Elf64_Dyn
); i
++) {
1320 if (dynp
[i
].d_tag
== DT_CHECKSUM
)
1326 if (dync
.d_tag
!= DT_CHECKSUM
)
1329 dprintf("image cksum value is %llx\n",
1330 (u_longlong_t
)dync
.d_un
.d_val
);
1331 return (dync
.d_un
.d_val
!= cksum
);
1339 * Read data from the specified process and construct an in memory
1340 * image of an ELF file that represents it well enough to let
1341 * us probe it for information.
1344 fake_elf(struct ps_prochandle
*P
, file_info_t
*fptr
)
1350 if (fptr
->file_map
== NULL
)
1353 if ((Pcontent(P
) & (CC_CONTENT_TEXT
| CC_CONTENT_DATA
)) !=
1354 (CC_CONTENT_TEXT
| CC_CONTENT_DATA
))
1357 addr
= fptr
->file_map
->map_pmap
.pr_vaddr
;
1359 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
1363 if ((read_ehdr32(P
, &ehdr
, &phnum
, addr
) != 0) ||
1364 read_dynamic_phdr32(P
, &ehdr
, phnum
, &phdr
, addr
) != 0)
1367 elf
= fake_elf32(P
, fptr
, addr
, &ehdr
, phnum
, &phdr
);
1373 if (read_ehdr64(P
, &ehdr
, &phnum
, addr
) != 0 ||
1374 read_dynamic_phdr64(P
, &ehdr
, phnum
, &phdr
, addr
) != 0)
1377 elf
= fake_elf64(P
, fptr
, addr
, &ehdr
, phnum
, &phdr
);
1385 * We wouldn't need these if qsort(3C) took an argument for the callback...
1387 static mutex_t sort_mtx
= DEFAULTMUTEX
;
1388 static char *sort_strs
;
1389 static GElf_Sym
*sort_syms
;
1392 byaddr_cmp_common(GElf_Sym
*a
, char *aname
, GElf_Sym
*b
, char *bname
)
1394 if (a
->st_value
< b
->st_value
)
1396 if (a
->st_value
> b
->st_value
)
1400 * Prefer the function to the non-function.
1402 if (GELF_ST_TYPE(a
->st_info
) != GELF_ST_TYPE(b
->st_info
)) {
1403 if (GELF_ST_TYPE(a
->st_info
) == STT_FUNC
)
1405 if (GELF_ST_TYPE(b
->st_info
) == STT_FUNC
)
1410 * Prefer the weak or strong global symbol to the local symbol.
1412 if (GELF_ST_BIND(a
->st_info
) != GELF_ST_BIND(b
->st_info
)) {
1413 if (GELF_ST_BIND(b
->st_info
) == STB_LOCAL
)
1415 if (GELF_ST_BIND(a
->st_info
) == STB_LOCAL
)
1420 * Prefer the symbol that doesn't begin with a '$' since compilers and
1421 * other symbol generators often use it as a prefix.
1429 * Prefer the name with fewer leading underscores in the name.
1431 while (*aname
== '_' && *bname
== '_') {
1442 * Prefer the symbol with the smaller size.
1444 if (a
->st_size
< b
->st_size
)
1446 if (a
->st_size
> b
->st_size
)
1450 * All other factors being equal, fall back to lexicographic order.
1452 return (strcmp(aname
, bname
));
1456 byaddr_cmp(const void *aa
, const void *bb
)
1458 GElf_Sym
*a
= &sort_syms
[*(uint_t
*)aa
];
1459 GElf_Sym
*b
= &sort_syms
[*(uint_t
*)bb
];
1460 char *aname
= sort_strs
+ a
->st_name
;
1461 char *bname
= sort_strs
+ b
->st_name
;
1463 return (byaddr_cmp_common(a
, aname
, b
, bname
));
1467 byname_cmp(const void *aa
, const void *bb
)
1469 GElf_Sym
*a
= &sort_syms
[*(uint_t
*)aa
];
1470 GElf_Sym
*b
= &sort_syms
[*(uint_t
*)bb
];
1471 char *aname
= sort_strs
+ a
->st_name
;
1472 char *bname
= sort_strs
+ b
->st_name
;
1474 return (strcmp(aname
, bname
));
1478 * Given a symbol index, look up the corresponding symbol from the
1479 * given symbol table.
1481 * This function allows the caller to treat the symbol table as a single
1482 * logical entity even though there may be 2 actual ELF symbol tables
1483 * involved. See the comments in Pcontrol.h for details.
1486 symtab_getsym(sym_tbl_t
*symtab
, int ndx
, GElf_Sym
*dst
)
1488 /* If index is in range of primary symtab, look it up there */
1489 if (ndx
>= symtab
->sym_symn_aux
) {
1490 return (gelf_getsym(symtab
->sym_data_pri
,
1491 ndx
- symtab
->sym_symn_aux
, dst
));
1494 /* Not in primary: Look it up in the auxiliary symtab */
1495 return (gelf_getsym(symtab
->sym_data_aux
, ndx
, dst
));
1499 optimize_symtab(sym_tbl_t
*symtab
)
1501 GElf_Sym
*symp
, *syms
;
1502 uint_t i
, *indexa
, *indexb
;
1503 size_t symn
, strsz
, count
;
1505 if (symtab
== NULL
|| symtab
->sym_data_pri
== NULL
||
1506 symtab
->sym_byaddr
!= NULL
)
1509 symn
= symtab
->sym_symn
;
1510 strsz
= symtab
->sym_strsz
;
1512 symp
= syms
= malloc(sizeof (GElf_Sym
) * symn
);
1514 dprintf("optimize_symtab: failed to malloc symbol array");
1519 * First record all the symbols into a table and count up the ones
1520 * that we're interested in. We mark symbols as invalid by setting
1521 * the st_name to an illegal value.
1523 for (i
= 0, count
= 0; i
< symn
; i
++, symp
++) {
1524 if (symtab_getsym(symtab
, i
, symp
) != NULL
&&
1525 symp
->st_name
< strsz
&&
1526 IS_DATA_TYPE(GELF_ST_TYPE(symp
->st_info
)))
1529 symp
->st_name
= strsz
;
1533 * Allocate sufficient space for both tables and populate them
1534 * with the same symbols we just counted.
1536 symtab
->sym_count
= count
;
1537 indexa
= symtab
->sym_byaddr
= calloc(sizeof (uint_t
), count
);
1538 indexb
= symtab
->sym_byname
= calloc(sizeof (uint_t
), count
);
1539 if (indexa
== NULL
|| indexb
== NULL
) {
1541 "optimize_symtab: failed to malloc symbol index arrays");
1542 symtab
->sym_count
= 0;
1543 if (indexa
!= NULL
) { /* First alloc succeeded. Free it */
1545 symtab
->sym_byaddr
= NULL
;
1550 for (i
= 0, symp
= syms
; i
< symn
; i
++, symp
++) {
1551 if (symp
->st_name
< strsz
)
1552 *indexa
++ = *indexb
++ = i
;
1556 * Sort the two tables according to the appropriate criteria,
1557 * unless the user has overridden this behaviour.
1559 * An example where we might not sort the tables is the relatively
1560 * unusual case of a process with very large symbol tables in which
1561 * we perform few lookups. In such a case the total time would be
1562 * dominated by the sort. It is difficult to determine a priori
1563 * how many lookups an arbitrary client will perform, and
1564 * hence whether the symbol tables should be sorted. We therefore
1565 * sort the tables by default, but provide the user with a
1566 * "chicken switch" in the form of the LIBPROC_NO_QSORT
1567 * environment variable.
1569 if (!_libproc_no_qsort
) {
1570 (void) mutex_lock(&sort_mtx
);
1571 sort_strs
= symtab
->sym_strs
;
1574 qsort(symtab
->sym_byaddr
, count
, sizeof (uint_t
), byaddr_cmp
);
1575 qsort(symtab
->sym_byname
, count
, sizeof (uint_t
), byname_cmp
);
1579 (void) mutex_unlock(&sort_mtx
);
1587 build_fake_elf(struct ps_prochandle
*P
, file_info_t
*fptr
, GElf_Ehdr
*ehdr
,
1588 size_t *nshdrs
, Elf_Data
**shdata
)
1594 if ((elf
= fake_elf(P
, fptr
)) == NULL
||
1595 elf_kind(elf
) != ELF_K_ELF
||
1596 gelf_getehdr(elf
, ehdr
) == NULL
||
1597 elf_getshdrnum(elf
, nshdrs
) == -1 ||
1598 elf_getshdrstrndx(elf
, &shstrndx
) == -1 ||
1599 (scn
= elf_getscn(elf
, shstrndx
)) == NULL
||
1600 (*shdata
= elf_getdata(scn
, NULL
)) == NULL
) {
1602 (void) elf_end(elf
);
1603 dprintf("failed to fake up ELF file\n");
1611 * Build the symbol table for the given mapped file.
1614 Pbuild_file_symtab(struct ps_prochandle
*P
, file_info_t
*fptr
)
1616 char objectfile
[PATH_MAX
];
1625 size_t nshdrs
, shstrndx
;
1631 } *cp
, *cache
= NULL
, *dyn
= NULL
, *plt
= NULL
, *ctf
= NULL
;
1633 if (fptr
->file_init
)
1634 return; /* We've already processed this file */
1637 * Mark the file_info struct as having the symbol table initialized
1638 * even if we fail below. We tried once; we don't try again.
1640 fptr
->file_init
= 1;
1642 if (elf_version(EV_CURRENT
) == EV_NONE
) {
1643 dprintf("libproc ELF version is more recent than libelf\n");
1647 if (P
->state
== PS_DEAD
|| P
->state
== PS_IDLE
) {
1650 * If we're a not live, we can't open files from the /proc
1651 * object directory; we have only the mapping and file names
1652 * to guide us. We prefer the file_lname, but need to handle
1653 * the case of it being NULL in order to bootstrap: we first
1654 * come here during rd_new() when the only information we have
1655 * is interpreter name associated with the AT_BASE mapping.
1657 * Also, if the zone associated with the core file seems
1658 * to exists on this machine we'll try to open the object
1659 * file within the zone.
1661 if (fptr
->file_rname
!= NULL
)
1662 name
= fptr
->file_rname
;
1663 else if (fptr
->file_lname
!= NULL
)
1664 name
= fptr
->file_lname
;
1666 name
= fptr
->file_pname
;
1667 (void) strlcpy(objectfile
, name
, sizeof (objectfile
));
1669 (void) snprintf(objectfile
, sizeof (objectfile
),
1671 procfs_path
, (int)P
->pid
, fptr
->file_pname
);
1675 * Open the object file, create the elf file, and then get the elf
1676 * header and .shstrtab data buffer so we can process sections by
1677 * name. If anything goes wrong try to fake up an elf file from
1678 * the in-core elf image.
1681 if (_libproc_incore_elf
|| (P
->flags
& INCORE
)) {
1682 dprintf("Pbuild_file_symtab: using in-core data for: %s\n",
1685 if ((elf
= build_fake_elf(P
, fptr
, &ehdr
, &nshdrs
, &shdata
)) ==
1689 } else if ((fptr
->file_fd
= open(objectfile
, O_RDONLY
)) < 0) {
1690 dprintf("Pbuild_file_symtab: failed to open %s: %s\n",
1691 objectfile
, strerror(errno
));
1693 if ((elf
= build_fake_elf(P
, fptr
, &ehdr
, &nshdrs
, &shdata
)) ==
1697 } else if ((elf
= elf_begin(fptr
->file_fd
, ELF_C_READ
, NULL
)) == NULL
||
1698 elf_kind(elf
) != ELF_K_ELF
||
1699 gelf_getehdr(elf
, &ehdr
) == NULL
||
1700 elf_getshdrnum(elf
, &nshdrs
) == -1 ||
1701 elf_getshdrstrndx(elf
, &shstrndx
) == -1 ||
1702 (scn
= elf_getscn(elf
, shstrndx
)) == NULL
||
1703 (shdata
= elf_getdata(scn
, NULL
)) == NULL
) {
1704 int err
= elf_errno();
1706 dprintf("failed to process ELF file %s: %s\n",
1707 objectfile
, (err
== 0) ? "<null>" : elf_errmsg(err
));
1708 (void) elf_end(elf
);
1710 if ((elf
= build_fake_elf(P
, fptr
, &ehdr
, &nshdrs
, &shdata
)) ==
1714 } else if (file_differs(P
, elf
, fptr
)) {
1718 * Before we get too excited about this elf file, we'll check
1719 * its checksum value against the value we have in memory. If
1720 * they don't agree, we try to fake up a new elf file and
1721 * proceed with that instead.
1723 dprintf("ELF file %s (%lx) doesn't match in-core image\n",
1725 (ulong_t
)fptr
->file_map
->map_pmap
.pr_vaddr
);
1727 if ((newelf
= build_fake_elf(P
, fptr
, &ehdr
, &nshdrs
, &shdata
))
1729 (void) elf_end(elf
);
1731 dprintf("switched to faked up ELF file\n");
1734 * Check to see if the file that we just discovered
1735 * to be an imposter matches the execname that was
1736 * determined by Pfindexec(). If it does, we (clearly)
1737 * don't have the right binary, and we zero out
1738 * execname before anyone gets hurt.
1740 if (fptr
->file_rname
!= NULL
&& P
->execname
!= NULL
&&
1741 strcmp(fptr
->file_rname
, P
->execname
) == 0) {
1742 dprintf("file/in-core image mismatch was "
1743 "on P->execname; discarding\n");
1750 if ((cache
= malloc(nshdrs
* sizeof (*cache
))) == NULL
) {
1751 dprintf("failed to malloc section cache for %s\n", objectfile
);
1755 dprintf("processing ELF file %s\n", objectfile
);
1756 fptr
->file_class
= ehdr
.e_ident
[EI_CLASS
];
1757 fptr
->file_etype
= ehdr
.e_type
;
1758 fptr
->file_elf
= elf
;
1759 fptr
->file_shstrs
= shdata
->d_buf
;
1760 fptr
->file_shstrsz
= shdata
->d_size
;
1763 * Iterate through each section, caching its section header, data
1764 * pointer, and name. We use this for handling sh_link values below.
1766 for (cp
= cache
+ 1, scn
= NULL
; scn
= elf_nextscn(elf
, scn
); cp
++) {
1767 if (gelf_getshdr(scn
, &cp
->c_shdr
) == NULL
) {
1768 dprintf("Pbuild_file_symtab: Failed to get section "
1770 goto bad
; /* Failed to get section header */
1773 if ((cp
->c_data
= elf_getdata(scn
, NULL
)) == NULL
) {
1774 dprintf("Pbuild_file_symtab: Failed to get section "
1776 goto bad
; /* Failed to get section data */
1779 if (cp
->c_shdr
.sh_name
>= shdata
->d_size
) {
1780 dprintf("Pbuild_file_symtab: corrupt section name");
1781 goto bad
; /* Corrupt section name */
1784 cp
->c_name
= (const char *)shdata
->d_buf
+ cp
->c_shdr
.sh_name
;
1788 * Now iterate through the section cache in order to locate info
1789 * for the .symtab, .dynsym, .SUNW_ldynsym, .dynamic, .plt,
1790 * and .SUNW_ctf sections:
1792 for (i
= 1, cp
= cache
+ 1; i
< nshdrs
; i
++, cp
++) {
1793 GElf_Shdr
*shp
= &cp
->c_shdr
;
1795 if (shp
->sh_type
== SHT_SYMTAB
|| shp
->sh_type
== SHT_DYNSYM
) {
1796 sym_tbl_t
*symp
= shp
->sh_type
== SHT_SYMTAB
?
1797 &fptr
->file_symtab
: &fptr
->file_dynsym
;
1799 * It's possible that the we already got the symbol
1800 * table from the core file itself. Either the file
1801 * differs in which case our faked up elf file will
1802 * only contain the dynsym (not the symtab) or the
1803 * file matches in which case we'll just be replacing
1804 * the symbol table we pulled out of the core file
1805 * with an equivalent one. In either case, this
1806 * check isn't essential, but it's a good idea.
1808 if (symp
->sym_data_pri
== NULL
) {
1809 dprintf("Symbol table found for %s\n",
1811 symp
->sym_data_pri
= cp
->c_data
;
1813 shp
->sh_size
/ shp
->sh_entsize
;
1815 cache
[shp
->sh_link
].c_data
->d_buf
;
1817 cache
[shp
->sh_link
].c_data
->d_size
;
1818 symp
->sym_hdr_pri
= cp
->c_shdr
;
1819 symp
->sym_strhdr
= cache
[shp
->sh_link
].c_shdr
;
1821 dprintf("Symbol table already there for %s\n",
1824 } else if (shp
->sh_type
== SHT_SUNW_LDYNSYM
) {
1825 /* .SUNW_ldynsym section is auxiliary to .dynsym */
1826 if (fptr
->file_dynsym
.sym_data_aux
== NULL
) {
1827 dprintf(".SUNW_ldynsym symbol table"
1828 " found for %s\n", objectfile
);
1829 fptr
->file_dynsym
.sym_data_aux
= cp
->c_data
;
1830 fptr
->file_dynsym
.sym_symn_aux
=
1831 shp
->sh_size
/ shp
->sh_entsize
;
1832 fptr
->file_dynsym
.sym_symn
+=
1833 fptr
->file_dynsym
.sym_symn_aux
;
1834 fptr
->file_dynsym
.sym_hdr_aux
= cp
->c_shdr
;
1836 dprintf(".SUNW_ldynsym symbol table already"
1837 " there for %s\n", objectfile
);
1839 } else if (shp
->sh_type
== SHT_DYNAMIC
) {
1841 } else if (strcmp(cp
->c_name
, ".plt") == 0) {
1843 } else if (strcmp(cp
->c_name
, ".SUNW_ctf") == 0) {
1845 * Skip over bogus CTF sections so they don't come back
1846 * to haunt us later.
1848 if (shp
->sh_link
== 0 ||
1849 shp
->sh_link
>= nshdrs
||
1850 (cache
[shp
->sh_link
].c_shdr
.sh_type
!= SHT_DYNSYM
&&
1851 cache
[shp
->sh_link
].c_shdr
.sh_type
!= SHT_SYMTAB
)) {
1852 dprintf("Bad sh_link %d for "
1853 "CTF\n", shp
->sh_link
);
1861 * At this point, we've found all the symbol tables we're ever going
1862 * to find: the ones in the loop above and possibly the symtab that
1863 * was included in the core file. Before we perform any lookups, we
1864 * create sorted versions to optimize for lookups.
1866 optimize_symtab(&fptr
->file_symtab
);
1867 optimize_symtab(&fptr
->file_dynsym
);
1870 * Fill in the base address of the text mapping for shared libraries.
1871 * This allows us to translate symbols before librtld_db is ready.
1873 if (fptr
->file_etype
== ET_DYN
) {
1874 fptr
->file_dyn_base
= fptr
->file_map
->map_pmap
.pr_vaddr
-
1875 fptr
->file_map
->map_pmap
.pr_offset
;
1876 dprintf("setting file_dyn_base for %s to %lx\n",
1877 objectfile
, (long)fptr
->file_dyn_base
);
1881 * Record the CTF section information in the file info structure.
1884 fptr
->file_ctf_off
= ctf
->c_shdr
.sh_offset
;
1885 fptr
->file_ctf_size
= ctf
->c_shdr
.sh_size
;
1886 if (ctf
->c_shdr
.sh_link
!= 0 &&
1887 cache
[ctf
->c_shdr
.sh_link
].c_shdr
.sh_type
== SHT_DYNSYM
)
1888 fptr
->file_ctf_dyn
= 1;
1891 if (fptr
->file_lo
== NULL
)
1892 goto done
; /* Nothing else to do if no load object info */
1895 * If the object is a shared library and we have a different rl_base
1896 * value, reset file_dyn_base according to librtld_db's information.
1898 if (fptr
->file_etype
== ET_DYN
&&
1899 fptr
->file_lo
->rl_base
!= fptr
->file_dyn_base
) {
1900 dprintf("resetting file_dyn_base for %s to %lx\n",
1901 objectfile
, (long)fptr
->file_lo
->rl_base
);
1902 fptr
->file_dyn_base
= fptr
->file_lo
->rl_base
;
1906 * Fill in the PLT information for this file if a PLT symbol is found.
1908 if (sym_by_name(&fptr
->file_dynsym
, "_PROCEDURE_LINKAGE_TABLE_", &s
,
1910 fptr
->file_plt_base
= s
.st_value
+ fptr
->file_dyn_base
;
1911 fptr
->file_plt_size
= (plt
!= NULL
) ? plt
->c_shdr
.sh_size
: 0;
1914 * Bring the load object up to date; it is the only way the
1915 * user has to access the PLT data. The PLT information in the
1916 * rd_loadobj_t is not set in the call to map_iter() (the
1917 * callback for rd_loadobj_iter) where we set file_lo.
1919 fptr
->file_lo
->rl_plt_base
= fptr
->file_plt_base
;
1920 fptr
->file_lo
->rl_plt_size
= fptr
->file_plt_size
;
1922 dprintf("PLT found at %p, size = %lu\n",
1923 (void *)fptr
->file_plt_base
, (ulong_t
)fptr
->file_plt_size
);
1927 * Fill in the PLT information.
1930 uintptr_t dynaddr
= dyn
->c_shdr
.sh_addr
+ fptr
->file_dyn_base
;
1931 size_t ndyn
= dyn
->c_shdr
.sh_size
/ dyn
->c_shdr
.sh_entsize
;
1934 for (i
= 0; i
< ndyn
; i
++) {
1935 if (gelf_getdyn(dyn
->c_data
, i
, &d
) == NULL
)
1940 dprintf("DT_JMPREL is %p\n",
1941 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1942 fptr
->file_jmp_rel
=
1943 d
.d_un
.d_ptr
+ fptr
->file_dyn_base
;
1946 dprintf("DT_STRTAB is %p\n",
1947 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1950 dprintf("DT_PLTGOT is %p\n",
1951 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1953 case DT_SUNW_SYMTAB
:
1954 dprintf("DT_SUNW_SYMTAB is %p\n",
1955 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1958 dprintf("DT_SYMTAB is %p\n",
1959 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1962 dprintf("DT_HASH is %p\n",
1963 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1968 dprintf("_DYNAMIC found at %p, %lu entries, DT_JMPREL = %p\n",
1969 (void *)dynaddr
, (ulong_t
)ndyn
, (void *)fptr
->file_jmp_rel
);
1979 (void) elf_end(elf
);
1980 fptr
->file_elf
= NULL
;
1981 if (fptr
->file_elfmem
!= NULL
) {
1982 free(fptr
->file_elfmem
);
1983 fptr
->file_elfmem
= NULL
;
1985 (void) close(fptr
->file_fd
);
1990 * Given a process virtual address, return the map_info_t containing it.
1991 * If none found, return NULL.
1994 Paddr2mptr(struct ps_prochandle
*P
, uintptr_t addr
)
1997 int hi
= P
->map_count
- 1;
2003 mid
= (lo
+ hi
) / 2;
2004 mp
= &P
->mappings
[mid
];
2006 /* check that addr is in [vaddr, vaddr + size) */
2007 if ((addr
- mp
->map_pmap
.pr_vaddr
) < mp
->map_pmap
.pr_size
)
2010 if (addr
< mp
->map_pmap
.pr_vaddr
)
2020 * Return the map_info_t for the executable file.
2021 * If not found, return NULL.
2024 exec_map(struct ps_prochandle
*P
)
2028 map_info_t
*mold
= NULL
;
2032 for (i
= 0, mptr
= P
->mappings
; i
< P
->map_count
; i
++, mptr
++) {
2033 if (mptr
->map_pmap
.pr_mapname
[0] == '\0')
2035 if (strcmp(mptr
->map_pmap
.pr_mapname
, "a.out") == 0) {
2036 if ((fptr
= mptr
->map_file
) != NULL
&&
2037 fptr
->file_lo
!= NULL
) {
2038 base
= fptr
->file_lo
->rl_base
;
2039 if (base
>= mptr
->map_pmap
.pr_vaddr
&&
2040 base
< mptr
->map_pmap
.pr_vaddr
+
2041 mptr
->map_pmap
.pr_size
) /* text space */
2043 mold
= mptr
; /* must be the data */
2046 /* This is a poor way to test for text space */
2047 if (!(mptr
->map_pmap
.pr_mflags
& MA_EXEC
) ||
2048 (mptr
->map_pmap
.pr_mflags
& MA_WRITE
)) {
2060 * Given a shared object name, return the map_info_t for it. If no matching
2061 * object is found, return NULL. Normally, the link maps contain the full
2062 * object pathname, e.g. /usr/lib/libc.so.1. We allow the object name to
2063 * take one of the following forms:
2065 * 1. An exact match (i.e. a full pathname): "/usr/lib/libc.so.1"
2066 * 2. An exact basename match: "libc.so.1"
2067 * 3. An initial basename match up to a '.' suffix: "libc.so" or "libc"
2068 * 4. The literal string "a.out" is an alias for the executable mapping
2070 * The third case is a convenience for callers and may not be necessary.
2072 * As the exact same object name may be loaded on different link maps (see
2073 * dlmopen(3DL)), we also allow the caller to resolve the object name by
2074 * specifying a particular link map id. If lmid is PR_LMID_EVERY, the
2075 * first matching name will be returned, regardless of the link map id.
2078 object_to_map(struct ps_prochandle
*P
, Lmid_t lmid
, const char *objname
)
2086 * If we have no rtld_db, then always treat a request as one for all
2090 lmid
= PR_LMID_EVERY
;
2093 * First pass: look for exact matches of the entire pathname or
2094 * basename (cases 1 and 2 above):
2096 for (i
= 0, mp
= P
->mappings
; i
< P
->map_count
; i
++, mp
++) {
2098 if (mp
->map_pmap
.pr_mapname
[0] == '\0' ||
2099 (fp
= mp
->map_file
) == NULL
||
2100 ((fp
->file_lname
== NULL
) && (fp
->file_rname
== NULL
)))
2103 if (lmid
!= PR_LMID_EVERY
&&
2104 (fp
->file_lo
== NULL
|| lmid
!= fp
->file_lo
->rl_lmident
))
2108 * If we match, return the primary text mapping; otherwise
2109 * just return the mapping we matched.
2111 if ((fp
->file_lbase
&& strcmp(fp
->file_lbase
, objname
) == 0) ||
2112 (fp
->file_rbase
&& strcmp(fp
->file_rbase
, objname
) == 0) ||
2113 (fp
->file_lname
&& strcmp(fp
->file_lname
, objname
) == 0) ||
2114 (fp
->file_rname
&& strcmp(fp
->file_rname
, objname
) == 0))
2115 return (fp
->file_map
? fp
->file_map
: mp
);
2118 objlen
= strlen(objname
);
2121 * Second pass: look for partial matches (case 3 above):
2123 for (i
= 0, mp
= P
->mappings
; i
< P
->map_count
; i
++, mp
++) {
2125 if (mp
->map_pmap
.pr_mapname
[0] == '\0' ||
2126 (fp
= mp
->map_file
) == NULL
||
2127 ((fp
->file_lname
== NULL
) && (fp
->file_rname
== NULL
)))
2130 if (lmid
!= PR_LMID_EVERY
&&
2131 (fp
->file_lo
== NULL
|| lmid
!= fp
->file_lo
->rl_lmident
))
2135 * If we match, return the primary text mapping; otherwise
2136 * just return the mapping we matched.
2138 if ((fp
->file_lbase
!= NULL
) &&
2139 (strncmp(fp
->file_lbase
, objname
, objlen
) == 0) &&
2140 (fp
->file_lbase
[objlen
] == '.'))
2141 return (fp
->file_map
? fp
->file_map
: mp
);
2142 if ((fp
->file_rbase
!= NULL
) &&
2143 (strncmp(fp
->file_rbase
, objname
, objlen
) == 0) &&
2144 (fp
->file_rbase
[objlen
] == '.'))
2145 return (fp
->file_map
? fp
->file_map
: mp
);
2149 * One last check: we allow "a.out" to always alias the executable,
2150 * assuming this name was not in use for something else.
2152 if ((lmid
== PR_LMID_EVERY
|| lmid
== LM_ID_BASE
) &&
2153 (strcmp(objname
, "a.out") == 0))
2154 return (P
->map_exec
);
2160 object_name_to_map(struct ps_prochandle
*P
, Lmid_t lmid
, const char *name
)
2167 if (P
->map_exec
== NULL
&& ((mptr
= Paddr2mptr(P
,
2168 Pgetauxval(P
, AT_ENTRY
))) != NULL
|| (mptr
= exec_map(P
)) != NULL
))
2171 if (P
->map_ldso
== NULL
&& (mptr
= Paddr2mptr(P
,
2172 Pgetauxval(P
, AT_BASE
))) != NULL
)
2175 if (name
== PR_OBJ_EXEC
)
2177 else if (name
== PR_OBJ_LDSO
)
2179 else if (Prd_agent(P
) != NULL
|| P
->state
== PS_IDLE
)
2180 mptr
= object_to_map(P
, lmid
, name
);
2188 * When two symbols are found by address, decide which one is to be preferred.
2191 sym_prefer(GElf_Sym
*sym1
, char *name1
, GElf_Sym
*sym2
, char *name2
)
2194 * Prefer the non-NULL symbol.
2202 * Defer to the sort ordering...
2204 return (byaddr_cmp_common(sym1
, name1
, sym2
, name2
) <= 0 ? sym1
: sym2
);
2208 * Use a binary search to do the work of sym_by_addr().
2211 sym_by_addr_binary(sym_tbl_t
*symtab
, GElf_Addr addr
, GElf_Sym
*symp
,
2215 uint_t i
, oid
, *byaddr
= symtab
->sym_byaddr
;
2216 int min
, max
, mid
, omid
, found
= 0;
2218 if (symtab
->sym_data_pri
== NULL
|| symtab
->sym_count
== 0)
2222 max
= symtab
->sym_count
- 1;
2226 * We can't return when we've found a match, we have to continue
2227 * searching for the closest matching symbol.
2229 while (min
<= max
) {
2230 mid
= (max
+ min
) / 2;
2233 (void) symtab_getsym(symtab
, i
, &sym
);
2235 if (addr
>= sym
.st_value
&&
2236 addr
< sym
.st_value
+ sym
.st_size
&&
2237 (!found
|| sym
.st_value
> osym
.st_value
)) {
2244 if (addr
< sym
.st_value
)
2254 * There may be many symbols with identical values so we walk
2255 * backward in the byaddr table to find the best match.
2264 oid
= byaddr
[--omid
];
2265 (void) symtab_getsym(symtab
, oid
, &osym
);
2266 } while (addr
>= osym
.st_value
&&
2267 addr
< sym
.st_value
+ osym
.st_size
&&
2268 osym
.st_value
== sym
.st_value
);
2277 * Use a linear search to do the work of sym_by_addr().
2280 sym_by_addr_linear(sym_tbl_t
*symtab
, GElf_Addr addr
, GElf_Sym
*symbolp
,
2283 size_t symn
= symtab
->sym_symn
;
2284 char *strs
= symtab
->sym_strs
;
2285 GElf_Sym sym
, *symp
= NULL
;
2286 GElf_Sym osym
, *osymp
= NULL
;
2289 if (symtab
->sym_data_pri
== NULL
|| symn
== 0 || strs
== NULL
)
2292 for (i
= 0; i
< symn
; i
++) {
2293 if ((symp
= symtab_getsym(symtab
, i
, &sym
)) != NULL
) {
2294 if (addr
>= sym
.st_value
&&
2295 addr
< sym
.st_value
+ sym
.st_size
) {
2298 symp
, strs
+ symp
->st_name
,
2299 osymp
, strs
+ osymp
->st_name
);
2300 if (symp
!= osymp
) {
2318 * Look up a symbol by address in the specified symbol table.
2319 * Adjustment to 'addr' must already have been made for the
2320 * offset of the symbol if this is a dynamic library symbol table.
2322 * Use a linear or a binary search depending on whether or not we
2323 * chose to sort the table in optimize_symtab().
2326 sym_by_addr(sym_tbl_t
*symtab
, GElf_Addr addr
, GElf_Sym
*symp
, uint_t
*idp
)
2328 if (_libproc_no_qsort
) {
2329 return (sym_by_addr_linear(symtab
, addr
, symp
, idp
));
2331 return (sym_by_addr_binary(symtab
, addr
, symp
, idp
));
2336 * Use a binary search to do the work of sym_by_name().
2339 sym_by_name_binary(sym_tbl_t
*symtab
, const char *name
, GElf_Sym
*symp
,
2342 char *strs
= symtab
->sym_strs
;
2343 uint_t i
, *byname
= symtab
->sym_byname
;
2344 int min
, mid
, max
, cmp
;
2346 if (symtab
->sym_data_pri
== NULL
|| strs
== NULL
||
2347 symtab
->sym_count
== 0)
2351 max
= symtab
->sym_count
- 1;
2353 while (min
<= max
) {
2354 mid
= (max
+ min
) / 2;
2357 (void) symtab_getsym(symtab
, i
, symp
);
2359 if ((cmp
= strcmp(name
, strs
+ symp
->st_name
)) == 0) {
2375 * Use a linear search to do the work of sym_by_name().
2378 sym_by_name_linear(sym_tbl_t
*symtab
, const char *name
, GElf_Sym
*symp
,
2381 size_t symn
= symtab
->sym_symn
;
2382 char *strs
= symtab
->sym_strs
;
2385 if (symtab
->sym_data_pri
== NULL
|| symn
== 0 || strs
== NULL
)
2388 for (i
= 0; i
< symn
; i
++) {
2389 if (symtab_getsym(symtab
, i
, symp
) &&
2390 strcmp(name
, strs
+ symp
->st_name
) == 0) {
2401 * Look up a symbol by name in the specified symbol table.
2403 * Use a linear or a binary search depending on whether or not we
2404 * chose to sort the table in optimize_symtab().
2407 sym_by_name(sym_tbl_t
*symtab
, const char *name
, GElf_Sym
*symp
, uint_t
*idp
)
2409 if (_libproc_no_qsort
) {
2410 return (sym_by_name_linear(symtab
, name
, symp
, idp
));
2412 return (sym_by_name_binary(symtab
, name
, symp
, idp
));
2417 * Search the process symbol tables looking for a symbol whose
2418 * value to value+size contain the address specified by addr.
2419 * Return values are:
2420 * sym_name_buffer containing the symbol name
2421 * GElf_Sym symbol table entry
2422 * prsyminfo_t ancillary symbol information
2423 * Returns 0 on success, -1 on failure.
2427 struct ps_prochandle
*P
,
2428 int lmresolve
, /* use resolve linker object names */
2429 uintptr_t addr
, /* process address being sought */
2430 char *sym_name_buffer
, /* buffer for the symbol name */
2431 size_t bufsize
, /* size of sym_name_buffer */
2432 GElf_Sym
*symbolp
, /* returned symbol table entry */
2433 prsyminfo_t
*sip
) /* returned symbol info */
2437 GElf_Sym sym1
, *sym1p
= NULL
;
2438 GElf_Sym sym2
, *sym2p
= NULL
;
2446 (void) Prd_agent(P
);
2448 if ((mptr
= Paddr2mptr(P
, addr
)) == NULL
|| /* no such address */
2449 (fptr
= build_map_symtab(P
, mptr
)) == NULL
|| /* no mapped file */
2450 fptr
->file_elf
== NULL
) /* not an ELF file */
2454 * Adjust the address by the load object base address in
2455 * case the address turns out to be in a shared library.
2457 addr
-= fptr
->file_dyn_base
;
2460 * Search both symbol tables, symtab first, then dynsym.
2462 if ((sym1p
= sym_by_addr(&fptr
->file_symtab
, addr
, &sym1
, &i1
)) != NULL
)
2463 name1
= fptr
->file_symtab
.sym_strs
+ sym1
.st_name
;
2464 if ((sym2p
= sym_by_addr(&fptr
->file_dynsym
, addr
, &sym2
, &i2
)) != NULL
)
2465 name2
= fptr
->file_dynsym
.sym_strs
+ sym2
.st_name
;
2467 if ((symp
= sym_prefer(sym1p
, name1
, sym2p
, name2
)) == NULL
)
2470 name
= (symp
== sym1p
) ? name1
: name2
;
2472 (void) strncpy(sym_name_buffer
, name
, bufsize
);
2473 sym_name_buffer
[bufsize
- 1] = '\0';
2478 sip
->prs_name
= bufsize
== 0 ? NULL
: sym_name_buffer
;
2479 if (lmresolve
&& (fptr
->file_rname
!= NULL
))
2480 sip
->prs_object
= fptr
->file_rbase
;
2482 sip
->prs_object
= fptr
->file_lbase
;
2483 sip
->prs_id
= (symp
== sym1p
) ? i1
: i2
;
2484 sip
->prs_table
= (symp
== sym1p
) ? PR_SYMTAB
: PR_DYNSYM
;
2485 sip
->prs_lmid
= (fptr
->file_lo
== NULL
) ? LM_ID_BASE
:
2486 fptr
->file_lo
->rl_lmident
;
2489 if (GELF_ST_TYPE(symbolp
->st_info
) != STT_TLS
)
2490 symbolp
->st_value
+= fptr
->file_dyn_base
;
2496 Pxlookup_by_addr(struct ps_prochandle
*P
, uintptr_t addr
, char *buf
,
2497 size_t bufsize
, GElf_Sym
*symp
, prsyminfo_t
*sip
)
2499 return (i_Pxlookup_by_addr(P
, B_FALSE
, addr
, buf
, bufsize
, symp
, sip
));
2503 Pxlookup_by_addr_resolved(struct ps_prochandle
*P
, uintptr_t addr
, char *buf
,
2504 size_t bufsize
, GElf_Sym
*symp
, prsyminfo_t
*sip
)
2506 return (i_Pxlookup_by_addr(P
, B_TRUE
, addr
, buf
, bufsize
, symp
, sip
));
2510 Plookup_by_addr(struct ps_prochandle
*P
, uintptr_t addr
, char *buf
,
2511 size_t size
, GElf_Sym
*symp
)
2513 return (i_Pxlookup_by_addr(P
, B_FALSE
, addr
, buf
, size
, symp
, NULL
));
2517 * Search the process symbol tables looking for a symbol whose name matches the
2518 * specified name and whose object and link map optionally match the specified
2519 * parameters. On success, the function returns 0 and fills in the GElf_Sym
2520 * symbol table entry. On failure, -1 is returned.
2524 struct ps_prochandle
*P
,
2525 Lmid_t lmid
, /* link map to match, or -1 for any */
2526 const char *oname
, /* load object name */
2527 const char *sname
, /* symbol name */
2528 GElf_Sym
*symp
, /* returned symbol table entry */
2529 prsyminfo_t
*sip
) /* returned symbol info */
2540 if (oname
== PR_OBJ_EVERY
) {
2541 /* create all the file_info_t's for all the mappings */
2542 (void) Prd_agent(P
);
2544 fptr
= list_next(&P
->file_head
);
2547 if ((mptr
= object_name_to_map(P
, lmid
, oname
)) == NULL
||
2548 (fptr
= build_map_symtab(P
, mptr
)) == NULL
)
2553 * Iterate through the loaded object files and look for the symbol
2554 * name in the .symtab and .dynsym of each. If we encounter a match
2555 * with SHN_UNDEF, keep looking in hopes of finding a better match.
2556 * This means that a name such as "puts" will match the puts function
2557 * in libc instead of matching the puts PLT entry in the a.out file.
2559 for (; cnt
> 0; cnt
--, fptr
= list_next(fptr
)) {
2560 Pbuild_file_symtab(P
, fptr
);
2562 if (fptr
->file_elf
== NULL
)
2565 if (lmid
!= PR_LMID_EVERY
&& fptr
->file_lo
!= NULL
&&
2566 lmid
!= fptr
->file_lo
->rl_lmident
)
2569 if (fptr
->file_symtab
.sym_data_pri
!= NULL
&&
2570 sym_by_name(&fptr
->file_symtab
, sname
, symp
, &id
)) {
2573 sip
->prs_table
= PR_SYMTAB
;
2574 sip
->prs_object
= oname
;
2575 sip
->prs_name
= sname
;
2576 sip
->prs_lmid
= fptr
->file_lo
== NULL
?
2577 LM_ID_BASE
: fptr
->file_lo
->rl_lmident
;
2579 } else if (fptr
->file_dynsym
.sym_data_pri
!= NULL
&&
2580 sym_by_name(&fptr
->file_dynsym
, sname
, symp
, &id
)) {
2583 sip
->prs_table
= PR_DYNSYM
;
2584 sip
->prs_object
= oname
;
2585 sip
->prs_name
= sname
;
2586 sip
->prs_lmid
= fptr
->file_lo
== NULL
?
2587 LM_ID_BASE
: fptr
->file_lo
->rl_lmident
;
2593 if (GELF_ST_TYPE(symp
->st_info
) != STT_TLS
)
2594 symp
->st_value
+= fptr
->file_dyn_base
;
2596 if (symp
->st_shndx
!= SHN_UNDEF
)
2617 * Search the process symbol tables looking for a symbol whose name matches the
2618 * specified name, but without any restriction on the link map id.
2621 Plookup_by_name(struct ps_prochandle
*P
, const char *object
,
2622 const char *symbol
, GElf_Sym
*symp
)
2624 return (Pxlookup_by_name(P
, PR_LMID_EVERY
, object
, symbol
, symp
, NULL
));
2628 * Iterate over the process's address space mappings.
2631 i_Pmapping_iter(struct ps_prochandle
*P
, boolean_t lmresolve
,
2632 proc_map_f
*func
, void *cd
)
2640 /* create all the file_info_t's for all the mappings */
2641 (void) Prd_agent(P
);
2643 for (i
= 0, mptr
= P
->mappings
; i
< P
->map_count
; i
++, mptr
++) {
2644 if ((fptr
= mptr
->map_file
) == NULL
)
2646 else if (lmresolve
&& (fptr
->file_rname
!= NULL
))
2647 object_name
= fptr
->file_rname
;
2649 object_name
= fptr
->file_lname
;
2650 if ((rc
= func(cd
, &mptr
->map_pmap
, object_name
)) != 0)
2657 Pmapping_iter(struct ps_prochandle
*P
, proc_map_f
*func
, void *cd
)
2659 return (i_Pmapping_iter(P
, B_FALSE
, func
, cd
));
2663 Pmapping_iter_resolved(struct ps_prochandle
*P
, proc_map_f
*func
, void *cd
)
2665 return (i_Pmapping_iter(P
, B_TRUE
, func
, cd
));
2669 * Iterate over the process's mapped objects.
2672 i_Pobject_iter(struct ps_prochandle
*P
, boolean_t lmresolve
,
2673 proc_map_f
*func
, void *cd
)
2680 (void) Prd_agent(P
); /* create file_info_t's for all the mappings */
2683 for (cnt
= P
->num_files
, fptr
= list_next(&P
->file_head
);
2684 cnt
; cnt
--, fptr
= list_next(fptr
)) {
2687 if (lmresolve
&& (fptr
->file_rname
!= NULL
))
2688 lname
= fptr
->file_rname
;
2689 else if (fptr
->file_lname
!= NULL
)
2690 lname
= fptr
->file_lname
;
2694 if ((mptr
= fptr
->file_map
) == NULL
)
2697 if ((rc
= func(cd
, &mptr
->map_pmap
, lname
)) != 0)
2707 Pobject_iter(struct ps_prochandle
*P
, proc_map_f
*func
, void *cd
)
2709 return (i_Pobject_iter(P
, B_FALSE
, func
, cd
));
2713 Pobject_iter_resolved(struct ps_prochandle
*P
, proc_map_f
*func
, void *cd
)
2715 return (i_Pobject_iter(P
, B_TRUE
, func
, cd
));
2719 i_Pobjname(struct ps_prochandle
*P
, boolean_t lmresolve
, uintptr_t addr
,
2720 char *buffer
, size_t bufsize
)
2725 /* create all the file_info_t's for all the mappings */
2726 (void) Prd_agent(P
);
2728 if ((mptr
= Paddr2mptr(P
, addr
)) == NULL
)
2732 if (((fptr
= mptr
->map_file
) == NULL
) ||
2733 (fptr
->file_lname
== NULL
))
2735 (void) strlcpy(buffer
, fptr
->file_lname
, bufsize
);
2739 /* Check for a cached copy of the resolved path */
2740 if (Pfindmap(P
, mptr
, buffer
, bufsize
) != NULL
)
2747 * Given a virtual address, return the name of the underlying
2748 * mapped object (file) as provided by the dynamic linker.
2749 * Return NULL if we can't find any name information for the object.
2752 Pobjname(struct ps_prochandle
*P
, uintptr_t addr
,
2753 char *buffer
, size_t bufsize
)
2755 return (i_Pobjname(P
, B_FALSE
, addr
, buffer
, bufsize
));
2759 * Given a virtual address, try to return a filesystem path to the
2760 * underlying mapped object (file). If we're in the global zone,
2761 * this path could resolve to an object in another zone. If we're
2762 * unable return a valid filesystem path, we'll fall back to providing
2763 * the mapped object (file) name provided by the dynamic linker in
2764 * the target process (ie, the object reported by Pobjname()).
2767 Pobjname_resolved(struct ps_prochandle
*P
, uintptr_t addr
,
2768 char *buffer
, size_t bufsize
)
2770 return (i_Pobjname(P
, B_TRUE
, addr
, buffer
, bufsize
));
2774 * Given a virtual address, return the link map id of the underlying mapped
2775 * object (file), as provided by the dynamic linker. Return -1 on failure.
2778 Plmid(struct ps_prochandle
*P
, uintptr_t addr
, Lmid_t
*lmidp
)
2783 /* create all the file_info_t's for all the mappings */
2784 (void) Prd_agent(P
);
2786 if ((mptr
= Paddr2mptr(P
, addr
)) != NULL
&&
2787 (fptr
= mptr
->map_file
) != NULL
&& fptr
->file_lo
!= NULL
) {
2788 *lmidp
= fptr
->file_lo
->rl_lmident
;
2796 * Given an object name and optional lmid, iterate over the object's symbols.
2797 * If which == PR_SYMTAB, search the normal symbol table.
2798 * If which == PR_DYNSYM, search the dynamic symbol table.
2801 Psymbol_iter_com(struct ps_prochandle
*P
, Lmid_t lmid
, const char *object_name
,
2802 int which
, int mask
, pr_order_t order
, proc_xsym_f
*func
, void *cd
)
2804 #if STT_NUM != (STT_TLS + 1)
2805 #error "STT_NUM has grown. update Psymbol_iter_com()"
2818 uint_t
*map
, i
, count
, ndx
;
2820 if ((mptr
= object_name_to_map(P
, lmid
, object_name
)) == NULL
)
2823 if ((fptr
= build_map_symtab(P
, mptr
)) == NULL
|| /* no mapped file */
2824 fptr
->file_elf
== NULL
) /* not an ELF file */
2828 * Search the specified symbol table.
2832 symtab
= &fptr
->file_symtab
;
2833 si
.prs_table
= PR_SYMTAB
;
2836 symtab
= &fptr
->file_dynsym
;
2837 si
.prs_table
= PR_DYNSYM
;
2843 si
.prs_object
= object_name
;
2844 si
.prs_lmid
= fptr
->file_lo
== NULL
?
2845 LM_ID_BASE
: fptr
->file_lo
->rl_lmident
;
2847 symn
= symtab
->sym_symn
;
2848 strs
= symtab
->sym_strs
;
2849 strsz
= symtab
->sym_strsz
;
2857 map
= symtab
->sym_byname
;
2858 count
= symtab
->sym_count
;
2861 map
= symtab
->sym_byaddr
;
2862 count
= symtab
->sym_count
;
2868 if (symtab
->sym_data_pri
== NULL
|| strs
== NULL
|| count
== 0)
2873 for (i
= 0; i
< count
; i
++) {
2874 ndx
= map
== NULL
? i
: map
[i
];
2875 if (symtab_getsym(symtab
, ndx
, &sym
) != NULL
) {
2876 uint_t s_bind
, s_type
, type
;
2878 if (sym
.st_name
>= strsz
) /* invalid st_name */
2881 s_bind
= GELF_ST_BIND(sym
.st_info
);
2882 s_type
= GELF_ST_TYPE(sym
.st_info
);
2885 * In case you haven't already guessed, this relies on
2886 * the bitmask used in <libproc.h> for encoding symbol
2887 * type and binding matching the order of STB and STT
2888 * constants in <sys/elf.h>. Changes to ELF must
2889 * maintain binary compatibility, so I think this is
2890 * reasonably fair game.
2892 if (s_bind
< STB_NUM
&& s_type
< STT_NUM
) {
2893 type
= (1 << (s_type
+ 8)) | (1 << s_bind
);
2894 if ((type
& ~mask
) != 0)
2897 continue; /* Invalid type or binding */
2899 if (GELF_ST_TYPE(sym
.st_info
) != STT_TLS
)
2900 sym
.st_value
+= fptr
->file_dyn_base
;
2902 si
.prs_name
= strs
+ sym
.st_name
;
2905 * If symbol's type is STT_SECTION, then try to lookup
2906 * the name of the corresponding section.
2908 if (GELF_ST_TYPE(sym
.st_info
) == STT_SECTION
&&
2909 fptr
->file_shstrs
!= NULL
&&
2910 gelf_getshdr(elf_getscn(fptr
->file_elf
,
2911 sym
.st_shndx
), &shdr
) != NULL
&&
2912 shdr
.sh_name
!= 0 &&
2913 shdr
.sh_name
< fptr
->file_shstrsz
)
2914 si
.prs_name
= fptr
->file_shstrs
+ shdr
.sh_name
;
2917 if ((rv
= func(cd
, &sym
, si
.prs_name
, &si
)) != 0)
2926 Pxsymbol_iter(struct ps_prochandle
*P
, Lmid_t lmid
, const char *object_name
,
2927 int which
, int mask
, proc_xsym_f
*func
, void *cd
)
2929 return (Psymbol_iter_com(P
, lmid
, object_name
, which
, mask
,
2930 PRO_NATURAL
, func
, cd
));
2934 Psymbol_iter_by_lmid(struct ps_prochandle
*P
, Lmid_t lmid
,
2935 const char *object_name
, int which
, int mask
, proc_sym_f
*func
, void *cd
)
2937 return (Psymbol_iter_com(P
, lmid
, object_name
, which
, mask
,
2938 PRO_NATURAL
, (proc_xsym_f
*)func
, cd
));
2942 Psymbol_iter(struct ps_prochandle
*P
,
2943 const char *object_name
, int which
, int mask
, proc_sym_f
*func
, void *cd
)
2945 return (Psymbol_iter_com(P
, PR_LMID_EVERY
, object_name
, which
, mask
,
2946 PRO_NATURAL
, (proc_xsym_f
*)func
, cd
));
2950 Psymbol_iter_by_addr(struct ps_prochandle
*P
,
2951 const char *object_name
, int which
, int mask
, proc_sym_f
*func
, void *cd
)
2953 return (Psymbol_iter_com(P
, PR_LMID_EVERY
, object_name
, which
, mask
,
2954 PRO_BYADDR
, (proc_xsym_f
*)func
, cd
));
2958 Psymbol_iter_by_name(struct ps_prochandle
*P
,
2959 const char *object_name
, int which
, int mask
, proc_sym_f
*func
, void *cd
)
2961 return (Psymbol_iter_com(P
, PR_LMID_EVERY
, object_name
, which
, mask
,
2962 PRO_BYNAME
, (proc_xsym_f
*)func
, cd
));
2966 * Get the platform string.
2969 Pplatform(struct ps_prochandle
*P
, char *s
, size_t n
)
2971 return (P
->ops
.pop_platform(P
, s
, n
, P
->data
));
2975 * Get the uname(2) information.
2978 Puname(struct ps_prochandle
*P
, struct utsname
*u
)
2980 return (P
->ops
.pop_uname(P
, u
, P
->data
));
2984 * Called from Pcreate(), Pgrab(), and Pfgrab_core() to initialize
2985 * the symbol table heads in the new ps_prochandle.
2988 Pinitsym(struct ps_prochandle
*P
)
2991 list_link(&P
->file_head
, NULL
);
2995 * Called from Prelease() to destroy the symbol tables.
2996 * Must be called by the client after an exec() in the victim process.
2999 Preset_maps(struct ps_prochandle
*P
)
3003 if (P
->rap
!= NULL
) {
3008 if (P
->execname
!= NULL
) {
3013 if (P
->auxv
!= NULL
) {
3019 for (i
= 0; i
< P
->map_count
; i
++)
3020 map_info_free(P
, &P
->mappings
[i
]);
3022 if (P
->mappings
!= NULL
) {
3026 P
->map_count
= P
->map_alloc
= 0;
3031 typedef struct getenv_data
{
3040 getenv_func(void *data
, struct ps_prochandle
*P
, uintptr_t addr
,
3041 const char *nameval
)
3043 getenv_data_t
*d
= data
;
3046 if (nameval
== NULL
)
3049 if (d
->searchlen
< strlen(nameval
) &&
3050 strncmp(nameval
, d
->search
, d
->searchlen
) == 0 &&
3051 nameval
[d
->searchlen
] == '=') {
3052 len
= MIN(strlen(nameval
), d
->bufsize
- 1);
3053 (void) strncpy(d
->buf
, nameval
, len
);
3062 Pgetenv(struct ps_prochandle
*P
, const char *name
, char *buf
, size_t buflen
)
3069 d
.searchlen
= strlen(name
);
3071 if (Penv_iter(P
, getenv_func
, &d
) == 1) {
3072 char *equals
= strchr(d
.buf
, '=');
3074 if (equals
!= NULL
) {
3075 (void) memmove(d
.buf
, equals
+ 1,
3076 d
.buf
+ buflen
- equals
- 1);
3077 d
.buf
[d
.buf
+ buflen
- equals
] = '\0';
3086 /* number of argument or environment pointers to read all at once */
3090 Penv_iter(struct ps_prochandle
*P
, proc_env_f
*func
, void *data
)
3092 const psinfo_t
*psp
;
3096 char *buf
, *nameval
;
3103 * Attempt to find the "_environ" variable in the process.
3104 * Failing that, use the original value provided by Ppsinfo().
3106 if ((psp
= Ppsinfo(P
)) == NULL
)
3109 envpoff
= psp
->pr_envp
; /* Default if no _environ found */
3111 if (Plookup_by_name(P
, PR_OBJ_EXEC
, "_environ", &sym
) == 0) {
3112 if (P
->status
.pr_dmodel
== PR_MODEL_NATIVE
) {
3113 if (Pread(P
, &envpoff
, sizeof (envpoff
),
3114 sym
.st_value
) != sizeof (envpoff
))
3115 envpoff
= psp
->pr_envp
;
3116 } else if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
3119 if (Pread(P
, &envpoff32
, sizeof (envpoff32
),
3120 sym
.st_value
) != sizeof (envpoff32
))
3121 envpoff
= psp
->pr_envp
;
3123 envpoff
= envpoff32
;
3128 buf
= malloc(buflen
);
3135 (void) memset(envp
, 0, sizeof (envp
));
3136 if (P
->status
.pr_dmodel
== PR_MODEL_NATIVE
) {
3138 sizeof (envp
), envpoff
) <= 0) {
3142 } else if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
3146 (void) memset(e32
, 0, sizeof (e32
));
3147 if (Pread(P
, e32
, sizeof (e32
), envpoff
) <= 0) {
3151 for (i
= 0; i
< NARG
; i
++)
3157 if ((envoff
= envp
[nenv
++]) == (uintptr_t)NULL
)
3161 * Attempt to read the string from the process.
3164 ret
= Pread_string(P
, buf
, buflen
, envoff
);
3168 } else if (ret
== buflen
- 1) {
3171 * Bail if we have a corrupted environment
3173 if (buflen
>= ARG_MAX
)
3176 buf
= malloc(buflen
);
3182 if ((ret
= func(data
, P
, envoff
, nameval
)) != 0)
3185 envpoff
+= (P
->status
.pr_dmodel
== PR_MODEL_LP64
)? 8 : 4;