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