Print this page
OS-4904 mdb can't print types from an object file with ctf
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
OS-4341 libproc should also check the GNU build id in addition to the debug link
Reviewed by: Patrick Mooney <patrick.f.mooney@gmail.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4050 libproc reads .gnu_debuglink padding incorrectly
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-3780 libproc could know about .gnu_debuglink for remote symbol tables
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>


   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 /*


 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;


 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) {


 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);


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


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         /*


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) */




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2016 Joyent, Inc.
  25  * Copyright (c) 2013 by Delphix. All rights reserved.
  26  */
  27 
  28 #include <assert.h>
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <stddef.h>
  32 #include <unistd.h>
  33 #include <ctype.h>
  34 #include <fcntl.h>
  35 #include <string.h>
  36 #include <strings.h>
  37 #include <memory.h>
  38 #include <errno.h>
  39 #include <dirent.h>
  40 #include <signal.h>
  41 #include <limits.h>
  42 #include <libgen.h>
  43 #include <sys/types.h>
  44 #include <sys/stat.h>
  45 #include <sys/sysmacros.h>
  46 #include <sys/crc32.h>
  47 
  48 #include "libproc.h"
  49 #include "Pcontrol.h"
  50 #include "Putil.h"
  51 #include "Psymtab_machelf.h"
  52 
  53 static file_info_t *build_map_symtab(struct ps_prochandle *, map_info_t *);
  54 static map_info_t *exec_map(struct ps_prochandle *);
  55 static map_info_t *object_to_map(struct ps_prochandle *, Lmid_t, const char *);
  56 static map_info_t *object_name_to_map(struct ps_prochandle *,
  57         Lmid_t, const char *);
  58 static GElf_Sym *sym_by_name(sym_tbl_t *, const char *, GElf_Sym *, uint_t *);
  59 static int read_ehdr32(struct ps_prochandle *, Elf32_Ehdr *, uint_t *,
  60     uintptr_t);
  61 #ifdef _LP64
  62 static int read_ehdr64(struct ps_prochandle *, Elf64_Ehdr *, uint_t *,
  63     uintptr_t);
  64 #endif
  65 static uint32_t psym_crc32[] = { CRC32_TABLE };
  66 
  67 #define DATA_TYPES      \
  68         ((1 << STT_OBJECT) | (1 << STT_FUNC) | \
  69         (1 << STT_COMMON) | (1 << STT_TLS))
  70 #define IS_DATA_TYPE(tp)        (((1 << (tp)) & DATA_TYPES) != 0)
  71 
  72 #define MA_RWX  (MA_READ | MA_WRITE | MA_EXEC)
  73 
  74 /*
  75  * Minimum and maximum length of a build-id that we'll accept. Generally it's a
  76  * 20 byte SHA1 and it's expected that the first byte (which is two ascii
  77  * characters) indicates a directory and the remaining bytes become the file
  78  * name. Therefore, our minimum length is at least 2 bytes (one for the
  79  * directory and one for the name) and the max is a bit over the minimum -- 64,
  80  * just in case folks do something odd. The string length is three times the max
  81  * length. This accounts for the fact that each byte is two characters, a null
  82  * terminator, and the directory '/' character.
  83  */
  84 #define MINBUILDID      2
  85 #define MAXBUILDID      64
  86 #define BUILDID_STRLEN  (3*MAXBUILDID)
  87 #define BUILDID_NAME    ".note.gnu.build-id"
  88 #define DBGLINK_NAME    ".gnu_debuglink"
  89 
  90 typedef enum {
  91         PRO_NATURAL,
  92         PRO_BYADDR,
  93         PRO_BYNAME
  94 } pr_order_t;
  95 
  96 static int
  97 addr_cmp(const void *aa, const void *bb)
  98 {
  99         uintptr_t a = *((uintptr_t *)aa);
 100         uintptr_t b = *((uintptr_t *)bb);
 101 
 102         if (a > b)
 103                 return (1);
 104         if (a < b)
 105                 return (-1);
 106         return (0);
 107 }
 108 
 109 /*


 185 
 186 /*
 187  * Allocation function for a new file_info_t
 188  */
 189 file_info_t *
 190 file_info_new(struct ps_prochandle *P, map_info_t *mptr)
 191 {
 192         file_info_t *fptr;
 193         map_info_t *mp;
 194         uintptr_t mstart, mend, sstart, send;
 195         uint_t i;
 196 
 197         if ((fptr = calloc(1, sizeof (file_info_t))) == NULL)
 198                 return (NULL);
 199 
 200         list_link(fptr, &P->file_head);
 201         (void) strcpy(fptr->file_pname, mptr->map_pmap.pr_mapname);
 202         mptr->map_file = fptr;
 203         fptr->file_ref = 1;
 204         fptr->file_fd = -1;
 205         fptr->file_dbgfile = -1;
 206         P->num_files++;
 207 
 208         /*
 209          * To figure out which map_info_t instances correspond to the mappings
 210          * for this load object we try to obtain the start and end address
 211          * for each section of our in-memory ELF image. If successful, we
 212          * walk down the list of addresses and the list of map_info_t
 213          * instances in lock step to correctly find the mappings that
 214          * correspond to this load object.
 215          */
 216         if ((fptr->file_saddrs = get_saddrs(P, mptr->map_pmap.pr_vaddr,
 217             &fptr->file_nsaddrs)) == NULL)
 218                 return (fptr);
 219 
 220         mp = P->mappings;
 221         i = 0;
 222         while (mp < P->mappings + P->map_count && i < fptr->file_nsaddrs) {
 223 
 224                 /* Calculate the start and end of the mapping and section */
 225                 mstart = mp->map_pmap.pr_vaddr;


 276                         (void) elf_end(fptr->file_dynsym.sym_elf);
 277                         free(fptr->file_dynsym.sym_elfmem);
 278                 }
 279                 if (fptr->file_dynsym.sym_byname)
 280                         free(fptr->file_dynsym.sym_byname);
 281                 if (fptr->file_dynsym.sym_byaddr)
 282                         free(fptr->file_dynsym.sym_byaddr);
 283 
 284                 if (fptr->file_lo)
 285                         free(fptr->file_lo);
 286                 if (fptr->file_lname)
 287                         free(fptr->file_lname);
 288                 if (fptr->file_rname)
 289                         free(fptr->file_rname);
 290                 if (fptr->file_elf)
 291                         (void) elf_end(fptr->file_elf);
 292                 if (fptr->file_elfmem != NULL)
 293                         free(fptr->file_elfmem);
 294                 if (fptr->file_fd >= 0)
 295                         (void) close(fptr->file_fd);
 296                 if (fptr->file_dbgelf)
 297                         (void) elf_end(fptr->file_dbgelf);
 298                 if (fptr->file_dbgfile >= 0)
 299                         (void) close(fptr->file_dbgfile);
 300                 if (fptr->file_ctfp) {
 301                         ctf_close(fptr->file_ctfp);
 302                         free(fptr->file_ctf_buf);
 303                 }
 304                 if (fptr->file_saddrs)
 305                         free(fptr->file_saddrs);
 306                 free(fptr);
 307                 P->num_files--;
 308         }
 309 }
 310 
 311 /*
 312  * Deallocation function for a map_info_t
 313  */
 314 static void
 315 map_info_free(struct ps_prochandle *P, map_info_t *mptr)
 316 {
 317         file_info_t *fptr;
 318 
 319         if ((fptr = mptr->map_file) != NULL) {


 825 ctf_file_t *
 826 Paddr_to_ctf(struct ps_prochandle *P, uintptr_t addr)
 827 {
 828         map_info_t *mptr;
 829         file_info_t *fptr;
 830 
 831         if (!P->info_valid)
 832                 Pupdate_maps(P);
 833 
 834         if ((mptr = Paddr2mptr(P, addr)) == NULL ||
 835             (fptr = mptr->map_file) == NULL)
 836                 return (NULL);
 837 
 838         return (Pbuild_file_ctf(P, fptr));
 839 }
 840 
 841 ctf_file_t *
 842 Plmid_to_ctf(struct ps_prochandle *P, Lmid_t lmid, const char *name)
 843 {
 844         map_info_t *mptr;
 845         file_info_t *fptr = NULL;
 846 
 847         if (name == PR_OBJ_EVERY)
 848                 return (NULL);
 849 
 850         /*
 851          * While most idle files are all ELF objects, not all of them have
 852          * mapping information available. There's nothing which would make
 853          * sense to fake up for ET_REL. Instead, if we're being asked for their
 854          * executable object and we know that the information is valid and they
 855          * only have a single file, we jump straight to that file pointer.
 856          */
 857         if (P->state == PS_IDLE && name == PR_OBJ_EXEC && P->info_valid == 1 &&
 858             P->num_files == 1 && P->mappings == NULL) {
 859                 fptr = list_next(&P->file_head);
 860         }
 861 
 862         if (fptr == NULL) {
 863                 if ((mptr = object_name_to_map(P, lmid, name)) == NULL ||
 864                     (fptr = mptr->map_file) == NULL)
 865                         return (NULL);
 866         }
 867 
 868         return (Pbuild_file_ctf(P, fptr));
 869 }
 870 
 871 ctf_file_t *
 872 Pname_to_ctf(struct ps_prochandle *P, const char *name)
 873 {
 874         return (Plmid_to_ctf(P, PR_LMID_EVERY, name));
 875 }
 876 
 877 void
 878 Preadauxvec(struct ps_prochandle *P)
 879 {
 880         if (P->auxv != NULL) {
 881                 free(P->auxv);
 882                 P->auxv = NULL;
 883                 P->nauxv = 0;
 884         }
 885 
 886         P->ops.pop_read_aux(P, &P->auxv, &P->nauxv, P->data);


1587         Elf_Scn *scn;
1588         Elf *elf;
1589 
1590         if ((elf = fake_elf(P, fptr)) == NULL ||
1591             elf_kind(elf) != ELF_K_ELF ||
1592             gelf_getehdr(elf, ehdr) == NULL ||
1593             elf_getshdrnum(elf, nshdrs) == -1 ||
1594             elf_getshdrstrndx(elf, &shstrndx) == -1 ||
1595             (scn = elf_getscn(elf, shstrndx)) == NULL ||
1596             (*shdata = elf_getdata(scn, NULL)) == NULL) {
1597                 if (elf != NULL)
1598                         (void) elf_end(elf);
1599                 dprintf("failed to fake up ELF file\n");
1600                 return (NULL);
1601         }
1602 
1603         return (elf);
1604 }
1605 
1606 /*
1607  * Try and find the file described by path in the file system and validate that
1608  * it matches our CRC before we try and process it for symbol information. If we
1609  * instead have an ELF data section, then that means we're checking a build-id
1610  * section instead. In that case we just need to find and bcmp the corresponding
1611  * section.
1612  *
1613  * Before we validate if it's a valid CRC or data section, we check to ensure
1614  * that it's a normal file and not anything else.
1615  */
1616 static boolean_t
1617 build_alt_debug(file_info_t *fptr, const char *path, uint32_t crc,
1618     Elf_Data *data)
1619 {
1620         int fd;
1621         struct stat st;
1622         Elf *elf;
1623         Elf_Scn *scn;
1624         GElf_Shdr symshdr, strshdr;
1625         Elf_Data *symdata, *strdata;
1626         boolean_t valid;
1627         uint32_t c = -1U;
1628 
1629         if ((fd = open(path, O_RDONLY)) < 0)
1630                 return (B_FALSE);
1631 
1632         if (fstat(fd, &st) != 0) {
1633                 (void) close(fd);
1634                 return (B_FALSE);
1635         }
1636 
1637         if (S_ISREG(st.st_mode) == 0) {
1638                 (void) close(fd);
1639                 return (B_FALSE);
1640         }
1641 
1642         /*
1643          * Only check the CRC if we've come here through a GNU debug link
1644          * section as opposed to the build id. This is indicated by having the
1645          * value of data be NULL.
1646          */
1647         if (data == NULL) {
1648                 for (;;) {
1649                         char buf[4096];
1650                         ssize_t ret = read(fd, buf, sizeof (buf));
1651                         if (ret == -1) {
1652                                 if (ret == EINTR)
1653                                         continue;
1654                                 (void) close(fd);
1655                                 return (B_FALSE);
1656                         }
1657                         if (ret == 0) {
1658                                 c = ~c;
1659                                 if (c != crc) {
1660                                         dprintf("crc mismatch, found: 0x%x "
1661                                             "expected 0x%x\n", c, crc);
1662                                         (void) close(fd);
1663                                         return (B_FALSE);
1664                                 }
1665                                 break;
1666                         }
1667                         CRC32(c, buf, ret, c, psym_crc32);
1668                 }
1669         }
1670 
1671         elf = elf_begin(fd, ELF_C_READ, NULL);
1672         if (elf == NULL) {
1673                 (void) close(fd);
1674                 return (B_FALSE);
1675         }
1676 
1677         if (elf_kind(elf) != ELF_K_ELF) {
1678                 goto fail;
1679         }
1680 
1681         /*
1682          * If we have a data section, that indicates we have a build-id which
1683          * means we need to find the corresponding build-id section and compare
1684          * it.
1685          */
1686         scn = NULL;
1687         valid = B_FALSE;
1688         for (scn = elf_nextscn(elf, scn); data != NULL && scn != NULL;
1689             scn = elf_nextscn(elf, scn)) {
1690                 GElf_Shdr hdr;
1691                 Elf_Data *ntdata;
1692 
1693                 if (gelf_getshdr(scn, &hdr) == NULL)
1694                         goto fail;
1695 
1696                 if (hdr.sh_type != SHT_NOTE)
1697                         continue;
1698 
1699                 if ((ntdata = elf_getdata(scn, NULL)) == NULL)
1700                         goto fail;
1701 
1702                 /*
1703                  * First verify the data section sizes are equal, then the
1704                  * section name. If that's all true, then we can just do a bcmp.
1705                  */
1706                 if (data->d_size != ntdata->d_size)
1707                         continue;
1708 
1709                 dprintf("found corresponding section in alternate file\n");
1710                 if (bcmp(ntdata->d_buf, data->d_buf, data->d_size) != 0)
1711                         goto fail;
1712 
1713                 valid = B_TRUE;
1714                 break;
1715         }
1716         if (data != NULL && valid == B_FALSE) {
1717                 dprintf("failed to find a matching %s section in %s\n",
1718                     BUILDID_NAME, path);
1719                 goto fail;
1720         }
1721 
1722 
1723         /*
1724          * Do two passes, first see if we have a symbol header, then see if we
1725          * can find the corresponding linked string table.
1726          */
1727         scn = NULL;
1728         for (scn = elf_nextscn(elf, scn); scn != NULL;
1729             scn = elf_nextscn(elf, scn)) {
1730 
1731                 if (gelf_getshdr(scn, &symshdr) == NULL)
1732                         goto fail;
1733 
1734                 if (symshdr.sh_type != SHT_SYMTAB)
1735                         continue;
1736 
1737                 if ((symdata = elf_getdata(scn, NULL)) == NULL)
1738                         goto fail;
1739 
1740                 break;
1741         }
1742         if (scn == NULL)
1743                 goto fail;
1744 
1745         if ((scn = elf_getscn(elf, symshdr.sh_link)) == NULL)
1746                 goto fail;
1747 
1748         if (gelf_getshdr(scn, &strshdr) == NULL)
1749                 goto fail;
1750 
1751         if ((strdata = elf_getdata(scn, NULL)) == NULL)
1752                 goto fail;
1753 
1754         fptr->file_symtab.sym_data_pri = symdata;
1755         fptr->file_symtab.sym_symn += symshdr.sh_size / symshdr.sh_entsize;
1756         fptr->file_symtab.sym_strs = strdata->d_buf;
1757         fptr->file_symtab.sym_strsz = strdata->d_size;
1758         fptr->file_symtab.sym_hdr_pri = symshdr;
1759         fptr->file_symtab.sym_strhdr = strshdr;
1760 
1761         dprintf("successfully loaded additional debug symbols for %s from %s\n",
1762             fptr->file_rname, path);
1763 
1764         fptr->file_dbgfile = fd;
1765         fptr->file_dbgelf = elf;
1766         return (B_TRUE);
1767 fail:
1768         (void) elf_end(elf);
1769         (void) close(fd);
1770         return (B_FALSE);
1771 }
1772 
1773 /*
1774  * We're here because the object in question has no symbol information, that's a
1775  * bit unfortunate. However, we've found that there's a .gnu_debuglink sitting
1776  * around. By convention that means that given the current location of the
1777  * object on disk, and the debug name that we found in the binary we need to
1778  * search the following locations for a matching file.
1779  *
1780  * <dirname>/.debug/<debug-name>
1781  * /usr/lib/debug/<dirname>/<debug-name>
1782  *
1783  * In the future, we should consider supporting looking in the prefix's
1784  * lib/debug directory for a matching object or supporting an arbitrary user
1785  * defined set of places to look.
1786  */
1787 static void
1788 find_alt_debuglink(file_info_t *fptr, const char *name, uint32_t crc)
1789 {
1790         boolean_t r;
1791         char *dup = NULL, *path = NULL, *dname;
1792 
1793         dprintf("find_alt_debug: looking for %s, crc 0x%x\n", name, crc);
1794         if (fptr->file_rname == NULL) {
1795                 dprintf("find_alt_debug: encountered null file_rname\n");
1796                 return;
1797         }
1798 
1799         dup = strdup(fptr->file_rname);
1800         if (dup == NULL)
1801                 return;
1802 
1803         dname = dirname(dup);
1804         if (asprintf(&path, "%s/.debug/%s", dname, name) != -1) {
1805                 dprintf("attempting to load alternate debug information "
1806                     "from %s\n", path);
1807                 r = build_alt_debug(fptr, path, crc, NULL);
1808                 free(path);
1809                 if (r == B_TRUE)
1810                         goto out;
1811         }
1812 
1813         if (asprintf(&path, "/usr/lib/debug/%s/%s", dname, name) != -1) {
1814                 dprintf("attempting to load alternate debug information "
1815                     "from %s\n", path);
1816                 r = build_alt_debug(fptr, path, crc, NULL);
1817                 free(path);
1818                 if (r == B_TRUE)
1819                         goto out;
1820         }
1821 out:
1822         free(dup);
1823 }
1824 
1825 /*
1826  * Build the symbol table for the given mapped file.
1827  */
1828 void
1829 Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr)
1830 {
1831         char objectfile[PATH_MAX];
1832         uint_t i;
1833 
1834         GElf_Ehdr ehdr;
1835         GElf_Sym s;
1836 
1837         Elf_Data *shdata;
1838         Elf_Scn *scn;
1839         Elf *elf;
1840         size_t nshdrs, shstrndx;
1841 
1842         struct {
1843                 GElf_Shdr c_shdr;
1844                 Elf_Data *c_data;
1845                 const char *c_name;
1846         } *cp, *cache = NULL, *dyn = NULL, *plt = NULL, *ctf = NULL,
1847         *dbglink = NULL, *buildid = NULL;
1848 
1849         if (fptr->file_init)
1850                 return; /* We've already processed this file */
1851 
1852         /*
1853          * Mark the file_info struct as having the symbol table initialized
1854          * even if we fail below.  We tried once; we don't try again.
1855          */
1856         fptr->file_init = 1;
1857 
1858         if (elf_version(EV_CURRENT) == EV_NONE) {
1859                 dprintf("libproc ELF version is more recent than libelf\n");
1860                 return;
1861         }
1862 
1863         if (P->state == PS_DEAD || P->state == PS_IDLE) {
1864                 char *name;
1865                 /*
1866                  * If we're a not live, we can't open files from the /proc
1867                  * object directory; we have only the mapping and file names


2053                                     " there for %s\n", objectfile);
2054                         }
2055                 } else if (shp->sh_type == SHT_DYNAMIC) {
2056                         dyn = cp;
2057                 } else if (strcmp(cp->c_name, ".plt") == 0) {
2058                         plt = cp;
2059                 } else if (strcmp(cp->c_name, ".SUNW_ctf") == 0) {
2060                         /*
2061                          * Skip over bogus CTF sections so they don't come back
2062                          * to haunt us later.
2063                          */
2064                         if (shp->sh_link == 0 ||
2065                             shp->sh_link >= nshdrs ||
2066                             (cache[shp->sh_link].c_shdr.sh_type != SHT_DYNSYM &&
2067                             cache[shp->sh_link].c_shdr.sh_type != SHT_SYMTAB)) {
2068                                 dprintf("Bad sh_link %d for "
2069                                     "CTF\n", shp->sh_link);
2070                                 continue;
2071                         }
2072                         ctf = cp;
2073                 } else if (strcmp(cp->c_name, BUILDID_NAME) == 0) {
2074                         dprintf("Found a %s section for %s\n", BUILDID_NAME,
2075                             fptr->file_rname);
2076                         /* The ElfXX_Nhdr is 32/64-bit neutral */
2077                         if (cp->c_shdr.sh_type == SHT_NOTE &&
2078                             cp->c_data->d_buf != NULL &&
2079                             cp->c_data->d_size >= sizeof (Elf32_Nhdr)) {
2080                                 Elf32_Nhdr *hdr = cp->c_data->d_buf;
2081                                 if (hdr->n_type != 3)
2082                                         continue;
2083                                 if (hdr->n_namesz != 4)
2084                                         continue;
2085                                 if (hdr->n_descsz < MINBUILDID)
2086                                         continue;
2087                                 /* Set a reasonable upper bound */
2088                                 if (hdr->n_descsz > MAXBUILDID) {
2089                                         dprintf("Skipped %s as too large "
2090                                             "(%ld)\n", BUILDID_NAME,
2091                                             (unsigned long)hdr->n_descsz);
2092                                         continue;
2093                                 }
2094 
2095                                 if (cp->c_data->d_size < sizeof (hdr) +
2096                                     hdr->n_namesz + hdr->n_descsz)
2097                                         continue;
2098                                 buildid = cp;
2099                         }
2100                 } else if (strcmp(cp->c_name, DBGLINK_NAME) == 0) {
2101                         dprintf("found %s section for %s\n", DBGLINK_NAME,
2102                             fptr->file_rname);
2103                         /*
2104                          * Let's make sure of a few things before we do this.
2105                          */
2106                         if (cp->c_shdr.sh_type == SHT_PROGBITS &&
2107                             cp->c_data->d_buf != NULL &&
2108                             cp->c_data->d_size) {
2109                                 dbglink = cp;
2110                         }
2111                 }
2112         }
2113 
2114         /*
2115          * If we haven't found any symbol table information and we have found
2116          * either a .note.gnu.build-id or a .gnu_debuglink, it's time to try and
2117          * figure out where we might find this. Originally, GNU used the
2118          * .gnu_debuglink solely, but then they added a .note.gnu.build-id. The
2119          * build-id is some size, usually 16 or 20 bytes, often a SHA1 sum of
2120          * the old, but not present file. All that you have to do to compare
2121          * things is see if the sections are less, in theory saving you from
2122          * doing lots of expensive I/O.
2123          *
2124          * For the .note.gnu.build-id, we're going to check a few things before
2125          * using it, first that the name is 4 bytes, and is GNU and that the
2126          * type is 3, which they say is the build-id identifier.
2127          *
2128          * To verify that the elf data for the .gnu_debuglink seems somewhat
2129          * sane, eg. the elf data should be a string, so we want to verify we
2130          * have a null-terminator.
2131          */
2132         if (fptr->file_symtab.sym_data_pri == NULL && buildid != NULL) {
2133                 int i, bo;
2134                 uint8_t *dp;
2135                 char buf[BUILDID_STRLEN], *path;
2136                 Elf32_Nhdr *hdr = buildid->c_data->d_buf;
2137 
2138                 /*
2139                  * This was checked for validity when assigning the buildid
2140                  * variable.
2141                  */
2142                 bzero(buf, sizeof (buf));
2143                 dp = (uint8_t *)((uintptr_t)hdr + sizeof (*hdr) +
2144                     hdr->n_namesz);
2145                 for (i = 0, bo = 0; i < hdr->n_descsz; i++, bo += 2, dp++) {
2146                         assert(sizeof (buf) - bo > 0);
2147 
2148                         /*
2149                          * Recall that the build-id is structured as a series of
2150                          * bytes. However, the first two characters are supposed
2151                          * to represent a directory. Hence, once we reach offset
2152                          * two, we insert a '/' character.
2153                          */
2154                         if (bo == 2) {
2155                                 buf[bo] = '/';
2156                                 bo++;
2157                         }
2158                         (void) snprintf(buf + bo, sizeof (buf) - bo, "%2x",
2159                             *dp);
2160                 }
2161 
2162                 if (asprintf(&path, "/usr/lib/debug/.build-id/%s.debug",
2163                     buf) != -1) {
2164                         boolean_t r;
2165                         dprintf("attempting to find build id alternate debug "
2166                             "file at %s\n", path);
2167                         r = build_alt_debug(fptr, path, 0, buildid->c_data);
2168                         dprintf("attempt %s\n", r == B_TRUE ?
2169                             "succeeded" : "failed");
2170                         free(path);
2171                 } else {
2172                         dprintf("failed to construct build id path: %s\n",
2173                             strerror(errno));
2174                 }
2175         }
2176 
2177         if (fptr->file_symtab.sym_data_pri == NULL && dbglink != NULL) {
2178                 char *c = dbglink->c_data->d_buf;
2179                 size_t i;
2180                 boolean_t found = B_FALSE;
2181                 Elf_Data *ed = dbglink->c_data;
2182                 uint32_t crc;
2183 
2184                 for (i = 0; i < ed->d_size; i++) {
2185                         if (c[i] == '\0') {
2186                                 uintptr_t off;
2187                                 dprintf("got .gnu_debuglink terminator at "
2188                                     "offset %lu\n", (unsigned long)i);
2189                                 /*
2190                                  * After the null terminator, there should be
2191                                  * padding, followed by a 4 byte CRC of the
2192                                  * file. If we don't see this, we're going to
2193                                  * assume this is bogus.
2194                                  */
2195                                 if ((i % sizeof (uint32_t)) == 0) {
2196                                         i += 4;
2197                                 } else {
2198                                         i += sizeof (uint32_t) -
2199                                             (i % sizeof (uint32_t));
2200                                 }
2201                                 if (i + sizeof (uint32_t) ==
2202                                     dbglink->c_data->d_size) {
2203                                         found = B_TRUE;
2204                                         off = (uintptr_t)ed->d_buf + i;
2205                                         crc = *(uint32_t *)off;
2206                                 } else {
2207                                         dprintf(".gnu_debuglink size mismatch, "
2208                                             "expected: %lu, found: %lu\n",
2209                                             (unsigned long)i,
2210                                             (unsigned long)ed->d_size);
2211                                 }
2212                                 break;
2213                         }
2214                 }
2215 
2216                 if (found == B_TRUE)
2217                         find_alt_debuglink(fptr, dbglink->c_data->d_buf, crc);
2218         }
2219 
2220         /*
2221          * At this point, we've found all the symbol tables we're ever going
2222          * to find: the ones in the loop above and possibly the symtab that
2223          * was included in the core file. Before we perform any lookups, we
2224          * create sorted versions to optimize for lookups.
2225          */
2226         optimize_symtab(&fptr->file_symtab);
2227         optimize_symtab(&fptr->file_dynsym);
2228 
2229         /*
2230          * Fill in the base address of the text mapping for shared libraries.
2231          * This allows us to translate symbols before librtld_db is ready.
2232          */
2233         if (fptr->file_etype == ET_DYN) {
2234                 fptr->file_dyn_base = fptr->file_map->map_pmap.pr_vaddr -
2235                     fptr->file_map->map_pmap.pr_offset;
2236                 dprintf("setting file_dyn_base for %s to %lx\n",
2237                     objectfile, (long)fptr->file_dyn_base);
2238         }
2239 
2240         /*


2327 
2328                 dprintf("_DYNAMIC found at %p, %lu entries, DT_JMPREL = %p\n",
2329                     (void *)dynaddr, (ulong_t)ndyn, (void *)fptr->file_jmp_rel);
2330         }
2331 
2332 done:
2333         free(cache);
2334         return;
2335 
2336 bad:
2337         if (cache != NULL)
2338                 free(cache);
2339 
2340         (void) elf_end(elf);
2341         fptr->file_elf = NULL;
2342         if (fptr->file_elfmem != NULL) {
2343                 free(fptr->file_elfmem);
2344                 fptr->file_elfmem = NULL;
2345         }
2346         (void) close(fptr->file_fd);
2347         if (fptr->file_dbgelf != NULL)
2348                 (void) elf_end(fptr->file_dbgelf);
2349         fptr->file_dbgelf = NULL;
2350         if (fptr->file_dbgfile >= 0)
2351                 (void) close(fptr->file_dbgfile);
2352         fptr->file_fd = -1;
2353         fptr->file_dbgfile = -1;
2354 }
2355 
2356 /*
2357  * Given a process virtual address, return the map_info_t containing it.
2358  * If none found, return NULL.
2359  */
2360 map_info_t *
2361 Paddr2mptr(struct ps_prochandle *P, uintptr_t addr)
2362 {
2363         int lo = 0;
2364         int hi = P->map_count - 1;
2365         int mid;
2366         map_info_t *mp;
2367 
2368         while (lo <= hi) {
2369 
2370                 mid = (lo + hi) / 2;
2371                 mp = &P->mappings[mid];
2372 
2373                 /* check that addr is in [vaddr, vaddr + size) */