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 case PT_EH_FRAME: 2292 // not implemented yet, but can be ignored 2293 continue; 2294 default: 2295 dprintf("%s: unhandled pheader type %#" B_PRIx32 "\n", fileName, 2296 programHeaders[i].p_type); 2297 continue; 2298 } 2299 2300 // we're here, so it must be a PT_LOAD segment 2301 2302 // Usually add-ons have two PT_LOAD headers: one for .data one or .text. 2303 // x86 and PPC may differ in permission bits for .data's PT_LOAD header 2304 // x86 is usually RW, PPC is RWE 2305 2306 // Some add-ons may have .text and .data concatenated in a single 2307 // PT_LOAD RWE header and we must map that to .text. 2308 if (programHeaders[i].IsReadWrite() 2309 && (!programHeaders[i].IsExecutable() 2310 || executableHeaderCount > 1)) { 2311 // this is the writable segment 2312 if (image->data_region.size != 0) { 2313 // we've already created this segment 2314 continue; 2315 } 2316 region = &image->data_region; 2317 2318 snprintf(regionName, B_OS_NAME_LENGTH, "%s_data", fileName); 2319 } else if (programHeaders[i].IsExecutable()) { 2320 // this is the non-writable segment 2321 if (image->text_region.size != 0) { 2322 // we've already created this segment 2323 continue; 2324 } 2325 region = &image->text_region; 2326 2327 // some programs may have .text and .data concatenated in a 2328 // single PT_LOAD section which is readable/writable/executable 2329 textSectionWritable = programHeaders[i].IsReadWrite(); 2330 snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", fileName); 2331 } else { 2332 dprintf("%s: weird program header flags %#" B_PRIx32 "\n", fileName, 2333 programHeaders[i].p_flags); 2334 continue; 2335 } 2336 2337 region->start = (addr_t)reservedAddress + ROUNDDOWN( 2338 programHeaders[i].p_vaddr, B_PAGE_SIZE); 2339 region->size = ROUNDUP(programHeaders[i].p_memsz 2340 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 2341 region->id = create_area(regionName, (void **)®ion->start, 2342 B_EXACT_ADDRESS, region->size, B_FULL_LOCK, 2343 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); 2344 if (region->id < B_OK) { 2345 dprintf("%s: error allocating area: %s\n", fileName, 2346 strerror(region->id)); 2347 status = B_NOT_AN_EXECUTABLE; 2348 goto error4; 2349 } 2350 region->delta = -ROUNDDOWN(programHeaders[i].p_vaddr, B_PAGE_SIZE); 2351 2352 TRACE(("elf_load_kspace: created area \"%s\" at %p\n", 2353 regionName, (void *)region->start)); 2354 2355 length = _kern_read(fd, programHeaders[i].p_offset, 2356 (void *)(region->start + (programHeaders[i].p_vaddr % B_PAGE_SIZE)), 2357 programHeaders[i].p_filesz); 2358 if (length < B_OK) { 2359 status = length; 2360 dprintf("%s: error reading in segment %" B_PRId32 "\n", fileName, 2361 i); 2362 goto error5; 2363 } 2364 } 2365 2366 image->data_region.delta += image->data_region.start; 2367 image->text_region.delta += image->text_region.start; 2368 2369 // modify the dynamic ptr by the delta of the regions 2370 image->dynamic_section += image->text_region.delta; 2371 2372 status = elf_parse_dynamic_section(image); 2373 if (status < B_OK) 2374 goto error5; 2375 2376 status = init_image_version_infos(image); 2377 if (status != B_OK) 2378 goto error5; 2379 2380 status = check_needed_image_versions(image); 2381 if (status != B_OK) 2382 goto error5; 2383 2384 status = elf_relocate(image, sKernelImage); 2385 if (status < B_OK) 2386 goto error5; 2387 2388 // We needed to read in the contents of the "text" area, but 2389 // now we can protect it read-only/execute, unless this is a 2390 // special image with concatenated .text and .data, when it 2391 // will also need write access. 2392 set_area_protection(image->text_region.id, 2393 B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA 2394 | (textSectionWritable ? B_KERNEL_WRITE_AREA : 0)); 2395 2396 // There might be a hole between the two segments, and we don't need to 2397 // reserve this any longer 2398 vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress, 2399 reservedSize); 2400 2401 if (sLoadElfSymbols) 2402 load_elf_symbol_table(fd, image); 2403 2404 free(programHeaders); 2405 mutex_lock(&sImageMutex); 2406 register_elf_image(image); 2407 mutex_unlock(&sImageMutex); 2408 2409 done: 2410 _kern_close(fd); 2411 mutex_unlock(&sImageLoadMutex); 2412 2413 return image->id; 2414 2415 error5: 2416 error4: 2417 vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress, 2418 reservedSize); 2419 error3: 2420 free(programHeaders); 2421 error2: 2422 delete_elf_image(image); 2423 elfHeader = NULL; 2424 error1: 2425 free(elfHeader); 2426 error: 2427 mutex_unlock(&sImageLoadMutex); 2428 error0: 2429 dprintf("Could not load kernel add-on \"%s\": %s\n", path, 2430 strerror(status)); 2431 2432 if (vnode) 2433 vfs_put_vnode(vnode); 2434 _kern_close(fd); 2435 2436 return status; 2437 } 2438 2439 2440 status_t 2441 unload_kernel_add_on(image_id id) 2442 { 2443 MutexLocker _(sImageLoadMutex); 2444 MutexLocker _2(sImageMutex); 2445 2446 elf_image_info *image = find_image(id); 2447 if (image == NULL) 2448 return B_BAD_IMAGE_ID; 2449 2450 unload_elf_image(image); 2451 return B_OK; 2452 } 2453 2454 2455 struct elf_image_info* 2456 elf_get_kernel_image() 2457 { 2458 return sKernelImage; 2459 } 2460 2461 2462 status_t 2463 elf_get_image_info_for_address(addr_t address, image_info* info) 2464 { 2465 MutexLocker _(sImageMutex); 2466 struct elf_image_info* elfInfo = find_image_at_address(address); 2467 if (elfInfo == NULL) 2468 return B_ENTRY_NOT_FOUND; 2469 2470 info->id = elfInfo->id; 2471 info->type = B_SYSTEM_IMAGE; 2472 info->sequence = 0; 2473 info->init_order = 0; 2474 info->init_routine = NULL; 2475 info->term_routine = NULL; 2476 info->device = -1; 2477 info->node = -1; 2478 // TODO: We could actually fill device/node in. 2479 strlcpy(info->name, elfInfo->name, sizeof(info->name)); 2480 info->text = (void*)elfInfo->text_region.start; 2481 info->data = (void*)elfInfo->data_region.start; 2482 info->text_size = elfInfo->text_region.size; 2483 info->data_size = elfInfo->data_region.size; 2484 2485 return B_OK; 2486 } 2487 2488 2489 image_id 2490 elf_create_memory_image(const char* imageName, addr_t text, size_t textSize, 2491 addr_t data, size_t dataSize) 2492 { 2493 // allocate the image 2494 elf_image_info* image = create_image_struct(); 2495 if (image == NULL) 2496 return B_NO_MEMORY; 2497 MemoryDeleter imageDeleter(image); 2498 2499 // allocate symbol and string tables -- we allocate an empty symbol table, 2500 // so that elf_debug_lookup_symbol_address() won't try the dynamic symbol 2501 // table, which we don't have. 2502 elf_sym* symbolTable = (elf_sym*)malloc(0); 2503 char* stringTable = (char*)malloc(1); 2504 MemoryDeleter symbolTableDeleter(symbolTable); 2505 MemoryDeleter stringTableDeleter(stringTable); 2506 if (symbolTable == NULL || stringTable == NULL) 2507 return B_NO_MEMORY; 2508 2509 // the string table always contains the empty string 2510 stringTable[0] = '\0'; 2511 2512 image->debug_symbols = symbolTable; 2513 image->num_debug_symbols = 0; 2514 image->debug_string_table = stringTable; 2515 2516 // dup image name 2517 image->name = strdup(imageName); 2518 if (image->name == NULL) 2519 return B_NO_MEMORY; 2520 2521 // data and text region 2522 image->text_region.id = -1; 2523 image->text_region.start = text; 2524 image->text_region.size = textSize; 2525 image->text_region.delta = 0; 2526 2527 image->data_region.id = -1; 2528 image->data_region.start = data; 2529 image->data_region.size = dataSize; 2530 image->data_region.delta = 0; 2531 2532 mutex_lock(&sImageMutex); 2533 register_elf_image(image); 2534 image_id imageID = image->id; 2535 mutex_unlock(&sImageMutex); 2536 2537 // keep the allocated memory 2538 imageDeleter.Detach(); 2539 symbolTableDeleter.Detach(); 2540 stringTableDeleter.Detach(); 2541 2542 return imageID; 2543 } 2544 2545 2546 status_t 2547 elf_add_memory_image_symbol(image_id id, const char* name, addr_t address, 2548 size_t size, int32 type) 2549 { 2550 MutexLocker _(sImageMutex); 2551 2552 // get the image 2553 struct elf_image_info* image = find_image(id); 2554 if (image == NULL) 2555 return B_ENTRY_NOT_FOUND; 2556 2557 // get the current string table size 2558 size_t stringTableSize = 1; 2559 if (image->num_debug_symbols > 0) { 2560 for (int32 i = image->num_debug_symbols - 1; i >= 0; i--) { 2561 int32 nameIndex = image->debug_symbols[i].st_name; 2562 if (nameIndex != 0) { 2563 stringTableSize = nameIndex 2564 + strlen(image->debug_string_table + nameIndex) + 1; 2565 break; 2566 } 2567 } 2568 } 2569 2570 // enter the name in the string table 2571 char* stringTable = (char*)image->debug_string_table; 2572 size_t stringIndex = 0; 2573 if (name != NULL) { 2574 size_t nameSize = strlen(name) + 1; 2575 stringIndex = stringTableSize; 2576 stringTableSize += nameSize; 2577 stringTable = (char*)realloc((char*)image->debug_string_table, 2578 stringTableSize); 2579 if (stringTable == NULL) 2580 return B_NO_MEMORY; 2581 image->debug_string_table = stringTable; 2582 memcpy(stringTable + stringIndex, name, nameSize); 2583 } 2584 2585 // resize the symbol table 2586 int32 symbolCount = image->num_debug_symbols + 1; 2587 elf_sym* symbolTable = (elf_sym*)realloc( 2588 (elf_sym*)image->debug_symbols, sizeof(elf_sym) * symbolCount); 2589 if (symbolTable == NULL) 2590 return B_NO_MEMORY; 2591 image->debug_symbols = symbolTable; 2592 2593 // enter the symbol 2594 elf_sym& symbol = symbolTable[symbolCount - 1]; 2595 symbol.SetInfo(STB_GLOBAL, 2596 type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC); 2597 symbol.st_name = stringIndex; 2598 symbol.st_value = address; 2599 symbol.st_size = size; 2600 symbol.st_other = 0; 2601 symbol.st_shndx = 0; 2602 image->num_debug_symbols++; 2603 2604 return B_OK; 2605 } 2606 2607 2608 /*! Reads the symbol and string table for the kernel image with the given ID. 2609 \a _symbolCount and \a _stringTableSize are both in- and output parameters. 2610 When called they call the size of the buffers given by \a symbolTable and 2611 \a stringTable respectively. When the function returns successfully, they 2612 will contain the actual sizes (which can be greater than the original ones). 2613 The function will copy as much as possible into the buffers. For only 2614 getting the required buffer sizes, it can be invoked with \c NULL buffers. 2615 On success \a _imageDelta will contain the offset to be added to the symbol 2616 values in the table to get the actual symbol addresses. 2617 */ 2618 status_t 2619 elf_read_kernel_image_symbols(image_id id, elf_sym* symbolTable, 2620 int32* _symbolCount, char* stringTable, size_t* _stringTableSize, 2621 addr_t* _imageDelta, bool kernel) 2622 { 2623 // check params 2624 if (_symbolCount == NULL || _stringTableSize == NULL) 2625 return B_BAD_VALUE; 2626 if (!kernel) { 2627 if (!IS_USER_ADDRESS(_symbolCount) || !IS_USER_ADDRESS(_stringTableSize) 2628 || (_imageDelta != NULL && !IS_USER_ADDRESS(_imageDelta)) 2629 || (symbolTable != NULL && !IS_USER_ADDRESS(symbolTable)) 2630 || (stringTable != NULL && !IS_USER_ADDRESS(stringTable))) { 2631 return B_BAD_ADDRESS; 2632 } 2633 } 2634 2635 // get buffer sizes 2636 int32 maxSymbolCount; 2637 size_t maxStringTableSize; 2638 if (kernel) { 2639 maxSymbolCount = *_symbolCount; 2640 maxStringTableSize = *_stringTableSize; 2641 } else { 2642 if (user_memcpy(&maxSymbolCount, _symbolCount, sizeof(maxSymbolCount)) 2643 != B_OK 2644 || user_memcpy(&maxStringTableSize, _stringTableSize, 2645 sizeof(maxStringTableSize)) != B_OK) { 2646 return B_BAD_ADDRESS; 2647 } 2648 } 2649 2650 // find the image 2651 MutexLocker _(sImageMutex); 2652 struct elf_image_info* image = find_image(id); 2653 if (image == NULL) 2654 return B_ENTRY_NOT_FOUND; 2655 2656 // get the tables and infos 2657 addr_t imageDelta = image->text_region.delta; 2658 const elf_sym* symbols; 2659 int32 symbolCount; 2660 const char* strings; 2661 2662 if (image->debug_symbols != NULL) { 2663 symbols = image->debug_symbols; 2664 symbolCount = image->num_debug_symbols; 2665 strings = image->debug_string_table; 2666 } else { 2667 symbols = image->syms; 2668 symbolCount = image->symhash[1]; 2669 strings = image->strtab; 2670 } 2671 2672 // The string table size isn't stored in the elf_image_info structure. Find 2673 // out by iterating through all symbols. 2674 size_t stringTableSize = 0; 2675 for (int32 i = 0; i < symbolCount; i++) { 2676 size_t index = symbols[i].st_name; 2677 if (index > stringTableSize) 2678 stringTableSize = index; 2679 } 2680 stringTableSize += strlen(strings + stringTableSize) + 1; 2681 // add size of the last string 2682 2683 // copy symbol table 2684 int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount); 2685 if (symbolTable != NULL && symbolsToCopy > 0) { 2686 if (kernel) { 2687 memcpy(symbolTable, symbols, sizeof(elf_sym) * symbolsToCopy); 2688 } else if (user_memcpy(symbolTable, symbols, 2689 sizeof(elf_sym) * symbolsToCopy) != B_OK) { 2690 return B_BAD_ADDRESS; 2691 } 2692 } 2693 2694 // copy string table 2695 size_t stringsToCopy = min_c(stringTableSize, maxStringTableSize); 2696 if (stringTable != NULL && stringsToCopy > 0) { 2697 if (kernel) { 2698 memcpy(stringTable, strings, stringsToCopy); 2699 } else { 2700 if (user_memcpy(stringTable, strings, stringsToCopy) 2701 != B_OK) { 2702 return B_BAD_ADDRESS; 2703 } 2704 } 2705 } 2706 2707 // copy sizes 2708 if (kernel) { 2709 *_symbolCount = symbolCount; 2710 *_stringTableSize = stringTableSize; 2711 if (_imageDelta != NULL) 2712 *_imageDelta = imageDelta; 2713 } else { 2714 if (user_memcpy(_symbolCount, &symbolCount, sizeof(symbolCount)) != B_OK 2715 || user_memcpy(_stringTableSize, &stringTableSize, 2716 sizeof(stringTableSize)) != B_OK 2717 || (_imageDelta != NULL && user_memcpy(_imageDelta, &imageDelta, 2718 sizeof(imageDelta)) != B_OK)) { 2719 return B_BAD_ADDRESS; 2720 } 2721 } 2722 2723 return B_OK; 2724 } 2725 2726 2727 status_t 2728 elf_init(kernel_args* args) 2729 { 2730 struct preloaded_image* image; 2731 2732 image_init(); 2733 2734 if (void* handle = load_driver_settings("kernel")) { 2735 sLoadElfSymbols = get_driver_boolean_parameter(handle, "load_symbols", 2736 false, false); 2737 2738 unload_driver_settings(handle); 2739 } 2740 2741 sImagesHash = new(std::nothrow) ImageHash(); 2742 if (sImagesHash == NULL) 2743 return B_NO_MEMORY; 2744 status_t init = sImagesHash->Init(IMAGE_HASH_SIZE); 2745 if (init != B_OK) 2746 return init; 2747 2748 // Build a image structure for the kernel, which has already been loaded. 2749 // The preloaded_images were already prepared by the VM. 2750 image = args->kernel_image; 2751 if (insert_preloaded_image(static_cast<preloaded_elf_image *>(image), 2752 true) < B_OK) 2753 panic("could not create kernel image.\n"); 2754 2755 // Build image structures for all preloaded images. 2756 for (image = args->preloaded_images; image != NULL; image = image->next) 2757 insert_preloaded_image(static_cast<preloaded_elf_image *>(image), 2758 false); 2759 2760 add_debugger_command("ls", &dump_address_info, 2761 "lookup symbol for a particular address"); 2762 add_debugger_command("symbols", &dump_symbols, "dump symbols for image"); 2763 add_debugger_command("symbol", &dump_symbol, "search symbol in images"); 2764 add_debugger_command_etc("image", &dump_image, "dump image info", 2765 "Prints info about the specified image.\n" 2766 " <image> - pointer to the semaphore structure, or ID\n" 2767 " of the image to print info for.\n", 0); 2768 2769 sInitialized = true; 2770 return B_OK; 2771 } 2772 2773 2774 // #pragma mark - 2775 2776 2777 /*! Reads the symbol and string table for the kernel image with the given ID. 2778 \a _symbolCount and \a _stringTableSize are both in- and output parameters. 2779 When called they call the size of the buffers given by \a symbolTable and 2780 \a stringTable respectively. When the function returns successfully, they 2781 will contain the actual sizes (which can be greater than the original ones). 2782 The function will copy as much as possible into the buffers. For only 2783 getting the required buffer sizes, it can be invoked with \c NULL buffers. 2784 On success \a _imageDelta will contain the offset to be added to the symbol 2785 values in the table to get the actual symbol addresses. 2786 */ 2787 status_t 2788 _user_read_kernel_image_symbols(image_id id, elf_sym* symbolTable, 2789 int32* _symbolCount, char* stringTable, size_t* _stringTableSize, 2790 addr_t* _imageDelta) 2791 { 2792 return elf_read_kernel_image_symbols(id, symbolTable, _symbolCount, 2793 stringTable, _stringTableSize, _imageDelta, false); 2794 } 2795 2796 #endif // ELF32_COMPAT 2797 2798