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