1 /* 2 * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com. 3 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. 4 * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. 5 * Distributed under the terms of the MIT License. 6 * 7 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 8 * Distributed under the terms of the NewOS License. 9 */ 10 11 /*! Contains the ELF loader */ 12 13 14 #include <elf.h> 15 16 #include <OS.h> 17 18 #include <unistd.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <stdio.h> 22 #include <ctype.h> 23 24 #include <algorithm> 25 26 #include <AutoDeleter.h> 27 #include <BytePointer.h> 28 #include <commpage.h> 29 #include <driver_settings.h> 30 #include <boot/kernel_args.h> 31 #include <debug.h> 32 #include <image_defs.h> 33 #include <kernel.h> 34 #include <kimage.h> 35 #include <syscalls.h> 36 #include <team.h> 37 #include <thread.h> 38 #include <runtime_loader.h> 39 #include <util/AutoLock.h> 40 #include <StackOrHeapArray.h> 41 #include <vfs.h> 42 #include <vm/vm.h> 43 #include <vm/vm_types.h> 44 #include <vm/VMAddressSpace.h> 45 #include <vm/VMArea.h> 46 47 #include <arch/cpu.h> 48 #include <arch/elf.h> 49 #include <elf_priv.h> 50 #include <boot/elf.h> 51 52 //#define TRACE_ELF 53 #ifdef TRACE_ELF 54 # define TRACE(x) dprintf x 55 #else 56 # define TRACE(x) ; 57 #endif 58 59 60 namespace { 61 62 #define IMAGE_HASH_SIZE 16 63 64 struct ImageHashDefinition { 65 typedef struct elf_image_info ValueType; 66 typedef image_id KeyType; 67 68 size_t Hash(ValueType* entry) const 69 { return HashKey(entry->id); } 70 ValueType*& GetLink(ValueType* entry) const 71 { return entry->next; } 72 73 size_t HashKey(KeyType key) const 74 { 75 return (size_t)key; 76 } 77 78 bool Compare(KeyType key, ValueType* entry) const 79 { 80 return key == entry->id; 81 } 82 }; 83 84 typedef BOpenHashTable<ImageHashDefinition> ImageHash; 85 86 } // namespace 87 88 89 #ifndef ELF32_COMPAT 90 91 static ImageHash *sImagesHash; 92 93 static struct elf_image_info *sKernelImage = NULL; 94 static mutex sImageMutex = MUTEX_INITIALIZER("kimages_lock"); 95 // guards sImagesHash 96 static mutex sImageLoadMutex = MUTEX_INITIALIZER("kimages_load_lock"); 97 // serializes loading/unloading add-ons locking order 98 // sImageLoadMutex -> sImageMutex 99 static bool sLoadElfSymbols = false; 100 static bool sInitialized = false; 101 102 103 static elf_sym *elf_find_symbol(struct elf_image_info *image, const char *name, 104 const elf_version_info *version, bool lookupDefault); 105 106 107 static void 108 unregister_elf_image(struct elf_image_info *image) 109 { 110 unregister_image(team_get_kernel_team(), image->id); 111 sImagesHash->Remove(image); 112 } 113 114 115 static void 116 register_elf_image(struct elf_image_info *image) 117 { 118 extended_image_info imageInfo; 119 120 memset(&imageInfo, 0, sizeof(imageInfo)); 121 imageInfo.basic_info.id = image->id; 122 imageInfo.basic_info.type = B_SYSTEM_IMAGE; 123 strlcpy(imageInfo.basic_info.name, image->name, 124 sizeof(imageInfo.basic_info.name)); 125 126 imageInfo.basic_info.text = (void *)image->text_region.start; 127 imageInfo.basic_info.text_size = image->text_region.size; 128 imageInfo.basic_info.data = (void *)image->data_region.start; 129 imageInfo.basic_info.data_size = image->data_region.size; 130 131 if (image->text_region.id >= 0) { 132 // evaluate the API/ABI version symbols 133 134 // Haiku API version 135 imageInfo.basic_info.api_version = 0; 136 elf_sym* symbol = elf_find_symbol(image, 137 B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE_NAME, NULL, true); 138 if (symbol != NULL && symbol->st_shndx != SHN_UNDEF 139 && symbol->st_value > 0 140 && symbol->Type() == STT_OBJECT 141 && symbol->st_size >= sizeof(uint32)) { 142 addr_t symbolAddress = symbol->st_value + image->text_region.delta; 143 if (symbolAddress >= image->text_region.start 144 && symbolAddress - image->text_region.start + sizeof(uint32) 145 <= image->text_region.size) { 146 imageInfo.basic_info.api_version = *(uint32*)symbolAddress; 147 } 148 } 149 150 // Haiku ABI 151 imageInfo.basic_info.abi = 0; 152 symbol = elf_find_symbol(image, 153 B_SHARED_OBJECT_HAIKU_ABI_VARIABLE_NAME, NULL, true); 154 if (symbol != NULL && symbol->st_shndx != SHN_UNDEF 155 && symbol->st_value > 0 156 && symbol->Type() == STT_OBJECT 157 && symbol->st_size >= sizeof(uint32)) { 158 addr_t symbolAddress = symbol->st_value + image->text_region.delta; 159 if (symbolAddress >= image->text_region.start 160 && symbolAddress - image->text_region.start + sizeof(uint32) 161 <= image->text_region.size) { 162 imageInfo.basic_info.api_version = *(uint32*)symbolAddress; 163 } 164 } 165 } else { 166 // in-memory image -- use the current values 167 imageInfo.basic_info.api_version = B_HAIKU_VERSION; 168 imageInfo.basic_info.abi = B_HAIKU_ABI; 169 } 170 171 image->id = register_image(team_get_kernel_team(), &imageInfo, 172 sizeof(imageInfo)); 173 sImagesHash->Insert(image); 174 } 175 176 177 /*! Note, you must lock the image mutex when you call this function. */ 178 static struct elf_image_info * 179 find_image_at_address(addr_t address) 180 { 181 #if KDEBUG 182 if (!debug_debugger_running()) 183 ASSERT_LOCKED_MUTEX(&sImageMutex); 184 #endif 185 186 ImageHash::Iterator iterator(sImagesHash); 187 188 // get image that may contain the address 189 190 while (iterator.HasNext()) { 191 struct elf_image_info* image = iterator.Next(); 192 if ((address >= image->text_region.start && address 193 <= (image->text_region.start + image->text_region.size)) 194 || (address >= image->data_region.start 195 && address 196 <= (image->data_region.start + image->data_region.size))) 197 return image; 198 } 199 200 return NULL; 201 } 202 203 204 static int 205 dump_address_info(int argc, char **argv) 206 { 207 const char *symbol, *imageName; 208 bool exactMatch; 209 addr_t address, baseAddress; 210 211 if (argc < 2) { 212 kprintf("usage: ls <address>\n"); 213 return 0; 214 } 215 216 address = strtoul(argv[1], NULL, 16); 217 218 status_t error; 219 220 if (IS_KERNEL_ADDRESS(address)) { 221 error = elf_debug_lookup_symbol_address(address, &baseAddress, &symbol, 222 &imageName, &exactMatch); 223 } else { 224 error = elf_debug_lookup_user_symbol_address( 225 debug_get_debugged_thread()->team, address, &baseAddress, &symbol, 226 &imageName, &exactMatch); 227 } 228 229 if (error == B_OK) { 230 kprintf("%p = %s + 0x%lx (%s)%s\n", (void*)address, symbol, 231 address - baseAddress, imageName, exactMatch ? "" : " (nearest)"); 232 } else 233 kprintf("There is no image loaded at this address!\n"); 234 235 return 0; 236 } 237 238 239 static struct elf_image_info * 240 find_image(image_id id) 241 { 242 return sImagesHash->Lookup(id); 243 } 244 245 246 static struct elf_image_info * 247 find_image_by_vnode(void *vnode) 248 { 249 MutexLocker locker(sImageMutex); 250 251 ImageHash::Iterator iterator(sImagesHash); 252 while (iterator.HasNext()) { 253 struct elf_image_info* image = iterator.Next(); 254 if (image->vnode == vnode) 255 return image; 256 } 257 258 return NULL; 259 } 260 261 262 #endif // ELF32_COMPAT 263 264 265 static struct elf_image_info * 266 create_image_struct() 267 { 268 struct elf_image_info *image 269 = (struct elf_image_info *)malloc(sizeof(struct elf_image_info)); 270 if (image == NULL) 271 return NULL; 272 273 memset(image, 0, sizeof(struct elf_image_info)); 274 275 image->text_region.id = -1; 276 image->data_region.id = -1; 277 image->ref_count = 1; 278 279 return image; 280 } 281 282 283 static void 284 delete_elf_image(struct elf_image_info *image) 285 { 286 if (image->text_region.id >= 0) 287 delete_area(image->text_region.id); 288 289 if (image->data_region.id >= 0) 290 delete_area(image->data_region.id); 291 292 if (image->vnode) 293 vfs_put_vnode(image->vnode); 294 295 free(image->versions); 296 free(image->debug_symbols); 297 free((void*)image->debug_string_table); 298 free(image->elf_header); 299 free(image->name); 300 free(image); 301 } 302 303 304 static uint32 305 elf_hash(const char *name) 306 { 307 uint32 hash = 0; 308 uint32 temp; 309 310 while (*name) { 311 hash = (hash << 4) + (uint8)*name++; 312 if ((temp = hash & 0xf0000000) != 0) 313 hash ^= temp >> 24; 314 hash &= ~temp; 315 } 316 return hash; 317 } 318 319 320 static const char * 321 get_symbol_type_string(elf_sym *symbol) 322 { 323 switch (symbol->Type()) { 324 case STT_FUNC: 325 return "func"; 326 case STT_OBJECT: 327 return " obj"; 328 case STT_FILE: 329 return "file"; 330 default: 331 return "----"; 332 } 333 } 334 335 336 static const char * 337 get_symbol_bind_string(elf_sym *symbol) 338 { 339 switch (symbol->Bind()) { 340 case STB_LOCAL: 341 return "loc "; 342 case STB_GLOBAL: 343 return "glob"; 344 case STB_WEAK: 345 return "weak"; 346 default: 347 return "----"; 348 } 349 } 350 351 352 #ifndef ELF32_COMPAT 353 354 355 /*! Searches a symbol (pattern) in all kernel images */ 356 static int 357 dump_symbol(int argc, char **argv) 358 { 359 if (argc != 2 || !strcmp(argv[1], "--help")) { 360 kprintf("usage: %s <symbol-name>\n", argv[0]); 361 return 0; 362 } 363 364 struct elf_image_info *image = NULL; 365 const char *pattern = argv[1]; 366 367 void* symbolAddress = NULL; 368 369 ImageHash::Iterator iterator(sImagesHash); 370 while (iterator.HasNext()) { 371 image = iterator.Next(); 372 if (image->num_debug_symbols > 0) { 373 // search extended debug symbol table (contains static symbols) 374 for (uint32 i = 0; i < image->num_debug_symbols; i++) { 375 elf_sym *symbol = &image->debug_symbols[i]; 376 const char *name = image->debug_string_table + symbol->st_name; 377 378 if (symbol->st_value > 0 && strstr(name, pattern) != 0) { 379 symbolAddress 380 = (void*)(symbol->st_value + image->text_region.delta); 381 kprintf("%p %5lu %s:%s\n", symbolAddress, symbol->st_size, 382 image->name, name); 383 } 384 } 385 } else { 386 // search standard symbol lookup table 387 for (uint32 i = 0; i < HASHTABSIZE(image); i++) { 388 for (uint32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF; 389 j = HASHCHAINS(image)[j]) { 390 elf_sym *symbol = &image->syms[j]; 391 const char *name = SYMNAME(image, symbol); 392 393 if (symbol->st_value > 0 && strstr(name, pattern) != 0) { 394 symbolAddress = (void*)(symbol->st_value 395 + image->text_region.delta); 396 kprintf("%p %5lu %s:%s\n", symbolAddress, 397 symbol->st_size, image->name, name); 398 } 399 } 400 } 401 } 402 } 403 404 if (symbolAddress != NULL) 405 set_debug_variable("_", (addr_t)symbolAddress); 406 407 return 0; 408 } 409 410 411 static int 412 dump_symbols(int argc, char **argv) 413 { 414 struct elf_image_info *image = NULL; 415 uint32 i; 416 417 // if the argument looks like a hex number, treat it as such 418 if (argc > 1) { 419 if (isdigit(argv[1][0])) { 420 addr_t num = strtoul(argv[1], NULL, 0); 421 422 if (IS_KERNEL_ADDRESS(num)) { 423 // find image at address 424 425 ImageHash::Iterator iterator(sImagesHash); 426 while (iterator.HasNext()) { 427 elf_image_info* current = iterator.Next(); 428 if (current->text_region.start <= num 429 && current->text_region.start 430 + current->text_region.size >= num) { 431 image = current; 432 break; 433 } 434 } 435 436 if (image == NULL) { 437 kprintf("No image covers %#" B_PRIxADDR " in the kernel!\n", 438 num); 439 } 440 } else { 441 image = sImagesHash->Lookup(num); 442 if (image == NULL) { 443 kprintf("image %#" B_PRIxADDR " doesn't exist in the " 444 "kernel!\n", num); 445 } 446 } 447 } else { 448 // look for image by name 449 ImageHash::Iterator iterator(sImagesHash); 450 while (iterator.HasNext()) { 451 elf_image_info* current = iterator.Next(); 452 if (!strcmp(current->name, argv[1])) { 453 image = current; 454 break; 455 } 456 } 457 458 if (image == NULL) 459 kprintf("No image \"%s\" found in kernel!\n", argv[1]); 460 } 461 } else { 462 kprintf("usage: %s image_name/image_id/address_in_image\n", argv[0]); 463 return 0; 464 } 465 466 if (image == NULL) 467 return -1; 468 469 // dump symbols 470 471 kprintf("Symbols of image %" B_PRId32 " \"%s\":\n", image->id, image->name); 472 kprintf("%-*s Type Size Name\n", B_PRINTF_POINTER_WIDTH, "Address"); 473 474 if (image->num_debug_symbols > 0) { 475 // search extended debug symbol table (contains static symbols) 476 for (i = 0; i < image->num_debug_symbols; i++) { 477 elf_sym *symbol = &image->debug_symbols[i]; 478 479 if (symbol->st_value == 0 || symbol->st_size 480 >= image->text_region.size + image->data_region.size) 481 continue; 482 483 kprintf("%0*lx %s/%s %5ld %s\n", B_PRINTF_POINTER_WIDTH, 484 symbol->st_value + image->text_region.delta, 485 get_symbol_type_string(symbol), get_symbol_bind_string(symbol), 486 symbol->st_size, image->debug_string_table + symbol->st_name); 487 } 488 } else { 489 int32 j; 490 491 // search standard symbol lookup table 492 for (i = 0; i < HASHTABSIZE(image); i++) { 493 for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; 494 j = HASHCHAINS(image)[j]) { 495 elf_sym *symbol = &image->syms[j]; 496 497 if (symbol->st_value == 0 || symbol->st_size 498 >= image->text_region.size + image->data_region.size) 499 continue; 500 501 kprintf("%08lx %s/%s %5ld %s\n", 502 symbol->st_value + image->text_region.delta, 503 get_symbol_type_string(symbol), 504 get_symbol_bind_string(symbol), 505 symbol->st_size, SYMNAME(image, symbol)); 506 } 507 } 508 } 509 510 return 0; 511 } 512 513 514 static void 515 dump_elf_region(struct elf_region *region, const char *name) 516 { 517 kprintf(" %s.id %" B_PRId32 "\n", name, region->id); 518 kprintf(" %s.start %#" B_PRIxADDR "\n", name, region->start); 519 kprintf(" %s.size %#" B_PRIxSIZE "\n", name, region->size); 520 kprintf(" %s.delta %ld\n", name, region->delta); 521 } 522 523 524 static void 525 dump_image_info(struct elf_image_info *image) 526 { 527 kprintf("elf_image_info at %p:\n", image); 528 kprintf(" next %p\n", image->next); 529 kprintf(" id %" B_PRId32 "\n", image->id); 530 dump_elf_region(&image->text_region, "text"); 531 dump_elf_region(&image->data_region, "data"); 532 kprintf(" dynamic_section %#" B_PRIxADDR "\n", image->dynamic_section); 533 kprintf(" needed %p\n", image->needed); 534 kprintf(" symhash %p\n", image->symhash); 535 kprintf(" syms %p\n", image->syms); 536 kprintf(" strtab %p\n", image->strtab); 537 kprintf(" rel %p\n", image->rel); 538 kprintf(" rel_len %#x\n", image->rel_len); 539 kprintf(" rela %p\n", image->rela); 540 kprintf(" rela_len %#x\n", image->rela_len); 541 kprintf(" pltrel %p\n", image->pltrel); 542 kprintf(" pltrel_len %#x\n", image->pltrel_len); 543 544 kprintf(" debug_symbols %p (%" B_PRIu32 ")\n", 545 image->debug_symbols, image->num_debug_symbols); 546 } 547 548 549 static int 550 dump_image(int argc, char **argv) 551 { 552 struct elf_image_info *image; 553 554 // if the argument looks like a hex number, treat it as such 555 if (argc > 1) { 556 addr_t num = strtoul(argv[1], NULL, 0); 557 558 if (IS_KERNEL_ADDRESS(num)) { 559 // semi-hack 560 dump_image_info((struct elf_image_info *)num); 561 } else { 562 image = sImagesHash->Lookup(num); 563 if (image == NULL) { 564 kprintf("image %#" B_PRIxADDR " doesn't exist in the kernel!\n", 565 num); 566 } else 567 dump_image_info(image); 568 } 569 return 0; 570 } 571 572 kprintf("loaded kernel images:\n"); 573 574 ImageHash::Iterator iterator(sImagesHash); 575 576 while (iterator.HasNext()) { 577 image = iterator.Next(); 578 kprintf("%p (%" B_PRId32 ") %s\n", image, image->id, image->name); 579 } 580 581 return 0; 582 } 583 584 585 // Currently unused 586 /*static 587 void dump_symbol(struct elf_image_info *image, elf_sym *sym) 588 { 589 590 kprintf("symbol at %p, in image %p\n", sym, image); 591 592 kprintf(" name index %d, '%s'\n", sym->st_name, SYMNAME(image, sym)); 593 kprintf(" st_value 0x%x\n", sym->st_value); 594 kprintf(" st_size %d\n", sym->st_size); 595 kprintf(" st_info 0x%x\n", sym->st_info); 596 kprintf(" st_other 0x%x\n", sym->st_other); 597 kprintf(" st_shndx %d\n", sym->st_shndx); 598 } 599 */ 600 601 602 #endif // ELF32_COMPAT 603 604 605 static elf_sym * 606 elf_find_symbol(struct elf_image_info *image, const char *name, 607 const elf_version_info *lookupVersion, bool lookupDefault) 608 { 609 if (image->dynamic_section == 0 || HASHTABSIZE(image) == 0) 610 return NULL; 611 612 elf_sym* versionedSymbol = NULL; 613 uint32 versionedSymbolCount = 0; 614 615 uint32 hash = elf_hash(name) % HASHTABSIZE(image); 616 for (uint32 i = HASHBUCKETS(image)[hash]; i != STN_UNDEF; 617 i = HASHCHAINS(image)[i]) { 618 elf_sym* symbol = &image->syms[i]; 619 620 // consider only symbols with the right name and binding 621 if (symbol->st_shndx == SHN_UNDEF 622 || ((symbol->Bind() != STB_GLOBAL) && (symbol->Bind() != STB_WEAK)) 623 || strcmp(SYMNAME(image, symbol), name) != 0) { 624 continue; 625 } 626 627 // check the version 628 629 // Handle the simple cases -- the image doesn't have version 630 // information -- first. 631 if (image->symbol_versions == NULL) { 632 if (lookupVersion == NULL) { 633 // No specific symbol version was requested either, so the 634 // symbol is just fine. 635 return symbol; 636 } 637 638 // A specific version is requested. Since the only possible 639 // dependency is the kernel itself, the add-on was obviously linked 640 // against a newer kernel. 641 dprintf("Kernel add-on requires version support, but the kernel " 642 "is too old.\n"); 643 return NULL; 644 } 645 646 // The image has version information. Let's see what we've got. 647 uint32 versionID = image->symbol_versions[i]; 648 uint32 versionIndex = VER_NDX(versionID); 649 elf_version_info& version = image->versions[versionIndex]; 650 651 // skip local versions 652 if (versionIndex == VER_NDX_LOCAL) 653 continue; 654 655 if (lookupVersion != NULL) { 656 // a specific version is requested 657 658 // compare the versions 659 if (version.hash == lookupVersion->hash 660 && strcmp(version.name, lookupVersion->name) == 0) { 661 // versions match 662 return symbol; 663 } 664 665 // The versions don't match. We're still fine with the 666 // base version, if it is public and we're not looking for 667 // the default version. 668 if ((versionID & VER_NDX_FLAG_HIDDEN) == 0 669 && versionIndex == VER_NDX_GLOBAL 670 && !lookupDefault) { 671 // TODO: Revise the default version case! That's how 672 // FreeBSD implements it, but glibc doesn't handle it 673 // specially. 674 return symbol; 675 } 676 } else { 677 // No specific version requested, but the image has version 678 // information. This can happen in either of these cases: 679 // 680 // * The dependent object was linked against an older version 681 // of the now versioned dependency. 682 // * The symbol is looked up via find_image_symbol() or dlsym(). 683 // 684 // In the first case we return the base version of the symbol 685 // (VER_NDX_GLOBAL or VER_NDX_INITIAL), or, if that doesn't 686 // exist, the unique, non-hidden versioned symbol. 687 // 688 // In the second case we want to return the public default 689 // version of the symbol. The handling is pretty similar to the 690 // first case, with the exception that we treat VER_NDX_INITIAL 691 // as regular version. 692 693 // VER_NDX_GLOBAL is always good, VER_NDX_INITIAL is fine, if 694 // we don't look for the default version. 695 if (versionIndex == VER_NDX_GLOBAL 696 || (!lookupDefault && versionIndex == VER_NDX_INITIAL)) { 697 return symbol; 698 } 699 700 // If not hidden, remember the version -- we'll return it, if 701 // it is the only one. 702 if ((versionID & VER_NDX_FLAG_HIDDEN) == 0) { 703 versionedSymbolCount++; 704 versionedSymbol = symbol; 705 } 706 } 707 } 708 709 return versionedSymbolCount == 1 ? versionedSymbol : NULL; 710 } 711 712 713 static status_t 714 elf_parse_dynamic_section(struct elf_image_info *image) 715 { 716 elf_dyn *d; 717 ssize_t neededOffset = -1; 718 719 TRACE(("top of elf_parse_dynamic_section\n")); 720 721 image->symhash = 0; 722 image->syms = 0; 723 image->strtab = 0; 724 725 d = (elf_dyn *)image->dynamic_section; 726 if (!d) 727 return B_ERROR; 728 729 for (int32 i = 0; d[i].d_tag != DT_NULL; i++) { 730 switch (d[i].d_tag) { 731 case DT_NEEDED: 732 neededOffset = d[i].d_un.d_ptr + image->text_region.delta; 733 break; 734 case DT_HASH: 735 image->symhash = (uint32 *)(d[i].d_un.d_ptr 736 + image->text_region.delta); 737 break; 738 case DT_STRTAB: 739 image->strtab = (char *)(d[i].d_un.d_ptr 740 + image->text_region.delta); 741 break; 742 case DT_SYMTAB: 743 image->syms = (elf_sym *)(d[i].d_un.d_ptr 744 + image->text_region.delta); 745 break; 746 case DT_REL: 747 image->rel = (elf_rel *)(d[i].d_un.d_ptr 748 + image->text_region.delta); 749 break; 750 case DT_RELSZ: 751 image->rel_len = d[i].d_un.d_val; 752 break; 753 case DT_RELA: 754 image->rela = (elf_rela *)(d[i].d_un.d_ptr 755 + image->text_region.delta); 756 break; 757 case DT_RELASZ: 758 image->rela_len = d[i].d_un.d_val; 759 break; 760 case DT_JMPREL: 761 image->pltrel = (elf_rel *)(d[i].d_un.d_ptr 762 + image->text_region.delta); 763 break; 764 case DT_PLTRELSZ: 765 image->pltrel_len = d[i].d_un.d_val; 766 break; 767 case DT_PLTREL: 768 image->pltrel_type = d[i].d_un.d_val; 769 break; 770 case DT_VERSYM: 771 image->symbol_versions = (elf_versym*) 772 (d[i].d_un.d_ptr + image->text_region.delta); 773 break; 774 case DT_VERDEF: 775 image->version_definitions = (elf_verdef*) 776 (d[i].d_un.d_ptr + image->text_region.delta); 777 break; 778 case DT_VERDEFNUM: 779 image->num_version_definitions = d[i].d_un.d_val; 780 break; 781 case DT_VERNEED: 782 image->needed_versions = (elf_verneed*) 783 (d[i].d_un.d_ptr + image->text_region.delta); 784 break; 785 case DT_VERNEEDNUM: 786 image->num_needed_versions = d[i].d_un.d_val; 787 break; 788 case DT_SYMBOLIC: 789 image->symbolic = true; 790 break; 791 case DT_FLAGS: 792 { 793 uint32 flags = d[i].d_un.d_val; 794 if ((flags & DF_SYMBOLIC) != 0) 795 image->symbolic = true; 796 break; 797 } 798 799 default: 800 continue; 801 } 802 } 803 804 // lets make sure we found all the required sections 805 if (!image->symhash || !image->syms || !image->strtab) 806 return B_ERROR; 807 808 TRACE(("needed_offset = %ld\n", neededOffset)); 809 810 if (neededOffset >= 0) 811 image->needed = STRING(image, neededOffset); 812 813 return B_OK; 814 } 815 816 817 #ifndef ELF32_COMPAT 818 819 820 static status_t 821 assert_defined_image_version(elf_image_info* dependentImage, 822 elf_image_info* image, const elf_version_info& neededVersion, bool weak) 823 { 824 // If the image doesn't have version definitions, we print a warning and 825 // succeed. Weird, but that's how glibc does it. Not unlikely we'll fail 826 // later when resolving versioned symbols. 827 if (image->version_definitions == NULL) { 828 dprintf("%s: No version information available (required by %s)\n", 829 image->name, dependentImage->name); 830 return B_OK; 831 } 832 833 // iterate through the defined versions to find the given one 834 BytePointer<elf_verdef> definition(image->version_definitions); 835 for (uint32 i = 0; i < image->num_version_definitions; i++) { 836 uint32 versionIndex = VER_NDX(definition->vd_ndx); 837 elf_version_info& info = image->versions[versionIndex]; 838 839 if (neededVersion.hash == info.hash 840 && strcmp(neededVersion.name, info.name) == 0) { 841 return B_OK; 842 } 843 844 definition += definition->vd_next; 845 } 846 847 // version not found -- fail, if not weak 848 if (!weak) { 849 dprintf("%s: version \"%s\" not found (required by %s)\n", image->name, 850 neededVersion.name, dependentImage->name); 851 return B_MISSING_SYMBOL; 852 } 853 854 return B_OK; 855 } 856 857 858 static status_t 859 init_image_version_infos(elf_image_info* image) 860 { 861 // First find out how many version infos we need -- i.e. get the greatest 862 // version index from the defined and needed versions (they use the same 863 // index namespace). 864 uint32 maxIndex = 0; 865 866 if (image->version_definitions != NULL) { 867 BytePointer<elf_verdef> definition(image->version_definitions); 868 for (uint32 i = 0; i < image->num_version_definitions; i++) { 869 if (definition->vd_version != 1) { 870 dprintf("Unsupported version definition revision: %u\n", 871 definition->vd_version); 872 return B_BAD_VALUE; 873 } 874 875 uint32 versionIndex = VER_NDX(definition->vd_ndx); 876 if (versionIndex > maxIndex) 877 maxIndex = versionIndex; 878 879 definition += definition->vd_next; 880 } 881 } 882 883 if (image->needed_versions != NULL) { 884 BytePointer<elf_verneed> needed(image->needed_versions); 885 for (uint32 i = 0; i < image->num_needed_versions; i++) { 886 if (needed->vn_version != 1) { 887 dprintf("Unsupported version needed revision: %u\n", 888 needed->vn_version); 889 return B_BAD_VALUE; 890 } 891 892 BytePointer<elf_vernaux> vernaux(needed + needed->vn_aux); 893 for (uint32 k = 0; k < needed->vn_cnt; k++) { 894 uint32 versionIndex = VER_NDX(vernaux->vna_other); 895 if (versionIndex > maxIndex) 896 maxIndex = versionIndex; 897 898 vernaux += vernaux->vna_next; 899 } 900 901 needed += needed->vn_next; 902 } 903 } 904 905 if (maxIndex == 0) 906 return B_OK; 907 908 // allocate the version infos 909 image->versions 910 = (elf_version_info*)malloc(sizeof(elf_version_info) * (maxIndex + 1)); 911 if (image->versions == NULL) { 912 dprintf("Memory shortage in init_image_version_infos()\n"); 913 return B_NO_MEMORY; 914 } 915 image->num_versions = maxIndex + 1; 916 917 // init the version infos 918 919 // version definitions 920 if (image->version_definitions != NULL) { 921 BytePointer<elf_verdef> definition(image->version_definitions); 922 for (uint32 i = 0; i < image->num_version_definitions; i++) { 923 if (definition->vd_cnt > 0 924 && (definition->vd_flags & VER_FLG_BASE) == 0) { 925 BytePointer<elf_verdaux> verdaux(definition 926 + definition->vd_aux); 927 928 uint32 versionIndex = VER_NDX(definition->vd_ndx); 929 elf_version_info& info = image->versions[versionIndex]; 930 info.hash = definition->vd_hash; 931 info.name = STRING(image, verdaux->vda_name); 932 info.file_name = NULL; 933 } 934 935 definition += definition->vd_next; 936 } 937 } 938 939 // needed versions 940 if (image->needed_versions != NULL) { 941 BytePointer<elf_verneed> needed(image->needed_versions); 942 for (uint32 i = 0; i < image->num_needed_versions; i++) { 943 const char* fileName = STRING(image, needed->vn_file); 944 945 BytePointer<elf_vernaux> vernaux(needed + needed->vn_aux); 946 for (uint32 k = 0; k < needed->vn_cnt; k++) { 947 uint32 versionIndex = VER_NDX(vernaux->vna_other); 948 elf_version_info& info = image->versions[versionIndex]; 949 info.hash = vernaux->vna_hash; 950 info.name = STRING(image, vernaux->vna_name); 951 info.file_name = fileName; 952 953 vernaux += vernaux->vna_next; 954 } 955 956 needed += needed->vn_next; 957 } 958 } 959 960 return B_OK; 961 } 962 963 964 static status_t 965 check_needed_image_versions(elf_image_info* image) 966 { 967 if (image->needed_versions == NULL) 968 return B_OK; 969 970 BytePointer<elf_verneed> needed(image->needed_versions); 971 for (uint32 i = 0; i < image->num_needed_versions; i++) { 972 elf_image_info* dependency = sKernelImage; 973 974 BytePointer<elf_vernaux> vernaux(needed + needed->vn_aux); 975 for (uint32 k = 0; k < needed->vn_cnt; k++) { 976 uint32 versionIndex = VER_NDX(vernaux->vna_other); 977 elf_version_info& info = image->versions[versionIndex]; 978 979 status_t error = assert_defined_image_version(image, dependency, 980 info, (vernaux->vna_flags & VER_FLG_WEAK) != 0); 981 if (error != B_OK) 982 return error; 983 984 vernaux += vernaux->vna_next; 985 } 986 987 needed += needed->vn_next; 988 } 989 990 return B_OK; 991 } 992 993 994 #endif // ELF32_COMPAT 995 996 997 /*! Resolves the \a symbol by linking against \a sharedImage if necessary. 998 Returns the resolved symbol's address in \a _symbolAddress. 999 */ 1000 status_t 1001 elf_resolve_symbol(struct elf_image_info *image, elf_sym *symbol, 1002 struct elf_image_info *sharedImage, elf_addr *_symbolAddress) 1003 { 1004 // Local symbols references are always resolved to the given symbol. 1005 if (symbol->Bind() == STB_LOCAL) { 1006 *_symbolAddress = symbol->st_value + image->text_region.delta; 1007 return B_OK; 1008 } 1009 1010 // Non-local symbols we try to resolve to the kernel image first. Unless 1011 // the image is linked symbolically, then vice versa. 1012 elf_image_info* firstImage = sharedImage; 1013 elf_image_info* secondImage = image; 1014 if (image->symbolic) 1015 std::swap(firstImage, secondImage); 1016 1017 const char *symbolName = SYMNAME(image, symbol); 1018 1019 // get the version info 1020 const elf_version_info* versionInfo = NULL; 1021 if (image->symbol_versions != NULL) { 1022 uint32 index = symbol - image->syms; 1023 uint32 versionIndex = VER_NDX(image->symbol_versions[index]); 1024 if (versionIndex >= VER_NDX_INITIAL) 1025 versionInfo = image->versions + versionIndex; 1026 } 1027 1028 // find the symbol 1029 elf_image_info* foundImage = firstImage; 1030 elf_sym* foundSymbol = elf_find_symbol(firstImage, symbolName, versionInfo, 1031 false); 1032 if (foundSymbol == NULL 1033 || foundSymbol->Bind() == STB_WEAK) { 1034 // Not found or found a weak definition -- try to resolve in the other 1035 // image. 1036 elf_sym* secondSymbol = elf_find_symbol(secondImage, symbolName, 1037 versionInfo, false); 1038 // If we found a symbol -- take it in case we didn't have a symbol 1039 // before or the new symbol is not weak. 1040 if (secondSymbol != NULL 1041 && (foundSymbol == NULL 1042 || secondSymbol->Bind() != STB_WEAK)) { 1043 foundImage = secondImage; 1044 foundSymbol = secondSymbol; 1045 } 1046 } 1047 1048 if (foundSymbol == NULL) { 1049 // Weak undefined symbols get a value of 0, if unresolved. 1050 if (symbol->Bind() == STB_WEAK) { 1051 *_symbolAddress = 0; 1052 return B_OK; 1053 } 1054 1055 dprintf("\"%s\": could not resolve symbol '%s'\n", image->name, 1056 symbolName); 1057 return B_MISSING_SYMBOL; 1058 } 1059 1060 // make sure they're the same type 1061 if (symbol->Type() != foundSymbol->Type()) { 1062 dprintf("elf_resolve_symbol: found symbol '%s' in image '%s' " 1063 "(requested by image '%s') but wrong type (%d vs. %d)\n", 1064 symbolName, foundImage->name, image->name, 1065 foundSymbol->Type(), symbol->Type()); 1066 return B_MISSING_SYMBOL; 1067 } 1068 1069 *_symbolAddress = foundSymbol->st_value + foundImage->text_region.delta; 1070 return B_OK; 1071 } 1072 1073 1074 /*! Until we have shared library support, just this links against the kernel */ 1075 static int 1076 elf_relocate(struct elf_image_info* image, struct elf_image_info* resolveImage) 1077 { 1078 int status = B_NO_ERROR; 1079 1080 TRACE(("elf_relocate(%p (\"%s\"))\n", image, image->name)); 1081 1082 // deal with the rels first 1083 if (image->rel) { 1084 TRACE(("total %i rel relocs\n", image->rel_len / (int)sizeof(elf_rel))); 1085 1086 status = arch_elf_relocate_rel(image, resolveImage, image->rel, 1087 image->rel_len); 1088 if (status < B_OK) 1089 return status; 1090 } 1091 1092 if (image->pltrel) { 1093 if (image->pltrel_type == DT_REL) { 1094 TRACE(("total %i plt-relocs\n", 1095 image->pltrel_len / (int)sizeof(elf_rel))); 1096 status = arch_elf_relocate_rel(image, resolveImage, image->pltrel, 1097 image->pltrel_len); 1098 } else { 1099 TRACE(("total %i plt-relocs\n", 1100 image->pltrel_len / (int)sizeof(elf_rela))); 1101 status = arch_elf_relocate_rela(image, resolveImage, 1102 (elf_rela *)image->pltrel, image->pltrel_len); 1103 } 1104 if (status < B_OK) 1105 return status; 1106 } 1107 1108 if (image->rela) { 1109 TRACE(("total %i rel relocs\n", 1110 image->rela_len / (int)sizeof(elf_rela))); 1111 1112 status = arch_elf_relocate_rela(image, resolveImage, image->rela, 1113 image->rela_len); 1114 if (status < B_OK) 1115 return status; 1116 } 1117 1118 return status; 1119 } 1120 1121 1122 static int 1123 verify_eheader(elf_ehdr *elfHeader) 1124 { 1125 if (memcmp(elfHeader->e_ident, ELFMAG, 4) != 0) 1126 return B_NOT_AN_EXECUTABLE; 1127 1128 if (elfHeader->e_ident[4] != ELF_CLASS) 1129 return B_NOT_AN_EXECUTABLE; 1130 1131 if (elfHeader->e_phoff == 0) 1132 return B_NOT_AN_EXECUTABLE; 1133 1134 if (elfHeader->e_phentsize < sizeof(elf_phdr)) 1135 return B_NOT_AN_EXECUTABLE; 1136 1137 return 0; 1138 } 1139 1140 1141 #ifndef ELF32_COMPAT 1142 1143 1144 static void 1145 unload_elf_image(struct elf_image_info *image) 1146 { 1147 if (atomic_add(&image->ref_count, -1) > 1) 1148 return; 1149 1150 TRACE(("unload image %" B_PRId32 ", %s\n", image->id, image->name)); 1151 1152 unregister_elf_image(image); 1153 delete_elf_image(image); 1154 } 1155 1156 1157 static status_t 1158 load_elf_symbol_table(int fd, struct elf_image_info *image) 1159 { 1160 elf_ehdr *elfHeader = image->elf_header; 1161 elf_sym *symbolTable = NULL; 1162 elf_shdr *stringHeader = NULL; 1163 uint32 numSymbols = 0; 1164 char *stringTable; 1165 status_t status; 1166 ssize_t length; 1167 int32 i; 1168 1169 // get section headers 1170 1171 ssize_t size = elfHeader->e_shnum * elfHeader->e_shentsize; 1172 elf_shdr *sectionHeaders = (elf_shdr *)malloc(size); 1173 if (sectionHeaders == NULL) { 1174 dprintf("error allocating space for section headers\n"); 1175 return B_NO_MEMORY; 1176 } 1177 1178 length = read_pos(fd, elfHeader->e_shoff, sectionHeaders, size); 1179 if (length < size) { 1180 TRACE(("error reading in program headers\n")); 1181 status = B_ERROR; 1182 goto error1; 1183 } 1184 1185 // find symbol table in section headers 1186 1187 for (i = 0; i < elfHeader->e_shnum; i++) { 1188 if (sectionHeaders[i].sh_type == SHT_SYMTAB) { 1189 stringHeader = §ionHeaders[sectionHeaders[i].sh_link]; 1190 1191 if (stringHeader->sh_type != SHT_STRTAB) { 1192 TRACE(("doesn't link to string table\n")); 1193 status = B_BAD_DATA; 1194 goto error1; 1195 } 1196 1197 // read in symbol table 1198 size = sectionHeaders[i].sh_size; 1199 symbolTable = (elf_sym *)malloc(size); 1200 if (symbolTable == NULL) { 1201 status = B_NO_MEMORY; 1202 goto error1; 1203 } 1204 1205 length 1206 = read_pos(fd, sectionHeaders[i].sh_offset, symbolTable, size); 1207 if (length < size) { 1208 TRACE(("error reading in symbol table\n")); 1209 status = B_ERROR; 1210 goto error2; 1211 } 1212 1213 numSymbols = size / sizeof(elf_sym); 1214 break; 1215 } 1216 } 1217 1218 if (symbolTable == NULL) { 1219 TRACE(("no symbol table\n")); 1220 status = B_BAD_VALUE; 1221 goto error1; 1222 } 1223 1224 // read in string table 1225 1226 stringTable = (char *)malloc(size = stringHeader->sh_size); 1227 if (stringTable == NULL) { 1228 status = B_NO_MEMORY; 1229 goto error2; 1230 } 1231 1232 length = read_pos(fd, stringHeader->sh_offset, stringTable, size); 1233 if (length < size) { 1234 TRACE(("error reading in string table\n")); 1235 status = B_ERROR; 1236 goto error3; 1237 } 1238 1239 TRACE(("loaded %" B_PRId32 " debug symbols\n", numSymbols)); 1240 1241 // insert tables into image 1242 image->debug_symbols = symbolTable; 1243 image->num_debug_symbols = numSymbols; 1244 image->debug_string_table = stringTable; 1245 1246 free(sectionHeaders); 1247 return B_OK; 1248 1249 error3: 1250 free(stringTable); 1251 error2: 1252 free(symbolTable); 1253 error1: 1254 free(sectionHeaders); 1255 1256 return status; 1257 } 1258 1259 1260 static status_t 1261 insert_preloaded_image(preloaded_elf_image *preloadedImage, bool kernel) 1262 { 1263 status_t status; 1264 1265 status = verify_eheader(&preloadedImage->elf_header); 1266 if (status != B_OK) 1267 return status; 1268 1269 elf_image_info *image = create_image_struct(); 1270 if (image == NULL) 1271 return B_NO_MEMORY; 1272 1273 image->name = strdup(preloadedImage->name); 1274 image->dynamic_section = preloadedImage->dynamic_section.start; 1275 1276 image->text_region.id = preloadedImage->text_region.id; 1277 image->text_region.start = preloadedImage->text_region.start; 1278 image->text_region.size = preloadedImage->text_region.size; 1279 image->text_region.delta = preloadedImage->text_region.delta; 1280 image->data_region.id = preloadedImage->data_region.id; 1281 image->data_region.start = preloadedImage->data_region.start; 1282 image->data_region.size = preloadedImage->data_region.size; 1283 image->data_region.delta = preloadedImage->data_region.delta; 1284 1285 status = elf_parse_dynamic_section(image); 1286 if (status != B_OK) 1287 goto error1; 1288 1289 status = init_image_version_infos(image); 1290 if (status != B_OK) 1291 goto error1; 1292 1293 if (!kernel) { 1294 status = check_needed_image_versions(image); 1295 if (status != B_OK) 1296 goto error1; 1297 1298 status = elf_relocate(image, sKernelImage); 1299 if (status != B_OK) 1300 goto error1; 1301 } else 1302 sKernelImage = image; 1303 1304 // copy debug symbols to the kernel heap 1305 if (preloadedImage->debug_symbols != NULL) { 1306 int32 debugSymbolsSize = sizeof(elf_sym) 1307 * preloadedImage->num_debug_symbols; 1308 image->debug_symbols = (elf_sym*)malloc(debugSymbolsSize); 1309 if (image->debug_symbols != NULL) { 1310 memcpy(image->debug_symbols, preloadedImage->debug_symbols, 1311 debugSymbolsSize); 1312 } 1313 } 1314 image->num_debug_symbols = preloadedImage->num_debug_symbols; 1315 1316 // copy debug string table to the kernel heap 1317 if (preloadedImage->debug_string_table != NULL) { 1318 image->debug_string_table = (char*)malloc( 1319 preloadedImage->debug_string_table_size); 1320 if (image->debug_string_table != NULL) { 1321 memcpy((void*)image->debug_string_table, 1322 preloadedImage->debug_string_table, 1323 preloadedImage->debug_string_table_size); 1324 } 1325 } 1326 1327 register_elf_image(image); 1328 preloadedImage->id = image->id; 1329 // modules_init() uses this information to get the preloaded images 1330 1331 // we now no longer need to write to the text area anymore 1332 set_area_protection(image->text_region.id, 1333 B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA); 1334 1335 return B_OK; 1336 1337 error1: 1338 delete_elf_image(image); 1339 1340 preloadedImage->id = -1; 1341 1342 return status; 1343 } 1344 1345 1346 // #pragma mark - userland symbol lookup 1347 1348 1349 class UserSymbolLookup { 1350 public: 1351 static UserSymbolLookup& Default() 1352 { 1353 return sLookup; 1354 } 1355 1356 status_t Init(Team* team) 1357 { 1358 // find the runtime loader debug area 1359 VMArea* area; 1360 for (VMAddressSpace::AreaIterator it 1361 = team->address_space->GetAreaIterator(); 1362 (area = it.Next()) != NULL;) { 1363 if (strcmp(area->name, RUNTIME_LOADER_DEBUG_AREA_NAME) == 0) 1364 break; 1365 } 1366 1367 if (area == NULL) 1368 return B_ERROR; 1369 1370 // copy the runtime loader data structure 1371 if (!_Read((runtime_loader_debug_area*)area->Base(), fDebugArea)) 1372 return B_BAD_ADDRESS; 1373 1374 fTeam = team; 1375 return B_OK; 1376 } 1377 1378 status_t LookupSymbolAddress(addr_t address, addr_t *_baseAddress, 1379 const char **_symbolName, const char **_imageName, bool *_exactMatch) 1380 { 1381 // Note, that this function doesn't find all symbols that we would like 1382 // to find. E.g. static functions do not appear in the symbol table 1383 // as function symbols, but as sections without name and size. The 1384 // .symtab section together with the .strtab section, which apparently 1385 // differ from the tables referred to by the .dynamic section, also 1386 // contain proper names and sizes for those symbols. Therefore, to get 1387 // completely satisfying results, we would need to read those tables 1388 // from the shared object. 1389 1390 // get the image for the address 1391 image_t image; 1392 status_t error = _FindImageAtAddress(address, image); 1393 if (error != B_OK) { 1394 // commpage requires special treatment since kernel stores symbol 1395 // information 1396 addr_t commPageAddress = (addr_t)fTeam->commpage_address; 1397 if (address >= commPageAddress 1398 && address < commPageAddress + COMMPAGE_SIZE) { 1399 if (*_imageName) 1400 *_imageName = "commpage"; 1401 address -= (addr_t)commPageAddress; 1402 error = elf_debug_lookup_symbol_address(address, _baseAddress, 1403 _symbolName, NULL, _exactMatch); 1404 if (_baseAddress) 1405 *_baseAddress += (addr_t)fTeam->commpage_address; 1406 } 1407 return error; 1408 } 1409 1410 strlcpy(fImageName, image.name, sizeof(fImageName)); 1411 1412 // symbol hash table size 1413 uint32 hashTabSize; 1414 if (!_Read(image.symhash, hashTabSize)) 1415 return B_BAD_ADDRESS; 1416 1417 // remote pointers to hash buckets and chains 1418 const uint32* hashBuckets = image.symhash + 2; 1419 const uint32* hashChains = image.symhash + 2 + hashTabSize; 1420 1421 const elf_region_t& textRegion = image.regions[0]; 1422 1423 // search the image for the symbol 1424 elf_sym symbolFound; 1425 addr_t deltaFound = INT_MAX; 1426 bool exactMatch = false; 1427 1428 // to get rid of the erroneous "uninitialized" warnings 1429 symbolFound.st_name = 0; 1430 symbolFound.st_value = 0; 1431 1432 for (uint32 i = 0; i < hashTabSize; i++) { 1433 uint32 bucket; 1434 if (!_Read(&hashBuckets[i], bucket)) 1435 return B_BAD_ADDRESS; 1436 1437 for (uint32 j = bucket; j != STN_UNDEF; 1438 _Read(&hashChains[j], j) ? 0 : j = STN_UNDEF) { 1439 1440 elf_sym symbol; 1441 if (!_Read(image.syms + j, symbol)) 1442 continue; 1443 1444 // The symbol table contains not only symbols referring to 1445 // functions and data symbols within the shared object, but also 1446 // referenced symbols of other shared objects, as well as 1447 // section and file references. We ignore everything but 1448 // function and data symbols that have an st_value != 0 (0 1449 // seems to be an indication for a symbol defined elsewhere 1450 // -- couldn't verify that in the specs though). 1451 if ((symbol.Type() != STT_FUNC && symbol.Type() != STT_OBJECT) 1452 || symbol.st_value == 0 1453 || symbol.st_value + symbol.st_size + textRegion.delta 1454 > textRegion.vmstart + textRegion.size) { 1455 continue; 1456 } 1457 1458 // skip symbols starting after the given address 1459 addr_t symbolAddress = symbol.st_value + textRegion.delta; 1460 if (symbolAddress > address) 1461 continue; 1462 addr_t symbolDelta = address - symbolAddress; 1463 1464 if (symbolDelta < deltaFound) { 1465 deltaFound = symbolDelta; 1466 symbolFound = symbol; 1467 1468 if (symbolDelta >= 0 && symbolDelta < symbol.st_size) { 1469 // exact match 1470 exactMatch = true; 1471 break; 1472 } 1473 } 1474 } 1475 } 1476 1477 if (_imageName) 1478 *_imageName = fImageName; 1479 1480 if (_symbolName) { 1481 *_symbolName = NULL; 1482 1483 if (deltaFound < INT_MAX) { 1484 if (_ReadString(image, symbolFound.st_name, fSymbolName, 1485 sizeof(fSymbolName))) { 1486 *_symbolName = fSymbolName; 1487 } else { 1488 // we can't get its name, so forget the symbol 1489 deltaFound = INT_MAX; 1490 } 1491 } 1492 } 1493 1494 if (_baseAddress) { 1495 if (deltaFound < INT_MAX) 1496 *_baseAddress = symbolFound.st_value + textRegion.delta; 1497 else 1498 *_baseAddress = textRegion.vmstart; 1499 } 1500 1501 if (_exactMatch) 1502 *_exactMatch = exactMatch; 1503 1504 return B_OK; 1505 } 1506 1507 status_t _FindImageAtAddress(addr_t address, image_t& image) 1508 { 1509 image_queue_t imageQueue; 1510 if (!_Read(fDebugArea.loaded_images, imageQueue)) 1511 return B_BAD_ADDRESS; 1512 1513 image_t* imageAddress = imageQueue.head; 1514 while (imageAddress != NULL) { 1515 if (!_Read(imageAddress, image)) 1516 return B_BAD_ADDRESS; 1517 1518 if (image.regions[0].vmstart <= address 1519 && address < image.regions[0].vmstart + image.regions[0].size) { 1520 return B_OK; 1521 } 1522 1523 imageAddress = image.next; 1524 } 1525 1526 return B_ENTRY_NOT_FOUND; 1527 } 1528 1529 bool _ReadString(const image_t& image, uint32 offset, char* buffer, 1530 size_t bufferSize) 1531 { 1532 const char* address = image.strtab + offset; 1533 1534 if (!IS_USER_ADDRESS(address)) 1535 return false; 1536 1537 if (debug_debugger_running()) { 1538 return debug_strlcpy(B_CURRENT_TEAM, buffer, address, bufferSize) 1539 >= 0; 1540 } 1541 return user_strlcpy(buffer, address, bufferSize) >= 0; 1542 } 1543 1544 template<typename T> bool _Read(const T* address, T& data); 1545 // gcc 2.95.3 doesn't like it defined in-place 1546 1547 private: 1548 Team* fTeam; 1549 runtime_loader_debug_area fDebugArea; 1550 char fImageName[B_OS_NAME_LENGTH]; 1551 char fSymbolName[256]; 1552 static UserSymbolLookup sLookup; 1553 }; 1554 1555 1556 template<typename T> 1557 bool 1558 UserSymbolLookup::_Read(const T* address, T& data) 1559 { 1560 if (!IS_USER_ADDRESS(address)) 1561 return false; 1562 1563 if (debug_debugger_running()) 1564 return debug_memcpy(B_CURRENT_TEAM, &data, address, sizeof(T)) == B_OK; 1565 return user_memcpy(&data, address, sizeof(T)) == B_OK; 1566 } 1567 1568 1569 UserSymbolLookup UserSymbolLookup::sLookup; 1570 // doesn't need construction, but has an Init() method 1571 1572 1573 // #pragma mark - public kernel API 1574 1575 1576 status_t 1577 get_image_symbol(image_id id, const char *name, int32 symbolClass, 1578 void **_symbol) 1579 { 1580 struct elf_image_info *image; 1581 elf_sym *symbol; 1582 status_t status = B_OK; 1583 1584 TRACE(("get_image_symbol(%s)\n", name)); 1585 1586 mutex_lock(&sImageMutex); 1587 1588 image = find_image(id); 1589 if (image == NULL) { 1590 status = B_BAD_IMAGE_ID; 1591 goto done; 1592 } 1593 1594 symbol = elf_find_symbol(image, name, NULL, true); 1595 if (symbol == NULL || symbol->st_shndx == SHN_UNDEF) { 1596 status = B_ENTRY_NOT_FOUND; 1597 goto done; 1598 } 1599 1600 // TODO: support the "symbolClass" parameter! 1601 1602 TRACE(("found: %lx (%lx + %lx)\n", 1603 symbol->st_value + image->text_region.delta, 1604 symbol->st_value, image->text_region.delta)); 1605 1606 *_symbol = (void *)(symbol->st_value + image->text_region.delta); 1607 1608 done: 1609 mutex_unlock(&sImageMutex); 1610 return status; 1611 } 1612 1613 1614 // #pragma mark - kernel private API 1615 1616 1617 /*! Looks up a symbol by address in all images loaded in kernel space. 1618 Note, if you need to call this function outside a debugger, make 1619 sure you fix locking and the way it returns its information, first! 1620 */ 1621 status_t 1622 elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress, 1623 const char **_symbolName, const char **_imageName, bool *_exactMatch) 1624 { 1625 struct elf_image_info *image; 1626 elf_sym *symbolFound = NULL; 1627 const char *symbolName = NULL; 1628 addr_t deltaFound = INT_MAX; 1629 bool exactMatch = false; 1630 status_t status; 1631 1632 TRACE(("looking up %p\n", (void *)address)); 1633 1634 if (!sInitialized) 1635 return B_ERROR; 1636 1637 //mutex_lock(&sImageMutex); 1638 1639 image = find_image_at_address(address); 1640 // get image that may contain the address 1641 1642 if (image != NULL) { 1643 addr_t symbolDelta; 1644 uint32 i; 1645 int32 j; 1646 1647 TRACE((" image %p, base = %p, size = %p\n", image, 1648 (void *)image->text_region.start, (void *)image->text_region.size)); 1649 1650 if (image->debug_symbols != NULL) { 1651 // search extended debug symbol table (contains static symbols) 1652 1653 TRACE((" searching debug symbols...\n")); 1654 1655 for (i = 0; i < image->num_debug_symbols; i++) { 1656 elf_sym *symbol = &image->debug_symbols[i]; 1657 1658 if (symbol->st_value == 0 || symbol->st_size 1659 >= image->text_region.size + image->data_region.size) 1660 continue; 1661 1662 symbolDelta 1663 = address - (symbol->st_value + image->text_region.delta); 1664 if (symbolDelta >= 0 && symbolDelta < symbol->st_size) 1665 exactMatch = true; 1666 1667 if (exactMatch || symbolDelta < deltaFound) { 1668 deltaFound = symbolDelta; 1669 symbolFound = symbol; 1670 symbolName = image->debug_string_table + symbol->st_name; 1671 1672 if (exactMatch) 1673 break; 1674 } 1675 } 1676 } else { 1677 // search standard symbol lookup table 1678 1679 TRACE((" searching standard symbols...\n")); 1680 1681 for (i = 0; i < HASHTABSIZE(image); i++) { 1682 for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; 1683 j = HASHCHAINS(image)[j]) { 1684 elf_sym *symbol = &image->syms[j]; 1685 1686 if (symbol->st_value == 0 1687 || symbol->st_size >= image->text_region.size 1688 + image->data_region.size) 1689 continue; 1690 1691 symbolDelta = address - (long)(symbol->st_value 1692 + image->text_region.delta); 1693 if (symbolDelta >= 0 && symbolDelta < symbol->st_size) 1694 exactMatch = true; 1695 1696 if (exactMatch || symbolDelta < deltaFound) { 1697 deltaFound = symbolDelta; 1698 symbolFound = symbol; 1699 symbolName = SYMNAME(image, symbol); 1700 1701 if (exactMatch) 1702 goto symbol_found; 1703 } 1704 } 1705 } 1706 } 1707 } 1708 symbol_found: 1709 1710 if (symbolFound != NULL) { 1711 if (_symbolName) 1712 *_symbolName = symbolName; 1713 if (_imageName) 1714 *_imageName = image->name; 1715 if (_baseAddress) 1716 *_baseAddress = symbolFound->st_value + image->text_region.delta; 1717 if (_exactMatch) 1718 *_exactMatch = exactMatch; 1719 1720 status = B_OK; 1721 } else if (image != NULL) { 1722 TRACE(("symbol not found!\n")); 1723 1724 if (_symbolName) 1725 *_symbolName = NULL; 1726 if (_imageName) 1727 *_imageName = image->name; 1728 if (_baseAddress) 1729 *_baseAddress = image->text_region.start; 1730 if (_exactMatch) 1731 *_exactMatch = false; 1732 1733 status = B_OK; 1734 } else { 1735 TRACE(("image not found!\n")); 1736 status = B_ENTRY_NOT_FOUND; 1737 } 1738 1739 // Note, theoretically, all information we return back to our caller 1740 // would have to be locked - but since this function is only called 1741 // from the debugger, it's safe to do it this way 1742 1743 //mutex_unlock(&sImageMutex); 1744 1745 return status; 1746 } 1747 1748 1749 /*! Tries to find a matching user symbol for the given address. 1750 Note that the given team's address space must already be in effect. 1751 */ 1752 status_t 1753 elf_debug_lookup_user_symbol_address(Team* team, addr_t address, 1754 addr_t *_baseAddress, const char **_symbolName, const char **_imageName, 1755 bool *_exactMatch) 1756 { 1757 if (team == NULL || team == team_get_kernel_team()) 1758 return B_BAD_VALUE; 1759 1760 UserSymbolLookup& lookup = UserSymbolLookup::Default(); 1761 status_t error = lookup.Init(team); 1762 if (error != B_OK) 1763 return error; 1764 1765 return lookup.LookupSymbolAddress(address, _baseAddress, _symbolName, 1766 _imageName, _exactMatch); 1767 } 1768 1769 1770 /*! Looks up a symbol in all kernel images. Note, this function is thought to 1771 be used in the kernel debugger, and therefore doesn't perform any locking. 1772 */ 1773 addr_t 1774 elf_debug_lookup_symbol(const char* searchName) 1775 { 1776 struct elf_image_info *image = NULL; 1777 1778 ImageHash::Iterator iterator(sImagesHash); 1779 while (iterator.HasNext()) { 1780 image = iterator.Next(); 1781 if (image->num_debug_symbols > 0) { 1782 // search extended debug symbol table (contains static symbols) 1783 for (uint32 i = 0; i < image->num_debug_symbols; i++) { 1784 elf_sym *symbol = &image->debug_symbols[i]; 1785 const char *name = image->debug_string_table + symbol->st_name; 1786 1787 if (symbol->st_value > 0 && !strcmp(name, searchName)) 1788 return symbol->st_value + image->text_region.delta; 1789 } 1790 } else { 1791 // search standard symbol lookup table 1792 for (uint32 i = 0; i < HASHTABSIZE(image); i++) { 1793 for (uint32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF; 1794 j = HASHCHAINS(image)[j]) { 1795 elf_sym *symbol = &image->syms[j]; 1796 const char *name = SYMNAME(image, symbol); 1797 1798 if (symbol->st_value > 0 && !strcmp(name, searchName)) 1799 return symbol->st_value + image->text_region.delta; 1800 } 1801 } 1802 } 1803 } 1804 1805 return 0; 1806 } 1807 1808 1809 status_t 1810 elf_lookup_kernel_symbol(const char* name, elf_symbol_info* info) 1811 { 1812 // find the symbol 1813 elf_sym* foundSymbol = elf_find_symbol(sKernelImage, name, NULL, false); 1814 if (foundSymbol == NULL) 1815 return B_MISSING_SYMBOL; 1816 1817 info->address = foundSymbol->st_value + sKernelImage->text_region.delta; 1818 info->size = foundSymbol->st_size; 1819 return B_OK; 1820 } 1821 1822 1823 #endif // ELF32_COMPAT 1824 1825 1826 status_t 1827 elf_load_user_image(const char *path, Team *team, uint32 flags, addr_t *entry) 1828 { 1829 elf_ehdr elfHeader; 1830 char baseName[B_OS_NAME_LENGTH]; 1831 status_t status; 1832 ssize_t length; 1833 1834 TRACE(("elf_load: entry path '%s', team %p\n", path, team)); 1835 1836 int fd = _kern_open(-1, path, O_RDONLY, 0); 1837 if (fd < 0) 1838 return fd; 1839 FileDescriptorCloser fdCloser(fd); 1840 1841 struct stat st; 1842 status = _kern_read_stat(fd, NULL, false, &st, sizeof(st)); 1843 if (status != B_OK) 1844 return status; 1845 1846 // read and verify the ELF header 1847 1848 length = _kern_read(fd, 0, &elfHeader, sizeof(elfHeader)); 1849 if (length < B_OK) 1850 return length; 1851 1852 if (length != sizeof(elfHeader)) { 1853 // short read 1854 return B_NOT_AN_EXECUTABLE; 1855 } 1856 status = verify_eheader(&elfHeader); 1857 if (status < B_OK) 1858 return status; 1859 1860 #ifdef ELF_LOAD_USER_IMAGE_TEST_EXECUTABLE 1861 if ((flags & ELF_LOAD_USER_IMAGE_TEST_EXECUTABLE) != 0) 1862 return B_OK; 1863 #endif 1864 1865 struct elf_image_info* image; 1866 image = create_image_struct(); 1867 if (image == NULL) 1868 return B_NO_MEMORY; 1869 CObjectDeleter<elf_image_info, void, delete_elf_image> imageDeleter(image); 1870 1871 struct ElfHeaderUnsetter { 1872 ElfHeaderUnsetter(elf_image_info* image) 1873 : fImage(image) 1874 { 1875 } 1876 ~ElfHeaderUnsetter() 1877 { 1878 fImage->elf_header = NULL; 1879 } 1880 1881 elf_image_info* fImage; 1882 } headerUnsetter(image); 1883 image->elf_header = &elfHeader; 1884 1885 // read program header 1886 1887 elf_phdr *programHeaders = (elf_phdr *)malloc( 1888 elfHeader.e_phnum * elfHeader.e_phentsize); 1889 if (programHeaders == NULL) { 1890 dprintf("error allocating space for program headers\n"); 1891 return B_NO_MEMORY; 1892 } 1893 MemoryDeleter headersDeleter(programHeaders); 1894 1895 TRACE(("reading in program headers at 0x%lx, length 0x%x\n", 1896 elfHeader.e_phoff, elfHeader.e_phnum * elfHeader.e_phentsize)); 1897 length = _kern_read(fd, elfHeader.e_phoff, programHeaders, 1898 elfHeader.e_phnum * elfHeader.e_phentsize); 1899 if (length < B_OK) { 1900 dprintf("error reading in program headers\n"); 1901 return length; 1902 } 1903 if (length != elfHeader.e_phnum * elfHeader.e_phentsize) { 1904 dprintf("short read while reading in program headers\n"); 1905 return B_ERROR; 1906 } 1907 1908 // construct a nice name for the region we have to create below 1909 { 1910 int32 length; 1911 1912 const char *leaf = strrchr(path, '/'); 1913 if (leaf == NULL) 1914 leaf = path; 1915 else 1916 leaf++; 1917 1918 length = strlen(leaf); 1919 if (length > B_OS_NAME_LENGTH - 16) 1920 snprintf(baseName, B_OS_NAME_LENGTH, "...%s", leaf + length + 16 - B_OS_NAME_LENGTH); 1921 else 1922 strcpy(baseName, leaf); 1923 } 1924 1925 // map the program's segments into memory, initially with rw access 1926 // correct area protection will be set after relocation 1927 1928 BStackOrHeapArray<area_id, 8> mappedAreas(elfHeader.e_phnum); 1929 if (!mappedAreas.IsValid()) 1930 return B_NO_MEMORY; 1931 1932 extended_image_info imageInfo; 1933 memset(&imageInfo, 0, sizeof(imageInfo)); 1934 1935 addr_t delta = 0; 1936 uint32 addressSpec = B_RANDOMIZED_BASE_ADDRESS; 1937 for (int i = 0; i < elfHeader.e_phnum; i++) { 1938 char regionName[B_OS_NAME_LENGTH]; 1939 char *regionAddress; 1940 char *originalRegionAddress; 1941 area_id id; 1942 1943 mappedAreas[i] = -1; 1944 1945 if (programHeaders[i].p_type == PT_DYNAMIC) { 1946 image->dynamic_section = programHeaders[i].p_vaddr; 1947 continue; 1948 } 1949 1950 if (programHeaders[i].p_type != PT_LOAD) 1951 continue; 1952 1953 regionAddress = (char *)(ROUNDDOWN(programHeaders[i].p_vaddr, 1954 B_PAGE_SIZE) + delta); 1955 originalRegionAddress = regionAddress; 1956 1957 if (programHeaders[i].p_flags & PF_WRITE) { 1958 // rw/data segment 1959 size_t memUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1960 + programHeaders[i].p_memsz; 1961 size_t fileUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1962 + programHeaders[i].p_filesz; 1963 1964 memUpperBound = ROUNDUP(memUpperBound, B_PAGE_SIZE); 1965 fileUpperBound = ROUNDUP(fileUpperBound, B_PAGE_SIZE); 1966 1967 snprintf(regionName, B_OS_NAME_LENGTH, "%s_seg%drw", baseName, i); 1968 1969 id = vm_map_file(team->id, regionName, (void **)®ionAddress, 1970 addressSpec, fileUpperBound, 1971 B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, false, 1972 fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); 1973 if (id < B_OK) { 1974 dprintf("error mapping file data: %s!\n", strerror(id)); 1975 return B_NOT_AN_EXECUTABLE; 1976 } 1977 mappedAreas[i] = id; 1978 1979 imageInfo.basic_info.data = regionAddress; 1980 imageInfo.basic_info.data_size = memUpperBound; 1981 1982 image->data_region.start = (addr_t)regionAddress; 1983 image->data_region.size = memUpperBound; 1984 1985 // clean garbage brought by mmap (the region behind the file, 1986 // at least parts of it are the bss and have to be zeroed) 1987 addr_t start = (addr_t)regionAddress 1988 + (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1989 + programHeaders[i].p_filesz; 1990 size_t amount = fileUpperBound 1991 - (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1992 - (programHeaders[i].p_filesz); 1993 set_ac(); 1994 memset((void *)start, 0, amount); 1995 clear_ac(); 1996 1997 // Check if we need extra storage for the bss - we have to do this if 1998 // the above region doesn't already comprise the memory size, too. 1999 2000 if (memUpperBound != fileUpperBound) { 2001 size_t bssSize = memUpperBound - fileUpperBound; 2002 2003 snprintf(regionName, B_OS_NAME_LENGTH, "%s_bss%d", baseName, i); 2004 2005 regionAddress += fileUpperBound; 2006 virtual_address_restrictions virtualRestrictions = {}; 2007 virtualRestrictions.address = regionAddress; 2008 virtualRestrictions.address_specification = B_EXACT_ADDRESS; 2009 physical_address_restrictions physicalRestrictions = {}; 2010 id = create_area_etc(team->id, regionName, bssSize, B_NO_LOCK, 2011 B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions, 2012 &physicalRestrictions, (void**)®ionAddress); 2013 if (id < B_OK) { 2014 dprintf("error allocating bss area: %s!\n", strerror(id)); 2015 return B_NOT_AN_EXECUTABLE; 2016 } 2017 } 2018 } else { 2019 // assume ro/text segment 2020 snprintf(regionName, B_OS_NAME_LENGTH, "%s_seg%dro", baseName, i); 2021 2022 size_t segmentSize = ROUNDUP(programHeaders[i].p_memsz 2023 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 2024 2025 id = vm_map_file(team->id, regionName, (void **)®ionAddress, 2026 addressSpec, segmentSize, 2027 B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, false, fd, 2028 ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); 2029 if (id < B_OK) { 2030 dprintf("error mapping file text: %s!\n", strerror(id)); 2031 return B_NOT_AN_EXECUTABLE; 2032 } 2033 2034 mappedAreas[i] = id; 2035 2036 imageInfo.basic_info.text = regionAddress; 2037 imageInfo.basic_info.text_size = segmentSize; 2038 2039 image->text_region.start = (addr_t)regionAddress; 2040 image->text_region.size = segmentSize; 2041 } 2042 2043 if (addressSpec != B_EXACT_ADDRESS) { 2044 addressSpec = B_EXACT_ADDRESS; 2045 delta = regionAddress - originalRegionAddress; 2046 } 2047 } 2048 2049 image->data_region.delta = delta; 2050 image->text_region.delta = delta; 2051 2052 // modify the dynamic ptr by the delta of the regions 2053 image->dynamic_section += image->text_region.delta; 2054 2055 set_ac(); 2056 status = elf_parse_dynamic_section(image); 2057 if (status != B_OK) { 2058 clear_ac(); 2059 return status; 2060 } 2061 2062 status = elf_relocate(image, image); 2063 if (status != B_OK) { 2064 clear_ac(); 2065 return status; 2066 } 2067 2068 clear_ac(); 2069 2070 // set correct area protection 2071 for (int i = 0; i < elfHeader.e_phnum; i++) { 2072 if (mappedAreas[i] == -1) 2073 continue; 2074 2075 uint32 protection = 0; 2076 2077 if (programHeaders[i].p_flags & PF_EXECUTE) 2078 protection |= B_EXECUTE_AREA; 2079 if (programHeaders[i].p_flags & PF_WRITE) 2080 protection |= B_WRITE_AREA; 2081 if (programHeaders[i].p_flags & PF_READ) 2082 protection |= B_READ_AREA; 2083 2084 status = vm_set_area_protection(team->id, mappedAreas[i], protection, 2085 true); 2086 if (status != B_OK) 2087 return status; 2088 } 2089 2090 // register the loaded image 2091 imageInfo.basic_info.type = B_LIBRARY_IMAGE; 2092 imageInfo.basic_info.device = st.st_dev; 2093 imageInfo.basic_info.node = st.st_ino; 2094 strlcpy(imageInfo.basic_info.name, path, sizeof(imageInfo.basic_info.name)); 2095 2096 imageInfo.basic_info.api_version = B_HAIKU_VERSION; 2097 imageInfo.basic_info.abi = B_HAIKU_ABI; 2098 // TODO: Get the actual values for the shared object. Currently only 2099 // the runtime loader is loaded, so this is good enough for the time 2100 // being. 2101 2102 imageInfo.text_delta = delta; 2103 imageInfo.symbol_table = image->syms; 2104 imageInfo.symbol_hash = image->symhash; 2105 imageInfo.string_table = image->strtab; 2106 2107 imageInfo.basic_info.id = register_image(team, &imageInfo, 2108 sizeof(imageInfo)); 2109 if (imageInfo.basic_info.id >= 0 && team_get_current_team_id() == team->id) 2110 user_debug_image_created(&imageInfo.basic_info); 2111 // Don't care, if registering fails. It's not crucial. 2112 2113 TRACE(("elf_load: done!\n")); 2114 2115 *entry = elfHeader.e_entry + delta; 2116 return B_OK; 2117 } 2118 2119 2120 #ifndef ELF32_COMPAT 2121 2122 image_id 2123 load_kernel_add_on(const char *path) 2124 { 2125 elf_phdr *programHeaders; 2126 elf_ehdr *elfHeader; 2127 struct elf_image_info *image; 2128 const char *fileName; 2129 void *reservedAddress; 2130 size_t reservedSize; 2131 status_t status; 2132 ssize_t length; 2133 bool textSectionWritable = false; 2134 int executableHeaderCount = 0; 2135 2136 TRACE(("elf_load_kspace: entry path '%s'\n", path)); 2137 2138 int fd = _kern_open(-1, path, O_RDONLY, 0); 2139 if (fd < 0) 2140 return fd; 2141 2142 struct vnode *vnode; 2143 status = vfs_get_vnode_from_fd(fd, true, &vnode); 2144 if (status < B_OK) 2145 goto error0; 2146 2147 // get the file name 2148 fileName = strrchr(path, '/'); 2149 if (fileName == NULL) 2150 fileName = path; 2151 else 2152 fileName++; 2153 2154 // Prevent someone else from trying to load this image 2155 mutex_lock(&sImageLoadMutex); 2156 2157 // make sure it's not loaded already. Search by vnode 2158 image = find_image_by_vnode(vnode); 2159 if (image) { 2160 atomic_add(&image->ref_count, 1); 2161 goto done; 2162 } 2163 2164 elfHeader = (elf_ehdr *)malloc(sizeof(*elfHeader)); 2165 if (!elfHeader) { 2166 status = B_NO_MEMORY; 2167 goto error; 2168 } 2169 2170 length = _kern_read(fd, 0, elfHeader, sizeof(*elfHeader)); 2171 if (length < B_OK) { 2172 status = length; 2173 goto error1; 2174 } 2175 if (length != sizeof(*elfHeader)) { 2176 // short read 2177 status = B_NOT_AN_EXECUTABLE; 2178 goto error1; 2179 } 2180 status = verify_eheader(elfHeader); 2181 if (status < B_OK) 2182 goto error1; 2183 2184 image = create_image_struct(); 2185 if (!image) { 2186 status = B_NO_MEMORY; 2187 goto error1; 2188 } 2189 image->vnode = vnode; 2190 image->elf_header = elfHeader; 2191 image->name = strdup(path); 2192 vnode = NULL; 2193 2194 programHeaders = (elf_phdr *)malloc(elfHeader->e_phnum 2195 * elfHeader->e_phentsize); 2196 if (programHeaders == NULL) { 2197 dprintf("%s: error allocating space for program headers\n", fileName); 2198 status = B_NO_MEMORY; 2199 goto error2; 2200 } 2201 2202 TRACE(("reading in program headers at 0x%lx, length 0x%x\n", 2203 elfHeader->e_phoff, elfHeader->e_phnum * elfHeader->e_phentsize)); 2204 2205 length = _kern_read(fd, elfHeader->e_phoff, programHeaders, 2206 elfHeader->e_phnum * elfHeader->e_phentsize); 2207 if (length < B_OK) { 2208 status = length; 2209 TRACE(("%s: error reading in program headers\n", fileName)); 2210 goto error3; 2211 } 2212 if (length != elfHeader->e_phnum * elfHeader->e_phentsize) { 2213 TRACE(("%s: short read while reading in program headers\n", fileName)); 2214 status = B_ERROR; 2215 goto error3; 2216 } 2217 2218 // determine how much space we need for all loaded segments 2219 2220 reservedSize = 0; 2221 length = 0; 2222 2223 for (int32 i = 0; i < elfHeader->e_phnum; i++) { 2224 size_t end; 2225 2226 if (programHeaders[i].p_type != PT_LOAD) 2227 continue; 2228 2229 length += ROUNDUP(programHeaders[i].p_memsz 2230 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 2231 2232 end = ROUNDUP(programHeaders[i].p_memsz + programHeaders[i].p_vaddr, 2233 B_PAGE_SIZE); 2234 if (end > reservedSize) 2235 reservedSize = end; 2236 2237 if (programHeaders[i].IsExecutable()) 2238 executableHeaderCount++; 2239 } 2240 2241 // Check whether the segments have an unreasonable amount of unused space 2242 // inbetween. 2243 if ((ssize_t)reservedSize > length + 8 * 1024) { 2244 status = B_BAD_DATA; 2245 goto error1; 2246 } 2247 2248 // reserve that space and allocate the areas from that one 2249 if (vm_reserve_address_range(VMAddressSpace::KernelID(), &reservedAddress, 2250 B_ANY_KERNEL_ADDRESS, reservedSize, 0) < B_OK) { 2251 status = B_NO_MEMORY; 2252 goto error3; 2253 } 2254 2255 image->data_region.size = 0; 2256 image->text_region.size = 0; 2257 2258 for (int32 i = 0; i < elfHeader->e_phnum; i++) { 2259 char regionName[B_OS_NAME_LENGTH]; 2260 elf_region *region; 2261 2262 TRACE(("looking at program header %" B_PRId32 "\n", i)); 2263 2264 switch (programHeaders[i].p_type) { 2265 case PT_LOAD: 2266 break; 2267 case PT_DYNAMIC: 2268 image->dynamic_section = programHeaders[i].p_vaddr; 2269 continue; 2270 case PT_INTERP: 2271 // should check here for appropriate interpreter 2272 continue; 2273 case PT_PHDR: 2274 case PT_STACK: 2275 // we don't use it 2276 continue; 2277 case PT_EH_FRAME: 2278 // not implemented yet, but can be ignored 2279 continue; 2280 case PT_ARM_UNWIND: 2281 continue; 2282 case PT_RISCV_ATTRIBUTES: 2283 // TODO: check ABI compatibility attributes 2284 continue; 2285 default: 2286 dprintf("%s: unhandled pheader type %#" B_PRIx32 "\n", fileName, 2287 programHeaders[i].p_type); 2288 continue; 2289 } 2290 2291 // we're here, so it must be a PT_LOAD segment 2292 2293 // Usually add-ons have two PT_LOAD headers: one for .data one or .text. 2294 // x86 and PPC may differ in permission bits for .data's PT_LOAD header 2295 // x86 is usually RW, PPC is RWE 2296 2297 // Some add-ons may have .text and .data concatenated in a single 2298 // PT_LOAD RWE header and we must map that to .text. 2299 if (programHeaders[i].IsReadWrite() 2300 && (!programHeaders[i].IsExecutable() 2301 || executableHeaderCount > 1)) { 2302 // this is the writable segment 2303 if (image->data_region.size != 0) { 2304 // we've already created this segment 2305 continue; 2306 } 2307 region = &image->data_region; 2308 2309 snprintf(regionName, B_OS_NAME_LENGTH, "%s_data", fileName); 2310 } else if (programHeaders[i].IsExecutable()) { 2311 // this is the non-writable segment 2312 if (image->text_region.size != 0) { 2313 // we've already created this segment 2314 continue; 2315 } 2316 region = &image->text_region; 2317 2318 // some programs may have .text and .data concatenated in a 2319 // single PT_LOAD section which is readable/writable/executable 2320 textSectionWritable = programHeaders[i].IsReadWrite(); 2321 snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", fileName); 2322 } else { 2323 dprintf("%s: weird program header flags %#" B_PRIx32 "\n", fileName, 2324 programHeaders[i].p_flags); 2325 continue; 2326 } 2327 2328 region->start = (addr_t)reservedAddress + ROUNDDOWN( 2329 programHeaders[i].p_vaddr, B_PAGE_SIZE); 2330 region->size = ROUNDUP(programHeaders[i].p_memsz 2331 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 2332 region->id = create_area(regionName, (void **)®ion->start, 2333 B_EXACT_ADDRESS, region->size, B_FULL_LOCK, 2334 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); 2335 if (region->id < B_OK) { 2336 dprintf("%s: error allocating area: %s\n", fileName, 2337 strerror(region->id)); 2338 status = B_NOT_AN_EXECUTABLE; 2339 goto error4; 2340 } 2341 region->delta = -ROUNDDOWN(programHeaders[i].p_vaddr, B_PAGE_SIZE); 2342 2343 TRACE(("elf_load_kspace: created area \"%s\" at %p\n", 2344 regionName, (void *)region->start)); 2345 2346 length = _kern_read(fd, programHeaders[i].p_offset, 2347 (void *)(region->start + (programHeaders[i].p_vaddr % B_PAGE_SIZE)), 2348 programHeaders[i].p_filesz); 2349 if (length < B_OK) { 2350 status = length; 2351 dprintf("%s: error reading in segment %" B_PRId32 "\n", fileName, 2352 i); 2353 goto error5; 2354 } 2355 } 2356 2357 image->data_region.delta += image->data_region.start; 2358 image->text_region.delta += image->text_region.start; 2359 2360 // modify the dynamic ptr by the delta of the regions 2361 image->dynamic_section += image->text_region.delta; 2362 2363 status = elf_parse_dynamic_section(image); 2364 if (status < B_OK) 2365 goto error5; 2366 2367 status = init_image_version_infos(image); 2368 if (status != B_OK) 2369 goto error5; 2370 2371 status = check_needed_image_versions(image); 2372 if (status != B_OK) 2373 goto error5; 2374 2375 status = elf_relocate(image, sKernelImage); 2376 if (status < B_OK) 2377 goto error5; 2378 2379 // We needed to read in the contents of the "text" area, but 2380 // now we can protect it read-only/execute, unless this is a 2381 // special image with concatenated .text and .data, when it 2382 // will also need write access. 2383 set_area_protection(image->text_region.id, 2384 B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA 2385 | (textSectionWritable ? B_KERNEL_WRITE_AREA : 0)); 2386 2387 // There might be a hole between the two segments, and we don't need to 2388 // reserve this any longer 2389 vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress, 2390 reservedSize); 2391 2392 if (sLoadElfSymbols) 2393 load_elf_symbol_table(fd, image); 2394 2395 free(programHeaders); 2396 mutex_lock(&sImageMutex); 2397 register_elf_image(image); 2398 mutex_unlock(&sImageMutex); 2399 2400 done: 2401 _kern_close(fd); 2402 mutex_unlock(&sImageLoadMutex); 2403 2404 return image->id; 2405 2406 error5: 2407 error4: 2408 vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress, 2409 reservedSize); 2410 error3: 2411 free(programHeaders); 2412 error2: 2413 delete_elf_image(image); 2414 elfHeader = NULL; 2415 error1: 2416 free(elfHeader); 2417 error: 2418 mutex_unlock(&sImageLoadMutex); 2419 error0: 2420 dprintf("Could not load kernel add-on \"%s\": %s\n", path, 2421 strerror(status)); 2422 2423 if (vnode) 2424 vfs_put_vnode(vnode); 2425 _kern_close(fd); 2426 2427 return status; 2428 } 2429 2430 2431 status_t 2432 unload_kernel_add_on(image_id id) 2433 { 2434 MutexLocker _(sImageLoadMutex); 2435 MutexLocker _2(sImageMutex); 2436 2437 elf_image_info *image = find_image(id); 2438 if (image == NULL) 2439 return B_BAD_IMAGE_ID; 2440 2441 unload_elf_image(image); 2442 return B_OK; 2443 } 2444 2445 2446 struct elf_image_info* 2447 elf_get_kernel_image() 2448 { 2449 return sKernelImage; 2450 } 2451 2452 2453 status_t 2454 elf_get_image_info_for_address(addr_t address, image_info* info) 2455 { 2456 MutexLocker _(sImageMutex); 2457 struct elf_image_info* elfInfo = find_image_at_address(address); 2458 if (elfInfo == NULL) 2459 return B_ENTRY_NOT_FOUND; 2460 2461 info->id = elfInfo->id; 2462 info->type = B_SYSTEM_IMAGE; 2463 info->sequence = 0; 2464 info->init_order = 0; 2465 info->init_routine = NULL; 2466 info->term_routine = NULL; 2467 info->device = -1; 2468 info->node = -1; 2469 // TODO: We could actually fill device/node in. 2470 strlcpy(info->name, elfInfo->name, sizeof(info->name)); 2471 info->text = (void*)elfInfo->text_region.start; 2472 info->data = (void*)elfInfo->data_region.start; 2473 info->text_size = elfInfo->text_region.size; 2474 info->data_size = elfInfo->data_region.size; 2475 2476 return B_OK; 2477 } 2478 2479 2480 image_id 2481 elf_create_memory_image(const char* imageName, addr_t text, size_t textSize, 2482 addr_t data, size_t dataSize) 2483 { 2484 // allocate the image 2485 elf_image_info* image = create_image_struct(); 2486 if (image == NULL) 2487 return B_NO_MEMORY; 2488 MemoryDeleter imageDeleter(image); 2489 2490 // allocate symbol and string tables -- we allocate an empty symbol table, 2491 // so that elf_debug_lookup_symbol_address() won't try the dynamic symbol 2492 // table, which we don't have. 2493 elf_sym* symbolTable = (elf_sym*)malloc(0); 2494 char* stringTable = (char*)malloc(1); 2495 MemoryDeleter symbolTableDeleter(symbolTable); 2496 MemoryDeleter stringTableDeleter(stringTable); 2497 if (symbolTable == NULL || stringTable == NULL) 2498 return B_NO_MEMORY; 2499 2500 // the string table always contains the empty string 2501 stringTable[0] = '\0'; 2502 2503 image->debug_symbols = symbolTable; 2504 image->num_debug_symbols = 0; 2505 image->debug_string_table = stringTable; 2506 2507 // dup image name 2508 image->name = strdup(imageName); 2509 if (image->name == NULL) 2510 return B_NO_MEMORY; 2511 2512 // data and text region 2513 image->text_region.id = -1; 2514 image->text_region.start = text; 2515 image->text_region.size = textSize; 2516 image->text_region.delta = 0; 2517 2518 image->data_region.id = -1; 2519 image->data_region.start = data; 2520 image->data_region.size = dataSize; 2521 image->data_region.delta = 0; 2522 2523 mutex_lock(&sImageMutex); 2524 register_elf_image(image); 2525 image_id imageID = image->id; 2526 mutex_unlock(&sImageMutex); 2527 2528 // keep the allocated memory 2529 imageDeleter.Detach(); 2530 symbolTableDeleter.Detach(); 2531 stringTableDeleter.Detach(); 2532 2533 return imageID; 2534 } 2535 2536 2537 status_t 2538 elf_add_memory_image_symbol(image_id id, const char* name, addr_t address, 2539 size_t size, int32 type) 2540 { 2541 MutexLocker _(sImageMutex); 2542 2543 // get the image 2544 struct elf_image_info* image = find_image(id); 2545 if (image == NULL) 2546 return B_ENTRY_NOT_FOUND; 2547 2548 // get the current string table size 2549 size_t stringTableSize = 1; 2550 if (image->num_debug_symbols > 0) { 2551 for (int32 i = image->num_debug_symbols - 1; i >= 0; i--) { 2552 int32 nameIndex = image->debug_symbols[i].st_name; 2553 if (nameIndex != 0) { 2554 stringTableSize = nameIndex 2555 + strlen(image->debug_string_table + nameIndex) + 1; 2556 break; 2557 } 2558 } 2559 } 2560 2561 // enter the name in the string table 2562 char* stringTable = (char*)image->debug_string_table; 2563 size_t stringIndex = 0; 2564 if (name != NULL) { 2565 size_t nameSize = strlen(name) + 1; 2566 stringIndex = stringTableSize; 2567 stringTableSize += nameSize; 2568 stringTable = (char*)realloc((char*)image->debug_string_table, 2569 stringTableSize); 2570 if (stringTable == NULL) 2571 return B_NO_MEMORY; 2572 image->debug_string_table = stringTable; 2573 memcpy(stringTable + stringIndex, name, nameSize); 2574 } 2575 2576 // resize the symbol table 2577 int32 symbolCount = image->num_debug_symbols + 1; 2578 elf_sym* symbolTable = (elf_sym*)realloc( 2579 (elf_sym*)image->debug_symbols, sizeof(elf_sym) * symbolCount); 2580 if (symbolTable == NULL) 2581 return B_NO_MEMORY; 2582 image->debug_symbols = symbolTable; 2583 2584 // enter the symbol 2585 elf_sym& symbol = symbolTable[symbolCount - 1]; 2586 symbol.SetInfo(STB_GLOBAL, 2587 type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC); 2588 symbol.st_name = stringIndex; 2589 symbol.st_value = address; 2590 symbol.st_size = size; 2591 symbol.st_other = 0; 2592 symbol.st_shndx = 0; 2593 image->num_debug_symbols++; 2594 2595 return B_OK; 2596 } 2597 2598 2599 /*! Reads the symbol and string table for the kernel image with the given ID. 2600 \a _symbolCount and \a _stringTableSize are both in- and output parameters. 2601 When called they call the size of the buffers given by \a symbolTable and 2602 \a stringTable respectively. When the function returns successfully, they 2603 will contain the actual sizes (which can be greater than the original ones). 2604 The function will copy as much as possible into the buffers. For only 2605 getting the required buffer sizes, it can be invoked with \c NULL buffers. 2606 On success \a _imageDelta will contain the offset to be added to the symbol 2607 values in the table to get the actual symbol addresses. 2608 */ 2609 status_t 2610 elf_read_kernel_image_symbols(image_id id, elf_sym* symbolTable, 2611 int32* _symbolCount, char* stringTable, size_t* _stringTableSize, 2612 addr_t* _imageDelta, bool kernel) 2613 { 2614 // check params 2615 if (_symbolCount == NULL || _stringTableSize == NULL) 2616 return B_BAD_VALUE; 2617 if (!kernel) { 2618 if (!IS_USER_ADDRESS(_symbolCount) || !IS_USER_ADDRESS(_stringTableSize) 2619 || (_imageDelta != NULL && !IS_USER_ADDRESS(_imageDelta)) 2620 || (symbolTable != NULL && !IS_USER_ADDRESS(symbolTable)) 2621 || (stringTable != NULL && !IS_USER_ADDRESS(stringTable))) { 2622 return B_BAD_ADDRESS; 2623 } 2624 } 2625 2626 // get buffer sizes 2627 int32 maxSymbolCount; 2628 size_t maxStringTableSize; 2629 if (kernel) { 2630 maxSymbolCount = *_symbolCount; 2631 maxStringTableSize = *_stringTableSize; 2632 } else { 2633 if (user_memcpy(&maxSymbolCount, _symbolCount, sizeof(maxSymbolCount)) 2634 != B_OK 2635 || user_memcpy(&maxStringTableSize, _stringTableSize, 2636 sizeof(maxStringTableSize)) != B_OK) { 2637 return B_BAD_ADDRESS; 2638 } 2639 } 2640 2641 // find the image 2642 MutexLocker _(sImageMutex); 2643 struct elf_image_info* image = find_image(id); 2644 if (image == NULL) 2645 return B_ENTRY_NOT_FOUND; 2646 2647 // get the tables and infos 2648 addr_t imageDelta = image->text_region.delta; 2649 const elf_sym* symbols; 2650 int32 symbolCount; 2651 const char* strings; 2652 2653 if (image->debug_symbols != NULL) { 2654 symbols = image->debug_symbols; 2655 symbolCount = image->num_debug_symbols; 2656 strings = image->debug_string_table; 2657 } else { 2658 symbols = image->syms; 2659 symbolCount = image->symhash[1]; 2660 strings = image->strtab; 2661 } 2662 2663 // The string table size isn't stored in the elf_image_info structure. Find 2664 // out by iterating through all symbols. 2665 size_t stringTableSize = 0; 2666 for (int32 i = 0; i < symbolCount; i++) { 2667 size_t index = symbols[i].st_name; 2668 if (index > stringTableSize) 2669 stringTableSize = index; 2670 } 2671 stringTableSize += strlen(strings + stringTableSize) + 1; 2672 // add size of the last string 2673 2674 // copy symbol table 2675 int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount); 2676 if (symbolTable != NULL && symbolsToCopy > 0) { 2677 if (kernel) { 2678 memcpy(symbolTable, symbols, sizeof(elf_sym) * symbolsToCopy); 2679 } else if (user_memcpy(symbolTable, symbols, 2680 sizeof(elf_sym) * symbolsToCopy) != B_OK) { 2681 return B_BAD_ADDRESS; 2682 } 2683 } 2684 2685 // copy string table 2686 size_t stringsToCopy = min_c(stringTableSize, maxStringTableSize); 2687 if (stringTable != NULL && stringsToCopy > 0) { 2688 if (kernel) { 2689 memcpy(stringTable, strings, stringsToCopy); 2690 } else { 2691 if (user_memcpy(stringTable, strings, stringsToCopy) 2692 != B_OK) { 2693 return B_BAD_ADDRESS; 2694 } 2695 } 2696 } 2697 2698 // copy sizes 2699 if (kernel) { 2700 *_symbolCount = symbolCount; 2701 *_stringTableSize = stringTableSize; 2702 if (_imageDelta != NULL) 2703 *_imageDelta = imageDelta; 2704 } else { 2705 if (user_memcpy(_symbolCount, &symbolCount, sizeof(symbolCount)) != B_OK 2706 || user_memcpy(_stringTableSize, &stringTableSize, 2707 sizeof(stringTableSize)) != B_OK 2708 || (_imageDelta != NULL && user_memcpy(_imageDelta, &imageDelta, 2709 sizeof(imageDelta)) != B_OK)) { 2710 return B_BAD_ADDRESS; 2711 } 2712 } 2713 2714 return B_OK; 2715 } 2716 2717 2718 status_t 2719 elf_init(kernel_args* args) 2720 { 2721 struct preloaded_image* image; 2722 2723 image_init(); 2724 2725 if (void* handle = load_driver_settings("kernel")) { 2726 sLoadElfSymbols = get_driver_boolean_parameter(handle, "load_symbols", 2727 false, false); 2728 2729 unload_driver_settings(handle); 2730 } 2731 2732 sImagesHash = new(std::nothrow) ImageHash(); 2733 if (sImagesHash == NULL) 2734 return B_NO_MEMORY; 2735 status_t init = sImagesHash->Init(IMAGE_HASH_SIZE); 2736 if (init != B_OK) 2737 return init; 2738 2739 // Build a image structure for the kernel, which has already been loaded. 2740 // The preloaded_images were already prepared by the VM. 2741 image = args->kernel_image; 2742 if (insert_preloaded_image(static_cast<preloaded_elf_image *>(image), 2743 true) < B_OK) 2744 panic("could not create kernel image.\n"); 2745 2746 // Build image structures for all preloaded images. 2747 for (image = args->preloaded_images; image != NULL; image = image->next) 2748 insert_preloaded_image(static_cast<preloaded_elf_image *>(image), 2749 false); 2750 2751 add_debugger_command("ls", &dump_address_info, 2752 "lookup symbol for a particular address"); 2753 add_debugger_command("symbols", &dump_symbols, "dump symbols for image"); 2754 add_debugger_command("symbol", &dump_symbol, "search symbol in images"); 2755 add_debugger_command_etc("image", &dump_image, "dump image info", 2756 "Prints info about the specified image.\n" 2757 " <image> - pointer to the semaphore structure, or ID\n" 2758 " of the image to print info for.\n", 0); 2759 2760 sInitialized = true; 2761 return B_OK; 2762 } 2763 2764 2765 // #pragma mark - 2766 2767 2768 /*! Reads the symbol and string table for the kernel image with the given ID. 2769 \a _symbolCount and \a _stringTableSize are both in- and output parameters. 2770 When called they call the size of the buffers given by \a symbolTable and 2771 \a stringTable respectively. When the function returns successfully, they 2772 will contain the actual sizes (which can be greater than the original ones). 2773 The function will copy as much as possible into the buffers. For only 2774 getting the required buffer sizes, it can be invoked with \c NULL buffers. 2775 On success \a _imageDelta will contain the offset to be added to the symbol 2776 values in the table to get the actual symbol addresses. 2777 */ 2778 status_t 2779 _user_read_kernel_image_symbols(image_id id, elf_sym* symbolTable, 2780 int32* _symbolCount, char* stringTable, size_t* _stringTableSize, 2781 addr_t* _imageDelta) 2782 { 2783 return elf_read_kernel_image_symbols(id, symbolTable, _symbolCount, 2784 stringTable, _stringTableSize, _imageDelta, false); 2785 } 2786 2787 #endif // ELF32_COMPAT 2788 2789