1 /* 2 * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2003-2012, Axel Dörfler, axeld@pinc-software.de. 4 * Distributed under the terms of the MIT License. 5 * 6 * Copyright 2002, Manuel J. Petit. All rights reserved. 7 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 8 * Distributed under the terms of the NewOS License. 9 */ 10 11 #include "elf_load_image.h" 12 13 #include <stdio.h> 14 #include <string.h> 15 16 #include <syscalls.h> 17 18 #include "add_ons.h" 19 #include "elf_haiku_version.h" 20 #include "elf_symbol_lookup.h" 21 #include "elf_tls.h" 22 #include "elf_versioning.h" 23 #include "images.h" 24 #include "runtime_loader_private.h" 25 26 27 static const char* sSearchPathSubDir = NULL; 28 29 30 static const char* 31 get_program_path() 32 { 33 return gProgramImage != NULL ? gProgramImage->path : NULL; 34 } 35 36 37 static int32 38 count_regions(const char* imagePath, char const* buff, int phnum, int phentsize) 39 { 40 elf_phdr* pheaders; 41 int32 count = 0; 42 int i; 43 44 for (i = 0; i < phnum; i++) { 45 pheaders = (elf_phdr*)(buff + i * phentsize); 46 47 switch (pheaders->p_type) { 48 case PT_NULL: 49 // NOP header 50 break; 51 case PT_LOAD: 52 count += 1; 53 if (pheaders->p_memsz != pheaders->p_filesz) { 54 addr_t A = TO_PAGE_SIZE(pheaders->p_vaddr 55 + pheaders->p_memsz); 56 addr_t B = TO_PAGE_SIZE(pheaders->p_vaddr 57 + pheaders->p_filesz); 58 59 if (A != B) 60 count += 1; 61 } 62 break; 63 case PT_DYNAMIC: 64 // will be handled at some other place 65 break; 66 case PT_INTERP: 67 // should check here for appropriate interpreter 68 break; 69 case PT_NOTE: 70 // unsupported 71 break; 72 case PT_SHLIB: 73 // undefined semantics 74 break; 75 case PT_PHDR: 76 // we don't use it 77 break; 78 case PT_EH_FRAME: 79 case PT_RELRO: 80 // not implemented yet, but can be ignored 81 break; 82 case PT_STACK: 83 // we don't use it 84 break; 85 case PT_TLS: 86 // will be handled at some other place 87 break; 88 case PT_ARM_UNWIND: 89 // will be handled in libgcc_s.so.1 90 break; 91 case PT_RISCV_ATTRIBUTES: 92 // TODO: check ABI compatibility attributes 93 break; 94 default: 95 FATAL("%s: Unhandled pheader type in count 0x%" B_PRIx32 "\n", 96 imagePath, pheaders->p_type); 97 break; 98 } 99 } 100 101 return count; 102 } 103 104 105 static status_t 106 parse_program_headers(image_t* image, char* buff, int phnum, int phentsize) 107 { 108 elf_phdr* pheader; 109 int regcount; 110 int i; 111 112 image->dso_tls_id = unsigned(-1); 113 114 regcount = 0; 115 for (i = 0; i < phnum; i++) { 116 pheader = (elf_phdr*)(buff + i * phentsize); 117 118 switch (pheader->p_type) { 119 case PT_NULL: 120 /* NOP header */ 121 break; 122 case PT_LOAD: 123 if (pheader->p_memsz == pheader->p_filesz) { 124 /* 125 * everything in one area 126 */ 127 image->regions[regcount].start = pheader->p_vaddr; 128 image->regions[regcount].size = pheader->p_memsz; 129 image->regions[regcount].vmstart 130 = PAGE_BASE(pheader->p_vaddr); 131 image->regions[regcount].vmsize 132 = TO_PAGE_SIZE(pheader->p_memsz 133 + PAGE_OFFSET(pheader->p_vaddr)); 134 image->regions[regcount].fdstart = pheader->p_offset; 135 image->regions[regcount].fdsize = pheader->p_filesz; 136 image->regions[regcount].delta = 0; 137 image->regions[regcount].flags = 0; 138 if (pheader->p_flags & PF_WRITE) { 139 // this is a writable segment 140 image->regions[regcount].flags |= RFLAG_RW; 141 } 142 } else { 143 /* 144 * may require splitting 145 */ 146 addr_t A = TO_PAGE_SIZE(pheader->p_vaddr 147 + pheader->p_memsz); 148 addr_t B = TO_PAGE_SIZE(pheader->p_vaddr 149 + pheader->p_filesz); 150 151 image->regions[regcount].start = pheader->p_vaddr; 152 image->regions[regcount].size = pheader->p_filesz; 153 image->regions[regcount].vmstart 154 = PAGE_BASE(pheader->p_vaddr); 155 image->regions[regcount].vmsize 156 = TO_PAGE_SIZE(pheader->p_filesz 157 + PAGE_OFFSET(pheader->p_vaddr)); 158 image->regions[regcount].fdstart = pheader->p_offset; 159 image->regions[regcount].fdsize = pheader->p_filesz; 160 image->regions[regcount].delta = 0; 161 image->regions[regcount].flags = 0; 162 if (pheader->p_flags & PF_WRITE) { 163 // this is a writable segment 164 image->regions[regcount].flags |= RFLAG_RW; 165 } 166 167 if (A != B) { 168 /* 169 * yeah, it requires splitting 170 */ 171 regcount += 1; 172 image->regions[regcount].start = pheader->p_vaddr; 173 image->regions[regcount].size 174 = pheader->p_memsz - pheader->p_filesz; 175 image->regions[regcount].vmstart 176 = image->regions[regcount-1].vmstart 177 + image->regions[regcount-1].vmsize; 178 image->regions[regcount].vmsize 179 = TO_PAGE_SIZE(pheader->p_memsz 180 + PAGE_OFFSET(pheader->p_vaddr)) 181 - image->regions[regcount-1].vmsize; 182 image->regions[regcount].fdstart = 0; 183 image->regions[regcount].fdsize = 0; 184 image->regions[regcount].delta = 0; 185 image->regions[regcount].flags = RFLAG_ANON; 186 if (pheader->p_flags & PF_WRITE) { 187 // this is a writable segment 188 image->regions[regcount].flags |= RFLAG_RW; 189 } 190 } 191 } 192 regcount += 1; 193 break; 194 case PT_DYNAMIC: 195 image->dynamic_ptr = pheader->p_vaddr; 196 break; 197 case PT_INTERP: 198 // should check here for appropiate interpreter 199 break; 200 case PT_NOTE: 201 // unsupported 202 break; 203 case PT_SHLIB: 204 // undefined semantics 205 break; 206 case PT_PHDR: 207 // we don't use it 208 break; 209 case PT_EH_FRAME: 210 case PT_RELRO: 211 // not implemented yet, but can be ignored 212 break; 213 case PT_STACK: 214 // we don't use it 215 break; 216 case PT_TLS: 217 image->dso_tls_id 218 = TLSBlockTemplates::Get().Register( 219 TLSBlockTemplate((void*)pheader->p_vaddr, 220 pheader->p_filesz, pheader->p_memsz)); 221 break; 222 case PT_ARM_UNWIND: 223 // will be handled in libgcc_s.so.1 224 break; 225 case PT_RISCV_ATTRIBUTES: 226 // TODO: check ABI compatibility attributes 227 break; 228 default: 229 FATAL("%s: Unhandled pheader type in parse 0x%" B_PRIx32 "\n", 230 image->path, pheader->p_type); 231 return B_BAD_DATA; 232 } 233 } 234 235 return B_OK; 236 } 237 238 239 static bool 240 assert_dynamic_loadable(image_t* image) 241 { 242 uint32 i; 243 244 if (!image->dynamic_ptr) 245 return true; 246 247 for (i = 0; i < image->num_regions; i++) { 248 if (image->dynamic_ptr >= image->regions[i].start 249 && image->dynamic_ptr 250 < image->regions[i].start + image->regions[i].size) { 251 return true; 252 } 253 } 254 255 return false; 256 } 257 258 259 static bool 260 parse_dynamic_segment(image_t* image) 261 { 262 elf_dyn* d; 263 int i; 264 int sonameOffset = -1; 265 266 image->symhash = 0; 267 image->syms = 0; 268 image->strtab = 0; 269 270 d = (elf_dyn*)image->dynamic_ptr; 271 if (!d) 272 return true; 273 274 for (i = 0; d[i].d_tag != DT_NULL; i++) { 275 switch (d[i].d_tag) { 276 case DT_NEEDED: 277 image->num_needed += 1; 278 break; 279 case DT_HASH: 280 image->symhash 281 = (uint32*)(d[i].d_un.d_ptr + image->regions[0].delta); 282 break; 283 case DT_STRTAB: 284 image->strtab 285 = (char*)(d[i].d_un.d_ptr + image->regions[0].delta); 286 break; 287 case DT_SYMTAB: 288 image->syms = (elf_sym*) 289 (d[i].d_un.d_ptr + image->regions[0].delta); 290 break; 291 case DT_REL: 292 image->rel = (elf_rel*) 293 (d[i].d_un.d_ptr + image->regions[0].delta); 294 break; 295 case DT_RELSZ: 296 image->rel_len = d[i].d_un.d_val; 297 break; 298 case DT_RELA: 299 image->rela = (elf_rela*) 300 (d[i].d_un.d_ptr + image->regions[0].delta); 301 break; 302 case DT_RELASZ: 303 image->rela_len = d[i].d_un.d_val; 304 break; 305 case DT_JMPREL: 306 // procedure linkage table relocations 307 image->pltrel = (elf_rel*) 308 (d[i].d_un.d_ptr + image->regions[0].delta); 309 break; 310 case DT_PLTRELSZ: 311 image->pltrel_len = d[i].d_un.d_val; 312 break; 313 case DT_INIT: 314 image->init_routine 315 = (d[i].d_un.d_ptr + image->regions[0].delta); 316 break; 317 case DT_FINI: 318 image->term_routine 319 = (d[i].d_un.d_ptr + image->regions[0].delta); 320 break; 321 case DT_SONAME: 322 sonameOffset = d[i].d_un.d_val; 323 break; 324 case DT_GNU_HASH: 325 { 326 uint32* gnuhash = (uint32*) 327 (d[i].d_un.d_ptr + image->regions[0].delta); 328 const uint32 bucketCount = gnuhash[0]; 329 const uint32 symIndex = gnuhash[1]; 330 const uint32 maskWordsCount = gnuhash[2]; 331 const uint32 bloomSize = maskWordsCount * (sizeof(elf_addr) / 4); 332 333 image->gnuhash.mask_words_count_mask = maskWordsCount - 1; 334 image->gnuhash.shift2 = gnuhash[3]; 335 image->gnuhash.bucket_count = bucketCount; 336 image->gnuhash.bloom = (elf_addr*)(gnuhash + 4); 337 image->gnuhash.buckets = gnuhash + 4 + bloomSize; 338 image->gnuhash.chain0 = image->gnuhash.buckets + bucketCount - symIndex; 339 break; 340 } 341 case DT_VERSYM: 342 image->symbol_versions = (elf_versym*) 343 (d[i].d_un.d_ptr + image->regions[0].delta); 344 break; 345 case DT_VERDEF: 346 image->version_definitions = (elf_verdef*) 347 (d[i].d_un.d_ptr + image->regions[0].delta); 348 break; 349 case DT_VERDEFNUM: 350 image->num_version_definitions = d[i].d_un.d_val; 351 break; 352 case DT_VERNEED: 353 image->needed_versions = (elf_verneed*) 354 (d[i].d_un.d_ptr + image->regions[0].delta); 355 break; 356 case DT_VERNEEDNUM: 357 image->num_needed_versions = d[i].d_un.d_val; 358 break; 359 case DT_SYMBOLIC: 360 image->flags |= RFLAG_SYMBOLIC; 361 break; 362 case DT_FLAGS: 363 { 364 uint32 flags = d[i].d_un.d_val; 365 if ((flags & DF_SYMBOLIC) != 0) 366 image->flags |= RFLAG_SYMBOLIC; 367 if ((flags & DF_STATIC_TLS) != 0) { 368 FATAL("Static TLS model is not supported.\n"); 369 return false; 370 } 371 break; 372 } 373 case DT_INIT_ARRAY: 374 // array of pointers to initialization functions 375 image->init_array = (addr_t*) 376 (d[i].d_un.d_ptr + image->regions[0].delta); 377 break; 378 case DT_INIT_ARRAYSZ: 379 // size in bytes of the array of initialization functions 380 image->init_array_len = d[i].d_un.d_val; 381 break; 382 case DT_PREINIT_ARRAY: 383 // array of pointers to pre-initialization functions 384 image->preinit_array = (addr_t*) 385 (d[i].d_un.d_ptr + image->regions[0].delta); 386 break; 387 case DT_PREINIT_ARRAYSZ: 388 // size in bytes of the array of pre-initialization functions 389 image->preinit_array_len = d[i].d_un.d_val; 390 break; 391 case DT_FINI_ARRAY: 392 // array of pointers to termination functions 393 image->term_array = (addr_t*) 394 (d[i].d_un.d_ptr + image->regions[0].delta); 395 break; 396 case DT_FINI_ARRAYSZ: 397 // size in bytes of the array of termination functions 398 image->term_array_len = d[i].d_un.d_val; 399 break; 400 default: 401 continue; 402 403 // TODO: Implement: 404 // DT_RELENT: The size of a DT_REL entry. 405 // DT_RELAENT: The size of a DT_RELA entry. 406 // DT_SYMENT: The size of a symbol table entry. 407 // DT_PLTREL: The type of the PLT relocation entries (DT_JMPREL). 408 // DT_BIND_NOW/DF_BIND_NOW: No lazy binding allowed. 409 // DT_TEXTREL/DF_TEXTREL: Indicates whether text relocations are 410 // required (for optimization purposes only). 411 } 412 } 413 414 // lets make sure we found all the required sections 415 if (!image->symhash || !image->syms || !image->strtab) 416 return false; 417 418 if (sonameOffset >= 0) 419 strlcpy(image->name, STRING(image, sonameOffset), sizeof(image->name)); 420 421 return true; 422 } 423 424 425 // #pragma mark - 426 427 428 status_t 429 parse_elf_header(elf_ehdr* eheader, int32* _pheaderSize, 430 int32* _sheaderSize) 431 { 432 if (memcmp(eheader->e_ident, ELFMAG, 4) != 0) 433 return B_NOT_AN_EXECUTABLE; 434 435 if (eheader->e_ident[4] != ELF_CLASS) 436 return B_NOT_AN_EXECUTABLE; 437 438 if (eheader->e_phoff == 0) 439 return B_NOT_AN_EXECUTABLE; 440 441 if (eheader->e_phentsize < sizeof(elf_phdr)) 442 return B_NOT_AN_EXECUTABLE; 443 444 *_pheaderSize = eheader->e_phentsize * eheader->e_phnum; 445 *_sheaderSize = eheader->e_shentsize * eheader->e_shnum; 446 447 if (*_pheaderSize <= 0) 448 return B_NOT_AN_EXECUTABLE; 449 450 return B_OK; 451 } 452 453 454 #if defined(_COMPAT_MODE) 455 #if defined(__x86_64__) 456 status_t 457 parse_elf32_header(Elf32_Ehdr* eheader, int32* _pheaderSize, 458 int32* _sheaderSize) 459 { 460 if (memcmp(eheader->e_ident, ELFMAG, 4) != 0) 461 return B_NOT_AN_EXECUTABLE; 462 463 if (eheader->e_ident[4] != ELFCLASS32) 464 return B_NOT_AN_EXECUTABLE; 465 466 if (eheader->e_phoff == 0) 467 return B_NOT_AN_EXECUTABLE; 468 469 if (eheader->e_phentsize < sizeof(Elf32_Phdr)) 470 return B_NOT_AN_EXECUTABLE; 471 472 *_pheaderSize = eheader->e_phentsize * eheader->e_phnum; 473 *_sheaderSize = eheader->e_shentsize * eheader->e_shnum; 474 475 if (*_pheaderSize <= 0) 476 return B_NOT_AN_EXECUTABLE; 477 478 return B_OK; 479 } 480 #else 481 status_t 482 parse_elf64_header(Elf64_Ehdr* eheader, int32* _pheaderSize, 483 int32* _sheaderSize) 484 { 485 if (memcmp(eheader->e_ident, ELFMAG, 4) != 0) 486 return B_NOT_AN_EXECUTABLE; 487 488 if (eheader->e_ident[4] != ELFCLASS64) 489 return B_NOT_AN_EXECUTABLE; 490 491 if (eheader->e_phoff == 0) 492 return B_NOT_AN_EXECUTABLE; 493 494 if (eheader->e_phentsize < sizeof(Elf64_Phdr)) 495 return B_NOT_AN_EXECUTABLE; 496 497 *_pheaderSize = eheader->e_phentsize * eheader->e_phnum; 498 *_sheaderSize = eheader->e_shentsize * eheader->e_shnum; 499 500 if (*_pheaderSize <= 0) 501 return B_NOT_AN_EXECUTABLE; 502 503 return B_OK; 504 } 505 #endif // __x86_64__ 506 #endif // _COMPAT_MODE 507 508 509 status_t 510 load_image(char const* name, image_type type, const char* rpath, const char* runpath, 511 const char* requestingObjectPath, image_t** _image) 512 { 513 int32 pheaderSize, sheaderSize; 514 char path[PATH_MAX]; 515 ssize_t length; 516 char pheaderBuffer[4096]; 517 int32 numRegions; 518 image_t* found; 519 image_t* image; 520 status_t status; 521 int fd; 522 523 elf_ehdr eheader; 524 525 // Have we already loaded that image? Don't check for add-ons -- we always 526 // reload them. 527 if (type != B_ADD_ON_IMAGE) { 528 found = find_loaded_image_by_name(name, APP_OR_LIBRARY_TYPE); 529 530 if (found == NULL && type != B_APP_IMAGE && gProgramImage != NULL) { 531 // Special case for add-ons that link against the application 532 // executable, with the executable not having a soname set. 533 if (const char* lastSlash = strrchr(name, '/')) { 534 if (strcmp(gProgramImage->name, lastSlash + 1) == 0) 535 found = gProgramImage; 536 } 537 } 538 539 if (found) { 540 atomic_add(&found->ref_count, 1); 541 *_image = found; 542 KTRACE("rld: load_container(\"%s\", type: %d, %s: \"%s\") " 543 "already loaded", name, type, 544 runpath != NULL ? "runpath" : "rpath", runpath != NULL ? runpath : rpath); 545 return B_OK; 546 } 547 } 548 549 KTRACE("rld: load_container(\"%s\", type: %d, %s: \"%s\")", name, type, 550 runpath != NULL ? "runpath" : "rpath", runpath != NULL ? runpath : rpath); 551 552 strlcpy(path, name, sizeof(path)); 553 554 // find and open the file 555 fd = open_executable(path, type, rpath, runpath, get_program_path(), 556 requestingObjectPath, sSearchPathSubDir); 557 if (fd < 0) { 558 FATAL("Cannot open file %s (needed by %s): %s\n", name, requestingObjectPath, strerror(fd)); 559 KTRACE("rld: load_container(\"%s\"): failed to open file", name); 560 return fd; 561 } 562 563 // normalize the image path 564 status = _kern_normalize_path(path, true, path); 565 if (status != B_OK) 566 goto err1; 567 568 // Test again if this image has been registered already - this time, 569 // we can check the full path, not just its name as noted. 570 // You could end up loading an image twice with symbolic links, else. 571 if (type != B_ADD_ON_IMAGE) { 572 found = find_loaded_image_by_name(path, APP_OR_LIBRARY_TYPE); 573 if (found) { 574 atomic_add(&found->ref_count, 1); 575 *_image = found; 576 _kern_close(fd); 577 KTRACE("rld: load_container(\"%s\"): already loaded after all", 578 name); 579 return B_OK; 580 } 581 } 582 583 length = _kern_read(fd, 0, &eheader, sizeof(eheader)); 584 if (length != sizeof(eheader)) { 585 status = B_NOT_AN_EXECUTABLE; 586 FATAL("%s: Troubles reading ELF header\n", path); 587 goto err1; 588 } 589 590 status = parse_elf_header(&eheader, &pheaderSize, &sheaderSize); 591 if (status < B_OK) { 592 FATAL("%s: Incorrect ELF header\n", path); 593 goto err1; 594 } 595 596 // ToDo: what to do about this restriction?? 597 if (pheaderSize > (int)sizeof(pheaderBuffer)) { 598 FATAL("%s: Cannot handle program headers bigger than %lu\n", 599 path, sizeof(pheaderBuffer)); 600 status = B_UNSUPPORTED; 601 goto err1; 602 } 603 604 length = _kern_read(fd, eheader.e_phoff, pheaderBuffer, pheaderSize); 605 if (length != pheaderSize) { 606 FATAL("%s: Could not read program headers: %s\n", path, 607 strerror(length)); 608 status = B_BAD_DATA; 609 goto err1; 610 } 611 612 numRegions = count_regions(path, pheaderBuffer, eheader.e_phnum, 613 eheader.e_phentsize); 614 if (numRegions <= 0) { 615 FATAL("%s: Troubles parsing Program headers, numRegions = %" B_PRId32 616 "\n", path, numRegions); 617 status = B_BAD_DATA; 618 goto err1; 619 } 620 621 image = create_image(name, path, numRegions); 622 if (image == NULL) { 623 FATAL("%s: Failed to allocate image_t object\n", path); 624 status = B_NO_MEMORY; 625 goto err1; 626 } 627 628 status = parse_program_headers(image, pheaderBuffer, eheader.e_phnum, 629 eheader.e_phentsize); 630 if (status < B_OK) 631 goto err2; 632 633 if (!assert_dynamic_loadable(image)) { 634 FATAL("%s: Dynamic segment must be loadable (implementation " 635 "restriction)\n", image->path); 636 status = B_UNSUPPORTED; 637 goto err2; 638 } 639 640 status = map_image(fd, path, image, eheader.e_type == ET_EXEC); 641 if (status < B_OK) { 642 FATAL("%s: Could not map image: %s\n", image->path, strerror(status)); 643 status = B_ERROR; 644 goto err2; 645 } 646 647 if (!parse_dynamic_segment(image)) { 648 FATAL("%s: Troubles handling dynamic section\n", image->path); 649 status = B_BAD_DATA; 650 goto err3; 651 } 652 653 if (eheader.e_entry != 0) 654 image->entry_point = eheader.e_entry + image->regions[0].delta; 655 656 analyze_image_haiku_version_and_abi(fd, image, eheader, sheaderSize, 657 pheaderBuffer, sizeof(pheaderBuffer)); 658 659 // If sSearchPathSubDir is unset (meaning, this is the first image we're 660 // loading) we init the search path subdir if the compiler version doesn't 661 // match ours. 662 if (sSearchPathSubDir == NULL) { 663 #if __GNUC__ == 2 || (defined(_COMPAT_MODE) && !defined(__x86_64__)) 664 if ((image->abi & B_HAIKU_ABI_MAJOR) == B_HAIKU_ABI_GCC_4) 665 sSearchPathSubDir = "x86"; 666 #endif 667 #if __GNUC__ >= 4 || (defined(_COMPAT_MODE) && !defined(__x86_64__)) 668 if ((image->abi & B_HAIKU_ABI_MAJOR) == B_HAIKU_ABI_GCC_2) 669 sSearchPathSubDir = "x86_gcc2"; 670 #endif 671 } 672 673 set_abi_api_version(image->abi, image->api_version); 674 675 // init gcc version dependent image flags 676 // symbol resolution strategy 677 if (image->abi == B_HAIKU_ABI_GCC_2_ANCIENT) 678 image->find_undefined_symbol = find_undefined_symbol_beos; 679 680 // init version infos 681 status = init_image_version_infos(image); 682 683 image->type = type; 684 register_image(image, fd, path); 685 image_event(image, IMAGE_EVENT_LOADED); 686 687 _kern_close(fd); 688 689 enqueue_loaded_image(image); 690 691 *_image = image; 692 693 KTRACE("rld: load_container(\"%s\"): done: id: %" B_PRId32 " (ABI: %#" 694 B_PRIx32 ")", name, image->id, image->abi); 695 696 return B_OK; 697 698 err3: 699 unmap_image(image); 700 err2: 701 delete_image_struct(image); 702 err1: 703 _kern_close(fd); 704 705 KTRACE("rld: load_container(\"%s\"): failed: %s", name, 706 strerror(status)); 707 708 return status; 709 } 710