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, Joyent, Inc. All rights reserved.
25 * Copyright (c) 2013 by Delphix. All rights reserved.
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 if (fptr
->file_symtab
.sym_byname
)
252 free(fptr
->file_symtab
.sym_byname
);
253 if (fptr
->file_symtab
.sym_byaddr
)
254 free(fptr
->file_symtab
.sym_byaddr
);
256 if (fptr
->file_dynsym
.sym_elf
) {
257 (void) elf_end(fptr
->file_dynsym
.sym_elf
);
258 free(fptr
->file_dynsym
.sym_elfmem
);
260 if (fptr
->file_dynsym
.sym_byname
)
261 free(fptr
->file_dynsym
.sym_byname
);
262 if (fptr
->file_dynsym
.sym_byaddr
)
263 free(fptr
->file_dynsym
.sym_byaddr
);
267 if (fptr
->file_lname
)
268 free(fptr
->file_lname
);
269 if (fptr
->file_rname
)
270 free(fptr
->file_rname
);
272 (void) elf_end(fptr
->file_elf
);
273 if (fptr
->file_elfmem
!= NULL
)
274 free(fptr
->file_elfmem
);
275 if (fptr
->file_fd
>= 0)
276 (void) close(fptr
->file_fd
);
277 if (fptr
->file_ctfp
) {
278 ctf_close(fptr
->file_ctfp
);
279 free(fptr
->file_ctf_buf
);
281 if (fptr
->file_saddrs
)
282 free(fptr
->file_saddrs
);
289 * Deallocation function for a map_info_t
292 map_info_free(struct ps_prochandle
*P
, map_info_t
*mptr
)
296 if ((fptr
= mptr
->map_file
) != NULL
) {
297 if (fptr
->file_map
== mptr
)
298 fptr
->file_map
= NULL
;
299 file_info_free(P
, fptr
);
301 if (P
->execname
&& mptr
== P
->map_exec
) {
305 if (P
->auxv
&& (mptr
== P
->map_exec
|| mptr
== P
->map_ldso
)) {
310 if (mptr
== P
->map_exec
)
312 if (mptr
== P
->map_ldso
)
317 * Call-back function for librtld_db to iterate through all of its shared
318 * libraries. We use this to get the load object names for the mappings.
321 map_iter(const rd_loadobj_t
*lop
, void *cd
)
324 struct ps_prochandle
*P
= cd
;
328 dprintf("encountered rd object at %p\n", (void *)lop
->rl_base
);
330 if ((mptr
= Paddr2mptr(P
, lop
->rl_base
)) == NULL
) {
331 dprintf("map_iter: base address doesn't match any mapping\n");
332 return (1); /* Base address does not match any mapping */
335 if ((fptr
= mptr
->map_file
) == NULL
&&
336 (fptr
= file_info_new(P
, mptr
)) == NULL
) {
337 dprintf("map_iter: failed to allocate a new file_info_t\n");
338 return (1); /* Failed to allocate a new file_info_t */
341 if ((fptr
->file_lo
== NULL
) &&
342 (fptr
->file_lo
= malloc(sizeof (rd_loadobj_t
))) == NULL
) {
343 dprintf("map_iter: failed to allocate rd_loadobj_t\n");
344 file_info_free(P
, fptr
);
345 return (1); /* Failed to allocate rd_loadobj_t */
348 fptr
->file_map
= mptr
;
349 *fptr
->file_lo
= *lop
;
351 fptr
->file_lo
->rl_plt_base
= fptr
->file_plt_base
;
352 fptr
->file_lo
->rl_plt_size
= fptr
->file_plt_size
;
354 if (fptr
->file_lname
) {
355 free(fptr
->file_lname
);
356 fptr
->file_lname
= NULL
;
357 fptr
->file_lbase
= NULL
;
359 if (fptr
->file_rname
) {
360 free(fptr
->file_rname
);
361 fptr
->file_rname
= NULL
;
362 fptr
->file_rbase
= NULL
;
365 if (Pread_string(P
, buf
, sizeof (buf
), lop
->rl_nameaddr
) > 0) {
366 if ((fptr
->file_lname
= strdup(buf
)) != NULL
)
367 fptr
->file_lbase
= basename(fptr
->file_lname
);
369 dprintf("map_iter: failed to read string at %p\n",
370 (void *)lop
->rl_nameaddr
);
373 if ((Pfindmap(P
, mptr
, buf
, sizeof (buf
)) != NULL
) &&
374 ((fptr
->file_rname
= strdup(buf
)) != NULL
))
375 fptr
->file_rbase
= basename(fptr
->file_rname
);
377 dprintf("loaded rd object %s lmid %lx\n",
378 fptr
->file_lname
? buf
: "<NULL>", lop
->rl_lmident
);
383 map_set(struct ps_prochandle
*P
, map_info_t
*mptr
, const char *lname
)
388 if ((fptr
= mptr
->map_file
) == NULL
&&
389 (fptr
= file_info_new(P
, mptr
)) == NULL
)
390 return; /* Failed to allocate a new file_info_t */
392 fptr
->file_map
= mptr
;
394 if ((fptr
->file_lo
== NULL
) &&
395 (fptr
->file_lo
= malloc(sizeof (rd_loadobj_t
))) == NULL
) {
396 file_info_free(P
, fptr
);
397 return; /* Failed to allocate rd_loadobj_t */
400 (void) memset(fptr
->file_lo
, 0, sizeof (rd_loadobj_t
));
401 fptr
->file_lo
->rl_base
= mptr
->map_pmap
.pr_vaddr
;
402 fptr
->file_lo
->rl_bend
=
403 mptr
->map_pmap
.pr_vaddr
+ mptr
->map_pmap
.pr_size
;
405 fptr
->file_lo
->rl_plt_base
= fptr
->file_plt_base
;
406 fptr
->file_lo
->rl_plt_size
= fptr
->file_plt_size
;
408 if ((fptr
->file_lname
== NULL
) &&
409 (fptr
->file_lname
= strdup(lname
)) != NULL
)
410 fptr
->file_lbase
= basename(fptr
->file_lname
);
412 if ((Pfindmap(P
, mptr
, buf
, sizeof (buf
)) != NULL
) &&
413 ((fptr
->file_rname
= strdup(buf
)) != NULL
))
414 fptr
->file_rbase
= basename(fptr
->file_rname
);
418 load_static_maps(struct ps_prochandle
*P
)
423 * Construct the map for the a.out.
425 if ((mptr
= object_name_to_map(P
, PR_LMID_EVERY
, PR_OBJ_EXEC
)) != NULL
)
426 map_set(P
, mptr
, "a.out");
429 * If the dynamic linker exists for this process,
430 * construct the map for it.
432 if (Pgetauxval(P
, AT_BASE
) != -1L &&
433 (mptr
= object_name_to_map(P
, PR_LMID_EVERY
, PR_OBJ_LDSO
)) != NULL
)
434 map_set(P
, mptr
, "ld.so.1");
438 Preadmaps(struct ps_prochandle
*P
, prmap_t
**Pmapp
, ssize_t
*nmapp
)
440 return (P
->ops
.pop_read_maps(P
, Pmapp
, nmapp
, P
->data
));
444 * Go through all the address space mappings, validating or updating
445 * the information already gathered, or gathering new information.
447 * This function is only called when we suspect that the mappings have changed
448 * because this is the first time we're calling it or because of rtld activity.
451 Pupdate_maps(struct ps_prochandle
*P
)
453 prmap_t
*Pmap
= NULL
;
458 map_info_t
*newmap
, *newp
;
461 if (P
->info_valid
|| P
->state
== PS_UNDEAD
)
466 if (Preadmaps(P
, &Pmap
, &nmap
) != 0)
469 if ((newmap
= calloc(1, nmap
* sizeof (map_info_t
))) == NULL
)
473 * We try to merge any file information we may have for existing
474 * mappings, to avoid having to rebuild the file info.
479 oldmapcount
= P
->map_count
;
480 for (i
= 0; i
< nmap
; i
++, pmap
++, newp
++) {
482 if (oldmapcount
== 0) {
484 * We've exhausted all the old mappings. Every new
485 * mapping should be added.
487 newp
->map_pmap
= *pmap
;
489 } else if (pmap
->pr_vaddr
== mptr
->map_pmap
.pr_vaddr
&&
490 pmap
->pr_size
== mptr
->map_pmap
.pr_size
&&
491 pmap
->pr_offset
== mptr
->map_pmap
.pr_offset
&&
492 (pmap
->pr_mflags
& ~(MA_BREAK
| MA_STACK
)) ==
493 (mptr
->map_pmap
.pr_mflags
& ~(MA_BREAK
| MA_STACK
)) &&
494 pmap
->pr_pagesize
== mptr
->map_pmap
.pr_pagesize
&&
495 pmap
->pr_shmid
== mptr
->map_pmap
.pr_shmid
&&
496 strcmp(pmap
->pr_mapname
, mptr
->map_pmap
.pr_mapname
) == 0) {
499 * This mapping matches exactly. Copy over the old
500 * mapping, taking care to get the latest flags.
501 * Make sure the associated file_info_t is updated
505 if (P
->map_exec
== mptr
)
507 if (P
->map_ldso
== mptr
)
509 newp
->map_pmap
.pr_mflags
= pmap
->pr_mflags
;
510 if (mptr
->map_file
!= NULL
&&
511 mptr
->map_file
->file_map
== mptr
)
512 mptr
->map_file
->file_map
= newp
;
516 } else if (pmap
->pr_vaddr
+ pmap
->pr_size
>
517 mptr
->map_pmap
.pr_vaddr
) {
520 * The old mapping doesn't exist any more, remove it
523 map_info_free(P
, mptr
);
533 * This is a new mapping, add it directly.
535 newp
->map_pmap
= *pmap
;
542 while (oldmapcount
) {
543 map_info_free(P
, mptr
);
549 if (P
->mappings
!= NULL
)
551 P
->mappings
= newmap
;
552 P
->map_count
= P
->map_alloc
= nmap
;
556 * Consult librtld_db to get the load object
557 * names for all of the shared libraries.
560 (void) rd_loadobj_iter(P
->rap
, map_iter
, P
);
564 * Update all of the mappings and rtld_db as if by Pupdate_maps(), and then
565 * forcibly cache all of the symbol tables associated with all object files.
568 Pupdate_syms(struct ps_prochandle
*P
)
575 for (i
= 0, fptr
= list_next(&P
->file_head
); i
< P
->num_files
;
576 i
++, fptr
= list_next(fptr
)) {
577 Pbuild_file_symtab(P
, fptr
);
578 (void) Pbuild_file_ctf(P
, fptr
);
583 * Return the librtld_db agent handle for the victim process.
584 * The handle will become invalid at the next successful exec() and the
585 * client (caller of proc_rd_agent()) must not use it beyond that point.
586 * If the process is already dead, we've already tried our best to
587 * create the agent during core file initialization.
590 Prd_agent(struct ps_prochandle
*P
)
592 if (P
->rap
== NULL
&& P
->state
!= PS_DEAD
&& P
->state
!= PS_IDLE
) {
594 if (P
->num_files
== 0)
596 rd_log(_libproc_debug
);
597 if ((P
->rap
= rd_new(P
)) != NULL
)
598 (void) rd_loadobj_iter(P
->rap
, map_iter
, P
);
604 * Return the prmap_t structure containing 'addr', but only if it
605 * is in the dynamic linker's link map and is the text section.
608 Paddr_to_text_map(struct ps_prochandle
*P
, uintptr_t addr
)
615 if ((mptr
= Paddr2mptr(P
, addr
)) != NULL
) {
616 file_info_t
*fptr
= build_map_symtab(P
, mptr
);
617 const prmap_t
*pmp
= &mptr
->map_pmap
;
620 * Assume that if rl_data_base is NULL, it means that no
621 * data section was found for this load object, and that
622 * a section must be text. Otherwise, a section will be
623 * text unless it ends above the start of the data
626 if (fptr
!= NULL
&& fptr
->file_lo
!= NULL
&&
627 (fptr
->file_lo
->rl_data_base
== NULL
||
628 pmp
->pr_vaddr
+ pmp
->pr_size
<=
629 fptr
->file_lo
->rl_data_base
))
637 * Return the prmap_t structure containing 'addr' (no restrictions on
638 * the type of mapping).
641 Paddr_to_map(struct ps_prochandle
*P
, uintptr_t addr
)
648 if ((mptr
= Paddr2mptr(P
, addr
)) != NULL
)
649 return (&mptr
->map_pmap
);
655 * Convert a full or partial load object name to the prmap_t for its
656 * corresponding primary text mapping.
659 Plmid_to_map(struct ps_prochandle
*P
, Lmid_t lmid
, const char *name
)
663 if (name
== PR_OBJ_EVERY
)
664 return (NULL
); /* A reasonable mistake */
666 if ((mptr
= object_name_to_map(P
, lmid
, name
)) != NULL
)
667 return (&mptr
->map_pmap
);
673 Pname_to_map(struct ps_prochandle
*P
, const char *name
)
675 return (Plmid_to_map(P
, PR_LMID_EVERY
, name
));
679 Paddr_to_loadobj(struct ps_prochandle
*P
, uintptr_t addr
)
686 if ((mptr
= Paddr2mptr(P
, addr
)) == NULL
)
690 * By building the symbol table, we implicitly bring the PLT
691 * information up to date in the load object.
693 (void) build_map_symtab(P
, mptr
);
695 return (mptr
->map_file
->file_lo
);
699 Plmid_to_loadobj(struct ps_prochandle
*P
, Lmid_t lmid
, const char *name
)
703 if (name
== PR_OBJ_EVERY
)
706 if ((mptr
= object_name_to_map(P
, lmid
, name
)) == NULL
)
710 * By building the symbol table, we implicitly bring the PLT
711 * information up to date in the load object.
713 (void) build_map_symtab(P
, mptr
);
715 return (mptr
->map_file
->file_lo
);
719 Pname_to_loadobj(struct ps_prochandle
*P
, const char *name
)
721 return (Plmid_to_loadobj(P
, PR_LMID_EVERY
, name
));
725 Pbuild_file_ctf(struct ps_prochandle
*P
, file_info_t
*fptr
)
727 ctf_sect_t ctdata
, symtab
, strtab
;
731 if (fptr
->file_ctfp
!= NULL
)
732 return (fptr
->file_ctfp
);
734 Pbuild_file_symtab(P
, fptr
);
736 if (fptr
->file_ctf_size
== 0)
739 symp
= fptr
->file_ctf_dyn
? &fptr
->file_dynsym
: &fptr
->file_symtab
;
740 if (symp
->sym_data_pri
== NULL
)
744 * The buffer may alread be allocated if this is a core file that
745 * contained CTF data for this file.
747 if (fptr
->file_ctf_buf
== NULL
) {
748 fptr
->file_ctf_buf
= malloc(fptr
->file_ctf_size
);
749 if (fptr
->file_ctf_buf
== NULL
) {
750 dprintf("failed to allocate ctf buffer\n");
754 if (pread(fptr
->file_fd
, fptr
->file_ctf_buf
,
755 fptr
->file_ctf_size
, fptr
->file_ctf_off
) !=
756 fptr
->file_ctf_size
) {
757 free(fptr
->file_ctf_buf
);
758 fptr
->file_ctf_buf
= NULL
;
759 dprintf("failed to read ctf data\n");
764 ctdata
.cts_name
= ".SUNW_ctf";
765 ctdata
.cts_type
= SHT_PROGBITS
;
766 ctdata
.cts_flags
= 0;
767 ctdata
.cts_data
= fptr
->file_ctf_buf
;
768 ctdata
.cts_size
= fptr
->file_ctf_size
;
769 ctdata
.cts_entsize
= 1;
770 ctdata
.cts_offset
= 0;
772 symtab
.cts_name
= fptr
->file_ctf_dyn
? ".dynsym" : ".symtab";
773 symtab
.cts_type
= symp
->sym_hdr_pri
.sh_type
;
774 symtab
.cts_flags
= symp
->sym_hdr_pri
.sh_flags
;
775 symtab
.cts_data
= symp
->sym_data_pri
->d_buf
;
776 symtab
.cts_size
= symp
->sym_hdr_pri
.sh_size
;
777 symtab
.cts_entsize
= symp
->sym_hdr_pri
.sh_entsize
;
778 symtab
.cts_offset
= symp
->sym_hdr_pri
.sh_offset
;
780 strtab
.cts_name
= fptr
->file_ctf_dyn
? ".dynstr" : ".strtab";
781 strtab
.cts_type
= symp
->sym_strhdr
.sh_type
;
782 strtab
.cts_flags
= symp
->sym_strhdr
.sh_flags
;
783 strtab
.cts_data
= symp
->sym_strs
;
784 strtab
.cts_size
= symp
->sym_strhdr
.sh_size
;
785 strtab
.cts_entsize
= symp
->sym_strhdr
.sh_entsize
;
786 strtab
.cts_offset
= symp
->sym_strhdr
.sh_offset
;
788 fptr
->file_ctfp
= ctf_bufopen(&ctdata
, &symtab
, &strtab
, &err
);
789 if (fptr
->file_ctfp
== NULL
) {
790 dprintf("ctf_bufopen() failed, error code %d\n", err
);
791 free(fptr
->file_ctf_buf
);
792 fptr
->file_ctf_buf
= NULL
;
796 dprintf("loaded %lu bytes of CTF data for %s\n",
797 (ulong_t
)fptr
->file_ctf_size
, fptr
->file_pname
);
799 return (fptr
->file_ctfp
);
803 Paddr_to_ctf(struct ps_prochandle
*P
, uintptr_t addr
)
811 if ((mptr
= Paddr2mptr(P
, addr
)) == NULL
||
812 (fptr
= mptr
->map_file
) == NULL
)
815 return (Pbuild_file_ctf(P
, fptr
));
819 Plmid_to_ctf(struct ps_prochandle
*P
, Lmid_t lmid
, const char *name
)
824 if (name
== PR_OBJ_EVERY
)
827 if ((mptr
= object_name_to_map(P
, lmid
, name
)) == NULL
||
828 (fptr
= mptr
->map_file
) == NULL
)
831 return (Pbuild_file_ctf(P
, fptr
));
835 Pname_to_ctf(struct ps_prochandle
*P
, const char *name
)
837 return (Plmid_to_ctf(P
, PR_LMID_EVERY
, name
));
841 Preadauxvec(struct ps_prochandle
*P
)
843 if (P
->auxv
!= NULL
) {
849 P
->ops
.pop_read_aux(P
, &P
->auxv
, &P
->nauxv
, P
->data
);
853 * Return a requested element from the process's aux vector.
854 * Return -1 on failure (this is adequate for our purposes).
857 Pgetauxval(struct ps_prochandle
*P
, int type
)
867 for (auxv
= P
->auxv
; auxv
->a_type
!= AT_NULL
; auxv
++) {
868 if (auxv
->a_type
== type
)
869 return (auxv
->a_un
.a_val
);
876 * Return a pointer to our internal copy of the process's aux vector.
877 * The caller should not hold on to this pointer across any libproc calls.
880 Pgetauxvec(struct ps_prochandle
*P
)
882 static const auxv_t empty
= { AT_NULL
, 0L };
894 * Return 1 if the given mapping corresponds to the given file_info_t's
895 * load object; return 0 otherwise.
898 is_mapping_in_file(struct ps_prochandle
*P
, map_info_t
*mptr
, file_info_t
*fptr
)
900 prmap_t
*pmap
= &mptr
->map_pmap
;
901 rd_loadobj_t
*lop
= fptr
->file_lo
;
903 uintptr_t mstart
, mend
, sstart
, send
;
906 * We can get for free the start address of the text and data
907 * sections of the load object. Start by seeing if the mapping
908 * encloses either of these.
910 if ((pmap
->pr_vaddr
<= lop
->rl_base
&&
911 lop
->rl_base
< pmap
->pr_vaddr
+ pmap
->pr_size
) ||
912 (pmap
->pr_vaddr
<= lop
->rl_data_base
&&
913 lop
->rl_data_base
< pmap
->pr_vaddr
+ pmap
->pr_size
))
917 * It's still possible that this mapping correponds to the load
918 * object. Consider the example of a mapping whose start and end
919 * addresses correspond to those of the load object's text section.
920 * If the mapping splits, e.g. as a result of a segment demotion,
921 * then although both mappings are still backed by the same section,
922 * only one will be seen to enclose that section's start address.
923 * Thus, to be rigorous, we ask not whether this mapping encloses
924 * the start of a section, but whether there exists a section that
925 * overlaps this mapping.
927 * If we don't already have the section addresses, and we successfully
928 * get them, then we cache them in case we come here again.
930 if (fptr
->file_saddrs
== NULL
&&
931 (fptr
->file_saddrs
= get_saddrs(P
,
932 fptr
->file_map
->map_pmap
.pr_vaddr
, &fptr
->file_nsaddrs
)) == NULL
)
935 mstart
= mptr
->map_pmap
.pr_vaddr
;
936 mend
= mptr
->map_pmap
.pr_vaddr
+ mptr
->map_pmap
.pr_size
;
937 for (i
= 0; i
< fptr
->file_nsaddrs
; i
+= 2) {
938 /* Does this section overlap the mapping? */
939 sstart
= fptr
->file_saddrs
[i
];
940 send
= fptr
->file_saddrs
[i
+ 1];
941 if (!(mend
<= sstart
|| mstart
>= send
))
949 * Find or build the symbol table for the given mapping.
952 build_map_symtab(struct ps_prochandle
*P
, map_info_t
*mptr
)
954 prmap_t
*pmap
= &mptr
->map_pmap
;
958 if ((fptr
= mptr
->map_file
) != NULL
) {
959 Pbuild_file_symtab(P
, fptr
);
963 if (pmap
->pr_mapname
[0] == '\0')
967 * Attempt to find a matching file.
968 * (A file can be mapped at several different addresses.)
970 for (i
= 0, fptr
= list_next(&P
->file_head
); i
< P
->num_files
;
971 i
++, fptr
= list_next(fptr
)) {
972 if (strcmp(fptr
->file_pname
, pmap
->pr_mapname
) == 0 &&
973 fptr
->file_lo
&& is_mapping_in_file(P
, mptr
, fptr
)) {
974 mptr
->map_file
= fptr
;
976 Pbuild_file_symtab(P
, fptr
);
982 * If we need to create a new file_info structure, iterate
983 * through the load objects in order to attempt to connect
984 * this new file with its primary text mapping. We again
985 * need to handle ld.so as a special case because we need
986 * to be able to bootstrap librtld_db.
988 if ((fptr
= file_info_new(P
, mptr
)) == NULL
)
991 if (P
->map_ldso
!= mptr
) {
993 (void) rd_loadobj_iter(P
->rap
, map_iter
, P
);
997 fptr
->file_map
= mptr
;
1001 * If librtld_db wasn't able to help us connect the file to a primary
1002 * text mapping, set file_map to the current mapping because we require
1003 * fptr->file_map to be set in Pbuild_file_symtab. librtld_db may be
1004 * unaware of what's going on in the rare case that a legitimate ELF
1005 * file has been mmap(2)ed into the process address space *without*
1006 * the use of dlopen(3x).
1008 if (fptr
->file_map
== NULL
)
1009 fptr
->file_map
= mptr
;
1011 Pbuild_file_symtab(P
, fptr
);
1017 read_ehdr32(struct ps_prochandle
*P
, Elf32_Ehdr
*ehdr
, uint_t
*phnum
,
1020 if (Pread(P
, ehdr
, sizeof (*ehdr
), addr
) != sizeof (*ehdr
))
1023 if (ehdr
->e_ident
[EI_MAG0
] != ELFMAG0
||
1024 ehdr
->e_ident
[EI_MAG1
] != ELFMAG1
||
1025 ehdr
->e_ident
[EI_MAG2
] != ELFMAG2
||
1026 ehdr
->e_ident
[EI_MAG3
] != ELFMAG3
||
1027 ehdr
->e_ident
[EI_CLASS
] != ELFCLASS32
||
1029 ehdr
->e_ident
[EI_DATA
] != ELFDATA2MSB
||
1031 ehdr
->e_ident
[EI_DATA
] != ELFDATA2LSB
||
1033 ehdr
->e_ident
[EI_VERSION
] != EV_CURRENT
)
1036 if ((*phnum
= ehdr
->e_phnum
) == PN_XNUM
) {
1039 if (ehdr
->e_shoff
== 0 || ehdr
->e_shentsize
< sizeof (shdr0
) ||
1040 Pread(P
, &shdr0
, sizeof (shdr0
), addr
+ ehdr
->e_shoff
) !=
1044 if (shdr0
.sh_info
!= 0)
1045 *phnum
= shdr0
.sh_info
;
1052 read_dynamic_phdr32(struct ps_prochandle
*P
, const Elf32_Ehdr
*ehdr
,
1053 uint_t phnum
, Elf32_Phdr
*phdr
, uintptr_t addr
)
1057 for (i
= 0; i
< phnum
; i
++) {
1058 uintptr_t a
= addr
+ ehdr
->e_phoff
+ i
* ehdr
->e_phentsize
;
1059 if (Pread(P
, phdr
, sizeof (*phdr
), a
) != sizeof (*phdr
))
1062 if (phdr
->p_type
== PT_DYNAMIC
)
1071 read_ehdr64(struct ps_prochandle
*P
, Elf64_Ehdr
*ehdr
, uint_t
*phnum
,
1074 if (Pread(P
, ehdr
, sizeof (Elf64_Ehdr
), addr
) != sizeof (Elf64_Ehdr
))
1077 if (ehdr
->e_ident
[EI_MAG0
] != ELFMAG0
||
1078 ehdr
->e_ident
[EI_MAG1
] != ELFMAG1
||
1079 ehdr
->e_ident
[EI_MAG2
] != ELFMAG2
||
1080 ehdr
->e_ident
[EI_MAG3
] != ELFMAG3
||
1081 ehdr
->e_ident
[EI_CLASS
] != ELFCLASS64
||
1083 ehdr
->e_ident
[EI_DATA
] != ELFDATA2MSB
||
1085 ehdr
->e_ident
[EI_DATA
] != ELFDATA2LSB
||
1087 ehdr
->e_ident
[EI_VERSION
] != EV_CURRENT
)
1090 if ((*phnum
= ehdr
->e_phnum
) == PN_XNUM
) {
1093 if (ehdr
->e_shoff
== 0 || ehdr
->e_shentsize
< sizeof (shdr0
) ||
1094 Pread(P
, &shdr0
, sizeof (shdr0
), addr
+ ehdr
->e_shoff
) !=
1098 if (shdr0
.sh_info
!= 0)
1099 *phnum
= shdr0
.sh_info
;
1106 read_dynamic_phdr64(struct ps_prochandle
*P
, const Elf64_Ehdr
*ehdr
,
1107 uint_t phnum
, Elf64_Phdr
*phdr
, uintptr_t addr
)
1111 for (i
= 0; i
< phnum
; i
++) {
1112 uintptr_t a
= addr
+ ehdr
->e_phoff
+ i
* ehdr
->e_phentsize
;
1113 if (Pread(P
, phdr
, sizeof (*phdr
), a
) != sizeof (*phdr
))
1116 if (phdr
->p_type
== PT_DYNAMIC
)
1125 * The text segment for each load object contains the elf header and
1126 * program headers. We can use this information to determine if the
1127 * file that corresponds to the load object is the same file that
1128 * was loaded into the process's address space. There can be a discrepency
1129 * if a file is recompiled after the process is started or if the target
1130 * represents a core file from a differently configured system -- two
1131 * common examples. The DT_CHECKSUM entry in the dynamic section
1132 * provides an easy method of comparison. It is important to note that
1133 * the dynamic section usually lives in the data segment, but the meta
1134 * data we use to find the dynamic section lives in the text segment so
1135 * if either of those segments is absent we can't proceed.
1137 * We're looking through the elf file for several items: the symbol tables
1138 * (both dynsym and symtab), the procedure linkage table (PLT) base,
1139 * size, and relocation base, and the CTF information. Most of this can
1140 * be recovered from the loaded image of the file itself, the exceptions
1141 * being the symtab and CTF data.
1143 * First we try to open the file that we think corresponds to the load
1144 * object, if the DT_CHECKSUM values match, we're all set, and can simply
1145 * recover all the information we need from the file. If the values of
1146 * DT_CHECKSUM don't match, or if we can't access the file for whatever
1147 * reasaon, we fake up a elf file to use in its stead. If we can't read
1148 * the elf data in the process's address space, we fall back to using
1149 * the file even though it may give inaccurate information.
1151 * The elf file that we fake up has to consist of sections for the
1152 * dynsym, the PLT and the dynamic section. Note that in the case of a
1153 * core file, we'll get the CTF data in the file_info_t later on from
1154 * a section embedded the core file (if it's present).
1156 * file_differs() conservatively looks for mismatched files, identifying
1157 * a match when there is any ambiguity (since that's the legacy behavior).
1160 file_differs(struct ps_prochandle
*P
, Elf
*elf
, file_info_t
*fptr
)
1170 if (fptr
->file_map
== NULL
)
1173 if ((Pcontent(P
) & (CC_CONTENT_TEXT
| CC_CONTENT_DATA
)) !=
1174 (CC_CONTENT_TEXT
| CC_CONTENT_DATA
))
1178 * First, we find the checksum value in the elf file.
1181 while ((scn
= elf_nextscn(elf
, scn
)) != NULL
) {
1182 if (gelf_getshdr(scn
, &shdr
) != NULL
&&
1183 shdr
.sh_type
== SHT_DYNAMIC
)
1189 if ((data
= elf_getdata(scn
, NULL
)) == NULL
)
1192 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
)
1193 ndyn
= shdr
.sh_size
/ sizeof (Elf32_Dyn
);
1195 else if (P
->status
.pr_dmodel
== PR_MODEL_LP64
)
1196 ndyn
= shdr
.sh_size
/ sizeof (Elf64_Dyn
);
1201 for (i
= 0; i
< ndyn
; i
++) {
1202 if (gelf_getdyn(data
, i
, &dyn
) != NULL
&&
1203 dyn
.d_tag
== DT_CHECKSUM
)
1208 * The in-memory ELF has no DT_CHECKSUM section, but we will report it
1209 * as matching the file anyhow.
1214 cksum
= dyn
.d_un
.d_val
;
1215 dprintf("elf cksum value is %llx\n", (u_longlong_t
)cksum
);
1218 * Get the base of the text mapping that corresponds to this file.
1220 addr
= fptr
->file_map
->map_pmap
.pr_vaddr
;
1222 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
1225 Elf32_Dyn dync
, *dynp
;
1228 if (read_ehdr32(P
, &ehdr
, &phnum
, addr
) != 0 ||
1229 read_dynamic_phdr32(P
, &ehdr
, phnum
, &phdr
, addr
) != 0)
1232 if (ehdr
.e_type
== ET_DYN
)
1233 phdr
.p_vaddr
+= addr
;
1234 if ((dynp
= malloc(phdr
.p_filesz
)) == NULL
)
1236 dync
.d_tag
= DT_NULL
;
1237 if (Pread(P
, dynp
, phdr
.p_filesz
, phdr
.p_vaddr
) !=
1243 for (i
= 0; i
< phdr
.p_filesz
/ sizeof (Elf32_Dyn
); i
++) {
1244 if (dynp
[i
].d_tag
== DT_CHECKSUM
)
1250 if (dync
.d_tag
!= DT_CHECKSUM
)
1253 dprintf("image cksum value is %llx\n",
1254 (u_longlong_t
)dync
.d_un
.d_val
);
1255 return (dync
.d_un
.d_val
!= cksum
);
1257 } else if (P
->status
.pr_dmodel
== PR_MODEL_LP64
) {
1260 Elf64_Dyn dync
, *dynp
;
1263 if (read_ehdr64(P
, &ehdr
, &phnum
, addr
) != 0 ||
1264 read_dynamic_phdr64(P
, &ehdr
, phnum
, &phdr
, addr
) != 0)
1267 if (ehdr
.e_type
== ET_DYN
)
1268 phdr
.p_vaddr
+= addr
;
1269 if ((dynp
= malloc(phdr
.p_filesz
)) == NULL
)
1271 dync
.d_tag
= DT_NULL
;
1272 if (Pread(P
, dynp
, phdr
.p_filesz
, phdr
.p_vaddr
) !=
1278 for (i
= 0; i
< phdr
.p_filesz
/ sizeof (Elf64_Dyn
); i
++) {
1279 if (dynp
[i
].d_tag
== DT_CHECKSUM
)
1285 if (dync
.d_tag
!= DT_CHECKSUM
)
1288 dprintf("image cksum value is %llx\n",
1289 (u_longlong_t
)dync
.d_un
.d_val
);
1290 return (dync
.d_un
.d_val
!= cksum
);
1298 * Read data from the specified process and construct an in memory
1299 * image of an ELF file that represents it well enough to let
1300 * us probe it for information.
1303 fake_elf(struct ps_prochandle
*P
, file_info_t
*fptr
)
1309 if (fptr
->file_map
== NULL
)
1312 if ((Pcontent(P
) & (CC_CONTENT_TEXT
| CC_CONTENT_DATA
)) !=
1313 (CC_CONTENT_TEXT
| CC_CONTENT_DATA
))
1316 addr
= fptr
->file_map
->map_pmap
.pr_vaddr
;
1318 if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
1322 if ((read_ehdr32(P
, &ehdr
, &phnum
, addr
) != 0) ||
1323 read_dynamic_phdr32(P
, &ehdr
, phnum
, &phdr
, addr
) != 0)
1326 elf
= fake_elf32(P
, fptr
, addr
, &ehdr
, phnum
, &phdr
);
1332 if (read_ehdr64(P
, &ehdr
, &phnum
, addr
) != 0 ||
1333 read_dynamic_phdr64(P
, &ehdr
, phnum
, &phdr
, addr
) != 0)
1336 elf
= fake_elf64(P
, fptr
, addr
, &ehdr
, phnum
, &phdr
);
1344 * We wouldn't need these if qsort(3C) took an argument for the callback...
1346 static mutex_t sort_mtx
= DEFAULTMUTEX
;
1347 static char *sort_strs
;
1348 static GElf_Sym
*sort_syms
;
1351 byaddr_cmp_common(GElf_Sym
*a
, char *aname
, GElf_Sym
*b
, char *bname
)
1353 if (a
->st_value
< b
->st_value
)
1355 if (a
->st_value
> b
->st_value
)
1359 * Prefer the function to the non-function.
1361 if (GELF_ST_TYPE(a
->st_info
) != GELF_ST_TYPE(b
->st_info
)) {
1362 if (GELF_ST_TYPE(a
->st_info
) == STT_FUNC
)
1364 if (GELF_ST_TYPE(b
->st_info
) == STT_FUNC
)
1369 * Prefer the weak or strong global symbol to the local symbol.
1371 if (GELF_ST_BIND(a
->st_info
) != GELF_ST_BIND(b
->st_info
)) {
1372 if (GELF_ST_BIND(b
->st_info
) == STB_LOCAL
)
1374 if (GELF_ST_BIND(a
->st_info
) == STB_LOCAL
)
1379 * Prefer the symbol that doesn't begin with a '$' since compilers and
1380 * other symbol generators often use it as a prefix.
1388 * Prefer the name with fewer leading underscores in the name.
1390 while (*aname
== '_' && *bname
== '_') {
1401 * Prefer the symbol with the smaller size.
1403 if (a
->st_size
< b
->st_size
)
1405 if (a
->st_size
> b
->st_size
)
1409 * All other factors being equal, fall back to lexicographic order.
1411 return (strcmp(aname
, bname
));
1415 byaddr_cmp(const void *aa
, const void *bb
)
1417 GElf_Sym
*a
= &sort_syms
[*(uint_t
*)aa
];
1418 GElf_Sym
*b
= &sort_syms
[*(uint_t
*)bb
];
1419 char *aname
= sort_strs
+ a
->st_name
;
1420 char *bname
= sort_strs
+ b
->st_name
;
1422 return (byaddr_cmp_common(a
, aname
, b
, bname
));
1426 byname_cmp(const void *aa
, const void *bb
)
1428 GElf_Sym
*a
= &sort_syms
[*(uint_t
*)aa
];
1429 GElf_Sym
*b
= &sort_syms
[*(uint_t
*)bb
];
1430 char *aname
= sort_strs
+ a
->st_name
;
1431 char *bname
= sort_strs
+ b
->st_name
;
1433 return (strcmp(aname
, bname
));
1437 * Given a symbol index, look up the corresponding symbol from the
1438 * given symbol table.
1440 * This function allows the caller to treat the symbol table as a single
1441 * logical entity even though there may be 2 actual ELF symbol tables
1442 * involved. See the comments in Pcontrol.h for details.
1445 symtab_getsym(sym_tbl_t
*symtab
, int ndx
, GElf_Sym
*dst
)
1447 /* If index is in range of primary symtab, look it up there */
1448 if (ndx
>= symtab
->sym_symn_aux
) {
1449 return (gelf_getsym(symtab
->sym_data_pri
,
1450 ndx
- symtab
->sym_symn_aux
, dst
));
1453 /* Not in primary: Look it up in the auxiliary symtab */
1454 return (gelf_getsym(symtab
->sym_data_aux
, ndx
, dst
));
1458 optimize_symtab(sym_tbl_t
*symtab
)
1460 GElf_Sym
*symp
, *syms
;
1461 uint_t i
, *indexa
, *indexb
;
1462 size_t symn
, strsz
, count
;
1464 if (symtab
== NULL
|| symtab
->sym_data_pri
== NULL
||
1465 symtab
->sym_byaddr
!= NULL
)
1468 symn
= symtab
->sym_symn
;
1469 strsz
= symtab
->sym_strsz
;
1471 symp
= syms
= malloc(sizeof (GElf_Sym
) * symn
);
1473 dprintf("optimize_symtab: failed to malloc symbol array");
1478 * First record all the symbols into a table and count up the ones
1479 * that we're interested in. We mark symbols as invalid by setting
1480 * the st_name to an illegal value.
1482 for (i
= 0, count
= 0; i
< symn
; i
++, symp
++) {
1483 if (symtab_getsym(symtab
, i
, symp
) != NULL
&&
1484 symp
->st_name
< strsz
&&
1485 IS_DATA_TYPE(GELF_ST_TYPE(symp
->st_info
)))
1488 symp
->st_name
= strsz
;
1492 * Allocate sufficient space for both tables and populate them
1493 * with the same symbols we just counted.
1495 symtab
->sym_count
= count
;
1496 indexa
= symtab
->sym_byaddr
= calloc(sizeof (uint_t
), count
);
1497 indexb
= symtab
->sym_byname
= calloc(sizeof (uint_t
), count
);
1498 if (indexa
== NULL
|| indexb
== NULL
) {
1500 "optimize_symtab: failed to malloc symbol index arrays");
1501 symtab
->sym_count
= 0;
1502 if (indexa
!= NULL
) { /* First alloc succeeded. Free it */
1504 symtab
->sym_byaddr
= NULL
;
1509 for (i
= 0, symp
= syms
; i
< symn
; i
++, symp
++) {
1510 if (symp
->st_name
< strsz
)
1511 *indexa
++ = *indexb
++ = i
;
1515 * Sort the two tables according to the appropriate criteria,
1516 * unless the user has overridden this behaviour.
1518 * An example where we might not sort the tables is the relatively
1519 * unusual case of a process with very large symbol tables in which
1520 * we perform few lookups. In such a case the total time would be
1521 * dominated by the sort. It is difficult to determine a priori
1522 * how many lookups an arbitrary client will perform, and
1523 * hence whether the symbol tables should be sorted. We therefore
1524 * sort the tables by default, but provide the user with a
1525 * "chicken switch" in the form of the LIBPROC_NO_QSORT
1526 * environment variable.
1528 if (!_libproc_no_qsort
) {
1529 (void) mutex_lock(&sort_mtx
);
1530 sort_strs
= symtab
->sym_strs
;
1533 qsort(symtab
->sym_byaddr
, count
, sizeof (uint_t
), byaddr_cmp
);
1534 qsort(symtab
->sym_byname
, count
, sizeof (uint_t
), byname_cmp
);
1538 (void) mutex_unlock(&sort_mtx
);
1546 build_fake_elf(struct ps_prochandle
*P
, file_info_t
*fptr
, GElf_Ehdr
*ehdr
,
1547 size_t *nshdrs
, Elf_Data
**shdata
)
1553 if ((elf
= fake_elf(P
, fptr
)) == NULL
||
1554 elf_kind(elf
) != ELF_K_ELF
||
1555 gelf_getehdr(elf
, ehdr
) == NULL
||
1556 elf_getshdrnum(elf
, nshdrs
) == -1 ||
1557 elf_getshdrstrndx(elf
, &shstrndx
) == -1 ||
1558 (scn
= elf_getscn(elf
, shstrndx
)) == NULL
||
1559 (*shdata
= elf_getdata(scn
, NULL
)) == NULL
) {
1561 (void) elf_end(elf
);
1562 dprintf("failed to fake up ELF file\n");
1570 * Build the symbol table for the given mapped file.
1573 Pbuild_file_symtab(struct ps_prochandle
*P
, file_info_t
*fptr
)
1575 char objectfile
[PATH_MAX
];
1584 size_t nshdrs
, shstrndx
;
1590 } *cp
, *cache
= NULL
, *dyn
= NULL
, *plt
= NULL
, *ctf
= NULL
;
1592 if (fptr
->file_init
)
1593 return; /* We've already processed this file */
1596 * Mark the file_info struct as having the symbol table initialized
1597 * even if we fail below. We tried once; we don't try again.
1599 fptr
->file_init
= 1;
1601 if (elf_version(EV_CURRENT
) == EV_NONE
) {
1602 dprintf("libproc ELF version is more recent than libelf\n");
1606 if (P
->state
== PS_DEAD
|| P
->state
== PS_IDLE
) {
1609 * If we're a not live, we can't open files from the /proc
1610 * object directory; we have only the mapping and file names
1611 * to guide us. We prefer the file_lname, but need to handle
1612 * the case of it being NULL in order to bootstrap: we first
1613 * come here during rd_new() when the only information we have
1614 * is interpreter name associated with the AT_BASE mapping.
1616 * Also, if the zone associated with the core file seems
1617 * to exists on this machine we'll try to open the object
1618 * file within the zone.
1620 if (fptr
->file_rname
!= NULL
)
1621 name
= fptr
->file_rname
;
1622 else if (fptr
->file_lname
!= NULL
)
1623 name
= fptr
->file_lname
;
1625 name
= fptr
->file_pname
;
1626 (void) strlcpy(objectfile
, name
, sizeof (objectfile
));
1628 (void) snprintf(objectfile
, sizeof (objectfile
),
1630 procfs_path
, (int)P
->pid
, fptr
->file_pname
);
1634 * Open the object file, create the elf file, and then get the elf
1635 * header and .shstrtab data buffer so we can process sections by
1636 * name. If anything goes wrong try to fake up an elf file from
1637 * the in-core elf image.
1640 if (_libproc_incore_elf
|| (P
->flags
& INCORE
)) {
1641 dprintf("Pbuild_file_symtab: using in-core data for: %s\n",
1644 if ((elf
= build_fake_elf(P
, fptr
, &ehdr
, &nshdrs
, &shdata
)) ==
1648 } else if ((fptr
->file_fd
= open(objectfile
, O_RDONLY
)) < 0) {
1649 dprintf("Pbuild_file_symtab: failed to open %s: %s\n",
1650 objectfile
, strerror(errno
));
1652 if ((elf
= build_fake_elf(P
, fptr
, &ehdr
, &nshdrs
, &shdata
)) ==
1656 } else if ((elf
= elf_begin(fptr
->file_fd
, ELF_C_READ
, NULL
)) == NULL
||
1657 elf_kind(elf
) != ELF_K_ELF
||
1658 gelf_getehdr(elf
, &ehdr
) == NULL
||
1659 elf_getshdrnum(elf
, &nshdrs
) == -1 ||
1660 elf_getshdrstrndx(elf
, &shstrndx
) == -1 ||
1661 (scn
= elf_getscn(elf
, shstrndx
)) == NULL
||
1662 (shdata
= elf_getdata(scn
, NULL
)) == NULL
) {
1663 int err
= elf_errno();
1665 dprintf("failed to process ELF file %s: %s\n",
1666 objectfile
, (err
== 0) ? "<null>" : elf_errmsg(err
));
1667 (void) elf_end(elf
);
1669 if ((elf
= build_fake_elf(P
, fptr
, &ehdr
, &nshdrs
, &shdata
)) ==
1673 } else if (file_differs(P
, elf
, fptr
)) {
1677 * Before we get too excited about this elf file, we'll check
1678 * its checksum value against the value we have in memory. If
1679 * they don't agree, we try to fake up a new elf file and
1680 * proceed with that instead.
1682 dprintf("ELF file %s (%lx) doesn't match in-core image\n",
1684 (ulong_t
)fptr
->file_map
->map_pmap
.pr_vaddr
);
1686 if ((newelf
= build_fake_elf(P
, fptr
, &ehdr
, &nshdrs
, &shdata
))
1688 (void) elf_end(elf
);
1690 dprintf("switched to faked up ELF file\n");
1693 * Check to see if the file that we just discovered
1694 * to be an imposter matches the execname that was
1695 * determined by Pfindexec(). If it does, we (clearly)
1696 * don't have the right binary, and we zero out
1697 * execname before anyone gets hurt.
1699 if (fptr
->file_rname
!= NULL
&& P
->execname
!= NULL
&&
1700 strcmp(fptr
->file_rname
, P
->execname
) == 0) {
1701 dprintf("file/in-core image mismatch was "
1702 "on P->execname; discarding\n");
1709 if ((cache
= malloc(nshdrs
* sizeof (*cache
))) == NULL
) {
1710 dprintf("failed to malloc section cache for %s\n", objectfile
);
1714 dprintf("processing ELF file %s\n", objectfile
);
1715 fptr
->file_class
= ehdr
.e_ident
[EI_CLASS
];
1716 fptr
->file_etype
= ehdr
.e_type
;
1717 fptr
->file_elf
= elf
;
1718 fptr
->file_shstrs
= shdata
->d_buf
;
1719 fptr
->file_shstrsz
= shdata
->d_size
;
1722 * Iterate through each section, caching its section header, data
1723 * pointer, and name. We use this for handling sh_link values below.
1725 for (cp
= cache
+ 1, scn
= NULL
; scn
= elf_nextscn(elf
, scn
); cp
++) {
1726 if (gelf_getshdr(scn
, &cp
->c_shdr
) == NULL
) {
1727 dprintf("Pbuild_file_symtab: Failed to get section "
1729 goto bad
; /* Failed to get section header */
1732 if ((cp
->c_data
= elf_getdata(scn
, NULL
)) == NULL
) {
1733 dprintf("Pbuild_file_symtab: Failed to get section "
1735 goto bad
; /* Failed to get section data */
1738 if (cp
->c_shdr
.sh_name
>= shdata
->d_size
) {
1739 dprintf("Pbuild_file_symtab: corrupt section name");
1740 goto bad
; /* Corrupt section name */
1743 cp
->c_name
= (const char *)shdata
->d_buf
+ cp
->c_shdr
.sh_name
;
1747 * Now iterate through the section cache in order to locate info
1748 * for the .symtab, .dynsym, .SUNW_ldynsym, .dynamic, .plt,
1749 * and .SUNW_ctf sections:
1751 for (i
= 1, cp
= cache
+ 1; i
< nshdrs
; i
++, cp
++) {
1752 GElf_Shdr
*shp
= &cp
->c_shdr
;
1754 if (shp
->sh_type
== SHT_SYMTAB
|| shp
->sh_type
== SHT_DYNSYM
) {
1755 sym_tbl_t
*symp
= shp
->sh_type
== SHT_SYMTAB
?
1756 &fptr
->file_symtab
: &fptr
->file_dynsym
;
1758 * It's possible that the we already got the symbol
1759 * table from the core file itself. Either the file
1760 * differs in which case our faked up elf file will
1761 * only contain the dynsym (not the symtab) or the
1762 * file matches in which case we'll just be replacing
1763 * the symbol table we pulled out of the core file
1764 * with an equivalent one. In either case, this
1765 * check isn't essential, but it's a good idea.
1767 if (symp
->sym_data_pri
== NULL
) {
1768 dprintf("Symbol table found for %s\n",
1770 symp
->sym_data_pri
= cp
->c_data
;
1772 shp
->sh_size
/ shp
->sh_entsize
;
1774 cache
[shp
->sh_link
].c_data
->d_buf
;
1776 cache
[shp
->sh_link
].c_data
->d_size
;
1777 symp
->sym_hdr_pri
= cp
->c_shdr
;
1778 symp
->sym_strhdr
= cache
[shp
->sh_link
].c_shdr
;
1780 dprintf("Symbol table already there for %s\n",
1783 } else if (shp
->sh_type
== SHT_SUNW_LDYNSYM
) {
1784 /* .SUNW_ldynsym section is auxiliary to .dynsym */
1785 if (fptr
->file_dynsym
.sym_data_aux
== NULL
) {
1786 dprintf(".SUNW_ldynsym symbol table"
1787 " found for %s\n", objectfile
);
1788 fptr
->file_dynsym
.sym_data_aux
= cp
->c_data
;
1789 fptr
->file_dynsym
.sym_symn_aux
=
1790 shp
->sh_size
/ shp
->sh_entsize
;
1791 fptr
->file_dynsym
.sym_symn
+=
1792 fptr
->file_dynsym
.sym_symn_aux
;
1793 fptr
->file_dynsym
.sym_hdr_aux
= cp
->c_shdr
;
1795 dprintf(".SUNW_ldynsym symbol table already"
1796 " there for %s\n", objectfile
);
1798 } else if (shp
->sh_type
== SHT_DYNAMIC
) {
1800 } else if (strcmp(cp
->c_name
, ".plt") == 0) {
1802 } else if (strcmp(cp
->c_name
, ".SUNW_ctf") == 0) {
1804 * Skip over bogus CTF sections so they don't come back
1805 * to haunt us later.
1807 if (shp
->sh_link
== 0 ||
1808 shp
->sh_link
>= nshdrs
||
1809 (cache
[shp
->sh_link
].c_shdr
.sh_type
!= SHT_DYNSYM
&&
1810 cache
[shp
->sh_link
].c_shdr
.sh_type
!= SHT_SYMTAB
)) {
1811 dprintf("Bad sh_link %d for "
1812 "CTF\n", shp
->sh_link
);
1820 * At this point, we've found all the symbol tables we're ever going
1821 * to find: the ones in the loop above and possibly the symtab that
1822 * was included in the core file. Before we perform any lookups, we
1823 * create sorted versions to optimize for lookups.
1825 optimize_symtab(&fptr
->file_symtab
);
1826 optimize_symtab(&fptr
->file_dynsym
);
1829 * Fill in the base address of the text mapping for shared libraries.
1830 * This allows us to translate symbols before librtld_db is ready.
1832 if (fptr
->file_etype
== ET_DYN
) {
1833 fptr
->file_dyn_base
= fptr
->file_map
->map_pmap
.pr_vaddr
-
1834 fptr
->file_map
->map_pmap
.pr_offset
;
1835 dprintf("setting file_dyn_base for %s to %lx\n",
1836 objectfile
, (long)fptr
->file_dyn_base
);
1840 * Record the CTF section information in the file info structure.
1843 fptr
->file_ctf_off
= ctf
->c_shdr
.sh_offset
;
1844 fptr
->file_ctf_size
= ctf
->c_shdr
.sh_size
;
1845 if (ctf
->c_shdr
.sh_link
!= 0 &&
1846 cache
[ctf
->c_shdr
.sh_link
].c_shdr
.sh_type
== SHT_DYNSYM
)
1847 fptr
->file_ctf_dyn
= 1;
1850 if (fptr
->file_lo
== NULL
)
1851 goto done
; /* Nothing else to do if no load object info */
1854 * If the object is a shared library and we have a different rl_base
1855 * value, reset file_dyn_base according to librtld_db's information.
1857 if (fptr
->file_etype
== ET_DYN
&&
1858 fptr
->file_lo
->rl_base
!= fptr
->file_dyn_base
) {
1859 dprintf("resetting file_dyn_base for %s to %lx\n",
1860 objectfile
, (long)fptr
->file_lo
->rl_base
);
1861 fptr
->file_dyn_base
= fptr
->file_lo
->rl_base
;
1865 * Fill in the PLT information for this file if a PLT symbol is found.
1867 if (sym_by_name(&fptr
->file_dynsym
, "_PROCEDURE_LINKAGE_TABLE_", &s
,
1869 fptr
->file_plt_base
= s
.st_value
+ fptr
->file_dyn_base
;
1870 fptr
->file_plt_size
= (plt
!= NULL
) ? plt
->c_shdr
.sh_size
: 0;
1873 * Bring the load object up to date; it is the only way the
1874 * user has to access the PLT data. The PLT information in the
1875 * rd_loadobj_t is not set in the call to map_iter() (the
1876 * callback for rd_loadobj_iter) where we set file_lo.
1878 fptr
->file_lo
->rl_plt_base
= fptr
->file_plt_base
;
1879 fptr
->file_lo
->rl_plt_size
= fptr
->file_plt_size
;
1881 dprintf("PLT found at %p, size = %lu\n",
1882 (void *)fptr
->file_plt_base
, (ulong_t
)fptr
->file_plt_size
);
1886 * Fill in the PLT information.
1889 uintptr_t dynaddr
= dyn
->c_shdr
.sh_addr
+ fptr
->file_dyn_base
;
1890 size_t ndyn
= dyn
->c_shdr
.sh_size
/ dyn
->c_shdr
.sh_entsize
;
1893 for (i
= 0; i
< ndyn
; i
++) {
1894 if (gelf_getdyn(dyn
->c_data
, i
, &d
) == NULL
)
1899 dprintf("DT_JMPREL is %p\n",
1900 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1901 fptr
->file_jmp_rel
=
1902 d
.d_un
.d_ptr
+ fptr
->file_dyn_base
;
1905 dprintf("DT_STRTAB is %p\n",
1906 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1909 dprintf("DT_PLTGOT is %p\n",
1910 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1912 case DT_SUNW_SYMTAB
:
1913 dprintf("DT_SUNW_SYMTAB is %p\n",
1914 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1917 dprintf("DT_SYMTAB is %p\n",
1918 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1921 dprintf("DT_HASH is %p\n",
1922 (void *)(uintptr_t)d
.d_un
.d_ptr
);
1927 dprintf("_DYNAMIC found at %p, %lu entries, DT_JMPREL = %p\n",
1928 (void *)dynaddr
, (ulong_t
)ndyn
, (void *)fptr
->file_jmp_rel
);
1939 (void) elf_end(elf
);
1940 fptr
->file_elf
= NULL
;
1941 if (fptr
->file_elfmem
!= NULL
) {
1942 free(fptr
->file_elfmem
);
1943 fptr
->file_elfmem
= NULL
;
1945 (void) close(fptr
->file_fd
);
1950 * Given a process virtual address, return the map_info_t containing it.
1951 * If none found, return NULL.
1954 Paddr2mptr(struct ps_prochandle
*P
, uintptr_t addr
)
1957 int hi
= P
->map_count
- 1;
1963 mid
= (lo
+ hi
) / 2;
1964 mp
= &P
->mappings
[mid
];
1966 /* check that addr is in [vaddr, vaddr + size) */
1967 if ((addr
- mp
->map_pmap
.pr_vaddr
) < mp
->map_pmap
.pr_size
)
1970 if (addr
< mp
->map_pmap
.pr_vaddr
)
1980 * Return the map_info_t for the executable file.
1981 * If not found, return NULL.
1984 exec_map(struct ps_prochandle
*P
)
1988 map_info_t
*mold
= NULL
;
1992 for (i
= 0, mptr
= P
->mappings
; i
< P
->map_count
; i
++, mptr
++) {
1993 if (mptr
->map_pmap
.pr_mapname
[0] == '\0')
1995 if (strcmp(mptr
->map_pmap
.pr_mapname
, "a.out") == 0) {
1996 if ((fptr
= mptr
->map_file
) != NULL
&&
1997 fptr
->file_lo
!= NULL
) {
1998 base
= fptr
->file_lo
->rl_base
;
1999 if (base
>= mptr
->map_pmap
.pr_vaddr
&&
2000 base
< mptr
->map_pmap
.pr_vaddr
+
2001 mptr
->map_pmap
.pr_size
) /* text space */
2003 mold
= mptr
; /* must be the data */
2006 /* This is a poor way to test for text space */
2007 if (!(mptr
->map_pmap
.pr_mflags
& MA_EXEC
) ||
2008 (mptr
->map_pmap
.pr_mflags
& MA_WRITE
)) {
2020 * Given a shared object name, return the map_info_t for it. If no matching
2021 * object is found, return NULL. Normally, the link maps contain the full
2022 * object pathname, e.g. /usr/lib/libc.so.1. We allow the object name to
2023 * take one of the following forms:
2025 * 1. An exact match (i.e. a full pathname): "/usr/lib/libc.so.1"
2026 * 2. An exact basename match: "libc.so.1"
2027 * 3. An initial basename match up to a '.' suffix: "libc.so" or "libc"
2028 * 4. The literal string "a.out" is an alias for the executable mapping
2030 * The third case is a convenience for callers and may not be necessary.
2032 * As the exact same object name may be loaded on different link maps (see
2033 * dlmopen(3DL)), we also allow the caller to resolve the object name by
2034 * specifying a particular link map id. If lmid is PR_LMID_EVERY, the
2035 * first matching name will be returned, regardless of the link map id.
2038 object_to_map(struct ps_prochandle
*P
, Lmid_t lmid
, const char *objname
)
2046 * If we have no rtld_db, then always treat a request as one for all
2050 lmid
= PR_LMID_EVERY
;
2053 * First pass: look for exact matches of the entire pathname or
2054 * basename (cases 1 and 2 above):
2056 for (i
= 0, mp
= P
->mappings
; i
< P
->map_count
; i
++, mp
++) {
2058 if (mp
->map_pmap
.pr_mapname
[0] == '\0' ||
2059 (fp
= mp
->map_file
) == NULL
||
2060 ((fp
->file_lname
== NULL
) && (fp
->file_rname
== NULL
)))
2063 if (lmid
!= PR_LMID_EVERY
&&
2064 (fp
->file_lo
== NULL
|| lmid
!= fp
->file_lo
->rl_lmident
))
2068 * If we match, return the primary text mapping; otherwise
2069 * just return the mapping we matched.
2071 if ((fp
->file_lbase
&& strcmp(fp
->file_lbase
, objname
) == 0) ||
2072 (fp
->file_rbase
&& strcmp(fp
->file_rbase
, objname
) == 0) ||
2073 (fp
->file_lname
&& strcmp(fp
->file_lname
, objname
) == 0) ||
2074 (fp
->file_rname
&& strcmp(fp
->file_rname
, objname
) == 0))
2075 return (fp
->file_map
? fp
->file_map
: mp
);
2078 objlen
= strlen(objname
);
2081 * Second pass: look for partial matches (case 3 above):
2083 for (i
= 0, mp
= P
->mappings
; i
< P
->map_count
; i
++, mp
++) {
2085 if (mp
->map_pmap
.pr_mapname
[0] == '\0' ||
2086 (fp
= mp
->map_file
) == NULL
||
2087 ((fp
->file_lname
== NULL
) && (fp
->file_rname
== NULL
)))
2090 if (lmid
!= PR_LMID_EVERY
&&
2091 (fp
->file_lo
== NULL
|| lmid
!= fp
->file_lo
->rl_lmident
))
2095 * If we match, return the primary text mapping; otherwise
2096 * just return the mapping we matched.
2098 if ((fp
->file_lbase
!= NULL
) &&
2099 (strncmp(fp
->file_lbase
, objname
, objlen
) == 0) &&
2100 (fp
->file_lbase
[objlen
] == '.'))
2101 return (fp
->file_map
? fp
->file_map
: mp
);
2102 if ((fp
->file_rbase
!= NULL
) &&
2103 (strncmp(fp
->file_rbase
, objname
, objlen
) == 0) &&
2104 (fp
->file_rbase
[objlen
] == '.'))
2105 return (fp
->file_map
? fp
->file_map
: mp
);
2109 * One last check: we allow "a.out" to always alias the executable,
2110 * assuming this name was not in use for something else.
2112 if ((lmid
== PR_LMID_EVERY
|| lmid
== LM_ID_BASE
) &&
2113 (strcmp(objname
, "a.out") == 0))
2114 return (P
->map_exec
);
2120 object_name_to_map(struct ps_prochandle
*P
, Lmid_t lmid
, const char *name
)
2127 if (P
->map_exec
== NULL
&& ((mptr
= Paddr2mptr(P
,
2128 Pgetauxval(P
, AT_ENTRY
))) != NULL
|| (mptr
= exec_map(P
)) != NULL
))
2131 if (P
->map_ldso
== NULL
&& (mptr
= Paddr2mptr(P
,
2132 Pgetauxval(P
, AT_BASE
))) != NULL
)
2135 if (name
== PR_OBJ_EXEC
)
2137 else if (name
== PR_OBJ_LDSO
)
2139 else if (Prd_agent(P
) != NULL
|| P
->state
== PS_IDLE
)
2140 mptr
= object_to_map(P
, lmid
, name
);
2148 * When two symbols are found by address, decide which one is to be preferred.
2151 sym_prefer(GElf_Sym
*sym1
, char *name1
, GElf_Sym
*sym2
, char *name2
)
2154 * Prefer the non-NULL symbol.
2162 * Defer to the sort ordering...
2164 return (byaddr_cmp_common(sym1
, name1
, sym2
, name2
) <= 0 ? sym1
: sym2
);
2168 * Use a binary search to do the work of sym_by_addr().
2171 sym_by_addr_binary(sym_tbl_t
*symtab
, GElf_Addr addr
, GElf_Sym
*symp
,
2175 uint_t i
, oid
, *byaddr
= symtab
->sym_byaddr
;
2176 int min
, max
, mid
, omid
, found
= 0;
2178 if (symtab
->sym_data_pri
== NULL
|| symtab
->sym_count
== 0)
2182 max
= symtab
->sym_count
- 1;
2186 * We can't return when we've found a match, we have to continue
2187 * searching for the closest matching symbol.
2189 while (min
<= max
) {
2190 mid
= (max
+ min
) / 2;
2193 (void) symtab_getsym(symtab
, i
, &sym
);
2195 if (addr
>= sym
.st_value
&&
2196 addr
< sym
.st_value
+ sym
.st_size
&&
2197 (!found
|| sym
.st_value
> osym
.st_value
)) {
2204 if (addr
< sym
.st_value
)
2214 * There may be many symbols with identical values so we walk
2215 * backward in the byaddr table to find the best match.
2224 oid
= byaddr
[--omid
];
2225 (void) symtab_getsym(symtab
, oid
, &osym
);
2226 } while (addr
>= osym
.st_value
&&
2227 addr
< sym
.st_value
+ osym
.st_size
&&
2228 osym
.st_value
== sym
.st_value
);
2237 * Use a linear search to do the work of sym_by_addr().
2240 sym_by_addr_linear(sym_tbl_t
*symtab
, GElf_Addr addr
, GElf_Sym
*symbolp
,
2243 size_t symn
= symtab
->sym_symn
;
2244 char *strs
= symtab
->sym_strs
;
2245 GElf_Sym sym
, *symp
= NULL
;
2246 GElf_Sym osym
, *osymp
= NULL
;
2249 if (symtab
->sym_data_pri
== NULL
|| symn
== 0 || strs
== NULL
)
2252 for (i
= 0; i
< symn
; i
++) {
2253 if ((symp
= symtab_getsym(symtab
, i
, &sym
)) != NULL
) {
2254 if (addr
>= sym
.st_value
&&
2255 addr
< sym
.st_value
+ sym
.st_size
) {
2258 symp
, strs
+ symp
->st_name
,
2259 osymp
, strs
+ osymp
->st_name
);
2260 if (symp
!= osymp
) {
2278 * Look up a symbol by address in the specified symbol table.
2279 * Adjustment to 'addr' must already have been made for the
2280 * offset of the symbol if this is a dynamic library symbol table.
2282 * Use a linear or a binary search depending on whether or not we
2283 * chose to sort the table in optimize_symtab().
2286 sym_by_addr(sym_tbl_t
*symtab
, GElf_Addr addr
, GElf_Sym
*symp
, uint_t
*idp
)
2288 if (_libproc_no_qsort
) {
2289 return (sym_by_addr_linear(symtab
, addr
, symp
, idp
));
2291 return (sym_by_addr_binary(symtab
, addr
, symp
, idp
));
2296 * Use a binary search to do the work of sym_by_name().
2299 sym_by_name_binary(sym_tbl_t
*symtab
, const char *name
, GElf_Sym
*symp
,
2302 char *strs
= symtab
->sym_strs
;
2303 uint_t i
, *byname
= symtab
->sym_byname
;
2304 int min
, mid
, max
, cmp
;
2306 if (symtab
->sym_data_pri
== NULL
|| strs
== NULL
||
2307 symtab
->sym_count
== 0)
2311 max
= symtab
->sym_count
- 1;
2313 while (min
<= max
) {
2314 mid
= (max
+ min
) / 2;
2317 (void) symtab_getsym(symtab
, i
, symp
);
2319 if ((cmp
= strcmp(name
, strs
+ symp
->st_name
)) == 0) {
2335 * Use a linear search to do the work of sym_by_name().
2338 sym_by_name_linear(sym_tbl_t
*symtab
, const char *name
, GElf_Sym
*symp
,
2341 size_t symn
= symtab
->sym_symn
;
2342 char *strs
= symtab
->sym_strs
;
2345 if (symtab
->sym_data_pri
== NULL
|| symn
== 0 || strs
== NULL
)
2348 for (i
= 0; i
< symn
; i
++) {
2349 if (symtab_getsym(symtab
, i
, symp
) &&
2350 strcmp(name
, strs
+ symp
->st_name
) == 0) {
2361 * Look up a symbol by name in the specified symbol table.
2363 * Use a linear or a binary search depending on whether or not we
2364 * chose to sort the table in optimize_symtab().
2367 sym_by_name(sym_tbl_t
*symtab
, const char *name
, GElf_Sym
*symp
, uint_t
*idp
)
2369 if (_libproc_no_qsort
) {
2370 return (sym_by_name_linear(symtab
, name
, symp
, idp
));
2372 return (sym_by_name_binary(symtab
, name
, symp
, idp
));
2377 * Search the process symbol tables looking for a symbol whose
2378 * value to value+size contain the address specified by addr.
2379 * Return values are:
2380 * sym_name_buffer containing the symbol name
2381 * GElf_Sym symbol table entry
2382 * prsyminfo_t ancillary symbol information
2383 * Returns 0 on success, -1 on failure.
2387 struct ps_prochandle
*P
,
2388 int lmresolve
, /* use resolve linker object names */
2389 uintptr_t addr
, /* process address being sought */
2390 char *sym_name_buffer
, /* buffer for the symbol name */
2391 size_t bufsize
, /* size of sym_name_buffer */
2392 GElf_Sym
*symbolp
, /* returned symbol table entry */
2393 prsyminfo_t
*sip
) /* returned symbol info */
2397 GElf_Sym sym1
, *sym1p
= NULL
;
2398 GElf_Sym sym2
, *sym2p
= NULL
;
2406 (void) Prd_agent(P
);
2408 if ((mptr
= Paddr2mptr(P
, addr
)) == NULL
|| /* no such address */
2409 (fptr
= build_map_symtab(P
, mptr
)) == NULL
|| /* no mapped file */
2410 fptr
->file_elf
== NULL
) /* not an ELF file */
2414 * Adjust the address by the load object base address in
2415 * case the address turns out to be in a shared library.
2417 addr
-= fptr
->file_dyn_base
;
2420 * Search both symbol tables, symtab first, then dynsym.
2422 if ((sym1p
= sym_by_addr(&fptr
->file_symtab
, addr
, &sym1
, &i1
)) != NULL
)
2423 name1
= fptr
->file_symtab
.sym_strs
+ sym1
.st_name
;
2424 if ((sym2p
= sym_by_addr(&fptr
->file_dynsym
, addr
, &sym2
, &i2
)) != NULL
)
2425 name2
= fptr
->file_dynsym
.sym_strs
+ sym2
.st_name
;
2427 if ((symp
= sym_prefer(sym1p
, name1
, sym2p
, name2
)) == NULL
)
2430 name
= (symp
== sym1p
) ? name1
: name2
;
2432 (void) strncpy(sym_name_buffer
, name
, bufsize
);
2433 sym_name_buffer
[bufsize
- 1] = '\0';
2438 sip
->prs_name
= bufsize
== 0 ? NULL
: sym_name_buffer
;
2439 if (lmresolve
&& (fptr
->file_rname
!= NULL
))
2440 sip
->prs_object
= fptr
->file_rbase
;
2442 sip
->prs_object
= fptr
->file_lbase
;
2443 sip
->prs_id
= (symp
== sym1p
) ? i1
: i2
;
2444 sip
->prs_table
= (symp
== sym1p
) ? PR_SYMTAB
: PR_DYNSYM
;
2445 sip
->prs_lmid
= (fptr
->file_lo
== NULL
) ? LM_ID_BASE
:
2446 fptr
->file_lo
->rl_lmident
;
2449 if (GELF_ST_TYPE(symbolp
->st_info
) != STT_TLS
)
2450 symbolp
->st_value
+= fptr
->file_dyn_base
;
2456 Pxlookup_by_addr(struct ps_prochandle
*P
, uintptr_t addr
, char *buf
,
2457 size_t bufsize
, GElf_Sym
*symp
, prsyminfo_t
*sip
)
2459 return (i_Pxlookup_by_addr(P
, B_FALSE
, addr
, buf
, bufsize
, symp
, sip
));
2463 Pxlookup_by_addr_resolved(struct ps_prochandle
*P
, uintptr_t addr
, char *buf
,
2464 size_t bufsize
, GElf_Sym
*symp
, prsyminfo_t
*sip
)
2466 return (i_Pxlookup_by_addr(P
, B_TRUE
, addr
, buf
, bufsize
, symp
, sip
));
2470 Plookup_by_addr(struct ps_prochandle
*P
, uintptr_t addr
, char *buf
,
2471 size_t size
, GElf_Sym
*symp
)
2473 return (i_Pxlookup_by_addr(P
, B_FALSE
, addr
, buf
, size
, symp
, NULL
));
2477 * Search the process symbol tables looking for a symbol whose name matches the
2478 * specified name and whose object and link map optionally match the specified
2479 * parameters. On success, the function returns 0 and fills in the GElf_Sym
2480 * symbol table entry. On failure, -1 is returned.
2484 struct ps_prochandle
*P
,
2485 Lmid_t lmid
, /* link map to match, or -1 for any */
2486 const char *oname
, /* load object name */
2487 const char *sname
, /* symbol name */
2488 GElf_Sym
*symp
, /* returned symbol table entry */
2489 prsyminfo_t
*sip
) /* returned symbol info */
2500 if (oname
== PR_OBJ_EVERY
) {
2501 /* create all the file_info_t's for all the mappings */
2502 (void) Prd_agent(P
);
2504 fptr
= list_next(&P
->file_head
);
2507 if ((mptr
= object_name_to_map(P
, lmid
, oname
)) == NULL
||
2508 (fptr
= build_map_symtab(P
, mptr
)) == NULL
)
2513 * Iterate through the loaded object files and look for the symbol
2514 * name in the .symtab and .dynsym of each. If we encounter a match
2515 * with SHN_UNDEF, keep looking in hopes of finding a better match.
2516 * This means that a name such as "puts" will match the puts function
2517 * in libc instead of matching the puts PLT entry in the a.out file.
2519 for (; cnt
> 0; cnt
--, fptr
= list_next(fptr
)) {
2520 Pbuild_file_symtab(P
, fptr
);
2522 if (fptr
->file_elf
== NULL
)
2525 if (lmid
!= PR_LMID_EVERY
&& fptr
->file_lo
!= NULL
&&
2526 lmid
!= fptr
->file_lo
->rl_lmident
)
2529 if (fptr
->file_symtab
.sym_data_pri
!= NULL
&&
2530 sym_by_name(&fptr
->file_symtab
, sname
, symp
, &id
)) {
2533 sip
->prs_table
= PR_SYMTAB
;
2534 sip
->prs_object
= oname
;
2535 sip
->prs_name
= sname
;
2536 sip
->prs_lmid
= fptr
->file_lo
== NULL
?
2537 LM_ID_BASE
: fptr
->file_lo
->rl_lmident
;
2539 } else if (fptr
->file_dynsym
.sym_data_pri
!= NULL
&&
2540 sym_by_name(&fptr
->file_dynsym
, sname
, symp
, &id
)) {
2543 sip
->prs_table
= PR_DYNSYM
;
2544 sip
->prs_object
= oname
;
2545 sip
->prs_name
= sname
;
2546 sip
->prs_lmid
= fptr
->file_lo
== NULL
?
2547 LM_ID_BASE
: fptr
->file_lo
->rl_lmident
;
2553 if (GELF_ST_TYPE(symp
->st_info
) != STT_TLS
)
2554 symp
->st_value
+= fptr
->file_dyn_base
;
2556 if (symp
->st_shndx
!= SHN_UNDEF
)
2577 * Search the process symbol tables looking for a symbol whose name matches the
2578 * specified name, but without any restriction on the link map id.
2581 Plookup_by_name(struct ps_prochandle
*P
, const char *object
,
2582 const char *symbol
, GElf_Sym
*symp
)
2584 return (Pxlookup_by_name(P
, PR_LMID_EVERY
, object
, symbol
, symp
, NULL
));
2588 * Iterate over the process's address space mappings.
2591 i_Pmapping_iter(struct ps_prochandle
*P
, boolean_t lmresolve
,
2592 proc_map_f
*func
, void *cd
)
2600 /* create all the file_info_t's for all the mappings */
2601 (void) Prd_agent(P
);
2603 for (i
= 0, mptr
= P
->mappings
; i
< P
->map_count
; i
++, mptr
++) {
2604 if ((fptr
= mptr
->map_file
) == NULL
)
2606 else if (lmresolve
&& (fptr
->file_rname
!= NULL
))
2607 object_name
= fptr
->file_rname
;
2609 object_name
= fptr
->file_lname
;
2610 if ((rc
= func(cd
, &mptr
->map_pmap
, object_name
)) != 0)
2617 Pmapping_iter(struct ps_prochandle
*P
, proc_map_f
*func
, void *cd
)
2619 return (i_Pmapping_iter(P
, B_FALSE
, func
, cd
));
2623 Pmapping_iter_resolved(struct ps_prochandle
*P
, proc_map_f
*func
, void *cd
)
2625 return (i_Pmapping_iter(P
, B_TRUE
, func
, cd
));
2629 * Iterate over the process's mapped objects.
2632 i_Pobject_iter(struct ps_prochandle
*P
, boolean_t lmresolve
,
2633 proc_map_f
*func
, void *cd
)
2640 (void) Prd_agent(P
); /* create file_info_t's for all the mappings */
2643 for (cnt
= P
->num_files
, fptr
= list_next(&P
->file_head
);
2644 cnt
; cnt
--, fptr
= list_next(fptr
)) {
2647 if (lmresolve
&& (fptr
->file_rname
!= NULL
))
2648 lname
= fptr
->file_rname
;
2649 else if (fptr
->file_lname
!= NULL
)
2650 lname
= fptr
->file_lname
;
2654 if ((mptr
= fptr
->file_map
) == NULL
)
2657 if ((rc
= func(cd
, &mptr
->map_pmap
, lname
)) != 0)
2667 Pobject_iter(struct ps_prochandle
*P
, proc_map_f
*func
, void *cd
)
2669 return (i_Pobject_iter(P
, B_FALSE
, func
, cd
));
2673 Pobject_iter_resolved(struct ps_prochandle
*P
, proc_map_f
*func
, void *cd
)
2675 return (i_Pobject_iter(P
, B_TRUE
, func
, cd
));
2679 i_Pobjname(struct ps_prochandle
*P
, boolean_t lmresolve
, uintptr_t addr
,
2680 char *buffer
, size_t bufsize
)
2685 /* create all the file_info_t's for all the mappings */
2686 (void) Prd_agent(P
);
2688 if ((mptr
= Paddr2mptr(P
, addr
)) == NULL
)
2692 if (((fptr
= mptr
->map_file
) == NULL
) ||
2693 (fptr
->file_lname
== NULL
))
2695 (void) strlcpy(buffer
, fptr
->file_lname
, bufsize
);
2699 /* Check for a cached copy of the resolved path */
2700 if (Pfindmap(P
, mptr
, buffer
, bufsize
) != NULL
)
2707 * Given a virtual address, return the name of the underlying
2708 * mapped object (file) as provided by the dynamic linker.
2709 * Return NULL if we can't find any name information for the object.
2712 Pobjname(struct ps_prochandle
*P
, uintptr_t addr
,
2713 char *buffer
, size_t bufsize
)
2715 return (i_Pobjname(P
, B_FALSE
, addr
, buffer
, bufsize
));
2719 * Given a virtual address, try to return a filesystem path to the
2720 * underlying mapped object (file). If we're in the global zone,
2721 * this path could resolve to an object in another zone. If we're
2722 * unable return a valid filesystem path, we'll fall back to providing
2723 * the mapped object (file) name provided by the dynamic linker in
2724 * the target process (ie, the object reported by Pobjname()).
2727 Pobjname_resolved(struct ps_prochandle
*P
, uintptr_t addr
,
2728 char *buffer
, size_t bufsize
)
2730 return (i_Pobjname(P
, B_TRUE
, addr
, buffer
, bufsize
));
2734 * Given a virtual address, return the link map id of the underlying mapped
2735 * object (file), as provided by the dynamic linker. Return -1 on failure.
2738 Plmid(struct ps_prochandle
*P
, uintptr_t addr
, Lmid_t
*lmidp
)
2743 /* create all the file_info_t's for all the mappings */
2744 (void) Prd_agent(P
);
2746 if ((mptr
= Paddr2mptr(P
, addr
)) != NULL
&&
2747 (fptr
= mptr
->map_file
) != NULL
&& fptr
->file_lo
!= NULL
) {
2748 *lmidp
= fptr
->file_lo
->rl_lmident
;
2756 * Given an object name and optional lmid, iterate over the object's symbols.
2757 * If which == PR_SYMTAB, search the normal symbol table.
2758 * If which == PR_DYNSYM, search the dynamic symbol table.
2761 Psymbol_iter_com(struct ps_prochandle
*P
, Lmid_t lmid
, const char *object_name
,
2762 int which
, int mask
, pr_order_t order
, proc_xsym_f
*func
, void *cd
)
2764 #if STT_NUM != (STT_TLS + 1)
2765 #error "STT_NUM has grown. update Psymbol_iter_com()"
2778 uint_t
*map
, i
, count
, ndx
;
2780 if ((mptr
= object_name_to_map(P
, lmid
, object_name
)) == NULL
)
2783 if ((fptr
= build_map_symtab(P
, mptr
)) == NULL
|| /* no mapped file */
2784 fptr
->file_elf
== NULL
) /* not an ELF file */
2788 * Search the specified symbol table.
2792 symtab
= &fptr
->file_symtab
;
2793 si
.prs_table
= PR_SYMTAB
;
2796 symtab
= &fptr
->file_dynsym
;
2797 si
.prs_table
= PR_DYNSYM
;
2803 si
.prs_object
= object_name
;
2804 si
.prs_lmid
= fptr
->file_lo
== NULL
?
2805 LM_ID_BASE
: fptr
->file_lo
->rl_lmident
;
2807 symn
= symtab
->sym_symn
;
2808 strs
= symtab
->sym_strs
;
2809 strsz
= symtab
->sym_strsz
;
2817 map
= symtab
->sym_byname
;
2818 count
= symtab
->sym_count
;
2821 map
= symtab
->sym_byaddr
;
2822 count
= symtab
->sym_count
;
2828 if (symtab
->sym_data_pri
== NULL
|| strs
== NULL
|| count
== 0)
2833 for (i
= 0; i
< count
; i
++) {
2834 ndx
= map
== NULL
? i
: map
[i
];
2835 if (symtab_getsym(symtab
, ndx
, &sym
) != NULL
) {
2836 uint_t s_bind
, s_type
, type
;
2838 if (sym
.st_name
>= strsz
) /* invalid st_name */
2841 s_bind
= GELF_ST_BIND(sym
.st_info
);
2842 s_type
= GELF_ST_TYPE(sym
.st_info
);
2845 * In case you haven't already guessed, this relies on
2846 * the bitmask used in <libproc.h> for encoding symbol
2847 * type and binding matching the order of STB and STT
2848 * constants in <sys/elf.h>. Changes to ELF must
2849 * maintain binary compatibility, so I think this is
2850 * reasonably fair game.
2852 if (s_bind
< STB_NUM
&& s_type
< STT_NUM
) {
2853 type
= (1 << (s_type
+ 8)) | (1 << s_bind
);
2854 if ((type
& ~mask
) != 0)
2857 continue; /* Invalid type or binding */
2859 if (GELF_ST_TYPE(sym
.st_info
) != STT_TLS
)
2860 sym
.st_value
+= fptr
->file_dyn_base
;
2862 si
.prs_name
= strs
+ sym
.st_name
;
2865 * If symbol's type is STT_SECTION, then try to lookup
2866 * the name of the corresponding section.
2868 if (GELF_ST_TYPE(sym
.st_info
) == STT_SECTION
&&
2869 fptr
->file_shstrs
!= NULL
&&
2870 gelf_getshdr(elf_getscn(fptr
->file_elf
,
2871 sym
.st_shndx
), &shdr
) != NULL
&&
2872 shdr
.sh_name
!= 0 &&
2873 shdr
.sh_name
< fptr
->file_shstrsz
)
2874 si
.prs_name
= fptr
->file_shstrs
+ shdr
.sh_name
;
2877 if ((rv
= func(cd
, &sym
, si
.prs_name
, &si
)) != 0)
2886 Pxsymbol_iter(struct ps_prochandle
*P
, Lmid_t lmid
, const char *object_name
,
2887 int which
, int mask
, proc_xsym_f
*func
, void *cd
)
2889 return (Psymbol_iter_com(P
, lmid
, object_name
, which
, mask
,
2890 PRO_NATURAL
, func
, cd
));
2894 Psymbol_iter_by_lmid(struct ps_prochandle
*P
, Lmid_t lmid
,
2895 const char *object_name
, int which
, int mask
, proc_sym_f
*func
, void *cd
)
2897 return (Psymbol_iter_com(P
, lmid
, object_name
, which
, mask
,
2898 PRO_NATURAL
, (proc_xsym_f
*)func
, cd
));
2902 Psymbol_iter(struct ps_prochandle
*P
,
2903 const char *object_name
, int which
, int mask
, proc_sym_f
*func
, void *cd
)
2905 return (Psymbol_iter_com(P
, PR_LMID_EVERY
, object_name
, which
, mask
,
2906 PRO_NATURAL
, (proc_xsym_f
*)func
, cd
));
2910 Psymbol_iter_by_addr(struct ps_prochandle
*P
,
2911 const char *object_name
, int which
, int mask
, proc_sym_f
*func
, void *cd
)
2913 return (Psymbol_iter_com(P
, PR_LMID_EVERY
, object_name
, which
, mask
,
2914 PRO_BYADDR
, (proc_xsym_f
*)func
, cd
));
2918 Psymbol_iter_by_name(struct ps_prochandle
*P
,
2919 const char *object_name
, int which
, int mask
, proc_sym_f
*func
, void *cd
)
2921 return (Psymbol_iter_com(P
, PR_LMID_EVERY
, object_name
, which
, mask
,
2922 PRO_BYNAME
, (proc_xsym_f
*)func
, cd
));
2926 * Get the platform string.
2929 Pplatform(struct ps_prochandle
*P
, char *s
, size_t n
)
2931 return (P
->ops
.pop_platform(P
, s
, n
, P
->data
));
2935 * Get the uname(2) information.
2938 Puname(struct ps_prochandle
*P
, struct utsname
*u
)
2940 return (P
->ops
.pop_uname(P
, u
, P
->data
));
2944 * Called from Pcreate(), Pgrab(), and Pfgrab_core() to initialize
2945 * the symbol table heads in the new ps_prochandle.
2948 Pinitsym(struct ps_prochandle
*P
)
2951 list_link(&P
->file_head
, NULL
);
2955 * Called from Prelease() to destroy the symbol tables.
2956 * Must be called by the client after an exec() in the victim process.
2959 Preset_maps(struct ps_prochandle
*P
)
2963 if (P
->rap
!= NULL
) {
2968 if (P
->execname
!= NULL
) {
2973 if (P
->auxv
!= NULL
) {
2979 for (i
= 0; i
< P
->map_count
; i
++)
2980 map_info_free(P
, &P
->mappings
[i
]);
2982 if (P
->mappings
!= NULL
) {
2986 P
->map_count
= P
->map_alloc
= 0;
2991 typedef struct getenv_data
{
3000 getenv_func(void *data
, struct ps_prochandle
*P
, uintptr_t addr
,
3001 const char *nameval
)
3003 getenv_data_t
*d
= data
;
3006 if (nameval
== NULL
)
3009 if (d
->searchlen
< strlen(nameval
) &&
3010 strncmp(nameval
, d
->search
, d
->searchlen
) == 0 &&
3011 nameval
[d
->searchlen
] == '=') {
3012 len
= MIN(strlen(nameval
), d
->bufsize
- 1);
3013 (void) strncpy(d
->buf
, nameval
, len
);
3022 Pgetenv(struct ps_prochandle
*P
, const char *name
, char *buf
, size_t buflen
)
3029 d
.searchlen
= strlen(name
);
3031 if (Penv_iter(P
, getenv_func
, &d
) == 1) {
3032 char *equals
= strchr(d
.buf
, '=');
3034 if (equals
!= NULL
) {
3035 (void) memmove(d
.buf
, equals
+ 1,
3036 d
.buf
+ buflen
- equals
- 1);
3037 d
.buf
[d
.buf
+ buflen
- equals
] = '\0';
3046 /* number of argument or environment pointers to read all at once */
3050 Penv_iter(struct ps_prochandle
*P
, proc_env_f
*func
, void *data
)
3052 const psinfo_t
*psp
;
3056 char *buf
, *nameval
;
3063 * Attempt to find the "_environ" variable in the process.
3064 * Failing that, use the original value provided by Ppsinfo().
3066 if ((psp
= Ppsinfo(P
)) == NULL
)
3069 envpoff
= psp
->pr_envp
; /* Default if no _environ found */
3071 if (Plookup_by_name(P
, PR_OBJ_EXEC
, "_environ", &sym
) == 0) {
3072 if (P
->status
.pr_dmodel
== PR_MODEL_NATIVE
) {
3073 if (Pread(P
, &envpoff
, sizeof (envpoff
),
3074 sym
.st_value
) != sizeof (envpoff
))
3075 envpoff
= psp
->pr_envp
;
3076 } else if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
3079 if (Pread(P
, &envpoff32
, sizeof (envpoff32
),
3080 sym
.st_value
) != sizeof (envpoff32
))
3081 envpoff
= psp
->pr_envp
;
3083 envpoff
= envpoff32
;
3088 buf
= malloc(buflen
);
3095 (void) memset(envp
, 0, sizeof (envp
));
3096 if (P
->status
.pr_dmodel
== PR_MODEL_NATIVE
) {
3098 sizeof (envp
), envpoff
) <= 0) {
3102 } else if (P
->status
.pr_dmodel
== PR_MODEL_ILP32
) {
3106 (void) memset(e32
, 0, sizeof (e32
));
3107 if (Pread(P
, e32
, sizeof (e32
), envpoff
) <= 0) {
3111 for (i
= 0; i
< NARG
; i
++)
3117 if ((envoff
= envp
[nenv
++]) == NULL
)
3121 * Attempt to read the string from the process.
3124 ret
= Pread_string(P
, buf
, buflen
, envoff
);
3128 } else if (ret
== buflen
- 1) {
3131 * Bail if we have a corrupted environment
3133 if (buflen
>= ARG_MAX
)
3136 buf
= malloc(buflen
);
3142 if ((ret
= func(data
, P
, envoff
, nameval
)) != 0)
3145 envpoff
+= (P
->status
.pr_dmodel
== PR_MODEL_LP64
)? 8 : 4;