1 /* 2 * Copyright (c) 2003, 2019, 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 }