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