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