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