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