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