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 amd64'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), TRUE, VM_MAPTYPE_NORMAL, 666 VM_PROT_ALL, VM_PROT_ALL, FALSE); 667 if (error) { 668 vm_object_deallocate(ef->object); 669 ef->object = 0; 670 goto out; 671 } 672 /* Wire the pages */ 673 error = vm_map_wire(&kernel_map, mapbase, 674 mapbase + round_page(mapsize), 0); 675 if (error != KERN_SUCCESS) { 676 error = ENOMEM; 677 goto out; 678 } 679 /* Inform the kld system about the situation */ 680 lf->address = ef->address = (caddr_t) mapbase; 681 lf->size = mapsize; 682 683 /* 684 * Now load code/data(progbits), zero bss(nobits), allocate space for 685 * and load relocs 686 */ 687 pb = 0; 688 rl = 0; 689 ra = 0; 690 alignmask = 0; 691 for (i = 0; i < hdr->e_shnum; i++) { 692 switch (shdr[i].sh_type) { 693 case SHT_PROGBITS: 694 case SHT_NOBITS: 695 alignmask = shdr[i].sh_addralign - 1; 696 mapbase += alignmask; 697 mapbase &= ~alignmask; 698 if (ef->shstrtab && shdr[i].sh_name != 0) 699 ef->progtab[pb].name = 700 ef->shstrtab + shdr[i].sh_name; 701 else if (shdr[i].sh_type == SHT_PROGBITS) 702 ef->progtab[pb].name = "<<PROGBITS>>"; 703 else 704 ef->progtab[pb].name = "<<NOBITS>>"; 705 #if 0 706 if (ef->progtab[pb].name != NULL && 707 !strcmp(ef->progtab[pb].name, "set_pcpu")) 708 ef->progtab[pb].addr = 709 dpcpu_alloc(shdr[i].sh_size); 710 #ifdef VIMAGE 711 else if (ef->progtab[pb].name != NULL && 712 !strcmp(ef->progtab[pb].name, VNET_SETNAME)) 713 ef->progtab[pb].addr = 714 vnet_data_alloc(shdr[i].sh_size); 715 #endif 716 else 717 #endif 718 ef->progtab[pb].addr = 719 (void *)(uintptr_t) mapbase; 720 if (ef->progtab[pb].addr == NULL) { 721 error = ENOSPC; 722 goto out; 723 } 724 ef->progtab[pb].size = shdr[i].sh_size; 725 ef->progtab[pb].sec = i; 726 if (shdr[i].sh_type == SHT_PROGBITS) { 727 error = vn_rdwr(UIO_READ, vp, 728 ef->progtab[pb].addr, 729 shdr[i].sh_size, shdr[i].sh_offset, 730 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, 731 &resid); 732 if (error) 733 goto out; 734 if (resid != 0) { 735 error = EINVAL; 736 goto out; 737 } 738 #if 0 739 /* Initialize the per-cpu or vnet area. */ 740 if (ef->progtab[pb].addr != (void *)mapbase && 741 !strcmp(ef->progtab[pb].name, "set_pcpu")) 742 dpcpu_copy(ef->progtab[pb].addr, 743 shdr[i].sh_size); 744 #ifdef VIMAGE 745 else if (ef->progtab[pb].addr != 746 (void *)mapbase && 747 !strcmp(ef->progtab[pb].name, VNET_SETNAME)) 748 vnet_data_copy(ef->progtab[pb].addr, 749 shdr[i].sh_size); 750 #endif 751 #endif 752 } else 753 bzero(ef->progtab[pb].addr, shdr[i].sh_size); 754 755 /* Update all symbol values with the offset. */ 756 for (j = 0; j < ef->ddbsymcnt; j++) { 757 es = &ef->ddbsymtab[j]; 758 if (es->st_shndx != i) 759 continue; 760 es->st_value += (Elf_Addr) ef->progtab[pb].addr; 761 } 762 mapbase += shdr[i].sh_size; 763 pb++; 764 break; 765 case SHT_REL: 766 ef->reltab[rl].rel = kmalloc(shdr[i].sh_size, M_LINKER, M_WAITOK); 767 ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel); 768 ef->reltab[rl].sec = shdr[i].sh_info; 769 error = vn_rdwr(UIO_READ, vp, 770 (void *)ef->reltab[rl].rel, 771 shdr[i].sh_size, shdr[i].sh_offset, 772 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 773 if (error) 774 goto out; 775 if (resid != 0) { 776 error = EINVAL; 777 goto out; 778 } 779 rl++; 780 break; 781 case SHT_RELA: 782 ef->relatab[ra].rela = kmalloc(shdr[i].sh_size, M_LINKER, M_WAITOK); 783 ef->relatab[ra].nrela = shdr[i].sh_size / sizeof(Elf_Rela); 784 ef->relatab[ra].sec = shdr[i].sh_info; 785 error = vn_rdwr(UIO_READ, vp, 786 (void *)ef->relatab[ra].rela, 787 shdr[i].sh_size, shdr[i].sh_offset, 788 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 789 if (error) 790 goto out; 791 if (resid != 0) { 792 error = EINVAL; 793 goto out; 794 } 795 ra++; 796 break; 797 } 798 } 799 if (pb != ef->nprogtab) 800 panic("lost progbits"); 801 if (rl != ef->nreltab) 802 panic("lost reltab"); 803 if (ra != ef->nrelatab) 804 panic("lost relatab"); 805 if (mapbase != (vm_offset_t) ef->address + mapsize) 806 panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n", 807 mapbase, ef->address, mapsize, 808 (vm_offset_t) ef->address + mapsize); 809 810 /* Local intra-module relocations */ 811 link_elf_obj_reloc_local(lf); 812 813 /* Pull in dependencies */ 814 error = linker_load_dependencies(lf); 815 if (error) 816 goto out; 817 818 /* External relocations */ 819 error = relocate_file(lf); 820 if (error) 821 goto out; 822 823 *result = lf; 824 825 out: 826 if (error && lf) 827 linker_file_unload(lf /*, LINKER_UNLOAD_FORCE */); 828 if (hdr) 829 kfree(hdr, M_LINKER); 830 vn_unlock(vp); 831 vn_close(vp, FREAD); 832 833 return error; 834 } 835 836 static void 837 link_elf_obj_unload_file(linker_file_t file) 838 { 839 elf_file_t ef = file->priv; 840 int i; 841 842 if (ef->progtab) { 843 for (i = 0; i < ef->nprogtab; i++) { 844 if (ef->progtab[i].size == 0) 845 continue; 846 if (ef->progtab[i].name == NULL) 847 continue; 848 #if 0 849 if (!strcmp(ef->progtab[i].name, "set_pcpu")) 850 dpcpu_free(ef->progtab[i].addr, 851 ef->progtab[i].size); 852 #ifdef VIMAGE 853 else if (!strcmp(ef->progtab[i].name, VNET_SETNAME)) 854 vnet_data_free(ef->progtab[i].addr, 855 ef->progtab[i].size); 856 #endif 857 #endif 858 } 859 } 860 if (ef->preloaded) { 861 if (ef->reltab) 862 kfree(ef->reltab, M_LINKER); 863 if (ef->relatab) 864 kfree(ef->relatab, M_LINKER); 865 if (ef->progtab) 866 kfree(ef->progtab, M_LINKER); 867 if (ef->ctftab) 868 kfree(ef->ctftab, M_LINKER); 869 if (ef->ctfoff) 870 kfree(ef->ctfoff, M_LINKER); 871 if (ef->typoff) 872 kfree(ef->typoff, M_LINKER); 873 if (file->filename != NULL) 874 preload_delete_name(file->filename); 875 kfree(ef, M_LINKER); 876 /* XXX reclaim module memory? */ 877 return; 878 } 879 880 for (i = 0; i < ef->nreltab; i++) 881 if (ef->reltab[i].rel) 882 kfree(ef->reltab[i].rel, M_LINKER); 883 for (i = 0; i < ef->nrelatab; i++) 884 if (ef->relatab[i].rela) 885 kfree(ef->relatab[i].rela, M_LINKER); 886 if (ef->reltab) 887 kfree(ef->reltab, M_LINKER); 888 if (ef->relatab) 889 kfree(ef->relatab, M_LINKER); 890 if (ef->progtab) 891 kfree(ef->progtab, M_LINKER); 892 893 if (ef->object) { 894 vm_map_remove(&kernel_map, (vm_offset_t) ef->address, 895 (vm_offset_t) ef->address + 896 (ef->object->size << PAGE_SHIFT)); 897 } 898 if (ef->e_shdr) 899 kfree(ef->e_shdr, M_LINKER); 900 if (ef->ddbsymtab) 901 kfree(ef->ddbsymtab, M_LINKER); 902 if (ef->ddbstrtab) 903 kfree(ef->ddbstrtab, M_LINKER); 904 if (ef->shstrtab) 905 kfree(ef->shstrtab, M_LINKER); 906 if (ef->ctftab) 907 kfree(ef->ctftab, M_LINKER); 908 if (ef->ctfoff) 909 kfree(ef->ctfoff, M_LINKER); 910 if (ef->typoff) 911 kfree(ef->typoff, M_LINKER); 912 kfree(ef, M_LINKER); 913 } 914 915 static const char * 916 symbol_name(elf_file_t ef, Elf_Size r_info) 917 { 918 const Elf_Sym *ref; 919 920 if (ELF_R_SYM(r_info)) { 921 ref = ef->ddbsymtab + ELF_R_SYM(r_info); 922 return ef->ddbstrtab + ref->st_name; 923 } else 924 return NULL; 925 } 926 927 static Elf_Addr 928 findbase(elf_file_t ef, int sec) 929 { 930 int i; 931 Elf_Addr base = 0; 932 933 for (i = 0; i < ef->nprogtab; i++) { 934 if (sec == ef->progtab[i].sec) { 935 base = (Elf_Addr)ef->progtab[i].addr; 936 break; 937 } 938 } 939 return base; 940 } 941 942 static int 943 relocate_file(linker_file_t lf) 944 { 945 elf_file_t ef = lf->priv; 946 const Elf_Rel *rellim; 947 const Elf_Rel *rel; 948 const Elf_Rela *relalim; 949 const Elf_Rela *rela; 950 const char *symname; 951 const Elf_Sym *sym; 952 int i; 953 Elf_Size symidx; 954 Elf_Addr base; 955 956 /* Perform relocations without addend if there are any: */ 957 for (i = 0; i < ef->nreltab; i++) { 958 rel = ef->reltab[i].rel; 959 if (rel == NULL) 960 panic("lost a reltab!"); 961 rellim = rel + ef->reltab[i].nrel; 962 base = findbase(ef, ef->reltab[i].sec); 963 if (base == 0) 964 panic("lost base for reltab"); 965 for ( ; rel < rellim; rel++) { 966 symidx = ELF_R_SYM(rel->r_info); 967 if (symidx >= ef->ddbsymcnt) 968 continue; 969 sym = ef->ddbsymtab + symidx; 970 /* Local relocs are already done */ 971 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 972 continue; 973 if (elf_reloc(lf, base, rel, ELF_RELOC_REL, 974 elf_obj_lookup)) { 975 symname = symbol_name(ef, rel->r_info); 976 kprintf("link_elf_obj_obj: symbol %s undefined\n", 977 symname); 978 return ENOENT; 979 } 980 } 981 } 982 983 /* Perform relocations with addend if there are any: */ 984 for (i = 0; i < ef->nrelatab; i++) { 985 rela = ef->relatab[i].rela; 986 if (rela == NULL) 987 panic("lost a relatab!"); 988 relalim = rela + ef->relatab[i].nrela; 989 base = findbase(ef, ef->relatab[i].sec); 990 if (base == 0) 991 panic("lost base for relatab"); 992 for ( ; rela < relalim; rela++) { 993 symidx = ELF_R_SYM(rela->r_info); 994 if (symidx >= ef->ddbsymcnt) 995 continue; 996 sym = ef->ddbsymtab + symidx; 997 /* Local relocs are already done */ 998 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 999 continue; 1000 if (elf_reloc(lf, base, rela, ELF_RELOC_RELA, 1001 elf_obj_lookup)) { 1002 symname = symbol_name(ef, rela->r_info); 1003 kprintf("link_elf_obj_obj: symbol %s undefined\n", 1004 symname); 1005 return ENOENT; 1006 } 1007 } 1008 } 1009 1010 return 0; 1011 } 1012 1013 static int 1014 link_elf_obj_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) 1015 { 1016 elf_file_t ef = lf->priv; 1017 const Elf_Sym *symp; 1018 const char *strp; 1019 int i; 1020 1021 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1022 strp = ef->ddbstrtab + symp->st_name; 1023 if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) { 1024 *sym = (c_linker_sym_t) symp; 1025 return 0; 1026 } 1027 } 1028 return ENOENT; 1029 } 1030 1031 static int 1032 link_elf_obj_symbol_values(linker_file_t lf, c_linker_sym_t sym, 1033 linker_symval_t *symval) 1034 { 1035 elf_file_t ef = lf->priv; 1036 const Elf_Sym *es = (const Elf_Sym*) sym; 1037 1038 if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { 1039 symval->name = ef->ddbstrtab + es->st_name; 1040 symval->value = (caddr_t)es->st_value; 1041 symval->size = es->st_size; 1042 return 0; 1043 } 1044 return ENOENT; 1045 } 1046 1047 static int 1048 link_elf_obj_search_symbol(linker_file_t lf, caddr_t value, 1049 c_linker_sym_t *sym, long *diffp) 1050 { 1051 elf_file_t ef = lf->priv; 1052 u_long off = (uintptr_t) (void *) value; 1053 u_long diff = off; 1054 u_long st_value; 1055 const Elf_Sym *es; 1056 const Elf_Sym *best = 0; 1057 int i; 1058 1059 for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) { 1060 if (es->st_name == 0) 1061 continue; 1062 st_value = es->st_value; 1063 if (off >= st_value) { 1064 if (off - st_value < diff) { 1065 diff = off - st_value; 1066 best = es; 1067 if (diff == 0) 1068 break; 1069 } else if (off - st_value == diff) { 1070 best = es; 1071 } 1072 } 1073 } 1074 if (best == 0) 1075 *diffp = off; 1076 else 1077 *diffp = diff; 1078 *sym = (c_linker_sym_t) best; 1079 1080 return 0; 1081 } 1082 1083 /* 1084 * Look up a linker set on an ELF system. 1085 */ 1086 static int 1087 link_elf_obj_lookup_set(linker_file_t lf, const char *name, 1088 void ***startp, void ***stopp, int *countp) 1089 { 1090 elf_file_t ef = lf->priv; 1091 void **start, **stop; 1092 int i, count; 1093 1094 /* Relative to section number */ 1095 for (i = 0; i < ef->nprogtab; i++) { 1096 if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) && 1097 strcmp(ef->progtab[i].name + 4, name) == 0) { 1098 start = (void **)ef->progtab[i].addr; 1099 stop = (void **)((char *)ef->progtab[i].addr + 1100 ef->progtab[i].size); 1101 count = stop - start; 1102 if (startp) 1103 *startp = start; 1104 if (stopp) 1105 *stopp = stop; 1106 if (countp) 1107 *countp = count; 1108 return (0); 1109 } 1110 } 1111 return (ESRCH); 1112 } 1113 1114 /* 1115 * Symbol lookup function that can be used when the symbol index is known (ie 1116 * in relocations). It uses the symbol index instead of doing a fully fledged 1117 * hash table based lookup when such is valid. For example for local symbols. 1118 * This is not only more efficient, it's also more correct. It's not always 1119 * the case that the symbol can be found through the hash table. 1120 */ 1121 static int 1122 elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *result) 1123 { 1124 elf_file_t ef = lf->priv; 1125 const Elf_Sym *sym; 1126 const char *symbol; 1127 1128 /* Don't even try to lookup the symbol if the index is bogus. */ 1129 if (symidx >= ef->ddbsymcnt) 1130 return (ENOENT); 1131 1132 sym = ef->ddbsymtab + symidx; 1133 1134 /* Quick answer if there is a definition included. */ 1135 if (sym->st_shndx != SHN_UNDEF) { 1136 *result = sym->st_value; 1137 return (0); 1138 } 1139 1140 /* If we get here, then it is undefined and needs a lookup. */ 1141 switch (ELF_ST_BIND(sym->st_info)) { 1142 case STB_LOCAL: 1143 /* Local, but undefined? huh? */ 1144 return (ENOENT); 1145 1146 case STB_GLOBAL: 1147 /* Relative to Data or Function name */ 1148 symbol = ef->ddbstrtab + sym->st_name; 1149 1150 /* Force a lookup failure if the symbol name is bogus. */ 1151 if (*symbol == 0) 1152 return (ENOENT); 1153 return (linker_file_lookup_symbol(lf, symbol, deps, (caddr_t *)result)); 1154 1155 case STB_WEAK: 1156 kprintf("link_elf_obj_obj: Weak symbols not supported\n"); 1157 return (ENOENT); 1158 1159 default: 1160 return (ENOENT); 1161 } 1162 } 1163 1164 static void 1165 link_elf_obj_fix_link_set(elf_file_t ef) 1166 { 1167 static const char startn[] = "__start_"; 1168 static const char stopn[] = "__stop_"; 1169 Elf_Sym *sym; 1170 const char *sym_name, *linkset_name; 1171 Elf_Addr startp, stopp; 1172 Elf_Size symidx; 1173 int start, i; 1174 1175 startp = stopp = 0; 1176 for (symidx = 1 /* zero entry is special */; 1177 symidx < ef->ddbsymcnt; symidx++) { 1178 sym = ef->ddbsymtab + symidx; 1179 if (sym->st_shndx != SHN_UNDEF) 1180 continue; 1181 1182 sym_name = ef->ddbstrtab + sym->st_name; 1183 if (strncmp(sym_name, startn, sizeof(startn) - 1) == 0) { 1184 start = 1; 1185 linkset_name = sym_name + sizeof(startn) - 1; 1186 } 1187 else if (strncmp(sym_name, stopn, sizeof(stopn) - 1) == 0) { 1188 start = 0; 1189 linkset_name = sym_name + sizeof(stopn) - 1; 1190 } 1191 else 1192 continue; 1193 1194 for (i = 0; i < ef->nprogtab; i++) { 1195 if (strcmp(ef->progtab[i].name, linkset_name) == 0) { 1196 startp = (Elf_Addr)ef->progtab[i].addr; 1197 stopp = (Elf_Addr)(startp + ef->progtab[i].size); 1198 break; 1199 } 1200 } 1201 if (i == ef->nprogtab) 1202 continue; 1203 1204 sym->st_value = start ? startp : stopp; 1205 sym->st_shndx = i; 1206 } 1207 } 1208 1209 static void 1210 link_elf_obj_reloc_local(linker_file_t lf) 1211 { 1212 elf_file_t ef = lf->priv; 1213 const Elf_Rel *rellim; 1214 const Elf_Rel *rel; 1215 const Elf_Rela *relalim; 1216 const Elf_Rela *rela; 1217 const Elf_Sym *sym; 1218 Elf_Addr base; 1219 int i; 1220 Elf_Size symidx; 1221 1222 link_elf_obj_fix_link_set(ef); 1223 1224 /* Perform relocations without addend if there are any: */ 1225 for (i = 0; i < ef->nreltab; i++) { 1226 rel = ef->reltab[i].rel; 1227 if (rel == NULL) 1228 panic("lost a reltab!"); 1229 rellim = rel + ef->reltab[i].nrel; 1230 base = findbase(ef, ef->reltab[i].sec); 1231 if (base == 0) 1232 panic("lost base for reltab"); 1233 for ( ; rel < rellim; rel++) { 1234 symidx = ELF_R_SYM(rel->r_info); 1235 if (symidx >= ef->ddbsymcnt) 1236 continue; 1237 sym = ef->ddbsymtab + symidx; 1238 /* Only do local relocs */ 1239 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) 1240 continue; 1241 elf_reloc_local(lf, base, rel, ELF_RELOC_REL, 1242 elf_obj_lookup); 1243 } 1244 } 1245 1246 /* Perform relocations with addend if there are any: */ 1247 for (i = 0; i < ef->nrelatab; i++) { 1248 rela = ef->relatab[i].rela; 1249 if (rela == NULL) 1250 panic("lost a relatab!"); 1251 relalim = rela + ef->relatab[i].nrela; 1252 base = findbase(ef, ef->relatab[i].sec); 1253 if (base == 0) 1254 panic("lost base for relatab"); 1255 for ( ; rela < relalim; rela++) { 1256 symidx = ELF_R_SYM(rela->r_info); 1257 if (symidx >= ef->ddbsymcnt) 1258 continue; 1259 sym = ef->ddbsymtab + symidx; 1260 /* Only do local relocs */ 1261 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) 1262 continue; 1263 elf_reloc_local(lf, base, rela, ELF_RELOC_RELA, 1264 elf_obj_lookup); 1265 } 1266 } 1267 } 1268