1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2016 Joyent, Inc.
25 * Copyright (c) 2013 by Delphix. All rights reserved.
26 */
27
28 #include <assert.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stddef.h>
32 #include <unistd.h>
33 #include <ctype.h>
34 #include <fcntl.h>
35 #include <string.h>
36 #include <strings.h>
37 #include <memory.h>
38 #include <errno.h>
39 #include <dirent.h>
40 #include <signal.h>
41 #include <limits.h>
42 #include <libgen.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <sys/sysmacros.h>
46 #include <sys/crc32.h>
47
48 #include "libproc.h"
49 #include "Pcontrol.h"
50 #include "Putil.h"
51 #include "Psymtab_machelf.h"
52
53 static file_info_t *build_map_symtab(struct ps_prochandle *, map_info_t *);
54 static map_info_t *exec_map(struct ps_prochandle *);
55 static map_info_t *object_to_map(struct ps_prochandle *, Lmid_t, const char *);
56 static map_info_t *object_name_to_map(struct ps_prochandle *,
57 Lmid_t, const char *);
58 static GElf_Sym *sym_by_name(sym_tbl_t *, const char *, GElf_Sym *, uint_t *);
59 static int read_ehdr32(struct ps_prochandle *, Elf32_Ehdr *, uint_t *,
60 uintptr_t);
61 #ifdef _LP64
62 static int read_ehdr64(struct ps_prochandle *, Elf64_Ehdr *, uint_t *,
63 uintptr_t);
64 #endif
65 static uint32_t psym_crc32[] = { CRC32_TABLE };
66
67 #define DATA_TYPES \
68 ((1 << STT_OBJECT) | (1 << STT_FUNC) | \
69 (1 << STT_COMMON) | (1 << STT_TLS))
70 #define IS_DATA_TYPE(tp) (((1 << (tp)) & DATA_TYPES) != 0)
71
72 #define MA_RWX (MA_READ | MA_WRITE | MA_EXEC)
73
74 /*
75 * Minimum and maximum length of a build-id that we'll accept. Generally it's a
76 * 20 byte SHA1 and it's expected that the first byte (which is two ascii
77 * characters) indicates a directory and the remaining bytes become the file
78 * name. Therefore, our minimum length is at least 2 bytes (one for the
79 * directory and one for the name) and the max is a bit over the minimum -- 64,
80 * just in case folks do something odd. The string length is three times the max
81 * length. This accounts for the fact that each byte is two characters, a null
82 * terminator, and the directory '/' character.
83 */
84 #define MINBUILDID 2
85 #define MAXBUILDID 64
86 #define BUILDID_STRLEN (3*MAXBUILDID)
87 #define BUILDID_NAME ".note.gnu.build-id"
88 #define DBGLINK_NAME ".gnu_debuglink"
89
90 typedef enum {
91 PRO_NATURAL,
92 PRO_BYADDR,
93 PRO_BYNAME
94 } pr_order_t;
95
96 static int
97 addr_cmp(const void *aa, const void *bb)
98 {
99 uintptr_t a = *((uintptr_t *)aa);
100 uintptr_t b = *((uintptr_t *)bb);
101
102 if (a > b)
103 return (1);
104 if (a < b)
105 return (-1);
106 return (0);
107 }
108
109 /*
110 * This function creates a list of addresses for a load object's sections.
111 * The list is in ascending address order and alternates start address
112 * then end address for each section we're interested in. The function
113 * returns a pointer to the list, which must be freed by the caller.
114 */
115 static uintptr_t *
116 get_saddrs(struct ps_prochandle *P, uintptr_t ehdr_start, uint_t *n)
117 {
118 uintptr_t a, addr, *addrs, last = 0;
119 uint_t i, naddrs = 0, unordered = 0;
120
121 if (P->status.pr_dmodel == PR_MODEL_ILP32) {
122 Elf32_Ehdr ehdr;
123 Elf32_Phdr phdr;
124 uint_t phnum;
125
126 if (read_ehdr32(P, &ehdr, &phnum, ehdr_start) != 0)
127 return (NULL);
128
129 addrs = malloc(sizeof (uintptr_t) * phnum * 2);
130 a = ehdr_start + ehdr.e_phoff;
131 for (i = 0; i < phnum; i++, a += ehdr.e_phentsize) {
132 if (Pread(P, &phdr, sizeof (phdr), a) !=
133 sizeof (phdr)) {
134 free(addrs);
135 return (NULL);
136 }
137 if (phdr.p_type != PT_LOAD || phdr.p_memsz == 0)
138 continue;
139
140 addr = phdr.p_vaddr;
141 if (ehdr.e_type == ET_DYN)
142 addr += ehdr_start;
143 if (last > addr)
144 unordered = 1;
145 addrs[naddrs++] = addr;
146 addrs[naddrs++] = last = addr + phdr.p_memsz - 1;
147 }
148 #ifdef _LP64
149 } else {
150 Elf64_Ehdr ehdr;
151 Elf64_Phdr phdr;
152 uint_t phnum;
153
154 if (read_ehdr64(P, &ehdr, &phnum, ehdr_start) != 0)
155 return (NULL);
156
157 addrs = malloc(sizeof (uintptr_t) * phnum * 2);
158 a = ehdr_start + ehdr.e_phoff;
159 for (i = 0; i < phnum; i++, a += ehdr.e_phentsize) {
160 if (Pread(P, &phdr, sizeof (phdr), a) !=
161 sizeof (phdr)) {
162 free(addrs);
163 return (NULL);
164 }
165 if (phdr.p_type != PT_LOAD || phdr.p_memsz == 0)
166 continue;
167
168 addr = phdr.p_vaddr;
169 if (ehdr.e_type == ET_DYN)
170 addr += ehdr_start;
171 if (last > addr)
172 unordered = 1;
173 addrs[naddrs++] = addr;
174 addrs[naddrs++] = last = addr + phdr.p_memsz - 1;
175 }
176 #endif
177 }
178
179 if (unordered)
180 qsort(addrs, naddrs, sizeof (uintptr_t), addr_cmp);
181
182 *n = naddrs;
183 return (addrs);
184 }
185
186 /*
187 * Allocation function for a new file_info_t
188 */
189 file_info_t *
190 file_info_new(struct ps_prochandle *P, map_info_t *mptr)
191 {
192 file_info_t *fptr;
193 map_info_t *mp;
194 uintptr_t mstart, mend, sstart, send;
195 uint_t i;
196
197 if ((fptr = calloc(1, sizeof (file_info_t))) == NULL)
198 return (NULL);
199
200 list_link(fptr, &P->file_head);
201 (void) strcpy(fptr->file_pname, mptr->map_pmap.pr_mapname);
202 mptr->map_file = fptr;
203 fptr->file_ref = 1;
204 fptr->file_fd = -1;
205 fptr->file_dbgfile = -1;
206 P->num_files++;
207
208 /*
209 * To figure out which map_info_t instances correspond to the mappings
210 * for this load object we try to obtain the start and end address
211 * for each section of our in-memory ELF image. If successful, we
212 * walk down the list of addresses and the list of map_info_t
213 * instances in lock step to correctly find the mappings that
214 * correspond to this load object.
215 */
216 if ((fptr->file_saddrs = get_saddrs(P, mptr->map_pmap.pr_vaddr,
217 &fptr->file_nsaddrs)) == NULL)
218 return (fptr);
219
220 mp = P->mappings;
221 i = 0;
222 while (mp < P->mappings + P->map_count && i < fptr->file_nsaddrs) {
223
224 /* Calculate the start and end of the mapping and section */
225 mstart = mp->map_pmap.pr_vaddr;
226 mend = mp->map_pmap.pr_vaddr + mp->map_pmap.pr_size;
227 sstart = fptr->file_saddrs[i];
228 send = fptr->file_saddrs[i + 1];
229
230 if (mend <= sstart) {
231 /* This mapping is below the current section */
232 mp++;
233 } else if (mstart >= send) {
234 /* This mapping is above the current section */
235 i += 2;
236 } else {
237 /* This mapping overlaps the current section */
238 if (mp->map_file == NULL) {
239 dprintf("file_info_new: associating "
240 "segment at %p\n",
241 (void *)mp->map_pmap.pr_vaddr);
242 mp->map_file = fptr;
243 fptr->file_ref++;
244 } else {
245 dprintf("file_info_new: segment at %p "
246 "already associated with %s\n",
247 (void *)mp->map_pmap.pr_vaddr,
248 (mp == mptr ? "this file" :
249 mp->map_file->file_pname));
250 }
251 mp++;
252 }
253 }
254
255 return (fptr);
256 }
257
258 /*
259 * Deallocation function for a file_info_t
260 */
261 static void
262 file_info_free(struct ps_prochandle *P, file_info_t *fptr)
263 {
264 if (--fptr->file_ref == 0) {
265 list_unlink(fptr);
266 if (fptr->file_symtab.sym_elf) {
267 (void) elf_end(fptr->file_symtab.sym_elf);
268 free(fptr->file_symtab.sym_elfmem);
269 }
270 if (fptr->file_symtab.sym_byname)
271 free(fptr->file_symtab.sym_byname);
272 if (fptr->file_symtab.sym_byaddr)
273 free(fptr->file_symtab.sym_byaddr);
274
275 if (fptr->file_dynsym.sym_elf) {
276 (void) elf_end(fptr->file_dynsym.sym_elf);
277 free(fptr->file_dynsym.sym_elfmem);
278 }
279 if (fptr->file_dynsym.sym_byname)
280 free(fptr->file_dynsym.sym_byname);
281 if (fptr->file_dynsym.sym_byaddr)
282 free(fptr->file_dynsym.sym_byaddr);
283
284 if (fptr->file_lo)
285 free(fptr->file_lo);
286 if (fptr->file_lname)
287 free(fptr->file_lname);
288 if (fptr->file_rname)
289 free(fptr->file_rname);
290 if (fptr->file_elf)
291 (void) elf_end(fptr->file_elf);
292 if (fptr->file_elfmem != NULL)
293 free(fptr->file_elfmem);
294 if (fptr->file_fd >= 0)
295 (void) close(fptr->file_fd);
296 if (fptr->file_dbgelf)
297 (void) elf_end(fptr->file_dbgelf);
298 if (fptr->file_dbgfile >= 0)
299 (void) close(fptr->file_dbgfile);
300 if (fptr->file_ctfp) {
301 ctf_close(fptr->file_ctfp);
302 free(fptr->file_ctf_buf);
303 }
304 if (fptr->file_saddrs)
305 free(fptr->file_saddrs);
306 free(fptr);
307 P->num_files--;
308 }
309 }
310
311 /*
312 * Deallocation function for a map_info_t
313 */
314 static void
315 map_info_free(struct ps_prochandle *P, map_info_t *mptr)
316 {
317 file_info_t *fptr;
318
319 if ((fptr = mptr->map_file) != NULL) {
320 if (fptr->file_map == mptr)
321 fptr->file_map = NULL;
322 file_info_free(P, fptr);
323 }
324 if (P->execname && mptr == P->map_exec) {
325 free(P->execname);
326 P->execname = NULL;
327 }
328 if (P->auxv && (mptr == P->map_exec || mptr == P->map_ldso)) {
329 free(P->auxv);
330 P->auxv = NULL;
331 P->nauxv = 0;
332 }
333 if (mptr == P->map_exec)
334 P->map_exec = NULL;
335 if (mptr == P->map_ldso)
336 P->map_ldso = NULL;
337 }
338
339 /*
340 * Call-back function for librtld_db to iterate through all of its shared
341 * libraries. We use this to get the load object names for the mappings.
342 */
343 static int
344 map_iter(const rd_loadobj_t *lop, void *cd)
345 {
346 char buf[PATH_MAX];
347 struct ps_prochandle *P = cd;
348 map_info_t *mptr;
349 file_info_t *fptr;
350
351 dprintf("encountered rd object at %p\n", (void *)lop->rl_base);
352
353 if ((mptr = Paddr2mptr(P, lop->rl_base)) == NULL) {
354 dprintf("map_iter: base address doesn't match any mapping\n");
355 return (1); /* Base address does not match any mapping */
356 }
357
358 if ((fptr = mptr->map_file) == NULL &&
359 (fptr = file_info_new(P, mptr)) == NULL) {
360 dprintf("map_iter: failed to allocate a new file_info_t\n");
361 return (1); /* Failed to allocate a new file_info_t */
362 }
363
364 if ((fptr->file_lo == NULL) &&
365 (fptr->file_lo = malloc(sizeof (rd_loadobj_t))) == NULL) {
366 dprintf("map_iter: failed to allocate rd_loadobj_t\n");
367 file_info_free(P, fptr);
368 return (1); /* Failed to allocate rd_loadobj_t */
369 }
370
371 fptr->file_map = mptr;
372 *fptr->file_lo = *lop;
373
374 fptr->file_lo->rl_plt_base = fptr->file_plt_base;
375 fptr->file_lo->rl_plt_size = fptr->file_plt_size;
376
377 if (fptr->file_lname) {
378 free(fptr->file_lname);
379 fptr->file_lname = NULL;
380 fptr->file_lbase = NULL;
381 }
382 if (fptr->file_rname) {
383 free(fptr->file_rname);
384 fptr->file_rname = NULL;
385 fptr->file_rbase = NULL;
386 }
387
388 if (Pread_string(P, buf, sizeof (buf), lop->rl_nameaddr) > 0) {
389 if ((fptr->file_lname = strdup(buf)) != NULL)
390 fptr->file_lbase = basename(fptr->file_lname);
391 } else {
392 dprintf("map_iter: failed to read string at %p\n",
393 (void *)lop->rl_nameaddr);
394 }
395
396 if ((Pfindmap(P, mptr, buf, sizeof (buf)) != NULL) &&
397 ((fptr->file_rname = strdup(buf)) != NULL))
398 fptr->file_rbase = basename(fptr->file_rname);
399
400 dprintf("loaded rd object %s lmid %lx\n",
401 fptr->file_lname ? buf : "<NULL>", lop->rl_lmident);
402 return (1);
403 }
404
405 static void
406 map_set(struct ps_prochandle *P, map_info_t *mptr, const char *lname)
407 {
408 file_info_t *fptr;
409 char buf[PATH_MAX];
410
411 if ((fptr = mptr->map_file) == NULL &&
412 (fptr = file_info_new(P, mptr)) == NULL)
413 return; /* Failed to allocate a new file_info_t */
414
415 fptr->file_map = mptr;
416
417 if ((fptr->file_lo == NULL) &&
418 (fptr->file_lo = malloc(sizeof (rd_loadobj_t))) == NULL) {
419 file_info_free(P, fptr);
420 return; /* Failed to allocate rd_loadobj_t */
421 }
422
423 (void) memset(fptr->file_lo, 0, sizeof (rd_loadobj_t));
424 fptr->file_lo->rl_base = mptr->map_pmap.pr_vaddr;
425 fptr->file_lo->rl_bend =
426 mptr->map_pmap.pr_vaddr + mptr->map_pmap.pr_size;
427
428 fptr->file_lo->rl_plt_base = fptr->file_plt_base;
429 fptr->file_lo->rl_plt_size = fptr->file_plt_size;
430
431 if ((fptr->file_lname == NULL) &&
432 (fptr->file_lname = strdup(lname)) != NULL)
433 fptr->file_lbase = basename(fptr->file_lname);
434
435 if ((Pfindmap(P, mptr, buf, sizeof (buf)) != NULL) &&
436 ((fptr->file_rname = strdup(buf)) != NULL))
437 fptr->file_rbase = basename(fptr->file_rname);
438 }
439
440 static void
441 load_static_maps(struct ps_prochandle *P)
442 {
443 map_info_t *mptr;
444
445 /*
446 * Construct the map for the a.out.
447 */
448 if ((mptr = object_name_to_map(P, PR_LMID_EVERY, PR_OBJ_EXEC)) != NULL)
449 map_set(P, mptr, "a.out");
450
451 /*
452 * If the dynamic linker exists for this process,
453 * construct the map for it.
454 */
455 if (Pgetauxval(P, AT_BASE) != -1L &&
456 (mptr = object_name_to_map(P, PR_LMID_EVERY, PR_OBJ_LDSO)) != NULL)
457 map_set(P, mptr, "ld.so.1");
458 }
459
460 int
461 Preadmaps(struct ps_prochandle *P, prmap_t **Pmapp, ssize_t *nmapp)
462 {
463 return (P->ops.pop_read_maps(P, Pmapp, nmapp, P->data));
464 }
465
466 /*
467 * Go through all the address space mappings, validating or updating
468 * the information already gathered, or gathering new information.
469 *
470 * This function is only called when we suspect that the mappings have changed
471 * because this is the first time we're calling it or because of rtld activity.
472 */
473 void
474 Pupdate_maps(struct ps_prochandle *P)
475 {
476 prmap_t *Pmap = NULL;
477 prmap_t *pmap;
478 ssize_t nmap;
479 int i;
480 uint_t oldmapcount;
481 map_info_t *newmap, *newp;
482 map_info_t *mptr;
483
484 if (P->info_valid || P->state == PS_UNDEAD)
485 return;
486
487 Preadauxvec(P);
488
489 if (Preadmaps(P, &Pmap, &nmap) != 0)
490 return;
491
492 if ((newmap = calloc(1, nmap * sizeof (map_info_t))) == NULL)
493 return;
494
495 /*
496 * We try to merge any file information we may have for existing
497 * mappings, to avoid having to rebuild the file info.
498 */
499 mptr = P->mappings;
500 pmap = Pmap;
501 newp = newmap;
502 oldmapcount = P->map_count;
503 for (i = 0; i < nmap; i++, pmap++, newp++) {
504
505 if (oldmapcount == 0) {
506 /*
507 * We've exhausted all the old mappings. Every new
508 * mapping should be added.
509 */
510 newp->map_pmap = *pmap;
511
512 } else if (pmap->pr_vaddr == mptr->map_pmap.pr_vaddr &&
513 pmap->pr_size == mptr->map_pmap.pr_size &&
514 pmap->pr_offset == mptr->map_pmap.pr_offset &&
515 (pmap->pr_mflags & ~(MA_BREAK | MA_STACK)) ==
516 (mptr->map_pmap.pr_mflags & ~(MA_BREAK | MA_STACK)) &&
517 pmap->pr_pagesize == mptr->map_pmap.pr_pagesize &&
518 pmap->pr_shmid == mptr->map_pmap.pr_shmid &&
519 strcmp(pmap->pr_mapname, mptr->map_pmap.pr_mapname) == 0) {
520
521 /*
522 * This mapping matches exactly. Copy over the old
523 * mapping, taking care to get the latest flags.
524 * Make sure the associated file_info_t is updated
525 * appropriately.
526 */
527 *newp = *mptr;
528 if (P->map_exec == mptr)
529 P->map_exec = newp;
530 if (P->map_ldso == mptr)
531 P->map_ldso = newp;
532 newp->map_pmap.pr_mflags = pmap->pr_mflags;
533 if (mptr->map_file != NULL &&
534 mptr->map_file->file_map == mptr)
535 mptr->map_file->file_map = newp;
536 oldmapcount--;
537 mptr++;
538
539 } else if (pmap->pr_vaddr + pmap->pr_size >
540 mptr->map_pmap.pr_vaddr) {
541
542 /*
543 * The old mapping doesn't exist any more, remove it
544 * from the list.
545 */
546 map_info_free(P, mptr);
547 oldmapcount--;
548 i--;
549 newp--;
550 pmap--;
551 mptr++;
552
553 } else {
554
555 /*
556 * This is a new mapping, add it directly.
557 */
558 newp->map_pmap = *pmap;
559 }
560 }
561
562 /*
563 * Free any old maps
564 */
565 while (oldmapcount) {
566 map_info_free(P, mptr);
567 oldmapcount--;
568 mptr++;
569 }
570
571 free(Pmap);
572 if (P->mappings != NULL)
573 free(P->mappings);
574 P->mappings = newmap;
575 P->map_count = P->map_alloc = nmap;
576 P->info_valid = 1;
577
578 /*
579 * Consult librtld_db to get the load object
580 * names for all of the shared libraries.
581 */
582 if (P->rap != NULL)
583 (void) rd_loadobj_iter(P->rap, map_iter, P);
584 }
585
586 /*
587 * Update all of the mappings and rtld_db as if by Pupdate_maps(), and then
588 * forcibly cache all of the symbol tables associated with all object files.
589 */
590 void
591 Pupdate_syms(struct ps_prochandle *P)
592 {
593 file_info_t *fptr;
594 int i;
595
596 Pupdate_maps(P);
597
598 for (i = 0, fptr = list_next(&P->file_head); i < P->num_files;
599 i++, fptr = list_next(fptr)) {
600 Pbuild_file_symtab(P, fptr);
601 (void) Pbuild_file_ctf(P, fptr);
602 }
603 }
604
605 /*
606 * Return the librtld_db agent handle for the victim process.
607 * The handle will become invalid at the next successful exec() and the
608 * client (caller of proc_rd_agent()) must not use it beyond that point.
609 * If the process is already dead, we've already tried our best to
610 * create the agent during core file initialization.
611 */
612 rd_agent_t *
613 Prd_agent(struct ps_prochandle *P)
614 {
615 if (P->rap == NULL && P->state != PS_DEAD && P->state != PS_IDLE) {
616 Pupdate_maps(P);
617 if (P->num_files == 0)
618 load_static_maps(P);
619 rd_log(_libproc_debug);
620 if ((P->rap = rd_new(P)) != NULL)
621 (void) rd_loadobj_iter(P->rap, map_iter, P);
622 }
623 return (P->rap);
624 }
625
626 /*
627 * Return the prmap_t structure containing 'addr', but only if it
628 * is in the dynamic linker's link map and is the text section.
629 */
630 const prmap_t *
631 Paddr_to_text_map(struct ps_prochandle *P, uintptr_t addr)
632 {
633 map_info_t *mptr;
634
635 if (!P->info_valid)
636 Pupdate_maps(P);
637
638 if ((mptr = Paddr2mptr(P, addr)) != NULL) {
639 file_info_t *fptr = build_map_symtab(P, mptr);
640 const prmap_t *pmp = &mptr->map_pmap;
641
642 /*
643 * Assume that if rl_data_base is NULL, it means that no
644 * data section was found for this load object, and that
645 * a section must be text. Otherwise, a section will be
646 * text unless it ends above the start of the data
647 * section.
648 */
649 if (fptr != NULL && fptr->file_lo != NULL &&
650 (fptr->file_lo->rl_data_base == NULL ||
651 pmp->pr_vaddr + pmp->pr_size <=
652 fptr->file_lo->rl_data_base))
653 return (pmp);
654 }
655
656 return (NULL);
657 }
658
659 /*
660 * Return the prmap_t structure containing 'addr' (no restrictions on
661 * the type of mapping).
662 */
663 const prmap_t *
664 Paddr_to_map(struct ps_prochandle *P, uintptr_t addr)
665 {
666 map_info_t *mptr;
667
668 if (!P->info_valid)
669 Pupdate_maps(P);
670
671 if ((mptr = Paddr2mptr(P, addr)) != NULL)
672 return (&mptr->map_pmap);
673
674 return (NULL);
675 }
676
677 /*
678 * Convert a full or partial load object name to the prmap_t for its
679 * corresponding primary text mapping.
680 */
681 const prmap_t *
682 Plmid_to_map(struct ps_prochandle *P, Lmid_t lmid, const char *name)
683 {
684 map_info_t *mptr;
685
686 if (name == PR_OBJ_EVERY)
687 return (NULL); /* A reasonable mistake */
688
689 if ((mptr = object_name_to_map(P, lmid, name)) != NULL)
690 return (&mptr->map_pmap);
691
692 return (NULL);
693 }
694
695 const prmap_t *
696 Pname_to_map(struct ps_prochandle *P, const char *name)
697 {
698 return (Plmid_to_map(P, PR_LMID_EVERY, name));
699 }
700
701 const rd_loadobj_t *
702 Paddr_to_loadobj(struct ps_prochandle *P, uintptr_t addr)
703 {
704 map_info_t *mptr;
705
706 if (!P->info_valid)
707 Pupdate_maps(P);
708
709 if ((mptr = Paddr2mptr(P, addr)) == NULL)
710 return (NULL);
711
712 /*
713 * By building the symbol table, we implicitly bring the PLT
714 * information up to date in the load object.
715 */
716 (void) build_map_symtab(P, mptr);
717
718 return (mptr->map_file->file_lo);
719 }
720
721 const rd_loadobj_t *
722 Plmid_to_loadobj(struct ps_prochandle *P, Lmid_t lmid, const char *name)
723 {
724 map_info_t *mptr;
725
726 if (name == PR_OBJ_EVERY)
727 return (NULL);
728
729 if ((mptr = object_name_to_map(P, lmid, name)) == NULL)
730 return (NULL);
731
732 /*
733 * By building the symbol table, we implicitly bring the PLT
734 * information up to date in the load object.
735 */
736 (void) build_map_symtab(P, mptr);
737
738 return (mptr->map_file->file_lo);
739 }
740
741 const rd_loadobj_t *
742 Pname_to_loadobj(struct ps_prochandle *P, const char *name)
743 {
744 return (Plmid_to_loadobj(P, PR_LMID_EVERY, name));
745 }
746
747 ctf_file_t *
748 Pbuild_file_ctf(struct ps_prochandle *P, file_info_t *fptr)
749 {
750 ctf_sect_t ctdata, symtab, strtab;
751 sym_tbl_t *symp;
752 int err;
753
754 if (fptr->file_ctfp != NULL)
755 return (fptr->file_ctfp);
756
757 Pbuild_file_symtab(P, fptr);
758
759 if (fptr->file_ctf_size == 0)
760 return (NULL);
761
762 symp = fptr->file_ctf_dyn ? &fptr->file_dynsym : &fptr->file_symtab;
763 if (symp->sym_data_pri == NULL)
764 return (NULL);
765
766 /*
767 * The buffer may alread be allocated if this is a core file that
768 * contained CTF data for this file.
769 */
770 if (fptr->file_ctf_buf == NULL) {
771 fptr->file_ctf_buf = malloc(fptr->file_ctf_size);
772 if (fptr->file_ctf_buf == NULL) {
773 dprintf("failed to allocate ctf buffer\n");
774 return (NULL);
775 }
776
777 if (pread(fptr->file_fd, fptr->file_ctf_buf,
778 fptr->file_ctf_size, fptr->file_ctf_off) !=
779 fptr->file_ctf_size) {
780 free(fptr->file_ctf_buf);
781 fptr->file_ctf_buf = NULL;
782 dprintf("failed to read ctf data\n");
783 return (NULL);
784 }
785 }
786
787 ctdata.cts_name = ".SUNW_ctf";
788 ctdata.cts_type = SHT_PROGBITS;
789 ctdata.cts_flags = 0;
790 ctdata.cts_data = fptr->file_ctf_buf;
791 ctdata.cts_size = fptr->file_ctf_size;
792 ctdata.cts_entsize = 1;
793 ctdata.cts_offset = 0;
794
795 symtab.cts_name = fptr->file_ctf_dyn ? ".dynsym" : ".symtab";
796 symtab.cts_type = symp->sym_hdr_pri.sh_type;
797 symtab.cts_flags = symp->sym_hdr_pri.sh_flags;
798 symtab.cts_data = symp->sym_data_pri->d_buf;
799 symtab.cts_size = symp->sym_hdr_pri.sh_size;
800 symtab.cts_entsize = symp->sym_hdr_pri.sh_entsize;
801 symtab.cts_offset = symp->sym_hdr_pri.sh_offset;
802
803 strtab.cts_name = fptr->file_ctf_dyn ? ".dynstr" : ".strtab";
804 strtab.cts_type = symp->sym_strhdr.sh_type;
805 strtab.cts_flags = symp->sym_strhdr.sh_flags;
806 strtab.cts_data = symp->sym_strs;
807 strtab.cts_size = symp->sym_strhdr.sh_size;
808 strtab.cts_entsize = symp->sym_strhdr.sh_entsize;
809 strtab.cts_offset = symp->sym_strhdr.sh_offset;
810
811 fptr->file_ctfp = ctf_bufopen(&ctdata, &symtab, &strtab, &err);
812 if (fptr->file_ctfp == NULL) {
813 dprintf("ctf_bufopen() failed, error code %d\n", err);
814 free(fptr->file_ctf_buf);
815 fptr->file_ctf_buf = NULL;
816 return (NULL);
817 }
818
819 dprintf("loaded %lu bytes of CTF data for %s\n",
820 (ulong_t)fptr->file_ctf_size, fptr->file_pname);
821
822 return (fptr->file_ctfp);
823 }
824
825 ctf_file_t *
826 Paddr_to_ctf(struct ps_prochandle *P, uintptr_t addr)
827 {
828 map_info_t *mptr;
829 file_info_t *fptr;
830
831 if (!P->info_valid)
832 Pupdate_maps(P);
833
834 if ((mptr = Paddr2mptr(P, addr)) == NULL ||
835 (fptr = mptr->map_file) == NULL)
836 return (NULL);
837
838 return (Pbuild_file_ctf(P, fptr));
839 }
840
841 ctf_file_t *
842 Plmid_to_ctf(struct ps_prochandle *P, Lmid_t lmid, const char *name)
843 {
844 map_info_t *mptr;
845 file_info_t *fptr = NULL;
846
847 if (name == PR_OBJ_EVERY)
848 return (NULL);
849
850 /*
851 * While most idle files are all ELF objects, not all of them have
852 * mapping information available. There's nothing which would make
853 * sense to fake up for ET_REL. Instead, if we're being asked for their
854 * executable object and we know that the information is valid and they
855 * only have a single file, we jump straight to that file pointer.
856 */
857 if (P->state == PS_IDLE && name == PR_OBJ_EXEC && P->info_valid == 1 &&
858 P->num_files == 1 && P->mappings == NULL) {
859 fptr = list_next(&P->file_head);
860 }
861
862 if (fptr == NULL) {
863 if ((mptr = object_name_to_map(P, lmid, name)) == NULL ||
864 (fptr = mptr->map_file) == NULL)
865 return (NULL);
866 }
867
868 return (Pbuild_file_ctf(P, fptr));
869 }
870
871 ctf_file_t *
872 Pname_to_ctf(struct ps_prochandle *P, const char *name)
873 {
874 return (Plmid_to_ctf(P, PR_LMID_EVERY, name));
875 }
876
877 void
878 Preadauxvec(struct ps_prochandle *P)
879 {
880 if (P->auxv != NULL) {
881 free(P->auxv);
882 P->auxv = NULL;
883 P->nauxv = 0;
884 }
885
886 P->ops.pop_read_aux(P, &P->auxv, &P->nauxv, P->data);
887 }
888
889 /*
890 * Return a requested element from the process's aux vector.
891 * Return -1 on failure (this is adequate for our purposes).
892 */
893 long
894 Pgetauxval(struct ps_prochandle *P, int type)
895 {
896 auxv_t *auxv;
897
898 if (P->auxv == NULL)
899 Preadauxvec(P);
900
901 if (P->auxv == NULL)
902 return (-1);
903
904 for (auxv = P->auxv; auxv->a_type != AT_NULL; auxv++) {
905 if (auxv->a_type == type)
906 return (auxv->a_un.a_val);
907 }
908
909 return (-1);
910 }
911
912 /*
913 * Return a pointer to our internal copy of the process's aux vector.
914 * The caller should not hold on to this pointer across any libproc calls.
915 */
916 const auxv_t *
917 Pgetauxvec(struct ps_prochandle *P)
918 {
919 static const auxv_t empty = { AT_NULL, 0L };
920
921 if (P->auxv == NULL)
922 Preadauxvec(P);
923
924 if (P->auxv == NULL)
925 return (&empty);
926
927 return (P->auxv);
928 }
929
930 /*
931 * Return 1 if the given mapping corresponds to the given file_info_t's
932 * load object; return 0 otherwise.
933 */
934 static int
935 is_mapping_in_file(struct ps_prochandle *P, map_info_t *mptr, file_info_t *fptr)
936 {
937 prmap_t *pmap = &mptr->map_pmap;
938 rd_loadobj_t *lop = fptr->file_lo;
939 uint_t i;
940 uintptr_t mstart, mend, sstart, send;
941
942 /*
943 * We can get for free the start address of the text and data
944 * sections of the load object. Start by seeing if the mapping
945 * encloses either of these.
946 */
947 if ((pmap->pr_vaddr <= lop->rl_base &&
948 lop->rl_base < pmap->pr_vaddr + pmap->pr_size) ||
949 (pmap->pr_vaddr <= lop->rl_data_base &&
950 lop->rl_data_base < pmap->pr_vaddr + pmap->pr_size))
951 return (1);
952
953 /*
954 * It's still possible that this mapping correponds to the load
955 * object. Consider the example of a mapping whose start and end
956 * addresses correspond to those of the load object's text section.
957 * If the mapping splits, e.g. as a result of a segment demotion,
958 * then although both mappings are still backed by the same section,
959 * only one will be seen to enclose that section's start address.
960 * Thus, to be rigorous, we ask not whether this mapping encloses
961 * the start of a section, but whether there exists a section that
962 * overlaps this mapping.
963 *
964 * If we don't already have the section addresses, and we successfully
965 * get them, then we cache them in case we come here again.
966 */
967 if (fptr->file_saddrs == NULL &&
968 (fptr->file_saddrs = get_saddrs(P,
969 fptr->file_map->map_pmap.pr_vaddr, &fptr->file_nsaddrs)) == NULL)
970 return (0);
971
972 mstart = mptr->map_pmap.pr_vaddr;
973 mend = mptr->map_pmap.pr_vaddr + mptr->map_pmap.pr_size;
974 for (i = 0; i < fptr->file_nsaddrs; i += 2) {
975 /* Does this section overlap the mapping? */
976 sstart = fptr->file_saddrs[i];
977 send = fptr->file_saddrs[i + 1];
978 if (!(mend <= sstart || mstart >= send))
979 return (1);
980 }
981
982 return (0);
983 }
984
985 /*
986 * Find or build the symbol table for the given mapping.
987 */
988 static file_info_t *
989 build_map_symtab(struct ps_prochandle *P, map_info_t *mptr)
990 {
991 prmap_t *pmap = &mptr->map_pmap;
992 file_info_t *fptr;
993 uint_t i;
994
995 if ((fptr = mptr->map_file) != NULL) {
996 Pbuild_file_symtab(P, fptr);
997 return (fptr);
998 }
999
1000 if (pmap->pr_mapname[0] == '\0')
1001 return (NULL);
1002
1003 /*
1004 * Attempt to find a matching file.
1005 * (A file can be mapped at several different addresses.)
1006 */
1007 for (i = 0, fptr = list_next(&P->file_head); i < P->num_files;
1008 i++, fptr = list_next(fptr)) {
1009 if (strcmp(fptr->file_pname, pmap->pr_mapname) == 0 &&
1010 fptr->file_lo && is_mapping_in_file(P, mptr, fptr)) {
1011 mptr->map_file = fptr;
1012 fptr->file_ref++;
1013 Pbuild_file_symtab(P, fptr);
1014 return (fptr);
1015 }
1016 }
1017
1018 /*
1019 * If we need to create a new file_info structure, iterate
1020 * through the load objects in order to attempt to connect
1021 * this new file with its primary text mapping. We again
1022 * need to handle ld.so as a special case because we need
1023 * to be able to bootstrap librtld_db.
1024 */
1025 if ((fptr = file_info_new(P, mptr)) == NULL)
1026 return (NULL);
1027
1028 if (P->map_ldso != mptr) {
1029 if (P->rap != NULL)
1030 (void) rd_loadobj_iter(P->rap, map_iter, P);
1031 else
1032 (void) Prd_agent(P);
1033 } else {
1034 fptr->file_map = mptr;
1035 }
1036
1037 /*
1038 * If librtld_db wasn't able to help us connect the file to a primary
1039 * text mapping, set file_map to the current mapping because we require
1040 * fptr->file_map to be set in Pbuild_file_symtab. librtld_db may be
1041 * unaware of what's going on in the rare case that a legitimate ELF
1042 * file has been mmap(2)ed into the process address space *without*
1043 * the use of dlopen(3x).
1044 */
1045 if (fptr->file_map == NULL)
1046 fptr->file_map = mptr;
1047
1048 Pbuild_file_symtab(P, fptr);
1049
1050 return (fptr);
1051 }
1052
1053 static int
1054 read_ehdr32(struct ps_prochandle *P, Elf32_Ehdr *ehdr, uint_t *phnum,
1055 uintptr_t addr)
1056 {
1057 if (Pread(P, ehdr, sizeof (*ehdr), addr) != sizeof (*ehdr))
1058 return (-1);
1059
1060 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1061 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1062 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1063 ehdr->e_ident[EI_MAG3] != ELFMAG3 ||
1064 ehdr->e_ident[EI_CLASS] != ELFCLASS32 ||
1065 #ifdef _BIG_ENDIAN
1066 ehdr->e_ident[EI_DATA] != ELFDATA2MSB ||
1067 #else
1068 ehdr->e_ident[EI_DATA] != ELFDATA2LSB ||
1069 #endif
1070 ehdr->e_ident[EI_VERSION] != EV_CURRENT)
1071 return (-1);
1072
1073 if ((*phnum = ehdr->e_phnum) == PN_XNUM) {
1074 Elf32_Shdr shdr0;
1075
1076 if (ehdr->e_shoff == 0 || ehdr->e_shentsize < sizeof (shdr0) ||
1077 Pread(P, &shdr0, sizeof (shdr0), addr + ehdr->e_shoff) !=
1078 sizeof (shdr0))
1079 return (-1);
1080
1081 if (shdr0.sh_info != 0)
1082 *phnum = shdr0.sh_info;
1083 }
1084
1085 return (0);
1086 }
1087
1088 static int
1089 read_dynamic_phdr32(struct ps_prochandle *P, const Elf32_Ehdr *ehdr,
1090 uint_t phnum, Elf32_Phdr *phdr, uintptr_t addr)
1091 {
1092 uint_t i;
1093
1094 for (i = 0; i < phnum; i++) {
1095 uintptr_t a = addr + ehdr->e_phoff + i * ehdr->e_phentsize;
1096 if (Pread(P, phdr, sizeof (*phdr), a) != sizeof (*phdr))
1097 return (-1);
1098
1099 if (phdr->p_type == PT_DYNAMIC)
1100 return (0);
1101 }
1102
1103 return (-1);
1104 }
1105
1106 #ifdef _LP64
1107 static int
1108 read_ehdr64(struct ps_prochandle *P, Elf64_Ehdr *ehdr, uint_t *phnum,
1109 uintptr_t addr)
1110 {
1111 if (Pread(P, ehdr, sizeof (Elf64_Ehdr), addr) != sizeof (Elf64_Ehdr))
1112 return (-1);
1113
1114 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1115 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1116 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1117 ehdr->e_ident[EI_MAG3] != ELFMAG3 ||
1118 ehdr->e_ident[EI_CLASS] != ELFCLASS64 ||
1119 #ifdef _BIG_ENDIAN
1120 ehdr->e_ident[EI_DATA] != ELFDATA2MSB ||
1121 #else
1122 ehdr->e_ident[EI_DATA] != ELFDATA2LSB ||
1123 #endif
1124 ehdr->e_ident[EI_VERSION] != EV_CURRENT)
1125 return (-1);
1126
1127 if ((*phnum = ehdr->e_phnum) == PN_XNUM) {
1128 Elf64_Shdr shdr0;
1129
1130 if (ehdr->e_shoff == 0 || ehdr->e_shentsize < sizeof (shdr0) ||
1131 Pread(P, &shdr0, sizeof (shdr0), addr + ehdr->e_shoff) !=
1132 sizeof (shdr0))
1133 return (-1);
1134
1135 if (shdr0.sh_info != 0)
1136 *phnum = shdr0.sh_info;
1137 }
1138
1139 return (0);
1140 }
1141
1142 static int
1143 read_dynamic_phdr64(struct ps_prochandle *P, const Elf64_Ehdr *ehdr,
1144 uint_t phnum, Elf64_Phdr *phdr, uintptr_t addr)
1145 {
1146 uint_t i;
1147
1148 for (i = 0; i < phnum; i++) {
1149 uintptr_t a = addr + ehdr->e_phoff + i * ehdr->e_phentsize;
1150 if (Pread(P, phdr, sizeof (*phdr), a) != sizeof (*phdr))
1151 return (-1);
1152
1153 if (phdr->p_type == PT_DYNAMIC)
1154 return (0);
1155 }
1156
1157 return (-1);
1158 }
1159 #endif /* _LP64 */
1160
1161 /*
1162 * The text segment for each load object contains the elf header and
1163 * program headers. We can use this information to determine if the
1164 * file that corresponds to the load object is the same file that
1165 * was loaded into the process's address space. There can be a discrepency
1166 * if a file is recompiled after the process is started or if the target
1167 * represents a core file from a differently configured system -- two
1168 * common examples. The DT_CHECKSUM entry in the dynamic section
1169 * provides an easy method of comparison. It is important to note that
1170 * the dynamic section usually lives in the data segment, but the meta
1171 * data we use to find the dynamic section lives in the text segment so
1172 * if either of those segments is absent we can't proceed.
1173 *
1174 * We're looking through the elf file for several items: the symbol tables
1175 * (both dynsym and symtab), the procedure linkage table (PLT) base,
1176 * size, and relocation base, and the CTF information. Most of this can
1177 * be recovered from the loaded image of the file itself, the exceptions
1178 * being the symtab and CTF data.
1179 *
1180 * First we try to open the file that we think corresponds to the load
1181 * object, if the DT_CHECKSUM values match, we're all set, and can simply
1182 * recover all the information we need from the file. If the values of
1183 * DT_CHECKSUM don't match, or if we can't access the file for whatever
1184 * reasaon, we fake up a elf file to use in its stead. If we can't read
1185 * the elf data in the process's address space, we fall back to using
1186 * the file even though it may give inaccurate information.
1187 *
1188 * The elf file that we fake up has to consist of sections for the
1189 * dynsym, the PLT and the dynamic section. Note that in the case of a
1190 * core file, we'll get the CTF data in the file_info_t later on from
1191 * a section embedded the core file (if it's present).
1192 *
1193 * file_differs() conservatively looks for mismatched files, identifying
1194 * a match when there is any ambiguity (since that's the legacy behavior).
1195 */
1196 static int
1197 file_differs(struct ps_prochandle *P, Elf *elf, file_info_t *fptr)
1198 {
1199 Elf_Scn *scn;
1200 GElf_Shdr shdr;
1201 GElf_Dyn dyn;
1202 Elf_Data *data;
1203 uint_t i, ndyn;
1204 GElf_Xword cksum;
1205 uintptr_t addr;
1206
1207 if (fptr->file_map == NULL)
1208 return (0);
1209
1210 if ((Pcontent(P) & (CC_CONTENT_TEXT | CC_CONTENT_DATA)) !=
1211 (CC_CONTENT_TEXT | CC_CONTENT_DATA))
1212 return (0);
1213
1214 /*
1215 * First, we find the checksum value in the elf file.
1216 */
1217 scn = NULL;
1218 while ((scn = elf_nextscn(elf, scn)) != NULL) {
1219 if (gelf_getshdr(scn, &shdr) != NULL &&
1220 shdr.sh_type == SHT_DYNAMIC)
1221 goto found_shdr;
1222 }
1223 return (0);
1224
1225 found_shdr:
1226 if ((data = elf_getdata(scn, NULL)) == NULL)
1227 return (0);
1228
1229 if (P->status.pr_dmodel == PR_MODEL_ILP32)
1230 ndyn = shdr.sh_size / sizeof (Elf32_Dyn);
1231 #ifdef _LP64
1232 else if (P->status.pr_dmodel == PR_MODEL_LP64)
1233 ndyn = shdr.sh_size / sizeof (Elf64_Dyn);
1234 #endif
1235 else
1236 return (0);
1237
1238 for (i = 0; i < ndyn; i++) {
1239 if (gelf_getdyn(data, i, &dyn) != NULL &&
1240 dyn.d_tag == DT_CHECKSUM)
1241 goto found_cksum;
1242 }
1243
1244 /*
1245 * The in-memory ELF has no DT_CHECKSUM section, but we will report it
1246 * as matching the file anyhow.
1247 */
1248 return (0);
1249
1250 found_cksum:
1251 cksum = dyn.d_un.d_val;
1252 dprintf("elf cksum value is %llx\n", (u_longlong_t)cksum);
1253
1254 /*
1255 * Get the base of the text mapping that corresponds to this file.
1256 */
1257 addr = fptr->file_map->map_pmap.pr_vaddr;
1258
1259 if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1260 Elf32_Ehdr ehdr;
1261 Elf32_Phdr phdr;
1262 Elf32_Dyn dync, *dynp;
1263 uint_t phnum, i;
1264
1265 if (read_ehdr32(P, &ehdr, &phnum, addr) != 0 ||
1266 read_dynamic_phdr32(P, &ehdr, phnum, &phdr, addr) != 0)
1267 return (0);
1268
1269 if (ehdr.e_type == ET_DYN)
1270 phdr.p_vaddr += addr;
1271 if ((dynp = malloc(phdr.p_filesz)) == NULL)
1272 return (0);
1273 dync.d_tag = DT_NULL;
1274 if (Pread(P, dynp, phdr.p_filesz, phdr.p_vaddr) !=
1275 phdr.p_filesz) {
1276 free(dynp);
1277 return (0);
1278 }
1279
1280 for (i = 0; i < phdr.p_filesz / sizeof (Elf32_Dyn); i++) {
1281 if (dynp[i].d_tag == DT_CHECKSUM)
1282 dync = dynp[i];
1283 }
1284
1285 free(dynp);
1286
1287 if (dync.d_tag != DT_CHECKSUM)
1288 return (0);
1289
1290 dprintf("image cksum value is %llx\n",
1291 (u_longlong_t)dync.d_un.d_val);
1292 return (dync.d_un.d_val != cksum);
1293 #ifdef _LP64
1294 } else if (P->status.pr_dmodel == PR_MODEL_LP64) {
1295 Elf64_Ehdr ehdr;
1296 Elf64_Phdr phdr;
1297 Elf64_Dyn dync, *dynp;
1298 uint_t phnum, i;
1299
1300 if (read_ehdr64(P, &ehdr, &phnum, addr) != 0 ||
1301 read_dynamic_phdr64(P, &ehdr, phnum, &phdr, addr) != 0)
1302 return (0);
1303
1304 if (ehdr.e_type == ET_DYN)
1305 phdr.p_vaddr += addr;
1306 if ((dynp = malloc(phdr.p_filesz)) == NULL)
1307 return (0);
1308 dync.d_tag = DT_NULL;
1309 if (Pread(P, dynp, phdr.p_filesz, phdr.p_vaddr) !=
1310 phdr.p_filesz) {
1311 free(dynp);
1312 return (0);
1313 }
1314
1315 for (i = 0; i < phdr.p_filesz / sizeof (Elf64_Dyn); i++) {
1316 if (dynp[i].d_tag == DT_CHECKSUM)
1317 dync = dynp[i];
1318 }
1319
1320 free(dynp);
1321
1322 if (dync.d_tag != DT_CHECKSUM)
1323 return (0);
1324
1325 dprintf("image cksum value is %llx\n",
1326 (u_longlong_t)dync.d_un.d_val);
1327 return (dync.d_un.d_val != cksum);
1328 #endif /* _LP64 */
1329 }
1330
1331 return (0);
1332 }
1333
1334 /*
1335 * Read data from the specified process and construct an in memory
1336 * image of an ELF file that represents it well enough to let
1337 * us probe it for information.
1338 */
1339 static Elf *
1340 fake_elf(struct ps_prochandle *P, file_info_t *fptr)
1341 {
1342 Elf *elf;
1343 uintptr_t addr;
1344 uint_t phnum;
1345
1346 if (fptr->file_map == NULL)
1347 return (NULL);
1348
1349 if ((Pcontent(P) & (CC_CONTENT_TEXT | CC_CONTENT_DATA)) !=
1350 (CC_CONTENT_TEXT | CC_CONTENT_DATA))
1351 return (NULL);
1352
1353 addr = fptr->file_map->map_pmap.pr_vaddr;
1354
1355 if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1356 Elf32_Ehdr ehdr;
1357 Elf32_Phdr phdr;
1358
1359 if ((read_ehdr32(P, &ehdr, &phnum, addr) != 0) ||
1360 read_dynamic_phdr32(P, &ehdr, phnum, &phdr, addr) != 0)
1361 return (NULL);
1362
1363 elf = fake_elf32(P, fptr, addr, &ehdr, phnum, &phdr);
1364 #ifdef _LP64
1365 } else {
1366 Elf64_Ehdr ehdr;
1367 Elf64_Phdr phdr;
1368
1369 if (read_ehdr64(P, &ehdr, &phnum, addr) != 0 ||
1370 read_dynamic_phdr64(P, &ehdr, phnum, &phdr, addr) != 0)
1371 return (NULL);
1372
1373 elf = fake_elf64(P, fptr, addr, &ehdr, phnum, &phdr);
1374 #endif
1375 }
1376
1377 return (elf);
1378 }
1379
1380 /*
1381 * We wouldn't need these if qsort(3C) took an argument for the callback...
1382 */
1383 static mutex_t sort_mtx = DEFAULTMUTEX;
1384 static char *sort_strs;
1385 static GElf_Sym *sort_syms;
1386
1387 int
1388 byaddr_cmp_common(GElf_Sym *a, char *aname, GElf_Sym *b, char *bname)
1389 {
1390 if (a->st_value < b->st_value)
1391 return (-1);
1392 if (a->st_value > b->st_value)
1393 return (1);
1394
1395 /*
1396 * Prefer the function to the non-function.
1397 */
1398 if (GELF_ST_TYPE(a->st_info) != GELF_ST_TYPE(b->st_info)) {
1399 if (GELF_ST_TYPE(a->st_info) == STT_FUNC)
1400 return (-1);
1401 if (GELF_ST_TYPE(b->st_info) == STT_FUNC)
1402 return (1);
1403 }
1404
1405 /*
1406 * Prefer the weak or strong global symbol to the local symbol.
1407 */
1408 if (GELF_ST_BIND(a->st_info) != GELF_ST_BIND(b->st_info)) {
1409 if (GELF_ST_BIND(b->st_info) == STB_LOCAL)
1410 return (-1);
1411 if (GELF_ST_BIND(a->st_info) == STB_LOCAL)
1412 return (1);
1413 }
1414
1415 /*
1416 * Prefer the symbol that doesn't begin with a '$' since compilers and
1417 * other symbol generators often use it as a prefix.
1418 */
1419 if (*bname == '$')
1420 return (-1);
1421 if (*aname == '$')
1422 return (1);
1423
1424 /*
1425 * Prefer the name with fewer leading underscores in the name.
1426 */
1427 while (*aname == '_' && *bname == '_') {
1428 aname++;
1429 bname++;
1430 }
1431
1432 if (*bname == '_')
1433 return (-1);
1434 if (*aname == '_')
1435 return (1);
1436
1437 /*
1438 * Prefer the symbol with the smaller size.
1439 */
1440 if (a->st_size < b->st_size)
1441 return (-1);
1442 if (a->st_size > b->st_size)
1443 return (1);
1444
1445 /*
1446 * All other factors being equal, fall back to lexicographic order.
1447 */
1448 return (strcmp(aname, bname));
1449 }
1450
1451 static int
1452 byaddr_cmp(const void *aa, const void *bb)
1453 {
1454 GElf_Sym *a = &sort_syms[*(uint_t *)aa];
1455 GElf_Sym *b = &sort_syms[*(uint_t *)bb];
1456 char *aname = sort_strs + a->st_name;
1457 char *bname = sort_strs + b->st_name;
1458
1459 return (byaddr_cmp_common(a, aname, b, bname));
1460 }
1461
1462 static int
1463 byname_cmp(const void *aa, const void *bb)
1464 {
1465 GElf_Sym *a = &sort_syms[*(uint_t *)aa];
1466 GElf_Sym *b = &sort_syms[*(uint_t *)bb];
1467 char *aname = sort_strs + a->st_name;
1468 char *bname = sort_strs + b->st_name;
1469
1470 return (strcmp(aname, bname));
1471 }
1472
1473 /*
1474 * Given a symbol index, look up the corresponding symbol from the
1475 * given symbol table.
1476 *
1477 * This function allows the caller to treat the symbol table as a single
1478 * logical entity even though there may be 2 actual ELF symbol tables
1479 * involved. See the comments in Pcontrol.h for details.
1480 */
1481 static GElf_Sym *
1482 symtab_getsym(sym_tbl_t *symtab, int ndx, GElf_Sym *dst)
1483 {
1484 /* If index is in range of primary symtab, look it up there */
1485 if (ndx >= symtab->sym_symn_aux) {
1486 return (gelf_getsym(symtab->sym_data_pri,
1487 ndx - symtab->sym_symn_aux, dst));
1488 }
1489
1490 /* Not in primary: Look it up in the auxiliary symtab */
1491 return (gelf_getsym(symtab->sym_data_aux, ndx, dst));
1492 }
1493
1494 void
1495 optimize_symtab(sym_tbl_t *symtab)
1496 {
1497 GElf_Sym *symp, *syms;
1498 uint_t i, *indexa, *indexb;
1499 size_t symn, strsz, count;
1500
1501 if (symtab == NULL || symtab->sym_data_pri == NULL ||
1502 symtab->sym_byaddr != NULL)
1503 return;
1504
1505 symn = symtab->sym_symn;
1506 strsz = symtab->sym_strsz;
1507
1508 symp = syms = malloc(sizeof (GElf_Sym) * symn);
1509 if (symp == NULL) {
1510 dprintf("optimize_symtab: failed to malloc symbol array");
1511 return;
1512 }
1513
1514 /*
1515 * First record all the symbols into a table and count up the ones
1516 * that we're interested in. We mark symbols as invalid by setting
1517 * the st_name to an illegal value.
1518 */
1519 for (i = 0, count = 0; i < symn; i++, symp++) {
1520 if (symtab_getsym(symtab, i, symp) != NULL &&
1521 symp->st_name < strsz &&
1522 IS_DATA_TYPE(GELF_ST_TYPE(symp->st_info)))
1523 count++;
1524 else
1525 symp->st_name = strsz;
1526 }
1527
1528 /*
1529 * Allocate sufficient space for both tables and populate them
1530 * with the same symbols we just counted.
1531 */
1532 symtab->sym_count = count;
1533 indexa = symtab->sym_byaddr = calloc(sizeof (uint_t), count);
1534 indexb = symtab->sym_byname = calloc(sizeof (uint_t), count);
1535 if (indexa == NULL || indexb == NULL) {
1536 dprintf(
1537 "optimize_symtab: failed to malloc symbol index arrays");
1538 symtab->sym_count = 0;
1539 if (indexa != NULL) { /* First alloc succeeded. Free it */
1540 free(indexa);
1541 symtab->sym_byaddr = NULL;
1542 }
1543 free(syms);
1544 return;
1545 }
1546 for (i = 0, symp = syms; i < symn; i++, symp++) {
1547 if (symp->st_name < strsz)
1548 *indexa++ = *indexb++ = i;
1549 }
1550
1551 /*
1552 * Sort the two tables according to the appropriate criteria,
1553 * unless the user has overridden this behaviour.
1554 *
1555 * An example where we might not sort the tables is the relatively
1556 * unusual case of a process with very large symbol tables in which
1557 * we perform few lookups. In such a case the total time would be
1558 * dominated by the sort. It is difficult to determine a priori
1559 * how many lookups an arbitrary client will perform, and
1560 * hence whether the symbol tables should be sorted. We therefore
1561 * sort the tables by default, but provide the user with a
1562 * "chicken switch" in the form of the LIBPROC_NO_QSORT
1563 * environment variable.
1564 */
1565 if (!_libproc_no_qsort) {
1566 (void) mutex_lock(&sort_mtx);
1567 sort_strs = symtab->sym_strs;
1568 sort_syms = syms;
1569
1570 qsort(symtab->sym_byaddr, count, sizeof (uint_t), byaddr_cmp);
1571 qsort(symtab->sym_byname, count, sizeof (uint_t), byname_cmp);
1572
1573 sort_strs = NULL;
1574 sort_syms = NULL;
1575 (void) mutex_unlock(&sort_mtx);
1576 }
1577
1578 free(syms);
1579 }
1580
1581
1582 static Elf *
1583 build_fake_elf(struct ps_prochandle *P, file_info_t *fptr, GElf_Ehdr *ehdr,
1584 size_t *nshdrs, Elf_Data **shdata)
1585 {
1586 size_t shstrndx;
1587 Elf_Scn *scn;
1588 Elf *elf;
1589
1590 if ((elf = fake_elf(P, fptr)) == NULL ||
1591 elf_kind(elf) != ELF_K_ELF ||
1592 gelf_getehdr(elf, ehdr) == NULL ||
1593 elf_getshdrnum(elf, nshdrs) == -1 ||
1594 elf_getshdrstrndx(elf, &shstrndx) == -1 ||
1595 (scn = elf_getscn(elf, shstrndx)) == NULL ||
1596 (*shdata = elf_getdata(scn, NULL)) == NULL) {
1597 if (elf != NULL)
1598 (void) elf_end(elf);
1599 dprintf("failed to fake up ELF file\n");
1600 return (NULL);
1601 }
1602
1603 return (elf);
1604 }
1605
1606 /*
1607 * Try and find the file described by path in the file system and validate that
1608 * it matches our CRC before we try and process it for symbol information. If we
1609 * instead have an ELF data section, then that means we're checking a build-id
1610 * section instead. In that case we just need to find and bcmp the corresponding
1611 * section.
1612 *
1613 * Before we validate if it's a valid CRC or data section, we check to ensure
1614 * that it's a normal file and not anything else.
1615 */
1616 static boolean_t
1617 build_alt_debug(file_info_t *fptr, const char *path, uint32_t crc,
1618 Elf_Data *data)
1619 {
1620 int fd;
1621 struct stat st;
1622 Elf *elf;
1623 Elf_Scn *scn;
1624 GElf_Shdr symshdr, strshdr;
1625 Elf_Data *symdata, *strdata;
1626 boolean_t valid;
1627 uint32_t c = -1U;
1628
1629 if ((fd = open(path, O_RDONLY)) < 0)
1630 return (B_FALSE);
1631
1632 if (fstat(fd, &st) != 0) {
1633 (void) close(fd);
1634 return (B_FALSE);
1635 }
1636
1637 if (S_ISREG(st.st_mode) == 0) {
1638 (void) close(fd);
1639 return (B_FALSE);
1640 }
1641
1642 /*
1643 * Only check the CRC if we've come here through a GNU debug link
1644 * section as opposed to the build id. This is indicated by having the
1645 * value of data be NULL.
1646 */
1647 if (data == NULL) {
1648 for (;;) {
1649 char buf[4096];
1650 ssize_t ret = read(fd, buf, sizeof (buf));
1651 if (ret == -1) {
1652 if (ret == EINTR)
1653 continue;
1654 (void) close(fd);
1655 return (B_FALSE);
1656 }
1657 if (ret == 0) {
1658 c = ~c;
1659 if (c != crc) {
1660 dprintf("crc mismatch, found: 0x%x "
1661 "expected 0x%x\n", c, crc);
1662 (void) close(fd);
1663 return (B_FALSE);
1664 }
1665 break;
1666 }
1667 CRC32(c, buf, ret, c, psym_crc32);
1668 }
1669 }
1670
1671 elf = elf_begin(fd, ELF_C_READ, NULL);
1672 if (elf == NULL) {
1673 (void) close(fd);
1674 return (B_FALSE);
1675 }
1676
1677 if (elf_kind(elf) != ELF_K_ELF) {
1678 goto fail;
1679 }
1680
1681 /*
1682 * If we have a data section, that indicates we have a build-id which
1683 * means we need to find the corresponding build-id section and compare
1684 * it.
1685 */
1686 scn = NULL;
1687 valid = B_FALSE;
1688 for (scn = elf_nextscn(elf, scn); data != NULL && scn != NULL;
1689 scn = elf_nextscn(elf, scn)) {
1690 GElf_Shdr hdr;
1691 Elf_Data *ntdata;
1692
1693 if (gelf_getshdr(scn, &hdr) == NULL)
1694 goto fail;
1695
1696 if (hdr.sh_type != SHT_NOTE)
1697 continue;
1698
1699 if ((ntdata = elf_getdata(scn, NULL)) == NULL)
1700 goto fail;
1701
1702 /*
1703 * First verify the data section sizes are equal, then the
1704 * section name. If that's all true, then we can just do a bcmp.
1705 */
1706 if (data->d_size != ntdata->d_size)
1707 continue;
1708
1709 dprintf("found corresponding section in alternate file\n");
1710 if (bcmp(ntdata->d_buf, data->d_buf, data->d_size) != 0)
1711 goto fail;
1712
1713 valid = B_TRUE;
1714 break;
1715 }
1716 if (data != NULL && valid == B_FALSE) {
1717 dprintf("failed to find a matching %s section in %s\n",
1718 BUILDID_NAME, path);
1719 goto fail;
1720 }
1721
1722
1723 /*
1724 * Do two passes, first see if we have a symbol header, then see if we
1725 * can find the corresponding linked string table.
1726 */
1727 scn = NULL;
1728 for (scn = elf_nextscn(elf, scn); scn != NULL;
1729 scn = elf_nextscn(elf, scn)) {
1730
1731 if (gelf_getshdr(scn, &symshdr) == NULL)
1732 goto fail;
1733
1734 if (symshdr.sh_type != SHT_SYMTAB)
1735 continue;
1736
1737 if ((symdata = elf_getdata(scn, NULL)) == NULL)
1738 goto fail;
1739
1740 break;
1741 }
1742 if (scn == NULL)
1743 goto fail;
1744
1745 if ((scn = elf_getscn(elf, symshdr.sh_link)) == NULL)
1746 goto fail;
1747
1748 if (gelf_getshdr(scn, &strshdr) == NULL)
1749 goto fail;
1750
1751 if ((strdata = elf_getdata(scn, NULL)) == NULL)
1752 goto fail;
1753
1754 fptr->file_symtab.sym_data_pri = symdata;
1755 fptr->file_symtab.sym_symn += symshdr.sh_size / symshdr.sh_entsize;
1756 fptr->file_symtab.sym_strs = strdata->d_buf;
1757 fptr->file_symtab.sym_strsz = strdata->d_size;
1758 fptr->file_symtab.sym_hdr_pri = symshdr;
1759 fptr->file_symtab.sym_strhdr = strshdr;
1760
1761 dprintf("successfully loaded additional debug symbols for %s from %s\n",
1762 fptr->file_rname, path);
1763
1764 fptr->file_dbgfile = fd;
1765 fptr->file_dbgelf = elf;
1766 return (B_TRUE);
1767 fail:
1768 (void) elf_end(elf);
1769 (void) close(fd);
1770 return (B_FALSE);
1771 }
1772
1773 /*
1774 * We're here because the object in question has no symbol information, that's a
1775 * bit unfortunate. However, we've found that there's a .gnu_debuglink sitting
1776 * around. By convention that means that given the current location of the
1777 * object on disk, and the debug name that we found in the binary we need to
1778 * search the following locations for a matching file.
1779 *
1780 * <dirname>/.debug/<debug-name>
1781 * /usr/lib/debug/<dirname>/<debug-name>
1782 *
1783 * In the future, we should consider supporting looking in the prefix's
1784 * lib/debug directory for a matching object or supporting an arbitrary user
1785 * defined set of places to look.
1786 */
1787 static void
1788 find_alt_debuglink(file_info_t *fptr, const char *name, uint32_t crc)
1789 {
1790 boolean_t r;
1791 char *dup = NULL, *path = NULL, *dname;
1792
1793 dprintf("find_alt_debug: looking for %s, crc 0x%x\n", name, crc);
1794 if (fptr->file_rname == NULL) {
1795 dprintf("find_alt_debug: encountered null file_rname\n");
1796 return;
1797 }
1798
1799 dup = strdup(fptr->file_rname);
1800 if (dup == NULL)
1801 return;
1802
1803 dname = dirname(dup);
1804 if (asprintf(&path, "%s/.debug/%s", dname, name) != -1) {
1805 dprintf("attempting to load alternate debug information "
1806 "from %s\n", path);
1807 r = build_alt_debug(fptr, path, crc, NULL);
1808 free(path);
1809 if (r == B_TRUE)
1810 goto out;
1811 }
1812
1813 if (asprintf(&path, "/usr/lib/debug/%s/%s", dname, name) != -1) {
1814 dprintf("attempting to load alternate debug information "
1815 "from %s\n", path);
1816 r = build_alt_debug(fptr, path, crc, NULL);
1817 free(path);
1818 if (r == B_TRUE)
1819 goto out;
1820 }
1821 out:
1822 free(dup);
1823 }
1824
1825 /*
1826 * Build the symbol table for the given mapped file.
1827 */
1828 void
1829 Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr)
1830 {
1831 char objectfile[PATH_MAX];
1832 uint_t i;
1833
1834 GElf_Ehdr ehdr;
1835 GElf_Sym s;
1836
1837 Elf_Data *shdata;
1838 Elf_Scn *scn;
1839 Elf *elf;
1840 size_t nshdrs, shstrndx;
1841
1842 struct {
1843 GElf_Shdr c_shdr;
1844 Elf_Data *c_data;
1845 const char *c_name;
1846 } *cp, *cache = NULL, *dyn = NULL, *plt = NULL, *ctf = NULL,
1847 *dbglink = NULL, *buildid = NULL;
1848
1849 if (fptr->file_init)
1850 return; /* We've already processed this file */
1851
1852 /*
1853 * Mark the file_info struct as having the symbol table initialized
1854 * even if we fail below. We tried once; we don't try again.
1855 */
1856 fptr->file_init = 1;
1857
1858 if (elf_version(EV_CURRENT) == EV_NONE) {
1859 dprintf("libproc ELF version is more recent than libelf\n");
1860 return;
1861 }
1862
1863 if (P->state == PS_DEAD || P->state == PS_IDLE) {
1864 char *name;
1865 /*
1866 * If we're a not live, we can't open files from the /proc
1867 * object directory; we have only the mapping and file names
1868 * to guide us. We prefer the file_lname, but need to handle
1869 * the case of it being NULL in order to bootstrap: we first
1870 * come here during rd_new() when the only information we have
1871 * is interpreter name associated with the AT_BASE mapping.
1872 *
1873 * Also, if the zone associated with the core file seems
1874 * to exists on this machine we'll try to open the object
1875 * file within the zone.
1876 */
1877 if (fptr->file_rname != NULL)
1878 name = fptr->file_rname;
1879 else if (fptr->file_lname != NULL)
1880 name = fptr->file_lname;
1881 else
1882 name = fptr->file_pname;
1883 (void) strlcpy(objectfile, name, sizeof (objectfile));
1884 } else {
1885 (void) snprintf(objectfile, sizeof (objectfile),
1886 "%s/%d/object/%s",
1887 procfs_path, (int)P->pid, fptr->file_pname);
1888 }
1889
1890 /*
1891 * Open the object file, create the elf file, and then get the elf
1892 * header and .shstrtab data buffer so we can process sections by
1893 * name. If anything goes wrong try to fake up an elf file from
1894 * the in-core elf image.
1895 */
1896
1897 if (_libproc_incore_elf || (P->flags & INCORE)) {
1898 dprintf("Pbuild_file_symtab: using in-core data for: %s\n",
1899 fptr->file_pname);
1900
1901 if ((elf = build_fake_elf(P, fptr, &ehdr, &nshdrs, &shdata)) ==
1902 NULL)
1903 return;
1904
1905 } else if ((fptr->file_fd = open(objectfile, O_RDONLY)) < 0) {
1906 dprintf("Pbuild_file_symtab: failed to open %s: %s\n",
1907 objectfile, strerror(errno));
1908
1909 if ((elf = build_fake_elf(P, fptr, &ehdr, &nshdrs, &shdata)) ==
1910 NULL)
1911 return;
1912
1913 } else if ((elf = elf_begin(fptr->file_fd, ELF_C_READ, NULL)) == NULL ||
1914 elf_kind(elf) != ELF_K_ELF ||
1915 gelf_getehdr(elf, &ehdr) == NULL ||
1916 elf_getshdrnum(elf, &nshdrs) == -1 ||
1917 elf_getshdrstrndx(elf, &shstrndx) == -1 ||
1918 (scn = elf_getscn(elf, shstrndx)) == NULL ||
1919 (shdata = elf_getdata(scn, NULL)) == NULL) {
1920 int err = elf_errno();
1921
1922 dprintf("failed to process ELF file %s: %s\n",
1923 objectfile, (err == 0) ? "<null>" : elf_errmsg(err));
1924 (void) elf_end(elf);
1925
1926 if ((elf = build_fake_elf(P, fptr, &ehdr, &nshdrs, &shdata)) ==
1927 NULL)
1928 return;
1929
1930 } else if (file_differs(P, elf, fptr)) {
1931 Elf *newelf;
1932
1933 /*
1934 * Before we get too excited about this elf file, we'll check
1935 * its checksum value against the value we have in memory. If
1936 * they don't agree, we try to fake up a new elf file and
1937 * proceed with that instead.
1938 */
1939 dprintf("ELF file %s (%lx) doesn't match in-core image\n",
1940 fptr->file_pname,
1941 (ulong_t)fptr->file_map->map_pmap.pr_vaddr);
1942
1943 if ((newelf = build_fake_elf(P, fptr, &ehdr, &nshdrs, &shdata))
1944 != NULL) {
1945 (void) elf_end(elf);
1946 elf = newelf;
1947 dprintf("switched to faked up ELF file\n");
1948
1949 /*
1950 * Check to see if the file that we just discovered
1951 * to be an imposter matches the execname that was
1952 * determined by Pfindexec(). If it does, we (clearly)
1953 * don't have the right binary, and we zero out
1954 * execname before anyone gets hurt.
1955 */
1956 if (fptr->file_rname != NULL && P->execname != NULL &&
1957 strcmp(fptr->file_rname, P->execname) == 0) {
1958 dprintf("file/in-core image mismatch was "
1959 "on P->execname; discarding\n");
1960 free(P->execname);
1961 P->execname = NULL;
1962 }
1963 }
1964 }
1965
1966 if ((cache = malloc(nshdrs * sizeof (*cache))) == NULL) {
1967 dprintf("failed to malloc section cache for %s\n", objectfile);
1968 goto bad;
1969 }
1970
1971 dprintf("processing ELF file %s\n", objectfile);
1972 fptr->file_class = ehdr.e_ident[EI_CLASS];
1973 fptr->file_etype = ehdr.e_type;
1974 fptr->file_elf = elf;
1975 fptr->file_shstrs = shdata->d_buf;
1976 fptr->file_shstrsz = shdata->d_size;
1977
1978 /*
1979 * Iterate through each section, caching its section header, data
1980 * pointer, and name. We use this for handling sh_link values below.
1981 */
1982 for (cp = cache + 1, scn = NULL; scn = elf_nextscn(elf, scn); cp++) {
1983 if (gelf_getshdr(scn, &cp->c_shdr) == NULL) {
1984 dprintf("Pbuild_file_symtab: Failed to get section "
1985 "header\n");
1986 goto bad; /* Failed to get section header */
1987 }
1988
1989 if ((cp->c_data = elf_getdata(scn, NULL)) == NULL) {
1990 dprintf("Pbuild_file_symtab: Failed to get section "
1991 "data\n");
1992 goto bad; /* Failed to get section data */
1993 }
1994
1995 if (cp->c_shdr.sh_name >= shdata->d_size) {
1996 dprintf("Pbuild_file_symtab: corrupt section name");
1997 goto bad; /* Corrupt section name */
1998 }
1999
2000 cp->c_name = (const char *)shdata->d_buf + cp->c_shdr.sh_name;
2001 }
2002
2003 /*
2004 * Now iterate through the section cache in order to locate info
2005 * for the .symtab, .dynsym, .SUNW_ldynsym, .dynamic, .plt,
2006 * and .SUNW_ctf sections:
2007 */
2008 for (i = 1, cp = cache + 1; i < nshdrs; i++, cp++) {
2009 GElf_Shdr *shp = &cp->c_shdr;
2010
2011 if (shp->sh_type == SHT_SYMTAB || shp->sh_type == SHT_DYNSYM) {
2012 sym_tbl_t *symp = shp->sh_type == SHT_SYMTAB ?
2013 &fptr->file_symtab : &fptr->file_dynsym;
2014 /*
2015 * It's possible that the we already got the symbol
2016 * table from the core file itself. Either the file
2017 * differs in which case our faked up elf file will
2018 * only contain the dynsym (not the symtab) or the
2019 * file matches in which case we'll just be replacing
2020 * the symbol table we pulled out of the core file
2021 * with an equivalent one. In either case, this
2022 * check isn't essential, but it's a good idea.
2023 */
2024 if (symp->sym_data_pri == NULL) {
2025 dprintf("Symbol table found for %s\n",
2026 objectfile);
2027 symp->sym_data_pri = cp->c_data;
2028 symp->sym_symn +=
2029 shp->sh_size / shp->sh_entsize;
2030 symp->sym_strs =
2031 cache[shp->sh_link].c_data->d_buf;
2032 symp->sym_strsz =
2033 cache[shp->sh_link].c_data->d_size;
2034 symp->sym_hdr_pri = cp->c_shdr;
2035 symp->sym_strhdr = cache[shp->sh_link].c_shdr;
2036 } else {
2037 dprintf("Symbol table already there for %s\n",
2038 objectfile);
2039 }
2040 } else if (shp->sh_type == SHT_SUNW_LDYNSYM) {
2041 /* .SUNW_ldynsym section is auxiliary to .dynsym */
2042 if (fptr->file_dynsym.sym_data_aux == NULL) {
2043 dprintf(".SUNW_ldynsym symbol table"
2044 " found for %s\n", objectfile);
2045 fptr->file_dynsym.sym_data_aux = cp->c_data;
2046 fptr->file_dynsym.sym_symn_aux =
2047 shp->sh_size / shp->sh_entsize;
2048 fptr->file_dynsym.sym_symn +=
2049 fptr->file_dynsym.sym_symn_aux;
2050 fptr->file_dynsym.sym_hdr_aux = cp->c_shdr;
2051 } else {
2052 dprintf(".SUNW_ldynsym symbol table already"
2053 " there for %s\n", objectfile);
2054 }
2055 } else if (shp->sh_type == SHT_DYNAMIC) {
2056 dyn = cp;
2057 } else if (strcmp(cp->c_name, ".plt") == 0) {
2058 plt = cp;
2059 } else if (strcmp(cp->c_name, ".SUNW_ctf") == 0) {
2060 /*
2061 * Skip over bogus CTF sections so they don't come back
2062 * to haunt us later.
2063 */
2064 if (shp->sh_link == 0 ||
2065 shp->sh_link >= nshdrs ||
2066 (cache[shp->sh_link].c_shdr.sh_type != SHT_DYNSYM &&
2067 cache[shp->sh_link].c_shdr.sh_type != SHT_SYMTAB)) {
2068 dprintf("Bad sh_link %d for "
2069 "CTF\n", shp->sh_link);
2070 continue;
2071 }
2072 ctf = cp;
2073 } else if (strcmp(cp->c_name, BUILDID_NAME) == 0) {
2074 dprintf("Found a %s section for %s\n", BUILDID_NAME,
2075 fptr->file_rname);
2076 /* The ElfXX_Nhdr is 32/64-bit neutral */
2077 if (cp->c_shdr.sh_type == SHT_NOTE &&
2078 cp->c_data->d_buf != NULL &&
2079 cp->c_data->d_size >= sizeof (Elf32_Nhdr)) {
2080 Elf32_Nhdr *hdr = cp->c_data->d_buf;
2081 if (hdr->n_type != 3)
2082 continue;
2083 if (hdr->n_namesz != 4)
2084 continue;
2085 if (hdr->n_descsz < MINBUILDID)
2086 continue;
2087 /* Set a reasonable upper bound */
2088 if (hdr->n_descsz > MAXBUILDID) {
2089 dprintf("Skipped %s as too large "
2090 "(%ld)\n", BUILDID_NAME,
2091 (unsigned long)hdr->n_descsz);
2092 continue;
2093 }
2094
2095 if (cp->c_data->d_size < sizeof (hdr) +
2096 hdr->n_namesz + hdr->n_descsz)
2097 continue;
2098 buildid = cp;
2099 }
2100 } else if (strcmp(cp->c_name, DBGLINK_NAME) == 0) {
2101 dprintf("found %s section for %s\n", DBGLINK_NAME,
2102 fptr->file_rname);
2103 /*
2104 * Let's make sure of a few things before we do this.
2105 */
2106 if (cp->c_shdr.sh_type == SHT_PROGBITS &&
2107 cp->c_data->d_buf != NULL &&
2108 cp->c_data->d_size) {
2109 dbglink = cp;
2110 }
2111 }
2112 }
2113
2114 /*
2115 * If we haven't found any symbol table information and we have found
2116 * either a .note.gnu.build-id or a .gnu_debuglink, it's time to try and
2117 * figure out where we might find this. Originally, GNU used the
2118 * .gnu_debuglink solely, but then they added a .note.gnu.build-id. The
2119 * build-id is some size, usually 16 or 20 bytes, often a SHA1 sum of
2120 * the old, but not present file. All that you have to do to compare
2121 * things is see if the sections are less, in theory saving you from
2122 * doing lots of expensive I/O.
2123 *
2124 * For the .note.gnu.build-id, we're going to check a few things before
2125 * using it, first that the name is 4 bytes, and is GNU and that the
2126 * type is 3, which they say is the build-id identifier.
2127 *
2128 * To verify that the elf data for the .gnu_debuglink seems somewhat
2129 * sane, eg. the elf data should be a string, so we want to verify we
2130 * have a null-terminator.
2131 */
2132 if (fptr->file_symtab.sym_data_pri == NULL && buildid != NULL) {
2133 int i, bo;
2134 uint8_t *dp;
2135 char buf[BUILDID_STRLEN], *path;
2136 Elf32_Nhdr *hdr = buildid->c_data->d_buf;
2137
2138 /*
2139 * This was checked for validity when assigning the buildid
2140 * variable.
2141 */
2142 bzero(buf, sizeof (buf));
2143 dp = (uint8_t *)((uintptr_t)hdr + sizeof (*hdr) +
2144 hdr->n_namesz);
2145 for (i = 0, bo = 0; i < hdr->n_descsz; i++, bo += 2, dp++) {
2146 assert(sizeof (buf) - bo > 0);
2147
2148 /*
2149 * Recall that the build-id is structured as a series of
2150 * bytes. However, the first two characters are supposed
2151 * to represent a directory. Hence, once we reach offset
2152 * two, we insert a '/' character.
2153 */
2154 if (bo == 2) {
2155 buf[bo] = '/';
2156 bo++;
2157 }
2158 (void) snprintf(buf + bo, sizeof (buf) - bo, "%2x",
2159 *dp);
2160 }
2161
2162 if (asprintf(&path, "/usr/lib/debug/.build-id/%s.debug",
2163 buf) != -1) {
2164 boolean_t r;
2165 dprintf("attempting to find build id alternate debug "
2166 "file at %s\n", path);
2167 r = build_alt_debug(fptr, path, 0, buildid->c_data);
2168 dprintf("attempt %s\n", r == B_TRUE ?
2169 "succeeded" : "failed");
2170 free(path);
2171 } else {
2172 dprintf("failed to construct build id path: %s\n",
2173 strerror(errno));
2174 }
2175 }
2176
2177 if (fptr->file_symtab.sym_data_pri == NULL && dbglink != NULL) {
2178 char *c = dbglink->c_data->d_buf;
2179 size_t i;
2180 boolean_t found = B_FALSE;
2181 Elf_Data *ed = dbglink->c_data;
2182 uint32_t crc;
2183
2184 for (i = 0; i < ed->d_size; i++) {
2185 if (c[i] == '\0') {
2186 uintptr_t off;
2187 dprintf("got .gnu_debuglink terminator at "
2188 "offset %lu\n", (unsigned long)i);
2189 /*
2190 * After the null terminator, there should be
2191 * padding, followed by a 4 byte CRC of the
2192 * file. If we don't see this, we're going to
2193 * assume this is bogus.
2194 */
2195 if ((i % sizeof (uint32_t)) == 0) {
2196 i += 4;
2197 } else {
2198 i += sizeof (uint32_t) -
2199 (i % sizeof (uint32_t));
2200 }
2201 if (i + sizeof (uint32_t) ==
2202 dbglink->c_data->d_size) {
2203 found = B_TRUE;
2204 off = (uintptr_t)ed->d_buf + i;
2205 crc = *(uint32_t *)off;
2206 } else {
2207 dprintf(".gnu_debuglink size mismatch, "
2208 "expected: %lu, found: %lu\n",
2209 (unsigned long)i,
2210 (unsigned long)ed->d_size);
2211 }
2212 break;
2213 }
2214 }
2215
2216 if (found == B_TRUE)
2217 find_alt_debuglink(fptr, dbglink->c_data->d_buf, crc);
2218 }
2219
2220 /*
2221 * At this point, we've found all the symbol tables we're ever going
2222 * to find: the ones in the loop above and possibly the symtab that
2223 * was included in the core file. Before we perform any lookups, we
2224 * create sorted versions to optimize for lookups.
2225 */
2226 optimize_symtab(&fptr->file_symtab);
2227 optimize_symtab(&fptr->file_dynsym);
2228
2229 /*
2230 * Fill in the base address of the text mapping for shared libraries.
2231 * This allows us to translate symbols before librtld_db is ready.
2232 */
2233 if (fptr->file_etype == ET_DYN) {
2234 fptr->file_dyn_base = fptr->file_map->map_pmap.pr_vaddr -
2235 fptr->file_map->map_pmap.pr_offset;
2236 dprintf("setting file_dyn_base for %s to %lx\n",
2237 objectfile, (long)fptr->file_dyn_base);
2238 }
2239
2240 /*
2241 * Record the CTF section information in the file info structure.
2242 */
2243 if (ctf != NULL) {
2244 fptr->file_ctf_off = ctf->c_shdr.sh_offset;
2245 fptr->file_ctf_size = ctf->c_shdr.sh_size;
2246 if (ctf->c_shdr.sh_link != 0 &&
2247 cache[ctf->c_shdr.sh_link].c_shdr.sh_type == SHT_DYNSYM)
2248 fptr->file_ctf_dyn = 1;
2249 }
2250
2251 if (fptr->file_lo == NULL)
2252 goto done; /* Nothing else to do if no load object info */
2253
2254 /*
2255 * If the object is a shared library and we have a different rl_base
2256 * value, reset file_dyn_base according to librtld_db's information.
2257 */
2258 if (fptr->file_etype == ET_DYN &&
2259 fptr->file_lo->rl_base != fptr->file_dyn_base) {
2260 dprintf("resetting file_dyn_base for %s to %lx\n",
2261 objectfile, (long)fptr->file_lo->rl_base);
2262 fptr->file_dyn_base = fptr->file_lo->rl_base;
2263 }
2264
2265 /*
2266 * Fill in the PLT information for this file if a PLT symbol is found.
2267 */
2268 if (sym_by_name(&fptr->file_dynsym, "_PROCEDURE_LINKAGE_TABLE_", &s,
2269 NULL) != NULL) {
2270 fptr->file_plt_base = s.st_value + fptr->file_dyn_base;
2271 fptr->file_plt_size = (plt != NULL) ? plt->c_shdr.sh_size : 0;
2272
2273 /*
2274 * Bring the load object up to date; it is the only way the
2275 * user has to access the PLT data. The PLT information in the
2276 * rd_loadobj_t is not set in the call to map_iter() (the
2277 * callback for rd_loadobj_iter) where we set file_lo.
2278 */
2279 fptr->file_lo->rl_plt_base = fptr->file_plt_base;
2280 fptr->file_lo->rl_plt_size = fptr->file_plt_size;
2281
2282 dprintf("PLT found at %p, size = %lu\n",
2283 (void *)fptr->file_plt_base, (ulong_t)fptr->file_plt_size);
2284 }
2285
2286 /*
2287 * Fill in the PLT information.
2288 */
2289 if (dyn != NULL) {
2290 uintptr_t dynaddr = dyn->c_shdr.sh_addr + fptr->file_dyn_base;
2291 size_t ndyn = dyn->c_shdr.sh_size / dyn->c_shdr.sh_entsize;
2292 GElf_Dyn d;
2293
2294 for (i = 0; i < ndyn; i++) {
2295 if (gelf_getdyn(dyn->c_data, i, &d) == NULL)
2296 continue;
2297
2298 switch (d.d_tag) {
2299 case DT_JMPREL:
2300 dprintf("DT_JMPREL is %p\n",
2301 (void *)(uintptr_t)d.d_un.d_ptr);
2302 fptr->file_jmp_rel =
2303 d.d_un.d_ptr + fptr->file_dyn_base;
2304 break;
2305 case DT_STRTAB:
2306 dprintf("DT_STRTAB is %p\n",
2307 (void *)(uintptr_t)d.d_un.d_ptr);
2308 break;
2309 case DT_PLTGOT:
2310 dprintf("DT_PLTGOT is %p\n",
2311 (void *)(uintptr_t)d.d_un.d_ptr);
2312 break;
2313 case DT_SUNW_SYMTAB:
2314 dprintf("DT_SUNW_SYMTAB is %p\n",
2315 (void *)(uintptr_t)d.d_un.d_ptr);
2316 break;
2317 case DT_SYMTAB:
2318 dprintf("DT_SYMTAB is %p\n",
2319 (void *)(uintptr_t)d.d_un.d_ptr);
2320 break;
2321 case DT_HASH:
2322 dprintf("DT_HASH is %p\n",
2323 (void *)(uintptr_t)d.d_un.d_ptr);
2324 break;
2325 }
2326 }
2327
2328 dprintf("_DYNAMIC found at %p, %lu entries, DT_JMPREL = %p\n",
2329 (void *)dynaddr, (ulong_t)ndyn, (void *)fptr->file_jmp_rel);
2330 }
2331
2332 done:
2333 free(cache);
2334 return;
2335
2336 bad:
2337 if (cache != NULL)
2338 free(cache);
2339
2340 (void) elf_end(elf);
2341 fptr->file_elf = NULL;
2342 if (fptr->file_elfmem != NULL) {
2343 free(fptr->file_elfmem);
2344 fptr->file_elfmem = NULL;
2345 }
2346 (void) close(fptr->file_fd);
2347 if (fptr->file_dbgelf != NULL)
2348 (void) elf_end(fptr->file_dbgelf);
2349 fptr->file_dbgelf = NULL;
2350 if (fptr->file_dbgfile >= 0)
2351 (void) close(fptr->file_dbgfile);
2352 fptr->file_fd = -1;
2353 fptr->file_dbgfile = -1;
2354 }
2355
2356 /*
2357 * Given a process virtual address, return the map_info_t containing it.
2358 * If none found, return NULL.
2359 */
2360 map_info_t *
2361 Paddr2mptr(struct ps_prochandle *P, uintptr_t addr)
2362 {
2363 int lo = 0;
2364 int hi = P->map_count - 1;
2365 int mid;
2366 map_info_t *mp;
2367
2368 while (lo <= hi) {
2369
2370 mid = (lo + hi) / 2;
2371 mp = &P->mappings[mid];
2372
2373 /* check that addr is in [vaddr, vaddr + size) */
2374 if ((addr - mp->map_pmap.pr_vaddr) < mp->map_pmap.pr_size)
2375 return (mp);
2376
2377 if (addr < mp->map_pmap.pr_vaddr)
2378 hi = mid - 1;
2379 else
2380 lo = mid + 1;
2381 }
2382
2383 return (NULL);
2384 }
2385
2386 /*
2387 * Return the map_info_t for the executable file.
2388 * If not found, return NULL.
2389 */
2390 static map_info_t *
2391 exec_map(struct ps_prochandle *P)
2392 {
2393 uint_t i;
2394 map_info_t *mptr;
2395 map_info_t *mold = NULL;
2396 file_info_t *fptr;
2397 uintptr_t base;
2398
2399 for (i = 0, mptr = P->mappings; i < P->map_count; i++, mptr++) {
2400 if (mptr->map_pmap.pr_mapname[0] == '\0')
2401 continue;
2402 if (strcmp(mptr->map_pmap.pr_mapname, "a.out") == 0) {
2403 if ((fptr = mptr->map_file) != NULL &&
2404 fptr->file_lo != NULL) {
2405 base = fptr->file_lo->rl_base;
2406 if (base >= mptr->map_pmap.pr_vaddr &&
2407 base < mptr->map_pmap.pr_vaddr +
2408 mptr->map_pmap.pr_size) /* text space */
2409 return (mptr);
2410 mold = mptr; /* must be the data */
2411 continue;
2412 }
2413 /* This is a poor way to test for text space */
2414 if (!(mptr->map_pmap.pr_mflags & MA_EXEC) ||
2415 (mptr->map_pmap.pr_mflags & MA_WRITE)) {
2416 mold = mptr;
2417 continue;
2418 }
2419 return (mptr);
2420 }
2421 }
2422
2423 return (mold);
2424 }
2425
2426 /*
2427 * Given a shared object name, return the map_info_t for it. If no matching
2428 * object is found, return NULL. Normally, the link maps contain the full
2429 * object pathname, e.g. /usr/lib/libc.so.1. We allow the object name to
2430 * take one of the following forms:
2431 *
2432 * 1. An exact match (i.e. a full pathname): "/usr/lib/libc.so.1"
2433 * 2. An exact basename match: "libc.so.1"
2434 * 3. An initial basename match up to a '.' suffix: "libc.so" or "libc"
2435 * 4. The literal string "a.out" is an alias for the executable mapping
2436 *
2437 * The third case is a convenience for callers and may not be necessary.
2438 *
2439 * As the exact same object name may be loaded on different link maps (see
2440 * dlmopen(3DL)), we also allow the caller to resolve the object name by
2441 * specifying a particular link map id. If lmid is PR_LMID_EVERY, the
2442 * first matching name will be returned, regardless of the link map id.
2443 */
2444 static map_info_t *
2445 object_to_map(struct ps_prochandle *P, Lmid_t lmid, const char *objname)
2446 {
2447 map_info_t *mp;
2448 file_info_t *fp;
2449 size_t objlen;
2450 uint_t i;
2451
2452 /*
2453 * If we have no rtld_db, then always treat a request as one for all
2454 * link maps.
2455 */
2456 if (P->rap == NULL)
2457 lmid = PR_LMID_EVERY;
2458
2459 /*
2460 * First pass: look for exact matches of the entire pathname or
2461 * basename (cases 1 and 2 above):
2462 */
2463 for (i = 0, mp = P->mappings; i < P->map_count; i++, mp++) {
2464
2465 if (mp->map_pmap.pr_mapname[0] == '\0' ||
2466 (fp = mp->map_file) == NULL ||
2467 ((fp->file_lname == NULL) && (fp->file_rname == NULL)))
2468 continue;
2469
2470 if (lmid != PR_LMID_EVERY &&
2471 (fp->file_lo == NULL || lmid != fp->file_lo->rl_lmident))
2472 continue;
2473
2474 /*
2475 * If we match, return the primary text mapping; otherwise
2476 * just return the mapping we matched.
2477 */
2478 if ((fp->file_lbase && strcmp(fp->file_lbase, objname) == 0) ||
2479 (fp->file_rbase && strcmp(fp->file_rbase, objname) == 0) ||
2480 (fp->file_lname && strcmp(fp->file_lname, objname) == 0) ||
2481 (fp->file_rname && strcmp(fp->file_rname, objname) == 0))
2482 return (fp->file_map ? fp->file_map : mp);
2483 }
2484
2485 objlen = strlen(objname);
2486
2487 /*
2488 * Second pass: look for partial matches (case 3 above):
2489 */
2490 for (i = 0, mp = P->mappings; i < P->map_count; i++, mp++) {
2491
2492 if (mp->map_pmap.pr_mapname[0] == '\0' ||
2493 (fp = mp->map_file) == NULL ||
2494 ((fp->file_lname == NULL) && (fp->file_rname == NULL)))
2495 continue;
2496
2497 if (lmid != PR_LMID_EVERY &&
2498 (fp->file_lo == NULL || lmid != fp->file_lo->rl_lmident))
2499 continue;
2500
2501 /*
2502 * If we match, return the primary text mapping; otherwise
2503 * just return the mapping we matched.
2504 */
2505 if ((fp->file_lbase != NULL) &&
2506 (strncmp(fp->file_lbase, objname, objlen) == 0) &&
2507 (fp->file_lbase[objlen] == '.'))
2508 return (fp->file_map ? fp->file_map : mp);
2509 if ((fp->file_rbase != NULL) &&
2510 (strncmp(fp->file_rbase, objname, objlen) == 0) &&
2511 (fp->file_rbase[objlen] == '.'))
2512 return (fp->file_map ? fp->file_map : mp);
2513 }
2514
2515 /*
2516 * One last check: we allow "a.out" to always alias the executable,
2517 * assuming this name was not in use for something else.
2518 */
2519 if ((lmid == PR_LMID_EVERY || lmid == LM_ID_BASE) &&
2520 (strcmp(objname, "a.out") == 0))
2521 return (P->map_exec);
2522
2523 return (NULL);
2524 }
2525
2526 static map_info_t *
2527 object_name_to_map(struct ps_prochandle *P, Lmid_t lmid, const char *name)
2528 {
2529 map_info_t *mptr;
2530
2531 if (!P->info_valid)
2532 Pupdate_maps(P);
2533
2534 if (P->map_exec == NULL && ((mptr = Paddr2mptr(P,
2535 Pgetauxval(P, AT_ENTRY))) != NULL || (mptr = exec_map(P)) != NULL))
2536 P->map_exec = mptr;
2537
2538 if (P->map_ldso == NULL && (mptr = Paddr2mptr(P,
2539 Pgetauxval(P, AT_BASE))) != NULL)
2540 P->map_ldso = mptr;
2541
2542 if (name == PR_OBJ_EXEC)
2543 mptr = P->map_exec;
2544 else if (name == PR_OBJ_LDSO)
2545 mptr = P->map_ldso;
2546 else if (Prd_agent(P) != NULL || P->state == PS_IDLE)
2547 mptr = object_to_map(P, lmid, name);
2548 else
2549 mptr = NULL;
2550
2551 return (mptr);
2552 }
2553
2554 /*
2555 * When two symbols are found by address, decide which one is to be preferred.
2556 */
2557 static GElf_Sym *
2558 sym_prefer(GElf_Sym *sym1, char *name1, GElf_Sym *sym2, char *name2)
2559 {
2560 /*
2561 * Prefer the non-NULL symbol.
2562 */
2563 if (sym1 == NULL)
2564 return (sym2);
2565 if (sym2 == NULL)
2566 return (sym1);
2567
2568 /*
2569 * Defer to the sort ordering...
2570 */
2571 return (byaddr_cmp_common(sym1, name1, sym2, name2) <= 0 ? sym1 : sym2);
2572 }
2573
2574 /*
2575 * Use a binary search to do the work of sym_by_addr().
2576 */
2577 static GElf_Sym *
2578 sym_by_addr_binary(sym_tbl_t *symtab, GElf_Addr addr, GElf_Sym *symp,
2579 uint_t *idp)
2580 {
2581 GElf_Sym sym, osym;
2582 uint_t i, oid, *byaddr = symtab->sym_byaddr;
2583 int min, max, mid, omid, found = 0;
2584
2585 if (symtab->sym_data_pri == NULL || symtab->sym_count == 0)
2586 return (NULL);
2587
2588 min = 0;
2589 max = symtab->sym_count - 1;
2590 osym.st_value = 0;
2591
2592 /*
2593 * We can't return when we've found a match, we have to continue
2594 * searching for the closest matching symbol.
2595 */
2596 while (min <= max) {
2597 mid = (max + min) / 2;
2598
2599 i = byaddr[mid];
2600 (void) symtab_getsym(symtab, i, &sym);
2601
2602 if (addr >= sym.st_value &&
2603 addr < sym.st_value + sym.st_size &&
2604 (!found || sym.st_value > osym.st_value)) {
2605 osym = sym;
2606 omid = mid;
2607 oid = i;
2608 found = 1;
2609 }
2610
2611 if (addr < sym.st_value)
2612 max = mid - 1;
2613 else
2614 min = mid + 1;
2615 }
2616
2617 if (!found)
2618 return (NULL);
2619
2620 /*
2621 * There may be many symbols with identical values so we walk
2622 * backward in the byaddr table to find the best match.
2623 */
2624 do {
2625 sym = osym;
2626 i = oid;
2627
2628 if (omid == 0)
2629 break;
2630
2631 oid = byaddr[--omid];
2632 (void) symtab_getsym(symtab, oid, &osym);
2633 } while (addr >= osym.st_value &&
2634 addr < sym.st_value + osym.st_size &&
2635 osym.st_value == sym.st_value);
2636
2637 *symp = sym;
2638 if (idp != NULL)
2639 *idp = i;
2640 return (symp);
2641 }
2642
2643 /*
2644 * Use a linear search to do the work of sym_by_addr().
2645 */
2646 static GElf_Sym *
2647 sym_by_addr_linear(sym_tbl_t *symtab, GElf_Addr addr, GElf_Sym *symbolp,
2648 uint_t *idp)
2649 {
2650 size_t symn = symtab->sym_symn;
2651 char *strs = symtab->sym_strs;
2652 GElf_Sym sym, *symp = NULL;
2653 GElf_Sym osym, *osymp = NULL;
2654 int i, id;
2655
2656 if (symtab->sym_data_pri == NULL || symn == 0 || strs == NULL)
2657 return (NULL);
2658
2659 for (i = 0; i < symn; i++) {
2660 if ((symp = symtab_getsym(symtab, i, &sym)) != NULL) {
2661 if (addr >= sym.st_value &&
2662 addr < sym.st_value + sym.st_size) {
2663 if (osymp)
2664 symp = sym_prefer(
2665 symp, strs + symp->st_name,
2666 osymp, strs + osymp->st_name);
2667 if (symp != osymp) {
2668 osym = sym;
2669 osymp = &osym;
2670 id = i;
2671 }
2672 }
2673 }
2674 }
2675 if (osymp) {
2676 *symbolp = osym;
2677 if (idp)
2678 *idp = id;
2679 return (symbolp);
2680 }
2681 return (NULL);
2682 }
2683
2684 /*
2685 * Look up a symbol by address in the specified symbol table.
2686 * Adjustment to 'addr' must already have been made for the
2687 * offset of the symbol if this is a dynamic library symbol table.
2688 *
2689 * Use a linear or a binary search depending on whether or not we
2690 * chose to sort the table in optimize_symtab().
2691 */
2692 static GElf_Sym *
2693 sym_by_addr(sym_tbl_t *symtab, GElf_Addr addr, GElf_Sym *symp, uint_t *idp)
2694 {
2695 if (_libproc_no_qsort) {
2696 return (sym_by_addr_linear(symtab, addr, symp, idp));
2697 } else {
2698 return (sym_by_addr_binary(symtab, addr, symp, idp));
2699 }
2700 }
2701
2702 /*
2703 * Use a binary search to do the work of sym_by_name().
2704 */
2705 static GElf_Sym *
2706 sym_by_name_binary(sym_tbl_t *symtab, const char *name, GElf_Sym *symp,
2707 uint_t *idp)
2708 {
2709 char *strs = symtab->sym_strs;
2710 uint_t i, *byname = symtab->sym_byname;
2711 int min, mid, max, cmp;
2712
2713 if (symtab->sym_data_pri == NULL || strs == NULL ||
2714 symtab->sym_count == 0)
2715 return (NULL);
2716
2717 min = 0;
2718 max = symtab->sym_count - 1;
2719
2720 while (min <= max) {
2721 mid = (max + min) / 2;
2722
2723 i = byname[mid];
2724 (void) symtab_getsym(symtab, i, symp);
2725
2726 if ((cmp = strcmp(name, strs + symp->st_name)) == 0) {
2727 if (idp != NULL)
2728 *idp = i;
2729 return (symp);
2730 }
2731
2732 if (cmp < 0)
2733 max = mid - 1;
2734 else
2735 min = mid + 1;
2736 }
2737
2738 return (NULL);
2739 }
2740
2741 /*
2742 * Use a linear search to do the work of sym_by_name().
2743 */
2744 static GElf_Sym *
2745 sym_by_name_linear(sym_tbl_t *symtab, const char *name, GElf_Sym *symp,
2746 uint_t *idp)
2747 {
2748 size_t symn = symtab->sym_symn;
2749 char *strs = symtab->sym_strs;
2750 int i;
2751
2752 if (symtab->sym_data_pri == NULL || symn == 0 || strs == NULL)
2753 return (NULL);
2754
2755 for (i = 0; i < symn; i++) {
2756 if (symtab_getsym(symtab, i, symp) &&
2757 strcmp(name, strs + symp->st_name) == 0) {
2758 if (idp)
2759 *idp = i;
2760 return (symp);
2761 }
2762 }
2763
2764 return (NULL);
2765 }
2766
2767 /*
2768 * Look up a symbol by name in the specified symbol table.
2769 *
2770 * Use a linear or a binary search depending on whether or not we
2771 * chose to sort the table in optimize_symtab().
2772 */
2773 static GElf_Sym *
2774 sym_by_name(sym_tbl_t *symtab, const char *name, GElf_Sym *symp, uint_t *idp)
2775 {
2776 if (_libproc_no_qsort) {
2777 return (sym_by_name_linear(symtab, name, symp, idp));
2778 } else {
2779 return (sym_by_name_binary(symtab, name, symp, idp));
2780 }
2781 }
2782
2783 /*
2784 * Search the process symbol tables looking for a symbol whose
2785 * value to value+size contain the address specified by addr.
2786 * Return values are:
2787 * sym_name_buffer containing the symbol name
2788 * GElf_Sym symbol table entry
2789 * prsyminfo_t ancillary symbol information
2790 * Returns 0 on success, -1 on failure.
2791 */
2792 static int
2793 i_Pxlookup_by_addr(
2794 struct ps_prochandle *P,
2795 int lmresolve, /* use resolve linker object names */
2796 uintptr_t addr, /* process address being sought */
2797 char *sym_name_buffer, /* buffer for the symbol name */
2798 size_t bufsize, /* size of sym_name_buffer */
2799 GElf_Sym *symbolp, /* returned symbol table entry */
2800 prsyminfo_t *sip) /* returned symbol info */
2801 {
2802 GElf_Sym *symp;
2803 char *name;
2804 GElf_Sym sym1, *sym1p = NULL;
2805 GElf_Sym sym2, *sym2p = NULL;
2806 char *name1 = NULL;
2807 char *name2 = NULL;
2808 uint_t i1;
2809 uint_t i2;
2810 map_info_t *mptr;
2811 file_info_t *fptr;
2812
2813 (void) Prd_agent(P);
2814
2815 if ((mptr = Paddr2mptr(P, addr)) == NULL || /* no such address */
2816 (fptr = build_map_symtab(P, mptr)) == NULL || /* no mapped file */
2817 fptr->file_elf == NULL) /* not an ELF file */
2818 return (-1);
2819
2820 /*
2821 * Adjust the address by the load object base address in
2822 * case the address turns out to be in a shared library.
2823 */
2824 addr -= fptr->file_dyn_base;
2825
2826 /*
2827 * Search both symbol tables, symtab first, then dynsym.
2828 */
2829 if ((sym1p = sym_by_addr(&fptr->file_symtab, addr, &sym1, &i1)) != NULL)
2830 name1 = fptr->file_symtab.sym_strs + sym1.st_name;
2831 if ((sym2p = sym_by_addr(&fptr->file_dynsym, addr, &sym2, &i2)) != NULL)
2832 name2 = fptr->file_dynsym.sym_strs + sym2.st_name;
2833
2834 if ((symp = sym_prefer(sym1p, name1, sym2p, name2)) == NULL)
2835 return (-1);
2836
2837 name = (symp == sym1p) ? name1 : name2;
2838 if (bufsize > 0) {
2839 (void) strncpy(sym_name_buffer, name, bufsize);
2840 sym_name_buffer[bufsize - 1] = '\0';
2841 }
2842
2843 *symbolp = *symp;
2844 if (sip != NULL) {
2845 sip->prs_name = bufsize == 0 ? NULL : sym_name_buffer;
2846 if (lmresolve && (fptr->file_rname != NULL))
2847 sip->prs_object = fptr->file_rbase;
2848 else
2849 sip->prs_object = fptr->file_lbase;
2850 sip->prs_id = (symp == sym1p) ? i1 : i2;
2851 sip->prs_table = (symp == sym1p) ? PR_SYMTAB : PR_DYNSYM;
2852 sip->prs_lmid = (fptr->file_lo == NULL) ? LM_ID_BASE :
2853 fptr->file_lo->rl_lmident;
2854 }
2855
2856 if (GELF_ST_TYPE(symbolp->st_info) != STT_TLS)
2857 symbolp->st_value += fptr->file_dyn_base;
2858
2859 return (0);
2860 }
2861
2862 int
2863 Pxlookup_by_addr(struct ps_prochandle *P, uintptr_t addr, char *buf,
2864 size_t bufsize, GElf_Sym *symp, prsyminfo_t *sip)
2865 {
2866 return (i_Pxlookup_by_addr(P, B_FALSE, addr, buf, bufsize, symp, sip));
2867 }
2868
2869 int
2870 Pxlookup_by_addr_resolved(struct ps_prochandle *P, uintptr_t addr, char *buf,
2871 size_t bufsize, GElf_Sym *symp, prsyminfo_t *sip)
2872 {
2873 return (i_Pxlookup_by_addr(P, B_TRUE, addr, buf, bufsize, symp, sip));
2874 }
2875
2876 int
2877 Plookup_by_addr(struct ps_prochandle *P, uintptr_t addr, char *buf,
2878 size_t size, GElf_Sym *symp)
2879 {
2880 return (i_Pxlookup_by_addr(P, B_FALSE, addr, buf, size, symp, NULL));
2881 }
2882
2883 /*
2884 * Search the process symbol tables looking for a symbol whose name matches the
2885 * specified name and whose object and link map optionally match the specified
2886 * parameters. On success, the function returns 0 and fills in the GElf_Sym
2887 * symbol table entry. On failure, -1 is returned.
2888 */
2889 int
2890 Pxlookup_by_name(
2891 struct ps_prochandle *P,
2892 Lmid_t lmid, /* link map to match, or -1 for any */
2893 const char *oname, /* load object name */
2894 const char *sname, /* symbol name */
2895 GElf_Sym *symp, /* returned symbol table entry */
2896 prsyminfo_t *sip) /* returned symbol info */
2897 {
2898 map_info_t *mptr;
2899 file_info_t *fptr;
2900 int cnt;
2901
2902 GElf_Sym sym;
2903 prsyminfo_t si;
2904 int rv = -1;
2905 uint_t id;
2906
2907 if (oname == PR_OBJ_EVERY) {
2908 /* create all the file_info_t's for all the mappings */
2909 (void) Prd_agent(P);
2910 cnt = P->num_files;
2911 fptr = list_next(&P->file_head);
2912 } else {
2913 cnt = 1;
2914 if ((mptr = object_name_to_map(P, lmid, oname)) == NULL ||
2915 (fptr = build_map_symtab(P, mptr)) == NULL)
2916 return (-1);
2917 }
2918
2919 /*
2920 * Iterate through the loaded object files and look for the symbol
2921 * name in the .symtab and .dynsym of each. If we encounter a match
2922 * with SHN_UNDEF, keep looking in hopes of finding a better match.
2923 * This means that a name such as "puts" will match the puts function
2924 * in libc instead of matching the puts PLT entry in the a.out file.
2925 */
2926 for (; cnt > 0; cnt--, fptr = list_next(fptr)) {
2927 Pbuild_file_symtab(P, fptr);
2928
2929 if (fptr->file_elf == NULL)
2930 continue;
2931
2932 if (lmid != PR_LMID_EVERY && fptr->file_lo != NULL &&
2933 lmid != fptr->file_lo->rl_lmident)
2934 continue;
2935
2936 if (fptr->file_symtab.sym_data_pri != NULL &&
2937 sym_by_name(&fptr->file_symtab, sname, symp, &id)) {
2938 if (sip != NULL) {
2939 sip->prs_id = id;
2940 sip->prs_table = PR_SYMTAB;
2941 sip->prs_object = oname;
2942 sip->prs_name = sname;
2943 sip->prs_lmid = fptr->file_lo == NULL ?
2944 LM_ID_BASE : fptr->file_lo->rl_lmident;
2945 }
2946 } else if (fptr->file_dynsym.sym_data_pri != NULL &&
2947 sym_by_name(&fptr->file_dynsym, sname, symp, &id)) {
2948 if (sip != NULL) {
2949 sip->prs_id = id;
2950 sip->prs_table = PR_DYNSYM;
2951 sip->prs_object = oname;
2952 sip->prs_name = sname;
2953 sip->prs_lmid = fptr->file_lo == NULL ?
2954 LM_ID_BASE : fptr->file_lo->rl_lmident;
2955 }
2956 } else {
2957 continue;
2958 }
2959
2960 if (GELF_ST_TYPE(symp->st_info) != STT_TLS)
2961 symp->st_value += fptr->file_dyn_base;
2962
2963 if (symp->st_shndx != SHN_UNDEF)
2964 return (0);
2965
2966 if (rv != 0) {
2967 if (sip != NULL)
2968 si = *sip;
2969 sym = *symp;
2970 rv = 0;
2971 }
2972 }
2973
2974 if (rv == 0) {
2975 if (sip != NULL)
2976 *sip = si;
2977 *symp = sym;
2978 }
2979
2980 return (rv);
2981 }
2982
2983 /*
2984 * Search the process symbol tables looking for a symbol whose name matches the
2985 * specified name, but without any restriction on the link map id.
2986 */
2987 int
2988 Plookup_by_name(struct ps_prochandle *P, const char *object,
2989 const char *symbol, GElf_Sym *symp)
2990 {
2991 return (Pxlookup_by_name(P, PR_LMID_EVERY, object, symbol, symp, NULL));
2992 }
2993
2994 /*
2995 * Iterate over the process's address space mappings.
2996 */
2997 static int
2998 i_Pmapping_iter(struct ps_prochandle *P, boolean_t lmresolve,
2999 proc_map_f *func, void *cd)
3000 {
3001 map_info_t *mptr;
3002 file_info_t *fptr;
3003 char *object_name;
3004 int rc = 0;
3005 int i;
3006
3007 /* create all the file_info_t's for all the mappings */
3008 (void) Prd_agent(P);
3009
3010 for (i = 0, mptr = P->mappings; i < P->map_count; i++, mptr++) {
3011 if ((fptr = mptr->map_file) == NULL)
3012 object_name = NULL;
3013 else if (lmresolve && (fptr->file_rname != NULL))
3014 object_name = fptr->file_rname;
3015 else
3016 object_name = fptr->file_lname;
3017 if ((rc = func(cd, &mptr->map_pmap, object_name)) != 0)
3018 return (rc);
3019 }
3020 return (0);
3021 }
3022
3023 int
3024 Pmapping_iter(struct ps_prochandle *P, proc_map_f *func, void *cd)
3025 {
3026 return (i_Pmapping_iter(P, B_FALSE, func, cd));
3027 }
3028
3029 int
3030 Pmapping_iter_resolved(struct ps_prochandle *P, proc_map_f *func, void *cd)
3031 {
3032 return (i_Pmapping_iter(P, B_TRUE, func, cd));
3033 }
3034
3035 /*
3036 * Iterate over the process's mapped objects.
3037 */
3038 static int
3039 i_Pobject_iter(struct ps_prochandle *P, boolean_t lmresolve,
3040 proc_map_f *func, void *cd)
3041 {
3042 map_info_t *mptr;
3043 file_info_t *fptr;
3044 uint_t cnt;
3045 int rc = 0;
3046
3047 (void) Prd_agent(P); /* create file_info_t's for all the mappings */
3048 Pupdate_maps(P);
3049
3050 for (cnt = P->num_files, fptr = list_next(&P->file_head);
3051 cnt; cnt--, fptr = list_next(fptr)) {
3052 const char *lname;
3053
3054 if (lmresolve && (fptr->file_rname != NULL))
3055 lname = fptr->file_rname;
3056 else if (fptr->file_lname != NULL)
3057 lname = fptr->file_lname;
3058 else
3059 lname = "";
3060
3061 if ((mptr = fptr->file_map) == NULL)
3062 continue;
3063
3064 if ((rc = func(cd, &mptr->map_pmap, lname)) != 0)
3065 return (rc);
3066
3067 if (!P->info_valid)
3068 Pupdate_maps(P);
3069 }
3070 return (0);
3071 }
3072
3073 int
3074 Pobject_iter(struct ps_prochandle *P, proc_map_f *func, void *cd)
3075 {
3076 return (i_Pobject_iter(P, B_FALSE, func, cd));
3077 }
3078
3079 int
3080 Pobject_iter_resolved(struct ps_prochandle *P, proc_map_f *func, void *cd)
3081 {
3082 return (i_Pobject_iter(P, B_TRUE, func, cd));
3083 }
3084
3085 static char *
3086 i_Pobjname(struct ps_prochandle *P, boolean_t lmresolve, uintptr_t addr,
3087 char *buffer, size_t bufsize)
3088 {
3089 map_info_t *mptr;
3090 file_info_t *fptr;
3091
3092 /* create all the file_info_t's for all the mappings */
3093 (void) Prd_agent(P);
3094
3095 if ((mptr = Paddr2mptr(P, addr)) == NULL)
3096 return (NULL);
3097
3098 if (!lmresolve) {
3099 if (((fptr = mptr->map_file) == NULL) ||
3100 (fptr->file_lname == NULL))
3101 return (NULL);
3102 (void) strlcpy(buffer, fptr->file_lname, bufsize);
3103 return (buffer);
3104 }
3105
3106 /* Check for a cached copy of the resolved path */
3107 if (Pfindmap(P, mptr, buffer, bufsize) != NULL)
3108 return (buffer);
3109
3110 return (NULL);
3111 }
3112
3113 /*
3114 * Given a virtual address, return the name of the underlying
3115 * mapped object (file) as provided by the dynamic linker.
3116 * Return NULL if we can't find any name information for the object.
3117 */
3118 char *
3119 Pobjname(struct ps_prochandle *P, uintptr_t addr,
3120 char *buffer, size_t bufsize)
3121 {
3122 return (i_Pobjname(P, B_FALSE, addr, buffer, bufsize));
3123 }
3124
3125 /*
3126 * Given a virtual address, try to return a filesystem path to the
3127 * underlying mapped object (file). If we're in the global zone,
3128 * this path could resolve to an object in another zone. If we're
3129 * unable return a valid filesystem path, we'll fall back to providing
3130 * the mapped object (file) name provided by the dynamic linker in
3131 * the target process (ie, the object reported by Pobjname()).
3132 */
3133 char *
3134 Pobjname_resolved(struct ps_prochandle *P, uintptr_t addr,
3135 char *buffer, size_t bufsize)
3136 {
3137 return (i_Pobjname(P, B_TRUE, addr, buffer, bufsize));
3138 }
3139
3140 /*
3141 * Given a virtual address, return the link map id of the underlying mapped
3142 * object (file), as provided by the dynamic linker. Return -1 on failure.
3143 */
3144 int
3145 Plmid(struct ps_prochandle *P, uintptr_t addr, Lmid_t *lmidp)
3146 {
3147 map_info_t *mptr;
3148 file_info_t *fptr;
3149
3150 /* create all the file_info_t's for all the mappings */
3151 (void) Prd_agent(P);
3152
3153 if ((mptr = Paddr2mptr(P, addr)) != NULL &&
3154 (fptr = mptr->map_file) != NULL && fptr->file_lo != NULL) {
3155 *lmidp = fptr->file_lo->rl_lmident;
3156 return (0);
3157 }
3158
3159 return (-1);
3160 }
3161
3162 /*
3163 * Given an object name and optional lmid, iterate over the object's symbols.
3164 * If which == PR_SYMTAB, search the normal symbol table.
3165 * If which == PR_DYNSYM, search the dynamic symbol table.
3166 */
3167 static int
3168 Psymbol_iter_com(struct ps_prochandle *P, Lmid_t lmid, const char *object_name,
3169 int which, int mask, pr_order_t order, proc_xsym_f *func, void *cd)
3170 {
3171 #if STT_NUM != (STT_TLS + 1)
3172 #error "STT_NUM has grown. update Psymbol_iter_com()"
3173 #endif
3174
3175 GElf_Sym sym;
3176 GElf_Shdr shdr;
3177 map_info_t *mptr;
3178 file_info_t *fptr;
3179 sym_tbl_t *symtab;
3180 size_t symn;
3181 const char *strs;
3182 size_t strsz;
3183 prsyminfo_t si;
3184 int rv;
3185 uint_t *map, i, count, ndx;
3186
3187 if ((mptr = object_name_to_map(P, lmid, object_name)) == NULL)
3188 return (-1);
3189
3190 if ((fptr = build_map_symtab(P, mptr)) == NULL || /* no mapped file */
3191 fptr->file_elf == NULL) /* not an ELF file */
3192 return (-1);
3193
3194 /*
3195 * Search the specified symbol table.
3196 */
3197 switch (which) {
3198 case PR_SYMTAB:
3199 symtab = &fptr->file_symtab;
3200 si.prs_table = PR_SYMTAB;
3201 break;
3202 case PR_DYNSYM:
3203 symtab = &fptr->file_dynsym;
3204 si.prs_table = PR_DYNSYM;
3205 break;
3206 default:
3207 return (-1);
3208 }
3209
3210 si.prs_object = object_name;
3211 si.prs_lmid = fptr->file_lo == NULL ?
3212 LM_ID_BASE : fptr->file_lo->rl_lmident;
3213
3214 symn = symtab->sym_symn;
3215 strs = symtab->sym_strs;
3216 strsz = symtab->sym_strsz;
3217
3218 switch (order) {
3219 case PRO_NATURAL:
3220 map = NULL;
3221 count = symn;
3222 break;
3223 case PRO_BYNAME:
3224 map = symtab->sym_byname;
3225 count = symtab->sym_count;
3226 break;
3227 case PRO_BYADDR:
3228 map = symtab->sym_byaddr;
3229 count = symtab->sym_count;
3230 break;
3231 default:
3232 return (-1);
3233 }
3234
3235 if (symtab->sym_data_pri == NULL || strs == NULL || count == 0)
3236 return (-1);
3237
3238 rv = 0;
3239
3240 for (i = 0; i < count; i++) {
3241 ndx = map == NULL ? i : map[i];
3242 if (symtab_getsym(symtab, ndx, &sym) != NULL) {
3243 uint_t s_bind, s_type, type;
3244
3245 if (sym.st_name >= strsz) /* invalid st_name */
3246 continue;
3247
3248 s_bind = GELF_ST_BIND(sym.st_info);
3249 s_type = GELF_ST_TYPE(sym.st_info);
3250
3251 /*
3252 * In case you haven't already guessed, this relies on
3253 * the bitmask used in <libproc.h> for encoding symbol
3254 * type and binding matching the order of STB and STT
3255 * constants in <sys/elf.h>. Changes to ELF must
3256 * maintain binary compatibility, so I think this is
3257 * reasonably fair game.
3258 */
3259 if (s_bind < STB_NUM && s_type < STT_NUM) {
3260 type = (1 << (s_type + 8)) | (1 << s_bind);
3261 if ((type & ~mask) != 0)
3262 continue;
3263 } else
3264 continue; /* Invalid type or binding */
3265
3266 if (GELF_ST_TYPE(sym.st_info) != STT_TLS)
3267 sym.st_value += fptr->file_dyn_base;
3268
3269 si.prs_name = strs + sym.st_name;
3270
3271 /*
3272 * If symbol's type is STT_SECTION, then try to lookup
3273 * the name of the corresponding section.
3274 */
3275 if (GELF_ST_TYPE(sym.st_info) == STT_SECTION &&
3276 fptr->file_shstrs != NULL &&
3277 gelf_getshdr(elf_getscn(fptr->file_elf,
3278 sym.st_shndx), &shdr) != NULL &&
3279 shdr.sh_name != 0 &&
3280 shdr.sh_name < fptr->file_shstrsz)
3281 si.prs_name = fptr->file_shstrs + shdr.sh_name;
3282
3283 si.prs_id = ndx;
3284 if ((rv = func(cd, &sym, si.prs_name, &si)) != 0)
3285 break;
3286 }
3287 }
3288
3289 return (rv);
3290 }
3291
3292 int
3293 Pxsymbol_iter(struct ps_prochandle *P, Lmid_t lmid, const char *object_name,
3294 int which, int mask, proc_xsym_f *func, void *cd)
3295 {
3296 return (Psymbol_iter_com(P, lmid, object_name, which, mask,
3297 PRO_NATURAL, func, cd));
3298 }
3299
3300 int
3301 Psymbol_iter_by_lmid(struct ps_prochandle *P, Lmid_t lmid,
3302 const char *object_name, int which, int mask, proc_sym_f *func, void *cd)
3303 {
3304 return (Psymbol_iter_com(P, lmid, object_name, which, mask,
3305 PRO_NATURAL, (proc_xsym_f *)func, cd));
3306 }
3307
3308 int
3309 Psymbol_iter(struct ps_prochandle *P,
3310 const char *object_name, int which, int mask, proc_sym_f *func, void *cd)
3311 {
3312 return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask,
3313 PRO_NATURAL, (proc_xsym_f *)func, cd));
3314 }
3315
3316 int
3317 Psymbol_iter_by_addr(struct ps_prochandle *P,
3318 const char *object_name, int which, int mask, proc_sym_f *func, void *cd)
3319 {
3320 return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask,
3321 PRO_BYADDR, (proc_xsym_f *)func, cd));
3322 }
3323
3324 int
3325 Psymbol_iter_by_name(struct ps_prochandle *P,
3326 const char *object_name, int which, int mask, proc_sym_f *func, void *cd)
3327 {
3328 return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask,
3329 PRO_BYNAME, (proc_xsym_f *)func, cd));
3330 }
3331
3332 /*
3333 * Get the platform string.
3334 */
3335 char *
3336 Pplatform(struct ps_prochandle *P, char *s, size_t n)
3337 {
3338 return (P->ops.pop_platform(P, s, n, P->data));
3339 }
3340
3341 /*
3342 * Get the uname(2) information.
3343 */
3344 int
3345 Puname(struct ps_prochandle *P, struct utsname *u)
3346 {
3347 return (P->ops.pop_uname(P, u, P->data));
3348 }
3349
3350 /*
3351 * Called from Pcreate(), Pgrab(), and Pfgrab_core() to initialize
3352 * the symbol table heads in the new ps_prochandle.
3353 */
3354 void
3355 Pinitsym(struct ps_prochandle *P)
3356 {
3357 P->num_files = 0;
3358 list_link(&P->file_head, NULL);
3359 }
3360
3361 /*
3362 * Called from Prelease() to destroy the symbol tables.
3363 * Must be called by the client after an exec() in the victim process.
3364 */
3365 void
3366 Preset_maps(struct ps_prochandle *P)
3367 {
3368 int i;
3369
3370 if (P->rap != NULL) {
3371 rd_delete(P->rap);
3372 P->rap = NULL;
3373 }
3374
3375 if (P->execname != NULL) {
3376 free(P->execname);
3377 P->execname = NULL;
3378 }
3379
3380 if (P->auxv != NULL) {
3381 free(P->auxv);
3382 P->auxv = NULL;
3383 P->nauxv = 0;
3384 }
3385
3386 for (i = 0; i < P->map_count; i++)
3387 map_info_free(P, &P->mappings[i]);
3388
3389 if (P->mappings != NULL) {
3390 free(P->mappings);
3391 P->mappings = NULL;
3392 }
3393 P->map_count = P->map_alloc = 0;
3394
3395 P->info_valid = 0;
3396 }
3397
3398 typedef struct getenv_data {
3399 char *buf;
3400 size_t bufsize;
3401 const char *search;
3402 size_t searchlen;
3403 } getenv_data_t;
3404
3405 /*ARGSUSED*/
3406 static int
3407 getenv_func(void *data, struct ps_prochandle *P, uintptr_t addr,
3408 const char *nameval)
3409 {
3410 getenv_data_t *d = data;
3411 size_t len;
3412
3413 if (nameval == NULL)
3414 return (0);
3415
3416 if (d->searchlen < strlen(nameval) &&
3417 strncmp(nameval, d->search, d->searchlen) == 0 &&
3418 nameval[d->searchlen] == '=') {
3419 len = MIN(strlen(nameval), d->bufsize - 1);
3420 (void) strncpy(d->buf, nameval, len);
3421 d->buf[len] = '\0';
3422 return (1);
3423 }
3424
3425 return (0);
3426 }
3427
3428 char *
3429 Pgetenv(struct ps_prochandle *P, const char *name, char *buf, size_t buflen)
3430 {
3431 getenv_data_t d;
3432
3433 d.buf = buf;
3434 d.bufsize = buflen;
3435 d.search = name;
3436 d.searchlen = strlen(name);
3437
3438 if (Penv_iter(P, getenv_func, &d) == 1) {
3439 char *equals = strchr(d.buf, '=');
3440
3441 if (equals != NULL) {
3442 (void) memmove(d.buf, equals + 1,
3443 d.buf + buflen - equals - 1);
3444 d.buf[d.buf + buflen - equals] = '\0';
3445
3446 return (buf);
3447 }
3448 }
3449
3450 return (NULL);
3451 }
3452
3453 /* number of argument or environment pointers to read all at once */
3454 #define NARG 100
3455
3456 int
3457 Penv_iter(struct ps_prochandle *P, proc_env_f *func, void *data)
3458 {
3459 const psinfo_t *psp;
3460 uintptr_t envpoff;
3461 GElf_Sym sym;
3462 int ret;
3463 char *buf, *nameval;
3464 size_t buflen;
3465
3466 int nenv = NARG;
3467 long envp[NARG];
3468
3469 /*
3470 * Attempt to find the "_environ" variable in the process.
3471 * Failing that, use the original value provided by Ppsinfo().
3472 */
3473 if ((psp = Ppsinfo(P)) == NULL)
3474 return (-1);
3475
3476 envpoff = psp->pr_envp; /* Default if no _environ found */
3477
3478 if (Plookup_by_name(P, PR_OBJ_EXEC, "_environ", &sym) == 0) {
3479 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
3480 if (Pread(P, &envpoff, sizeof (envpoff),
3481 sym.st_value) != sizeof (envpoff))
3482 envpoff = psp->pr_envp;
3483 } else if (P->status.pr_dmodel == PR_MODEL_ILP32) {
3484 uint32_t envpoff32;
3485
3486 if (Pread(P, &envpoff32, sizeof (envpoff32),
3487 sym.st_value) != sizeof (envpoff32))
3488 envpoff = psp->pr_envp;
3489 else
3490 envpoff = envpoff32;
3491 }
3492 }
3493
3494 buflen = 128;
3495 buf = malloc(buflen);
3496
3497 ret = 0;
3498 for (;;) {
3499 uintptr_t envoff;
3500
3501 if (nenv == NARG) {
3502 (void) memset(envp, 0, sizeof (envp));
3503 if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
3504 if (Pread(P, envp,
3505 sizeof (envp), envpoff) <= 0) {
3506 ret = -1;
3507 break;
3508 }
3509 } else if (P->status.pr_dmodel == PR_MODEL_ILP32) {
3510 uint32_t e32[NARG];
3511 int i;
3512
3513 (void) memset(e32, 0, sizeof (e32));
3514 if (Pread(P, e32, sizeof (e32), envpoff) <= 0) {
3515 ret = -1;
3516 break;
3517 }
3518 for (i = 0; i < NARG; i++)
3519 envp[i] = e32[i];
3520 }
3521 nenv = 0;
3522 }
3523
3524 if ((envoff = envp[nenv++]) == NULL)
3525 break;
3526
3527 /*
3528 * Attempt to read the string from the process.
3529 */
3530 again:
3531 ret = Pread_string(P, buf, buflen, envoff);
3532
3533 if (ret <= 0) {
3534 nameval = NULL;
3535 } else if (ret == buflen - 1) {
3536 free(buf);
3537 /*
3538 * Bail if we have a corrupted environment
3539 */
3540 if (buflen >= ARG_MAX)
3541 return (-1);
3542 buflen *= 2;
3543 buf = malloc(buflen);
3544 goto again;
3545 } else {
3546 nameval = buf;
3547 }
3548
3549 if ((ret = func(data, P, envoff, nameval)) != 0)
3550 break;
3551
3552 envpoff += (P->status.pr_dmodel == PR_MODEL_LP64)? 8 : 4;
3553 }
3554
3555 free(buf);
3556
3557 return (ret);
3558 }