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_VERSYM: 325 image->symbol_versions = (elf_versym*) 326 (d[i].d_un.d_ptr + image->regions[0].delta); 327 break; 328 case DT_VERDEF: 329 image->version_definitions = (elf_verdef*) 330 (d[i].d_un.d_ptr + image->regions[0].delta); 331 break; 332 case DT_VERDEFNUM: 333 image->num_version_definitions = d[i].d_un.d_val; 334 break; 335 case DT_VERNEED: 336 image->needed_versions = (elf_verneed*) 337 (d[i].d_un.d_ptr + image->regions[0].delta); 338 break; 339 case DT_VERNEEDNUM: 340 image->num_needed_versions = d[i].d_un.d_val; 341 break; 342 case DT_SYMBOLIC: 343 image->flags |= RFLAG_SYMBOLIC; 344 break; 345 case DT_FLAGS: 346 { 347 uint32 flags = d[i].d_un.d_val; 348 if ((flags & DF_SYMBOLIC) != 0) 349 image->flags |= RFLAG_SYMBOLIC; 350 if ((flags & DF_STATIC_TLS) != 0) { 351 FATAL("Static TLS model is not supported.\n"); 352 return false; 353 } 354 break; 355 } 356 case DT_INIT_ARRAY: 357 // array of pointers to initialization functions 358 image->init_array = (addr_t*) 359 (d[i].d_un.d_ptr + image->regions[0].delta); 360 break; 361 case DT_INIT_ARRAYSZ: 362 // size in bytes of the array of initialization functions 363 image->init_array_len = d[i].d_un.d_val; 364 break; 365 case DT_PREINIT_ARRAY: 366 // array of pointers to pre-initialization functions 367 image->preinit_array = (addr_t*) 368 (d[i].d_un.d_ptr + image->regions[0].delta); 369 break; 370 case DT_PREINIT_ARRAYSZ: 371 // size in bytes of the array of pre-initialization functions 372 image->preinit_array_len = d[i].d_un.d_val; 373 break; 374 case DT_FINI_ARRAY: 375 // array of pointers to termination functions 376 image->term_array = (addr_t*) 377 (d[i].d_un.d_ptr + image->regions[0].delta); 378 break; 379 case DT_FINI_ARRAYSZ: 380 // size in bytes of the array of termination functions 381 image->term_array_len = d[i].d_un.d_val; 382 break; 383 default: 384 continue; 385 386 // TODO: Implement: 387 // DT_RELENT: The size of a DT_REL entry. 388 // DT_RELAENT: The size of a DT_RELA entry. 389 // DT_SYMENT: The size of a symbol table entry. 390 // DT_PLTREL: The type of the PLT relocation entries (DT_JMPREL). 391 // DT_BIND_NOW/DF_BIND_NOW: No lazy binding allowed. 392 // DT_TEXTREL/DF_TEXTREL: Indicates whether text relocations are 393 // required (for optimization purposes only). 394 } 395 } 396 397 // lets make sure we found all the required sections 398 if (!image->symhash || !image->syms || !image->strtab) 399 return false; 400 401 if (sonameOffset >= 0) 402 strlcpy(image->name, STRING(image, sonameOffset), sizeof(image->name)); 403 404 return true; 405 } 406 407 408 // #pragma mark - 409 410 411 status_t 412 parse_elf_header(elf_ehdr* eheader, int32* _pheaderSize, 413 int32* _sheaderSize) 414 { 415 if (memcmp(eheader->e_ident, ELFMAG, 4) != 0) 416 return B_NOT_AN_EXECUTABLE; 417 418 if (eheader->e_ident[4] != ELF_CLASS) 419 return B_NOT_AN_EXECUTABLE; 420 421 if (eheader->e_phoff == 0) 422 return B_NOT_AN_EXECUTABLE; 423 424 if (eheader->e_phentsize < sizeof(elf_phdr)) 425 return B_NOT_AN_EXECUTABLE; 426 427 *_pheaderSize = eheader->e_phentsize * eheader->e_phnum; 428 *_sheaderSize = eheader->e_shentsize * eheader->e_shnum; 429 430 if (*_pheaderSize <= 0) 431 return B_NOT_AN_EXECUTABLE; 432 433 return B_OK; 434 } 435 436 437 #if defined(_COMPAT_MODE) 438 #if defined(__x86_64__) 439 status_t 440 parse_elf32_header(Elf32_Ehdr* eheader, int32* _pheaderSize, 441 int32* _sheaderSize) 442 { 443 if (memcmp(eheader->e_ident, ELFMAG, 4) != 0) 444 return B_NOT_AN_EXECUTABLE; 445 446 if (eheader->e_ident[4] != ELFCLASS32) 447 return B_NOT_AN_EXECUTABLE; 448 449 if (eheader->e_phoff == 0) 450 return B_NOT_AN_EXECUTABLE; 451 452 if (eheader->e_phentsize < sizeof(Elf32_Phdr)) 453 return B_NOT_AN_EXECUTABLE; 454 455 *_pheaderSize = eheader->e_phentsize * eheader->e_phnum; 456 *_sheaderSize = eheader->e_shentsize * eheader->e_shnum; 457 458 if (*_pheaderSize <= 0) 459 return B_NOT_AN_EXECUTABLE; 460 461 return B_OK; 462 } 463 #else 464 status_t 465 parse_elf64_header(Elf64_Ehdr* eheader, int32* _pheaderSize, 466 int32* _sheaderSize) 467 { 468 if (memcmp(eheader->e_ident, ELFMAG, 4) != 0) 469 return B_NOT_AN_EXECUTABLE; 470 471 if (eheader->e_ident[4] != ELFCLASS64) 472 return B_NOT_AN_EXECUTABLE; 473 474 if (eheader->e_phoff == 0) 475 return B_NOT_AN_EXECUTABLE; 476 477 if (eheader->e_phentsize < sizeof(Elf64_Phdr)) 478 return B_NOT_AN_EXECUTABLE; 479 480 *_pheaderSize = eheader->e_phentsize * eheader->e_phnum; 481 *_sheaderSize = eheader->e_shentsize * eheader->e_shnum; 482 483 if (*_pheaderSize <= 0) 484 return B_NOT_AN_EXECUTABLE; 485 486 return B_OK; 487 } 488 #endif // __x86_64__ 489 #endif // _COMPAT_MODE 490 491 492 status_t 493 load_image(char const* name, image_type type, const char* rpath, const char* runpath, 494 const char* requestingObjectPath, image_t** _image) 495 { 496 int32 pheaderSize, sheaderSize; 497 char path[PATH_MAX]; 498 ssize_t length; 499 char pheaderBuffer[4096]; 500 int32 numRegions; 501 image_t* found; 502 image_t* image; 503 status_t status; 504 int fd; 505 506 elf_ehdr eheader; 507 508 // Have we already loaded that image? Don't check for add-ons -- we always 509 // reload them. 510 if (type != B_ADD_ON_IMAGE) { 511 found = find_loaded_image_by_name(name, APP_OR_LIBRARY_TYPE); 512 513 if (found == NULL && type != B_APP_IMAGE && gProgramImage != NULL) { 514 // Special case for add-ons that link against the application 515 // executable, with the executable not having a soname set. 516 if (const char* lastSlash = strrchr(name, '/')) { 517 if (strcmp(gProgramImage->name, lastSlash + 1) == 0) 518 found = gProgramImage; 519 } 520 } 521 522 if (found) { 523 atomic_add(&found->ref_count, 1); 524 *_image = found; 525 KTRACE("rld: load_container(\"%s\", type: %d, %s: \"%s\") " 526 "already loaded", name, type, 527 runpath != NULL ? "runpath" : "rpath", runpath != NULL ? runpath : rpath); 528 return B_OK; 529 } 530 } 531 532 KTRACE("rld: load_container(\"%s\", type: %d, %s: \"%s\")", name, type, 533 runpath != NULL ? "runpath" : "rpath", runpath != NULL ? runpath : rpath); 534 535 strlcpy(path, name, sizeof(path)); 536 537 // find and open the file 538 fd = open_executable(path, type, rpath, runpath, get_program_path(), 539 requestingObjectPath, sSearchPathSubDir); 540 if (fd < 0) { 541 FATAL("Cannot open file %s (needed by %s): %s\n", name, requestingObjectPath, strerror(fd)); 542 KTRACE("rld: load_container(\"%s\"): failed to open file", name); 543 return fd; 544 } 545 546 // normalize the image path 547 status = _kern_normalize_path(path, true, path); 548 if (status != B_OK) 549 goto err1; 550 551 // Test again if this image has been registered already - this time, 552 // we can check the full path, not just its name as noted. 553 // You could end up loading an image twice with symbolic links, else. 554 if (type != B_ADD_ON_IMAGE) { 555 found = find_loaded_image_by_name(path, APP_OR_LIBRARY_TYPE); 556 if (found) { 557 atomic_add(&found->ref_count, 1); 558 *_image = found; 559 _kern_close(fd); 560 KTRACE("rld: load_container(\"%s\"): already loaded after all", 561 name); 562 return B_OK; 563 } 564 } 565 566 length = _kern_read(fd, 0, &eheader, sizeof(eheader)); 567 if (length != sizeof(eheader)) { 568 status = B_NOT_AN_EXECUTABLE; 569 FATAL("%s: Troubles reading ELF header\n", path); 570 goto err1; 571 } 572 573 status = parse_elf_header(&eheader, &pheaderSize, &sheaderSize); 574 if (status < B_OK) { 575 FATAL("%s: Incorrect ELF header\n", path); 576 goto err1; 577 } 578 579 // ToDo: what to do about this restriction?? 580 if (pheaderSize > (int)sizeof(pheaderBuffer)) { 581 FATAL("%s: Cannot handle program headers bigger than %lu\n", 582 path, sizeof(pheaderBuffer)); 583 status = B_UNSUPPORTED; 584 goto err1; 585 } 586 587 length = _kern_read(fd, eheader.e_phoff, pheaderBuffer, pheaderSize); 588 if (length != pheaderSize) { 589 FATAL("%s: Could not read program headers: %s\n", path, 590 strerror(length)); 591 status = B_BAD_DATA; 592 goto err1; 593 } 594 595 numRegions = count_regions(path, pheaderBuffer, eheader.e_phnum, 596 eheader.e_phentsize); 597 if (numRegions <= 0) { 598 FATAL("%s: Troubles parsing Program headers, numRegions = %" B_PRId32 599 "\n", path, numRegions); 600 status = B_BAD_DATA; 601 goto err1; 602 } 603 604 image = create_image(name, path, numRegions); 605 if (image == NULL) { 606 FATAL("%s: Failed to allocate image_t object\n", path); 607 status = B_NO_MEMORY; 608 goto err1; 609 } 610 611 status = parse_program_headers(image, pheaderBuffer, eheader.e_phnum, 612 eheader.e_phentsize); 613 if (status < B_OK) 614 goto err2; 615 616 if (!assert_dynamic_loadable(image)) { 617 FATAL("%s: Dynamic segment must be loadable (implementation " 618 "restriction)\n", image->path); 619 status = B_UNSUPPORTED; 620 goto err2; 621 } 622 623 status = map_image(fd, path, image, eheader.e_type == ET_EXEC); 624 if (status < B_OK) { 625 FATAL("%s: Could not map image: %s\n", image->path, strerror(status)); 626 status = B_ERROR; 627 goto err2; 628 } 629 630 if (!parse_dynamic_segment(image)) { 631 FATAL("%s: Troubles handling dynamic section\n", image->path); 632 status = B_BAD_DATA; 633 goto err3; 634 } 635 636 if (eheader.e_entry != 0) 637 image->entry_point = eheader.e_entry + image->regions[0].delta; 638 639 analyze_image_haiku_version_and_abi(fd, image, eheader, sheaderSize, 640 pheaderBuffer, sizeof(pheaderBuffer)); 641 642 // If sSearchPathSubDir is unset (meaning, this is the first image we're 643 // loading) we init the search path subdir if the compiler version doesn't 644 // match ours. 645 if (sSearchPathSubDir == NULL) { 646 #if __GNUC__ == 2 || (defined(_COMPAT_MODE) && !defined(__x86_64__)) 647 if ((image->abi & B_HAIKU_ABI_MAJOR) == B_HAIKU_ABI_GCC_4) 648 sSearchPathSubDir = "x86"; 649 #endif 650 #if __GNUC__ >= 4 || (defined(_COMPAT_MODE) && !defined(__x86_64__)) 651 if ((image->abi & B_HAIKU_ABI_MAJOR) == B_HAIKU_ABI_GCC_2) 652 sSearchPathSubDir = "x86_gcc2"; 653 #endif 654 } 655 656 set_abi_api_version(image->abi, image->api_version); 657 658 // init gcc version dependent image flags 659 // symbol resolution strategy 660 if (image->abi == B_HAIKU_ABI_GCC_2_ANCIENT) 661 image->find_undefined_symbol = find_undefined_symbol_beos; 662 663 // init version infos 664 status = init_image_version_infos(image); 665 666 image->type = type; 667 register_image(image, fd, path); 668 image_event(image, IMAGE_EVENT_LOADED); 669 670 _kern_close(fd); 671 672 enqueue_loaded_image(image); 673 674 *_image = image; 675 676 KTRACE("rld: load_container(\"%s\"): done: id: %" B_PRId32 " (ABI: %#" 677 B_PRIx32 ")", name, image->id, image->abi); 678 679 return B_OK; 680 681 err3: 682 unmap_image(image); 683 err2: 684 delete_image_struct(image); 685 err1: 686 _kern_close(fd); 687 688 KTRACE("rld: load_container(\"%s\"): failed: %s", name, 689 strerror(status)); 690 691 return status; 692 } 693