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