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