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$ 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 64 typedef 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 101 static int link_elf_link_common_finish(linker_file_t); 102 static int link_elf_link_preload(linker_class_t cls, 103 const char*, linker_file_t*); 104 static int link_elf_link_preload_finish(linker_file_t); 105 static int link_elf_load_file(linker_class_t, const char*, linker_file_t*); 106 static int link_elf_lookup_symbol(linker_file_t, const char*, 107 c_linker_sym_t*); 108 static int link_elf_symbol_values(linker_file_t, c_linker_sym_t, linker_symval_t*); 109 static int link_elf_search_symbol(linker_file_t, caddr_t value, 110 c_linker_sym_t* sym, long* diffp); 111 112 static void link_elf_unload_file(linker_file_t); 113 static void link_elf_unload_preload(linker_file_t); 114 static int link_elf_lookup_set(linker_file_t, const char *, 115 void ***, void ***, int *); 116 static int link_elf_each_function_name(linker_file_t, 117 int (*)(const char *, void *), 118 void *); 119 static void link_elf_reloc_local(linker_file_t); 120 121 static 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 134 static 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 143 static int parse_dynamic(elf_file_t ef); 144 static int relocate_file(elf_file_t ef); 145 static int link_elf_preload_parse_symbols(elf_file_t ef); 146 147 #ifdef DDB 148 static 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 */ 154 struct 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 */ 161 static void 162 r_debug_state(struct r_debug *dummy_one __unused, 163 struct link_map *dummy_two __unused) 164 { 165 } 166 167 static void 168 link_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 187 static void 188 link_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__ 203 Elf_Addr link_elf_get_gp(linker_file_t); 204 #endif 205 206 /* 207 * The kernel symbol table starts here. 208 */ 209 extern struct _dynamic _DYNAMIC; 210 211 static void 212 link_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 */ 221 static int 222 link_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, M_WAITOK); 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 249 static void 250 link_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 303 SYSINIT(link_elf, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0); 304 305 static int 306 link_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 356 static int 357 parse_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 445 static int 446 link_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 497 static int 498 link_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 522 static int 523 link_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, M_WAITOK); 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, M_WAITOK); 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_WAITOK | 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, M_WAITOK); 800 strcnt = shdr[symstrindex].sh_size; 801 ef->strbase = malloc(strcnt, M_LINKER, M_WAITOK); 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 829 nosyms: 830 831 *result = lf; 832 833 out: 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 846 static void 847 link_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 885 static void 886 link_elf_unload_preload(linker_file_t file) 887 { 888 if (file->filename) 889 preload_delete_name(file->filename); 890 } 891 892 static const char * 893 symbol_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 904 static int 905 relocate_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 */ 976 static unsigned long 977 elf_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 992 static int 993 link_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 1054 static int 1055 link_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 1077 static int 1078 link_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 */ 1116 static int 1117 link_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, M_WAITOK); 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 1166 out: 1167 free(setsym, M_LINKER); 1168 return error; 1169 } 1170 1171 static int 1172 link_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 */ 1197 Elf_Addr 1198 link_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 1205 const Elf_Sym * 1206 elf_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 1215 const char * 1216 elf_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 */ 1234 Elf_Addr 1235 elf_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 1274 static void 1275 link_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