1 /* 2 * Copyright 2009-2010, 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(B_CURRENT_TEAM, buffer, address, bufferSize) 1472 >= 0; 1473 } 1474 return user_strlcpy(buffer, address, bufferSize) >= 0; 1475 } 1476 1477 template<typename T> bool _Read(const T* address, T& data); 1478 // gcc 2.95.3 doesn't like it defined in-place 1479 1480 private: 1481 runtime_loader_debug_area fDebugArea; 1482 char fImageName[B_OS_NAME_LENGTH]; 1483 char fSymbolName[256]; 1484 static UserSymbolLookup sLookup; 1485 }; 1486 1487 1488 template<typename T> 1489 bool 1490 UserSymbolLookup::_Read(const T* address, T& data) 1491 { 1492 if (!IS_USER_ADDRESS(address)) 1493 return false; 1494 1495 if (debug_debugger_running()) 1496 return debug_memcpy(B_CURRENT_TEAM, &data, address, sizeof(T)) == B_OK; 1497 return user_memcpy(&data, address, sizeof(T)) == B_OK; 1498 } 1499 1500 1501 UserSymbolLookup UserSymbolLookup::sLookup; 1502 // doesn't need construction, but has an Init() method 1503 1504 1505 // #pragma mark - public kernel API 1506 1507 1508 status_t 1509 get_image_symbol(image_id id, const char *name, int32 symbolClass, 1510 void **_symbol) 1511 { 1512 struct elf_image_info *image; 1513 struct Elf32_Sym *symbol; 1514 status_t status = B_OK; 1515 1516 TRACE(("get_image_symbol(%s)\n", name)); 1517 1518 mutex_lock(&sImageMutex); 1519 1520 image = find_image(id); 1521 if (image == NULL) { 1522 status = B_BAD_IMAGE_ID; 1523 goto done; 1524 } 1525 1526 symbol = elf_find_symbol(image, name, NULL, true); 1527 if (symbol == NULL || symbol->st_shndx == SHN_UNDEF) { 1528 status = B_ENTRY_NOT_FOUND; 1529 goto done; 1530 } 1531 1532 // TODO: support the "symbolClass" parameter! 1533 1534 TRACE(("found: %lx (%lx + %lx)\n", 1535 symbol->st_value + image->text_region.delta, 1536 symbol->st_value, image->text_region.delta)); 1537 1538 *_symbol = (void *)(symbol->st_value + image->text_region.delta); 1539 1540 done: 1541 mutex_unlock(&sImageMutex); 1542 return status; 1543 } 1544 1545 1546 // #pragma mark - kernel private API 1547 1548 1549 /*! Looks up a symbol by address in all images loaded in kernel space. 1550 Note, if you need to call this function outside a debugger, make 1551 sure you fix locking and the way it returns its information, first! 1552 */ 1553 status_t 1554 elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress, 1555 const char **_symbolName, const char **_imageName, bool *_exactMatch) 1556 { 1557 struct elf_image_info *image; 1558 struct Elf32_Sym *symbolFound = NULL; 1559 const char *symbolName = NULL; 1560 addr_t deltaFound = INT_MAX; 1561 bool exactMatch = false; 1562 status_t status; 1563 1564 TRACE(("looking up %p\n", (void *)address)); 1565 1566 if (!sInitialized) 1567 return B_ERROR; 1568 1569 //mutex_lock(&sImageMutex); 1570 1571 image = find_image_at_address(address); 1572 // get image that may contain the address 1573 1574 if (image != NULL) { 1575 addr_t symbolDelta; 1576 uint32 i; 1577 int32 j; 1578 1579 TRACE((" image %p, base = %p, size = %p\n", image, 1580 (void *)image->text_region.start, (void *)image->text_region.size)); 1581 1582 if (image->debug_symbols != NULL) { 1583 // search extended debug symbol table (contains static symbols) 1584 1585 TRACE((" searching debug symbols...\n")); 1586 1587 for (i = 0; i < image->num_debug_symbols; i++) { 1588 struct Elf32_Sym *symbol = &image->debug_symbols[i]; 1589 1590 if (symbol->st_value == 0 || symbol->st_size 1591 >= image->text_region.size + image->data_region.size) 1592 continue; 1593 1594 symbolDelta 1595 = address - (symbol->st_value + image->text_region.delta); 1596 if (symbolDelta >= 0 && symbolDelta < symbol->st_size) 1597 exactMatch = true; 1598 1599 if (exactMatch || symbolDelta < deltaFound) { 1600 deltaFound = symbolDelta; 1601 symbolFound = symbol; 1602 symbolName = image->debug_string_table + symbol->st_name; 1603 1604 if (exactMatch) 1605 break; 1606 } 1607 } 1608 } else { 1609 // search standard symbol lookup table 1610 1611 TRACE((" searching standard symbols...\n")); 1612 1613 for (i = 0; i < HASHTABSIZE(image); i++) { 1614 for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; 1615 j = HASHCHAINS(image)[j]) { 1616 struct Elf32_Sym *symbol = &image->syms[j]; 1617 1618 if (symbol->st_value == 0 1619 || symbol->st_size >= image->text_region.size 1620 + image->data_region.size) 1621 continue; 1622 1623 symbolDelta = address - (long)(symbol->st_value 1624 + image->text_region.delta); 1625 if (symbolDelta >= 0 && symbolDelta < symbol->st_size) 1626 exactMatch = true; 1627 1628 if (exactMatch || symbolDelta < deltaFound) { 1629 deltaFound = symbolDelta; 1630 symbolFound = symbol; 1631 symbolName = SYMNAME(image, symbol); 1632 1633 if (exactMatch) 1634 goto symbol_found; 1635 } 1636 } 1637 } 1638 } 1639 } 1640 symbol_found: 1641 1642 if (symbolFound != NULL) { 1643 if (_symbolName) 1644 *_symbolName = symbolName; 1645 if (_imageName) 1646 *_imageName = image->name; 1647 if (_baseAddress) 1648 *_baseAddress = symbolFound->st_value + image->text_region.delta; 1649 if (_exactMatch) 1650 *_exactMatch = exactMatch; 1651 1652 status = B_OK; 1653 } else if (image != NULL) { 1654 TRACE(("symbol not found!\n")); 1655 1656 if (_symbolName) 1657 *_symbolName = NULL; 1658 if (_imageName) 1659 *_imageName = image->name; 1660 if (_baseAddress) 1661 *_baseAddress = image->text_region.start; 1662 if (_exactMatch) 1663 *_exactMatch = false; 1664 1665 status = B_OK; 1666 } else { 1667 TRACE(("image not found!\n")); 1668 status = B_ENTRY_NOT_FOUND; 1669 } 1670 1671 // Note, theoretically, all information we return back to our caller 1672 // would have to be locked - but since this function is only called 1673 // from the debugger, it's safe to do it this way 1674 1675 //mutex_unlock(&sImageMutex); 1676 1677 return status; 1678 } 1679 1680 1681 /*! Tries to find a matching user symbol for the given address. 1682 Note that the given team's address space must already be in effect. 1683 */ 1684 status_t 1685 elf_debug_lookup_user_symbol_address(struct team* team, addr_t address, 1686 addr_t *_baseAddress, const char **_symbolName, const char **_imageName, 1687 bool *_exactMatch) 1688 { 1689 if (team == NULL || team == team_get_kernel_team()) 1690 return B_BAD_VALUE; 1691 1692 UserSymbolLookup& lookup = UserSymbolLookup::Default(); 1693 status_t error = lookup.Init(team); 1694 if (error != B_OK) 1695 return error; 1696 1697 return lookup.LookupSymbolAddress(address, _baseAddress, _symbolName, 1698 _imageName, _exactMatch); 1699 } 1700 1701 1702 /*! Looks up a symbol in all kernel images. Note, this function is thought to 1703 be used in the kernel debugger, and therefore doesn't perform any locking. 1704 */ 1705 addr_t 1706 elf_debug_lookup_symbol(const char* searchName) 1707 { 1708 struct elf_image_info *image = NULL; 1709 struct hash_iterator iterator; 1710 1711 hash_open(sImagesHash, &iterator); 1712 while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator)) 1713 != NULL) { 1714 if (image->num_debug_symbols > 0) { 1715 // search extended debug symbol table (contains static symbols) 1716 for (uint32 i = 0; i < image->num_debug_symbols; i++) { 1717 struct Elf32_Sym *symbol = &image->debug_symbols[i]; 1718 const char *name = image->debug_string_table + symbol->st_name; 1719 1720 if (symbol->st_value > 0 && !strcmp(name, searchName)) 1721 return symbol->st_value + image->text_region.delta; 1722 } 1723 } else { 1724 // search standard symbol lookup table 1725 for (uint32 i = 0; i < HASHTABSIZE(image); i++) { 1726 for (uint32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF; 1727 j = HASHCHAINS(image)[j]) { 1728 struct Elf32_Sym *symbol = &image->syms[j]; 1729 const char *name = SYMNAME(image, symbol); 1730 1731 if (symbol->st_value > 0 && !strcmp(name, searchName)) 1732 return symbol->st_value + image->text_region.delta; 1733 } 1734 } 1735 } 1736 } 1737 hash_close(sImagesHash, &iterator, false); 1738 1739 return 0; 1740 } 1741 1742 1743 status_t 1744 elf_load_user_image(const char *path, struct team *team, int flags, 1745 addr_t *entry) 1746 { 1747 struct Elf32_Ehdr elfHeader; 1748 struct Elf32_Phdr *programHeaders = NULL; 1749 char baseName[B_OS_NAME_LENGTH]; 1750 status_t status; 1751 ssize_t length; 1752 int fd; 1753 int i; 1754 1755 TRACE(("elf_load: entry path '%s', team %p\n", path, team)); 1756 1757 fd = _kern_open(-1, path, O_RDONLY, 0); 1758 if (fd < 0) 1759 return fd; 1760 1761 struct stat st; 1762 status = _kern_read_stat(fd, NULL, false, &st, sizeof(st)); 1763 if (status != B_OK) 1764 return status; 1765 1766 // read and verify the ELF header 1767 1768 length = _kern_read(fd, 0, &elfHeader, sizeof(elfHeader)); 1769 if (length < B_OK) { 1770 status = length; 1771 goto error; 1772 } 1773 1774 if (length != sizeof(elfHeader)) { 1775 // short read 1776 status = B_NOT_AN_EXECUTABLE; 1777 goto error; 1778 } 1779 status = verify_eheader(&elfHeader); 1780 if (status < B_OK) 1781 goto error; 1782 1783 // read program header 1784 1785 programHeaders = (struct Elf32_Phdr *)malloc( 1786 elfHeader.e_phnum * elfHeader.e_phentsize); 1787 if (programHeaders == NULL) { 1788 dprintf("error allocating space for program headers\n"); 1789 status = B_NO_MEMORY; 1790 goto error; 1791 } 1792 1793 TRACE(("reading in program headers at 0x%lx, length 0x%x\n", 1794 elfHeader.e_phoff, elfHeader.e_phnum * elfHeader.e_phentsize)); 1795 length = _kern_read(fd, elfHeader.e_phoff, programHeaders, 1796 elfHeader.e_phnum * elfHeader.e_phentsize); 1797 if (length < B_OK) { 1798 status = length; 1799 dprintf("error reading in program headers\n"); 1800 goto error; 1801 } 1802 if (length != elfHeader.e_phnum * elfHeader.e_phentsize) { 1803 dprintf("short read while reading in program headers\n"); 1804 status = -1; 1805 goto error; 1806 } 1807 1808 // construct a nice name for the region we have to create below 1809 { 1810 int32 length; 1811 1812 const char *leaf = strrchr(path, '/'); 1813 if (leaf == NULL) 1814 leaf = path; 1815 else 1816 leaf++; 1817 1818 length = strlen(leaf); 1819 if (length > B_OS_NAME_LENGTH - 8) 1820 sprintf(baseName, "...%s", leaf + length + 8 - B_OS_NAME_LENGTH); 1821 else 1822 strcpy(baseName, leaf); 1823 } 1824 1825 // map the program's segments into memory 1826 1827 image_info imageInfo; 1828 memset(&imageInfo, 0, sizeof(image_info)); 1829 1830 for (i = 0; i < elfHeader.e_phnum; i++) { 1831 char regionName[B_OS_NAME_LENGTH]; 1832 char *regionAddress; 1833 area_id id; 1834 1835 if (programHeaders[i].p_type != PT_LOAD) 1836 continue; 1837 1838 regionAddress = (char *)ROUNDDOWN(programHeaders[i].p_vaddr, 1839 B_PAGE_SIZE); 1840 if (programHeaders[i].p_flags & PF_WRITE) { 1841 // rw/data segment 1842 uint32 memUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1843 + programHeaders[i].p_memsz; 1844 uint32 fileUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1845 + programHeaders[i].p_filesz; 1846 1847 memUpperBound = ROUNDUP(memUpperBound, B_PAGE_SIZE); 1848 fileUpperBound = ROUNDUP(fileUpperBound, B_PAGE_SIZE); 1849 1850 sprintf(regionName, "%s_seg%drw", baseName, i); 1851 1852 id = vm_map_file(team->id, regionName, (void **)®ionAddress, 1853 B_EXACT_ADDRESS, fileUpperBound, 1854 B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, false, 1855 fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); 1856 if (id < B_OK) { 1857 dprintf("error mapping file data: %s!\n", strerror(id)); 1858 status = B_NOT_AN_EXECUTABLE; 1859 goto error; 1860 } 1861 1862 imageInfo.data = regionAddress; 1863 imageInfo.data_size = memUpperBound; 1864 1865 // clean garbage brought by mmap (the region behind the file, 1866 // at least parts of it are the bss and have to be zeroed) 1867 uint32 start = (uint32)regionAddress 1868 + (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1869 + programHeaders[i].p_filesz; 1870 uint32 amount = fileUpperBound 1871 - (programHeaders[i].p_vaddr % B_PAGE_SIZE) 1872 - (programHeaders[i].p_filesz); 1873 memset((void *)start, 0, amount); 1874 1875 // Check if we need extra storage for the bss - we have to do this if 1876 // the above region doesn't already comprise the memory size, too. 1877 1878 if (memUpperBound != fileUpperBound) { 1879 size_t bssSize = memUpperBound - fileUpperBound; 1880 1881 snprintf(regionName, B_OS_NAME_LENGTH, "%s_bss%d", baseName, i); 1882 1883 regionAddress += fileUpperBound; 1884 id = create_area_etc(team->id, regionName, 1885 (void **)®ionAddress, B_EXACT_ADDRESS, bssSize, 1886 B_NO_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0); 1887 if (id < B_OK) { 1888 dprintf("error allocating bss area: %s!\n", strerror(id)); 1889 status = B_NOT_AN_EXECUTABLE; 1890 goto error; 1891 } 1892 } 1893 } else { 1894 // assume ro/text segment 1895 snprintf(regionName, B_OS_NAME_LENGTH, "%s_seg%dro", baseName, i); 1896 1897 size_t segmentSize = ROUNDUP(programHeaders[i].p_memsz 1898 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 1899 1900 id = vm_map_file(team->id, regionName, (void **)®ionAddress, 1901 B_EXACT_ADDRESS, segmentSize, 1902 B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP, false, 1903 fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); 1904 if (id < B_OK) { 1905 dprintf("error mapping file text: %s!\n", strerror(id)); 1906 status = B_NOT_AN_EXECUTABLE; 1907 goto error; 1908 } 1909 1910 imageInfo.text = regionAddress; 1911 imageInfo.text_size = segmentSize; 1912 } 1913 } 1914 1915 // register the loaded image 1916 imageInfo.type = B_LIBRARY_IMAGE; 1917 imageInfo.device = st.st_dev; 1918 imageInfo.node = st.st_ino; 1919 strlcpy(imageInfo.name, path, sizeof(imageInfo.name)); 1920 1921 imageInfo.api_version = B_HAIKU_VERSION; 1922 imageInfo.abi = B_HAIKU_ABI; 1923 // TODO: Get the actual values for the shared object. Currently only 1924 // the runtime loader is loaded, so this is good enough for the time 1925 // being. 1926 1927 imageInfo.id = register_image(team, &imageInfo, sizeof(image_info)); 1928 if (imageInfo.id >= 0 && team_get_current_team_id() == team->id) 1929 user_debug_image_created(&imageInfo); 1930 // Don't care, if registering fails. It's not crucial. 1931 1932 TRACE(("elf_load: done!\n")); 1933 1934 *entry = elfHeader.e_entry; 1935 status = B_OK; 1936 1937 error: 1938 free(programHeaders); 1939 _kern_close(fd); 1940 1941 return status; 1942 } 1943 1944 1945 image_id 1946 load_kernel_add_on(const char *path) 1947 { 1948 struct Elf32_Phdr *programHeaders; 1949 struct Elf32_Ehdr *elfHeader; 1950 struct elf_image_info *image; 1951 const char *fileName; 1952 void *reservedAddress; 1953 addr_t start; 1954 size_t reservedSize; 1955 status_t status; 1956 ssize_t length; 1957 1958 TRACE(("elf_load_kspace: entry path '%s'\n", path)); 1959 1960 int fd = _kern_open(-1, path, O_RDONLY, 0); 1961 if (fd < 0) 1962 return fd; 1963 1964 struct vnode *vnode; 1965 status = vfs_get_vnode_from_fd(fd, true, &vnode); 1966 if (status < B_OK) 1967 goto error0; 1968 1969 // get the file name 1970 fileName = strrchr(path, '/'); 1971 if (fileName == NULL) 1972 fileName = path; 1973 else 1974 fileName++; 1975 1976 // Prevent someone else from trying to load this image 1977 mutex_lock(&sImageLoadMutex); 1978 1979 // make sure it's not loaded already. Search by vnode 1980 image = find_image_by_vnode(vnode); 1981 if (image) { 1982 atomic_add(&image->ref_count, 1); 1983 goto done; 1984 } 1985 1986 elfHeader = (struct Elf32_Ehdr *)malloc(sizeof(*elfHeader)); 1987 if (!elfHeader) { 1988 status = B_NO_MEMORY; 1989 goto error; 1990 } 1991 1992 length = _kern_read(fd, 0, elfHeader, sizeof(*elfHeader)); 1993 if (length < B_OK) { 1994 status = length; 1995 goto error1; 1996 } 1997 if (length != sizeof(*elfHeader)) { 1998 // short read 1999 status = B_NOT_AN_EXECUTABLE; 2000 goto error1; 2001 } 2002 status = verify_eheader(elfHeader); 2003 if (status < B_OK) 2004 goto error1; 2005 2006 image = create_image_struct(); 2007 if (!image) { 2008 status = B_NO_MEMORY; 2009 goto error1; 2010 } 2011 image->vnode = vnode; 2012 image->elf_header = elfHeader; 2013 image->name = strdup(path); 2014 vnode = NULL; 2015 2016 programHeaders = (struct Elf32_Phdr *)malloc(elfHeader->e_phnum 2017 * elfHeader->e_phentsize); 2018 if (programHeaders == NULL) { 2019 dprintf("%s: error allocating space for program headers\n", fileName); 2020 status = B_NO_MEMORY; 2021 goto error2; 2022 } 2023 2024 TRACE(("reading in program headers at 0x%lx, length 0x%x\n", 2025 elfHeader->e_phoff, elfHeader->e_phnum * elfHeader->e_phentsize)); 2026 2027 length = _kern_read(fd, elfHeader->e_phoff, programHeaders, 2028 elfHeader->e_phnum * elfHeader->e_phentsize); 2029 if (length < B_OK) { 2030 status = length; 2031 TRACE(("%s: error reading in program headers\n", fileName)); 2032 goto error3; 2033 } 2034 if (length != elfHeader->e_phnum * elfHeader->e_phentsize) { 2035 TRACE(("%s: short read while reading in program headers\n", fileName)); 2036 status = B_ERROR; 2037 goto error3; 2038 } 2039 2040 // determine how much space we need for all loaded segments 2041 2042 reservedSize = 0; 2043 length = 0; 2044 2045 for (int32 i = 0; i < elfHeader->e_phnum; i++) { 2046 size_t end; 2047 2048 if (programHeaders[i].p_type != PT_LOAD) 2049 continue; 2050 2051 length += ROUNDUP(programHeaders[i].p_memsz 2052 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 2053 2054 end = ROUNDUP(programHeaders[i].p_memsz + programHeaders[i].p_vaddr, 2055 B_PAGE_SIZE); 2056 if (end > reservedSize) 2057 reservedSize = end; 2058 } 2059 2060 // Check whether the segments have an unreasonable amount of unused space 2061 // inbetween. 2062 if ((ssize_t)reservedSize > length + 8 * 1024) { 2063 status = B_BAD_DATA; 2064 goto error1; 2065 } 2066 2067 // reserve that space and allocate the areas from that one 2068 if (vm_reserve_address_range(VMAddressSpace::KernelID(), &reservedAddress, 2069 B_ANY_KERNEL_ADDRESS, reservedSize, 0) < B_OK) { 2070 status = B_NO_MEMORY; 2071 goto error3; 2072 } 2073 2074 start = (addr_t)reservedAddress; 2075 image->data_region.size = 0; 2076 image->text_region.size = 0; 2077 2078 for (int32 i = 0; i < elfHeader->e_phnum; i++) { 2079 char regionName[B_OS_NAME_LENGTH]; 2080 elf_region *region; 2081 2082 TRACE(("looking at program header %ld\n", i)); 2083 2084 switch (programHeaders[i].p_type) { 2085 case PT_LOAD: 2086 break; 2087 case PT_DYNAMIC: 2088 image->dynamic_section = programHeaders[i].p_vaddr; 2089 continue; 2090 default: 2091 dprintf("%s: unhandled pheader type 0x%lx\n", fileName, 2092 programHeaders[i].p_type); 2093 continue; 2094 } 2095 2096 // we're here, so it must be a PT_LOAD segment 2097 if (programHeaders[i].IsReadWrite()) { 2098 // this is the writable segment 2099 if (image->data_region.size != 0) { 2100 // we've already created this segment 2101 continue; 2102 } 2103 region = &image->data_region; 2104 2105 snprintf(regionName, B_OS_NAME_LENGTH, "%s_data", fileName); 2106 } else if (programHeaders[i].IsExecutable()) { 2107 // this is the non-writable segment 2108 if (image->text_region.size != 0) { 2109 // we've already created this segment 2110 continue; 2111 } 2112 region = &image->text_region; 2113 2114 snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", fileName); 2115 } else { 2116 dprintf("%s: weird program header flags 0x%lx\n", fileName, 2117 programHeaders[i].p_flags); 2118 continue; 2119 } 2120 2121 region->start = (addr_t)reservedAddress + ROUNDDOWN( 2122 programHeaders[i].p_vaddr, B_PAGE_SIZE); 2123 region->size = ROUNDUP(programHeaders[i].p_memsz 2124 + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); 2125 region->id = create_area(regionName, (void **)®ion->start, 2126 B_EXACT_ADDRESS, region->size, B_FULL_LOCK, 2127 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); 2128 if (region->id < B_OK) { 2129 dprintf("%s: error allocating area: %s\n", fileName, 2130 strerror(region->id)); 2131 status = B_NOT_AN_EXECUTABLE; 2132 goto error4; 2133 } 2134 region->delta = -ROUNDDOWN(programHeaders[i].p_vaddr, B_PAGE_SIZE); 2135 2136 TRACE(("elf_load_kspace: created area \"%s\" at %p\n", 2137 regionName, (void *)region->start)); 2138 2139 length = _kern_read(fd, programHeaders[i].p_offset, 2140 (void *)(region->start + (programHeaders[i].p_vaddr % B_PAGE_SIZE)), 2141 programHeaders[i].p_filesz); 2142 if (length < B_OK) { 2143 status = length; 2144 dprintf("%s: error reading in segment %ld\n", fileName, i); 2145 goto error5; 2146 } 2147 } 2148 2149 // get the segment order 2150 elf_region *firstRegion; 2151 elf_region *secondRegion; 2152 if (image->text_region.start < image->data_region.start) { 2153 firstRegion = &image->text_region; 2154 secondRegion = &image->data_region; 2155 } else { 2156 firstRegion = &image->data_region; 2157 secondRegion = &image->text_region; 2158 } 2159 2160 image->data_region.delta += image->data_region.start; 2161 image->text_region.delta += image->text_region.start; 2162 2163 // modify the dynamic ptr by the delta of the regions 2164 image->dynamic_section += image->text_region.delta; 2165 2166 status = elf_parse_dynamic_section(image); 2167 if (status < B_OK) 2168 goto error5; 2169 2170 status = init_image_version_infos(image); 2171 if (status != B_OK) 2172 goto error5; 2173 2174 status = check_needed_image_versions(image); 2175 if (status != B_OK) 2176 goto error5; 2177 2178 status = elf_relocate(image); 2179 if (status < B_OK) 2180 goto error5; 2181 2182 // We needed to read in the contents of the "text" area, but 2183 // now we can protect it read-only/execute 2184 set_area_protection(image->text_region.id, 2185 B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA); 2186 2187 // There might be a hole between the two segments, and we don't need to 2188 // reserve this any longer 2189 vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress, 2190 reservedSize); 2191 2192 // ToDo: this should be enabled by kernel settings! 2193 if (1) 2194 load_elf_symbol_table(fd, image); 2195 2196 free(programHeaders); 2197 mutex_lock(&sImageMutex); 2198 register_elf_image(image); 2199 mutex_unlock(&sImageMutex); 2200 2201 done: 2202 _kern_close(fd); 2203 mutex_unlock(&sImageLoadMutex); 2204 2205 return image->id; 2206 2207 error5: 2208 error4: 2209 vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress, 2210 reservedSize); 2211 error3: 2212 free(programHeaders); 2213 error2: 2214 delete_elf_image(image); 2215 elfHeader = NULL; 2216 error1: 2217 free(elfHeader); 2218 error: 2219 mutex_unlock(&sImageLoadMutex); 2220 error0: 2221 dprintf("Could not load kernel add-on \"%s\": %s\n", path, 2222 strerror(status)); 2223 2224 if (vnode) 2225 vfs_put_vnode(vnode); 2226 _kern_close(fd); 2227 2228 return status; 2229 } 2230 2231 2232 status_t 2233 unload_kernel_add_on(image_id id) 2234 { 2235 MutexLocker _(sImageLoadMutex); 2236 MutexLocker _2(sImageMutex); 2237 2238 elf_image_info *image = find_image(id); 2239 if (image == NULL) 2240 return B_BAD_IMAGE_ID; 2241 2242 unload_elf_image(image); 2243 return B_OK; 2244 } 2245 2246 2247 struct elf_image_info* 2248 elf_get_kernel_image() 2249 { 2250 return sKernelImage; 2251 } 2252 2253 2254 status_t 2255 elf_get_image_info_for_address(addr_t address, image_info* info) 2256 { 2257 MutexLocker _(sImageMutex); 2258 struct elf_image_info* elfInfo = find_image_at_address(address); 2259 if (elfInfo == NULL) 2260 return B_ENTRY_NOT_FOUND; 2261 2262 info->id = elfInfo->id; 2263 info->type = B_SYSTEM_IMAGE; 2264 info->sequence = 0; 2265 info->init_order = 0; 2266 info->init_routine = NULL; 2267 info->term_routine = NULL; 2268 info->device = -1; 2269 info->node = -1; 2270 // TODO: We could actually fill device/node in. 2271 strlcpy(info->name, elfInfo->name, sizeof(info->name)); 2272 info->text = (void*)elfInfo->text_region.start; 2273 info->data = (void*)elfInfo->data_region.start; 2274 info->text_size = elfInfo->text_region.size; 2275 info->data_size = elfInfo->data_region.size; 2276 2277 return B_OK; 2278 } 2279 2280 2281 image_id 2282 elf_create_memory_image(const char* imageName, addr_t text, size_t textSize, 2283 addr_t data, size_t dataSize) 2284 { 2285 // allocate the image 2286 elf_image_info* image = create_image_struct(); 2287 if (image == NULL) 2288 return B_NO_MEMORY; 2289 MemoryDeleter imageDeleter(image); 2290 2291 // allocate symbol and string tables -- we allocate an empty symbol table, 2292 // so that elf_debug_lookup_symbol_address() won't try the dynamic symbol 2293 // table, which we don't have. 2294 Elf32_Sym* symbolTable = (Elf32_Sym*)malloc(0); 2295 char* stringTable = (char*)malloc(1); 2296 MemoryDeleter symbolTableDeleter(symbolTable); 2297 MemoryDeleter stringTableDeleter(stringTable); 2298 if (symbolTable == NULL || stringTable == NULL) 2299 return B_NO_MEMORY; 2300 2301 // the string table always contains the empty string 2302 stringTable[0] = '\0'; 2303 2304 image->debug_symbols = symbolTable; 2305 image->num_debug_symbols = 0; 2306 image->debug_string_table = stringTable; 2307 2308 // dup image name 2309 image->name = strdup(imageName); 2310 if (image->name == NULL) 2311 return B_NO_MEMORY; 2312 2313 // data and text region 2314 image->text_region.id = -1; 2315 image->text_region.start = text; 2316 image->text_region.size = textSize; 2317 image->text_region.delta = 0; 2318 2319 image->data_region.id = -1; 2320 image->data_region.start = data; 2321 image->data_region.size = dataSize; 2322 image->data_region.delta = 0; 2323 2324 mutex_lock(&sImageMutex); 2325 register_elf_image(image); 2326 image_id imageID = image->id; 2327 mutex_unlock(&sImageMutex); 2328 2329 // keep the allocated memory 2330 imageDeleter.Detach(); 2331 symbolTableDeleter.Detach(); 2332 stringTableDeleter.Detach(); 2333 2334 return imageID; 2335 } 2336 2337 2338 status_t 2339 elf_add_memory_image_symbol(image_id id, const char* name, addr_t address, 2340 size_t size, int32 type) 2341 { 2342 MutexLocker _(sImageMutex); 2343 2344 // get the image 2345 struct elf_image_info* image = find_image(id); 2346 if (image == NULL) 2347 return B_ENTRY_NOT_FOUND; 2348 2349 // get the current string table size 2350 size_t stringTableSize = 1; 2351 if (image->num_debug_symbols > 0) { 2352 for (uint32 i = image->num_debug_symbols - 1; i >= 0; i--) { 2353 int32 nameIndex = image->debug_symbols[i].st_name; 2354 if (nameIndex != 0) { 2355 stringTableSize = nameIndex 2356 + strlen(image->debug_string_table + nameIndex) + 1; 2357 break; 2358 } 2359 } 2360 } 2361 2362 // enter the name in the string table 2363 char* stringTable = (char*)image->debug_string_table; 2364 size_t stringIndex = 0; 2365 if (name != NULL) { 2366 size_t nameSize = strlen(name) + 1; 2367 stringIndex = stringTableSize; 2368 stringTableSize += nameSize; 2369 stringTable = (char*)realloc((char*)image->debug_string_table, 2370 stringTableSize); 2371 if (stringTable == NULL) 2372 return B_NO_MEMORY; 2373 image->debug_string_table = stringTable; 2374 memcpy(stringTable + stringIndex, name, nameSize); 2375 } 2376 2377 // resize the symbol table 2378 int32 symbolCount = image->num_debug_symbols + 1; 2379 Elf32_Sym* symbolTable = (Elf32_Sym*)realloc( 2380 (Elf32_Sym*)image->debug_symbols, sizeof(Elf32_Sym) * symbolCount); 2381 if (symbolTable == NULL) 2382 return B_NO_MEMORY; 2383 image->debug_symbols = symbolTable; 2384 2385 // enter the symbol 2386 Elf32_Sym& symbol = symbolTable[symbolCount - 1]; 2387 uint32 symbolType = type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC; 2388 symbol.st_name = stringIndex; 2389 symbol.st_value = address; 2390 symbol.st_size = size; 2391 symbol.st_info = ELF32_ST_INFO(STB_GLOBAL, symbolType); 2392 symbol.st_other = 0; 2393 symbol.st_shndx = 0; 2394 image->num_debug_symbols++; 2395 2396 return B_OK; 2397 } 2398 2399 2400 status_t 2401 elf_init(kernel_args *args) 2402 { 2403 struct preloaded_image *image; 2404 2405 image_init(); 2406 2407 sImagesHash = hash_init(IMAGE_HASH_SIZE, 0, image_compare, image_hash); 2408 if (sImagesHash == NULL) 2409 return B_NO_MEMORY; 2410 2411 // Build a image structure for the kernel, which has already been loaded. 2412 // The preloaded_images were already prepared by the VM. 2413 if (insert_preloaded_image(&args->kernel_image, true) < B_OK) 2414 panic("could not create kernel image.\n"); 2415 2416 // Build image structures for all preloaded images. 2417 for (image = args->preloaded_images; image != NULL; image = image->next) 2418 insert_preloaded_image(image, false); 2419 2420 add_debugger_command("ls", &dump_address_info, 2421 "lookup symbol for a particular address"); 2422 add_debugger_command("symbols", &dump_symbols, "dump symbols for image"); 2423 add_debugger_command("symbol", &dump_symbol, "search symbol in images"); 2424 add_debugger_command_etc("image", &dump_image, "dump image info", 2425 "Prints info about the specified image.\n" 2426 " <image> - pointer to the semaphore structure, or ID\n" 2427 " of the image to print info for.\n", 0); 2428 2429 sInitialized = true; 2430 return B_OK; 2431 } 2432 2433 2434 // #pragma mark - 2435 2436 2437 /*! Reads the symbol and string table for the kernel image with the given ID. 2438 \a _symbolCount and \a _stringTableSize are both in- and output parameters. 2439 When called they call the size of the buffers given by \a symbolTable and 2440 \a stringTable respectively. When the function returns successfully, they 2441 will contain the actual sizes (which can be greater than the original ones). 2442 The function will copy as much as possible into the buffers. For only 2443 getting the required buffer sizes, it can be invoked with \c NULL buffers. 2444 On success \a _imageDelta will contain the offset to be added to the symbol 2445 values in the table to get the actual symbol addresses. 2446 */ 2447 status_t 2448 _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable, 2449 int32* _symbolCount, char* stringTable, size_t* _stringTableSize, 2450 addr_t* _imageDelta) 2451 { 2452 // check params 2453 if (_symbolCount == NULL || _stringTableSize == NULL) 2454 return B_BAD_VALUE; 2455 if (!IS_USER_ADDRESS(_symbolCount) || !IS_USER_ADDRESS(_stringTableSize) 2456 || (_imageDelta != NULL && !IS_USER_ADDRESS(_imageDelta)) 2457 || (symbolTable != NULL && !IS_USER_ADDRESS(symbolTable)) 2458 || (stringTable != NULL && !IS_USER_ADDRESS(stringTable))) { 2459 return B_BAD_ADDRESS; 2460 } 2461 2462 // get buffer sizes 2463 int32 maxSymbolCount; 2464 size_t maxStringTableSize; 2465 if (user_memcpy(&maxSymbolCount, _symbolCount, sizeof(maxSymbolCount)) 2466 != B_OK 2467 || user_memcpy(&maxStringTableSize, _stringTableSize, 2468 sizeof(maxStringTableSize)) != B_OK) { 2469 return B_BAD_ADDRESS; 2470 } 2471 2472 // find the image 2473 MutexLocker _(sImageMutex); 2474 struct elf_image_info* image = find_image(id); 2475 if (image == NULL) 2476 return B_ENTRY_NOT_FOUND; 2477 2478 // get the tables and infos 2479 addr_t imageDelta = image->text_region.delta; 2480 const Elf32_Sym* symbols; 2481 int32 symbolCount; 2482 const char* strings; 2483 2484 if (image->debug_symbols != NULL) { 2485 symbols = image->debug_symbols; 2486 symbolCount = image->num_debug_symbols; 2487 strings = image->debug_string_table; 2488 } else { 2489 symbols = image->syms; 2490 symbolCount = image->symhash[1]; 2491 strings = image->strtab; 2492 } 2493 2494 // The string table size isn't stored in the elf_image_info structure. Find 2495 // out by iterating through all symbols. 2496 size_t stringTableSize = 0; 2497 for (int32 i = 0; i < symbolCount; i++) { 2498 size_t index = symbols[i].st_name; 2499 if (index > stringTableSize) 2500 stringTableSize = index; 2501 } 2502 stringTableSize += strlen(strings + stringTableSize) + 1; 2503 // add size of the last string 2504 2505 // copy symbol table 2506 int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount); 2507 if (symbolTable != NULL && symbolsToCopy > 0) { 2508 if (user_memcpy(symbolTable, symbols, sizeof(Elf32_Sym) * symbolsToCopy) 2509 != B_OK) { 2510 return B_BAD_ADDRESS; 2511 } 2512 } 2513 2514 // copy string table 2515 size_t stringsToCopy = min_c(stringTableSize, maxStringTableSize); 2516 if (stringTable != NULL && stringsToCopy > 0) { 2517 if (user_memcpy(stringTable, strings, stringsToCopy) 2518 != B_OK) { 2519 return B_BAD_ADDRESS; 2520 } 2521 } 2522 2523 // copy sizes 2524 if (user_memcpy(_symbolCount, &symbolCount, sizeof(symbolCount)) != B_OK 2525 || user_memcpy(_stringTableSize, &stringTableSize, 2526 sizeof(stringTableSize)) != B_OK 2527 || (_imageDelta != NULL && user_memcpy(_imageDelta, &imageDelta, 2528 sizeof(imageDelta)) != B_OK)) { 2529 return B_BAD_ADDRESS; 2530 } 2531 2532 return B_OK; 2533 } 2534