1 /*
   2  * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include <unistd.h>
  26 #include <sys/procfs.h>
  27 #include <search.h>
  28 #include <stdlib.h>
  29 #include <string.h>
  30 #include "symtab.h"
  31 #include "salibelf.h"
  32 
  33 
  34 // ----------------------------------------------------
  35 // functions for symbol lookups
  36 // ----------------------------------------------------
  37 
  38 struct elf_section {
  39   ELF_SHDR   *c_shdr;
  40   void       *c_data;
  41 };
  42 
  43 struct elf_symbol {
  44   char *name;
  45   uintptr_t offset;
  46   uintptr_t size;
  47 };
  48 
  49 typedef struct symtab {
  50   char *strs;
  51   size_t num_symbols;
  52   struct elf_symbol *symbols;
  53   struct hsearch_data *hash_table;
  54 } symtab_t;
  55 
  56 
  57 // Directory that contains global debuginfo files.  In theory it
  58 // should be possible to change this, but in a Java environment there
  59 // is no obvious place to put a user interface to do it.  Maybe this
  60 // could be set with an environment variable.
  61 static const char debug_file_directory[] = "/usr/lib/debug";
  62 
  63 /* The CRC used in gnu_debuglink, retrieved from
  64    http://sourceware.org/gdb/current/onlinedocs/gdb/Separate-Debug-Files.html#Separate-Debug-Files. */
  65 unsigned int gnu_debuglink_crc32 (unsigned int crc,
  66                                   unsigned char *buf, size_t len)
  67 {
  68   static const unsigned int crc32_table[256] =
  69     {
  70       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
  71       0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
  72       0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
  73       0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
  74       0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
  75       0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
  76       0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
  77       0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
  78       0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
  79       0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
  80       0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
  81       0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
  82       0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
  83       0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
  84       0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
  85       0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
  86       0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
  87       0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
  88       0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
  89       0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
  90       0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
  91       0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
  92       0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
  93       0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
  94       0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
  95       0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
  96       0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
  97       0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
  98       0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
  99       0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
 100       0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
 101       0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
 102       0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
 103       0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
 104       0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
 105       0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
 106       0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
 107       0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
 108       0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
 109       0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
 110       0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
 111       0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
 112       0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
 113       0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
 114       0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
 115       0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
 116       0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
 117       0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
 118       0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
 119       0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
 120       0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
 121       0x2d02ef8d
 122     };
 123   unsigned char *end;
 124 
 125   crc = ~crc & 0xffffffff;
 126   for (end = buf + len; buf < end; ++buf)
 127     crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
 128   return ~crc & 0xffffffff;
 129 }
 130 
 131 /* Open a debuginfo file and check its CRC.  If it exists and the CRC
 132    matches return its fd.  */
 133 static int
 134 open_debug_file (const char *pathname, unsigned int crc)
 135 {
 136   unsigned int file_crc = 0;
 137   unsigned char buffer[8 * 1024];
 138 
 139   int fd = pathmap_open(pathname);
 140 
 141   if (fd < 0)
 142     return -1;
 143 
 144   lseek(fd, 0, SEEK_SET);
 145 
 146   for (;;) {
 147     int len = read(fd, buffer, sizeof buffer);
 148     if (len <= 0)
 149       break;
 150     file_crc = gnu_debuglink_crc32(file_crc, buffer, len);
 151   }
 152 
 153   if (crc == file_crc)
 154     return fd;
 155   else {
 156     close(fd);
 157     return -1;
 158   }
 159 }
 160 
 161 /* Find an ELF section.  */
 162 static struct elf_section *find_section_by_name(char *name,
 163                                                 int fd,
 164                                                 ELF_EHDR *ehdr,
 165                                                 struct elf_section *scn_cache)
 166 {
 167   char *strtab;
 168   int cnt;
 169   int strtab_size;
 170 
 171   // Section cache have to already contain data for e_shstrndx section.
 172   // If it's not true - elf file is broken, so just bail out
 173   if (scn_cache[ehdr->e_shstrndx].c_data == NULL) {
 174     return NULL;
 175   }
 176 
 177   strtab = scn_cache[ehdr->e_shstrndx].c_data;
 178   strtab_size = scn_cache[ehdr->e_shstrndx].c_shdr->sh_size;
 179 
 180   for (cnt = 0; cnt < ehdr->e_shnum; ++cnt) {
 181     if (scn_cache[cnt].c_shdr->sh_name < strtab_size) {
 182       if (strcmp(scn_cache[cnt].c_shdr->sh_name + strtab, name) == 0) {
 183         scn_cache[cnt].c_data = read_section_data(fd, ehdr, scn_cache[cnt].c_shdr);
 184         return &scn_cache[cnt];
 185       }
 186     }
 187   }
 188 
 189   return NULL;
 190 }
 191 
 192 /* Look for a ".gnu_debuglink" section.  If one exists, try to open a
 193    suitable debuginfo file.  */
 194 static int open_file_from_debug_link(const char *name,
 195                                      int fd,
 196                                      ELF_EHDR *ehdr,
 197                                      struct elf_section *scn_cache)
 198 {
 199   int debug_fd;
 200   struct elf_section *debug_link = find_section_by_name(".gnu_debuglink", fd, ehdr,
 201                                                          scn_cache);
 202   if (debug_link == NULL)
 203     return -1;
 204   char *debug_filename = debug_link->c_data;
 205   int offset = (strlen(debug_filename) + 4) >> 2;
 206   static unsigned int crc;
 207   crc = ((unsigned int*)debug_link->c_data)[offset];
 208   char *debug_pathname = malloc(strlen(debug_filename)
 209                                 + strlen(name)
 210                                 + strlen(".debug/")
 211                                 + strlen(debug_file_directory)
 212                                 + 2);
 213   strcpy(debug_pathname, name);
 214   char *last_slash = strrchr(debug_pathname, '/');
 215   if (last_slash == NULL) {
 216     free(debug_pathname);
 217     return -1;
 218   }
 219 
 220   /* Look in the same directory as the object.  */
 221   strcpy(last_slash+1, debug_filename);
 222   debug_fd = open_debug_file(debug_pathname, crc);
 223   if (debug_fd >= 0) {
 224     free(debug_pathname);
 225     return debug_fd;
 226   }
 227 
 228   /* Look in a subdirectory named ".debug".  */
 229   strcpy(last_slash+1, ".debug/");
 230   strcat(last_slash, debug_filename);
 231 
 232   debug_fd = open_debug_file(debug_pathname, crc);
 233   if (debug_fd >= 0) {
 234     free(debug_pathname);
 235     return debug_fd;
 236   }
 237 
 238   /* Look in /usr/lib/debug + the full pathname.  */
 239   strcpy(debug_pathname, debug_file_directory);
 240   strcat(debug_pathname, name);
 241   last_slash = strrchr(debug_pathname, '/');
 242   strcpy(last_slash+1, debug_filename);
 243 
 244   debug_fd = open_debug_file(debug_pathname, crc);
 245   if (debug_fd >= 0) {
 246     free(debug_pathname);
 247     return debug_fd;
 248   }
 249 
 250   free(debug_pathname);
 251   return -1;
 252 }
 253 
 254 static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo);
 255 
 256 /* Look for a ".gnu_debuglink" section.  If one exists, try to open a
 257    suitable debuginfo file and read a symbol table from it.  */
 258 static struct symtab *build_symtab_from_debug_link(const char *name,
 259                                      int fd,
 260                                      ELF_EHDR *ehdr,
 261                                      struct elf_section *scn_cache)
 262 {
 263   fd = open_file_from_debug_link(name, fd, ehdr, scn_cache);
 264 
 265   if (fd >= 0) {
 266     struct symtab *symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false);
 267     close(fd);
 268     return symtab;
 269   }
 270 
 271   return NULL;
 272 }
 273 
 274 // Given a build_id, find the associated debuginfo file
 275 static char *
 276 build_id_to_debug_filename (size_t size, unsigned char *data)
 277 {
 278   char *filename, *s;
 279 
 280   filename = malloc(strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
 281                     + 2 * size + (sizeof ".debug" - 1) + 1);
 282   s = filename + sprintf (filename, "%s/.build-id/", debug_file_directory);
 283   if (size > 0)
 284     {
 285       size--;
 286       s += sprintf (s, "%02x", *data++);
 287     }
 288   if (size > 0)
 289     *s++ = '/';
 290   while (size-- > 0)
 291     s += sprintf (s, "%02x", *data++);
 292   strcpy (s, ".debug");
 293 
 294   return filename;
 295 }
 296 
 297 // Read a build ID note.  Try to open any associated debuginfo file
 298 // and return its symtab
 299 static struct symtab* build_symtab_from_build_id(Elf64_Nhdr *note)
 300 {
 301   int fd;
 302   struct symtab *symtab = NULL;
 303 
 304   unsigned char *bytes
 305     = (unsigned char*)(note+1) + note->n_namesz;
 306   char *filename
 307     = (build_id_to_debug_filename (note->n_descsz, bytes));
 308 
 309   fd = pathmap_open(filename);
 310   if (fd >= 0) {
 311     symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false);
 312     close(fd);
 313   }
 314   free(filename);
 315 
 316   return symtab;
 317 }
 318 
 319 // read symbol table from given fd.  If try_debuginfo) is true, also
 320 // try to open an associated debuginfo file
 321 static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo) {
 322   ELF_EHDR ehdr;
 323   char *names = NULL;
 324   struct symtab* symtab = NULL;
 325 
 326   // Reading of elf header
 327   struct elf_section *scn_cache = NULL;
 328 #if defined(ppc64) && !defined(ABI_ELFv2)
 329   // Only big endian ppc64 (i.e. ABI_ELFv1) has 'official procedure descriptors' in ELF files
 330   // see: http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html
 331   struct elf_section *opd_sect = NULL;
 332   ELF_SHDR *opd = NULL;
 333 #endif
 334   int cnt = 0;
 335   ELF_SHDR* shbuf = NULL;
 336   ELF_SHDR* cursct = NULL;
 337   ELF_PHDR* phbuf = NULL;
 338   ELF_PHDR* phdr = NULL;
 339   int sym_section = SHT_DYNSYM;
 340 
 341   uintptr_t baseaddr = (uintptr_t)-1;
 342 
 343   lseek(fd, (off_t)0L, SEEK_SET);
 344   if (! read_elf_header(fd, &ehdr)) {
 345     // not an elf
 346     return NULL;
 347   }
 348 
 349   // read ELF header
 350   if ((shbuf = read_section_header_table(fd, &ehdr)) == NULL) {
 351     goto quit;
 352   }
 353 
 354   baseaddr = find_base_address(fd, &ehdr);
 355 
 356   scn_cache = (struct elf_section *)
 357               calloc(ehdr.e_shnum * sizeof(struct elf_section), 1);
 358   if (scn_cache == NULL) {
 359     goto quit;
 360   }
 361 
 362   for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) {
 363     scn_cache[cnt].c_shdr = cursct;
 364     if (cursct->sh_type == SHT_SYMTAB || cursct->sh_type == SHT_STRTAB
 365         || cursct->sh_type == SHT_NOTE || cursct->sh_type == SHT_DYNSYM) {
 366       if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) {
 367          goto quit;
 368       }
 369     }
 370     if (cursct->sh_type == SHT_SYMTAB) {
 371       // Full symbol table available so use that
 372       sym_section = cursct->sh_type;
 373     }
 374     cursct++;
 375   }
 376 
 377 #if defined(ppc64) && !defined(ABI_ELFv2)
 378   opd_sect = find_section_by_name(".opd", fd, &ehdr, scn_cache);
 379   if (opd_sect != NULL && opd_sect->c_data != NULL && opd_sect->c_shdr != NULL) {
 380     // plausibility check
 381     opd = opd_sect->c_shdr;
 382   }
 383 #endif
 384 
 385   for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
 386     ELF_SHDR *shdr = scn_cache[cnt].c_shdr;
 387 
 388     if (shdr->sh_type == sym_section) {
 389       ELF_SYM  *syms;
 390       int rslt;
 391       size_t size, n, j, htab_sz;
 392 
 393       // FIXME: there could be multiple data buffers associated with the
 394       // same ELF section. Here we can handle only one buffer. See man page
 395       // for elf_getdata on Solaris.
 396 
 397       // guarantee(symtab == NULL, "multiple symtab");
 398       symtab = (struct symtab*)calloc(1, sizeof(struct symtab));
 399       if (symtab == NULL) {
 400          goto quit;
 401       }
 402       // the symbol table
 403       syms = (ELF_SYM *)scn_cache[cnt].c_data;
 404 
 405       // number of symbols
 406       n = shdr->sh_size / shdr->sh_entsize;
 407 
 408       // create hash table, we use hcreate_r, hsearch_r and hdestroy_r to
 409       // manipulate the hash table.
 410 
 411       // NOTES section in the man page of hcreate_r says
 412       // "Hash table implementations are usually more efficient when
 413       // the table contains enough free space to minimize collisions.
 414       // Typically, this means that nel should be at least 25% larger
 415       // than the maximum number of elements that the caller expects
 416       // to store in the table."
 417       htab_sz = n*1.25;
 418 
 419       symtab->hash_table = (struct hsearch_data*) calloc(1, sizeof(struct hsearch_data));
 420       rslt = hcreate_r(n, symtab->hash_table);
 421       // guarantee(rslt, "unexpected failure: hcreate_r");
 422 
 423       // shdr->sh_link points to the section that contains the actual strings
 424       // for symbol names. the st_name field in ELF_SYM is just the
 425       // string table index. we make a copy of the string table so the
 426       // strings will not be destroyed by elf_end.
 427       size = scn_cache[shdr->sh_link].c_shdr->sh_size;
 428       symtab->strs = (char *)malloc(size);
 429       memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data, size);
 430 
 431       // allocate memory for storing symbol offset and size;
 432       symtab->num_symbols = n;
 433       symtab->symbols = (struct elf_symbol *)calloc(n , sizeof(struct elf_symbol));
 434 
 435       // copy symbols info our symtab and enter them info the hash table
 436       for (j = 0; j < n; j++, syms++) {
 437         ENTRY item, *ret;
 438         uintptr_t sym_value;
 439         char *sym_name = symtab->strs + syms->st_name;
 440 
 441         // skip non-object and non-function symbols
 442         int st_type = ELF_ST_TYPE(syms->st_info);
 443         if ( st_type != STT_FUNC && st_type != STT_OBJECT)
 444            continue;
 445         // skip empty strings and undefined symbols
 446         if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue;
 447 
 448         symtab->symbols[j].name   = sym_name;
 449         symtab->symbols[j].size   = syms->st_size;
 450         sym_value = syms->st_value;
 451 
 452 #if defined(ppc64) && !defined(ABI_ELFv2)
 453         // see hotspot/src/share/vm/utilities/elfFuncDescTable.hpp for a detailed description
 454         // of why we have to go this extra way via the '.opd' section on big endian ppc64
 455         if (opd != NULL && *sym_name != '.' &&
 456             (opd->sh_addr <= sym_value && sym_value <= opd->sh_addr + opd->sh_size)) {
 457           sym_value = ((ELF_ADDR*)opd_sect->c_data)[(sym_value - opd->sh_addr) / sizeof(ELF_ADDR*)];
 458         }
 459 #endif
 460 
 461         symtab->symbols[j].offset = sym_value - baseaddr;
 462         item.key = sym_name;
 463         item.data = (void *)&(symtab->symbols[j]);
 464         hsearch_r(item, ENTER, &ret, symtab->hash_table);
 465       }
 466     }
 467   }
 468 
 469 #if defined(ppc64) && !defined(ABI_ELFv2)
 470   // On Linux/PPC64 the debuginfo files contain an empty function descriptor
 471   // section (i.e. '.opd' section) which makes the resolution of symbols
 472   // with the above algorithm impossible (we would need the have both, the
 473   // .opd section from the library and the symbol table from the debuginfo
 474   // file which doesn't match with the current workflow.)
 475   goto quit;
 476 #endif
 477 
 478   // Look for a separate debuginfo file.
 479   if (try_debuginfo) {
 480     // We prefer a debug symtab to an object's own symtab, so look in
 481     // the debuginfo file.  We stash a copy of the old symtab in case
 482     // there is no debuginfo.
 483     struct symtab* prev_symtab = symtab;
 484     symtab = NULL;
 485 
 486 #ifdef NT_GNU_BUILD_ID
 487     // First we look for a Build ID
 488     for (cursct = shbuf, cnt = 0;
 489          symtab == NULL && cnt < ehdr.e_shnum;
 490          cnt++) {
 491       if (cursct->sh_type == SHT_NOTE) {
 492         Elf64_Nhdr *note = (Elf64_Nhdr *)scn_cache[cnt].c_data;
 493         if (note->n_type == NT_GNU_BUILD_ID) {
 494           symtab = build_symtab_from_build_id(note);
 495         }
 496       }
 497       cursct++;
 498     }
 499 #endif
 500 
 501     // Then, if that doesn't work, the debug link
 502     if (symtab == NULL) {
 503       symtab = build_symtab_from_debug_link(filename, fd, &ehdr,
 504                                             scn_cache);
 505     }
 506 
 507     // If we still haven't found a symtab, use the object's own symtab.
 508     if (symtab != NULL) {
 509       if (prev_symtab != NULL)
 510         destroy_symtab(prev_symtab);
 511     } else {
 512       symtab = prev_symtab;
 513     }
 514   }
 515 
 516 quit:
 517   if (shbuf) free(shbuf);
 518   if (phbuf) free(phbuf);
 519   if (scn_cache) {
 520     for (cnt = 0; cnt < ehdr.e_shnum; cnt++) {
 521       if (scn_cache[cnt].c_data != NULL) {
 522         free(scn_cache[cnt].c_data);
 523       }
 524     }
 525     free(scn_cache);
 526   }
 527   return symtab;
 528 }
 529 
 530 struct symtab* build_symtab(int fd, const char *filename) {
 531   return build_symtab_internal(fd, filename, /* try_debuginfo */ true);
 532 }
 533 
 534 
 535 void destroy_symtab(struct symtab* symtab) {
 536   if (!symtab) return;
 537   if (symtab->strs) free(symtab->strs);
 538   if (symtab->symbols) free(symtab->symbols);
 539   if (symtab->hash_table) {
 540      hdestroy_r(symtab->hash_table);
 541      free(symtab->hash_table);
 542   }
 543   free(symtab);
 544 }
 545 
 546 uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
 547                       const char *sym_name, int *sym_size) {
 548   ENTRY item;
 549   ENTRY* ret = NULL;
 550 
 551   // library does not have symbol table
 552   if (!symtab || !symtab->hash_table)
 553      return (uintptr_t)NULL;
 554 
 555   item.key = (char*) strdup(sym_name);
 556   item.data = NULL;
 557   hsearch_r(item, FIND, &ret, symtab->hash_table);
 558   if (ret) {
 559     struct elf_symbol * sym = (struct elf_symbol *)(ret->data);
 560     uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset);
 561     if (sym_size) *sym_size = sym->size;
 562     free(item.key);
 563     return rslt;
 564   }
 565 
 566 quit:
 567   free(item.key);
 568   return (uintptr_t) NULL;
 569 }
 570 
 571 const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
 572                            uintptr_t* poffset) {
 573   int n = 0;
 574   if (!symtab) return NULL;
 575   for (; n < symtab->num_symbols; n++) {
 576      struct elf_symbol* sym = &(symtab->symbols[n]);
 577      if (sym->name != NULL &&
 578          offset >= sym->offset && offset < sym->offset + sym->size) {
 579         if (poffset) *poffset = (offset - sym->offset);
 580         return sym->name;
 581      }
 582   }
 583   return NULL;
 584 }