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 case PT_STACK: 2287 // we don't use it 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 // ToDo: this should be enabled by kernel settings! 2397 if (1) 2398 load_elf_symbol_table(fd, image); 2399 2400 free(programHeaders); 2401 mutex_lock(&sImageMutex); 2402 register_elf_image(image); 2403 mutex_unlock(&sImageMutex); 2404 2405 done: 2406 _kern_close(fd); 2407 mutex_unlock(&sImageLoadMutex); 2408 2409 return image->id; 2410 2411 error5: 2412 error4: 2413 vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress, 2414 reservedSize); 2415 error3: 2416 free(programHeaders); 2417 error2: 2418 delete_elf_image(image); 2419 elfHeader = NULL; 2420 error1: 2421 free(elfHeader); 2422 error: 2423 mutex_unlock(&sImageLoadMutex); 2424 error0: 2425 dprintf("Could not load kernel add-on \"%s\": %s\n", path, 2426 strerror(status)); 2427 2428 if (vnode) 2429 vfs_put_vnode(vnode); 2430 _kern_close(fd); 2431 2432 return status; 2433 } 2434 2435 2436 status_t 2437 unload_kernel_add_on(image_id id) 2438 { 2439 MutexLocker _(sImageLoadMutex); 2440 MutexLocker _2(sImageMutex); 2441 2442 elf_image_info *image = find_image(id); 2443 if (image == NULL) 2444 return B_BAD_IMAGE_ID; 2445 2446 unload_elf_image(image); 2447 return B_OK; 2448 } 2449 2450 2451 struct elf_image_info* 2452 elf_get_kernel_image() 2453 { 2454 return sKernelImage; 2455 } 2456 2457 2458 status_t 2459 elf_get_image_info_for_address(addr_t address, image_info* info) 2460 { 2461 MutexLocker _(sImageMutex); 2462 struct elf_image_info* elfInfo = find_image_at_address(address); 2463 if (elfInfo == NULL) 2464 return B_ENTRY_NOT_FOUND; 2465 2466 info->id = elfInfo->id; 2467 info->type = B_SYSTEM_IMAGE; 2468 info->sequence = 0; 2469 info->init_order = 0; 2470 info->init_routine = NULL; 2471 info->term_routine = NULL; 2472 info->device = -1; 2473 info->node = -1; 2474 // TODO: We could actually fill device/node in. 2475 strlcpy(info->name, elfInfo->name, sizeof(info->name)); 2476 info->text = (void*)elfInfo->text_region.start; 2477 info->data = (void*)elfInfo->data_region.start; 2478 info->text_size = elfInfo->text_region.size; 2479 info->data_size = elfInfo->data_region.size; 2480 2481 return B_OK; 2482 } 2483 2484 2485 image_id 2486 elf_create_memory_image(const char* imageName, addr_t text, size_t textSize, 2487 addr_t data, size_t dataSize) 2488 { 2489 // allocate the image 2490 elf_image_info* image = create_image_struct(); 2491 if (image == NULL) 2492 return B_NO_MEMORY; 2493 MemoryDeleter imageDeleter(image); 2494 2495 // allocate symbol and string tables -- we allocate an empty symbol table, 2496 // so that elf_debug_lookup_symbol_address() won't try the dynamic symbol 2497 // table, which we don't have. 2498 elf_sym* symbolTable = (elf_sym*)malloc(0); 2499 char* stringTable = (char*)malloc(1); 2500 MemoryDeleter symbolTableDeleter(symbolTable); 2501 MemoryDeleter stringTableDeleter(stringTable); 2502 if (symbolTable == NULL || stringTable == NULL) 2503 return B_NO_MEMORY; 2504 2505 // the string table always contains the empty string 2506 stringTable[0] = '\0'; 2507 2508 image->debug_symbols = symbolTable; 2509 image->num_debug_symbols = 0; 2510 image->debug_string_table = stringTable; 2511 2512 // dup image name 2513 image->name = strdup(imageName); 2514 if (image->name == NULL) 2515 return B_NO_MEMORY; 2516 2517 // data and text region 2518 image->text_region.id = -1; 2519 image->text_region.start = text; 2520 image->text_region.size = textSize; 2521 image->text_region.delta = 0; 2522 2523 image->data_region.id = -1; 2524 image->data_region.start = data; 2525 image->data_region.size = dataSize; 2526 image->data_region.delta = 0; 2527 2528 mutex_lock(&sImageMutex); 2529 register_elf_image(image); 2530 image_id imageID = image->id; 2531 mutex_unlock(&sImageMutex); 2532 2533 // keep the allocated memory 2534 imageDeleter.Detach(); 2535 symbolTableDeleter.Detach(); 2536 stringTableDeleter.Detach(); 2537 2538 return imageID; 2539 } 2540 2541 2542 status_t 2543 elf_add_memory_image_symbol(image_id id, const char* name, addr_t address, 2544 size_t size, int32 type) 2545 { 2546 MutexLocker _(sImageMutex); 2547 2548 // get the image 2549 struct elf_image_info* image = find_image(id); 2550 if (image == NULL) 2551 return B_ENTRY_NOT_FOUND; 2552 2553 // get the current string table size 2554 size_t stringTableSize = 1; 2555 if (image->num_debug_symbols > 0) { 2556 for (int32 i = image->num_debug_symbols - 1; i >= 0; i--) { 2557 int32 nameIndex = image->debug_symbols[i].st_name; 2558 if (nameIndex != 0) { 2559 stringTableSize = nameIndex 2560 + strlen(image->debug_string_table + nameIndex) + 1; 2561 break; 2562 } 2563 } 2564 } 2565 2566 // enter the name in the string table 2567 char* stringTable = (char*)image->debug_string_table; 2568 size_t stringIndex = 0; 2569 if (name != NULL) { 2570 size_t nameSize = strlen(name) + 1; 2571 stringIndex = stringTableSize; 2572 stringTableSize += nameSize; 2573 stringTable = (char*)realloc((char*)image->debug_string_table, 2574 stringTableSize); 2575 if (stringTable == NULL) 2576 return B_NO_MEMORY; 2577 image->debug_string_table = stringTable; 2578 memcpy(stringTable + stringIndex, name, nameSize); 2579 } 2580 2581 // resize the symbol table 2582 int32 symbolCount = image->num_debug_symbols + 1; 2583 elf_sym* symbolTable = (elf_sym*)realloc( 2584 (elf_sym*)image->debug_symbols, sizeof(elf_sym) * symbolCount); 2585 if (symbolTable == NULL) 2586 return B_NO_MEMORY; 2587 image->debug_symbols = symbolTable; 2588 2589 // enter the symbol 2590 elf_sym& symbol = symbolTable[symbolCount - 1]; 2591 symbol.SetInfo(STB_GLOBAL, 2592 type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC); 2593 symbol.st_name = stringIndex; 2594 symbol.st_value = address; 2595 symbol.st_size = size; 2596 symbol.st_other = 0; 2597 symbol.st_shndx = 0; 2598 image->num_debug_symbols++; 2599 2600 return B_OK; 2601 } 2602 2603 2604 /*! Reads the symbol and string table for the kernel image with the given ID. 2605 \a _symbolCount and \a _stringTableSize are both in- and output parameters. 2606 When called they call the size of the buffers given by \a symbolTable and 2607 \a stringTable respectively. When the function returns successfully, they 2608 will contain the actual sizes (which can be greater than the original ones). 2609 The function will copy as much as possible into the buffers. For only 2610 getting the required buffer sizes, it can be invoked with \c NULL buffers. 2611 On success \a _imageDelta will contain the offset to be added to the symbol 2612 values in the table to get the actual symbol addresses. 2613 */ 2614 status_t 2615 elf_read_kernel_image_symbols(image_id id, elf_sym* symbolTable, 2616 int32* _symbolCount, char* stringTable, size_t* _stringTableSize, 2617 addr_t* _imageDelta, bool kernel) 2618 { 2619 // check params 2620 if (_symbolCount == NULL || _stringTableSize == NULL) 2621 return B_BAD_VALUE; 2622 if (!kernel) { 2623 if (!IS_USER_ADDRESS(_symbolCount) || !IS_USER_ADDRESS(_stringTableSize) 2624 || (_imageDelta != NULL && !IS_USER_ADDRESS(_imageDelta)) 2625 || (symbolTable != NULL && !IS_USER_ADDRESS(symbolTable)) 2626 || (stringTable != NULL && !IS_USER_ADDRESS(stringTable))) { 2627 return B_BAD_ADDRESS; 2628 } 2629 } 2630 2631 // get buffer sizes 2632 int32 maxSymbolCount; 2633 size_t maxStringTableSize; 2634 if (kernel) { 2635 maxSymbolCount = *_symbolCount; 2636 maxStringTableSize = *_stringTableSize; 2637 } else { 2638 if (user_memcpy(&maxSymbolCount, _symbolCount, sizeof(maxSymbolCount)) 2639 != B_OK 2640 || user_memcpy(&maxStringTableSize, _stringTableSize, 2641 sizeof(maxStringTableSize)) != B_OK) { 2642 return B_BAD_ADDRESS; 2643 } 2644 } 2645 2646 // find the image 2647 MutexLocker _(sImageMutex); 2648 struct elf_image_info* image = find_image(id); 2649 if (image == NULL) 2650 return B_ENTRY_NOT_FOUND; 2651 2652 // get the tables and infos 2653 addr_t imageDelta = image->text_region.delta; 2654 const elf_sym* symbols; 2655 int32 symbolCount; 2656 const char* strings; 2657 2658 if (image->debug_symbols != NULL) { 2659 symbols = image->debug_symbols; 2660 symbolCount = image->num_debug_symbols; 2661 strings = image->debug_string_table; 2662 } else { 2663 symbols = image->syms; 2664 symbolCount = image->symhash[1]; 2665 strings = image->strtab; 2666 } 2667 2668 // The string table size isn't stored in the elf_image_info structure. Find 2669 // out by iterating through all symbols. 2670 size_t stringTableSize = 0; 2671 for (int32 i = 0; i < symbolCount; i++) { 2672 size_t index = symbols[i].st_name; 2673 if (index > stringTableSize) 2674 stringTableSize = index; 2675 } 2676 stringTableSize += strlen(strings + stringTableSize) + 1; 2677 // add size of the last string 2678 2679 // copy symbol table 2680 int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount); 2681 if (symbolTable != NULL && symbolsToCopy > 0) { 2682 if (kernel) { 2683 memcpy(symbolTable, symbols, sizeof(elf_sym) * symbolsToCopy); 2684 } else if (user_memcpy(symbolTable, symbols, 2685 sizeof(elf_sym) * symbolsToCopy) != B_OK) { 2686 return B_BAD_ADDRESS; 2687 } 2688 } 2689 2690 // copy string table 2691 size_t stringsToCopy = min_c(stringTableSize, maxStringTableSize); 2692 if (stringTable != NULL && stringsToCopy > 0) { 2693 if (kernel) { 2694 memcpy(stringTable, strings, stringsToCopy); 2695 } else { 2696 if (user_memcpy(stringTable, strings, stringsToCopy) 2697 != B_OK) { 2698 return B_BAD_ADDRESS; 2699 } 2700 } 2701 } 2702 2703 // copy sizes 2704 if (kernel) { 2705 *_symbolCount = symbolCount; 2706 *_stringTableSize = stringTableSize; 2707 if (_imageDelta != NULL) 2708 *_imageDelta = imageDelta; 2709 } else { 2710 if (user_memcpy(_symbolCount, &symbolCount, sizeof(symbolCount)) != B_OK 2711 || user_memcpy(_stringTableSize, &stringTableSize, 2712 sizeof(stringTableSize)) != B_OK 2713 || (_imageDelta != NULL && user_memcpy(_imageDelta, &imageDelta, 2714 sizeof(imageDelta)) != B_OK)) { 2715 return B_BAD_ADDRESS; 2716 } 2717 } 2718 2719 return B_OK; 2720 } 2721 2722 2723 status_t 2724 elf_init(kernel_args *args) 2725 { 2726 struct preloaded_image *image; 2727 2728 image_init(); 2729 2730 sImagesHash = new(std::nothrow) ImageHash(); 2731 if (sImagesHash == NULL) 2732 return B_NO_MEMORY; 2733 status_t init = sImagesHash->Init(IMAGE_HASH_SIZE); 2734 if (init != B_OK) 2735 return init; 2736 2737 // Build a image structure for the kernel, which has already been loaded. 2738 // The preloaded_images were already prepared by the VM. 2739 image = args->kernel_image; 2740 if (insert_preloaded_image(static_cast<preloaded_elf_image *>(image), 2741 true) < B_OK) 2742 panic("could not create kernel image.\n"); 2743 2744 // Build image structures for all preloaded images. 2745 for (image = args->preloaded_images; image != NULL; image = image->next) 2746 insert_preloaded_image(static_cast<preloaded_elf_image *>(image), 2747 false); 2748 2749 add_debugger_command("ls", &dump_address_info, 2750 "lookup symbol for a particular address"); 2751 add_debugger_command("symbols", &dump_symbols, "dump symbols for image"); 2752 add_debugger_command("symbol", &dump_symbol, "search symbol in images"); 2753 add_debugger_command_etc("image", &dump_image, "dump image info", 2754 "Prints info about the specified image.\n" 2755 " <image> - pointer to the semaphore structure, or ID\n" 2756 " of the image to print info for.\n", 0); 2757 2758 sInitialized = true; 2759 return B_OK; 2760 } 2761 2762 2763 // #pragma mark - 2764 2765 2766 /*! Reads the symbol and string table for the kernel image with the given ID. 2767 \a _symbolCount and \a _stringTableSize are both in- and output parameters. 2768 When called they call the size of the buffers given by \a symbolTable and 2769 \a stringTable respectively. When the function returns successfully, they 2770 will contain the actual sizes (which can be greater than the original ones). 2771 The function will copy as much as possible into the buffers. For only 2772 getting the required buffer sizes, it can be invoked with \c NULL buffers. 2773 On success \a _imageDelta will contain the offset to be added to the symbol 2774 values in the table to get the actual symbol addresses. 2775 */ 2776 status_t 2777 _user_read_kernel_image_symbols(image_id id, elf_sym* symbolTable, 2778 int32* _symbolCount, char* stringTable, size_t* _stringTableSize, 2779 addr_t* _imageDelta) 2780 { 2781 return elf_read_kernel_image_symbols(id, symbolTable, _symbolCount, 2782 stringTable, _stringTableSize, _imageDelta, false); 2783 } 2784 2785 #endif // ELF32_COMPAT 2786 2787