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