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