1 /* 2 * Copyright (c) 2003, 2010, 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 ELF_SHDR *shbuf, 166 struct elf_section *scn_cache) 167 { 168 ELF_SHDR* cursct = NULL; 169 char *strtab; 170 int cnt; 171 172 if (scn_cache[ehdr->e_shstrndx].c_data == NULL) { 173 if ((scn_cache[ehdr->e_shstrndx].c_data 174 = read_section_data(fd, ehdr, cursct)) == NULL) { 175 return NULL; 176 } 177 } 178 179 strtab = scn_cache[ehdr->e_shstrndx].c_data; 180 181 for (cursct = shbuf, cnt = 0; 182 cnt < ehdr->e_shnum; 183 cnt++, cursct++) { 184 if (strcmp(cursct->sh_name + strtab, name) == 0) { 185 scn_cache[cnt].c_data = read_section_data(fd, ehdr, cursct); 186 return &scn_cache[cnt]; 187 } 188 } 189 190 return NULL; 191 } 192 193 /* Look for a ".gnu_debuglink" section. If one exists, try to open a 194 suitable debuginfo file. */ 195 static int open_file_from_debug_link(const char *name, 196 int fd, 197 ELF_EHDR *ehdr, 198 ELF_SHDR *shbuf, 199 struct elf_section *scn_cache) 200 { 201 int debug_fd; 202 struct elf_section *debug_link = find_section_by_name(".gnu_debuglink", fd, ehdr, 203 shbuf, scn_cache); 204 if (debug_link == NULL) 205 return -1; 206 char *debug_filename = debug_link->c_data; 207 int offset = (strlen(debug_filename) + 4) >> 2; 208 static unsigned int crc; 209 crc = ((unsigned int*)debug_link->c_data)[offset]; 210 char *debug_pathname = malloc(strlen(debug_filename) 211 + strlen(name) 212 + strlen(".debug/") 213 + strlen(debug_file_directory) 214 + 2); 215 strcpy(debug_pathname, name); 216 char *last_slash = strrchr(debug_pathname, '/'); 217 if (last_slash == NULL) 218 free(debug_pathname); 219 return -1; 220 221 /* Look in the same directory as the object. */ 222 strcpy(last_slash+1, debug_filename); 223 224 debug_fd = open_debug_file(debug_pathname, crc); 225 if (debug_fd >= 0) { 226 free(debug_pathname); 227 return debug_fd; 228 } 229 230 /* Look in a subdirectory named ".debug". */ 231 strcpy(last_slash+1, ".debug/"); 232 strcat(last_slash, debug_filename); 233 234 debug_fd = open_debug_file(debug_pathname, crc); 235 if (debug_fd >= 0) { 236 free(debug_pathname); 237 return debug_fd; 238 } 239 240 /* Look in /usr/lib/debug + the full pathname. */ 241 strcpy(debug_pathname, debug_file_directory); 242 strcat(debug_pathname, name); 243 last_slash = strrchr(debug_pathname, '/'); 244 strcpy(last_slash+1, debug_filename); 245 246 debug_fd = open_debug_file(debug_pathname, crc); 247 if (debug_fd >= 0) { 248 free(debug_pathname); 249 return debug_fd; 250 } 251 252 free(debug_pathname); 253 return -1; 254 } 255 256 static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo); 257 258 /* Look for a ".gnu_debuglink" section. If one exists, try to open a 259 suitable debuginfo file and read a symbol table from it. */ 260 static struct symtab *build_symtab_from_debug_link(const char *name, 261 int fd, 262 ELF_EHDR *ehdr, 263 ELF_SHDR *shbuf, 264 struct elf_section *scn_cache) 265 { 266 fd = open_file_from_debug_link(name, fd, ehdr, shbuf, scn_cache); 267 268 if (fd >= 0) { 269 struct symtab *symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false); 270 close(fd); 271 return symtab; 272 } 273 274 return NULL; 275 } 276 277 // Given a build_id, find the associated debuginfo file 278 static char * 279 build_id_to_debug_filename (size_t size, unsigned char *data) 280 { 281 char *filename, *s; 282 283 filename = malloc(strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1 284 + 2 * size + (sizeof ".debug" - 1) + 1); 285 s = filename + sprintf (filename, "%s/.build-id/", debug_file_directory); 286 if (size > 0) 287 { 288 size--; 289 s += sprintf (s, "%02x", *data++); 290 } 291 if (size > 0) 292 *s++ = '/'; 293 while (size-- > 0) 294 s += sprintf (s, "%02x", *data++); 295 strcpy (s, ".debug"); 296 297 return filename; 298 } 299 300 // Read a build ID note. Try to open any associated debuginfo file 301 // and return its symtab 302 static struct symtab* build_symtab_from_build_id(Elf64_Nhdr *note) 303 { 304 int fd; 305 struct symtab *symtab = NULL; 306 307 unsigned char *bytes 308 = (unsigned char*)(note+1) + note->n_namesz; 309 char *filename 310 = (build_id_to_debug_filename (note->n_descsz, bytes)); 311 312 fd = pathmap_open(filename); 313 if (fd >= 0) { 314 symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false); 315 close(fd); 316 } 317 free(filename); 318 319 return symtab; 320 } 321 322 // read symbol table from given fd. If try_debuginfo) is true, also 323 // try to open an associated debuginfo file 324 static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo) { 325 ELF_EHDR ehdr; 326 char *names = NULL; 327 struct symtab* symtab = NULL; 328 329 // Reading of elf header 330 struct elf_section *scn_cache = NULL; 331 int cnt = 0; 332 ELF_SHDR* shbuf = NULL; 333 ELF_SHDR* cursct = NULL; 334 ELF_PHDR* phbuf = NULL; 335 ELF_PHDR* phdr = NULL; 336 int sym_section = SHT_DYNSYM; 337 338 uintptr_t baseaddr = (uintptr_t)-1; 339 340 lseek(fd, (off_t)0L, SEEK_SET); 341 if (! read_elf_header(fd, &ehdr)) { 342 // not an elf 343 return NULL; 344 } 345 346 // read ELF header 347 if ((shbuf = read_section_header_table(fd, &ehdr)) == NULL) { 348 goto quit; 349 } 350 351 baseaddr = find_base_address(fd, &ehdr); 352 353 scn_cache = (struct elf_section *) 354 calloc(ehdr.e_shnum * sizeof(struct elf_section), 1); 355 if (scn_cache == NULL) { 356 goto quit; 357 } 358 359 for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) { 360 scn_cache[cnt].c_shdr = cursct; 361 if (cursct->sh_type == SHT_SYMTAB || cursct->sh_type == SHT_STRTAB 362 || cursct->sh_type == SHT_NOTE || cursct->sh_type == SHT_DYNSYM) { 363 if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) { 364 goto quit; 365 } 366 } 367 if (cursct->sh_type == SHT_SYMTAB) { 368 // Full symbol table available so use that 369 sym_section = cursct->sh_type; 370 } 371 cursct++; 372 } 373 374 for (cnt = 1; cnt < ehdr.e_shnum; cnt++) { 375 ELF_SHDR *shdr = scn_cache[cnt].c_shdr; 376 377 if (shdr->sh_type == sym_section) { 378 ELF_SYM *syms; 379 int j, n, rslt; 380 size_t size; 381 382 // FIXME: there could be multiple data buffers associated with the 383 // same ELF section. Here we can handle only one buffer. See man page 384 // for elf_getdata on Solaris. 385 386 // guarantee(symtab == NULL, "multiple symtab"); 387 symtab = (struct symtab*)calloc(1, sizeof(struct symtab)); 388 if (symtab == NULL) { 389 goto quit; 390 } 391 // the symbol table 392 syms = (ELF_SYM *)scn_cache[cnt].c_data; 393 394 // number of symbols 395 n = shdr->sh_size / shdr->sh_entsize; 396 397 // create hash table, we use hcreate_r, hsearch_r and hdestroy_r to 398 // manipulate the hash table. 399 symtab->hash_table = (struct hsearch_data*) calloc(1, sizeof(struct hsearch_data)); 400 rslt = hcreate_r(n, symtab->hash_table); 401 // guarantee(rslt, "unexpected failure: hcreate_r"); 402 403 // shdr->sh_link points to the section that contains the actual strings 404 // for symbol names. the st_name field in ELF_SYM is just the 405 // string table index. we make a copy of the string table so the 406 // strings will not be destroyed by elf_end. 407 size = scn_cache[shdr->sh_link].c_shdr->sh_size; 408 symtab->strs = (char *)malloc(size); 409 memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data, size); 410 411 // allocate memory for storing symbol offset and size; 412 symtab->num_symbols = n; 413 symtab->symbols = (struct elf_symbol *)calloc(n , sizeof(struct elf_symbol)); 414 415 // copy symbols info our symtab and enter them info the hash table 416 for (j = 0; j < n; j++, syms++) { 417 ENTRY item, *ret; 418 char *sym_name = symtab->strs + syms->st_name; 419 420 // skip non-object and non-function symbols 421 int st_type = ELF_ST_TYPE(syms->st_info); 422 if ( st_type != STT_FUNC && st_type != STT_OBJECT) 423 continue; 424 // skip empty strings and undefined symbols 425 if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue; 426 427 symtab->symbols[j].name = sym_name; 428 symtab->symbols[j].offset = syms->st_value - baseaddr; 429 symtab->symbols[j].size = syms->st_size; 430 431 item.key = sym_name; 432 item.data = (void *)&(symtab->symbols[j]); 433 434 hsearch_r(item, ENTER, &ret, symtab->hash_table); 435 } 436 } 437 } 438 439 // Look for a separate debuginfo file. 440 if (try_debuginfo) { 441 442 // We prefer a debug symtab to an object's own symtab, so look in 443 // the debuginfo file. We stash a copy of the old symtab in case 444 // there is no debuginfo. 445 struct symtab* prev_symtab = symtab; 446 symtab = NULL; 447 448 #ifdef NT_GNU_BUILD_ID 449 // First we look for a Build ID 450 for (cursct = shbuf, cnt = 0; 451 symtab == NULL && cnt < ehdr.e_shnum; 452 cnt++) { 453 if (cursct->sh_type == SHT_NOTE) { 454 Elf64_Nhdr *note = (Elf64_Nhdr *)scn_cache[cnt].c_data; 455 if (note->n_type == NT_GNU_BUILD_ID) { 456 symtab = build_symtab_from_build_id(note); 457 } 458 } 459 cursct++; 460 } 461 #endif 462 463 // Then, if that doesn't work, the debug link 464 if (symtab == NULL) { 465 symtab = build_symtab_from_debug_link(filename, fd, &ehdr, shbuf, 466 scn_cache); 467 } 468 469 // If we still haven't found a symtab, use the object's own symtab. 470 if (symtab != NULL) { 471 if (prev_symtab != NULL) 472 destroy_symtab(prev_symtab); 473 } else { 474 symtab = prev_symtab; 475 } 476 } 477 478 quit: 479 if (shbuf) free(shbuf); 480 if (phbuf) free(phbuf); 481 if (scn_cache) { 482 for (cnt = 0; cnt < ehdr.e_shnum; cnt++) { 483 if (scn_cache[cnt].c_data != NULL) { 484 free(scn_cache[cnt].c_data); 485 } 486 } 487 free(scn_cache); 488 } 489 return symtab; 490 } 491 492 struct symtab* build_symtab(int fd, const char *filename) { 493 return build_symtab_internal(fd, filename, /* try_debuginfo */ true); 494 } 495 496 497 void destroy_symtab(struct symtab* symtab) { 498 if (!symtab) return; 499 if (symtab->strs) free(symtab->strs); 500 if (symtab->symbols) free(symtab->symbols); 501 if (symtab->hash_table) { 502 hdestroy_r(symtab->hash_table); 503 free(symtab->hash_table); 504 } 505 free(symtab); 506 } 507 508 uintptr_t search_symbol(struct symtab* symtab, uintptr_t base, 509 const char *sym_name, int *sym_size) { 510 ENTRY item; 511 ENTRY* ret = NULL; 512 513 // library does not have symbol table 514 if (!symtab || !symtab->hash_table) 515 return (uintptr_t)NULL; 516 517 item.key = (char*) strdup(sym_name); 518 hsearch_r(item, FIND, &ret, symtab->hash_table); 519 if (ret) { 520 struct elf_symbol * sym = (struct elf_symbol *)(ret->data); 521 uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset); 522 if (sym_size) *sym_size = sym->size; 523 free(item.key); 524 return rslt; 525 } 526 527 quit: 528 free(item.key); 529 return (uintptr_t) NULL; 530 } 531 532 const char* nearest_symbol(struct symtab* symtab, uintptr_t offset, 533 uintptr_t* poffset) { 534 int n = 0; 535 if (!symtab) return NULL; 536 for (; n < symtab->num_symbols; n++) { 537 struct elf_symbol* sym = &(symtab->symbols[n]); 538 if (sym->name != NULL && 539 offset >= sym->offset && offset < sym->offset + sym->size) { 540 if (poffset) *poffset = (offset - sym->offset); 541 return sym->name; 542 } 543 } 544 return NULL; 545 }