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 if (programHeaders) 1937 free(programHeaders); 1938 _kern_close(fd); 1939 1940 return status; 1941 } 1942 1943 1944 image_id 1945 load_kernel_add_on(const char *path) 1946 { 1947 struct Elf32_Phdr *programHeaders; 1948 struct Elf32_Ehdr *elfHeader; 1949 struct elf_image_info *image; 1950 const char *fileName; 1951 void *reservedAddress; 1952 addr_t start; 1953 size_t reservedSize; 1954 status_t status; 1955 ssize_t length; 1956 1957 TRACE(("elf_load_kspace: entry path '%s'\n", path)); 1958 1959 int fd = _kern_open(-1, path, O_RDONLY, 0); 1960 if (fd < 0) 1961 return fd; 1962 1963 struct vnode *vnode; 1964 status = vfs_get_vnode_from_fd(fd, true, &vnode); 1965 if (status < B_OK) 1966 goto error0; 1967 1968 // get the file name 1969 fileName = strrchr(path, '/'); 1970 if (fileName == NULL) 1971 fileName = path; 1972 else 1973 fileName++; 1974 1975 // Prevent someone else from trying to load this image 1976 mutex_lock(&sImageLoadMutex); 1977 1978 // make sure it's not loaded already. Search by vnode 1979 image = find_image_by_vnode(vnode); 1980 if (image) { 1981 atomic_add(&image->ref_count, 1); 1982 goto done; 1983 } 1984 1985 elfHeader = (struct Elf32_Ehdr *)malloc(sizeof(*elfHeader)); 1986 if (!elfHeader) { 1987 status = B_NO_MEMORY; 1988 goto error; 1989 } 1990 1991 length = _kern_read(fd, 0, elfHeader, sizeof(*elfHeader)); 1992 if (length < B_OK) { 1993 status = length; 1994 goto error1; 1995 } 1996 if (length != sizeof(*elfHeader)) { 1997 // short read 1998 status = B_NOT_AN_EXECUTABLE; 1999 goto error1; 2000 } 2001 status = verify_eheader(elfHeader); 2002 if (status < B_OK) 2003 goto error1; 2004 2005 image = create_image_struct(); 2006 if (!image) { 2007 status = B_NO_MEMORY; 2008 goto error1; 2009 } 2010 image->vnode = vnode; 2011 image->elf_header = elfHeader; 2012 image->name = strdup(path); 2013 vnode = NULL; 2014 2015 programHeaders = (struct Elf32_Phdr *)malloc(elfHeader->e_phnum 2016 * elfHeader->e_phentsize); 2017 if (programHeaders == NULL) { 2018 dprintf("%s: error allocating space for program headers\n", fileName); 2019 status = B_NO_MEMORY; 2020 goto error2; 2021 } 2022 2023 TRACE(("reading in program headers at 0x%lx, length 0x%x\n", 2024 elfHeader->e_phoff, elfHeader->e_phnum * elfHeader->e_phentsize)); 2025 2026 length = _kern_read(fd, elfHeader->e_phoff, programHeaders, 2027 elfHeader->e_phnum * elfHeader->e_phentsize); 2028 if (length < B_OK) { 2029 status = length; 2030 TRACE(("%s: error reading in program headers\n", fileName)); 2031 goto error3; 2032 } 2033 if (length != elfHeader->e_phnum * elfHeader->e_phentsize) { 2034 TRACE(("%s: short read while reading in program headers\n", fileName)); 2035 status = B_ERROR; 2036 goto error3; 2037 } 2038 2039 // determine how much space we need for all loaded segments 2040 2041 reservedSize = 0; 2042 length = 0; 2043 2044 for (int32 i = 0; i < elfHeader->e_phnum; i++) { 2045 size_t end; 2046 2047 if (programHeaders[i].p_type != PT_LOAD) 2048 continue; 2049 2050 length += ROUNDUP(programHeaders[i].p_memsz 2051 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 2052 2053 end = ROUNDUP(programHeaders[i].p_memsz + programHeaders[i].p_vaddr, 2054 B_PAGE_SIZE); 2055 if (end > reservedSize) 2056 reservedSize = end; 2057 } 2058 2059 // Check whether the segments have an unreasonable amount of unused space 2060 // inbetween. 2061 if ((ssize_t)reservedSize > length + 8 * 1024) { 2062 status = B_BAD_DATA; 2063 goto error1; 2064 } 2065 2066 // reserve that space and allocate the areas from that one 2067 if (vm_reserve_address_range(VMAddressSpace::KernelID(), &reservedAddress, 2068 B_ANY_KERNEL_ADDRESS, reservedSize, 0) < B_OK) { 2069 status = B_NO_MEMORY; 2070 goto error3; 2071 } 2072 2073 start = (addr_t)reservedAddress; 2074 image->data_region.size = 0; 2075 image->text_region.size = 0; 2076 2077 for (int32 i = 0; i < elfHeader->e_phnum; i++) { 2078 char regionName[B_OS_NAME_LENGTH]; 2079 elf_region *region; 2080 2081 TRACE(("looking at program header %ld\n", i)); 2082 2083 switch (programHeaders[i].p_type) { 2084 case PT_LOAD: 2085 break; 2086 case PT_DYNAMIC: 2087 image->dynamic_section = programHeaders[i].p_vaddr; 2088 continue; 2089 default: 2090 dprintf("%s: unhandled pheader type 0x%lx\n", fileName, 2091 programHeaders[i].p_type); 2092 continue; 2093 } 2094 2095 // we're here, so it must be a PT_LOAD segment 2096 if (programHeaders[i].IsReadWrite()) { 2097 // this is the writable segment 2098 if (image->data_region.size != 0) { 2099 // we've already created this segment 2100 continue; 2101 } 2102 region = &image->data_region; 2103 2104 snprintf(regionName, B_OS_NAME_LENGTH, "%s_data", fileName); 2105 } else if (programHeaders[i].IsExecutable()) { 2106 // this is the non-writable segment 2107 if (image->text_region.size != 0) { 2108 // we've already created this segment 2109 continue; 2110 } 2111 region = &image->text_region; 2112 2113 snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", fileName); 2114 } else { 2115 dprintf("%s: weird program header flags 0x%lx\n", fileName, 2116 programHeaders[i].p_flags); 2117 continue; 2118 } 2119 2120 region->start = (addr_t)reservedAddress + ROUNDDOWN( 2121 programHeaders[i].p_vaddr, B_PAGE_SIZE); 2122 region->size = ROUNDUP(programHeaders[i].p_memsz 2123 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 2124 region->id = create_area(regionName, (void **)®ion->start, 2125 B_EXACT_ADDRESS, region->size, B_FULL_LOCK, 2126 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); 2127 if (region->id < B_OK) { 2128 dprintf("%s: error allocating area: %s\n", fileName, 2129 strerror(region->id)); 2130 status = B_NOT_AN_EXECUTABLE; 2131 goto error4; 2132 } 2133 region->delta = -ROUNDDOWN(programHeaders[i].p_vaddr, B_PAGE_SIZE); 2134 2135 TRACE(("elf_load_kspace: created area \"%s\" at %p\n", 2136 regionName, (void *)region->start)); 2137 2138 length = _kern_read(fd, programHeaders[i].p_offset, 2139 (void *)(region->start + (programHeaders[i].p_vaddr % B_PAGE_SIZE)), 2140 programHeaders[i].p_filesz); 2141 if (length < B_OK) { 2142 status = length; 2143 dprintf("%s: error reading in segment %ld\n", fileName, i); 2144 goto error5; 2145 } 2146 } 2147 2148 // get the segment order 2149 elf_region *firstRegion; 2150 elf_region *secondRegion; 2151 if (image->text_region.start < image->data_region.start) { 2152 firstRegion = &image->text_region; 2153 secondRegion = &image->data_region; 2154 } else { 2155 firstRegion = &image->data_region; 2156 secondRegion = &image->text_region; 2157 } 2158 2159 image->data_region.delta += image->data_region.start; 2160 image->text_region.delta += image->text_region.start; 2161 2162 // modify the dynamic ptr by the delta of the regions 2163 image->dynamic_section += image->text_region.delta; 2164 2165 status = elf_parse_dynamic_section(image); 2166 if (status < B_OK) 2167 goto error5; 2168 2169 status = init_image_version_infos(image); 2170 if (status != B_OK) 2171 goto error5; 2172 2173 status = check_needed_image_versions(image); 2174 if (status != B_OK) 2175 goto error5; 2176 2177 status = elf_relocate(image); 2178 if (status < B_OK) 2179 goto error5; 2180 2181 // We needed to read in the contents of the "text" area, but 2182 // now we can protect it read-only/execute 2183 set_area_protection(image->text_region.id, 2184 B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA); 2185 2186 // There might be a hole between the two segments, and we don't need to 2187 // reserve this any longer 2188 vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress, 2189 reservedSize); 2190 2191 // ToDo: this should be enabled by kernel settings! 2192 if (1) 2193 load_elf_symbol_table(fd, image); 2194 2195 free(programHeaders); 2196 mutex_lock(&sImageMutex); 2197 register_elf_image(image); 2198 mutex_unlock(&sImageMutex); 2199 2200 done: 2201 _kern_close(fd); 2202 mutex_unlock(&sImageLoadMutex); 2203 2204 return image->id; 2205 2206 error5: 2207 error4: 2208 vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress, 2209 reservedSize); 2210 error3: 2211 free(programHeaders); 2212 error2: 2213 delete_elf_image(image); 2214 elfHeader = NULL; 2215 error1: 2216 free(elfHeader); 2217 error: 2218 mutex_unlock(&sImageLoadMutex); 2219 error0: 2220 dprintf("Could not load kernel add-on \"%s\": %s\n", path, 2221 strerror(status)); 2222 2223 if (vnode) 2224 vfs_put_vnode(vnode); 2225 _kern_close(fd); 2226 2227 return status; 2228 } 2229 2230 2231 status_t 2232 unload_kernel_add_on(image_id id) 2233 { 2234 MutexLocker _(sImageLoadMutex); 2235 MutexLocker _2(sImageMutex); 2236 2237 elf_image_info *image = find_image(id); 2238 if (image == NULL) 2239 return B_BAD_IMAGE_ID; 2240 2241 unload_elf_image(image); 2242 return B_OK; 2243 } 2244 2245 2246 struct elf_image_info* 2247 elf_get_kernel_image() 2248 { 2249 return sKernelImage; 2250 } 2251 2252 2253 status_t 2254 elf_get_image_info_for_address(addr_t address, image_info* info) 2255 { 2256 MutexLocker _(sImageMutex); 2257 struct elf_image_info* elfInfo = find_image_at_address(address); 2258 if (elfInfo == NULL) 2259 return B_ENTRY_NOT_FOUND; 2260 2261 info->id = elfInfo->id; 2262 info->type = B_SYSTEM_IMAGE; 2263 info->sequence = 0; 2264 info->init_order = 0; 2265 info->init_routine = NULL; 2266 info->term_routine = NULL; 2267 info->device = -1; 2268 info->node = -1; 2269 // TODO: We could actually fill device/node in. 2270 strlcpy(info->name, elfInfo->name, sizeof(info->name)); 2271 info->text = (void*)elfInfo->text_region.start; 2272 info->data = (void*)elfInfo->data_region.start; 2273 info->text_size = elfInfo->text_region.size; 2274 info->data_size = elfInfo->data_region.size; 2275 2276 return B_OK; 2277 } 2278 2279 2280 image_id 2281 elf_create_memory_image(const char* imageName, addr_t text, size_t textSize, 2282 addr_t data, size_t dataSize) 2283 { 2284 // allocate the image 2285 elf_image_info* image = create_image_struct(); 2286 if (image == NULL) 2287 return B_NO_MEMORY; 2288 MemoryDeleter imageDeleter(image); 2289 2290 // allocate symbol and string tables -- we allocate an empty symbol table, 2291 // so that elf_debug_lookup_symbol_address() won't try the dynamic symbol 2292 // table, which we don't have. 2293 Elf32_Sym* symbolTable = (Elf32_Sym*)malloc(0); 2294 char* stringTable = (char*)malloc(1); 2295 MemoryDeleter symbolTableDeleter(symbolTable); 2296 MemoryDeleter stringTableDeleter(stringTable); 2297 if (symbolTable == NULL || stringTable == NULL) 2298 return B_NO_MEMORY; 2299 2300 // the string table always contains the empty string 2301 stringTable[0] = '\0'; 2302 2303 image->debug_symbols = symbolTable; 2304 image->num_debug_symbols = 0; 2305 image->debug_string_table = stringTable; 2306 2307 // dup image name 2308 image->name = strdup(imageName); 2309 if (image->name == NULL) 2310 return B_NO_MEMORY; 2311 2312 // data and text region 2313 image->text_region.id = -1; 2314 image->text_region.start = text; 2315 image->text_region.size = textSize; 2316 image->text_region.delta = 0; 2317 2318 image->data_region.id = -1; 2319 image->data_region.start = data; 2320 image->data_region.size = dataSize; 2321 image->data_region.delta = 0; 2322 2323 mutex_lock(&sImageMutex); 2324 register_elf_image(image); 2325 image_id imageID = image->id; 2326 mutex_unlock(&sImageMutex); 2327 2328 // keep the allocated memory 2329 imageDeleter.Detach(); 2330 symbolTableDeleter.Detach(); 2331 stringTableDeleter.Detach(); 2332 2333 return imageID; 2334 } 2335 2336 2337 status_t 2338 elf_add_memory_image_symbol(image_id id, const char* name, addr_t address, 2339 size_t size, int32 type) 2340 { 2341 MutexLocker _(sImageMutex); 2342 2343 // get the image 2344 struct elf_image_info* image = find_image(id); 2345 if (image == NULL) 2346 return B_ENTRY_NOT_FOUND; 2347 2348 // get the current string table size 2349 size_t stringTableSize = 1; 2350 if (image->num_debug_symbols > 0) { 2351 for (uint32 i = image->num_debug_symbols - 1; i >= 0; i--) { 2352 int32 nameIndex = image->debug_symbols[i].st_name; 2353 if (nameIndex != 0) { 2354 stringTableSize = nameIndex 2355 + strlen(image->debug_string_table + nameIndex) + 1; 2356 break; 2357 } 2358 } 2359 } 2360 2361 // enter the name in the string table 2362 char* stringTable = (char*)image->debug_string_table; 2363 size_t stringIndex = 0; 2364 if (name != NULL) { 2365 size_t nameSize = strlen(name) + 1; 2366 stringIndex = stringTableSize; 2367 stringTableSize += nameSize; 2368 stringTable = (char*)realloc((char*)image->debug_string_table, 2369 stringTableSize); 2370 if (stringTable == NULL) 2371 return B_NO_MEMORY; 2372 image->debug_string_table = stringTable; 2373 memcpy(stringTable + stringIndex, name, nameSize); 2374 } 2375 2376 // resize the symbol table 2377 int32 symbolCount = image->num_debug_symbols + 1; 2378 Elf32_Sym* symbolTable = (Elf32_Sym*)realloc( 2379 (Elf32_Sym*)image->debug_symbols, sizeof(Elf32_Sym) * symbolCount); 2380 if (symbolTable == NULL) 2381 return B_NO_MEMORY; 2382 image->debug_symbols = symbolTable; 2383 2384 // enter the symbol 2385 Elf32_Sym& symbol = symbolTable[symbolCount - 1]; 2386 uint32 symbolType = type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC; 2387 symbol.st_name = stringIndex; 2388 symbol.st_value = address; 2389 symbol.st_size = size; 2390 symbol.st_info = ELF32_ST_INFO(STB_GLOBAL, symbolType); 2391 symbol.st_other = 0; 2392 symbol.st_shndx = 0; 2393 image->num_debug_symbols++; 2394 2395 return B_OK; 2396 } 2397 2398 2399 status_t 2400 elf_init(kernel_args *args) 2401 { 2402 struct preloaded_image *image; 2403 2404 image_init(); 2405 2406 sImagesHash = hash_init(IMAGE_HASH_SIZE, 0, image_compare, image_hash); 2407 if (sImagesHash == NULL) 2408 return B_NO_MEMORY; 2409 2410 // Build a image structure for the kernel, which has already been loaded. 2411 // The preloaded_images were already prepared by the VM. 2412 if (insert_preloaded_image(&args->kernel_image, true) < B_OK) 2413 panic("could not create kernel image.\n"); 2414 2415 // Build image structures for all preloaded images. 2416 for (image = args->preloaded_images; image != NULL; image = image->next) 2417 insert_preloaded_image(image, false); 2418 2419 add_debugger_command("ls", &dump_address_info, 2420 "lookup symbol for a particular address"); 2421 add_debugger_command("symbols", &dump_symbols, "dump symbols for image"); 2422 add_debugger_command("symbol", &dump_symbol, "search symbol in images"); 2423 add_debugger_command_etc("image", &dump_image, "dump image info", 2424 "Prints info about the specified image.\n" 2425 " <image> - pointer to the semaphore structure, or ID\n" 2426 " of the image to print info for.\n", 0); 2427 2428 sInitialized = true; 2429 return B_OK; 2430 } 2431 2432 2433 // #pragma mark - 2434 2435 2436 /*! Reads the symbol and string table for the kernel image with the given ID. 2437 \a _symbolCount and \a _stringTableSize are both in- and output parameters. 2438 When called they call the size of the buffers given by \a symbolTable and 2439 \a stringTable respectively. When the function returns successfully, they 2440 will contain the actual sizes (which can be greater than the original ones). 2441 The function will copy as much as possible into the buffers. For only 2442 getting the required buffer sizes, it can be invoked with \c NULL buffers. 2443 On success \a _imageDelta will contain the offset to be added to the symbol 2444 values in the table to get the actual symbol addresses. 2445 */ 2446 status_t 2447 _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable, 2448 int32* _symbolCount, char* stringTable, size_t* _stringTableSize, 2449 addr_t* _imageDelta) 2450 { 2451 // check params 2452 if (_symbolCount == NULL || _stringTableSize == NULL) 2453 return B_BAD_VALUE; 2454 if (!IS_USER_ADDRESS(_symbolCount) || !IS_USER_ADDRESS(_stringTableSize) 2455 || (_imageDelta != NULL && !IS_USER_ADDRESS(_imageDelta)) 2456 || (symbolTable != NULL && !IS_USER_ADDRESS(symbolTable)) 2457 || (stringTable != NULL && !IS_USER_ADDRESS(stringTable))) { 2458 return B_BAD_ADDRESS; 2459 } 2460 2461 // get buffer sizes 2462 int32 maxSymbolCount; 2463 size_t maxStringTableSize; 2464 if (user_memcpy(&maxSymbolCount, _symbolCount, sizeof(maxSymbolCount)) 2465 != B_OK 2466 || user_memcpy(&maxStringTableSize, _stringTableSize, 2467 sizeof(maxStringTableSize)) != B_OK) { 2468 return B_BAD_ADDRESS; 2469 } 2470 2471 // find the image 2472 MutexLocker _(sImageMutex); 2473 struct elf_image_info* image = find_image(id); 2474 if (image == NULL) 2475 return B_ENTRY_NOT_FOUND; 2476 2477 // get the tables and infos 2478 addr_t imageDelta = image->text_region.delta; 2479 const Elf32_Sym* symbols; 2480 int32 symbolCount; 2481 const char* strings; 2482 2483 if (image->debug_symbols != NULL) { 2484 symbols = image->debug_symbols; 2485 symbolCount = image->num_debug_symbols; 2486 strings = image->debug_string_table; 2487 } else { 2488 symbols = image->syms; 2489 symbolCount = image->symhash[1]; 2490 strings = image->strtab; 2491 } 2492 2493 // The string table size isn't stored in the elf_image_info structure. Find 2494 // out by iterating through all symbols. 2495 size_t stringTableSize = 0; 2496 for (int32 i = 0; i < symbolCount; i++) { 2497 size_t index = symbols[i].st_name; 2498 if (index > stringTableSize) 2499 stringTableSize = index; 2500 } 2501 stringTableSize += strlen(strings + stringTableSize) + 1; 2502 // add size of the last string 2503 2504 // copy symbol table 2505 int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount); 2506 if (symbolTable != NULL && symbolsToCopy > 0) { 2507 if (user_memcpy(symbolTable, symbols, sizeof(Elf32_Sym) * symbolsToCopy) 2508 != B_OK) { 2509 return B_BAD_ADDRESS; 2510 } 2511 } 2512 2513 // copy string table 2514 size_t stringsToCopy = min_c(stringTableSize, maxStringTableSize); 2515 if (stringTable != NULL && stringsToCopy > 0) { 2516 if (user_memcpy(stringTable, strings, stringsToCopy) 2517 != B_OK) { 2518 return B_BAD_ADDRESS; 2519 } 2520 } 2521 2522 // copy sizes 2523 if (user_memcpy(_symbolCount, &symbolCount, sizeof(symbolCount)) != B_OK 2524 || user_memcpy(_stringTableSize, &stringTableSize, 2525 sizeof(stringTableSize)) != B_OK 2526 || (_imageDelta != NULL && user_memcpy(_imageDelta, &imageDelta, 2527 sizeof(imageDelta)) != B_OK)) { 2528 return B_BAD_ADDRESS; 2529 } 2530 2531 return B_OK; 2532 } 2533