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