37#include <sys/malloc.h> 38#include <sys/mutex.h> 39#include <sys/proc.h> 40#include <sys/namei.h> 41#include <sys/fcntl.h> 42#include <sys/vnode.h> 43#include <sys/linker.h> 44 45#include <machine/elf.h> 46#ifdef GPROF 47#include <machine/profile.h> 48#endif 49 50#include <vm/vm.h> 51#include <vm/vm_param.h> 52#ifdef SPARSE_MAPPING 53#include <vm/vm_object.h> 54#include <vm/vm_kern.h> 55#include <vm/vm_extern.h> 56#endif 57#include <vm/pmap.h> 58#include <vm/vm_map.h> 59 60#include <sys/link_elf.h> 61 62#include "linker_if.h" 63 64typedef struct elf_file { 65 struct linker_file lf; /* Common fields */ 66 int preloaded; /* Was file pre-loaded */ 67 caddr_t address; /* Relocation address */ 68#ifdef SPARSE_MAPPING 69 vm_object_t object; /* VM object to hold file pages */ 70#endif 71 Elf_Dyn* dynamic; /* Symbol table etc. */ 72 Elf_Hashelt nbuckets; /* DT_HASH info */ 73 Elf_Hashelt nchains; 74 const Elf_Hashelt* buckets; 75 const Elf_Hashelt* chains; 76 caddr_t hash; 77 caddr_t strtab; /* DT_STRTAB */ 78 int strsz; /* DT_STRSZ */ 79 const Elf_Sym* symtab; /* DT_SYMTAB */ 80 Elf_Addr* got; /* DT_PLTGOT */ 81 const Elf_Rel* pltrel; /* DT_JMPREL */ 82 int pltrelsize; /* DT_PLTRELSZ */ 83 const Elf_Rela* pltrela; /* DT_JMPREL */ 84 int pltrelasize; /* DT_PLTRELSZ */ 85 const Elf_Rel* rel; /* DT_REL */ 86 int relsize; /* DT_RELSZ */ 87 const Elf_Rela* rela; /* DT_RELA */ 88 int relasize; /* DT_RELASZ */ 89 caddr_t modptr; 90 const Elf_Sym* ddbsymtab; /* The symbol table we are using */ 91 long ddbsymcnt; /* Number of symbols */ 92 caddr_t ddbstrtab; /* String table */ 93 long ddbstrcnt; /* number of bytes in string table */ 94 caddr_t symbase; /* malloc'ed symbold base */ 95 caddr_t strbase; /* malloc'ed string base */ 96#ifdef DDB 97 struct link_map gdb; /* hooks for gdb */ 98#endif 99} *elf_file_t; 100 101static int link_elf_link_common_finish(linker_file_t); 102static int link_elf_link_preload(linker_class_t cls, 103 const char*, linker_file_t*); 104static int link_elf_link_preload_finish(linker_file_t); 105static int link_elf_load_file(linker_class_t, const char*, linker_file_t*); 106static int link_elf_lookup_symbol(linker_file_t, const char*, 107 c_linker_sym_t*); 108static int link_elf_symbol_values(linker_file_t, c_linker_sym_t, linker_symval_t*); 109static int link_elf_search_symbol(linker_file_t, caddr_t value, 110 c_linker_sym_t* sym, long* diffp); 111 112static void link_elf_unload_file(linker_file_t); 113static void link_elf_unload_preload(linker_file_t); 114static int link_elf_lookup_set(linker_file_t, const char *, 115 void ***, void ***, int *); 116static int link_elf_each_function_name(linker_file_t, 117 int (*)(const char *, void *), 118 void *); 119 120static kobj_method_t link_elf_methods[] = { 121 KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol), 122 KOBJMETHOD(linker_symbol_values, link_elf_symbol_values), 123 KOBJMETHOD(linker_search_symbol, link_elf_search_symbol), 124 KOBJMETHOD(linker_unload, link_elf_unload_file), 125 KOBJMETHOD(linker_load_file, link_elf_load_file), 126 KOBJMETHOD(linker_link_preload, link_elf_link_preload), 127 KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish), 128 KOBJMETHOD(linker_lookup_set, link_elf_lookup_set), 129 KOBJMETHOD(linker_each_function_name, link_elf_each_function_name), 130 { 0, 0 } 131}; 132 133static struct linker_class link_elf_class = { 134#if ELF_TARG_CLASS == ELFCLASS32 135 "elf32", 136#else 137 "elf64", 138#endif 139 link_elf_methods, sizeof(struct elf_file) 140}; 141 142static int parse_dynamic(elf_file_t ef); 143static int relocate_file(elf_file_t ef); 144static int link_elf_preload_parse_symbols(elf_file_t ef); 145 146#ifdef DDB 147static void r_debug_state(struct r_debug *dummy_one, 148 struct link_map *dummy_two); 149 150/* 151 * A list of loaded modules for GDB to use for loading symbols. 152 */ 153struct r_debug r_debug; 154 155#define GDB_STATE(s) r_debug.r_state = s; r_debug_state(NULL, NULL); 156 157/* 158 * Function for the debugger to set a breakpoint on to gain control. 159 */ 160static void 161r_debug_state(struct r_debug *dummy_one __unused, 162 struct link_map *dummy_two __unused) 163{ 164} 165 166static void 167link_elf_add_gdb(struct link_map *l) 168{ 169 struct link_map *prev; 170 171 l->l_next = NULL; 172 173 if (r_debug.r_map == NULL) { 174 /* Add first. */ 175 l->l_prev = NULL; 176 r_debug.r_map = l; 177 } else { 178 /* Append to list. */ 179 for (prev = r_debug.r_map; prev->l_next != NULL; prev = prev->l_next) 180 ; 181 l->l_prev = prev; 182 prev->l_next = l; 183 } 184} 185 186static void 187link_elf_delete_gdb(struct link_map *l) 188{ 189 if (l->l_prev == NULL) { 190 /* Remove first. */ 191 if ((r_debug.r_map = l->l_next) != NULL) 192 l->l_next->l_prev = NULL; 193 } else { 194 /* Remove any but first. */ 195 if ((l->l_prev->l_next = l->l_next) != NULL) 196 l->l_next->l_prev = l->l_prev; 197 } 198} 199#endif /* DDB */ 200 201#ifdef __ia64__ 202Elf_Addr link_elf_get_gp(linker_file_t); 203#endif 204 205/* 206 * The kernel symbol table starts here. 207 */ 208extern struct _dynamic _DYNAMIC; 209 210static void 211link_elf_error(const char *s) 212{ 213 printf("kldload: %s\n", s); 214} 215 216/* 217 * Actions performed after linking/loading both the preloaded kernel and any 218 * modules; whether preloaded or dynamicly loaded. 219 */ 220static int 221link_elf_link_common_finish(linker_file_t lf) 222{ 223#ifdef DDB 224 elf_file_t ef = (elf_file_t)lf; 225 char *newfilename; 226#endif 227 int error; 228 229 /* Notify MD code that a module is being loaded. */ 230 error = elf_cpu_load_file(lf); 231 if (error) 232 return (error); 233 234#ifdef DDB 235 GDB_STATE(RT_ADD); 236 ef->gdb.l_addr = lf->address; 237 newfilename = malloc(strlen(lf->filename) + 1, M_LINKER, M_WAITOK); 238 strcpy(newfilename, lf->filename); 239 ef->gdb.l_name = newfilename; 240 ef->gdb.l_ld = ef->dynamic; 241 link_elf_add_gdb(&ef->gdb); 242 GDB_STATE(RT_CONSISTENT); 243#endif 244 245 return (0); 246} 247 248static void 249link_elf_init(void* arg) 250{ 251 Elf_Dyn *dp; 252 caddr_t modptr, baseptr, sizeptr; 253 elf_file_t ef; 254 char *modname; 255 256 linker_add_class(&link_elf_class); 257 258 dp = (Elf_Dyn*) &_DYNAMIC; 259 modname = NULL; 260 modptr = preload_search_by_type("elf kernel"); 261 if (modptr) 262 modname = (char *)preload_search_info(modptr, MODINFO_NAME); 263 if (modname == NULL) 264 modname = "kernel"; 265 linker_kernel_file = linker_make_file(modname, &link_elf_class); 266 if (linker_kernel_file == NULL) 267 panic("link_elf_init: Can't create linker structures for kernel"); 268 269 ef = (elf_file_t) linker_kernel_file; 270 ef->preloaded = 1; 271 ef->address = 0; 272#ifdef SPARSE_MAPPING 273 ef->object = 0; 274#endif 275 ef->dynamic = dp; 276 277 if (dp) 278 parse_dynamic(ef); 279 linker_kernel_file->address = (caddr_t) KERNBASE; 280 linker_kernel_file->size = -(intptr_t)linker_kernel_file->address; 281 282 if (modptr) { 283 ef->modptr = modptr; 284 baseptr = preload_search_info(modptr, MODINFO_ADDR); 285 if (baseptr) 286 linker_kernel_file->address = *(caddr_t *)baseptr; 287 sizeptr = preload_search_info(modptr, MODINFO_SIZE); 288 if (sizeptr) 289 linker_kernel_file->size = *(size_t *)sizeptr; 290 } 291 (void)link_elf_preload_parse_symbols(ef); 292 293#ifdef DDB 294 r_debug.r_map = NULL; 295 r_debug.r_brk = r_debug_state; 296 r_debug.r_state = RT_CONSISTENT; 297#endif 298 299 (void)link_elf_link_common_finish(linker_kernel_file); 300} 301 302SYSINIT(link_elf, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0); 303 304static int 305link_elf_preload_parse_symbols(elf_file_t ef) 306{ 307 caddr_t pointer; 308 caddr_t ssym, esym, base; 309 caddr_t strtab; 310 int strcnt; 311 Elf_Sym* symtab; 312 int symcnt; 313 314 if (ef->modptr == NULL) 315 return 0; 316 pointer = preload_search_info(ef->modptr, MODINFO_METADATA|MODINFOMD_SSYM); 317 if (pointer == NULL) 318 return 0; 319 ssym = *(caddr_t *)pointer; 320 pointer = preload_search_info(ef->modptr, MODINFO_METADATA|MODINFOMD_ESYM); 321 if (pointer == NULL) 322 return 0; 323 esym = *(caddr_t *)pointer; 324 325 base = ssym; 326 327 symcnt = *(long *)base; 328 base += sizeof(long); 329 symtab = (Elf_Sym *)base; 330 base += roundup(symcnt, sizeof(long)); 331 332 if (base > esym || base < ssym) { 333 printf("Symbols are corrupt!\n"); 334 return EINVAL; 335 } 336 337 strcnt = *(long *)base; 338 base += sizeof(long); 339 strtab = base; 340 base += roundup(strcnt, sizeof(long)); 341 342 if (base > esym || base < ssym) { 343 printf("Symbols are corrupt!\n"); 344 return EINVAL; 345 } 346 347 ef->ddbsymtab = symtab; 348 ef->ddbsymcnt = symcnt / sizeof(Elf_Sym); 349 ef->ddbstrtab = strtab; 350 ef->ddbstrcnt = strcnt; 351 352 return 0; 353} 354 355static int 356parse_dynamic(elf_file_t ef) 357{ 358 Elf_Dyn *dp; 359 int plttype = DT_REL; 360 361 for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) { 362 switch (dp->d_tag) { 363 case DT_HASH: 364 { 365 /* From src/libexec/rtld-elf/rtld.c */ 366 const Elf_Hashelt *hashtab = (const Elf_Hashelt *) 367 (ef->address + dp->d_un.d_ptr); 368 ef->nbuckets = hashtab[0]; 369 ef->nchains = hashtab[1]; 370 ef->buckets = hashtab + 2; 371 ef->chains = ef->buckets + ef->nbuckets; 372 break; 373 } 374 case DT_STRTAB: 375 ef->strtab = (caddr_t) (ef->address + dp->d_un.d_ptr); 376 break; 377 case DT_STRSZ: 378 ef->strsz = dp->d_un.d_val; 379 break; 380 case DT_SYMTAB: 381 ef->symtab = (Elf_Sym*) (ef->address + dp->d_un.d_ptr); 382 break; 383 case DT_SYMENT: 384 if (dp->d_un.d_val != sizeof(Elf_Sym)) 385 return ENOEXEC; 386 break; 387 case DT_PLTGOT: 388 ef->got = (Elf_Addr *) (ef->address + dp->d_un.d_ptr); 389 break; 390 case DT_REL: 391 ef->rel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr); 392 break; 393 case DT_RELSZ: 394 ef->relsize = dp->d_un.d_val; 395 break; 396 case DT_RELENT: 397 if (dp->d_un.d_val != sizeof(Elf_Rel)) 398 return ENOEXEC; 399 break; 400 case DT_JMPREL: 401 ef->pltrel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr); 402 break; 403 case DT_PLTRELSZ: 404 ef->pltrelsize = dp->d_un.d_val; 405 break; 406 case DT_RELA: 407 ef->rela = (const Elf_Rela *) (ef->address + dp->d_un.d_ptr); 408 break; 409 case DT_RELASZ: 410 ef->relasize = dp->d_un.d_val; 411 break; 412 case DT_RELAENT: 413 if (dp->d_un.d_val != sizeof(Elf_Rela)) 414 return ENOEXEC; 415 break; 416 case DT_PLTREL: 417 plttype = dp->d_un.d_val; 418 if (plttype != DT_REL && plttype != DT_RELA) 419 return ENOEXEC; 420 break; 421#ifdef DDB 422 case DT_DEBUG: 423 dp->d_un.d_ptr = (Elf_Addr) &r_debug; 424 break; 425#endif 426 } 427 } 428 429 if (plttype == DT_RELA) { 430 ef->pltrela = (const Elf_Rela *) ef->pltrel; 431 ef->pltrel = NULL; 432 ef->pltrelasize = ef->pltrelsize; 433 ef->pltrelsize = 0; 434 } 435 436 ef->ddbsymtab = ef->symtab; 437 ef->ddbsymcnt = ef->nchains; 438 ef->ddbstrtab = ef->strtab; 439 ef->ddbstrcnt = ef->strsz; 440 441 return 0; 442} 443 444static int 445link_elf_link_preload(linker_class_t cls, 446 const char* filename, linker_file_t *result) 447{ 448 caddr_t modptr, baseptr, sizeptr, dynptr; 449 char *type; 450 elf_file_t ef; 451 linker_file_t lf; 452 int error; 453 vm_offset_t dp; 454 455 /* Look to see if we have the file preloaded */ 456 modptr = preload_search_by_name(filename); 457 if (modptr == NULL) 458 return ENOENT; 459 460 type = (char *)preload_search_info(modptr, MODINFO_TYPE); 461 baseptr = preload_search_info(modptr, MODINFO_ADDR); 462 sizeptr = preload_search_info(modptr, MODINFO_SIZE); 463 dynptr = preload_search_info(modptr, MODINFO_METADATA|MODINFOMD_DYNAMIC); 464 if (type == NULL || strcmp(type, "elf module") != 0) 465 return (EFTYPE); 466 if (baseptr == NULL || sizeptr == NULL || dynptr == NULL) 467 return (EINVAL); 468 469 lf = linker_make_file(filename, &link_elf_class); 470 if (lf == NULL) { 471 return ENOMEM; 472 } 473 474 ef = (elf_file_t) lf; 475 ef->preloaded = 1; 476 ef->modptr = modptr; 477 ef->address = *(caddr_t *)baseptr; 478#ifdef SPARSE_MAPPING 479 ef->object = 0; 480#endif 481 dp = (vm_offset_t)ef->address + *(vm_offset_t *)dynptr; 482 ef->dynamic = (Elf_Dyn *)dp; 483 lf->address = ef->address; 484 lf->size = *(size_t *)sizeptr; 485 486 error = parse_dynamic(ef); 487 if (error) { 488 linker_file_unload(lf); 489 return error; 490 } 491 *result = lf; 492 return (0); 493} 494 495static int 496link_elf_link_preload_finish(linker_file_t lf) 497{ 498 elf_file_t ef; 499 int error; 500 501 ef = (elf_file_t) lf; 502#if 0 /* this will be more trouble than it's worth for now */ 503 for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) { 504 if (dp->d_tag != DT_NEEDED) 505 continue; 506 modname = ef->strtab + dp->d_un.d_val; 507 error = linker_load_module(modname, lf); 508 if (error) 509 goto out; 510 } 511#endif 512 error = relocate_file(ef); 513 if (error) 514 return error; 515 (void)link_elf_preload_parse_symbols(ef); 516 517 return (link_elf_link_common_finish(lf)); 518} 519 520static int 521link_elf_load_file(linker_class_t cls, const char* filename, 522 linker_file_t* result) 523{ 524 struct nameidata nd; 525 struct thread* td = curthread; /* XXX */ 526 Elf_Ehdr *hdr; 527 caddr_t firstpage; 528 int nbytes, i; 529 Elf_Phdr *phdr; 530 Elf_Phdr *phlimit; 531 Elf_Phdr *segs[2]; 532 int nsegs; 533 Elf_Phdr *phdyn; 534 Elf_Phdr *phphdr; 535 caddr_t mapbase; 536 size_t mapsize; 537 Elf_Off base_offset; 538 Elf_Addr base_vaddr; 539 Elf_Addr base_vlimit; 540 int error = 0; 541 int resid, flags; 542 elf_file_t ef; 543 linker_file_t lf; 544 Elf_Shdr *shdr; 545 int symtabindex; 546 int symstrindex; 547 int symcnt; 548 int strcnt; 549 550 GIANT_REQUIRED; 551 552 shdr = NULL; 553 lf = NULL; 554 555 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td); 556 flags = FREAD; 557 error = vn_open(&nd, &flags, 0); 558 if (error) 559 return error; 560 NDFREE(&nd, NDF_ONLY_PNBUF);
|
568 569 /* 570 * Read the elf header from the file. 571 */ 572 firstpage = malloc(PAGE_SIZE, M_LINKER, M_WAITOK); 573 if (firstpage == NULL) { 574 error = ENOMEM; 575 goto out; 576 } 577 hdr = (Elf_Ehdr *)firstpage; 578 error = vn_rdwr(UIO_READ, nd.ni_vp, firstpage, PAGE_SIZE, 0, 579 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 580 &resid, td); 581 nbytes = PAGE_SIZE - resid; 582 if (error) 583 goto out; 584 585 if (!IS_ELF(*hdr)) { 586 error = ENOEXEC; 587 goto out; 588 } 589 590 if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS 591 || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) { 592 link_elf_error("Unsupported file layout"); 593 error = ENOEXEC; 594 goto out; 595 } 596 if (hdr->e_ident[EI_VERSION] != EV_CURRENT 597 || hdr->e_version != EV_CURRENT) { 598 link_elf_error("Unsupported file version"); 599 error = ENOEXEC; 600 goto out; 601 } 602 if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) { 603 link_elf_error("Unsupported file type"); 604 error = ENOEXEC; 605 goto out; 606 } 607 if (hdr->e_machine != ELF_TARG_MACH) { 608 link_elf_error("Unsupported machine"); 609 error = ENOEXEC; 610 goto out; 611 } 612 613 /* 614 * We rely on the program header being in the first page. This is 615 * not strictly required by the ABI specification, but it seems to 616 * always true in practice. And, it simplifies things considerably. 617 */ 618 if (!((hdr->e_phentsize == sizeof(Elf_Phdr)) && 619 (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= PAGE_SIZE) && 620 (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= nbytes))) 621 link_elf_error("Unreadable program headers"); 622 623 /* 624 * Scan the program header entries, and save key information. 625 * 626 * We rely on there being exactly two load segments, text and data, 627 * in that order. 628 */ 629 phdr = (Elf_Phdr *) (firstpage + hdr->e_phoff); 630 phlimit = phdr + hdr->e_phnum; 631 nsegs = 0; 632 phdyn = NULL; 633 phphdr = NULL; 634 while (phdr < phlimit) { 635 switch (phdr->p_type) { 636 637 case PT_LOAD: 638 if (nsegs == 2) { 639 link_elf_error("Too many sections"); 640 error = ENOEXEC; 641 goto out; 642 } 643 segs[nsegs] = phdr; 644 ++nsegs; 645 break; 646 647 case PT_PHDR: 648 phphdr = phdr; 649 break; 650 651 case PT_DYNAMIC: 652 phdyn = phdr; 653 break; 654 655 case PT_INTERP: 656 link_elf_error("Unsupported file type"); 657 error = ENOEXEC; 658 goto out; 659 } 660 661 ++phdr; 662 } 663 if (phdyn == NULL) { 664 link_elf_error("Object is not dynamically-linked"); 665 error = ENOEXEC; 666 goto out; 667 } 668 669 /* 670 * Allocate the entire address space of the object, to stake out our 671 * contiguous region, and to establish the base address for relocation. 672 */ 673 base_offset = trunc_page(segs[0]->p_offset); 674 base_vaddr = trunc_page(segs[0]->p_vaddr); 675 base_vlimit = round_page(segs[1]->p_vaddr + segs[1]->p_memsz); 676 mapsize = base_vlimit - base_vaddr; 677 678 lf = linker_make_file(filename, &link_elf_class); 679 if (!lf) { 680 error = ENOMEM; 681 goto out; 682 } 683 684 ef = (elf_file_t) lf; 685#ifdef SPARSE_MAPPING 686 ef->object = vm_object_allocate(OBJT_DEFAULT, mapsize >> PAGE_SHIFT); 687 if (ef->object == NULL) { 688 error = ENOMEM; 689 goto out; 690 } 691 vm_object_reference(ef->object); 692 ef->address = (caddr_t) vm_map_min(kernel_map); 693 error = vm_map_find(kernel_map, ef->object, 0, 694 (vm_offset_t *) &ef->address, 695 mapsize, 1, 696 VM_PROT_ALL, VM_PROT_ALL, 0); 697 if (error) { 698 vm_object_deallocate(ef->object); 699 ef->object = 0; 700 goto out; 701 } 702#else 703 ef->address = malloc(mapsize, M_LINKER, M_WAITOK); 704 if (!ef->address) { 705 error = ENOMEM; 706 goto out; 707 } 708#endif 709 mapbase = ef->address; 710 711 /* 712 * Read the text and data sections and zero the bss. 713 */ 714 for (i = 0; i < 2; i++) { 715 caddr_t segbase = mapbase + segs[i]->p_vaddr - base_vaddr; 716 error = vn_rdwr(UIO_READ, nd.ni_vp, 717 segbase, segs[i]->p_filesz, segs[i]->p_offset, 718 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 719 &resid, td); 720 if (error) { 721 goto out; 722 } 723 bzero(segbase + segs[i]->p_filesz, 724 segs[i]->p_memsz - segs[i]->p_filesz); 725 726#ifdef SPARSE_MAPPING 727 /* 728 * Wire down the pages 729 */ 730 vm_map_wire(kernel_map, 731 (vm_offset_t) segbase, 732 (vm_offset_t) segbase + segs[i]->p_memsz, 733 FALSE); 734#endif 735 } 736 737#ifdef GPROF 738 /* Update profiling information with the new text segment. */ 739 kmupetext((uintfptr_t)(mapbase + segs[0]->p_vaddr - base_vaddr + 740 segs[0]->p_memsz)); 741#endif 742 743 ef->dynamic = (Elf_Dyn *) (mapbase + phdyn->p_vaddr - base_vaddr); 744 745 lf->address = ef->address; 746 lf->size = mapsize; 747 748 error = parse_dynamic(ef); 749 if (error) 750 goto out; 751 error = linker_load_dependencies(lf); 752 if (error) 753 goto out; 754#if 0 /* this will be more trouble than it's worth for now */ 755 for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) { 756 if (dp->d_tag != DT_NEEDED) 757 continue; 758 modname = ef->strtab + dp->d_un.d_val; 759 error = linker_load_module(modname, lf); 760 if (error) 761 goto out; 762 } 763#endif 764 error = relocate_file(ef); 765 if (error) 766 goto out; 767 768 /* Try and load the symbol table if it's present. (you can strip it!) */ 769 nbytes = hdr->e_shnum * hdr->e_shentsize; 770 if (nbytes == 0 || hdr->e_shoff == 0) 771 goto nosyms; 772 shdr = malloc(nbytes, M_LINKER, M_WAITOK | M_ZERO); 773 if (shdr == NULL) { 774 error = ENOMEM; 775 goto out; 776 } 777 error = vn_rdwr(UIO_READ, nd.ni_vp, 778 (caddr_t)shdr, nbytes, hdr->e_shoff, 779 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 780 &resid, td); 781 if (error) 782 goto out; 783 symtabindex = -1; 784 symstrindex = -1; 785 for (i = 0; i < hdr->e_shnum; i++) { 786 if (shdr[i].sh_type == SHT_SYMTAB) { 787 symtabindex = i; 788 symstrindex = shdr[i].sh_link; 789 } 790 } 791 if (symtabindex < 0 || symstrindex < 0) 792 goto nosyms; 793 794 symcnt = shdr[symtabindex].sh_size; 795 ef->symbase = malloc(symcnt, M_LINKER, M_WAITOK); 796 strcnt = shdr[symstrindex].sh_size; 797 ef->strbase = malloc(strcnt, M_LINKER, M_WAITOK); 798 799 if (ef->symbase == NULL || ef->strbase == NULL) { 800 error = ENOMEM; 801 goto out; 802 } 803 error = vn_rdwr(UIO_READ, nd.ni_vp, 804 ef->symbase, symcnt, shdr[symtabindex].sh_offset, 805 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 806 &resid, td); 807 if (error) 808 goto out; 809 error = vn_rdwr(UIO_READ, nd.ni_vp, 810 ef->strbase, strcnt, shdr[symstrindex].sh_offset, 811 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 812 &resid, td); 813 if (error) 814 goto out; 815 816 ef->ddbsymcnt = symcnt / sizeof(Elf_Sym); 817 ef->ddbsymtab = (const Elf_Sym *)ef->symbase; 818 ef->ddbstrcnt = strcnt; 819 ef->ddbstrtab = ef->strbase; 820 821 error = link_elf_link_common_finish(lf); 822 if (error) 823 goto out; 824 825nosyms: 826 827 *result = lf; 828 829out: 830 if (error && lf) 831 linker_file_unload(lf); 832 if (shdr) 833 free(shdr, M_LINKER); 834 if (firstpage) 835 free(firstpage, M_LINKER); 836 VOP_UNLOCK(nd.ni_vp, 0, td); 837 vn_close(nd.ni_vp, FREAD, td->td_ucred, td); 838 839 return error; 840} 841 842static void 843link_elf_unload_file(linker_file_t file) 844{ 845 elf_file_t ef = (elf_file_t) file; 846 847#ifdef DDB 848 if (ef->gdb.l_ld) { 849 GDB_STATE(RT_DELETE); 850 free((void *)(uintptr_t)ef->gdb.l_name, M_LINKER); 851 link_elf_delete_gdb(&ef->gdb); 852 GDB_STATE(RT_CONSISTENT); 853 } 854#endif 855 856 /* Notify MD code that a module is being unloaded. */ 857 elf_cpu_unload_file(file); 858 859 if (ef->preloaded) { 860 link_elf_unload_preload(file); 861 return; 862 } 863 864#ifdef SPARSE_MAPPING 865 if (ef->object) { 866 vm_map_remove(kernel_map, (vm_offset_t) ef->address, 867 (vm_offset_t) ef->address 868 + (ef->object->size << PAGE_SHIFT)); 869 vm_object_deallocate(ef->object); 870 } 871#else 872 if (ef->address) 873 free(ef->address, M_LINKER); 874#endif 875 if (ef->symbase) 876 free(ef->symbase, M_LINKER); 877 if (ef->strbase) 878 free(ef->strbase, M_LINKER); 879} 880 881static void 882link_elf_unload_preload(linker_file_t file) 883{ 884 if (file->filename) 885 preload_delete_name(file->filename); 886} 887 888static const char * 889symbol_name(elf_file_t ef, Elf_Word r_info) 890{ 891 const Elf_Sym *ref; 892 893 if (ELF_R_SYM(r_info)) { 894 ref = ef->symtab + ELF_R_SYM(r_info); 895 return ef->strtab + ref->st_name; 896 } else 897 return NULL; 898} 899 900static int 901relocate_file(elf_file_t ef) 902{ 903 const Elf_Rel *rellim; 904 const Elf_Rel *rel; 905 const Elf_Rela *relalim; 906 const Elf_Rela *rela; 907 const char *symname; 908 909 /* Perform relocations without addend if there are any: */ 910 rel = ef->rel; 911 if (rel) { 912 rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize); 913 while (rel < rellim) { 914 if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) { 915 symname = symbol_name(ef, rel->r_info); 916 printf("link_elf: symbol %s undefined\n", symname); 917 return ENOENT; 918 } 919 rel++; 920 } 921 } 922 923 /* Perform relocations with addend if there are any: */ 924 rela = ef->rela; 925 if (rela) { 926 relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize); 927 while (rela < relalim) { 928 if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) { 929 symname = symbol_name(ef, rela->r_info); 930 printf("link_elf: symbol %s undefined\n", symname); 931 return ENOENT; 932 } 933 rela++; 934 } 935 } 936 937 /* Perform PLT relocations without addend if there are any: */ 938 rel = ef->pltrel; 939 if (rel) { 940 rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize); 941 while (rel < rellim) { 942 if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) { 943 symname = symbol_name(ef, rel->r_info); 944 printf("link_elf: symbol %s undefined\n", symname); 945 return ENOENT; 946 } 947 rel++; 948 } 949 } 950 951 /* Perform relocations with addend if there are any: */ 952 rela = ef->pltrela; 953 if (rela) { 954 relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize); 955 while (rela < relalim) { 956 if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) { 957 symname = symbol_name(ef, rela->r_info); 958 printf("link_elf: symbol %s undefined\n", symname); 959 return ENOENT; 960 } 961 rela++; 962 } 963 } 964 965 return 0; 966} 967 968/* 969 * Hash function for symbol table lookup. Don't even think about changing 970 * this. It is specified by the System V ABI. 971 */ 972static unsigned long 973elf_hash(const char *name) 974{ 975 const unsigned char *p = (const unsigned char *) name; 976 unsigned long h = 0; 977 unsigned long g; 978 979 while (*p != '\0') { 980 h = (h << 4) + *p++; 981 if ((g = h & 0xf0000000) != 0) 982 h ^= g >> 24; 983 h &= ~g; 984 } 985 return h; 986} 987 988static int 989link_elf_lookup_symbol(linker_file_t lf, const char* name, c_linker_sym_t* sym) 990{ 991 elf_file_t ef = (elf_file_t) lf; 992 unsigned long symnum; 993 const Elf_Sym* symp; 994 const char *strp; 995 unsigned long hash; 996 int i; 997 998 /* First, search hashed global symbols */ 999 hash = elf_hash(name); 1000 symnum = ef->buckets[hash % ef->nbuckets]; 1001 1002 while (symnum != STN_UNDEF) { 1003 if (symnum >= ef->nchains) { 1004 printf("link_elf_lookup_symbol: corrupt symbol table\n"); 1005 return ENOENT; 1006 } 1007 1008 symp = ef->symtab + symnum; 1009 if (symp->st_name == 0) { 1010 printf("link_elf_lookup_symbol: corrupt symbol table\n"); 1011 return ENOENT; 1012 } 1013 1014 strp = ef->strtab + symp->st_name; 1015 1016 if (strcmp(name, strp) == 0) { 1017 if (symp->st_shndx != SHN_UNDEF || 1018 (symp->st_value != 0 && 1019 ELF_ST_TYPE(symp->st_info) == STT_FUNC)) { 1020 *sym = (c_linker_sym_t) symp; 1021 return 0; 1022 } else 1023 return ENOENT; 1024 } 1025 1026 symnum = ef->chains[symnum]; 1027 } 1028 1029 /* If we have not found it, look at the full table (if loaded) */ 1030 if (ef->symtab == ef->ddbsymtab) 1031 return ENOENT; 1032 1033 /* Exhaustive search */ 1034 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1035 strp = ef->ddbstrtab + symp->st_name; 1036 if (strcmp(name, strp) == 0) { 1037 if (symp->st_shndx != SHN_UNDEF || 1038 (symp->st_value != 0 && 1039 ELF_ST_TYPE(symp->st_info) == STT_FUNC)) { 1040 *sym = (c_linker_sym_t) symp; 1041 return 0; 1042 } else 1043 return ENOENT; 1044 } 1045 } 1046 1047 return ENOENT; 1048} 1049 1050static int 1051link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t* symval) 1052{ 1053 elf_file_t ef = (elf_file_t) lf; 1054 const Elf_Sym* es = (const Elf_Sym*) sym; 1055 1056 if (es >= ef->symtab && es < (ef->symtab + ef->nchains)) { 1057 symval->name = ef->strtab + es->st_name; 1058 symval->value = (caddr_t) ef->address + es->st_value; 1059 symval->size = es->st_size; 1060 return 0; 1061 } 1062 if (ef->symtab == ef->ddbsymtab) 1063 return ENOENT; 1064 if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { 1065 symval->name = ef->ddbstrtab + es->st_name; 1066 symval->value = (caddr_t) ef->address + es->st_value; 1067 symval->size = es->st_size; 1068 return 0; 1069 } 1070 return ENOENT; 1071} 1072 1073static int 1074link_elf_search_symbol(linker_file_t lf, caddr_t value, 1075 c_linker_sym_t* sym, long* diffp) 1076{ 1077 elf_file_t ef = (elf_file_t) lf; 1078 u_long off = (uintptr_t) (void *) value; 1079 u_long diff = off; 1080 u_long st_value; 1081 const Elf_Sym* es; 1082 const Elf_Sym* best = 0; 1083 int i; 1084 1085 for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) { 1086 if (es->st_name == 0) 1087 continue; 1088 st_value = es->st_value + (uintptr_t) (void *) ef->address; 1089 if (off >= st_value) { 1090 if (off - st_value < diff) { 1091 diff = off - st_value; 1092 best = es; 1093 if (diff == 0) 1094 break; 1095 } else if (off - st_value == diff) { 1096 best = es; 1097 } 1098 } 1099 } 1100 if (best == 0) 1101 *diffp = off; 1102 else 1103 *diffp = diff; 1104 *sym = (c_linker_sym_t) best; 1105 1106 return 0; 1107} 1108 1109/* 1110 * Look up a linker set on an ELF system. 1111 */ 1112static int 1113link_elf_lookup_set(linker_file_t lf, const char *name, 1114 void ***startp, void ***stopp, int *countp) 1115{ 1116 c_linker_sym_t sym; 1117 linker_symval_t symval; 1118 char *setsym; 1119 void **start, **stop; 1120 int len, error = 0, count; 1121 1122 len = strlen(name) + sizeof("__start_set_"); /* sizeof includes \0 */ 1123 setsym = malloc(len, M_LINKER, M_WAITOK); 1124 if (setsym == NULL) 1125 return ENOMEM; 1126 1127 /* get address of first entry */ 1128 snprintf(setsym, len, "%s%s", "__start_set_", name); 1129 error = link_elf_lookup_symbol(lf, setsym, &sym); 1130 if (error) 1131 goto out; 1132 link_elf_symbol_values(lf, sym, &symval); 1133 if (symval.value == 0) { 1134 error = ESRCH; 1135 goto out; 1136 } 1137 start = (void **)symval.value; 1138 1139 /* get address of last entry */ 1140 snprintf(setsym, len, "%s%s", "__stop_set_", name); 1141 error = link_elf_lookup_symbol(lf, setsym, &sym); 1142 if (error) 1143 goto out; 1144 link_elf_symbol_values(lf, sym, &symval); 1145 if (symval.value == 0) { 1146 error = ESRCH; 1147 goto out; 1148 } 1149 stop = (void **)symval.value; 1150 1151 /* and the number of entries */ 1152 count = stop - start; 1153 1154 /* and copy out */ 1155 if (startp) 1156 *startp = start; 1157 if (stopp) 1158 *stopp = stop; 1159 if (countp) 1160 *countp = count; 1161 1162out: 1163 free(setsym, M_LINKER); 1164 return error; 1165} 1166 1167static int 1168link_elf_each_function_name(linker_file_t file, 1169 int (*callback)(const char *, void *), void *opaque) { 1170 elf_file_t ef = (elf_file_t)file; 1171 const Elf_Sym* symp; 1172 int i, error; 1173 1174 /* Exhaustive search */ 1175 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1176 if (symp->st_value != 0 && 1177 ELF_ST_TYPE(symp->st_info) == STT_FUNC) { 1178 error = callback(ef->ddbstrtab + symp->st_name, opaque); 1179 if (error) 1180 return (error); 1181 } 1182 } 1183 return (0); 1184} 1185 1186#ifdef __ia64__ 1187/* 1188 * Each KLD has its own GP. The GP value for each load module is given by 1189 * DT_PLTGOT on ia64. We need GP to construct function descriptors, but 1190 * don't have direct access to the ELF file structure. The link_elf_get_gp() 1191 * function returns the GP given a pointer to a generic linker file struct. 1192 */ 1193Elf_Addr 1194link_elf_get_gp(linker_file_t lf) 1195{ 1196 elf_file_t ef = (elf_file_t)lf; 1197 return (Elf_Addr)ef->got; 1198} 1199#endif 1200 1201const Elf_Sym * 1202elf_get_sym(linker_file_t lf, Elf_Word symidx) 1203{ 1204 elf_file_t ef = (elf_file_t)lf; 1205 1206 if (symidx >= ef->nchains) 1207 return (NULL); 1208 return (ef->symtab + symidx); 1209} 1210 1211const char * 1212elf_get_symname(linker_file_t lf, Elf_Word symidx) 1213{ 1214 elf_file_t ef = (elf_file_t)lf; 1215 const Elf_Sym *sym; 1216 1217 if (symidx >= ef->nchains) 1218 return (NULL); 1219 sym = ef->symtab + symidx; 1220 return (ef->strtab + sym->st_name); 1221} 1222 1223/* 1224 * Symbol lookup function that can be used when the symbol index is known (ie 1225 * in relocations). It uses the symbol index instead of doing a fully fledged 1226 * hash table based lookup when such is valid. For example for local symbols. 1227 * This is not only more efficient, it's also more correct. It's not always 1228 * the case that the symbol can be found through the hash table. 1229 */ 1230Elf_Addr 1231elf_lookup(linker_file_t lf, Elf_Word symidx, int deps) 1232{ 1233 elf_file_t ef = (elf_file_t)lf; 1234 const Elf_Sym *sym; 1235 const char *symbol; 1236 1237 /* Don't even try to lookup the symbol if the index is bogus. */ 1238 if (symidx >= ef->nchains) 1239 return (0); 1240 1241 sym = ef->symtab + symidx; 1242 1243 /* 1244 * Don't do a full lookup when the symbol is local. It may even 1245 * fail because it may not be found through the hash table. 1246 */ 1247 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) { 1248 /* Force lookup failure when we have an insanity. */ 1249 if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0) 1250 return (0); 1251 return ((Elf_Addr)ef->address + sym->st_value); 1252 } 1253 1254 /* 1255 * XXX we can avoid doing a hash table based lookup for global 1256 * symbols as well. This however is not always valid, so we'll 1257 * just do it the hard way for now. Performance tweaks can 1258 * always be added. 1259 */ 1260 1261 symbol = ef->strtab + sym->st_name; 1262 1263 /* Force a lookup failure if the symbol name is bogus. */ 1264 if (*symbol == 0) 1265 return (0); 1266 1267 return ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); 1268}
|