github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-elf-read.c (about) 1 /* 2 * jit-elf-read.c - Routines to read ELF-format binaries. 3 * 4 * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 * 6 * This file is part of the libjit library. 7 * 8 * The libjit library is free software: you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public License 10 * as published by the Free Software Foundation, either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * The libjit library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with the libjit library. If not, see 20 * <http://www.gnu.org/licenses/>. 21 */ 22 23 #include "jit-internal.h" 24 #include "jit-rules.h" 25 #include "jit-elf-defs.h" 26 #ifdef JIT_WIN32_PLATFORM 27 #ifdef HAVE_SYS_TYPES_H 28 #include <sys/types.h> 29 #endif 30 #include <windows.h> 31 #include <io.h> 32 #include <fcntl.h> 33 #else 34 #ifdef HAVE_SYS_TYPES_H 35 #include <sys/types.h> 36 #endif 37 #ifdef HAVE_SYS_STAT_H 38 #include <sys/stat.h> 39 #endif 40 #ifdef HAVE_FCNTL_H 41 #include <fcntl.h> 42 #endif 43 #ifdef HAVE_UNISTD_H 44 #include <unistd.h> 45 #endif 46 #ifdef HAVE_SYS_MMAN_H 47 #include <sys/mman.h> 48 #if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) && defined(HAVE_MPROTECT) 49 #define JIT_USE_MMAP_TO_LOAD 1 50 #ifndef MAP_ANON 51 #ifdef MAP_ANONYMOUS 52 #define MAP_ANON MAP_ANONYMOUS 53 #else 54 #define MAP_ANON 0 55 #endif 56 #endif 57 #ifndef MAP_FIXED 58 #define MAP_FIXED 0 59 #endif 60 #ifndef MAP_COPY 61 #define MAP_COPY MAP_PRIVATE 62 #endif 63 #endif 64 #endif 65 #endif 66 #include <stdio.h> 67 68 /*@ 69 70 The @code{libjit} library contains routines that permit pre-compiling 71 JIT'ed functions into an on-disk representation. This representation 72 can be loaded at some future time, to avoid the overhead of compiling 73 the functions at runtime. 74 75 We use the ELF format for this purpose, which is a common binary format 76 used by modern operating systems and compilers. 77 78 It isn't necessary for your operating system to be based on ELF natively. 79 We use our own routines to read and write ELF binaries. We chose ELF 80 because it has all of the features that we require, and reusing an 81 existing format was better than inventing a completely new one. 82 83 @section Reading ELF binaries 84 85 @*/ 86 87 /* 88 * Determine whether we should be using the 32-bit or 64-bit ELF structures. 89 */ 90 #ifdef JIT_NATIVE_INT32 91 typedef Elf32_Ehdr Elf_Ehdr; 92 typedef Elf32_Shdr Elf_Shdr; 93 typedef Elf32_Phdr Elf_Phdr; 94 typedef Elf32_Addr Elf_Addr; 95 typedef Elf32_Word Elf_Word; 96 typedef Elf32_Xword Elf_Xword; 97 typedef Elf32_Off Elf_Off; 98 typedef Elf32_Dyn Elf_Dyn; 99 typedef Elf32_Sym Elf_Sym; 100 typedef Elf32_Rel Elf_Rel; 101 typedef Elf32_Rela Elf_Rela; 102 #define ELF_R_SYM(val) ELF32_R_SYM((val)) 103 #define ELF_R_TYPE(val) ELF32_R_TYPE((val)) 104 #else 105 typedef Elf64_Ehdr Elf_Ehdr; 106 typedef Elf64_Shdr Elf_Shdr; 107 typedef Elf64_Phdr Elf_Phdr; 108 typedef Elf64_Addr Elf_Addr; 109 typedef Elf64_Word Elf_Word; 110 typedef Elf64_Xword Elf_Xword; 111 typedef Elf64_Off Elf_Off; 112 typedef Elf64_Dyn Elf_Dyn; 113 typedef Elf64_Sym Elf_Sym; 114 typedef Elf64_Rel Elf_Rel; 115 typedef Elf64_Rela Elf_Rela; 116 #define ELF_R_SYM(val) ELF64_R_SYM((val)) 117 #define ELF_R_TYPE(val) ELF64_R_TYPE((val)) 118 #endif 119 120 /* 121 * Deal with platform differences in the file descriptor routines. 122 */ 123 #ifdef JIT_WIN32_PLATFORM 124 #define sys_open _open 125 #define sys_close _close 126 #define sys_read _read 127 #define sys_lseek _lseek 128 #else 129 #define sys_open open 130 #define sys_close close 131 #define sys_read read 132 #define sys_lseek lseek 133 #endif 134 #ifndef O_BINARY 135 #define O_BINARY 0 136 #endif 137 138 /* 139 * Define the relocation function type. 140 */ 141 typedef int (*jit_reloc_func)(jit_readelf_t readelf, void *address, 142 int type, jit_nuint value, int has_addend, 143 jit_nuint addend); 144 145 /* 146 * Get the relocation function for a particular machine type. 147 */ 148 static jit_reloc_func get_reloc(unsigned int machine); 149 150 /* 151 * Structure of an ELF binary once it has been loaded into memory. 152 */ 153 struct jit_readelf 154 { 155 jit_readelf_t next; 156 int resolved; 157 Elf_Ehdr ehdr; 158 unsigned char *phdrs; 159 unsigned char *shdrs; 160 char *regular_strings; 161 jit_nuint regular_strings_size; 162 char *dynamic_strings; 163 jit_nuint dynamic_strings_size; 164 Elf_Sym *symbol_table; 165 jit_nuint symbol_table_size; 166 Elf_Word *symbol_hash; 167 jit_nuint symbol_hash_size; 168 Elf_Word symbol_hash_buckets; 169 jit_reloc_func reloc_func; 170 void *map_address; 171 jit_nuint map_size; 172 int free_with_munmap; 173 }; 174 175 /* 176 * Flag that indicates that an auxillary section was malloc'ed, 177 * and isn't part of the main memory range at "map_address". 178 */ 179 #define JIT_ELF_IS_MALLOCED 0x01000000 180 181 /* 182 * Get the address of a particular phdr. 183 */ 184 static Elf_Phdr *get_phdr(jit_readelf_t readelf, unsigned int index) 185 { 186 if(index < readelf->ehdr.e_phnum && 187 readelf->ehdr.e_phentsize >= sizeof(Elf_Phdr)) 188 { 189 return (Elf_Phdr *) 190 (readelf->phdrs + 191 index * ((unsigned int)(readelf->ehdr.e_phentsize))); 192 } 193 else 194 { 195 return 0; 196 } 197 } 198 199 /* 200 * Get the address of a particular shdr. 201 */ 202 static Elf_Shdr *get_shdr(jit_readelf_t readelf, unsigned int index) 203 { 204 if(index < readelf->ehdr.e_shnum && 205 readelf->ehdr.e_shentsize >= sizeof(Elf_Shdr)) 206 { 207 return (Elf_Shdr *) 208 (readelf->shdrs + 209 index * ((unsigned int)(readelf->ehdr.e_shentsize))); 210 } 211 else 212 { 213 return 0; 214 } 215 } 216 217 /* 218 * Find a specific string in the regular string table. 219 */ 220 static const char *get_string(jit_readelf_t readelf, Elf_Word _index) 221 { 222 jit_nuint index = (jit_nuint)_index; 223 if(index < readelf->regular_strings_size) 224 { 225 return readelf->regular_strings + index; 226 } 227 else 228 { 229 return 0; 230 } 231 } 232 233 /* 234 * Find a specific string in the dynamic string table. 235 */ 236 static const char *get_dyn_string(jit_readelf_t readelf, Elf_Addr _index) 237 { 238 jit_nuint index = (jit_nuint)_index; 239 if(index < readelf->dynamic_strings_size) 240 { 241 return readelf->dynamic_strings + index; 242 } 243 else 244 { 245 return 0; 246 } 247 } 248 249 /* 250 * Map all of the program segments into memory and set up the bss section. 251 */ 252 static int map_program(jit_readelf_t readelf, int fd) 253 { 254 Elf_Off file_size; 255 Elf_Off memory_size; 256 Elf_Off start, end; 257 Elf_Phdr *phdr; 258 unsigned int index; 259 void *base_address; 260 unsigned char *segment_address; 261 262 /* Get the maximum file and memory sizes for the program. 263 The bytes between "file_size" and "memory_size" are bss */ 264 file_size = 0; 265 memory_size = 0; 266 for(index = 0; index < readelf->ehdr.e_phnum; ++index) 267 { 268 phdr = get_phdr(readelf, index); 269 if(!phdr) 270 { 271 continue; 272 } 273 start = phdr->p_offset; 274 end = start + phdr->p_filesz; 275 if(end > file_size) 276 { 277 file_size = end; 278 } 279 start = phdr->p_vaddr; 280 end = start + phdr->p_memsz; 281 if(end > memory_size) 282 { 283 memory_size = end; 284 } 285 } 286 if(memory_size < file_size) 287 { 288 memory_size = file_size; 289 } 290 291 /* Try to map the program segments into memory using mmap */ 292 base_address = 0; 293 #ifdef JIT_USE_MMAP_TO_LOAD 294 { 295 Elf_Off page_size; 296 Elf_Off rounded_file_size; 297 Elf_Off temp_start; 298 Elf_Off temp_end; 299 int zero_fd, prot; 300 301 /* Round the total memory and file sizes up to the CPU page size */ 302 page_size = (Elf_Off)(jit_vmem_page_size()); 303 end = memory_size; 304 if((end % page_size) != 0) 305 { 306 end += page_size - (end % page_size); 307 } 308 rounded_file_size = file_size; 309 if((rounded_file_size % page_size) != 0) 310 { 311 rounded_file_size += page_size - (rounded_file_size % page_size); 312 } 313 314 /* Allocate memory for the program from /dev/zero. Once we have 315 the memory, we will overlay the program segments on top */ 316 zero_fd = sys_open("/dev/zero", O_RDWR, 0); 317 if(zero_fd < -1) 318 { 319 goto failed_mmap; 320 } 321 base_address = mmap(0, (size_t)end, PROT_READ | PROT_WRITE, 322 MAP_ANON | MAP_PRIVATE, zero_fd, 0); 323 close(zero_fd); 324 if(base_address == (void *)(jit_nint)(-1)) 325 { 326 base_address = 0; 327 goto failed_mmap; 328 } 329 330 /* Lay down the program sections at their mapped locations */ 331 for(index = 0; index < readelf->ehdr.e_phnum; ++index) 332 { 333 phdr = get_phdr(readelf, index); 334 if(phdr) 335 { 336 temp_start = phdr->p_offset; 337 temp_end = temp_start + phdr->p_filesz; 338 temp_start -= (temp_start % page_size); 339 if((temp_end % page_size) != 0) 340 { 341 temp_end += page_size - (temp_end % page_size); 342 } 343 start = phdr->p_vaddr; 344 start -= (start % page_size); 345 if(temp_start < temp_end) 346 { 347 segment_address = 348 ((unsigned char *)base_address) + (jit_nuint)start; 349 prot = 0; 350 if((phdr->p_flags & PF_X) != 0) 351 { 352 prot |= PROT_EXEC; 353 } 354 if((phdr->p_flags & PF_W) != 0) 355 { 356 prot |= PROT_WRITE; 357 } 358 if((phdr->p_flags & PF_R) != 0) 359 { 360 prot |= PROT_READ; 361 } 362 if(mmap(segment_address, (size_t)(temp_end - temp_start), 363 prot, MAP_COPY | MAP_FILE | MAP_FIXED, fd, 364 (off_t)temp_start) == (void *)(jit_nint)(-1)) 365 { 366 munmap(base_address, (size_t)end); 367 base_address = 0; 368 goto failed_mmap; 369 } 370 } 371 } 372 } 373 374 /* We need to free the memory with munmap when the program is closed */ 375 readelf->free_with_munmap = 1; 376 377 /* Clear the left-over ".bss" bits that did not get cleared above */ 378 for(index = 0; index < readelf->ehdr.e_phnum; ++index) 379 { 380 phdr = get_phdr(readelf, index); 381 if(phdr && phdr->p_filesz < phdr->p_memsz) 382 { 383 temp_start = phdr->p_vaddr + phdr->p_filesz; 384 start = (temp_start % page_size); 385 temp_start -= start; 386 if(start != 0) 387 { 388 segment_address = 389 ((unsigned char *)base_address) + 390 (jit_nuint)temp_start; 391 mprotect(segment_address, (size_t)page_size, 392 PROT_READ | PROT_WRITE); 393 jit_memzero(segment_address + (jit_nuint)start, 394 (unsigned int)(page_size - start)); 395 prot = 0; 396 if((phdr->p_flags & PF_X) != 0) 397 { 398 prot |= PROT_EXEC; 399 } 400 if((phdr->p_flags & PF_W) != 0) 401 { 402 prot |= PROT_WRITE; 403 } 404 if((phdr->p_flags & PF_R) != 0) 405 { 406 prot |= PROT_READ; 407 } 408 mprotect(segment_address, (size_t)page_size, prot); 409 } 410 } 411 } 412 } 413 failed_mmap: 414 #endif /* JIT_USE_MMAP_TO_LOAD */ 415 416 /* If we haven't mapped the file yet, then fall back to "malloc" */ 417 if(!base_address) 418 { 419 base_address = _jit_malloc_exec(memory_size); 420 if(!base_address) 421 { 422 return 0; 423 } 424 for(index = 0; index < readelf->ehdr.e_phnum; ++index) 425 { 426 phdr = get_phdr(readelf, index); 427 if(phdr) 428 { 429 segment_address = ((unsigned char *)base_address) + 430 (jit_nuint)(phdr->p_vaddr); 431 if(lseek(fd, (off_t)(phdr->p_offset), 0) != 432 (off_t)(phdr->p_offset) || 433 read(fd, segment_address, (size_t)(phdr->p_filesz)) 434 != (int)(size_t)(phdr->p_filesz)) 435 { 436 _jit_free_exec(base_address, memory_size); 437 return 0; 438 } 439 } 440 } 441 } 442 443 /* Record the mapped address and size for later */ 444 readelf->map_address = base_address; 445 readelf->map_size = memory_size; 446 return 1; 447 } 448 449 /* 450 * Map an auxillary section into memory and return its base address. 451 * Returns NULL if we ran out of memory. 452 */ 453 static void *map_section(int fd, Elf_Off offset, Elf_Xword file_size, 454 Elf_Xword memory_size, Elf_Word flags) 455 { 456 void *address; 457 if(memory_size < file_size) 458 { 459 memory_size = file_size; 460 } 461 address = _jit_malloc_exec(memory_size); 462 if(!address) 463 { 464 return 0; 465 } 466 if(lseek(fd, (off_t)offset, 0) != (off_t)offset) 467 { 468 _jit_free_exec(address, memory_size); 469 return 0; 470 } 471 if(read(fd, address, (size_t)file_size) != (int)(size_t)file_size) 472 { 473 _jit_free_exec(address, memory_size); 474 return 0; 475 } 476 return address; 477 } 478 479 /* 480 * Unmap an auxillary section from memory. 481 */ 482 static void unmap_section(void *address, Elf_Xword file_size, 483 Elf_Xword memory_size, Elf_Word flags) 484 { 485 if(memory_size < file_size) 486 { 487 memory_size = file_size; 488 } 489 if((flags & JIT_ELF_IS_MALLOCED) != 0) 490 { 491 _jit_free_exec(address, (unsigned int)memory_size); 492 } 493 } 494 495 /* 496 * Iterate over the contents of the ".dynamic" section. 497 */ 498 typedef struct 499 { 500 Elf_Dyn *dyn; 501 jit_nuint size; 502 503 } jit_dynamic_iter_t; 504 static void dynamic_iter_init(jit_dynamic_iter_t *iter, jit_readelf_t readelf) 505 { 506 iter->dyn = jit_readelf_get_section_by_type 507 (readelf, SHT_DYNAMIC, &(iter->size)); 508 } 509 static int dynamic_iter_next 510 (jit_dynamic_iter_t *iter, jit_uint *type, Elf_Addr *value) 511 { 512 if(iter->size >= sizeof(Elf_Dyn)) 513 { 514 *type = (jit_uint)(iter->dyn->d_tag); 515 *value = iter->dyn->d_un.d_ptr; 516 if(*type == DT_NULL) 517 { 518 /* Explicitly-marked end of the list */ 519 return 0; 520 } 521 ++(iter->dyn); 522 iter->size -= sizeof(Elf_Dyn); 523 return 1; 524 } 525 else 526 { 527 /* Implicitly-marked end of the list */ 528 return 0; 529 } 530 } 531 static int dynamic_for_type 532 (jit_readelf_t readelf, jit_uint type, Elf_Addr *value) 533 { 534 Elf_Addr temp_value; 535 jit_dynamic_iter_t iter; 536 jit_uint iter_type; 537 dynamic_iter_init(&iter, readelf); 538 while(dynamic_iter_next(&iter, &iter_type, &temp_value)) 539 { 540 if(iter_type == type) 541 { 542 if(value) 543 { 544 *value = temp_value; 545 } 546 return 1; 547 } 548 } 549 return 0; 550 } 551 552 /* 553 * Load interesting values from the ".dynamic" section, for quicker lookups. 554 */ 555 static void load_dynamic_section(jit_readelf_t readelf, int flags) 556 { 557 Elf_Addr value; 558 Elf_Addr value2; 559 jit_dynamic_iter_t iter; 560 jit_uint type; 561 jit_nuint size; 562 563 /* Get the position and size of the dynamic string table */ 564 if(dynamic_for_type(readelf, DT_STRTAB, &value) && 565 dynamic_for_type(readelf, DT_STRSZ, &value2)) 566 { 567 readelf->dynamic_strings = jit_readelf_map_vaddr 568 (readelf, (jit_nuint)value); 569 if(readelf->dynamic_strings) 570 { 571 readelf->dynamic_strings_size = (jit_nuint)value2; 572 } 573 } 574 575 /* Get the position and size of the dynamic symbol table */ 576 readelf->symbol_table = jit_readelf_get_section_by_type 577 (readelf, SHT_DYNSYM, &size); 578 if(readelf->symbol_table) 579 { 580 if(dynamic_for_type(readelf, DT_SYMENT, &value) && 581 value == sizeof(Elf_Sym)) 582 { 583 readelf->symbol_table_size = size / sizeof(Elf_Sym); 584 readelf->symbol_hash = jit_readelf_get_section_by_type 585 (readelf, SHT_HASH, &size); 586 if(readelf->symbol_hash) 587 { 588 readelf->symbol_hash_size = size / sizeof(Elf_Word); 589 if(readelf->symbol_hash_size >= 2) 590 { 591 readelf->symbol_hash_buckets = readelf->symbol_hash[0]; 592 } 593 } 594 } 595 else 596 { 597 readelf->symbol_table = 0; 598 } 599 } 600 601 /* Bail out if we don't need to print debugging information */ 602 if((flags & JIT_READELF_FLAG_DEBUG) == 0) 603 { 604 return; 605 } 606 607 /* Iterate through the ".dynamic" section, dumping all that we find */ 608 dynamic_iter_init(&iter, readelf); 609 while(dynamic_iter_next(&iter, &type, &value)) 610 { 611 switch(type) 612 { 613 case DT_NEEDED: 614 { 615 printf("needed library: %s\n", get_dyn_string(readelf, value)); 616 } 617 break; 618 619 case DT_PLTRELSZ: 620 { 621 printf("total size of PLT relocs: %ld\n", (long)value); 622 } 623 break; 624 625 case DT_PLTGOT: 626 { 627 printf("address of PLTGOT table: 0x%lx\n", (long)value); 628 } 629 break; 630 631 case DT_HASH: 632 { 633 printf("address of symbol hash table: 0x%lx\n", (long)value); 634 } 635 break; 636 637 case DT_STRTAB: 638 { 639 printf("address of string table: 0x%lx\n", (long)value); 640 } 641 break; 642 643 case DT_SYMTAB: 644 { 645 printf("address of symbol table: 0x%lx\n", (long)value); 646 } 647 break; 648 649 case DT_STRSZ: 650 { 651 printf("size of string table: %ld\n", (long)value); 652 } 653 break; 654 655 case DT_SYMENT: 656 { 657 printf("size of one symbol table entry: %ld\n", (long)value); 658 } 659 break; 660 661 case DT_INIT: 662 { 663 printf("address of init function: 0x%lx\n", (long)value); 664 } 665 break; 666 667 case DT_FINI: 668 { 669 printf("address of fini function: 0x%lx\n", (long)value); 670 } 671 break; 672 673 case DT_SONAME: 674 { 675 printf("library name: %s\n", get_dyn_string(readelf, value)); 676 } 677 break; 678 679 case DT_REL: 680 { 681 printf("address of Rel relocs: 0x%lx\n", (long)value); 682 } 683 break; 684 685 case DT_RELSZ: 686 { 687 printf("total size of Rel relocs: %ld\n", (long)value); 688 } 689 break; 690 691 case DT_RELENT: 692 { 693 printf("size of one Rel reloc: %ld\n", (long)value); 694 } 695 break; 696 697 case DT_RELA: 698 { 699 printf("address of Rela relocs: 0x%lx\n", (long)value); 700 } 701 break; 702 703 case DT_RELASZ: 704 { 705 printf("total size of Rela relocs: %ld\n", (long)value); 706 } 707 break; 708 709 case DT_RELAENT: 710 { 711 printf("size of one Rela reloc: %ld\n", (long)value); 712 } 713 break; 714 715 case DT_PLTREL: 716 { 717 printf("type of PLT relocs: %ld\n", (long)value); 718 } 719 break; 720 721 case DT_JMPREL: 722 { 723 printf("address of PLT relocs: 0x%lx\n", (long)value); 724 } 725 break; 726 727 default: 728 { 729 printf("dynamic info of type 0x%x: 0x%lx\n", 730 (int)type, (long)value); 731 } 732 break; 733 } 734 } 735 736 /* Iterate through the symbol table, dumping all of the entries */ 737 for(size = 0; size < readelf->symbol_table_size; ++size) 738 { 739 printf("%08lX %02X%02X %2d %s\n", 740 (long)(readelf->symbol_table[size].st_value), 741 (int)(readelf->symbol_table[size].st_info), 742 (int)(readelf->symbol_table[size].st_other), 743 (int)(readelf->symbol_table[size].st_shndx), 744 get_dyn_string(readelf, readelf->symbol_table[size].st_name)); 745 } 746 printf("number of symbols: %ld\n", (long)(readelf->symbol_table_size)); 747 printf("number of symbol hash entries: %ld\n", 748 (long)(readelf->symbol_hash_size)); 749 } 750 751 /*@ 752 * @deftypefun int jit_readelf_open (jit_readelf_t *@var{readelf}, const char *@var{filename}, int @var{force}) 753 * Open the specified @var{filename} and load the ELF binary that is 754 * contained within it. Returns one of the following result codes: 755 * 756 * @table @code 757 * @vindex JIT_READELF_OK 758 * @item JIT_READELF_OK 759 * The ELF binary was opened successfully. 760 * 761 * @vindex JIT_READELF_CANNOT_OPEN 762 * @item JIT_READELF_CANNOT_OPEN 763 * Could not open the file at the filesystem level (reason in @code{errno}). 764 * 765 * @vindex JIT_READELF_NOT_ELF 766 * @item JIT_READELF_NOT_ELF 767 * The file was opened, but it is not an ELF binary. 768 * 769 * @vindex JIT_READELF_WRONG_ARCH 770 * @item JIT_READELF_WRONG_ARCH 771 * The file is an ELF binary, but it does not pertain to the architecture 772 * of this machine. 773 * 774 * @vindex JIT_READELF_BAD_FORMAT 775 * @item JIT_READELF_BAD_FORMAT 776 * The file is an ELF binary, but the format is corrupted in some fashion. 777 * 778 * @vindex JIT_READELF_MEMORY 779 * @item JIT_READELF_MEMORY 780 * There is insufficient memory to open the ELF binary. 781 * @end table 782 * 783 * The following flags may be supplied to alter the manner in which 784 * the ELF binary is loaded: 785 * 786 * @table @code 787 * @vindex JIT_READELF_FLAG_FORCE 788 * @item JIT_READELF_FLAG_FORCE 789 * Force @code{jit_readelf_open} to open the ELF binary, even if 790 * the architecture does not match this machine. Useful for debugging. 791 * 792 * @vindex JIT_READELF_FLAG_DEBUG 793 * @item JIT_READELF_FLAG_DEBUG 794 * Print additional debug information to stdout. 795 * @end table 796 * @end deftypefun 797 @*/ 798 int jit_readelf_open(jit_readelf_t *_readelf, const char *filename, int flags) 799 { 800 int fd; 801 Elf_Ehdr ehdr; 802 Elf_Phdr *phdr; 803 Elf_Shdr *shdr; 804 jit_elf_info_t elf_info; 805 jit_readelf_t readelf; 806 unsigned int phdr_size; 807 unsigned int shdr_size; 808 unsigned int index; 809 void *address; 810 union 811 { 812 jit_ushort value; 813 unsigned char bytes[2]; 814 815 } un; 816 817 /* Get the machine and ABI values that we expect in the header */ 818 _jit_gen_get_elf_info(&elf_info); 819 820 /* Open the file and read the ELF magic number information */ 821 if((fd = sys_open(filename, O_RDONLY | O_BINARY, 0)) < 0) 822 { 823 return JIT_READELF_CANNOT_OPEN; 824 } 825 if(sys_read(fd, ehdr.e_ident, EI_NIDENT) != EI_NIDENT) 826 { 827 sys_close(fd); 828 return JIT_READELF_NOT_ELF; 829 } 830 831 /* Determine if the magic number matches what we expect to see */ 832 if(ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 || 833 ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3) 834 { 835 sys_close(fd); 836 return JIT_READELF_NOT_ELF; 837 } 838 #ifdef JIT_NATIVE_INT32 839 if(ehdr.e_ident[EI_CLASS] != ELFCLASS32) 840 { 841 sys_close(fd); 842 return JIT_READELF_WRONG_ARCH; 843 } 844 #else 845 if(ehdr.e_ident[EI_CLASS] != ELFCLASS64) 846 { 847 sys_close(fd); 848 return JIT_READELF_WRONG_ARCH; 849 } 850 #endif 851 un.value = 0x0102; 852 if(un.bytes[0] == 0x01) 853 { 854 /* Looking for a big-endian binary */ 855 if(ehdr.e_ident[EI_DATA] != ELFDATA2MSB) 856 { 857 sys_close(fd); 858 return JIT_READELF_WRONG_ARCH; 859 } 860 } 861 else 862 { 863 /* Looking for a little-endian binary */ 864 if(ehdr.e_ident[EI_DATA] != ELFDATA2LSB) 865 { 866 sys_close(fd); 867 return JIT_READELF_WRONG_ARCH; 868 } 869 } 870 if(ehdr.e_ident[EI_VERSION] != EV_CURRENT) 871 { 872 sys_close(fd); 873 return JIT_READELF_BAD_FORMAT; 874 } 875 876 /* Read the rest of the ELF header and validate it */ 877 if(sys_read(fd, &(ehdr.e_type), sizeof(Elf_Ehdr) - EI_NIDENT) 878 != (sizeof(Elf_Ehdr) - EI_NIDENT)) 879 { 880 sys_close(fd); 881 return JIT_READELF_BAD_FORMAT; 882 } 883 if(ehdr.e_type != ET_DYN) 884 { 885 /* We can only load files that are marked as dynamic shared objects */ 886 sys_close(fd); 887 return JIT_READELF_WRONG_ARCH; 888 } 889 if((flags & JIT_READELF_FLAG_FORCE) == 0) 890 { 891 if(ehdr.e_machine != elf_info.machine || 892 ehdr.e_ident[EI_OSABI] != elf_info.abi || 893 ehdr.e_ident[EI_ABIVERSION] != elf_info.abi_version) 894 { 895 /* The ELF binary does not pertain to this machine or ABI type */ 896 sys_close(fd); 897 return JIT_READELF_WRONG_ARCH; 898 } 899 } 900 if(ehdr.e_version != EV_CURRENT) 901 { 902 sys_close(fd); 903 return JIT_READELF_BAD_FORMAT; 904 } 905 if(ehdr.e_ehsize < sizeof(ehdr)) 906 { 907 sys_close(fd); 908 return JIT_READELF_BAD_FORMAT; 909 } 910 911 /* Allocate space for the ELF reader object */ 912 if((readelf = jit_cnew(struct jit_readelf)) == 0) 913 { 914 sys_close(fd); 915 return JIT_READELF_MEMORY; 916 } 917 readelf->ehdr = ehdr; 918 phdr_size = ((unsigned int)(ehdr.e_phnum)) * 919 ((unsigned int)(ehdr.e_phentsize)); 920 shdr_size = ((unsigned int)(ehdr.e_shnum)) * 921 ((unsigned int)(ehdr.e_shentsize)); 922 if(phdr_size > 0) 923 { 924 readelf->phdrs = (unsigned char *)jit_malloc(phdr_size); 925 if(!(readelf->phdrs)) 926 { 927 jit_free(readelf); 928 sys_close(fd); 929 return JIT_READELF_MEMORY; 930 } 931 } 932 if(shdr_size > 0) 933 { 934 readelf->shdrs = (unsigned char *)jit_malloc(shdr_size); 935 if(!(readelf->shdrs)) 936 { 937 jit_free(readelf->phdrs); 938 jit_free(readelf); 939 sys_close(fd); 940 return JIT_READELF_MEMORY; 941 } 942 } 943 944 /* Seek to the program and section header tables and read them */ 945 if(phdr_size > 0) 946 { 947 if(lseek(fd, (off_t)(ehdr.e_phoff), 0) != (off_t)(ehdr.e_phoff) || 948 read(fd, readelf->phdrs, phdr_size) != (int)phdr_size) 949 { 950 jit_free(readelf->shdrs); 951 jit_free(readelf->phdrs); 952 jit_free(readelf); 953 sys_close(fd); 954 return JIT_READELF_BAD_FORMAT; 955 } 956 } 957 if(shdr_size > 0) 958 { 959 if(lseek(fd, (off_t)(ehdr.e_shoff), 0) != (off_t)(ehdr.e_shoff) || 960 read(fd, readelf->shdrs, shdr_size) != (int)shdr_size) 961 { 962 jit_free(readelf->shdrs); 963 jit_free(readelf->phdrs); 964 jit_free(readelf); 965 sys_close(fd); 966 return JIT_READELF_BAD_FORMAT; 967 } 968 } 969 970 /* Load the program segments */ 971 if(!map_program(readelf, fd)) 972 { 973 jit_readelf_close(readelf); 974 sys_close(fd); 975 return JIT_READELF_MEMORY; 976 } 977 978 /* Load the auxillary sections */ 979 if(shdr_size > 0) 980 { 981 for(index = 0; index < ehdr.e_shnum; ++index) 982 { 983 shdr = get_shdr(readelf, index); 984 if(!shdr) 985 { 986 continue; 987 } 988 if((shdr->sh_flags & SHF_ALLOC) != 0 || shdr->sh_addr != 0) 989 { 990 /* This may be mapped inside one of the program segments. 991 If so, we don't want to load a second copy of it */ 992 address = jit_readelf_map_vaddr(readelf, shdr->sh_addr); 993 if(address) 994 { 995 continue; 996 } 997 } 998 if(shdr->sh_size == 0) 999 { 1000 /* Ignore zero-sized segments */ 1001 continue; 1002 } 1003 address = map_section 1004 (fd, shdr->sh_offset, shdr->sh_size, shdr->sh_size, 1005 ((shdr->sh_flags & SHF_WRITE) != 0 ? (PF_W | PF_R) : PF_R)); 1006 if(!address) 1007 { 1008 jit_readelf_close(readelf); 1009 sys_close(fd); 1010 return JIT_READELF_MEMORY; 1011 } 1012 shdr->sh_offset = (Elf_Off)(jit_nuint)address; 1013 shdr->sh_flags |= JIT_ELF_IS_MALLOCED; 1014 } 1015 } 1016 1017 /* Close the file descriptor because we don't need it any more */ 1018 sys_close(fd); 1019 1020 /* Find the regular string table */ 1021 shdr = get_shdr(readelf, ehdr.e_shstrndx); 1022 if(shdr) 1023 { 1024 if((shdr->sh_flags & JIT_ELF_IS_MALLOCED) != 0) 1025 { 1026 readelf->regular_strings = (char *)(jit_nuint)(shdr->sh_offset); 1027 } 1028 else 1029 { 1030 readelf->regular_strings = 1031 (char *)jit_readelf_map_vaddr(readelf, shdr->sh_addr); 1032 } 1033 if(readelf->regular_strings) 1034 { 1035 readelf->regular_strings_size = (jit_nuint)(shdr->sh_size); 1036 } 1037 } 1038 1039 /* Dump debug information about the program segments and sections */ 1040 if((flags & JIT_READELF_FLAG_DEBUG) != 0) 1041 { 1042 printf("header: machine=%d, abi=%d, abi_version=%d\n", 1043 (int)(ehdr.e_machine), (int)(ehdr.e_ident[EI_OSABI]), 1044 (int)(ehdr.e_ident[EI_ABIVERSION])); 1045 for(index = 0; index < ehdr.e_phnum; ++index) 1046 { 1047 phdr = get_phdr(readelf, index); 1048 if(phdr) 1049 { 1050 printf("program segment: type=%d, flags=0x%x, " 1051 "vaddr=0x%lx, file_size=%ld, memory_size=%ld\n", 1052 (int)(phdr->p_type), 1053 (int)(phdr->p_flags & ~JIT_ELF_IS_MALLOCED), 1054 (long)(phdr->p_vaddr), 1055 (long)(phdr->p_filesz), 1056 (long)(phdr->p_memsz)); 1057 } 1058 } 1059 for(index = 0; index < ehdr.e_shnum; ++index) 1060 { 1061 shdr = get_shdr(readelf, index); 1062 if(shdr) 1063 { 1064 printf("section %2d: name=\"%s\", type=%d, flags=0x%x, " 1065 "vaddr=0x%lx, size=%ld\n", 1066 index, 1067 get_string(readelf, shdr->sh_name), 1068 (int)(shdr->sh_type), 1069 (int)(shdr->sh_flags & ~JIT_ELF_IS_MALLOCED), 1070 (long)(shdr->sh_addr), 1071 (long)(shdr->sh_size)); 1072 } 1073 } 1074 } 1075 1076 /* Get the relocation function for this machine type */ 1077 readelf->reloc_func = get_reloc((unsigned int)(ehdr.e_machine)); 1078 1079 /* Load useful values from the dynamic section that we want to cache */ 1080 load_dynamic_section(readelf, flags); 1081 1082 /* The ELF binary is loaded and ready to go */ 1083 *_readelf = readelf; 1084 return JIT_READELF_OK; 1085 } 1086 1087 /*@ 1088 * @deftypefun void jit_readelf_close (jit_readelf_t @var{readelf}) 1089 * Close an ELF reader, reclaiming all of the memory that was used. 1090 * @end deftypefun 1091 @*/ 1092 void jit_readelf_close(jit_readelf_t readelf) 1093 { 1094 unsigned int index; 1095 Elf_Shdr *shdr; 1096 if(!readelf) 1097 { 1098 return; 1099 } 1100 #ifdef JIT_USE_MMAP_TO_LOAD 1101 if(readelf->free_with_munmap) 1102 { 1103 munmap(readelf->map_address, (size_t)(readelf->map_size)); 1104 } 1105 else 1106 #endif 1107 { 1108 _jit_free_exec(readelf->map_address, readelf->map_size); 1109 } 1110 for(index = 0; index < readelf->ehdr.e_shnum; ++index) 1111 { 1112 shdr = get_shdr(readelf, index); 1113 if(shdr && (shdr->sh_flags & JIT_ELF_IS_MALLOCED) != 0) 1114 { 1115 unmap_section 1116 ((void *)(jit_nuint)(shdr->sh_offset), 1117 shdr->sh_size, shdr->sh_size, shdr->sh_flags); 1118 } 1119 } 1120 jit_free(readelf->phdrs); 1121 jit_free(readelf->shdrs); 1122 jit_free(readelf); 1123 } 1124 1125 /*@ 1126 * @deftypefun {const char *} jit_readelf_get_name (jit_readelf_t @var{readelf}) 1127 * Get the library name that is embedded inside an ELF binary. 1128 * ELF binaries can refer to each other using this name. 1129 * @end deftypefun 1130 @*/ 1131 const char *jit_readelf_get_name(jit_readelf_t readelf) 1132 { 1133 Elf_Addr value; 1134 if(dynamic_for_type(readelf, DT_SONAME, &value)) 1135 { 1136 return get_dyn_string(readelf, value); 1137 } 1138 else 1139 { 1140 return 0; 1141 } 1142 } 1143 1144 /*@ 1145 * @deftypefun void *jit_readelf_get_symbol (jit_readelf_t @var{readelf}, const char *@var{name}) 1146 * Look up the symbol called @var{name} in the ELF binary represented 1147 * by @var{readelf}. Returns NULL if the symbol is not present. 1148 * 1149 * External references from this ELF binary to others are not resolved 1150 * until the ELF binary is loaded into a JIT context using 1151 * @code{jit_readelf_add_to_context} and @code{jit_readelf_resolve_all}. 1152 * You should not call functions within this ELF binary until after you 1153 * have fully resolved it. 1154 * @end deftypefun 1155 @*/ 1156 void *jit_readelf_get_symbol(jit_readelf_t readelf, const char *name) 1157 { 1158 unsigned long hash; 1159 unsigned long temp; 1160 unsigned int index; 1161 jit_nuint num_symbols; 1162 Elf_Sym *symbol; 1163 const char *symbol_name; 1164 1165 /* Bail out if we have insufficient information to resolve the name */ 1166 if(!readelf || !name || !(readelf->symbol_table)) 1167 { 1168 return 0; 1169 } 1170 1171 /* Hash the name to get the starting index in the symbol hash */ 1172 hash = 0; 1173 index = 0; 1174 while(name[index] != 0) 1175 { 1176 hash = (hash << 4) + (unsigned long)(name[index] & 0xFF); 1177 temp = (hash & 0xF0000000); 1178 if(temp != 0) 1179 { 1180 hash ^= temp | (temp >> 24); 1181 } 1182 ++index; 1183 } 1184 1185 /* Look in the hash table for the name */ 1186 if(readelf->symbol_hash_buckets != 0) 1187 { 1188 hash %= (unsigned long)(readelf->symbol_hash_buckets); 1189 temp = (unsigned long)(readelf->symbol_hash[hash + 2]); 1190 while(temp != 0 && temp < readelf->symbol_table_size) 1191 { 1192 symbol = &(readelf->symbol_table[temp]); 1193 symbol_name = get_dyn_string(readelf, symbol->st_name); 1194 if(symbol_name && !jit_strcmp(symbol_name, name)) 1195 { 1196 /* Ignore symbols in section 0, as they are external */ 1197 if(symbol->st_shndx) 1198 { 1199 return jit_readelf_map_vaddr 1200 (readelf, (jit_nuint)(symbol->st_value)); 1201 } 1202 break; 1203 } 1204 temp = (unsigned long)(readelf->symbol_hash 1205 [temp + readelf->symbol_hash_buckets + 2]); 1206 } 1207 return 0; 1208 } 1209 1210 /* There is no hash table, so search for the symbol the hard way */ 1211 symbol = readelf->symbol_table; 1212 for(num_symbols = readelf->symbol_table_size; 1213 num_symbols > 0; --num_symbols) 1214 { 1215 symbol_name = get_dyn_string(readelf, symbol->st_name); 1216 if(symbol_name && !jit_strcmp(symbol_name, name)) 1217 { 1218 /* Ignore symbols in section 0, as they are external */ 1219 if(symbol->st_shndx) 1220 { 1221 return jit_readelf_map_vaddr 1222 (readelf, (jit_nuint)(symbol->st_value)); 1223 } 1224 } 1225 ++symbol; 1226 } 1227 return 0; 1228 } 1229 1230 /*@ 1231 * @deftypefun {void *} jit_readelf_get_section (jit_readelf_t @var{readelf}, const char *@var{name}, jit_nuint *@var{size}) 1232 * Get the address and size of a particular section from an ELF binary. 1233 * Returns NULL if the section is not present in the ELF binary. 1234 * 1235 * The virtual machine may have stored auxillary information 1236 * in the section when the binary was first generated. This function 1237 * allows the virtual machine to retrieve its auxillary information. 1238 * 1239 * Examples of such information may be version numbers, timestamps, 1240 * checksums, and other identifying information for the bytecode that 1241 * was previously compiled by the virtual machine. The virtual machine 1242 * can use this to determine if the ELF binary is up to date and 1243 * relevant to its needs. 1244 * 1245 * It is recommended that virtual machines prefix their special sections 1246 * with a unique string (e.g. @code{.foovm}) to prevent clashes with 1247 * system-defined section names. The prefix @code{.libjit} is reserved 1248 * for use by @code{libjit} itself. 1249 * @end deftypefun 1250 @*/ 1251 void *jit_readelf_get_section 1252 (jit_readelf_t readelf, const char *name, jit_nuint *size) 1253 { 1254 unsigned int index; 1255 Elf_Shdr *shdr; 1256 const char *temp_name; 1257 if(!readelf || !name) 1258 { 1259 return 0; 1260 } 1261 for(index = 0; index < readelf->ehdr.e_shnum; ++index) 1262 { 1263 shdr = get_shdr(readelf, index); 1264 if(shdr) 1265 { 1266 temp_name = get_string(readelf, shdr->sh_name); 1267 if(temp_name && !jit_strcmp(name, temp_name)) 1268 { 1269 if(size) 1270 { 1271 *size = (jit_nuint)(shdr->sh_size); 1272 } 1273 if((shdr->sh_flags & JIT_ELF_IS_MALLOCED) != 0) 1274 { 1275 return (void *)(jit_nuint)(shdr->sh_offset); 1276 } 1277 else 1278 { 1279 return jit_readelf_map_vaddr 1280 (readelf, (jit_nuint)(shdr->sh_addr)); 1281 } 1282 } 1283 } 1284 } 1285 return 0; 1286 } 1287 1288 /*@ 1289 * @deftypefun {void *} jit_readelf_get_section_by_type (jit_readelf_t @var{readelf}, jit_int @var{type}, jit_nuint *@var{size}) 1290 * Get a particular section using its raw ELF section type (i.e. one of 1291 * the @code{SHT_*} constants in @code{jit-elf-defs.h}). This is mostly 1292 * for internal use, but some virtual machines may find it useful for 1293 * debugging purposes. 1294 * @end deftypefun 1295 @*/ 1296 void *jit_readelf_get_section_by_type 1297 (jit_readelf_t readelf, jit_int type, jit_nuint *size) 1298 { 1299 unsigned int index; 1300 Elf_Shdr *shdr; 1301 if(!readelf) 1302 { 1303 return 0; 1304 } 1305 for(index = 0; index < readelf->ehdr.e_shnum; ++index) 1306 { 1307 shdr = get_shdr(readelf, index); 1308 if(shdr && type == (jit_int)(shdr->sh_type)) 1309 { 1310 if(size) 1311 { 1312 *size = (jit_nuint)(shdr->sh_size); 1313 } 1314 if((shdr->sh_flags & JIT_ELF_IS_MALLOCED) != 0) 1315 { 1316 return (void *)(jit_nuint)(shdr->sh_offset); 1317 } 1318 else 1319 { 1320 return jit_readelf_map_vaddr 1321 (readelf, (jit_nuint)(shdr->sh_addr)); 1322 } 1323 } 1324 } 1325 return 0; 1326 } 1327 1328 /*@ 1329 * @deftypefun {void *} jit_readelf_map_vaddr (jit_readelf_t @var{readelf}, jit_nuint @var{vaddr}) 1330 * Map a virtual address to an actual address in a loaded ELF binary. 1331 * Returns NULL if @var{vaddr} could not be mapped. 1332 * @end deftypefun 1333 @*/ 1334 void *jit_readelf_map_vaddr(jit_readelf_t readelf, jit_nuint vaddr) 1335 { 1336 unsigned int index; 1337 Elf_Phdr *phdr; 1338 if(!readelf) 1339 { 1340 return 0; 1341 } 1342 for(index = 0; index < readelf->ehdr.e_phnum; ++index) 1343 { 1344 phdr = get_phdr(readelf, index); 1345 if(phdr && vaddr >= phdr->p_vaddr && 1346 vaddr < (phdr->p_vaddr + phdr->p_memsz)) 1347 { 1348 return (void *)(((unsigned char *)(readelf->map_address)) + vaddr); 1349 } 1350 } 1351 return 0; 1352 } 1353 1354 /*@ 1355 * @deftypefun {unsigned int} jit_readelf_num_needed (jit_readelf_t @var{readelf}) 1356 * Get the number of dependent libraries that are needed by this 1357 * ELF binary. The virtual machine will normally need to arrange 1358 * to load these libraries with @code{jit_readelf_open} as well, 1359 * so that all of the necessary symbols can be resolved. 1360 * @end deftypefun 1361 @*/ 1362 unsigned int jit_readelf_num_needed(jit_readelf_t readelf) 1363 { 1364 jit_dynamic_iter_t iter; 1365 unsigned int count = 0; 1366 jit_uint type; 1367 Elf_Addr value; 1368 dynamic_iter_init(&iter, readelf); 1369 while(dynamic_iter_next(&iter, &type, &value)) 1370 { 1371 if(type == DT_NEEDED) 1372 { 1373 ++count; 1374 } 1375 } 1376 return count; 1377 } 1378 1379 /*@ 1380 * @deftypefun {const char *} jit_readelf_get_needed (jit_readelf_t @var{readelf}, unsigned int @var{index}) 1381 * Get the name of the dependent library at position @var{index} within 1382 * the needed libraries list of this ELF binary. Returns NULL if 1383 * the @var{index} is invalid. 1384 * @end deftypefun 1385 @*/ 1386 const char *jit_readelf_get_needed(jit_readelf_t readelf, unsigned int index) 1387 { 1388 jit_dynamic_iter_t iter; 1389 jit_uint type; 1390 Elf_Addr value; 1391 dynamic_iter_init(&iter, readelf); 1392 while(dynamic_iter_next(&iter, &type, &value)) 1393 { 1394 if(type == DT_NEEDED) 1395 { 1396 if(index == 0) 1397 { 1398 return get_dyn_string(readelf, value); 1399 } 1400 --index; 1401 } 1402 } 1403 return 0; 1404 } 1405 1406 /*@ 1407 * @deftypefun void jit_readelf_add_to_context (jit_readelf_t @var{readelf}, jit_context_t @var{context}) 1408 * Add this ELF binary to a JIT context, so that its contents can be used 1409 * when executing JIT-managed code. The binary will be closed automatically 1410 * if the context is destroyed and @code{jit_readelf_close} has not been 1411 * called explicitly yet. 1412 * 1413 * The functions in the ELF binary cannot be used until you also call 1414 * @code{jit_readelf_resolve_all} to resolve cross-library symbol references. 1415 * The reason why adding and resolution are separate steps is to allow for 1416 * resolving circular dependencies between ELF binaries. 1417 * @end deftypefun 1418 @*/ 1419 void jit_readelf_add_to_context(jit_readelf_t readelf, jit_context_t context) 1420 { 1421 if(!readelf || !context) 1422 { 1423 return; 1424 } 1425 1426 _jit_memory_lock(context); 1427 1428 readelf->next = context->elf_binaries; 1429 context->elf_binaries = readelf; 1430 1431 _jit_memory_unlock(context); 1432 } 1433 1434 /* 1435 * Import the internal symbol table from "jit-symbol.c". 1436 */ 1437 typedef struct 1438 { 1439 const char *name; 1440 void *value; 1441 1442 } jit_internalsym; 1443 extern jit_internalsym const _jit_internal_symbols[]; 1444 extern int const _jit_num_internal_symbols; 1445 1446 /* 1447 * Resolve a symbol to an address. 1448 */ 1449 static void *resolve_symbol 1450 (jit_context_t context, jit_readelf_t readelf, 1451 int print_failures, const char *name, jit_nuint symbol) 1452 { 1453 Elf_Sym *sym; 1454 void *value; 1455 const char *symbol_name; 1456 jit_readelf_t library; 1457 int index, left, right, cmp; 1458 1459 /* Find the actual symbol details */ 1460 if(symbol >= readelf->symbol_table_size) 1461 { 1462 if(print_failures) 1463 { 1464 printf("%s: invalid symbol table index %lu\n", 1465 name, (unsigned long)symbol); 1466 } 1467 return 0; 1468 } 1469 sym = &(readelf->symbol_table[symbol]); 1470 1471 /* Does the symbol have a locally-defined value? */ 1472 if(sym->st_value) 1473 { 1474 value = jit_readelf_map_vaddr(readelf, (jit_nuint)(sym->st_value)); 1475 if(!value) 1476 { 1477 if(print_failures) 1478 { 1479 printf("%s: could not map virtual address 0x%lx\n", 1480 name, (long)(sym->st_value)); 1481 } 1482 } 1483 return value; 1484 } 1485 1486 /* Get the symbol's name, so that we can look it up in other libraries */ 1487 symbol_name = get_dyn_string(readelf, sym->st_name); 1488 if(!symbol_name) 1489 { 1490 if(print_failures) 1491 { 1492 printf("%s: symbol table index %lu does not have a valid name\n", 1493 name, (unsigned long)symbol); 1494 } 1495 return 0; 1496 } 1497 1498 /* Look for "before" symbols that are registered with the context */ 1499 for(index = 0; index < context->num_registered_symbols; ++index) 1500 { 1501 if(!jit_strcmp(symbol_name, context->registered_symbols[index]->name) && 1502 !(context->registered_symbols[index]->after)) 1503 { 1504 return context->registered_symbols[index]->value; 1505 } 1506 } 1507 1508 /* Search all loaded ELF libraries for the name */ 1509 library = context->elf_binaries; 1510 while(library != 0) 1511 { 1512 value = jit_readelf_get_symbol(library, symbol_name); 1513 if(value) 1514 { 1515 return value; 1516 } 1517 library = library->next; 1518 } 1519 1520 /* Look for libjit internal symbols (i.e. intrinsics) */ 1521 left = 0; 1522 right = _jit_num_internal_symbols - 1; 1523 while(left <= right) 1524 { 1525 index = (left + right) / 2; 1526 cmp = jit_strcmp(symbol_name, _jit_internal_symbols[index].name); 1527 if(cmp == 0) 1528 { 1529 return _jit_internal_symbols[index].value; 1530 } 1531 else if(cmp < 0) 1532 { 1533 right = index - 1; 1534 } 1535 else 1536 { 1537 left = index + 1; 1538 } 1539 } 1540 1541 /* Look for "after" symbols that are registered with the context */ 1542 for(index = 0; index < context->num_registered_symbols; ++index) 1543 { 1544 if(!jit_strcmp(symbol_name, context->registered_symbols[index]->name) && 1545 context->registered_symbols[index]->after) 1546 { 1547 return context->registered_symbols[index]->value; 1548 } 1549 } 1550 1551 /* If we get here, then we could not resolve the symbol */ 1552 printf("%s: could not resolve `%s'\n", name, symbol_name); 1553 return 0; 1554 } 1555 1556 /* 1557 * Perform a DT_REL style relocation on an ELF binary. 1558 */ 1559 static int perform_rel 1560 (jit_context_t context, jit_readelf_t readelf, 1561 int print_failures, const char *name, Elf_Rel *reloc) 1562 { 1563 void *address; 1564 void *value; 1565 1566 /* Get the address to apply the relocation at */ 1567 address = jit_readelf_map_vaddr(readelf, (jit_nuint)(reloc->r_offset)); 1568 if(!address) 1569 { 1570 if(print_failures) 1571 { 1572 printf("%s: cannot map virtual address 0x%lx\n", 1573 name, (long)(reloc->r_offset)); 1574 } 1575 return 0; 1576 } 1577 1578 /* Resolve the designated symbol to its actual value */ 1579 value = resolve_symbol 1580 (context, readelf, print_failures, name, 1581 (jit_nuint)ELF_R_SYM(reloc->r_info)); 1582 if(!value) 1583 { 1584 return 0; 1585 } 1586 1587 /* Perform the relocation */ 1588 if(!(*(readelf->reloc_func)) 1589 (readelf, address, (int)(ELF_R_TYPE(reloc->r_info)), 1590 (jit_nuint)value, 0, 0)) 1591 { 1592 if(print_failures) 1593 { 1594 printf("%s: relocation type %d was not recognized\n", 1595 name, (int)(ELF_R_TYPE(reloc->r_info))); 1596 } 1597 return 0; 1598 } 1599 return 1; 1600 } 1601 1602 /* 1603 * Perform a DT_RELA style relocation on an ELF binary. 1604 */ 1605 static int perform_rela 1606 (jit_context_t context, jit_readelf_t readelf, 1607 int print_failures, const char *name, Elf_Rela *reloc) 1608 { 1609 void *address; 1610 void *value; 1611 1612 /* Get the address to apply the relocation at */ 1613 address = jit_readelf_map_vaddr(readelf, (jit_nuint)(reloc->r_offset)); 1614 if(!address) 1615 { 1616 if(print_failures) 1617 { 1618 printf("%s: cannot map virtual address 0x%lx\n", 1619 name, (long)(reloc->r_offset)); 1620 } 1621 return 0; 1622 } 1623 1624 /* Resolve the designated symbol to its actual value */ 1625 value = resolve_symbol 1626 (context, readelf, print_failures, name, 1627 (jit_nuint)ELF_R_SYM(reloc->r_info)); 1628 if(!value) 1629 { 1630 return 0; 1631 } 1632 1633 /* Perform the relocation */ 1634 if(!(*(readelf->reloc_func)) 1635 (readelf, address, (int)(ELF_R_TYPE(reloc->r_info)), 1636 (jit_nuint)value, 1, (jit_nuint)(reloc->r_addend))) 1637 { 1638 if(print_failures) 1639 { 1640 printf("%s: relocation type %d was not recognized\n", 1641 name, (int)(ELF_R_TYPE(reloc->r_info))); 1642 } 1643 return 0; 1644 } 1645 return 1; 1646 } 1647 1648 /* 1649 * Perform relocations on an ELF binary. Returns zero on failure. 1650 */ 1651 static int perform_relocations 1652 (jit_context_t context, jit_readelf_t readelf, int print_failures) 1653 { 1654 Elf_Addr address; 1655 Elf_Addr table_size; 1656 Elf_Addr entry_size; 1657 unsigned char *table; 1658 const char *name; 1659 int ok = 1; 1660 1661 /* Get the library name, for printing diagnostic messages */ 1662 name = jit_readelf_get_name(readelf); 1663 if(!name) 1664 { 1665 name = "unknown-elf-binary"; 1666 } 1667 1668 /* Bail out if we don't know how to perform relocations */ 1669 if(!(readelf->reloc_func)) 1670 { 1671 if(print_failures) 1672 { 1673 printf("%s: do not know how to perform relocations\n", name); 1674 } 1675 return 0; 1676 } 1677 1678 /* Apply the "Rel" relocations in the dynamic section */ 1679 if(dynamic_for_type(readelf, DT_REL, &address) && 1680 dynamic_for_type(readelf, DT_RELSZ, &table_size) && 1681 dynamic_for_type(readelf, DT_RELENT, &entry_size) && entry_size) 1682 { 1683 table = (unsigned char *)jit_readelf_map_vaddr 1684 (readelf, (jit_nuint)address); 1685 while(table && table_size >= entry_size) 1686 { 1687 if(!perform_rel(context, readelf, print_failures, name, 1688 (Elf_Rel *)table)) 1689 { 1690 ok = 0; 1691 } 1692 table += (jit_nuint)entry_size; 1693 table_size -= entry_size; 1694 } 1695 } 1696 1697 /* Apply the "Rela" relocations in the dynamic section */ 1698 if(dynamic_for_type(readelf, DT_RELA, &address) && 1699 dynamic_for_type(readelf, DT_RELASZ, &table_size) && 1700 dynamic_for_type(readelf, DT_RELAENT, &entry_size) && entry_size) 1701 { 1702 table = (unsigned char *)jit_readelf_map_vaddr 1703 (readelf, (jit_nuint)address); 1704 while(table && table_size >= entry_size) 1705 { 1706 if(!perform_rela(context, readelf, print_failures, name, 1707 (Elf_Rela *)table)) 1708 { 1709 ok = 0; 1710 } 1711 table += (jit_nuint)entry_size; 1712 table_size -= entry_size; 1713 } 1714 } 1715 1716 /* Apply the "PLT" relocations in the dynamic section, which 1717 may be either DT_REL or DT_RELA style relocations */ 1718 if(dynamic_for_type(readelf, DT_JMPREL, &address) && 1719 dynamic_for_type(readelf, DT_PLTRELSZ, &table_size) && 1720 dynamic_for_type(readelf, DT_PLTREL, &entry_size)) 1721 { 1722 if(entry_size == DT_REL) 1723 { 1724 if(dynamic_for_type(readelf, DT_RELENT, &entry_size) && entry_size) 1725 { 1726 table = (unsigned char *)jit_readelf_map_vaddr 1727 (readelf, (jit_nuint)address); 1728 while(table && table_size >= entry_size) 1729 { 1730 if(!perform_rel(context, readelf, print_failures, name, 1731 (Elf_Rel *)table)) 1732 { 1733 ok = 0; 1734 } 1735 table += (jit_nuint)entry_size; 1736 table_size -= entry_size; 1737 } 1738 } 1739 } 1740 else if(entry_size == DT_RELA) 1741 { 1742 if(dynamic_for_type(readelf, DT_RELAENT, &entry_size) && entry_size) 1743 { 1744 table = (unsigned char *)jit_readelf_map_vaddr 1745 (readelf, (jit_nuint)address); 1746 while(table && table_size >= entry_size) 1747 { 1748 if(!perform_rela(context, readelf, print_failures, name, 1749 (Elf_Rela *)table)) 1750 { 1751 ok = 0; 1752 } 1753 table += (jit_nuint)entry_size; 1754 table_size -= entry_size; 1755 } 1756 } 1757 } 1758 } 1759 1760 /* Return to the caller */ 1761 return ok; 1762 } 1763 1764 /*@ 1765 * @deftypefun int jit_readelf_resolve_all (jit_context_t @var{context}, int @var{print_failures}) 1766 * Resolve all of the cross-library symbol references in ELF binaries 1767 * that have been added to @var{context} but which were not resolved 1768 * in the previous call to this function. If @var{print_failures} 1769 * is non-zero, then diagnostic messages will be written to stdout 1770 * for any symbol resolutions that fail. 1771 * 1772 * Returns zero on failure, or non-zero if all symbols were successfully 1773 * resolved. If there are no ELF binaries awaiting resolution, then 1774 * this function will return a non-zero result. 1775 * @end deftypefun 1776 @*/ 1777 int jit_readelf_resolve_all(jit_context_t context, int print_failures) 1778 { 1779 int ok = 1; 1780 jit_readelf_t readelf; 1781 if(!context) 1782 { 1783 return 0; 1784 } 1785 1786 _jit_memory_lock(context); 1787 1788 readelf = context->elf_binaries; 1789 while(readelf != 0) 1790 { 1791 if(!(readelf->resolved)) 1792 { 1793 readelf->resolved = 1; 1794 if(!perform_relocations(context, readelf, print_failures)) 1795 { 1796 ok = 0; 1797 } 1798 } 1799 readelf = readelf->next; 1800 } 1801 1802 _jit_memory_unlock(context); 1803 return ok; 1804 } 1805 1806 /*@ 1807 * @deftypefun int jit_readelf_register_symbol (jit_context_t @var{context}, const char *@var{name}, void *@var{value}, int @var{after}) 1808 * Register @var{value} with @var{name} on the specified @var{context}. 1809 * Whenever symbols are resolved with @code{jit_readelf_resolve_all}, 1810 * and the symbol @var{name} is encountered, @var{value} will be 1811 * substituted. Returns zero if out of memory or there is something 1812 * wrong with the parameters. 1813 * 1814 * If @var{after} is non-zero, then @var{name} will be resolved after all 1815 * other ELF libraries; otherwise it will be resolved before the ELF 1816 * libraries. 1817 * 1818 * This function is used to register intrinsic symbols that are specific to 1819 * the front end virtual machine. References to intrinsics within 1820 * @code{libjit} itself are resolved automatically. 1821 * @end deftypefun 1822 @*/ 1823 int jit_readelf_register_symbol 1824 (jit_context_t context, const char *name, void *value, int after) 1825 { 1826 jit_regsym_t sym; 1827 jit_regsym_t *new_list; 1828 1829 /* Bail out if there is something wrong with the parameters */ 1830 if(!context || !name || !value) 1831 { 1832 return 0; 1833 } 1834 1835 /* Allocate and populate the symbol information block */ 1836 sym = (jit_regsym_t)jit_malloc 1837 (sizeof(struct jit_regsym) + jit_strlen(name)); 1838 if(!sym) 1839 { 1840 return 0; 1841 } 1842 sym->value = value; 1843 sym->after = after; 1844 jit_strcpy(sym->name, name); 1845 1846 /* Add the symbol details to the registered list */ 1847 new_list = (jit_regsym_t *)jit_realloc 1848 (context->registered_symbols, 1849 sizeof(jit_regsym_t) * (context->num_registered_symbols + 1)); 1850 if(!new_list) 1851 { 1852 jit_free(sym); 1853 return 0; 1854 } 1855 new_list[(context->num_registered_symbols)++] = sym; 1856 context->registered_symbols = new_list; 1857 return 1; 1858 } 1859 1860 /************************************************************************ 1861 1862 Warning! Warning! Warning! 1863 1864 The following code is very system-dependent, as every ELF target has its 1865 own peculiar mechanism for performing relocations. Consult your target's 1866 documentation for the precise details. 1867 1868 To make things a little easier, you only need to support the relocation 1869 types that you intend to use in the JIT's ELF writer. And many types 1870 only pertain to ELF executable or object files, which we don't use. 1871 1872 ************************************************************************/ 1873 1874 #if defined(__i386) || defined(__i386__) || defined(_M_IX86) 1875 1876 /* 1877 * Apply relocations for i386 platforms. 1878 */ 1879 static int i386_reloc(jit_readelf_t readelf, void *address, int type, 1880 jit_nuint value, int has_addend, jit_nuint addend) 1881 { 1882 if(type == R_386_32) 1883 { 1884 if(has_addend) 1885 { 1886 *((jit_nuint *)address) = value + addend; 1887 } 1888 else 1889 { 1890 *((jit_nuint *)address) += value; 1891 } 1892 return 1; 1893 } 1894 else if(type == R_386_PC32) 1895 { 1896 value -= (jit_nuint)address; 1897 if(has_addend) 1898 { 1899 *((jit_nuint *)address) = value + addend; 1900 } 1901 else 1902 { 1903 *((jit_nuint *)address) += value; 1904 } 1905 return 1; 1906 } 1907 return 0; 1908 } 1909 1910 #endif /* i386 */ 1911 1912 #if defined(__arm) || defined(__arm__) 1913 1914 /* 1915 * Apply relocations for ARM platforms. 1916 */ 1917 static int arm_reloc(jit_readelf_t readelf, void *address, int type, 1918 jit_nuint value, int has_addend, jit_nuint addend) 1919 { 1920 if(type == R_ARM_PC24) 1921 { 1922 value -= (jit_nuint)address; 1923 if(has_addend) 1924 { 1925 *((jit_nuint *)address) = 1926 (*((jit_nuint *)address) & 0xFF000000) + value + addend; 1927 } 1928 else 1929 { 1930 *((jit_nuint *)address) += value; 1931 } 1932 return 1; 1933 } 1934 else if(type == R_ARM_ABS32) 1935 { 1936 if(has_addend) 1937 { 1938 *((jit_nuint *)address) = value + addend; 1939 } 1940 else 1941 { 1942 *((jit_nuint *)address) += value; 1943 } 1944 return 1; 1945 } 1946 else if(type == R_ARM_REL32) 1947 { 1948 value -= (jit_nuint)address; 1949 if(has_addend) 1950 { 1951 *((jit_nuint *)address) = value + addend; 1952 } 1953 else 1954 { 1955 *((jit_nuint *)address) += value; 1956 } 1957 return 1; 1958 } 1959 return 0; 1960 } 1961 1962 #endif /* arm */ 1963 1964 /* 1965 * Apply relocations for the interpreted platform. 1966 */ 1967 static int interp_reloc(jit_readelf_t readelf, void *address, int type, 1968 jit_nuint value, int has_addend, jit_nuint addend) 1969 { 1970 /* We only have one type of relocation for the interpreter: direct */ 1971 if(type == 1) 1972 { 1973 *((jit_nuint *)address) = value; 1974 return 1; 1975 } 1976 else 1977 { 1978 return 0; 1979 } 1980 } 1981 1982 /* 1983 * Get the relocation function for a particular machine type. 1984 */ 1985 static jit_reloc_func get_reloc(unsigned int machine) 1986 { 1987 #if defined(__i386) || defined(__i386__) || defined(_M_IX86) 1988 if(machine == EM_386) 1989 { 1990 return i386_reloc; 1991 } 1992 #endif 1993 #if defined(__arm) || defined(__arm__) 1994 if(machine == EM_ARM) 1995 { 1996 return arm_reloc; 1997 } 1998 #endif 1999 if(machine == 0x4C6A) /* "Lj" for the libjit interpreter */ 2000 { 2001 return interp_reloc; 2002 } 2003 return 0; 2004 }