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