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