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