1 /*- 2 * Copyright (c) 1998-2000 Doug Rabson 3 * Copyright (c) 2004 Peter Wemm 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include "opt_ddb.h" 32 #include "opt_mac.h" 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/lock.h> 38 #include <sys/mac.h> 39 #include <sys/malloc.h> 40 #include <sys/mutex.h> 41 #include <sys/proc.h> 42 #include <sys/namei.h> 43 #include <sys/fcntl.h> 44 #include <sys/vnode.h> 45 #include <sys/linker.h> 46 47 #include <machine/elf.h> 48 49 #include <vm/vm.h> 50 #include <vm/vm_param.h> 51 #include <vm/vm_object.h> 52 #include <vm/vm_kern.h> 53 #include <vm/vm_extern.h> 54 #include <vm/pmap.h> 55 #include <vm/vm_map.h> 56 57 #include <sys/link_elf.h> 58 59 #include "linker_if.h" 60 61 typedef struct { 62 void *addr; 63 Elf_Off size; 64 int flags; 65 int sec; /* Original section */ 66 char *name; 67 } Elf_progent; 68 69 typedef struct { 70 Elf_Rel *rel; 71 int nrel; 72 int sec; 73 } Elf_relent; 74 75 typedef struct { 76 Elf_Rela *rela; 77 int nrela; 78 int sec; 79 } Elf_relaent; 80 81 82 typedef struct elf_file { 83 struct linker_file lf; /* Common fields */ 84 85 int preloaded; 86 caddr_t address; /* Relocation address */ 87 vm_object_t object; /* VM object to hold file pages */ 88 Elf_Shdr *e_shdr; 89 90 Elf_progent *progtab; 91 int nprogtab; 92 93 Elf_relaent *relatab; 94 int nrela; 95 96 Elf_relent *reltab; 97 int nrel; 98 99 Elf_Sym *ddbsymtab; /* The symbol table we are using */ 100 long ddbsymcnt; /* Number of symbols */ 101 caddr_t ddbstrtab; /* String table */ 102 long ddbstrcnt; /* number of bytes in string table */ 103 104 caddr_t shstrtab; /* Section name string table */ 105 long shstrcnt; /* number of bytes in string table */ 106 107 } *elf_file_t; 108 109 static int link_elf_link_preload(linker_class_t cls, 110 const char *, linker_file_t *); 111 static int link_elf_link_preload_finish(linker_file_t); 112 static int link_elf_load_file(linker_class_t, const char *, linker_file_t *); 113 static int link_elf_lookup_symbol(linker_file_t, const char *, 114 c_linker_sym_t *); 115 static int link_elf_symbol_values(linker_file_t, c_linker_sym_t, 116 linker_symval_t *); 117 static int link_elf_search_symbol(linker_file_t, caddr_t value, 118 c_linker_sym_t *sym, long *diffp); 119 120 static void link_elf_unload_file(linker_file_t); 121 static int link_elf_lookup_set(linker_file_t, const char *, 122 void ***, void ***, int *); 123 static int link_elf_each_function_name(linker_file_t, 124 int (*)(const char *, void *), void *); 125 static void link_elf_reloc_local(linker_file_t); 126 127 static Elf_Addr elf_obj_lookup(linker_file_t lf, Elf_Word symidx, int deps); 128 129 static kobj_method_t link_elf_methods[] = { 130 KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol), 131 KOBJMETHOD(linker_symbol_values, link_elf_symbol_values), 132 KOBJMETHOD(linker_search_symbol, link_elf_search_symbol), 133 KOBJMETHOD(linker_unload, link_elf_unload_file), 134 KOBJMETHOD(linker_load_file, link_elf_load_file), 135 KOBJMETHOD(linker_link_preload, link_elf_link_preload), 136 KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish), 137 KOBJMETHOD(linker_lookup_set, link_elf_lookup_set), 138 KOBJMETHOD(linker_each_function_name, link_elf_each_function_name), 139 { 0, 0 } 140 }; 141 142 static struct linker_class link_elf_class = { 143 #if ELF_TARG_CLASS == ELFCLASS32 144 "elf32_obj", 145 #else 146 "elf64_obj", 147 #endif 148 link_elf_methods, sizeof(struct elf_file) 149 }; 150 151 static int relocate_file(elf_file_t ef); 152 153 static void 154 link_elf_error(const char *s) 155 { 156 printf("kldload: %s\n", s); 157 } 158 159 static void 160 link_elf_init(void *arg) 161 { 162 163 linker_add_class(&link_elf_class); 164 } 165 166 SYSINIT(link_elf_obj, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0); 167 168 static int 169 link_elf_link_preload(linker_class_t cls, const char *filename, 170 linker_file_t *result) 171 { 172 Elf_Ehdr *hdr; 173 Elf_Shdr *shdr; 174 Elf_Sym *es; 175 void *modptr, *baseptr, *sizeptr; 176 char *type; 177 elf_file_t ef; 178 linker_file_t lf; 179 Elf_Addr off; 180 int error, i, j, pb, ra, rl, shstrindex, symstrindex, symtabindex; 181 182 /* Look to see if we have the file preloaded */ 183 modptr = preload_search_by_name(filename); 184 if (modptr == NULL) 185 return ENOENT; 186 187 type = (char *)preload_search_info(modptr, MODINFO_TYPE); 188 baseptr = preload_search_info(modptr, MODINFO_ADDR); 189 sizeptr = preload_search_info(modptr, MODINFO_SIZE); 190 hdr = (Elf_Ehdr *)preload_search_info(modptr, MODINFO_METADATA | 191 MODINFOMD_ELFHDR); 192 shdr = (Elf_Shdr *)preload_search_info(modptr, MODINFO_METADATA | 193 MODINFOMD_SHDR); 194 if (type == NULL || (strcmp(type, "elf" __XSTRING(__ELF_WORD_SIZE) 195 " obj module") != 0 && 196 strcmp(type, "elf obj module") != 0)) { 197 return (EFTYPE); 198 } 199 if (baseptr == NULL || sizeptr == NULL || hdr == NULL || 200 shdr == NULL) 201 return (EINVAL); 202 203 lf = linker_make_file(filename, &link_elf_class); 204 if (lf == NULL) 205 return (ENOMEM); 206 207 ef = (elf_file_t)lf; 208 ef->preloaded = 1; 209 ef->address = *(caddr_t *)baseptr; 210 lf->address = *(caddr_t *)baseptr; 211 lf->size = *(size_t *)sizeptr; 212 213 if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || 214 hdr->e_ident[EI_DATA] != ELF_TARG_DATA || 215 hdr->e_ident[EI_VERSION] != EV_CURRENT || 216 hdr->e_version != EV_CURRENT || 217 hdr->e_type != ET_REL || 218 hdr->e_machine != ELF_TARG_MACH) { 219 error = EFTYPE; 220 goto out; 221 } 222 ef->e_shdr = shdr; 223 224 /* Scan the section header for information and table sizing. */ 225 symtabindex = -1; 226 symstrindex = -1; 227 for (i = 0; i < hdr->e_shnum; i++) { 228 switch (shdr[i].sh_type) { 229 case SHT_PROGBITS: 230 case SHT_NOBITS: 231 ef->nprogtab++; 232 break; 233 case SHT_SYMTAB: 234 symtabindex = i; 235 symstrindex = shdr[i].sh_link; 236 break; 237 case SHT_REL: 238 ef->nrel++; 239 break; 240 case SHT_RELA: 241 ef->nrela++; 242 break; 243 } 244 } 245 246 shstrindex = hdr->e_shstrndx; 247 if (ef->nprogtab == 0 || symstrindex < 0 || 248 symstrindex >= hdr->e_shnum || 249 shdr[symstrindex].sh_type != SHT_STRTAB || shstrindex == 0 || 250 shstrindex >= hdr->e_shnum || 251 shdr[shstrindex].sh_type != SHT_STRTAB) { 252 printf("%s: bad/missing section headers\n", filename); 253 error = ENOEXEC; 254 goto out; 255 } 256 257 /* Allocate space for tracking the load chunks */ 258 if (ef->nprogtab != 0) 259 ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab), 260 M_LINKER, M_WAITOK | M_ZERO); 261 if (ef->nrel != 0) 262 ef->reltab = malloc(ef->nrel * sizeof(*ef->reltab), M_LINKER, 263 M_WAITOK | M_ZERO); 264 if (ef->nrela != 0) 265 ef->relatab = malloc(ef->nrela * sizeof(*ef->relatab), M_LINKER, 266 M_WAITOK | M_ZERO); 267 if ((ef->nprogtab != 0 && ef->progtab == NULL) || 268 (ef->nrel != 0 && ef->reltab == NULL) || 269 (ef->nrela != 0 && ef->relatab == NULL)) { 270 error = ENOMEM; 271 goto out; 272 } 273 274 /* XXX, relocate the sh_addr fields saved by the loader. */ 275 off = 0; 276 for (i = 0; i < hdr->e_shnum; i++) { 277 if (shdr[i].sh_addr != 0 && (off == 0 || shdr[i].sh_addr < off)) 278 off = shdr[i].sh_addr; 279 } 280 for (i = 0; i < hdr->e_shnum; i++) { 281 if (shdr[i].sh_addr != 0) 282 shdr[i].sh_addr = shdr[i].sh_addr - off + 283 (Elf_Addr)ef->address; 284 } 285 286 ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym); 287 ef->ddbsymtab = (Elf_Sym *)shdr[symtabindex].sh_addr; 288 ef->ddbstrcnt = shdr[symstrindex].sh_size; 289 ef->ddbstrtab = (char *)shdr[symstrindex].sh_addr; 290 ef->shstrcnt = shdr[shstrindex].sh_size; 291 ef->shstrtab = (char *)shdr[shstrindex].sh_addr; 292 293 /* Now fill out progtab and the relocation tables. */ 294 pb = 0; 295 rl = 0; 296 ra = 0; 297 for (i = 0; i < hdr->e_shnum; i++) { 298 switch (shdr[i].sh_type) { 299 case SHT_PROGBITS: 300 case SHT_NOBITS: 301 ef->progtab[pb].addr = (void *)shdr[i].sh_addr; 302 if (shdr[i].sh_type == SHT_PROGBITS) 303 ef->progtab[pb].name = "<<PROGBITS>>"; 304 else 305 ef->progtab[pb].name = "<<NOBITS>>"; 306 ef->progtab[pb].size = shdr[i].sh_size; 307 ef->progtab[pb].sec = i; 308 if (ef->shstrtab && shdr[i].sh_name != 0) 309 ef->progtab[pb].name = 310 ef->shstrtab + shdr[i].sh_name; 311 312 /* Update all symbol values with the offset. */ 313 for (j = 0; j < ef->ddbsymcnt; j++) { 314 es = &ef->ddbsymtab[j]; 315 if (es->st_shndx != i) 316 continue; 317 es->st_value += (Elf_Addr)ef->progtab[pb].addr; 318 } 319 pb++; 320 break; 321 case SHT_REL: 322 ef->reltab[rl].rel = (Elf_Rel *)shdr[i].sh_addr; 323 ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel); 324 ef->reltab[rl].sec = shdr[i].sh_info; 325 rl++; 326 break; 327 case SHT_RELA: 328 ef->relatab[ra].rela = (Elf_Rela *)shdr[i].sh_addr; 329 ef->relatab[ra].nrela = 330 shdr[i].sh_size / sizeof(Elf_Rela); 331 ef->relatab[ra].sec = shdr[i].sh_info; 332 ra++; 333 break; 334 } 335 } 336 if (pb != ef->nprogtab) 337 panic("lost progbits"); 338 if (rl != ef->nrel) 339 panic("lost rel"); 340 if (ra != ef->nrela) 341 panic("lost rela"); 342 343 /* Local intra-module relocations */ 344 link_elf_reloc_local(lf); 345 346 *result = lf; 347 return (0); 348 349 out: 350 /* preload not done this way */ 351 linker_file_unload(lf, LINKER_UNLOAD_FORCE); 352 return (error); 353 } 354 355 static int 356 link_elf_link_preload_finish(linker_file_t lf) 357 { 358 elf_file_t ef; 359 int error; 360 361 ef = (elf_file_t)lf; 362 error = relocate_file(ef); 363 if (error) 364 return error; 365 366 /* Notify MD code that a module is being loaded. */ 367 error = elf_cpu_load_file(lf); 368 if (error) 369 return (error); 370 371 return (0); 372 } 373 374 static int 375 link_elf_load_file(linker_class_t cls, const char *filename, 376 linker_file_t *result) 377 { 378 struct nameidata nd; 379 struct thread *td = curthread; /* XXX */ 380 Elf_Ehdr *hdr; 381 Elf_Shdr *shdr; 382 Elf_Sym *es; 383 int nbytes, i, j; 384 vm_offset_t mapbase; 385 size_t mapsize; 386 int error = 0; 387 int resid, flags; 388 elf_file_t ef; 389 linker_file_t lf; 390 int symtabindex; 391 int symstrindex; 392 int shstrindex; 393 int nsym; 394 int pb, rl, ra; 395 int alignmask; 396 397 GIANT_REQUIRED; 398 399 shdr = NULL; 400 lf = NULL; 401 mapsize = 0; 402 hdr = NULL; 403 404 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td); 405 flags = FREAD; 406 error = vn_open(&nd, &flags, 0, -1); 407 if (error) 408 return error; 409 NDFREE(&nd, NDF_ONLY_PNBUF); 410 #ifdef MAC 411 error = mac_check_kld_load(td->td_ucred, nd.ni_vp); 412 if (error) { 413 goto out; 414 } 415 #endif 416 417 /* Read the elf header from the file. */ 418 hdr = malloc(sizeof(*hdr), M_LINKER, M_WAITOK); 419 if (hdr == NULL) { 420 error = ENOMEM; 421 goto out; 422 } 423 error = vn_rdwr(UIO_READ, nd.ni_vp, (void *)hdr, sizeof(*hdr), 0, 424 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 425 &resid, td); 426 if (error) 427 goto out; 428 if (resid != 0){ 429 error = ENOEXEC; 430 goto out; 431 } 432 433 if (!IS_ELF(*hdr)) { 434 error = ENOEXEC; 435 goto out; 436 } 437 438 if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS 439 || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) { 440 link_elf_error("Unsupported file layout"); 441 error = ENOEXEC; 442 goto out; 443 } 444 if (hdr->e_ident[EI_VERSION] != EV_CURRENT 445 || hdr->e_version != EV_CURRENT) { 446 link_elf_error("Unsupported file version"); 447 error = ENOEXEC; 448 goto out; 449 } 450 if (hdr->e_type != ET_REL) { 451 link_elf_error("Unsupported file type"); 452 error = ENOEXEC; 453 goto out; 454 } 455 if (hdr->e_machine != ELF_TARG_MACH) { 456 link_elf_error("Unsupported machine"); 457 error = ENOEXEC; 458 goto out; 459 } 460 461 lf = linker_make_file(filename, &link_elf_class); 462 if (!lf) { 463 error = ENOMEM; 464 goto out; 465 } 466 ef = (elf_file_t) lf; 467 ef->nprogtab = 0; 468 ef->e_shdr = 0; 469 ef->nrel = 0; 470 ef->nrela = 0; 471 472 /* Allocate and read in the section header */ 473 nbytes = hdr->e_shnum * hdr->e_shentsize; 474 if (nbytes == 0 || hdr->e_shoff == 0 || 475 hdr->e_shentsize != sizeof(Elf_Shdr)) { 476 error = ENOEXEC; 477 goto out; 478 } 479 shdr = malloc(nbytes, M_LINKER, M_WAITOK); 480 if (shdr == NULL) { 481 error = ENOMEM; 482 goto out; 483 } 484 ef->e_shdr = shdr; 485 error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shdr, nbytes, hdr->e_shoff, 486 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td); 487 if (error) 488 goto out; 489 if (resid) { 490 error = ENOEXEC; 491 goto out; 492 } 493 494 /* Scan the section header for information and table sizing. */ 495 nsym = 0; 496 symtabindex = -1; 497 symstrindex = -1; 498 for (i = 0; i < hdr->e_shnum; i++) { 499 switch (shdr[i].sh_type) { 500 case SHT_PROGBITS: 501 case SHT_NOBITS: 502 ef->nprogtab++; 503 break; 504 case SHT_SYMTAB: 505 nsym++; 506 symtabindex = i; 507 symstrindex = shdr[i].sh_link; 508 break; 509 case SHT_REL: 510 ef->nrel++; 511 break; 512 case SHT_RELA: 513 ef->nrela++; 514 break; 515 case SHT_STRTAB: 516 break; 517 } 518 } 519 if (ef->nprogtab == 0) { 520 link_elf_error("file has no contents"); 521 error = ENOEXEC; 522 goto out; 523 } 524 if (nsym != 1) { 525 /* Only allow one symbol table for now */ 526 link_elf_error("file has no valid symbol table"); 527 error = ENOEXEC; 528 goto out; 529 } 530 if (symstrindex < 0 || symstrindex > hdr->e_shnum || 531 shdr[symstrindex].sh_type != SHT_STRTAB) { 532 link_elf_error("file has invalid symbol strings"); 533 error = ENOEXEC; 534 goto out; 535 } 536 537 /* Allocate space for tracking the load chunks */ 538 if (ef->nprogtab != 0) 539 ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab), 540 M_LINKER, M_WAITOK | M_ZERO); 541 if (ef->nrel != 0) 542 ef->reltab = malloc(ef->nrel * sizeof(*ef->reltab), M_LINKER, 543 M_WAITOK | M_ZERO); 544 if (ef->nrela != 0) 545 ef->relatab = malloc(ef->nrela * sizeof(*ef->relatab), M_LINKER, 546 M_WAITOK | M_ZERO); 547 if ((ef->nprogtab != 0 && ef->progtab == NULL) || 548 (ef->nrel != 0 && ef->reltab == NULL) || 549 (ef->nrela != 0 && ef->relatab == NULL)) { 550 error = ENOMEM; 551 goto out; 552 } 553 554 if (symtabindex == -1) 555 panic("lost symbol table index"); 556 /* Allocate space for and load the symbol table */ 557 ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym); 558 ef->ddbsymtab = malloc(shdr[symtabindex].sh_size, M_LINKER, M_WAITOK); 559 if (ef->ddbsymtab == NULL) { 560 error = ENOMEM; 561 goto out; 562 } 563 error = vn_rdwr(UIO_READ, nd.ni_vp, (void *)ef->ddbsymtab, 564 shdr[symtabindex].sh_size, shdr[symtabindex].sh_offset, 565 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 566 &resid, td); 567 if (error) 568 goto out; 569 if (resid != 0){ 570 error = EINVAL; 571 goto out; 572 } 573 574 if (symstrindex == -1) 575 panic("lost symbol string index"); 576 /* Allocate space for and load the symbol strings */ 577 ef->ddbstrcnt = shdr[symstrindex].sh_size; 578 ef->ddbstrtab = malloc(shdr[symstrindex].sh_size, M_LINKER, M_WAITOK); 579 if (ef->ddbstrtab == NULL) { 580 error = ENOMEM; 581 goto out; 582 } 583 error = vn_rdwr(UIO_READ, nd.ni_vp, ef->ddbstrtab, 584 shdr[symstrindex].sh_size, shdr[symstrindex].sh_offset, 585 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 586 &resid, td); 587 if (error) 588 goto out; 589 if (resid != 0){ 590 error = EINVAL; 591 goto out; 592 } 593 594 /* Do we have a string table for the section names? */ 595 shstrindex = -1; 596 if (hdr->e_shstrndx != 0 && 597 shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) { 598 shstrindex = hdr->e_shstrndx; 599 ef->shstrcnt = shdr[shstrindex].sh_size; 600 ef->shstrtab = malloc(shdr[shstrindex].sh_size, M_LINKER, 601 M_WAITOK); 602 if (ef->shstrtab == NULL) { 603 error = ENOMEM; 604 goto out; 605 } 606 error = vn_rdwr(UIO_READ, nd.ni_vp, ef->shstrtab, 607 shdr[shstrindex].sh_size, shdr[shstrindex].sh_offset, 608 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 609 &resid, td); 610 if (error) 611 goto out; 612 if (resid != 0){ 613 error = EINVAL; 614 goto out; 615 } 616 } 617 618 /* Size up code/data(progbits) and bss(nobits). */ 619 alignmask = 0; 620 for (i = 0; i < hdr->e_shnum; i++) { 621 switch (shdr[i].sh_type) { 622 case SHT_PROGBITS: 623 case SHT_NOBITS: 624 alignmask = shdr[i].sh_addralign - 1; 625 mapsize += alignmask; 626 mapsize &= ~alignmask; 627 mapsize += shdr[i].sh_size; 628 break; 629 } 630 } 631 632 /* 633 * We know how much space we need for the text/data/bss/etc. 634 * This stuff needs to be in a single chunk so that profiling etc 635 * can get the bounds and gdb can associate offsets with modules 636 */ 637 ef->object = vm_object_allocate(OBJT_DEFAULT, 638 round_page(mapsize) >> PAGE_SHIFT); 639 if (ef->object == NULL) { 640 error = ENOMEM; 641 goto out; 642 } 643 vm_object_reference(ef->object); 644 ef->address = (caddr_t) vm_map_min(kernel_map); 645 error = vm_map_find(kernel_map, ef->object, 0, &mapbase, 646 round_page(mapsize), TRUE, VM_PROT_ALL, VM_PROT_ALL, FALSE); 647 if (error) { 648 vm_object_deallocate(ef->object); 649 ef->object = 0; 650 goto out; 651 } 652 653 /* Wire the pages */ 654 vm_map_wire(kernel_map, mapbase, 655 mapbase + round_page(mapsize), 656 VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES); 657 658 /* Inform the kld system about the situation */ 659 lf->address = ef->address = (caddr_t)mapbase; 660 lf->size = mapsize; 661 662 /* 663 * Now load code/data(progbits), zero bss(nobits), allocate space for 664 * and load relocs 665 */ 666 pb = 0; 667 rl = 0; 668 ra = 0; 669 alignmask = 0; 670 for (i = 0; i < hdr->e_shnum; i++) { 671 switch (shdr[i].sh_type) { 672 case SHT_PROGBITS: 673 case SHT_NOBITS: 674 alignmask = shdr[i].sh_addralign - 1; 675 mapbase += alignmask; 676 mapbase &= ~alignmask; 677 ef->progtab[pb].addr = (void *)(uintptr_t)mapbase; 678 if (shdr[i].sh_type == SHT_PROGBITS) { 679 ef->progtab[pb].name = "<<PROGBITS>>"; 680 error = vn_rdwr(UIO_READ, nd.ni_vp, 681 ef->progtab[pb].addr, 682 shdr[i].sh_size, shdr[i].sh_offset, 683 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, 684 NOCRED, &resid, td); 685 if (error) 686 goto out; 687 if (resid != 0){ 688 error = EINVAL; 689 goto out; 690 } 691 } else { 692 ef->progtab[pb].name = "<<NOBITS>>"; 693 bzero(ef->progtab[pb].addr, shdr[i].sh_size); 694 } 695 ef->progtab[pb].size = shdr[i].sh_size; 696 ef->progtab[pb].sec = i; 697 if (ef->shstrtab && shdr[i].sh_name != 0) 698 ef->progtab[pb].name = 699 ef->shstrtab + shdr[i].sh_name; 700 701 /* Update all symbol values with the offset. */ 702 for (j = 0; j < ef->ddbsymcnt; j++) { 703 es = &ef->ddbsymtab[j]; 704 if (es->st_shndx != i) 705 continue; 706 es->st_value += (Elf_Addr)ef->progtab[pb].addr; 707 } 708 mapbase += shdr[i].sh_size; 709 pb++; 710 break; 711 case SHT_REL: 712 ef->reltab[rl].rel = malloc(shdr[i].sh_size, M_LINKER, 713 M_WAITOK); 714 ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel); 715 ef->reltab[rl].sec = shdr[i].sh_info; 716 error = vn_rdwr(UIO_READ, nd.ni_vp, 717 (void *)ef->reltab[rl].rel, 718 shdr[i].sh_size, shdr[i].sh_offset, 719 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 720 &resid, td); 721 if (error) 722 goto out; 723 if (resid != 0){ 724 error = EINVAL; 725 goto out; 726 } 727 rl++; 728 break; 729 case SHT_RELA: 730 ef->relatab[ra].rela = malloc(shdr[i].sh_size, M_LINKER, 731 M_WAITOK); 732 ef->relatab[ra].nrela = 733 shdr[i].sh_size / sizeof(Elf_Rela); 734 ef->relatab[ra].sec = shdr[i].sh_info; 735 error = vn_rdwr(UIO_READ, nd.ni_vp, 736 (void *)ef->relatab[ra].rela, 737 shdr[i].sh_size, shdr[i].sh_offset, 738 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 739 &resid, td); 740 if (error) 741 goto out; 742 if (resid != 0){ 743 error = EINVAL; 744 goto out; 745 } 746 ra++; 747 break; 748 } 749 } 750 if (pb != ef->nprogtab) 751 panic("lost progbits"); 752 if (rl != ef->nrel) 753 panic("lost rel"); 754 if (ra != ef->nrela) 755 panic("lost rela"); 756 if (mapbase != (vm_offset_t)ef->address + mapsize) 757 panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n", 758 mapbase, ef->address, mapsize, 759 (vm_offset_t)ef->address + mapsize); 760 761 /* Local intra-module relocations */ 762 link_elf_reloc_local(lf); 763 764 /* Pull in dependencies */ 765 error = linker_load_dependencies(lf); 766 if (error) 767 goto out; 768 769 /* External relocations */ 770 error = relocate_file(ef); 771 if (error) 772 goto out; 773 774 /* Notify MD code that a module is being loaded. */ 775 error = elf_cpu_load_file(lf); 776 if (error) 777 goto out; 778 779 *result = lf; 780 781 out: 782 if (error && lf) 783 linker_file_unload(lf, LINKER_UNLOAD_FORCE); 784 if (hdr) 785 free(hdr, M_LINKER); 786 VOP_UNLOCK(nd.ni_vp, 0, td); 787 vn_close(nd.ni_vp, FREAD, td->td_ucred, td); 788 789 return error; 790 } 791 792 static void 793 link_elf_unload_file(linker_file_t file) 794 { 795 elf_file_t ef = (elf_file_t) file; 796 int i; 797 798 /* Notify MD code that a module is being unloaded. */ 799 elf_cpu_unload_file(file); 800 801 if (ef->preloaded) { 802 if (ef->reltab) 803 free(ef->reltab, M_LINKER); 804 if (ef->relatab) 805 free(ef->relatab, M_LINKER); 806 if (ef->progtab) 807 free(ef->progtab, M_LINKER); 808 if (file->filename != NULL) 809 preload_delete_name(file->filename); 810 /* XXX reclaim module memory? */ 811 return; 812 } 813 814 for (i = 0; i < ef->nrel; i++) 815 if (ef->reltab[i].rel) 816 free(ef->reltab[i].rel, M_LINKER); 817 for (i = 0; i < ef->nrela; i++) 818 if (ef->relatab[i].rela) 819 free(ef->relatab[i].rela, M_LINKER); 820 if (ef->reltab) 821 free(ef->reltab, M_LINKER); 822 if (ef->relatab) 823 free(ef->relatab, M_LINKER); 824 if (ef->progtab) 825 free(ef->progtab, M_LINKER); 826 827 if (ef->object) { 828 vm_map_remove(kernel_map, (vm_offset_t) ef->address, 829 (vm_offset_t) ef->address + 830 (ef->object->size << PAGE_SHIFT)); 831 vm_object_deallocate(ef->object); 832 } 833 if (ef->e_shdr) 834 free(ef->e_shdr, M_LINKER); 835 if (ef->ddbsymtab) 836 free(ef->ddbsymtab, M_LINKER); 837 if (ef->ddbstrtab) 838 free(ef->ddbstrtab, M_LINKER); 839 if (ef->shstrtab) 840 free(ef->shstrtab, M_LINKER); 841 } 842 843 static const char * 844 symbol_name(elf_file_t ef, Elf_Word r_info) 845 { 846 const Elf_Sym *ref; 847 848 if (ELF_R_SYM(r_info)) { 849 ref = ef->ddbsymtab + ELF_R_SYM(r_info); 850 return ef->ddbstrtab + ref->st_name; 851 } else 852 return NULL; 853 } 854 855 static Elf_Addr 856 findbase(elf_file_t ef, int sec) 857 { 858 int i; 859 Elf_Addr base = 0; 860 861 for (i = 0; i < ef->nprogtab; i++) { 862 if (sec == ef->progtab[i].sec) { 863 base = (Elf_Addr)ef->progtab[i].addr; 864 break; 865 } 866 } 867 return base; 868 } 869 870 static int 871 relocate_file(elf_file_t ef) 872 { 873 const Elf_Rel *rellim; 874 const Elf_Rel *rel; 875 const Elf_Rela *relalim; 876 const Elf_Rela *rela; 877 const char *symname; 878 const Elf_Sym *sym; 879 int i; 880 Elf_Word symidx; 881 Elf_Addr base; 882 883 884 /* Perform relocations without addend if there are any: */ 885 for (i = 0; i < ef->nrel; i++) { 886 rel = ef->reltab[i].rel; 887 if (rel == NULL) 888 panic("lost a reltab!"); 889 rellim = rel + ef->reltab[i].nrel; 890 base = findbase(ef, ef->reltab[i].sec); 891 if (base == 0) 892 panic("lost base for reltab"); 893 for ( ; rel < rellim; rel++) { 894 symidx = ELF_R_SYM(rel->r_info); 895 if (symidx >= ef->ddbsymcnt) 896 continue; 897 sym = ef->ddbsymtab + symidx; 898 /* Local relocs are already done */ 899 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 900 continue; 901 if (elf_reloc(&ef->lf, base, rel, ELF_RELOC_REL, 902 elf_obj_lookup)) { 903 symname = symbol_name(ef, rel->r_info); 904 printf("link_elf_obj: symbol %s undefined\n", 905 symname); 906 return ENOENT; 907 } 908 } 909 } 910 911 /* Perform relocations with addend if there are any: */ 912 for (i = 0; i < ef->nrela; i++) { 913 rela = ef->relatab[i].rela; 914 if (rela == NULL) 915 panic("lost a relatab!"); 916 relalim = rela + ef->relatab[i].nrela; 917 base = findbase(ef, ef->relatab[i].sec); 918 if (base == 0) 919 panic("lost base for relatab"); 920 for ( ; rela < relalim; rela++) { 921 symidx = ELF_R_SYM(rela->r_info); 922 if (symidx >= ef->ddbsymcnt) 923 continue; 924 sym = ef->ddbsymtab + symidx; 925 /* Local relocs are already done */ 926 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 927 continue; 928 if (elf_reloc(&ef->lf, base, rela, ELF_RELOC_RELA, 929 elf_obj_lookup)) { 930 symname = symbol_name(ef, rela->r_info); 931 printf("link_elf_obj: symbol %s undefined\n", 932 symname); 933 return ENOENT; 934 } 935 } 936 } 937 938 return 0; 939 } 940 941 static int 942 link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) 943 { 944 elf_file_t ef = (elf_file_t) lf; 945 const Elf_Sym *symp; 946 const char *strp; 947 int i; 948 949 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 950 strp = ef->ddbstrtab + symp->st_name; 951 if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) { 952 *sym = (c_linker_sym_t) symp; 953 return 0; 954 } 955 } 956 return ENOENT; 957 } 958 959 static int 960 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, 961 linker_symval_t *symval) 962 { 963 elf_file_t ef = (elf_file_t) lf; 964 const Elf_Sym *es = (const Elf_Sym*) sym; 965 966 if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { 967 symval->name = ef->ddbstrtab + es->st_name; 968 symval->value = (caddr_t)es->st_value; 969 symval->size = es->st_size; 970 return 0; 971 } 972 return ENOENT; 973 } 974 975 static int 976 link_elf_search_symbol(linker_file_t lf, caddr_t value, 977 c_linker_sym_t *sym, long *diffp) 978 { 979 elf_file_t ef = (elf_file_t) lf; 980 u_long off = (uintptr_t) (void *) value; 981 u_long diff = off; 982 u_long st_value; 983 const Elf_Sym *es; 984 const Elf_Sym *best = 0; 985 int i; 986 987 for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) { 988 if (es->st_name == 0) 989 continue; 990 st_value = es->st_value; 991 if (off >= st_value) { 992 if (off - st_value < diff) { 993 diff = off - st_value; 994 best = es; 995 if (diff == 0) 996 break; 997 } else if (off - st_value == diff) { 998 best = es; 999 } 1000 } 1001 } 1002 if (best == 0) 1003 *diffp = off; 1004 else 1005 *diffp = diff; 1006 *sym = (c_linker_sym_t) best; 1007 1008 return 0; 1009 } 1010 1011 /* 1012 * Look up a linker set on an ELF system. 1013 */ 1014 static int 1015 link_elf_lookup_set(linker_file_t lf, const char *name, 1016 void ***startp, void ***stopp, int *countp) 1017 { 1018 elf_file_t ef = (elf_file_t)lf; 1019 void **start, **stop; 1020 int i, count; 1021 1022 /* Relative to section number */ 1023 for (i = 0; i < ef->nprogtab; i++) { 1024 if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) && 1025 strcmp(ef->progtab[i].name + 4, name) == 0) { 1026 start = (void **)ef->progtab[i].addr; 1027 stop = (void **)((char *)ef->progtab[i].addr + 1028 ef->progtab[i].size); 1029 count = stop - start; 1030 if (startp) 1031 *startp = start; 1032 if (stopp) 1033 *stopp = stop; 1034 if (countp) 1035 *countp = count; 1036 return (0); 1037 } 1038 } 1039 return (ESRCH); 1040 } 1041 1042 static int 1043 link_elf_each_function_name(linker_file_t file, 1044 int (*callback)(const char *, void *), void *opaque) 1045 { 1046 elf_file_t ef = (elf_file_t)file; 1047 const Elf_Sym *symp; 1048 int i, error; 1049 1050 /* Exhaustive search */ 1051 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1052 if (symp->st_value != 0 && 1053 ELF_ST_TYPE(symp->st_info) == STT_FUNC) { 1054 error = callback(ef->ddbstrtab + symp->st_name, opaque); 1055 if (error) 1056 return (error); 1057 } 1058 } 1059 return (0); 1060 } 1061 1062 /* 1063 * Symbol lookup function that can be used when the symbol index is known (ie 1064 * in relocations). It uses the symbol index instead of doing a fully fledged 1065 * hash table based lookup when such is valid. For example for local symbols. 1066 * This is not only more efficient, it's also more correct. It's not always 1067 * the case that the symbol can be found through the hash table. 1068 */ 1069 static Elf_Addr 1070 elf_obj_lookup(linker_file_t lf, Elf_Word symidx, int deps) 1071 { 1072 elf_file_t ef = (elf_file_t)lf; 1073 const Elf_Sym *sym; 1074 const char *symbol; 1075 Elf_Addr ret; 1076 1077 /* Don't even try to lookup the symbol if the index is bogus. */ 1078 if (symidx >= ef->ddbsymcnt) 1079 return (0); 1080 1081 sym = ef->ddbsymtab + symidx; 1082 1083 /* Quick answer if there is a definition included. */ 1084 if (sym->st_shndx != SHN_UNDEF) 1085 return (sym->st_value); 1086 1087 /* If we get here, then it is undefined and needs a lookup. */ 1088 switch (ELF_ST_BIND(sym->st_info)) { 1089 case STB_LOCAL: 1090 /* Local, but undefined? huh? */ 1091 return (0); 1092 1093 case STB_GLOBAL: 1094 /* Relative to Data or Function name */ 1095 symbol = ef->ddbstrtab + sym->st_name; 1096 1097 /* Force a lookup failure if the symbol name is bogus. */ 1098 if (*symbol == 0) 1099 return (0); 1100 ret = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); 1101 return ret; 1102 1103 case STB_WEAK: 1104 printf("link_elf_obj: Weak symbols not supported\n"); 1105 return (0); 1106 1107 default: 1108 return (0); 1109 } 1110 } 1111 1112 static void 1113 link_elf_reloc_local(linker_file_t lf) 1114 { 1115 elf_file_t ef = (elf_file_t)lf; 1116 const Elf_Rel *rellim; 1117 const Elf_Rel *rel; 1118 const Elf_Rela *relalim; 1119 const Elf_Rela *rela; 1120 const Elf_Sym *sym; 1121 Elf_Addr base; 1122 int i; 1123 Elf_Word symidx; 1124 1125 /* Perform relocations without addend if there are any: */ 1126 for (i = 0; i < ef->nrel; i++) { 1127 rel = ef->reltab[i].rel; 1128 if (rel == NULL) 1129 panic("lost a reltab!"); 1130 rellim = rel + ef->reltab[i].nrel; 1131 base = findbase(ef, ef->reltab[i].sec); 1132 if (base == 0) 1133 panic("lost base for reltab"); 1134 for ( ; rel < rellim; rel++) { 1135 symidx = ELF_R_SYM(rel->r_info); 1136 if (symidx >= ef->ddbsymcnt) 1137 continue; 1138 sym = ef->ddbsymtab + symidx; 1139 /* Only do local relocs */ 1140 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) 1141 continue; 1142 elf_reloc_local(lf, base, rel, ELF_RELOC_REL, 1143 elf_obj_lookup); 1144 } 1145 } 1146 1147 /* Perform relocations with addend if there are any: */ 1148 for (i = 0; i < ef->nrela; i++) { 1149 rela = ef->relatab[i].rela; 1150 if (rela == NULL) 1151 panic("lost a relatab!"); 1152 relalim = rela + ef->relatab[i].nrela; 1153 base = findbase(ef, ef->relatab[i].sec); 1154 if (base == 0) 1155 panic("lost base for relatab"); 1156 for ( ; rela < relalim; rela++) { 1157 symidx = ELF_R_SYM(rela->r_info); 1158 if (symidx >= ef->ddbsymcnt) 1159 continue; 1160 sym = ef->ddbsymtab + symidx; 1161 /* Only do local relocs */ 1162 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) 1163 continue; 1164 elf_reloc_local(lf, base, rela, ELF_RELOC_RELA, 1165 elf_obj_lookup); 1166 } 1167 } 1168 } 1169