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