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 ef->address = (caddr_t) vm_map_min(kernel_map); 644 error = vm_map_find(kernel_map, ef->object, 0, &mapbase, 645 round_page(mapsize), TRUE, VM_PROT_ALL, VM_PROT_ALL, FALSE); 646 if (error) { 647 vm_object_deallocate(ef->object); 648 ef->object = 0; 649 goto out; 650 } 651 652 /* Wire the pages */ 653 error = vm_map_wire(kernel_map, mapbase, 654 mapbase + round_page(mapsize), 655 VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES); 656 if (error != KERN_SUCCESS) { 657 error = ENOMEM; 658 goto out; 659 } 660 661 /* Inform the kld system about the situation */ 662 lf->address = ef->address = (caddr_t)mapbase; 663 lf->size = mapsize; 664 665 /* 666 * Now load code/data(progbits), zero bss(nobits), allocate space for 667 * and load relocs 668 */ 669 pb = 0; 670 rl = 0; 671 ra = 0; 672 alignmask = 0; 673 for (i = 0; i < hdr->e_shnum; i++) { 674 switch (shdr[i].sh_type) { 675 case SHT_PROGBITS: 676 case SHT_NOBITS: 677 alignmask = shdr[i].sh_addralign - 1; 678 mapbase += alignmask; 679 mapbase &= ~alignmask; 680 ef->progtab[pb].addr = (void *)(uintptr_t)mapbase; 681 if (shdr[i].sh_type == SHT_PROGBITS) { 682 ef->progtab[pb].name = "<<PROGBITS>>"; 683 error = vn_rdwr(UIO_READ, nd.ni_vp, 684 ef->progtab[pb].addr, 685 shdr[i].sh_size, shdr[i].sh_offset, 686 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, 687 NOCRED, &resid, td); 688 if (error) 689 goto out; 690 if (resid != 0){ 691 error = EINVAL; 692 goto out; 693 } 694 } else { 695 ef->progtab[pb].name = "<<NOBITS>>"; 696 bzero(ef->progtab[pb].addr, shdr[i].sh_size); 697 } 698 ef->progtab[pb].size = shdr[i].sh_size; 699 ef->progtab[pb].sec = i; 700 if (ef->shstrtab && shdr[i].sh_name != 0) 701 ef->progtab[pb].name = 702 ef->shstrtab + shdr[i].sh_name; 703 704 /* Update all symbol values with the offset. */ 705 for (j = 0; j < ef->ddbsymcnt; j++) { 706 es = &ef->ddbsymtab[j]; 707 if (es->st_shndx != i) 708 continue; 709 es->st_value += (Elf_Addr)ef->progtab[pb].addr; 710 } 711 mapbase += shdr[i].sh_size; 712 pb++; 713 break; 714 case SHT_REL: 715 ef->reltab[rl].rel = malloc(shdr[i].sh_size, M_LINKER, 716 M_WAITOK); 717 ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel); 718 ef->reltab[rl].sec = shdr[i].sh_info; 719 error = vn_rdwr(UIO_READ, nd.ni_vp, 720 (void *)ef->reltab[rl].rel, 721 shdr[i].sh_size, shdr[i].sh_offset, 722 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 723 &resid, td); 724 if (error) 725 goto out; 726 if (resid != 0){ 727 error = EINVAL; 728 goto out; 729 } 730 rl++; 731 break; 732 case SHT_RELA: 733 ef->relatab[ra].rela = malloc(shdr[i].sh_size, M_LINKER, 734 M_WAITOK); 735 ef->relatab[ra].nrela = 736 shdr[i].sh_size / sizeof(Elf_Rela); 737 ef->relatab[ra].sec = shdr[i].sh_info; 738 error = vn_rdwr(UIO_READ, nd.ni_vp, 739 (void *)ef->relatab[ra].rela, 740 shdr[i].sh_size, shdr[i].sh_offset, 741 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 742 &resid, td); 743 if (error) 744 goto out; 745 if (resid != 0){ 746 error = EINVAL; 747 goto out; 748 } 749 ra++; 750 break; 751 } 752 } 753 if (pb != ef->nprogtab) 754 panic("lost progbits"); 755 if (rl != ef->nrel) 756 panic("lost rel"); 757 if (ra != ef->nrela) 758 panic("lost rela"); 759 if (mapbase != (vm_offset_t)ef->address + mapsize) 760 panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n", 761 mapbase, ef->address, mapsize, 762 (vm_offset_t)ef->address + mapsize); 763 764 /* Local intra-module relocations */ 765 link_elf_reloc_local(lf); 766 767 /* Pull in dependencies */ 768 error = linker_load_dependencies(lf); 769 if (error) 770 goto out; 771 772 /* External relocations */ 773 error = relocate_file(ef); 774 if (error) 775 goto out; 776 777 /* Notify MD code that a module is being loaded. */ 778 error = elf_cpu_load_file(lf); 779 if (error) 780 goto out; 781 782 *result = lf; 783 784 out: 785 if (error && lf) 786 linker_file_unload(lf, LINKER_UNLOAD_FORCE); 787 if (hdr) 788 free(hdr, M_LINKER); 789 VOP_UNLOCK(nd.ni_vp, 0, td); 790 vn_close(nd.ni_vp, FREAD, td->td_ucred, td); 791 792 return error; 793 } 794 795 static void 796 link_elf_unload_file(linker_file_t file) 797 { 798 elf_file_t ef = (elf_file_t) file; 799 int i; 800 801 /* Notify MD code that a module is being unloaded. */ 802 elf_cpu_unload_file(file); 803 804 if (ef->preloaded) { 805 if (ef->reltab) 806 free(ef->reltab, M_LINKER); 807 if (ef->relatab) 808 free(ef->relatab, M_LINKER); 809 if (ef->progtab) 810 free(ef->progtab, M_LINKER); 811 if (file->filename != NULL) 812 preload_delete_name(file->filename); 813 /* XXX reclaim module memory? */ 814 return; 815 } 816 817 for (i = 0; i < ef->nrel; i++) 818 if (ef->reltab[i].rel) 819 free(ef->reltab[i].rel, M_LINKER); 820 for (i = 0; i < ef->nrela; i++) 821 if (ef->relatab[i].rela) 822 free(ef->relatab[i].rela, M_LINKER); 823 if (ef->reltab) 824 free(ef->reltab, M_LINKER); 825 if (ef->relatab) 826 free(ef->relatab, M_LINKER); 827 if (ef->progtab) 828 free(ef->progtab, M_LINKER); 829 830 if (ef->object) { 831 vm_map_remove(kernel_map, (vm_offset_t) ef->address, 832 (vm_offset_t) ef->address + 833 (ef->object->size << PAGE_SHIFT)); 834 } 835 if (ef->e_shdr) 836 free(ef->e_shdr, M_LINKER); 837 if (ef->ddbsymtab) 838 free(ef->ddbsymtab, M_LINKER); 839 if (ef->ddbstrtab) 840 free(ef->ddbstrtab, M_LINKER); 841 if (ef->shstrtab) 842 free(ef->shstrtab, M_LINKER); 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->ddbsymtab + ELF_R_SYM(r_info); 852 return ef->ddbstrtab + ref->st_name; 853 } else 854 return NULL; 855 } 856 857 static Elf_Addr 858 findbase(elf_file_t ef, int sec) 859 { 860 int i; 861 Elf_Addr base = 0; 862 863 for (i = 0; i < ef->nprogtab; i++) { 864 if (sec == ef->progtab[i].sec) { 865 base = (Elf_Addr)ef->progtab[i].addr; 866 break; 867 } 868 } 869 return base; 870 } 871 872 static int 873 relocate_file(elf_file_t ef) 874 { 875 const Elf_Rel *rellim; 876 const Elf_Rel *rel; 877 const Elf_Rela *relalim; 878 const Elf_Rela *rela; 879 const char *symname; 880 const Elf_Sym *sym; 881 int i; 882 Elf_Word symidx; 883 Elf_Addr base; 884 885 886 /* Perform relocations without addend if there are any: */ 887 for (i = 0; i < ef->nrel; i++) { 888 rel = ef->reltab[i].rel; 889 if (rel == NULL) 890 panic("lost a reltab!"); 891 rellim = rel + ef->reltab[i].nrel; 892 base = findbase(ef, ef->reltab[i].sec); 893 if (base == 0) 894 panic("lost base for reltab"); 895 for ( ; rel < rellim; rel++) { 896 symidx = ELF_R_SYM(rel->r_info); 897 if (symidx >= ef->ddbsymcnt) 898 continue; 899 sym = ef->ddbsymtab + symidx; 900 /* Local relocs are already done */ 901 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 902 continue; 903 if (elf_reloc(&ef->lf, base, rel, ELF_RELOC_REL, 904 elf_obj_lookup)) { 905 symname = symbol_name(ef, rel->r_info); 906 printf("link_elf_obj: symbol %s undefined\n", 907 symname); 908 return ENOENT; 909 } 910 } 911 } 912 913 /* Perform relocations with addend if there are any: */ 914 for (i = 0; i < ef->nrela; i++) { 915 rela = ef->relatab[i].rela; 916 if (rela == NULL) 917 panic("lost a relatab!"); 918 relalim = rela + ef->relatab[i].nrela; 919 base = findbase(ef, ef->relatab[i].sec); 920 if (base == 0) 921 panic("lost base for relatab"); 922 for ( ; rela < relalim; rela++) { 923 symidx = ELF_R_SYM(rela->r_info); 924 if (symidx >= ef->ddbsymcnt) 925 continue; 926 sym = ef->ddbsymtab + symidx; 927 /* Local relocs are already done */ 928 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 929 continue; 930 if (elf_reloc(&ef->lf, base, rela, ELF_RELOC_RELA, 931 elf_obj_lookup)) { 932 symname = symbol_name(ef, rela->r_info); 933 printf("link_elf_obj: symbol %s undefined\n", 934 symname); 935 return ENOENT; 936 } 937 } 938 } 939 940 return 0; 941 } 942 943 static int 944 link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) 945 { 946 elf_file_t ef = (elf_file_t) lf; 947 const Elf_Sym *symp; 948 const char *strp; 949 int i; 950 951 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 952 strp = ef->ddbstrtab + symp->st_name; 953 if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) { 954 *sym = (c_linker_sym_t) symp; 955 return 0; 956 } 957 } 958 return ENOENT; 959 } 960 961 static int 962 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, 963 linker_symval_t *symval) 964 { 965 elf_file_t ef = (elf_file_t) lf; 966 const Elf_Sym *es = (const Elf_Sym*) sym; 967 968 if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { 969 symval->name = ef->ddbstrtab + es->st_name; 970 symval->value = (caddr_t)es->st_value; 971 symval->size = es->st_size; 972 return 0; 973 } 974 return ENOENT; 975 } 976 977 static int 978 link_elf_search_symbol(linker_file_t lf, caddr_t value, 979 c_linker_sym_t *sym, long *diffp) 980 { 981 elf_file_t ef = (elf_file_t) lf; 982 u_long off = (uintptr_t) (void *) value; 983 u_long diff = off; 984 u_long st_value; 985 const Elf_Sym *es; 986 const Elf_Sym *best = 0; 987 int i; 988 989 for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) { 990 if (es->st_name == 0) 991 continue; 992 st_value = es->st_value; 993 if (off >= st_value) { 994 if (off - st_value < diff) { 995 diff = off - st_value; 996 best = es; 997 if (diff == 0) 998 break; 999 } else if (off - st_value == diff) { 1000 best = es; 1001 } 1002 } 1003 } 1004 if (best == 0) 1005 *diffp = off; 1006 else 1007 *diffp = diff; 1008 *sym = (c_linker_sym_t) best; 1009 1010 return 0; 1011 } 1012 1013 /* 1014 * Look up a linker set on an ELF system. 1015 */ 1016 static int 1017 link_elf_lookup_set(linker_file_t lf, const char *name, 1018 void ***startp, void ***stopp, int *countp) 1019 { 1020 elf_file_t ef = (elf_file_t)lf; 1021 void **start, **stop; 1022 int i, count; 1023 1024 /* Relative to section number */ 1025 for (i = 0; i < ef->nprogtab; i++) { 1026 if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) && 1027 strcmp(ef->progtab[i].name + 4, name) == 0) { 1028 start = (void **)ef->progtab[i].addr; 1029 stop = (void **)((char *)ef->progtab[i].addr + 1030 ef->progtab[i].size); 1031 count = stop - start; 1032 if (startp) 1033 *startp = start; 1034 if (stopp) 1035 *stopp = stop; 1036 if (countp) 1037 *countp = count; 1038 return (0); 1039 } 1040 } 1041 return (ESRCH); 1042 } 1043 1044 static int 1045 link_elf_each_function_name(linker_file_t file, 1046 int (*callback)(const char *, void *), void *opaque) 1047 { 1048 elf_file_t ef = (elf_file_t)file; 1049 const Elf_Sym *symp; 1050 int i, error; 1051 1052 /* Exhaustive search */ 1053 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1054 if (symp->st_value != 0 && 1055 ELF_ST_TYPE(symp->st_info) == STT_FUNC) { 1056 error = callback(ef->ddbstrtab + symp->st_name, opaque); 1057 if (error) 1058 return (error); 1059 } 1060 } 1061 return (0); 1062 } 1063 1064 /* 1065 * Symbol lookup function that can be used when the symbol index is known (ie 1066 * in relocations). It uses the symbol index instead of doing a fully fledged 1067 * hash table based lookup when such is valid. For example for local symbols. 1068 * This is not only more efficient, it's also more correct. It's not always 1069 * the case that the symbol can be found through the hash table. 1070 */ 1071 static Elf_Addr 1072 elf_obj_lookup(linker_file_t lf, Elf_Word symidx, int deps) 1073 { 1074 elf_file_t ef = (elf_file_t)lf; 1075 const Elf_Sym *sym; 1076 const char *symbol; 1077 Elf_Addr ret; 1078 1079 /* Don't even try to lookup the symbol if the index is bogus. */ 1080 if (symidx >= ef->ddbsymcnt) 1081 return (0); 1082 1083 sym = ef->ddbsymtab + symidx; 1084 1085 /* Quick answer if there is a definition included. */ 1086 if (sym->st_shndx != SHN_UNDEF) 1087 return (sym->st_value); 1088 1089 /* If we get here, then it is undefined and needs a lookup. */ 1090 switch (ELF_ST_BIND(sym->st_info)) { 1091 case STB_LOCAL: 1092 /* Local, but undefined? huh? */ 1093 return (0); 1094 1095 case STB_GLOBAL: 1096 /* Relative to Data or Function name */ 1097 symbol = ef->ddbstrtab + sym->st_name; 1098 1099 /* Force a lookup failure if the symbol name is bogus. */ 1100 if (*symbol == 0) 1101 return (0); 1102 ret = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); 1103 return ret; 1104 1105 case STB_WEAK: 1106 printf("link_elf_obj: Weak symbols not supported\n"); 1107 return (0); 1108 1109 default: 1110 return (0); 1111 } 1112 } 1113 1114 static void 1115 link_elf_reloc_local(linker_file_t lf) 1116 { 1117 elf_file_t ef = (elf_file_t)lf; 1118 const Elf_Rel *rellim; 1119 const Elf_Rel *rel; 1120 const Elf_Rela *relalim; 1121 const Elf_Rela *rela; 1122 const Elf_Sym *sym; 1123 Elf_Addr base; 1124 int i; 1125 Elf_Word symidx; 1126 1127 /* Perform relocations without addend if there are any: */ 1128 for (i = 0; i < ef->nrel; i++) { 1129 rel = ef->reltab[i].rel; 1130 if (rel == NULL) 1131 panic("lost a reltab!"); 1132 rellim = rel + ef->reltab[i].nrel; 1133 base = findbase(ef, ef->reltab[i].sec); 1134 if (base == 0) 1135 panic("lost base for reltab"); 1136 for ( ; rel < rellim; rel++) { 1137 symidx = ELF_R_SYM(rel->r_info); 1138 if (symidx >= ef->ddbsymcnt) 1139 continue; 1140 sym = ef->ddbsymtab + symidx; 1141 /* Only do local relocs */ 1142 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) 1143 continue; 1144 elf_reloc_local(lf, base, rel, ELF_RELOC_REL, 1145 elf_obj_lookup); 1146 } 1147 } 1148 1149 /* Perform relocations with addend if there are any: */ 1150 for (i = 0; i < ef->nrela; i++) { 1151 rela = ef->relatab[i].rela; 1152 if (rela == NULL) 1153 panic("lost a relatab!"); 1154 relalim = rela + ef->relatab[i].nrela; 1155 base = findbase(ef, ef->relatab[i].sec); 1156 if (base == 0) 1157 panic("lost base for relatab"); 1158 for ( ; rela < relalim; rela++) { 1159 symidx = ELF_R_SYM(rela->r_info); 1160 if (symidx >= ef->ddbsymcnt) 1161 continue; 1162 sym = ef->ddbsymtab + symidx; 1163 /* Only do local relocs */ 1164 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) 1165 continue; 1166 elf_reloc_local(lf, base, rela, ELF_RELOC_RELA, 1167 elf_obj_lookup); 1168 } 1169 } 1170 } 1171