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