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