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