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