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 if (image->dynamic_section == 0 || HASHTABSIZE(image) == 0) 527 return NULL; 528 529 uint32 hash = elf_hash(name) % HASHTABSIZE(image); 530 for (uint32 i = HASHBUCKETS(image)[hash]; i != STN_UNDEF; 531 i = HASHCHAINS(image)[i]) { 532 if (!strcmp(SYMNAME(image, &image->syms[i]), name)) 533 return &image->syms[i]; 534 } 535 536 return NULL; 537 } 538 539 540 static status_t 541 elf_parse_dynamic_section(struct elf_image_info *image) 542 { 543 struct Elf32_Dyn *d; 544 int32 neededOffset = -1; 545 546 TRACE(("top of elf_parse_dynamic_section\n")); 547 548 image->symhash = 0; 549 image->syms = 0; 550 image->strtab = 0; 551 552 d = (struct Elf32_Dyn *)image->dynamic_section; 553 if (!d) 554 return B_ERROR; 555 556 for (int32 i = 0; d[i].d_tag != DT_NULL; i++) { 557 switch (d[i].d_tag) { 558 case DT_NEEDED: 559 neededOffset = d[i].d_un.d_ptr + image->text_region.delta; 560 break; 561 case DT_HASH: 562 image->symhash = (uint32 *)(d[i].d_un.d_ptr 563 + image->text_region.delta); 564 break; 565 case DT_STRTAB: 566 image->strtab = (char *)(d[i].d_un.d_ptr 567 + image->text_region.delta); 568 break; 569 case DT_SYMTAB: 570 image->syms = (struct Elf32_Sym *)(d[i].d_un.d_ptr 571 + image->text_region.delta); 572 break; 573 case DT_REL: 574 image->rel = (struct Elf32_Rel *)(d[i].d_un.d_ptr 575 + image->text_region.delta); 576 break; 577 case DT_RELSZ: 578 image->rel_len = d[i].d_un.d_val; 579 break; 580 case DT_RELA: 581 image->rela = (struct Elf32_Rela *)(d[i].d_un.d_ptr 582 + image->text_region.delta); 583 break; 584 case DT_RELASZ: 585 image->rela_len = d[i].d_un.d_val; 586 break; 587 case DT_JMPREL: 588 image->pltrel = (struct Elf32_Rel *)(d[i].d_un.d_ptr 589 + image->text_region.delta); 590 break; 591 case DT_PLTRELSZ: 592 image->pltrel_len = d[i].d_un.d_val; 593 break; 594 case DT_PLTREL: 595 image->pltrel_type = d[i].d_un.d_val; 596 break; 597 598 default: 599 continue; 600 } 601 } 602 603 // lets make sure we found all the required sections 604 if (!image->symhash || !image->syms || !image->strtab) 605 return B_ERROR; 606 607 TRACE(("needed_offset = %ld\n", neededOffset)); 608 609 if (neededOffset >= 0) 610 image->needed = STRING(image, neededOffset); 611 612 return B_OK; 613 } 614 615 616 /*! Resolves the \a symbol by linking against \a sharedImage if necessary. 617 Returns the resolved symbol's address in \a _symbolAddress. 618 TODO: eventually get rid of "symbolPrepend" 619 */ 620 status_t 621 elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol, 622 struct elf_image_info *sharedImage, const char *symbolPrepend, 623 addr_t *_symbolAddress) 624 { 625 switch (symbol->st_shndx) { 626 case SHN_UNDEF: 627 { 628 struct Elf32_Sym *newSymbol; 629 char newNameBuffer[368]; 630 char *newName; 631 632 // patch the symbol name 633 if (symbolPrepend) { 634 newName = newNameBuffer; 635 strlcpy(newName, symbolPrepend, sizeof(newName)); 636 strlcat(newName, SYMNAME(image, symbol), sizeof(newName)); 637 } else 638 newName = SYMNAME(image, symbol); 639 640 // it's undefined, must be outside this image, try the other image 641 newSymbol = elf_find_symbol(sharedImage, newName); 642 if (newSymbol == NULL) { 643 dprintf("\"%s\": could not resolve symbol '%s'\n", 644 image->name, newName); 645 return B_MISSING_SYMBOL; 646 } 647 648 // make sure they're the same type 649 if (ELF32_ST_TYPE(symbol->st_info) 650 != ELF32_ST_TYPE(newSymbol->st_info)) { 651 dprintf("elf_resolve_symbol: found symbol '%s' in shared image " 652 "but wrong type\n", newName); 653 return B_MISSING_SYMBOL; 654 } 655 656 if (ELF32_ST_BIND(newSymbol->st_info) != STB_GLOBAL 657 && ELF32_ST_BIND(newSymbol->st_info) != STB_WEAK) { 658 TRACE(("elf_resolve_symbol: found symbol '%s' but not " 659 "exported\n", newName)); 660 return B_MISSING_SYMBOL; 661 } 662 663 *_symbolAddress = newSymbol->st_value 664 + sharedImage->text_region.delta; 665 return B_OK; 666 } 667 case SHN_ABS: 668 *_symbolAddress = symbol->st_value; 669 return B_OK; 670 case SHN_COMMON: 671 // ToDo: finish this 672 TRACE(("elf_resolve_symbol: COMMON symbol, finish me!\n")); 673 return B_ERROR; 674 675 default: 676 // standard symbol 677 *_symbolAddress = symbol->st_value + image->text_region.delta; 678 return B_OK; 679 } 680 } 681 682 683 /*! Until we have shared library support, just this links against the kernel */ 684 static int 685 elf_relocate(struct elf_image_info *image, const char *symbolPrepend) 686 { 687 int status = B_NO_ERROR; 688 689 TRACE(("top of elf_relocate\n")); 690 691 // deal with the rels first 692 if (image->rel) { 693 TRACE(("total %i relocs\n", 694 image->rel_len / (int)sizeof(struct Elf32_Rel))); 695 696 status = arch_elf_relocate_rel(image, symbolPrepend, sKernelImage, 697 image->rel, image->rel_len); 698 if (status < B_OK) 699 return status; 700 } 701 702 if (image->pltrel) { 703 TRACE(("total %i plt-relocs\n", 704 image->pltrel_len / (int)sizeof(struct Elf32_Rel))); 705 706 if (image->pltrel_type == DT_REL) { 707 status = arch_elf_relocate_rel(image, symbolPrepend, sKernelImage, 708 image->pltrel, image->pltrel_len); 709 } else { 710 status = arch_elf_relocate_rela(image, symbolPrepend, sKernelImage, 711 (struct Elf32_Rela *)image->pltrel, image->pltrel_len); 712 } 713 if (status < B_OK) 714 return status; 715 } 716 717 if (image->rela) { 718 status = arch_elf_relocate_rela(image, symbolPrepend, sKernelImage, 719 image->rela, image->rela_len); 720 if (status < B_OK) 721 return status; 722 } 723 724 return status; 725 } 726 727 728 static int 729 verify_eheader(struct Elf32_Ehdr *elfHeader) 730 { 731 if (memcmp(elfHeader->e_ident, ELF_MAGIC, 4) != 0) 732 return B_NOT_AN_EXECUTABLE; 733 734 if (elfHeader->e_ident[4] != ELFCLASS32) 735 return B_NOT_AN_EXECUTABLE; 736 737 if (elfHeader->e_phoff == 0) 738 return B_NOT_AN_EXECUTABLE; 739 740 if (elfHeader->e_phentsize < sizeof(struct Elf32_Phdr)) 741 return B_NOT_AN_EXECUTABLE; 742 743 return 0; 744 } 745 746 747 static status_t 748 unload_elf_image(struct elf_image_info *image) 749 { 750 if (atomic_add(&image->ref_count, -1) > 1) 751 return B_OK; 752 753 TRACE(("unload image %ld, %s\n", image->id, image->name)); 754 755 delete_area(image->text_region.id); 756 delete_area(image->data_region.id); 757 758 if (image->vnode) 759 vfs_put_vnode(image->vnode); 760 761 unregister_elf_image(image); 762 763 free(image->debug_symbols); 764 free((void*)image->debug_string_table); 765 free(image->elf_header); 766 free(image->name); 767 free(image); 768 769 return B_NO_ERROR; 770 } 771 772 773 static status_t 774 load_elf_symbol_table(int fd, struct elf_image_info *image) 775 { 776 struct Elf32_Ehdr *elfHeader = image->elf_header; 777 struct Elf32_Sym *symbolTable = NULL; 778 struct Elf32_Shdr *stringHeader = NULL; 779 uint32 numSymbols = 0; 780 char *stringTable; 781 status_t status; 782 ssize_t length; 783 int32 i; 784 785 // get section headers 786 787 ssize_t size = elfHeader->e_shnum * elfHeader->e_shentsize; 788 struct Elf32_Shdr *sectionHeaders = (struct Elf32_Shdr *)malloc(size); 789 if (sectionHeaders == NULL) { 790 dprintf("error allocating space for section headers\n"); 791 return B_NO_MEMORY; 792 } 793 794 length = read_pos(fd, elfHeader->e_shoff, sectionHeaders, size); 795 if (length < size) { 796 TRACE(("error reading in program headers\n")); 797 status = B_ERROR; 798 goto error1; 799 } 800 801 // find symbol table in section headers 802 803 for (i = 0; i < elfHeader->e_shnum; i++) { 804 if (sectionHeaders[i].sh_type == SHT_SYMTAB) { 805 stringHeader = §ionHeaders[sectionHeaders[i].sh_link]; 806 807 if (stringHeader->sh_type != SHT_STRTAB) { 808 TRACE(("doesn't link to string table\n")); 809 status = B_BAD_DATA; 810 goto error1; 811 } 812 813 // read in symbol table 814 symbolTable 815 = (struct Elf32_Sym *)malloc(size = sectionHeaders[i].sh_size); 816 if (symbolTable == NULL) { 817 status = B_NO_MEMORY; 818 goto error1; 819 } 820 821 length 822 = read_pos(fd, sectionHeaders[i].sh_offset, symbolTable, size); 823 if (length < size) { 824 TRACE(("error reading in symbol table\n")); 825 status = B_ERROR; 826 goto error1; 827 } 828 829 numSymbols = size / sizeof(struct Elf32_Sym); 830 break; 831 } 832 } 833 834 if (symbolTable == NULL) { 835 TRACE(("no symbol table\n")); 836 status = B_BAD_VALUE; 837 goto error1; 838 } 839 840 // read in string table 841 842 stringTable = (char *)malloc(size = stringHeader->sh_size); 843 if (stringTable == NULL) { 844 status = B_NO_MEMORY; 845 goto error2; 846 } 847 848 length = read_pos(fd, stringHeader->sh_offset, stringTable, size); 849 if (length < size) { 850 TRACE(("error reading in string table\n")); 851 status = B_ERROR; 852 goto error3; 853 } 854 855 TRACE(("loaded debug %ld symbols\n", numSymbols)); 856 857 // insert tables into image 858 image->debug_symbols = symbolTable; 859 image->num_debug_symbols = numSymbols; 860 image->debug_string_table = stringTable; 861 862 free(sectionHeaders); 863 return B_OK; 864 865 error3: 866 free(stringTable); 867 error2: 868 free(symbolTable); 869 error1: 870 free(sectionHeaders); 871 872 return status; 873 } 874 875 876 static status_t 877 insert_preloaded_image(struct preloaded_image *preloadedImage, bool kernel) 878 { 879 struct elf_image_info *image; 880 status_t status; 881 882 status = verify_eheader(&preloadedImage->elf_header); 883 if (status < B_OK) 884 return status; 885 886 image = create_image_struct(); 887 if (image == NULL) 888 return B_NO_MEMORY; 889 890 image->name = strdup(preloadedImage->name); 891 image->dynamic_section = preloadedImage->dynamic_section.start; 892 893 image->text_region = preloadedImage->text_region; 894 image->data_region = preloadedImage->data_region; 895 896 status = elf_parse_dynamic_section(image); 897 if (status < B_OK) 898 goto error1; 899 900 if (!kernel) { 901 status = elf_relocate(image, NULL); 902 if (status < B_OK) 903 goto error1; 904 } else 905 sKernelImage = image; 906 907 // copy debug symbols to the kernel heap 908 if (preloadedImage->debug_symbols != NULL) { 909 int32 debugSymbolsSize = sizeof(Elf32_Sym) 910 * preloadedImage->num_debug_symbols; 911 image->debug_symbols = (Elf32_Sym*)malloc(debugSymbolsSize); 912 if (image->debug_symbols != NULL) { 913 memcpy(image->debug_symbols, preloadedImage->debug_symbols, 914 debugSymbolsSize); 915 } 916 } 917 image->num_debug_symbols = preloadedImage->num_debug_symbols; 918 919 // copy debug string table to the kernel heap 920 if (preloadedImage->debug_string_table != NULL) { 921 image->debug_string_table = (char*)malloc( 922 preloadedImage->debug_string_table_size); 923 if (image->debug_string_table != NULL) { 924 memcpy((void*)image->debug_string_table, 925 preloadedImage->debug_string_table, 926 preloadedImage->debug_string_table_size); 927 } 928 } 929 930 register_elf_image(image); 931 preloadedImage->id = image->id; 932 // modules_init() uses this information to get the preloaded images 933 934 // we now no longer need to write to the text area anymore 935 set_area_protection(image->text_region.id, 936 B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA); 937 938 return B_OK; 939 940 error1: 941 free(image); 942 943 // clean up preloaded image resources (this image won't be used anymore) 944 delete_area(preloadedImage->text_region.id); 945 delete_area(preloadedImage->data_region.id); 946 preloadedImage->id = -1; 947 948 return status; 949 } 950 951 952 // #pragma mark - userland symbol lookup 953 954 955 class UserSymbolLookup { 956 public: 957 static UserSymbolLookup& Default() 958 { 959 return sLookup; 960 } 961 962 status_t Init(struct team* team) 963 { 964 // find the runtime loader debug area 965 vm_area* area = team->address_space->areas; 966 while (area != NULL) { 967 if (strcmp(area->name, RUNTIME_LOADER_DEBUG_AREA_NAME) == 0) 968 break; 969 area = area->address_space_next; 970 } 971 972 if (area == NULL) 973 return B_ERROR; 974 975 // copy the runtime loader data structure 976 if (!_Read((runtime_loader_debug_area*)area->base, fDebugArea)) 977 return B_BAD_ADDRESS; 978 979 return B_OK; 980 } 981 982 status_t LookupSymbolAddress(addr_t address, addr_t *_baseAddress, 983 const char **_symbolName, const char **_imageName, bool *_exactMatch) 984 { 985 // Note, that this function doesn't find all symbols that we would like 986 // to find. E.g. static functions do not appear in the symbol table 987 // as function symbols, but as sections without name and size. The 988 // .symtab section together with the .strtab section, which apparently 989 // differ from the tables referred to by the .dynamic section, also 990 // contain proper names and sizes for those symbols. Therefore, to get 991 // completely satisfying results, we would need to read those tables 992 // from the shared object. 993 994 // get the image for the address 995 image_t image; 996 status_t error = _FindImageAtAddress(address, image); 997 if (error != B_OK) 998 return error; 999 1000 strlcpy(fImageName, image.name, sizeof(fImageName)); 1001 1002 // symbol hash table size 1003 uint32 hashTabSize; 1004 if (!_Read(image.symhash, hashTabSize)) 1005 return B_BAD_ADDRESS; 1006 1007 // remote pointers to hash buckets and chains 1008 const uint32* hashBuckets = image.symhash + 2; 1009 const uint32* hashChains = image.symhash + 2 + hashTabSize; 1010 1011 const elf_region_t& textRegion = image.regions[0]; 1012 1013 // search the image for the symbol 1014 Elf32_Sym symbolFound; 1015 addr_t deltaFound = INT_MAX; 1016 bool exactMatch = false; 1017 1018 // to get rid of the erroneous "uninitialized" warnings 1019 symbolFound.st_name = 0; 1020 symbolFound.st_value = 0; 1021 1022 for (uint32 i = 0; i < hashTabSize; i++) { 1023 uint32 bucket; 1024 if (!_Read(&hashBuckets[i], bucket)) 1025 return B_BAD_ADDRESS; 1026 1027 for (uint32 j = bucket; j != STN_UNDEF; 1028 _Read(&hashChains[j], j) ? 0 : j = STN_UNDEF) { 1029 1030 Elf32_Sym symbol; 1031 if (!_Read(image.syms + j, symbol)) 1032 continue; 1033 1034 // The symbol table contains not only symbols referring to 1035 // functions and data symbols within the shared object, but also 1036 // referenced symbols of other shared objects, as well as 1037 // section and file references. We ignore everything but 1038 // function and data symbols that have an st_value != 0 (0 1039 // seems to be an indication for a symbol defined elsewhere 1040 // -- couldn't verify that in the specs though). 1041 if ((ELF32_ST_TYPE(symbol.st_info) != STT_FUNC 1042 && ELF32_ST_TYPE(symbol.st_info) != STT_OBJECT) 1043 || symbol.st_value == 0 1044 || symbol.st_value + symbol.st_size + textRegion.delta 1045 > textRegion.vmstart + textRegion.size) { 1046 continue; 1047 } 1048 1049 // skip symbols starting after the given address 1050 addr_t symbolAddress = symbol.st_value + textRegion.delta; 1051 if (symbolAddress > address) 1052 continue; 1053 addr_t symbolDelta = address - symbolAddress; 1054 1055 if (symbolDelta < deltaFound) { 1056 deltaFound = symbolDelta; 1057 symbolFound = symbol; 1058 1059 if (symbolDelta >= 0 && symbolDelta < symbol.st_size) { 1060 // exact match 1061 exactMatch = true; 1062 break; 1063 } 1064 } 1065 } 1066 } 1067 1068 if (_imageName) 1069 *_imageName = fImageName; 1070 1071 if (_symbolName) { 1072 *_symbolName = NULL; 1073 1074 if (deltaFound < INT_MAX) { 1075 if (_ReadString(image, symbolFound.st_name, fSymbolName, 1076 sizeof(fSymbolName))) { 1077 *_symbolName = fSymbolName; 1078 } else { 1079 // we can't get its name, so forget the symbol 1080 deltaFound = INT_MAX; 1081 } 1082 } 1083 } 1084 1085 if (_baseAddress) { 1086 if (deltaFound < INT_MAX) 1087 *_baseAddress = symbolFound.st_value + textRegion.delta; 1088 else 1089 *_baseAddress = textRegion.vmstart; 1090 } 1091 1092 if (_exactMatch) 1093 *_exactMatch = exactMatch; 1094 1095 return B_OK; 1096 } 1097 1098 status_t _FindImageAtAddress(addr_t address, image_t& image) 1099 { 1100 image_queue_t imageQueue; 1101 if (!_Read(fDebugArea.loaded_images, imageQueue)) 1102 return B_BAD_ADDRESS; 1103 1104 image_t* imageAddress = imageQueue.head; 1105 while (imageAddress != NULL) { 1106 if (!_Read(imageAddress, image)) 1107 return B_BAD_ADDRESS; 1108 1109 if (image.regions[0].vmstart <= address 1110 && address < image.regions[0].vmstart + image.regions[0].size) { 1111 return B_OK; 1112 } 1113 1114 imageAddress = image.next; 1115 } 1116 1117 return B_ENTRY_NOT_FOUND; 1118 } 1119 1120 bool _ReadString(const image_t& image, uint32 offset, char* buffer, 1121 size_t bufferSize) 1122 { 1123 const char* address = image.strtab + offset; 1124 1125 if (!IS_USER_ADDRESS(address)) 1126 return false; 1127 1128 return user_strlcpy(buffer, address, bufferSize) >= 0; 1129 } 1130 1131 template<typename T> bool _Read(const T* address, T& data); 1132 // gcc 2.95.3 doesn't like it defined in-place 1133 1134 private: 1135 runtime_loader_debug_area fDebugArea; 1136 char fImageName[B_OS_NAME_LENGTH]; 1137 char fSymbolName[256]; 1138 static UserSymbolLookup sLookup; 1139 }; 1140 1141 1142 template<typename T> 1143 bool 1144 UserSymbolLookup::_Read(const T* address, T& data) 1145 { 1146 if (!IS_USER_ADDRESS(address)) 1147 return false; 1148 1149 return user_memcpy(&data, address, sizeof(T)) == B_OK; 1150 } 1151 1152 1153 UserSymbolLookup UserSymbolLookup::sLookup; 1154 // doesn't need construction, but has an Init() method 1155 1156 1157 // #pragma mark - public kernel API 1158 1159 1160 status_t 1161 get_image_symbol(image_id id, const char *name, int32 symbolClass, 1162 void **_symbol) 1163 { 1164 struct elf_image_info *image; 1165 struct Elf32_Sym *symbol; 1166 status_t status = B_OK; 1167 1168 TRACE(("get_image_symbol(%s)\n", name)); 1169 1170 mutex_lock(&sImageMutex); 1171 1172 image = find_image(id); 1173 if (image == NULL) { 1174 status = B_BAD_IMAGE_ID; 1175 goto done; 1176 } 1177 1178 symbol = elf_find_symbol(image, name); 1179 if (symbol == NULL || symbol->st_shndx == SHN_UNDEF) { 1180 status = B_ENTRY_NOT_FOUND; 1181 goto done; 1182 } 1183 1184 // TODO: support the "symbolClass" parameter! 1185 1186 TRACE(("found: %lx (%lx + %lx)\n", 1187 symbol->st_value + image->text_region.delta, 1188 symbol->st_value, image->text_region.delta)); 1189 1190 *_symbol = (void *)(symbol->st_value + image->text_region.delta); 1191 1192 done: 1193 mutex_unlock(&sImageMutex); 1194 return status; 1195 } 1196 1197 1198 // #pragma mark - kernel private API 1199 1200 1201 /*! Looks up a symbol by address in all images loaded in kernel space. 1202 Note, if you need to call this function outside a debugger, make 1203 sure you fix locking and the way it returns its information, first! 1204 */ 1205 status_t 1206 elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress, 1207 const char **_symbolName, const char **_imageName, bool *_exactMatch) 1208 { 1209 struct elf_image_info *image; 1210 struct Elf32_Sym *symbolFound = NULL; 1211 const char *symbolName = NULL; 1212 addr_t deltaFound = INT_MAX; 1213 bool exactMatch = false; 1214 status_t status; 1215 1216 TRACE(("looking up %p\n", (void *)address)); 1217 1218 if (!sInitialized) 1219 return B_ERROR; 1220 1221 //mutex_lock(&sImageMutex); 1222 1223 image = find_image_at_address(address); 1224 // get image that may contain the address 1225 1226 if (image != NULL) { 1227 addr_t symbolDelta; 1228 uint32 i; 1229 int32 j; 1230 1231 TRACE((" image %p, base = %p, size = %p\n", image, 1232 (void *)image->text_region.start, (void *)image->text_region.size)); 1233 1234 if (image->debug_symbols != NULL) { 1235 // search extended debug symbol table (contains static symbols) 1236 1237 TRACE((" searching debug symbols...\n")); 1238 1239 for (i = 0; i < image->num_debug_symbols; i++) { 1240 struct Elf32_Sym *symbol = &image->debug_symbols[i]; 1241 1242 if (symbol->st_value == 0 || symbol->st_size 1243 >= image->text_region.size + image->data_region.size) 1244 continue; 1245 1246 symbolDelta 1247 = address - (symbol->st_value + image->text_region.delta); 1248 if (symbolDelta >= 0 && symbolDelta < symbol->st_size) 1249 exactMatch = true; 1250 1251 if (exactMatch || symbolDelta < deltaFound) { 1252 deltaFound = symbolDelta; 1253 symbolFound = symbol; 1254 symbolName = image->debug_string_table + symbol->st_name; 1255 1256 if (exactMatch) 1257 break; 1258 } 1259 } 1260 } else { 1261 // search standard symbol lookup table 1262 1263 TRACE((" searching standard symbols...\n")); 1264 1265 for (i = 0; i < HASHTABSIZE(image); i++) { 1266 for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; 1267 j = HASHCHAINS(image)[j]) { 1268 struct Elf32_Sym *symbol = &image->syms[j]; 1269 1270 if (symbol->st_value == 0 1271 || symbol->st_size >= image->text_region.size 1272 + image->data_region.size) 1273 continue; 1274 1275 symbolDelta = address - (long)(symbol->st_value 1276 + image->text_region.delta); 1277 if (symbolDelta >= 0 && symbolDelta < symbol->st_size) 1278 exactMatch = true; 1279 1280 if (exactMatch || symbolDelta < deltaFound) { 1281 deltaFound = symbolDelta; 1282 symbolFound = symbol; 1283 symbolName = SYMNAME(image, symbol); 1284 1285 if (exactMatch) 1286 goto symbol_found; 1287 } 1288 } 1289 } 1290 } 1291 } 1292 symbol_found: 1293 1294 if (symbolFound != NULL) { 1295 if (_symbolName) 1296 *_symbolName = symbolName; 1297 if (_imageName) 1298 *_imageName = image->name; 1299 if (_baseAddress) 1300 *_baseAddress = symbolFound->st_value + image->text_region.delta; 1301 if (_exactMatch) 1302 *_exactMatch = exactMatch; 1303 1304 status = B_OK; 1305 } else if (image != NULL) { 1306 TRACE(("symbol not found!\n")); 1307 1308 if (_symbolName) 1309 *_symbolName = NULL; 1310 if (_imageName) 1311 *_imageName = image->name; 1312 if (_baseAddress) 1313 *_baseAddress = image->text_region.start; 1314 if (_exactMatch) 1315 *_exactMatch = false; 1316 1317 status = B_OK; 1318 } else { 1319 TRACE(("image not found!\n")); 1320 status = B_ENTRY_NOT_FOUND; 1321 } 1322 1323 // Note, theoretically, all information we return back to our caller 1324 // would have to be locked - but since this function is only called 1325 // from the debugger, it's safe to do it this way 1326 1327 //mutex_unlock(&sImageMutex); 1328 1329 return status; 1330 } 1331 1332 1333 /*! Tries to find a matching user symbol for the given address. 1334 Note that the given team's address space must already be in effect. 1335 */ 1336 status_t 1337 elf_debug_lookup_user_symbol_address(struct team* team, addr_t address, 1338 addr_t *_baseAddress, const char **_symbolName, const char **_imageName, 1339 bool *_exactMatch) 1340 { 1341 if (team == NULL || team == team_get_kernel_team()) 1342 return B_BAD_VALUE; 1343 1344 UserSymbolLookup& lookup = UserSymbolLookup::Default(); 1345 status_t error = lookup.Init(team); 1346 if (error != B_OK) 1347 return error; 1348 1349 return lookup.LookupSymbolAddress(address, _baseAddress, _symbolName, 1350 _imageName, _exactMatch); 1351 } 1352 1353 1354 status_t 1355 elf_load_user_image(const char *path, struct team *team, int flags, 1356 addr_t *entry) 1357 { 1358 struct Elf32_Ehdr elfHeader; 1359 struct Elf32_Phdr *programHeaders = NULL; 1360 char baseName[B_OS_NAME_LENGTH]; 1361 status_t status; 1362 ssize_t length; 1363 int fd; 1364 int i; 1365 1366 TRACE(("elf_load: entry path '%s', team %p\n", path, team)); 1367 1368 fd = _kern_open(-1, path, O_RDONLY, 0); 1369 if (fd < 0) 1370 return fd; 1371 1372 struct stat st; 1373 status = _kern_read_stat(fd, NULL, false, &st, sizeof(st)); 1374 if (status != B_OK) 1375 return status; 1376 1377 // read and verify the ELF header 1378 1379 length = _kern_read(fd, 0, &elfHeader, sizeof(elfHeader)); 1380 if (length < B_OK) { 1381 status = length; 1382 goto error; 1383 } 1384 1385 if (length != sizeof(elfHeader)) { 1386 // short read 1387 status = B_NOT_AN_EXECUTABLE; 1388 goto error; 1389 } 1390 status = verify_eheader(&elfHeader); 1391 if (status < B_OK) 1392 goto error; 1393 1394 // read program header 1395 1396 programHeaders = (struct Elf32_Phdr *)malloc( 1397 elfHeader.e_phnum * elfHeader.e_phentsize); 1398 if (programHeaders == NULL) { 1399 dprintf("error allocating space for program headers\n"); 1400 status = B_NO_MEMORY; 1401 goto error; 1402 } 1403 1404 TRACE(("reading in program headers at 0x%lx, length 0x%x\n", 1405 elfHeader.e_phoff, elfHeader.e_phnum * elfHeader.e_phentsize)); 1406 length = _kern_read(fd, elfHeader.e_phoff, programHeaders, 1407 elfHeader.e_phnum * elfHeader.e_phentsize); 1408 if (length < B_OK) { 1409 status = length; 1410 dprintf("error reading in program headers\n"); 1411 goto error; 1412 } 1413 if (length != elfHeader.e_phnum * elfHeader.e_phentsize) { 1414 dprintf("short read while reading in program headers\n"); 1415 status = -1; 1416 goto error; 1417 } 1418 1419 // construct a nice name for the region we have to create below 1420 { 1421 int32 length; 1422 1423 const char *leaf = strrchr(path, '/'); 1424 if (leaf == NULL) 1425 leaf = path; 1426 else 1427 leaf++; 1428 1429 length = strlen(leaf); 1430 if (length > B_OS_NAME_LENGTH - 8) 1431 sprintf(baseName, "...%s", leaf + length + 8 - B_OS_NAME_LENGTH); 1432 else 1433 strcpy(baseName, leaf); 1434 } 1435 1436 // map the program's segments into memory 1437 1438 image_info imageInfo; 1439 memset(&imageInfo, 0, sizeof(image_info)); 1440 1441 for (i = 0; i < elfHeader.e_phnum; i++) { 1442 char regionName[B_OS_NAME_LENGTH]; 1443 char *regionAddress; 1444 area_id id; 1445 1446 if (programHeaders[i].p_type != PT_LOAD) 1447 continue; 1448 1449 regionAddress = (char *)ROUNDOWN(programHeaders[i].p_vaddr, 1450 B_PAGE_SIZE); 1451 if (programHeaders[i].p_flags & PF_WRITE) { 1452 // rw/data segment 1453 uint32 memUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1454 + programHeaders[i].p_memsz; 1455 uint32 fileUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1456 + programHeaders[i].p_filesz; 1457 1458 memUpperBound = ROUNDUP(memUpperBound, B_PAGE_SIZE); 1459 fileUpperBound = ROUNDUP(fileUpperBound, B_PAGE_SIZE); 1460 1461 sprintf(regionName, "%s_seg%drw", baseName, i); 1462 1463 id = vm_map_file(team->id, regionName, (void **)®ionAddress, 1464 B_EXACT_ADDRESS, fileUpperBound, 1465 B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, 1466 fd, ROUNDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); 1467 if (id < B_OK) { 1468 dprintf("error mapping file data: %s!\n", strerror(id)); 1469 status = B_NOT_AN_EXECUTABLE; 1470 goto error; 1471 } 1472 1473 imageInfo.data = regionAddress; 1474 imageInfo.data_size = memUpperBound; 1475 1476 // clean garbage brought by mmap (the region behind the file, 1477 // at least parts of it are the bss and have to be zeroed) 1478 uint32 start = (uint32)regionAddress 1479 + (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1480 + programHeaders[i].p_filesz; 1481 uint32 amount = fileUpperBound 1482 - (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1483 - (programHeaders[i].p_filesz); 1484 memset((void *)start, 0, amount); 1485 1486 // Check if we need extra storage for the bss - we have to do this if 1487 // the above region doesn't already comprise the memory size, too. 1488 1489 if (memUpperBound != fileUpperBound) { 1490 size_t bssSize = memUpperBound - fileUpperBound; 1491 1492 snprintf(regionName, B_OS_NAME_LENGTH, "%s_bss%d", baseName, i); 1493 1494 regionAddress += fileUpperBound; 1495 id = create_area_etc(team->id, regionName, 1496 (void **)®ionAddress, B_EXACT_ADDRESS, bssSize, 1497 B_NO_LOCK, B_READ_AREA | B_WRITE_AREA, 0); 1498 if (id < B_OK) { 1499 dprintf("error allocating bss area: %s!\n", strerror(id)); 1500 status = B_NOT_AN_EXECUTABLE; 1501 goto error; 1502 } 1503 } 1504 } else { 1505 // assume ro/text segment 1506 snprintf(regionName, B_OS_NAME_LENGTH, "%s_seg%dro", baseName, i); 1507 1508 size_t segmentSize = ROUNDUP(programHeaders[i].p_memsz 1509 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 1510 1511 id = vm_map_file(team->id, regionName, (void **)®ionAddress, 1512 B_EXACT_ADDRESS, segmentSize, 1513 B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP, 1514 fd, ROUNDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); 1515 if (id < B_OK) { 1516 dprintf("error mapping file text: %s!\n", strerror(id)); 1517 status = B_NOT_AN_EXECUTABLE; 1518 goto error; 1519 } 1520 1521 imageInfo.text = regionAddress; 1522 imageInfo.text_size = segmentSize; 1523 } 1524 } 1525 1526 // register the loaded image 1527 imageInfo.type = B_LIBRARY_IMAGE; 1528 imageInfo.device = st.st_dev; 1529 imageInfo.node = st.st_ino; 1530 strlcpy(imageInfo.name, path, sizeof(imageInfo.name)); 1531 1532 imageInfo.id = register_image(team, &imageInfo, sizeof(image_info)); 1533 if (imageInfo.id >= 0 && team_get_current_team_id() == team->id) 1534 user_debug_image_created(&imageInfo); 1535 // Don't care, if registering fails. It's not crucial. 1536 1537 TRACE(("elf_load: done!\n")); 1538 1539 *entry = elfHeader.e_entry; 1540 status = B_OK; 1541 1542 error: 1543 if (programHeaders) 1544 free(programHeaders); 1545 _kern_close(fd); 1546 1547 return status; 1548 } 1549 1550 1551 image_id 1552 load_kernel_add_on(const char *path) 1553 { 1554 struct Elf32_Phdr *programHeaders; 1555 struct Elf32_Ehdr *elfHeader; 1556 struct elf_image_info *image; 1557 const char *fileName; 1558 void *reservedAddress; 1559 addr_t start; 1560 size_t reservedSize; 1561 status_t status; 1562 ssize_t length; 1563 1564 TRACE(("elf_load_kspace: entry path '%s'\n", path)); 1565 1566 int fd = _kern_open(-1, path, O_RDONLY, 0); 1567 if (fd < 0) 1568 return fd; 1569 1570 struct vnode *vnode; 1571 status = vfs_get_vnode_from_fd(fd, true, &vnode); 1572 if (status < B_OK) 1573 goto error0; 1574 1575 // get the file name 1576 fileName = strrchr(path, '/'); 1577 if (fileName == NULL) 1578 fileName = path; 1579 else 1580 fileName++; 1581 1582 // Prevent someone else from trying to load this image 1583 mutex_lock(&sImageLoadMutex); 1584 1585 // make sure it's not loaded already. Search by vnode 1586 image = find_image_by_vnode(vnode); 1587 if (image) { 1588 atomic_add(&image->ref_count, 1); 1589 goto done; 1590 } 1591 1592 elfHeader = (struct Elf32_Ehdr *)malloc(sizeof(*elfHeader)); 1593 if (!elfHeader) { 1594 status = B_NO_MEMORY; 1595 goto error; 1596 } 1597 1598 length = _kern_read(fd, 0, elfHeader, sizeof(*elfHeader)); 1599 if (length < B_OK) { 1600 status = length; 1601 goto error1; 1602 } 1603 if (length != sizeof(*elfHeader)) { 1604 // short read 1605 status = B_NOT_AN_EXECUTABLE; 1606 goto error1; 1607 } 1608 status = verify_eheader(elfHeader); 1609 if (status < B_OK) 1610 goto error1; 1611 1612 image = create_image_struct(); 1613 if (!image) { 1614 status = B_NO_MEMORY; 1615 goto error1; 1616 } 1617 image->vnode = vnode; 1618 image->elf_header = elfHeader; 1619 image->name = strdup(path); 1620 1621 programHeaders = (struct Elf32_Phdr *)malloc(elfHeader->e_phnum 1622 * elfHeader->e_phentsize); 1623 if (programHeaders == NULL) { 1624 dprintf("%s: error allocating space for program headers\n", fileName); 1625 status = B_NO_MEMORY; 1626 goto error2; 1627 } 1628 1629 TRACE(("reading in program headers at 0x%lx, length 0x%x\n", 1630 elfHeader->e_phoff, elfHeader->e_phnum * elfHeader->e_phentsize)); 1631 1632 length = _kern_read(fd, elfHeader->e_phoff, programHeaders, 1633 elfHeader->e_phnum * elfHeader->e_phentsize); 1634 if (length < B_OK) { 1635 status = length; 1636 TRACE(("%s: error reading in program headers\n", fileName)); 1637 goto error3; 1638 } 1639 if (length != elfHeader->e_phnum * elfHeader->e_phentsize) { 1640 TRACE(("%s: short read while reading in program headers\n", fileName)); 1641 status = B_ERROR; 1642 goto error3; 1643 } 1644 1645 // determine how much space we need for all loaded segments 1646 1647 reservedSize = 0; 1648 length = 0; 1649 1650 for (int32 i = 0; i < elfHeader->e_phnum; i++) { 1651 size_t end; 1652 1653 if (programHeaders[i].p_type != PT_LOAD) 1654 continue; 1655 1656 length += ROUNDUP(programHeaders[i].p_memsz 1657 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 1658 1659 end = ROUNDUP(programHeaders[i].p_memsz + programHeaders[i].p_vaddr, 1660 B_PAGE_SIZE); 1661 if (end > reservedSize) 1662 reservedSize = end; 1663 } 1664 1665 // Check whether the segments have an unreasonable amount of unused space 1666 // inbetween. 1667 if ((ssize_t)reservedSize > length + 8 * 1024) { 1668 status = B_BAD_DATA; 1669 goto error1; 1670 } 1671 1672 // reserve that space and allocate the areas from that one 1673 if (vm_reserve_address_range(vm_kernel_address_space_id(), &reservedAddress, 1674 B_ANY_KERNEL_ADDRESS, reservedSize, 0) < B_OK) { 1675 status = B_NO_MEMORY; 1676 goto error3; 1677 } 1678 1679 start = (addr_t)reservedAddress; 1680 image->data_region.size = 0; 1681 image->text_region.size = 0; 1682 1683 for (int32 i = 0; i < elfHeader->e_phnum; i++) { 1684 char regionName[B_OS_NAME_LENGTH]; 1685 elf_region *region; 1686 1687 TRACE(("looking at program header %ld\n", i)); 1688 1689 switch (programHeaders[i].p_type) { 1690 case PT_LOAD: 1691 break; 1692 case PT_DYNAMIC: 1693 image->dynamic_section = programHeaders[i].p_vaddr; 1694 continue; 1695 default: 1696 dprintf("%s: unhandled pheader type 0x%lx\n", fileName, 1697 programHeaders[i].p_type); 1698 continue; 1699 } 1700 1701 // we're here, so it must be a PT_LOAD segment 1702 if (programHeaders[i].IsReadWrite()) { 1703 // this is the writable segment 1704 if (image->data_region.size != 0) { 1705 // we've already created this segment 1706 continue; 1707 } 1708 region = &image->data_region; 1709 1710 snprintf(regionName, B_OS_NAME_LENGTH, "%s_data", fileName); 1711 } else if (programHeaders[i].IsExecutable()) { 1712 // this is the non-writable segment 1713 if (image->text_region.size != 0) { 1714 // we've already created this segment 1715 continue; 1716 } 1717 region = &image->text_region; 1718 1719 snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", fileName); 1720 } else { 1721 dprintf("%s: weird program header flags 0x%lx\n", fileName, 1722 programHeaders[i].p_flags); 1723 continue; 1724 } 1725 1726 region->start = (addr_t)reservedAddress + ROUNDOWN( 1727 programHeaders[i].p_vaddr, B_PAGE_SIZE); 1728 region->size = ROUNDUP(programHeaders[i].p_memsz 1729 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 1730 region->id = create_area(regionName, (void **)®ion->start, 1731 B_EXACT_ADDRESS, region->size, B_FULL_LOCK, 1732 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); 1733 if (region->id < B_OK) { 1734 dprintf("%s: error allocating area: %s\n", fileName, 1735 strerror(region->id)); 1736 status = B_NOT_AN_EXECUTABLE; 1737 goto error4; 1738 } 1739 region->delta = -ROUNDOWN(programHeaders[i].p_vaddr, B_PAGE_SIZE); 1740 1741 TRACE(("elf_load_kspace: created area \"%s\" at %p\n", 1742 regionName, (void *)region->start)); 1743 1744 length = _kern_read(fd, programHeaders[i].p_offset, 1745 (void *)(region->start + (programHeaders[i].p_vaddr % B_PAGE_SIZE)), 1746 programHeaders[i].p_filesz); 1747 if (length < B_OK) { 1748 status = length; 1749 dprintf("%s: error reading in segment %ld\n", fileName, i); 1750 goto error5; 1751 } 1752 } 1753 1754 // get the segment order 1755 elf_region *firstRegion; 1756 elf_region *secondRegion; 1757 if (image->text_region.start < image->data_region.start) { 1758 firstRegion = &image->text_region; 1759 secondRegion = &image->data_region; 1760 } else { 1761 firstRegion = &image->data_region; 1762 secondRegion = &image->text_region; 1763 } 1764 1765 image->data_region.delta += image->data_region.start; 1766 image->text_region.delta += image->text_region.start; 1767 1768 // modify the dynamic ptr by the delta of the regions 1769 image->dynamic_section += image->text_region.delta; 1770 1771 status = elf_parse_dynamic_section(image); 1772 if (status < B_OK) 1773 goto error5; 1774 1775 status = elf_relocate(image, NULL); 1776 if (status < B_OK) 1777 goto error5; 1778 1779 // We needed to read in the contents of the "text" area, but 1780 // now we can protect it read-only/execute 1781 set_area_protection(image->text_region.id, 1782 B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA); 1783 1784 // There might be a hole between the two segments, and we don't need to 1785 // reserve this any longer 1786 vm_unreserve_address_range(vm_kernel_address_space_id(), reservedAddress, 1787 reservedSize); 1788 1789 // ToDo: this should be enabled by kernel settings! 1790 if (1) 1791 load_elf_symbol_table(fd, image); 1792 1793 free(programHeaders); 1794 mutex_lock(&sImageMutex); 1795 register_elf_image(image); 1796 mutex_unlock(&sImageMutex); 1797 1798 done: 1799 _kern_close(fd); 1800 mutex_unlock(&sImageLoadMutex); 1801 1802 return image->id; 1803 1804 error5: 1805 delete_area(image->data_region.id); 1806 delete_area(image->text_region.id); 1807 error4: 1808 vm_unreserve_address_range(vm_kernel_address_space_id(), reservedAddress, 1809 reservedSize); 1810 error3: 1811 free(programHeaders); 1812 error2: 1813 free(image); 1814 error1: 1815 free(elfHeader); 1816 error: 1817 mutex_unlock(&sImageLoadMutex); 1818 error0: 1819 dprintf("Could not load kernel add-on \"%s\": %s\n", path, 1820 strerror(status)); 1821 1822 if (vnode) 1823 vfs_put_vnode(vnode); 1824 _kern_close(fd); 1825 1826 return status; 1827 } 1828 1829 1830 status_t 1831 unload_kernel_add_on(image_id id) 1832 { 1833 struct elf_image_info *image; 1834 status_t status; 1835 1836 mutex_lock(&sImageLoadMutex); 1837 mutex_lock(&sImageMutex); 1838 1839 image = find_image(id); 1840 if (image != NULL) 1841 status = unload_elf_image(image); 1842 else 1843 status = B_BAD_IMAGE_ID; 1844 1845 mutex_unlock(&sImageMutex); 1846 mutex_unlock(&sImageLoadMutex); 1847 1848 return status; 1849 } 1850 1851 1852 status_t 1853 elf_get_image_info_for_address(addr_t address, image_info* info) 1854 { 1855 MutexLocker _(sImageMutex); 1856 struct elf_image_info* elfInfo = find_image_at_address(address); 1857 if (elfInfo == NULL) 1858 return B_ENTRY_NOT_FOUND; 1859 1860 info->id = elfInfo->id; 1861 info->type = B_SYSTEM_IMAGE; 1862 info->sequence = 0; 1863 info->init_order = 0; 1864 info->init_routine = NULL; 1865 info->term_routine = NULL; 1866 info->device = -1; 1867 info->node = -1; 1868 // TODO: We could actually fill device/node in. 1869 strlcpy(info->name, elfInfo->name, sizeof(info->name)); 1870 info->text = (void*)elfInfo->text_region.start; 1871 info->data = (void*)elfInfo->data_region.start; 1872 info->text_size = elfInfo->text_region.size; 1873 info->data_size = elfInfo->data_region.size; 1874 1875 return B_OK; 1876 } 1877 1878 1879 image_id 1880 elf_create_memory_image(const char* imageName, addr_t text, size_t textSize, 1881 addr_t data, size_t dataSize) 1882 { 1883 // allocate the image 1884 elf_image_info* image = create_image_struct(); 1885 if (image == NULL) 1886 return B_NO_MEMORY; 1887 MemoryDeleter imageDeleter(image); 1888 1889 // allocate symbol and string tables -- we allocate an empty symbol table, 1890 // so that elf_debug_lookup_symbol_address() won't try the dynamic symbol 1891 // table, which we don't have. 1892 Elf32_Sym* symbolTable = (Elf32_Sym*)malloc(0); 1893 char* stringTable = (char*)malloc(1); 1894 MemoryDeleter symbolTableDeleter(symbolTable); 1895 MemoryDeleter stringTableDeleter(stringTable); 1896 if (symbolTable == NULL || stringTable == NULL) 1897 return B_NO_MEMORY; 1898 1899 // the string table always contains the empty string 1900 stringTable[0] = '\0'; 1901 1902 image->debug_symbols = symbolTable; 1903 image->num_debug_symbols = 0; 1904 image->debug_string_table = stringTable; 1905 1906 // dup image name 1907 image->name = strdup(imageName); 1908 if (image->name == NULL) 1909 return B_NO_MEMORY; 1910 1911 // data and text region 1912 image->text_region.id = -1; 1913 image->text_region.start = text; 1914 image->text_region.size = textSize; 1915 image->text_region.delta = 0; 1916 1917 image->data_region.id = -1; 1918 image->data_region.start = data; 1919 image->data_region.size = dataSize; 1920 image->data_region.delta = 0; 1921 1922 mutex_lock(&sImageMutex); 1923 register_elf_image(image); 1924 image_id imageID = image->id; 1925 mutex_unlock(&sImageMutex); 1926 1927 // keep the allocated memory 1928 imageDeleter.Detach(); 1929 symbolTableDeleter.Detach(); 1930 stringTableDeleter.Detach(); 1931 1932 return imageID; 1933 } 1934 1935 1936 status_t 1937 elf_add_memory_image_symbol(image_id id, const char* name, addr_t address, 1938 size_t size, int32 type) 1939 { 1940 MutexLocker _(sImageMutex); 1941 1942 // get the image 1943 struct elf_image_info* image = find_image(id); 1944 if (image == NULL) 1945 return B_ENTRY_NOT_FOUND; 1946 1947 // get the current string table size 1948 size_t stringTableSize = 1; 1949 if (image->num_debug_symbols > 0) { 1950 for (uint32 i = image->num_debug_symbols - 1; i >= 0; i--) { 1951 int32 nameIndex = image->debug_symbols[i].st_name; 1952 if (nameIndex != 0) { 1953 stringTableSize = nameIndex 1954 + strlen(image->debug_string_table + nameIndex) + 1; 1955 break; 1956 } 1957 } 1958 } 1959 1960 // enter the name in the string table 1961 char* stringTable = (char*)image->debug_string_table; 1962 size_t stringIndex = 0; 1963 if (name != NULL) { 1964 size_t nameSize = strlen(name) + 1; 1965 stringIndex = stringTableSize; 1966 stringTableSize += nameSize; 1967 stringTable = (char*)realloc((char*)image->debug_string_table, 1968 stringTableSize); 1969 if (stringTable == NULL) 1970 return B_NO_MEMORY; 1971 image->debug_string_table = stringTable; 1972 memcpy(stringTable + stringIndex, name, nameSize); 1973 } 1974 1975 // resize the symbol table 1976 int32 symbolCount = image->num_debug_symbols + 1; 1977 Elf32_Sym* symbolTable = (Elf32_Sym*)realloc( 1978 (Elf32_Sym*)image->debug_symbols, sizeof(Elf32_Sym) * symbolCount); 1979 if (symbolTable == NULL) 1980 return B_NO_MEMORY; 1981 image->debug_symbols = symbolTable; 1982 1983 // enter the symbol 1984 Elf32_Sym& symbol = symbolTable[symbolCount - 1]; 1985 uint32 symbolType = type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC; 1986 symbol.st_name = stringIndex; 1987 symbol.st_value = address; 1988 symbol.st_size = size; 1989 symbol.st_info = ELF32_ST_INFO(STB_GLOBAL, symbolType); 1990 symbol.st_other = 0; 1991 symbol.st_shndx = 0; 1992 image->num_debug_symbols++; 1993 1994 return B_OK; 1995 } 1996 1997 1998 status_t 1999 elf_init(kernel_args *args) 2000 { 2001 struct preloaded_image *image; 2002 2003 image_init(); 2004 2005 sImagesHash = hash_init(IMAGE_HASH_SIZE, 0, image_compare, image_hash); 2006 if (sImagesHash == NULL) 2007 return B_NO_MEMORY; 2008 2009 // Build a image structure for the kernel, which has already been loaded. 2010 // The preloaded_images were already prepared by the VM. 2011 if (insert_preloaded_image(&args->kernel_image, true) < B_OK) 2012 panic("could not create kernel image.\n"); 2013 2014 // Build image structures for all preloaded images. 2015 for (image = args->preloaded_images; image != NULL; image = image->next) { 2016 insert_preloaded_image(image, false); 2017 } 2018 2019 add_debugger_command("ls", &dump_address_info, 2020 "lookup symbol for a particular address"); 2021 add_debugger_command("symbols", &dump_symbols, "dump symbols for image"); 2022 add_debugger_command("symbol", &dump_symbol, "search symbol in images"); 2023 add_debugger_command_etc("image", &dump_image, "dump image info", 2024 "Prints info about the specified image.\n" 2025 " <image> - pointer to the semaphore structure, or ID\n" 2026 " of the image to print info for.\n", 0); 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