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