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