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