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