1 /*- 2 * Copyright (c) 1998 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 * $FreeBSD: src/sys/kern/link_elf.c,v 1.24 1999/12/24 15:33:36 bde Exp $ 28 * $DragonFly: src/sys/kern/link_elf.c,v 1.29 2008/08/01 23:11:16 dillon Exp $ 29 */ 30 31 #include <sys/param.h> 32 #include <sys/kernel.h> 33 #include <sys/systm.h> 34 #include <sys/malloc.h> 35 #include <sys/proc.h> 36 #include <sys/nlookup.h> 37 #include <sys/fcntl.h> 38 #include <sys/vnode.h> 39 #include <sys/linker.h> 40 #include <machine/elf.h> 41 42 #include <vm/vm.h> 43 #include <vm/vm_param.h> 44 #include <vm/vm_zone.h> 45 #include <vm/vm_object.h> 46 #include <vm/vm_kern.h> 47 #include <vm/vm_extern.h> 48 #include <sys/lock.h> 49 #include <vm/pmap.h> 50 #include <vm/vm_map.h> 51 52 static int link_elf_obj_preload_file(const char *, linker_file_t *); 53 static int link_elf_obj_preload_finish(linker_file_t); 54 static int link_elf_obj_load_file(const char *, linker_file_t *); 55 static int 56 link_elf_obj_lookup_symbol(linker_file_t, const char *, 57 c_linker_sym_t *); 58 static int link_elf_obj_symbol_values(linker_file_t, c_linker_sym_t, linker_symval_t *); 59 static int 60 link_elf_obj_search_symbol(linker_file_t, caddr_t value, 61 c_linker_sym_t * sym, long *diffp); 62 63 static void link_elf_obj_unload_file(linker_file_t); 64 static int 65 link_elf_obj_lookup_set(linker_file_t, const char *, 66 void ***, void ***, int *); 67 static void link_elf_obj_reloc_local(linker_file_t lf); 68 static int elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *); 69 70 static struct linker_class_ops link_elf_obj_class_ops = { 71 link_elf_obj_load_file, 72 link_elf_obj_preload_file, 73 }; 74 75 static struct linker_file_ops link_elf_obj_file_ops = { 76 .lookup_symbol = link_elf_obj_lookup_symbol, 77 .symbol_values = link_elf_obj_symbol_values, 78 .search_symbol = link_elf_obj_search_symbol, 79 .preload_finish = link_elf_obj_preload_finish, 80 .unload = link_elf_obj_unload_file, 81 .lookup_set = link_elf_obj_lookup_set, 82 }; 83 84 typedef struct { 85 void *addr; 86 Elf_Off size; 87 int flags; 88 int sec; /* Original section */ 89 char *name; 90 } Elf_progent; 91 92 typedef struct { 93 Elf_Rel *rel; 94 int nrel; 95 int sec; 96 } Elf_relent; 97 98 typedef struct { 99 Elf_Rela *rela; 100 int nrela; 101 int sec; 102 } Elf_relaent; 103 104 105 typedef struct elf_file { 106 int preloaded; 107 108 caddr_t address; /* Relocation address */ 109 size_t bytes; /* Chunk size in bytes */ 110 vm_object_t object; /* VM object to hold file pages */ 111 Elf_Shdr *e_shdr; 112 113 Elf_progent *progtab; 114 int nprogtab; 115 116 Elf_relaent *relatab; 117 int nrelatab; 118 119 Elf_relent *reltab; 120 int nreltab; 121 122 Elf_Sym *ddbsymtab; /* The symbol table we are using */ 123 long ddbsymcnt; /* Number of symbols */ 124 caddr_t ddbstrtab; /* String table */ 125 long ddbstrcnt; /* number of bytes in string table */ 126 127 caddr_t shstrtab; /* Section name string table */ 128 long shstrcnt; /* number of bytes in string table */ 129 130 caddr_t ctftab; /* CTF table */ 131 long ctfcnt; /* number of bytes in CTF table */ 132 caddr_t ctfoff; /* CTF offset table */ 133 caddr_t typoff; /* Type offset table */ 134 long typlen; /* Number of type entries. */ 135 136 } *elf_file_t; 137 138 static int relocate_file(linker_file_t lf); 139 140 /* 141 * The kernel symbol table starts here. 142 */ 143 extern struct _dynamic _DYNAMIC; 144 145 static void 146 link_elf_obj_init(void *arg) 147 { 148 #if ELF_TARG_CLASS == ELFCLASS32 149 linker_add_class("elf32", NULL, &link_elf_obj_class_ops); 150 #else 151 linker_add_class("elf64", NULL, &link_elf_obj_class_ops); 152 #endif 153 } 154 155 SYSINIT(link_elf, SI_BOOT2_KLD, SI_ORDER_SECOND, link_elf_obj_init, 0); 156 157 static void 158 link_elf_obj_error(const char *file, const char *s) 159 { 160 kprintf("kldload: %s: %s\n", file, s); 161 } 162 163 static int 164 link_elf_obj_preload_file(const char *filename, linker_file_t *result) 165 { 166 Elf_Ehdr *hdr; 167 Elf_Shdr *shdr; 168 Elf_Sym *es; 169 caddr_t modptr, baseptr, sizeptr; 170 char *type; 171 elf_file_t ef; 172 linker_file_t lf; 173 Elf_Addr off; 174 int error, i, j, pb, ra, rl, shstrindex, symstrindex, symtabindex; 175 176 /* 177 * Look to see if we have the module preloaded. 178 */ 179 modptr = preload_search_by_name(filename); 180 if (modptr == NULL) 181 return ENOENT; 182 183 /* It's preloaded, check we can handle it and collect information */ 184 type = (char *)preload_search_info(modptr, MODINFO_TYPE); 185 baseptr = preload_search_info(modptr, MODINFO_ADDR); 186 sizeptr = preload_search_info(modptr, MODINFO_SIZE); 187 hdr = (Elf_Ehdr *) preload_search_info(modptr, MODINFO_METADATA | 188 MODINFOMD_ELFHDR); 189 shdr = (Elf_Shdr *) preload_search_info(modptr, MODINFO_METADATA | 190 MODINFOMD_SHDR); 191 if (type == NULL || 192 (strcmp(type, "elf" __XSTRING(__ELF_WORD_SIZE) " obj module") != 0 && 193 strcmp(type, "elf obj module") != 0)) { 194 return (EFTYPE); 195 } 196 if (baseptr == NULL || sizeptr == NULL || hdr == NULL || shdr == NULL) 197 return (EINVAL); 198 199 ef = kmalloc(sizeof(struct elf_file), M_LINKER, M_WAITOK | M_ZERO); 200 ef->preloaded = 1; 201 ef->address = *(caddr_t *) baseptr; 202 ef->bytes = 0; 203 lf = linker_make_file(filename, ef, &link_elf_obj_file_ops); 204 if (lf == NULL) { 205 kfree(ef, M_LINKER); 206 return ENOMEM; 207 } 208 lf->address = ef->address; 209 lf->size = *(size_t *) sizeptr; 210 211 if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || 212 hdr->e_ident[EI_DATA] != ELF_TARG_DATA || 213 hdr->e_ident[EI_VERSION] != EV_CURRENT || 214 hdr->e_version != EV_CURRENT || 215 hdr->e_type != ET_REL || 216 hdr->e_machine != ELF_TARG_MACH) { 217 error = EFTYPE; 218 goto out; 219 } 220 ef->e_shdr = shdr; 221 222 /* Scan the section header for information and table sizing. */ 223 symtabindex = -1; 224 symstrindex = -1; 225 for (i = 0; i < hdr->e_shnum; i++) { 226 switch (shdr[i].sh_type) { 227 case SHT_PROGBITS: 228 case SHT_NOBITS: 229 ef->nprogtab++; 230 break; 231 case SHT_SYMTAB: 232 symtabindex = i; 233 symstrindex = shdr[i].sh_link; 234 break; 235 case SHT_REL: 236 ef->nreltab++; 237 break; 238 case SHT_RELA: 239 ef->nrelatab++; 240 break; 241 } 242 } 243 244 shstrindex = hdr->e_shstrndx; 245 if (ef->nprogtab == 0 || symstrindex < 0 || 246 symstrindex >= hdr->e_shnum || 247 shdr[symstrindex].sh_type != SHT_STRTAB || shstrindex == 0 || 248 shstrindex >= hdr->e_shnum || 249 shdr[shstrindex].sh_type != SHT_STRTAB) { 250 error = ENOEXEC; 251 goto out; 252 } 253 /* Allocate space for tracking the load chunks */ 254 if (ef->nprogtab != 0) 255 ef->progtab = kmalloc(ef->nprogtab * sizeof(*ef->progtab), 256 M_LINKER, M_WAITOK | M_ZERO); 257 if (ef->nreltab != 0) 258 ef->reltab = kmalloc(ef->nreltab * sizeof(*ef->reltab), 259 M_LINKER, M_WAITOK | M_ZERO); 260 if (ef->nrelatab != 0) 261 ef->relatab = kmalloc(ef->nrelatab * sizeof(*ef->relatab), 262 M_LINKER, M_WAITOK | M_ZERO); 263 if ((ef->nprogtab != 0 && ef->progtab == NULL) || 264 (ef->nreltab != 0 && ef->reltab == NULL) || 265 (ef->nrelatab != 0 && ef->relatab == NULL)) { 266 error = ENOMEM; 267 goto out; 268 } 269 /* XXX, relocate the sh_addr fields saved by the loader. */ 270 off = 0; 271 for (i = 0; i < hdr->e_shnum; i++) { 272 if (shdr[i].sh_addr != 0 && (off == 0 || shdr[i].sh_addr < off)) 273 off = shdr[i].sh_addr; 274 } 275 for (i = 0; i < hdr->e_shnum; i++) { 276 if (shdr[i].sh_addr != 0) 277 shdr[i].sh_addr = shdr[i].sh_addr - off + 278 (Elf_Addr) ef->address; 279 } 280 281 ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym); 282 ef->ddbsymtab = (Elf_Sym *) shdr[symtabindex].sh_addr; 283 ef->ddbstrcnt = shdr[symstrindex].sh_size; 284 ef->ddbstrtab = (char *)shdr[symstrindex].sh_addr; 285 ef->shstrcnt = shdr[shstrindex].sh_size; 286 ef->shstrtab = (char *)shdr[shstrindex].sh_addr; 287 288 /* Now fill out progtab and the relocation tables. */ 289 pb = 0; 290 rl = 0; 291 ra = 0; 292 for (i = 0; i < hdr->e_shnum; i++) { 293 switch (shdr[i].sh_type) { 294 case SHT_PROGBITS: 295 case SHT_NOBITS: 296 ef->progtab[pb].addr = (void *)shdr[i].sh_addr; 297 if (shdr[i].sh_type == SHT_PROGBITS) 298 ef->progtab[pb].name = "<<PROGBITS>>"; 299 else 300 ef->progtab[pb].name = "<<NOBITS>>"; 301 ef->progtab[pb].size = shdr[i].sh_size; 302 ef->progtab[pb].sec = i; 303 if (ef->shstrtab && shdr[i].sh_name != 0) 304 ef->progtab[pb].name = 305 ef->shstrtab + shdr[i].sh_name; 306 #if 0 307 if (ef->progtab[pb].name != NULL && 308 !strcmp(ef->progtab[pb].name, "set_pcpu")) { 309 void *dpcpu; 310 311 dpcpu = dpcpu_alloc(shdr[i].sh_size); 312 if (dpcpu == NULL) { 313 error = ENOSPC; 314 goto out; 315 } 316 memcpy(dpcpu, ef->progtab[pb].addr, 317 ef->progtab[pb].size); 318 dpcpu_copy(dpcpu, shdr[i].sh_size); 319 ef->progtab[pb].addr = dpcpu; 320 #ifdef VIMAGE 321 } else if (ef->progtab[pb].name != NULL && 322 !strcmp(ef->progtab[pb].name, VNET_SETNAME)) { 323 void *vnet_data; 324 325 vnet_data = vnet_data_alloc(shdr[i].sh_size); 326 if (vnet_data == NULL) { 327 error = ENOSPC; 328 goto out; 329 } 330 memcpy(vnet_data, ef->progtab[pb].addr, 331 ef->progtab[pb].size); 332 vnet_data_copy(vnet_data, shdr[i].sh_size); 333 ef->progtab[pb].addr = vnet_data; 334 #endif 335 } 336 #endif 337 /* Update all symbol values with the offset. */ 338 for (j = 0; j < ef->ddbsymcnt; j++) { 339 es = &ef->ddbsymtab[j]; 340 if (es->st_shndx != i) 341 continue; 342 es->st_value += (Elf_Addr) ef->progtab[pb].addr; 343 } 344 pb++; 345 break; 346 case SHT_REL: 347 ef->reltab[rl].rel = (Elf_Rel *) shdr[i].sh_addr; 348 ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel); 349 ef->reltab[rl].sec = shdr[i].sh_info; 350 rl++; 351 break; 352 case SHT_RELA: 353 ef->relatab[ra].rela = (Elf_Rela *) shdr[i].sh_addr; 354 ef->relatab[ra].nrela = 355 shdr[i].sh_size / sizeof(Elf_Rela); 356 ef->relatab[ra].sec = shdr[i].sh_info; 357 ra++; 358 break; 359 } 360 } 361 if (pb != ef->nprogtab) 362 panic("lost progbits"); 363 if (rl != ef->nreltab) 364 panic("lost reltab"); 365 if (ra != ef->nrelatab) 366 panic("lost relatab"); 367 368 /* Local intra-module relocations */ 369 link_elf_obj_reloc_local(lf); 370 371 *result = lf; 372 return (0); 373 374 out: 375 /* preload not done this way */ 376 linker_file_unload(lf /* , LINKER_UNLOAD_FORCE */ ); 377 return (error); 378 } 379 380 static int 381 link_elf_obj_preload_finish(linker_file_t lf) 382 { 383 int error; 384 385 error = relocate_file(lf); 386 387 return (error); 388 } 389 390 static int 391 link_elf_obj_load_file(const char *filename, linker_file_t * result) 392 { 393 struct nlookupdata nd; 394 struct thread *td = curthread; /* XXX */ 395 struct proc *p = td->td_proc; 396 char *pathname; 397 struct vnode *vp; 398 Elf_Ehdr *hdr; 399 Elf_Shdr *shdr; 400 Elf_Sym *es; 401 int nbytes, i, j; 402 vm_offset_t mapbase; 403 size_t mapsize; 404 int error = 0; 405 int resid; 406 elf_file_t ef; 407 linker_file_t lf; 408 int symtabindex; 409 int symstrindex; 410 int shstrindex; 411 int nsym; 412 int pb, rl, ra; 413 int alignmask; 414 415 /* XXX Hack for firmware loading where p == NULL */ 416 if (p == NULL) { 417 p = &proc0; 418 } 419 420 KKASSERT(p != NULL); 421 if (p->p_ucred == NULL) { 422 kprintf("link_elf_obj_load_file: cannot load '%s' from filesystem" 423 " this early\n", filename); 424 return ENOENT; 425 } 426 shdr = NULL; 427 lf = NULL; 428 mapsize = 0; 429 hdr = NULL; 430 pathname = linker_search_path(filename); 431 if (pathname == NULL) 432 return ENOENT; 433 434 error = nlookup_init(&nd, pathname, UIO_SYSSPACE, NLC_FOLLOW | NLC_LOCKVP); 435 if (error == 0) 436 error = vn_open(&nd, NULL, FREAD, 0); 437 kfree(pathname, M_LINKER); 438 if (error) { 439 nlookup_done(&nd); 440 return error; 441 } 442 vp = nd.nl_open_vp; 443 nd.nl_open_vp = NULL; 444 nlookup_done(&nd); 445 446 /* 447 * Read the elf header from the file. 448 */ 449 hdr = kmalloc(sizeof(*hdr), M_LINKER, M_WAITOK); 450 if (hdr == NULL) { 451 error = ENOMEM; 452 goto out; 453 } 454 error = vn_rdwr(UIO_READ, vp, (void *)hdr, sizeof(*hdr), 0, 455 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 456 if (error) 457 goto out; 458 if (resid != 0) { 459 error = ENOEXEC; 460 goto out; 461 } 462 if (!IS_ELF(*hdr)) { 463 error = ENOEXEC; 464 goto out; 465 } 466 467 if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS 468 || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) { 469 link_elf_obj_error(filename, "Unsupported file layout"); 470 error = ENOEXEC; 471 goto out; 472 } 473 if (hdr->e_ident[EI_VERSION] != EV_CURRENT 474 || hdr->e_version != EV_CURRENT) { 475 link_elf_obj_error(filename, "Unsupported file version"); 476 error = ENOEXEC; 477 goto out; 478 } 479 if (hdr->e_type != ET_REL) { 480 error = ENOSYS; 481 goto out; 482 } 483 if (hdr->e_machine != ELF_TARG_MACH) { 484 link_elf_obj_error(filename, "Unsupported machine"); 485 error = ENOEXEC; 486 goto out; 487 } 488 489 ef = kmalloc(sizeof(struct elf_file), M_LINKER, M_WAITOK | M_ZERO); 490 lf = linker_make_file(filename, ef, &link_elf_obj_file_ops); 491 if (lf == NULL) { 492 kfree(ef, M_LINKER); 493 error = ENOMEM; 494 goto out; 495 } 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 = kmalloc(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, vp, (caddr_t) shdr, nbytes, hdr->e_shoff, 515 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 516 if (error) 517 goto out; 518 if (resid) { 519 error = ENOEXEC; 520 goto out; 521 } 522 /* Scan the section header for information and table sizing. */ 523 nsym = 0; 524 symtabindex = -1; 525 symstrindex = -1; 526 for (i = 0; i < hdr->e_shnum; i++) { 527 switch (shdr[i].sh_type) { 528 case SHT_PROGBITS: 529 case SHT_NOBITS: 530 ef->nprogtab++; 531 break; 532 case SHT_SYMTAB: 533 nsym++; 534 symtabindex = i; 535 symstrindex = shdr[i].sh_link; 536 break; 537 case SHT_REL: 538 ef->nreltab++; 539 break; 540 case SHT_RELA: 541 ef->nrelatab++; 542 break; 543 case SHT_STRTAB: 544 break; 545 } 546 } 547 if (ef->nprogtab == 0) { 548 link_elf_obj_error(filename, "file has no contents"); 549 error = ENOEXEC; 550 goto out; 551 } 552 if (nsym != 1) { 553 /* Only allow one symbol table for now */ 554 link_elf_obj_error(filename, "file has no valid symbol table"); 555 error = ENOEXEC; 556 goto out; 557 } 558 if (symstrindex < 0 || symstrindex > hdr->e_shnum || 559 shdr[symstrindex].sh_type != SHT_STRTAB) { 560 link_elf_obj_error(filename, "file has invalid symbol strings"); 561 error = ENOEXEC; 562 goto out; 563 } 564 /* Allocate space for tracking the load chunks */ 565 if (ef->nprogtab != 0) 566 ef->progtab = kmalloc(ef->nprogtab * sizeof(*ef->progtab), 567 M_LINKER, M_WAITOK | M_ZERO); 568 if (ef->nreltab != 0) 569 ef->reltab = kmalloc(ef->nreltab * sizeof(*ef->reltab), 570 M_LINKER, M_WAITOK | M_ZERO); 571 if (ef->nrelatab != 0) 572 ef->relatab = kmalloc(ef->nrelatab * sizeof(*ef->relatab), 573 M_LINKER, M_WAITOK | M_ZERO); 574 if ((ef->nprogtab != 0 && ef->progtab == NULL) || 575 (ef->nreltab != 0 && ef->reltab == NULL) || 576 (ef->nrelatab != 0 && ef->relatab == NULL)) { 577 error = ENOMEM; 578 goto out; 579 } 580 if (symtabindex == -1) 581 panic("lost symbol table index"); 582 /* Allocate space for and load the symbol table */ 583 ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym); 584 ef->ddbsymtab = kmalloc(shdr[symtabindex].sh_size, M_LINKER, M_WAITOK); 585 if (ef->ddbsymtab == NULL) { 586 error = ENOMEM; 587 goto out; 588 } 589 error = vn_rdwr(UIO_READ, vp, (void *)ef->ddbsymtab, 590 shdr[symtabindex].sh_size, shdr[symtabindex].sh_offset, 591 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 592 if (error) 593 goto out; 594 if (resid != 0) { 595 error = EINVAL; 596 goto out; 597 } 598 if (symstrindex == -1) 599 panic("lost symbol string index"); 600 /* Allocate space for and load the symbol strings */ 601 ef->ddbstrcnt = shdr[symstrindex].sh_size; 602 ef->ddbstrtab = kmalloc(shdr[symstrindex].sh_size, M_LINKER, M_WAITOK); 603 if (ef->ddbstrtab == NULL) { 604 error = ENOMEM; 605 goto out; 606 } 607 error = vn_rdwr(UIO_READ, vp, ef->ddbstrtab, 608 shdr[symstrindex].sh_size, shdr[symstrindex].sh_offset, 609 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 610 if (error) 611 goto out; 612 if (resid != 0) { 613 error = EINVAL; 614 goto out; 615 } 616 /* Do we have a string table for the section names? */ 617 shstrindex = -1; 618 if (hdr->e_shstrndx != 0 && 619 shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) { 620 shstrindex = hdr->e_shstrndx; 621 ef->shstrcnt = shdr[shstrindex].sh_size; 622 ef->shstrtab = kmalloc(shdr[shstrindex].sh_size, M_LINKER, 623 M_WAITOK); 624 if (ef->shstrtab == NULL) { 625 error = ENOMEM; 626 goto out; 627 } 628 error = vn_rdwr(UIO_READ, vp, ef->shstrtab, 629 shdr[shstrindex].sh_size, shdr[shstrindex].sh_offset, 630 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 631 if (error) 632 goto out; 633 if (resid != 0) { 634 error = EINVAL; 635 goto out; 636 } 637 } 638 /* Size up code/data(progbits) and bss(nobits). */ 639 alignmask = 0; 640 for (i = 0; i < hdr->e_shnum; i++) { 641 switch (shdr[i].sh_type) { 642 case SHT_PROGBITS: 643 case SHT_NOBITS: 644 alignmask = shdr[i].sh_addralign - 1; 645 mapsize += alignmask; 646 mapsize &= ~alignmask; 647 mapsize += shdr[i].sh_size; 648 break; 649 } 650 } 651 652 /* 653 * We know how much space we need for the text/data/bss/etc. This 654 * stuff needs to be in a single chunk so that profiling etc can get 655 * the bounds and gdb can associate offsets with modules 656 */ 657 ef->object = vm_object_allocate(OBJT_DEFAULT, 658 round_page(mapsize) >> PAGE_SHIFT); 659 if (ef->object == NULL) { 660 error = ENOMEM; 661 goto out; 662 } 663 vm_object_hold(ef->object); 664 vm_object_reference_locked(ef->object); 665 ef->address = (caddr_t) vm_map_min(&kernel_map); 666 ef->bytes = 0; 667 668 /* 669 * In order to satisfy x86_64's architectural requirements on the 670 * location of code and data in the kernel's address space, request a 671 * mapping that is above the kernel. 672 * 673 * vkernel64's text+data is outside the managed VM space entirely. 674 */ 675 #if defined(__amd64__) && defined(_KERNEL_VIRTUAL) 676 error = vkernel_module_memory_alloc(&mapbase, round_page(mapsize)); 677 #else 678 mapbase = KERNBASE; 679 error = vm_map_find(&kernel_map, ef->object, 0, &mapbase, 680 round_page(mapsize), PAGE_SIZE, 681 TRUE, VM_MAPTYPE_NORMAL, 682 VM_PROT_ALL, VM_PROT_ALL, FALSE); 683 vm_object_drop(ef->object); 684 if (error) { 685 vm_object_deallocate(ef->object); 686 ef->object = NULL; 687 goto out; 688 } 689 /* Wire the pages */ 690 error = vm_map_wire(&kernel_map, mapbase, 691 mapbase + round_page(mapsize), 0); 692 #endif 693 if (error != KERN_SUCCESS) { 694 error = ENOMEM; 695 goto out; 696 } 697 /* Inform the kld system about the situation */ 698 lf->address = ef->address = (caddr_t) mapbase; 699 lf->size = round_page(mapsize); 700 ef->bytes = mapsize; 701 702 /* 703 * Now load code/data(progbits), zero bss(nobits), allocate space for 704 * and load relocs 705 */ 706 pb = 0; 707 rl = 0; 708 ra = 0; 709 alignmask = 0; 710 for (i = 0; i < hdr->e_shnum; i++) { 711 switch (shdr[i].sh_type) { 712 case SHT_PROGBITS: 713 case SHT_NOBITS: 714 alignmask = shdr[i].sh_addralign - 1; 715 mapbase += alignmask; 716 mapbase &= ~alignmask; 717 if (ef->shstrtab && shdr[i].sh_name != 0) 718 ef->progtab[pb].name = 719 ef->shstrtab + shdr[i].sh_name; 720 else if (shdr[i].sh_type == SHT_PROGBITS) 721 ef->progtab[pb].name = "<<PROGBITS>>"; 722 else 723 ef->progtab[pb].name = "<<NOBITS>>"; 724 #if 0 725 if (ef->progtab[pb].name != NULL && 726 !strcmp(ef->progtab[pb].name, "set_pcpu")) 727 ef->progtab[pb].addr = 728 dpcpu_alloc(shdr[i].sh_size); 729 #ifdef VIMAGE 730 else if (ef->progtab[pb].name != NULL && 731 !strcmp(ef->progtab[pb].name, VNET_SETNAME)) 732 ef->progtab[pb].addr = 733 vnet_data_alloc(shdr[i].sh_size); 734 #endif 735 else 736 #endif 737 ef->progtab[pb].addr = 738 (void *)(uintptr_t) mapbase; 739 if (ef->progtab[pb].addr == NULL) { 740 error = ENOSPC; 741 goto out; 742 } 743 ef->progtab[pb].size = shdr[i].sh_size; 744 ef->progtab[pb].sec = i; 745 if (shdr[i].sh_type == SHT_PROGBITS) { 746 error = vn_rdwr(UIO_READ, vp, 747 ef->progtab[pb].addr, 748 shdr[i].sh_size, shdr[i].sh_offset, 749 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, 750 &resid); 751 if (error) 752 goto out; 753 if (resid != 0) { 754 error = EINVAL; 755 goto out; 756 } 757 #if 0 758 /* Initialize the per-cpu or vnet area. */ 759 if (ef->progtab[pb].addr != (void *)mapbase && 760 !strcmp(ef->progtab[pb].name, "set_pcpu")) 761 dpcpu_copy(ef->progtab[pb].addr, 762 shdr[i].sh_size); 763 #ifdef VIMAGE 764 else if (ef->progtab[pb].addr != 765 (void *)mapbase && 766 !strcmp(ef->progtab[pb].name, VNET_SETNAME)) 767 vnet_data_copy(ef->progtab[pb].addr, 768 shdr[i].sh_size); 769 #endif 770 #endif 771 } else 772 bzero(ef->progtab[pb].addr, shdr[i].sh_size); 773 774 /* Update all symbol values with the offset. */ 775 for (j = 0; j < ef->ddbsymcnt; j++) { 776 es = &ef->ddbsymtab[j]; 777 if (es->st_shndx != i) 778 continue; 779 es->st_value += (Elf_Addr) ef->progtab[pb].addr; 780 } 781 mapbase += shdr[i].sh_size; 782 pb++; 783 break; 784 case SHT_REL: 785 ef->reltab[rl].rel = kmalloc(shdr[i].sh_size, M_LINKER, M_WAITOK); 786 ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel); 787 ef->reltab[rl].sec = shdr[i].sh_info; 788 error = vn_rdwr(UIO_READ, vp, 789 (void *)ef->reltab[rl].rel, 790 shdr[i].sh_size, shdr[i].sh_offset, 791 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 792 if (error) 793 goto out; 794 if (resid != 0) { 795 error = EINVAL; 796 goto out; 797 } 798 rl++; 799 break; 800 case SHT_RELA: 801 ef->relatab[ra].rela = kmalloc(shdr[i].sh_size, M_LINKER, M_WAITOK); 802 ef->relatab[ra].nrela = shdr[i].sh_size / sizeof(Elf_Rela); 803 ef->relatab[ra].sec = shdr[i].sh_info; 804 error = vn_rdwr(UIO_READ, vp, 805 (void *)ef->relatab[ra].rela, 806 shdr[i].sh_size, shdr[i].sh_offset, 807 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 808 if (error) 809 goto out; 810 if (resid != 0) { 811 error = EINVAL; 812 goto out; 813 } 814 ra++; 815 break; 816 } 817 } 818 if (pb != ef->nprogtab) 819 panic("lost progbits"); 820 if (rl != ef->nreltab) 821 panic("lost reltab"); 822 if (ra != ef->nrelatab) 823 panic("lost relatab"); 824 if (mapbase != (vm_offset_t) ef->address + mapsize) 825 panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n", 826 mapbase, ef->address, mapsize, 827 (vm_offset_t) ef->address + mapsize); 828 829 /* Local intra-module relocations */ 830 link_elf_obj_reloc_local(lf); 831 832 /* Pull in dependencies */ 833 error = linker_load_dependencies(lf); 834 if (error) 835 goto out; 836 837 /* External relocations */ 838 error = relocate_file(lf); 839 if (error) 840 goto out; 841 842 *result = lf; 843 844 out: 845 if (error && lf) 846 linker_file_unload(lf /*, LINKER_UNLOAD_FORCE */); 847 if (hdr) 848 kfree(hdr, M_LINKER); 849 vn_unlock(vp); 850 vn_close(vp, FREAD); 851 852 return error; 853 } 854 855 static void 856 link_elf_obj_unload_file(linker_file_t file) 857 { 858 elf_file_t ef = file->priv; 859 int i; 860 861 if (ef->progtab) { 862 for (i = 0; i < ef->nprogtab; i++) { 863 if (ef->progtab[i].size == 0) 864 continue; 865 if (ef->progtab[i].name == NULL) 866 continue; 867 #if 0 868 if (!strcmp(ef->progtab[i].name, "set_pcpu")) 869 dpcpu_free(ef->progtab[i].addr, 870 ef->progtab[i].size); 871 #ifdef VIMAGE 872 else if (!strcmp(ef->progtab[i].name, VNET_SETNAME)) 873 vnet_data_free(ef->progtab[i].addr, 874 ef->progtab[i].size); 875 #endif 876 #endif 877 } 878 } 879 if (ef->preloaded) { 880 if (ef->reltab) 881 kfree(ef->reltab, M_LINKER); 882 if (ef->relatab) 883 kfree(ef->relatab, M_LINKER); 884 if (ef->progtab) 885 kfree(ef->progtab, M_LINKER); 886 if (ef->ctftab) 887 kfree(ef->ctftab, M_LINKER); 888 if (ef->ctfoff) 889 kfree(ef->ctfoff, M_LINKER); 890 if (ef->typoff) 891 kfree(ef->typoff, M_LINKER); 892 if (file->filename != NULL) 893 preload_delete_name(file->filename); 894 kfree(ef, M_LINKER); 895 /* XXX reclaim module memory? */ 896 return; 897 } 898 899 for (i = 0; i < ef->nreltab; i++) 900 if (ef->reltab[i].rel) 901 kfree(ef->reltab[i].rel, M_LINKER); 902 for (i = 0; i < ef->nrelatab; i++) 903 if (ef->relatab[i].rela) 904 kfree(ef->relatab[i].rela, M_LINKER); 905 if (ef->reltab) 906 kfree(ef->reltab, M_LINKER); 907 if (ef->relatab) 908 kfree(ef->relatab, M_LINKER); 909 if (ef->progtab) 910 kfree(ef->progtab, M_LINKER); 911 912 if (ef->object) { 913 #if defined(__amd64__) && defined(_KERNEL_VIRTUAL) 914 vkernel_module_memory_free((vm_offset_t)ef->address, ef->bytes); 915 #else 916 vm_map_remove(&kernel_map, (vm_offset_t) ef->address, 917 (vm_offset_t) ef->address + 918 (ef->object->size << PAGE_SHIFT)); 919 #endif 920 vm_object_deallocate(ef->object); 921 ef->object = NULL; 922 } 923 if (ef->e_shdr) 924 kfree(ef->e_shdr, M_LINKER); 925 if (ef->ddbsymtab) 926 kfree(ef->ddbsymtab, M_LINKER); 927 if (ef->ddbstrtab) 928 kfree(ef->ddbstrtab, M_LINKER); 929 if (ef->shstrtab) 930 kfree(ef->shstrtab, M_LINKER); 931 if (ef->ctftab) 932 kfree(ef->ctftab, M_LINKER); 933 if (ef->ctfoff) 934 kfree(ef->ctfoff, M_LINKER); 935 if (ef->typoff) 936 kfree(ef->typoff, M_LINKER); 937 kfree(ef, M_LINKER); 938 } 939 940 static const char * 941 symbol_name(elf_file_t ef, Elf_Size r_info) 942 { 943 const Elf_Sym *ref; 944 945 if (ELF_R_SYM(r_info)) { 946 ref = ef->ddbsymtab + ELF_R_SYM(r_info); 947 return ef->ddbstrtab + ref->st_name; 948 } else 949 return NULL; 950 } 951 952 static Elf_Addr 953 findbase(elf_file_t ef, int sec) 954 { 955 int i; 956 Elf_Addr base = 0; 957 958 for (i = 0; i < ef->nprogtab; i++) { 959 if (sec == ef->progtab[i].sec) { 960 base = (Elf_Addr)ef->progtab[i].addr; 961 break; 962 } 963 } 964 return base; 965 } 966 967 static int 968 relocate_file(linker_file_t lf) 969 { 970 elf_file_t ef = lf->priv; 971 const Elf_Rel *rellim; 972 const Elf_Rel *rel; 973 const Elf_Rela *relalim; 974 const Elf_Rela *rela; 975 const char *symname; 976 const Elf_Sym *sym; 977 int i; 978 Elf_Size symidx; 979 Elf_Addr base; 980 981 /* Perform relocations without addend if there are any: */ 982 for (i = 0; i < ef->nreltab; i++) { 983 rel = ef->reltab[i].rel; 984 if (rel == NULL) 985 panic("lost a reltab!"); 986 rellim = rel + ef->reltab[i].nrel; 987 base = findbase(ef, ef->reltab[i].sec); 988 if (base == 0) 989 panic("lost base for reltab"); 990 for ( ; rel < rellim; rel++) { 991 symidx = ELF_R_SYM(rel->r_info); 992 if (symidx >= ef->ddbsymcnt) 993 continue; 994 sym = ef->ddbsymtab + symidx; 995 /* Local relocs are already done */ 996 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 997 continue; 998 if (elf_reloc(lf, base, rel, ELF_RELOC_REL, 999 elf_obj_lookup)) { 1000 symname = symbol_name(ef, rel->r_info); 1001 kprintf("link_elf_obj_obj: symbol %s undefined\n", 1002 symname); 1003 return ENOENT; 1004 } 1005 } 1006 } 1007 1008 /* Perform relocations with addend if there are any: */ 1009 for (i = 0; i < ef->nrelatab; i++) { 1010 rela = ef->relatab[i].rela; 1011 if (rela == NULL) 1012 panic("lost a relatab!"); 1013 relalim = rela + ef->relatab[i].nrela; 1014 base = findbase(ef, ef->relatab[i].sec); 1015 if (base == 0) 1016 panic("lost base for relatab"); 1017 for ( ; rela < relalim; rela++) { 1018 symidx = ELF_R_SYM(rela->r_info); 1019 if (symidx >= ef->ddbsymcnt) 1020 continue; 1021 sym = ef->ddbsymtab + symidx; 1022 /* Local relocs are already done */ 1023 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 1024 continue; 1025 if (elf_reloc(lf, base, rela, ELF_RELOC_RELA, 1026 elf_obj_lookup)) { 1027 symname = symbol_name(ef, rela->r_info); 1028 kprintf("link_elf_obj_obj: symbol %s undefined\n", 1029 symname); 1030 return ENOENT; 1031 } 1032 } 1033 } 1034 1035 return 0; 1036 } 1037 1038 static int 1039 link_elf_obj_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) 1040 { 1041 elf_file_t ef = lf->priv; 1042 const Elf_Sym *symp; 1043 const char *strp; 1044 int i; 1045 1046 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1047 strp = ef->ddbstrtab + symp->st_name; 1048 if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) { 1049 *sym = (c_linker_sym_t) symp; 1050 return 0; 1051 } 1052 } 1053 return ENOENT; 1054 } 1055 1056 static int 1057 link_elf_obj_symbol_values(linker_file_t lf, c_linker_sym_t sym, 1058 linker_symval_t *symval) 1059 { 1060 elf_file_t ef = lf->priv; 1061 const Elf_Sym *es = (const Elf_Sym*) sym; 1062 1063 if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { 1064 symval->name = ef->ddbstrtab + es->st_name; 1065 symval->value = (caddr_t)es->st_value; 1066 symval->size = es->st_size; 1067 return 0; 1068 } 1069 return ENOENT; 1070 } 1071 1072 static int 1073 link_elf_obj_search_symbol(linker_file_t lf, caddr_t value, 1074 c_linker_sym_t *sym, long *diffp) 1075 { 1076 elf_file_t ef = lf->priv; 1077 u_long off = (uintptr_t) (void *) value; 1078 u_long diff = off; 1079 u_long st_value; 1080 const Elf_Sym *es; 1081 const Elf_Sym *best = 0; 1082 int i; 1083 1084 for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) { 1085 if (es->st_name == 0) 1086 continue; 1087 st_value = es->st_value; 1088 if (off >= st_value) { 1089 if (off - st_value < diff) { 1090 diff = off - st_value; 1091 best = es; 1092 if (diff == 0) 1093 break; 1094 } else if (off - st_value == diff) { 1095 best = es; 1096 } 1097 } 1098 } 1099 if (best == 0) 1100 *diffp = off; 1101 else 1102 *diffp = diff; 1103 *sym = (c_linker_sym_t) best; 1104 1105 return 0; 1106 } 1107 1108 /* 1109 * Look up a linker set on an ELF system. 1110 */ 1111 static int 1112 link_elf_obj_lookup_set(linker_file_t lf, const char *name, 1113 void ***startp, void ***stopp, int *countp) 1114 { 1115 elf_file_t ef = lf->priv; 1116 void **start, **stop; 1117 int i, count; 1118 1119 /* Relative to section number */ 1120 for (i = 0; i < ef->nprogtab; i++) { 1121 if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) && 1122 strcmp(ef->progtab[i].name + 4, name) == 0) { 1123 start = (void **)ef->progtab[i].addr; 1124 stop = (void **)((char *)ef->progtab[i].addr + 1125 ef->progtab[i].size); 1126 count = stop - start; 1127 if (startp) 1128 *startp = start; 1129 if (stopp) 1130 *stopp = stop; 1131 if (countp) 1132 *countp = count; 1133 return (0); 1134 } 1135 } 1136 return (ESRCH); 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 int 1147 elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *result) 1148 { 1149 elf_file_t ef = lf->priv; 1150 const Elf_Sym *sym; 1151 const char *symbol; 1152 1153 /* Don't even try to lookup the symbol if the index is bogus. */ 1154 if (symidx >= ef->ddbsymcnt) 1155 return (ENOENT); 1156 1157 sym = ef->ddbsymtab + symidx; 1158 1159 /* Quick answer if there is a definition included. */ 1160 if (sym->st_shndx != SHN_UNDEF) { 1161 *result = sym->st_value; 1162 return (0); 1163 } 1164 1165 /* If we get here, then it is undefined and needs a lookup. */ 1166 switch (ELF_ST_BIND(sym->st_info)) { 1167 case STB_LOCAL: 1168 /* Local, but undefined? huh? */ 1169 return (ENOENT); 1170 1171 case STB_GLOBAL: 1172 /* Relative to Data or Function name */ 1173 symbol = ef->ddbstrtab + sym->st_name; 1174 1175 /* Force a lookup failure if the symbol name is bogus. */ 1176 if (*symbol == 0) 1177 return (ENOENT); 1178 return (linker_file_lookup_symbol(lf, symbol, deps, (caddr_t *)result)); 1179 1180 case STB_WEAK: 1181 kprintf("link_elf_obj_obj: Weak symbols not supported\n"); 1182 return (ENOENT); 1183 1184 default: 1185 return (ENOENT); 1186 } 1187 } 1188 1189 static void 1190 link_elf_obj_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_obj_reloc_local(linker_file_t lf) 1236 { 1237 elf_file_t ef = lf->priv; 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_obj_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