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