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 /* XXX Hack for firmware loading where p == NULL */ 414 if (p == NULL) { 415 p = &proc0; 416 } 417 418 KKASSERT(p != NULL); 419 if (p->p_ucred == NULL) { 420 kprintf("link_elf_obj_load_file: cannot load '%s' from filesystem" 421 " this early\n", filename); 422 return ENOENT; 423 } 424 shdr = NULL; 425 lf = NULL; 426 mapsize = 0; 427 hdr = NULL; 428 pathname = linker_search_path(filename); 429 if (pathname == NULL) 430 return ENOENT; 431 432 error = nlookup_init(&nd, pathname, UIO_SYSSPACE, NLC_FOLLOW | NLC_LOCKVP); 433 if (error == 0) 434 error = vn_open(&nd, NULL, FREAD, 0); 435 kfree(pathname, M_LINKER); 436 if (error) { 437 nlookup_done(&nd); 438 return error; 439 } 440 vp = nd.nl_open_vp; 441 nd.nl_open_vp = NULL; 442 nlookup_done(&nd); 443 444 /* 445 * Read the elf header from the file. 446 */ 447 hdr = kmalloc(sizeof(*hdr), M_LINKER, M_WAITOK); 448 if (hdr == NULL) { 449 error = ENOMEM; 450 goto out; 451 } 452 error = vn_rdwr(UIO_READ, vp, (void *)hdr, sizeof(*hdr), 0, 453 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 454 if (error) 455 goto out; 456 if (resid != 0) { 457 error = ENOEXEC; 458 goto out; 459 } 460 if (!IS_ELF(*hdr)) { 461 error = ENOEXEC; 462 goto out; 463 } 464 465 if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS 466 || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) { 467 link_elf_obj_error(filename, "Unsupported file layout"); 468 error = ENOEXEC; 469 goto out; 470 } 471 if (hdr->e_ident[EI_VERSION] != EV_CURRENT 472 || hdr->e_version != EV_CURRENT) { 473 link_elf_obj_error(filename, "Unsupported file version"); 474 error = ENOEXEC; 475 goto out; 476 } 477 if (hdr->e_type != ET_REL) { 478 error = ENOSYS; 479 goto out; 480 } 481 if (hdr->e_machine != ELF_TARG_MACH) { 482 link_elf_obj_error(filename, "Unsupported machine"); 483 error = ENOEXEC; 484 goto out; 485 } 486 487 ef = kmalloc(sizeof(struct elf_file), M_LINKER, M_WAITOK | M_ZERO); 488 lf = linker_make_file(filename, ef, &link_elf_obj_file_ops); 489 if (lf == NULL) { 490 kfree(ef, M_LINKER); 491 error = ENOMEM; 492 goto out; 493 } 494 ef->nprogtab = 0; 495 ef->e_shdr = 0; 496 ef->nreltab = 0; 497 ef->nrelatab = 0; 498 499 /* Allocate and read in the section header */ 500 nbytes = hdr->e_shnum * hdr->e_shentsize; 501 if (nbytes == 0 || hdr->e_shoff == 0 || 502 hdr->e_shentsize != sizeof(Elf_Shdr)) { 503 error = ENOEXEC; 504 goto out; 505 } 506 shdr = kmalloc(nbytes, M_LINKER, M_WAITOK); 507 if (shdr == NULL) { 508 error = ENOMEM; 509 goto out; 510 } 511 ef->e_shdr = shdr; 512 error = vn_rdwr(UIO_READ, vp, (caddr_t) shdr, nbytes, hdr->e_shoff, 513 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 514 if (error) 515 goto out; 516 if (resid) { 517 error = ENOEXEC; 518 goto out; 519 } 520 /* Scan the section header for information and table sizing. */ 521 nsym = 0; 522 symtabindex = -1; 523 symstrindex = -1; 524 for (i = 0; i < hdr->e_shnum; i++) { 525 switch (shdr[i].sh_type) { 526 case SHT_PROGBITS: 527 case SHT_NOBITS: 528 ef->nprogtab++; 529 break; 530 case SHT_SYMTAB: 531 nsym++; 532 symtabindex = i; 533 symstrindex = shdr[i].sh_link; 534 break; 535 case SHT_REL: 536 ef->nreltab++; 537 break; 538 case SHT_RELA: 539 ef->nrelatab++; 540 break; 541 case SHT_STRTAB: 542 break; 543 } 544 } 545 if (ef->nprogtab == 0) { 546 link_elf_obj_error(filename, "file has no contents"); 547 error = ENOEXEC; 548 goto out; 549 } 550 if (nsym != 1) { 551 /* Only allow one symbol table for now */ 552 link_elf_obj_error(filename, "file has no valid symbol table"); 553 error = ENOEXEC; 554 goto out; 555 } 556 if (symstrindex < 0 || symstrindex > hdr->e_shnum || 557 shdr[symstrindex].sh_type != SHT_STRTAB) { 558 link_elf_obj_error(filename, "file has invalid symbol strings"); 559 error = ENOEXEC; 560 goto out; 561 } 562 /* Allocate space for tracking the load chunks */ 563 if (ef->nprogtab != 0) 564 ef->progtab = kmalloc(ef->nprogtab * sizeof(*ef->progtab), 565 M_LINKER, M_WAITOK | M_ZERO); 566 if (ef->nreltab != 0) 567 ef->reltab = kmalloc(ef->nreltab * sizeof(*ef->reltab), 568 M_LINKER, M_WAITOK | M_ZERO); 569 if (ef->nrelatab != 0) 570 ef->relatab = kmalloc(ef->nrelatab * sizeof(*ef->relatab), 571 M_LINKER, M_WAITOK | M_ZERO); 572 if ((ef->nprogtab != 0 && ef->progtab == NULL) || 573 (ef->nreltab != 0 && ef->reltab == NULL) || 574 (ef->nrelatab != 0 && ef->relatab == NULL)) { 575 error = ENOMEM; 576 goto out; 577 } 578 if (symtabindex == -1) 579 panic("lost symbol table index"); 580 /* Allocate space for and load the symbol table */ 581 ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym); 582 ef->ddbsymtab = kmalloc(shdr[symtabindex].sh_size, M_LINKER, M_WAITOK); 583 if (ef->ddbsymtab == NULL) { 584 error = ENOMEM; 585 goto out; 586 } 587 error = vn_rdwr(UIO_READ, vp, (void *)ef->ddbsymtab, 588 shdr[symtabindex].sh_size, shdr[symtabindex].sh_offset, 589 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 590 if (error) 591 goto out; 592 if (resid != 0) { 593 error = EINVAL; 594 goto out; 595 } 596 if (symstrindex == -1) 597 panic("lost symbol string index"); 598 /* Allocate space for and load the symbol strings */ 599 ef->ddbstrcnt = shdr[symstrindex].sh_size; 600 ef->ddbstrtab = kmalloc(shdr[symstrindex].sh_size, M_LINKER, M_WAITOK); 601 if (ef->ddbstrtab == NULL) { 602 error = ENOMEM; 603 goto out; 604 } 605 error = vn_rdwr(UIO_READ, vp, ef->ddbstrtab, 606 shdr[symstrindex].sh_size, shdr[symstrindex].sh_offset, 607 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 608 if (error) 609 goto out; 610 if (resid != 0) { 611 error = EINVAL; 612 goto out; 613 } 614 /* Do we have a string table for the section names? */ 615 shstrindex = -1; 616 if (hdr->e_shstrndx != 0 && 617 shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) { 618 shstrindex = hdr->e_shstrndx; 619 ef->shstrcnt = shdr[shstrindex].sh_size; 620 ef->shstrtab = kmalloc(shdr[shstrindex].sh_size, M_LINKER, 621 M_WAITOK); 622 if (ef->shstrtab == NULL) { 623 error = ENOMEM; 624 goto out; 625 } 626 error = vn_rdwr(UIO_READ, vp, ef->shstrtab, 627 shdr[shstrindex].sh_size, shdr[shstrindex].sh_offset, 628 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 629 if (error) 630 goto out; 631 if (resid != 0) { 632 error = EINVAL; 633 goto out; 634 } 635 } 636 /* Size up code/data(progbits) and bss(nobits). */ 637 alignmask = 0; 638 for (i = 0; i < hdr->e_shnum; i++) { 639 switch (shdr[i].sh_type) { 640 case SHT_PROGBITS: 641 case SHT_NOBITS: 642 alignmask = shdr[i].sh_addralign - 1; 643 mapsize += alignmask; 644 mapsize &= ~alignmask; 645 mapsize += shdr[i].sh_size; 646 break; 647 } 648 } 649 650 /* 651 * We know how much space we need for the text/data/bss/etc. This 652 * stuff needs to be in a single chunk so that profiling etc can get 653 * the bounds and gdb can associate offsets with modules 654 */ 655 ef->object = vm_object_allocate(OBJT_DEFAULT, 656 round_page(mapsize) >> PAGE_SHIFT); 657 if (ef->object == NULL) { 658 error = ENOMEM; 659 goto out; 660 } 661 ef->address = (caddr_t) vm_map_min(&kernel_map); 662 663 /* 664 * In order to satisfy x86_64's architectural requirements on the 665 * location of code and data in the kernel's address space, request a 666 * mapping that is above the kernel. 667 */ 668 mapbase = KERNBASE; 669 error = vm_map_find(&kernel_map, ef->object, 0, &mapbase, 670 round_page(mapsize), PAGE_SIZE, 671 TRUE, VM_MAPTYPE_NORMAL, 672 VM_PROT_ALL, VM_PROT_ALL, FALSE); 673 if (error) { 674 vm_object_deallocate(ef->object); 675 ef->object = 0; 676 goto out; 677 } 678 /* Wire the pages */ 679 error = vm_map_wire(&kernel_map, mapbase, 680 mapbase + round_page(mapsize), 0); 681 if (error != KERN_SUCCESS) { 682 error = ENOMEM; 683 goto out; 684 } 685 /* Inform the kld system about the situation */ 686 lf->address = ef->address = (caddr_t) mapbase; 687 lf->size = mapsize; 688 689 /* 690 * Now load code/data(progbits), zero bss(nobits), allocate space for 691 * and load relocs 692 */ 693 pb = 0; 694 rl = 0; 695 ra = 0; 696 alignmask = 0; 697 for (i = 0; i < hdr->e_shnum; i++) { 698 switch (shdr[i].sh_type) { 699 case SHT_PROGBITS: 700 case SHT_NOBITS: 701 alignmask = shdr[i].sh_addralign - 1; 702 mapbase += alignmask; 703 mapbase &= ~alignmask; 704 if (ef->shstrtab && shdr[i].sh_name != 0) 705 ef->progtab[pb].name = 706 ef->shstrtab + shdr[i].sh_name; 707 else if (shdr[i].sh_type == SHT_PROGBITS) 708 ef->progtab[pb].name = "<<PROGBITS>>"; 709 else 710 ef->progtab[pb].name = "<<NOBITS>>"; 711 #if 0 712 if (ef->progtab[pb].name != NULL && 713 !strcmp(ef->progtab[pb].name, "set_pcpu")) 714 ef->progtab[pb].addr = 715 dpcpu_alloc(shdr[i].sh_size); 716 #ifdef VIMAGE 717 else if (ef->progtab[pb].name != NULL && 718 !strcmp(ef->progtab[pb].name, VNET_SETNAME)) 719 ef->progtab[pb].addr = 720 vnet_data_alloc(shdr[i].sh_size); 721 #endif 722 else 723 #endif 724 ef->progtab[pb].addr = 725 (void *)(uintptr_t) mapbase; 726 if (ef->progtab[pb].addr == NULL) { 727 error = ENOSPC; 728 goto out; 729 } 730 ef->progtab[pb].size = shdr[i].sh_size; 731 ef->progtab[pb].sec = i; 732 if (shdr[i].sh_type == SHT_PROGBITS) { 733 error = vn_rdwr(UIO_READ, vp, 734 ef->progtab[pb].addr, 735 shdr[i].sh_size, shdr[i].sh_offset, 736 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, 737 &resid); 738 if (error) 739 goto out; 740 if (resid != 0) { 741 error = EINVAL; 742 goto out; 743 } 744 #if 0 745 /* Initialize the per-cpu or vnet area. */ 746 if (ef->progtab[pb].addr != (void *)mapbase && 747 !strcmp(ef->progtab[pb].name, "set_pcpu")) 748 dpcpu_copy(ef->progtab[pb].addr, 749 shdr[i].sh_size); 750 #ifdef VIMAGE 751 else if (ef->progtab[pb].addr != 752 (void *)mapbase && 753 !strcmp(ef->progtab[pb].name, VNET_SETNAME)) 754 vnet_data_copy(ef->progtab[pb].addr, 755 shdr[i].sh_size); 756 #endif 757 #endif 758 } else 759 bzero(ef->progtab[pb].addr, shdr[i].sh_size); 760 761 /* Update all symbol values with the offset. */ 762 for (j = 0; j < ef->ddbsymcnt; j++) { 763 es = &ef->ddbsymtab[j]; 764 if (es->st_shndx != i) 765 continue; 766 es->st_value += (Elf_Addr) ef->progtab[pb].addr; 767 } 768 mapbase += shdr[i].sh_size; 769 pb++; 770 break; 771 case SHT_REL: 772 ef->reltab[rl].rel = kmalloc(shdr[i].sh_size, M_LINKER, M_WAITOK); 773 ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel); 774 ef->reltab[rl].sec = shdr[i].sh_info; 775 error = vn_rdwr(UIO_READ, vp, 776 (void *)ef->reltab[rl].rel, 777 shdr[i].sh_size, shdr[i].sh_offset, 778 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 779 if (error) 780 goto out; 781 if (resid != 0) { 782 error = EINVAL; 783 goto out; 784 } 785 rl++; 786 break; 787 case SHT_RELA: 788 ef->relatab[ra].rela = kmalloc(shdr[i].sh_size, M_LINKER, M_WAITOK); 789 ef->relatab[ra].nrela = shdr[i].sh_size / sizeof(Elf_Rela); 790 ef->relatab[ra].sec = shdr[i].sh_info; 791 error = vn_rdwr(UIO_READ, vp, 792 (void *)ef->relatab[ra].rela, 793 shdr[i].sh_size, shdr[i].sh_offset, 794 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid); 795 if (error) 796 goto out; 797 if (resid != 0) { 798 error = EINVAL; 799 goto out; 800 } 801 ra++; 802 break; 803 } 804 } 805 if (pb != ef->nprogtab) 806 panic("lost progbits"); 807 if (rl != ef->nreltab) 808 panic("lost reltab"); 809 if (ra != ef->nrelatab) 810 panic("lost relatab"); 811 if (mapbase != (vm_offset_t) ef->address + mapsize) 812 panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n", 813 mapbase, ef->address, mapsize, 814 (vm_offset_t) ef->address + mapsize); 815 816 /* Local intra-module relocations */ 817 link_elf_obj_reloc_local(lf); 818 819 /* Pull in dependencies */ 820 error = linker_load_dependencies(lf); 821 if (error) 822 goto out; 823 824 /* External relocations */ 825 error = relocate_file(lf); 826 if (error) 827 goto out; 828 829 *result = lf; 830 831 out: 832 if (error && lf) 833 linker_file_unload(lf /*, LINKER_UNLOAD_FORCE */); 834 if (hdr) 835 kfree(hdr, M_LINKER); 836 vn_unlock(vp); 837 vn_close(vp, FREAD); 838 839 return error; 840 } 841 842 static void 843 link_elf_obj_unload_file(linker_file_t file) 844 { 845 elf_file_t ef = file->priv; 846 int i; 847 848 if (ef->progtab) { 849 for (i = 0; i < ef->nprogtab; i++) { 850 if (ef->progtab[i].size == 0) 851 continue; 852 if (ef->progtab[i].name == NULL) 853 continue; 854 #if 0 855 if (!strcmp(ef->progtab[i].name, "set_pcpu")) 856 dpcpu_free(ef->progtab[i].addr, 857 ef->progtab[i].size); 858 #ifdef VIMAGE 859 else if (!strcmp(ef->progtab[i].name, VNET_SETNAME)) 860 vnet_data_free(ef->progtab[i].addr, 861 ef->progtab[i].size); 862 #endif 863 #endif 864 } 865 } 866 if (ef->preloaded) { 867 if (ef->reltab) 868 kfree(ef->reltab, M_LINKER); 869 if (ef->relatab) 870 kfree(ef->relatab, M_LINKER); 871 if (ef->progtab) 872 kfree(ef->progtab, M_LINKER); 873 if (ef->ctftab) 874 kfree(ef->ctftab, M_LINKER); 875 if (ef->ctfoff) 876 kfree(ef->ctfoff, M_LINKER); 877 if (ef->typoff) 878 kfree(ef->typoff, M_LINKER); 879 if (file->filename != NULL) 880 preload_delete_name(file->filename); 881 kfree(ef, M_LINKER); 882 /* XXX reclaim module memory? */ 883 return; 884 } 885 886 for (i = 0; i < ef->nreltab; i++) 887 if (ef->reltab[i].rel) 888 kfree(ef->reltab[i].rel, M_LINKER); 889 for (i = 0; i < ef->nrelatab; i++) 890 if (ef->relatab[i].rela) 891 kfree(ef->relatab[i].rela, M_LINKER); 892 if (ef->reltab) 893 kfree(ef->reltab, M_LINKER); 894 if (ef->relatab) 895 kfree(ef->relatab, M_LINKER); 896 if (ef->progtab) 897 kfree(ef->progtab, M_LINKER); 898 899 if (ef->object) { 900 vm_map_remove(&kernel_map, (vm_offset_t) ef->address, 901 (vm_offset_t) ef->address + 902 (ef->object->size << PAGE_SHIFT)); 903 } 904 if (ef->e_shdr) 905 kfree(ef->e_shdr, M_LINKER); 906 if (ef->ddbsymtab) 907 kfree(ef->ddbsymtab, M_LINKER); 908 if (ef->ddbstrtab) 909 kfree(ef->ddbstrtab, M_LINKER); 910 if (ef->shstrtab) 911 kfree(ef->shstrtab, M_LINKER); 912 if (ef->ctftab) 913 kfree(ef->ctftab, M_LINKER); 914 if (ef->ctfoff) 915 kfree(ef->ctfoff, M_LINKER); 916 if (ef->typoff) 917 kfree(ef->typoff, M_LINKER); 918 kfree(ef, M_LINKER); 919 } 920 921 static const char * 922 symbol_name(elf_file_t ef, Elf_Size r_info) 923 { 924 const Elf_Sym *ref; 925 926 if (ELF_R_SYM(r_info)) { 927 ref = ef->ddbsymtab + ELF_R_SYM(r_info); 928 return ef->ddbstrtab + ref->st_name; 929 } else 930 return NULL; 931 } 932 933 static Elf_Addr 934 findbase(elf_file_t ef, int sec) 935 { 936 int i; 937 Elf_Addr base = 0; 938 939 for (i = 0; i < ef->nprogtab; i++) { 940 if (sec == ef->progtab[i].sec) { 941 base = (Elf_Addr)ef->progtab[i].addr; 942 break; 943 } 944 } 945 return base; 946 } 947 948 static int 949 relocate_file(linker_file_t lf) 950 { 951 elf_file_t ef = lf->priv; 952 const Elf_Rel *rellim; 953 const Elf_Rel *rel; 954 const Elf_Rela *relalim; 955 const Elf_Rela *rela; 956 const char *symname; 957 const Elf_Sym *sym; 958 int i; 959 Elf_Size symidx; 960 Elf_Addr base; 961 962 /* Perform relocations without addend if there are any: */ 963 for (i = 0; i < ef->nreltab; i++) { 964 rel = ef->reltab[i].rel; 965 if (rel == NULL) 966 panic("lost a reltab!"); 967 rellim = rel + ef->reltab[i].nrel; 968 base = findbase(ef, ef->reltab[i].sec); 969 if (base == 0) 970 panic("lost base for reltab"); 971 for ( ; rel < rellim; rel++) { 972 symidx = ELF_R_SYM(rel->r_info); 973 if (symidx >= ef->ddbsymcnt) 974 continue; 975 sym = ef->ddbsymtab + symidx; 976 /* Local relocs are already done */ 977 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 978 continue; 979 if (elf_reloc(lf, base, rel, ELF_RELOC_REL, 980 elf_obj_lookup)) { 981 symname = symbol_name(ef, rel->r_info); 982 kprintf("link_elf_obj_obj: symbol %s undefined\n", 983 symname); 984 return ENOENT; 985 } 986 } 987 } 988 989 /* Perform relocations with addend if there are any: */ 990 for (i = 0; i < ef->nrelatab; i++) { 991 rela = ef->relatab[i].rela; 992 if (rela == NULL) 993 panic("lost a relatab!"); 994 relalim = rela + ef->relatab[i].nrela; 995 base = findbase(ef, ef->relatab[i].sec); 996 if (base == 0) 997 panic("lost base for relatab"); 998 for ( ; rela < relalim; rela++) { 999 symidx = ELF_R_SYM(rela->r_info); 1000 if (symidx >= ef->ddbsymcnt) 1001 continue; 1002 sym = ef->ddbsymtab + symidx; 1003 /* Local relocs are already done */ 1004 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 1005 continue; 1006 if (elf_reloc(lf, base, rela, ELF_RELOC_RELA, 1007 elf_obj_lookup)) { 1008 symname = symbol_name(ef, rela->r_info); 1009 kprintf("link_elf_obj_obj: symbol %s undefined\n", 1010 symname); 1011 return ENOENT; 1012 } 1013 } 1014 } 1015 1016 return 0; 1017 } 1018 1019 static int 1020 link_elf_obj_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) 1021 { 1022 elf_file_t ef = lf->priv; 1023 const Elf_Sym *symp; 1024 const char *strp; 1025 int i; 1026 1027 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1028 strp = ef->ddbstrtab + symp->st_name; 1029 if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) { 1030 *sym = (c_linker_sym_t) symp; 1031 return 0; 1032 } 1033 } 1034 return ENOENT; 1035 } 1036 1037 static int 1038 link_elf_obj_symbol_values(linker_file_t lf, c_linker_sym_t sym, 1039 linker_symval_t *symval) 1040 { 1041 elf_file_t ef = lf->priv; 1042 const Elf_Sym *es = (const Elf_Sym*) sym; 1043 1044 if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { 1045 symval->name = ef->ddbstrtab + es->st_name; 1046 symval->value = (caddr_t)es->st_value; 1047 symval->size = es->st_size; 1048 return 0; 1049 } 1050 return ENOENT; 1051 } 1052 1053 static int 1054 link_elf_obj_search_symbol(linker_file_t lf, caddr_t value, 1055 c_linker_sym_t *sym, long *diffp) 1056 { 1057 elf_file_t ef = lf->priv; 1058 u_long off = (uintptr_t) (void *) value; 1059 u_long diff = off; 1060 u_long st_value; 1061 const Elf_Sym *es; 1062 const Elf_Sym *best = 0; 1063 int i; 1064 1065 for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) { 1066 if (es->st_name == 0) 1067 continue; 1068 st_value = es->st_value; 1069 if (off >= st_value) { 1070 if (off - st_value < diff) { 1071 diff = off - st_value; 1072 best = es; 1073 if (diff == 0) 1074 break; 1075 } else if (off - st_value == diff) { 1076 best = es; 1077 } 1078 } 1079 } 1080 if (best == 0) 1081 *diffp = off; 1082 else 1083 *diffp = diff; 1084 *sym = (c_linker_sym_t) best; 1085 1086 return 0; 1087 } 1088 1089 /* 1090 * Look up a linker set on an ELF system. 1091 */ 1092 static int 1093 link_elf_obj_lookup_set(linker_file_t lf, const char *name, 1094 void ***startp, void ***stopp, int *countp) 1095 { 1096 elf_file_t ef = lf->priv; 1097 void **start, **stop; 1098 int i, count; 1099 1100 /* Relative to section number */ 1101 for (i = 0; i < ef->nprogtab; i++) { 1102 if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) && 1103 strcmp(ef->progtab[i].name + 4, name) == 0) { 1104 start = (void **)ef->progtab[i].addr; 1105 stop = (void **)((char *)ef->progtab[i].addr + 1106 ef->progtab[i].size); 1107 count = stop - start; 1108 if (startp) 1109 *startp = start; 1110 if (stopp) 1111 *stopp = stop; 1112 if (countp) 1113 *countp = count; 1114 return (0); 1115 } 1116 } 1117 return (ESRCH); 1118 } 1119 1120 /* 1121 * Symbol lookup function that can be used when the symbol index is known (ie 1122 * in relocations). It uses the symbol index instead of doing a fully fledged 1123 * hash table based lookup when such is valid. For example for local symbols. 1124 * This is not only more efficient, it's also more correct. It's not always 1125 * the case that the symbol can be found through the hash table. 1126 */ 1127 static int 1128 elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *result) 1129 { 1130 elf_file_t ef = lf->priv; 1131 const Elf_Sym *sym; 1132 const char *symbol; 1133 1134 /* Don't even try to lookup the symbol if the index is bogus. */ 1135 if (symidx >= ef->ddbsymcnt) 1136 return (ENOENT); 1137 1138 sym = ef->ddbsymtab + symidx; 1139 1140 /* Quick answer if there is a definition included. */ 1141 if (sym->st_shndx != SHN_UNDEF) { 1142 *result = sym->st_value; 1143 return (0); 1144 } 1145 1146 /* If we get here, then it is undefined and needs a lookup. */ 1147 switch (ELF_ST_BIND(sym->st_info)) { 1148 case STB_LOCAL: 1149 /* Local, but undefined? huh? */ 1150 return (ENOENT); 1151 1152 case STB_GLOBAL: 1153 /* Relative to Data or Function name */ 1154 symbol = ef->ddbstrtab + sym->st_name; 1155 1156 /* Force a lookup failure if the symbol name is bogus. */ 1157 if (*symbol == 0) 1158 return (ENOENT); 1159 return (linker_file_lookup_symbol(lf, symbol, deps, (caddr_t *)result)); 1160 1161 case STB_WEAK: 1162 kprintf("link_elf_obj_obj: Weak symbols not supported\n"); 1163 return (ENOENT); 1164 1165 default: 1166 return (ENOENT); 1167 } 1168 } 1169 1170 static void 1171 link_elf_obj_fix_link_set(elf_file_t ef) 1172 { 1173 static const char startn[] = "__start_"; 1174 static const char stopn[] = "__stop_"; 1175 Elf_Sym *sym; 1176 const char *sym_name, *linkset_name; 1177 Elf_Addr startp, stopp; 1178 Elf_Size symidx; 1179 int start, i; 1180 1181 startp = stopp = 0; 1182 for (symidx = 1 /* zero entry is special */; 1183 symidx < ef->ddbsymcnt; symidx++) { 1184 sym = ef->ddbsymtab + symidx; 1185 if (sym->st_shndx != SHN_UNDEF) 1186 continue; 1187 1188 sym_name = ef->ddbstrtab + sym->st_name; 1189 if (strncmp(sym_name, startn, sizeof(startn) - 1) == 0) { 1190 start = 1; 1191 linkset_name = sym_name + sizeof(startn) - 1; 1192 } 1193 else if (strncmp(sym_name, stopn, sizeof(stopn) - 1) == 0) { 1194 start = 0; 1195 linkset_name = sym_name + sizeof(stopn) - 1; 1196 } 1197 else 1198 continue; 1199 1200 for (i = 0; i < ef->nprogtab; i++) { 1201 if (strcmp(ef->progtab[i].name, linkset_name) == 0) { 1202 startp = (Elf_Addr)ef->progtab[i].addr; 1203 stopp = (Elf_Addr)(startp + ef->progtab[i].size); 1204 break; 1205 } 1206 } 1207 if (i == ef->nprogtab) 1208 continue; 1209 1210 sym->st_value = start ? startp : stopp; 1211 sym->st_shndx = i; 1212 } 1213 } 1214 1215 static void 1216 link_elf_obj_reloc_local(linker_file_t lf) 1217 { 1218 elf_file_t ef = lf->priv; 1219 const Elf_Rel *rellim; 1220 const Elf_Rel *rel; 1221 const Elf_Rela *relalim; 1222 const Elf_Rela *rela; 1223 const Elf_Sym *sym; 1224 Elf_Addr base; 1225 int i; 1226 Elf_Size symidx; 1227 1228 link_elf_obj_fix_link_set(ef); 1229 1230 /* Perform relocations without addend if there are any: */ 1231 for (i = 0; i < ef->nreltab; i++) { 1232 rel = ef->reltab[i].rel; 1233 if (rel == NULL) 1234 panic("lost a reltab!"); 1235 rellim = rel + ef->reltab[i].nrel; 1236 base = findbase(ef, ef->reltab[i].sec); 1237 if (base == 0) 1238 panic("lost base for reltab"); 1239 for ( ; rel < rellim; rel++) { 1240 symidx = ELF_R_SYM(rel->r_info); 1241 if (symidx >= ef->ddbsymcnt) 1242 continue; 1243 sym = ef->ddbsymtab + symidx; 1244 /* Only do local relocs */ 1245 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) 1246 continue; 1247 elf_reloc_local(lf, base, rel, ELF_RELOC_REL, 1248 elf_obj_lookup); 1249 } 1250 } 1251 1252 /* Perform relocations with addend if there are any: */ 1253 for (i = 0; i < ef->nrelatab; i++) { 1254 rela = ef->relatab[i].rela; 1255 if (rela == NULL) 1256 panic("lost a relatab!"); 1257 relalim = rela + ef->relatab[i].nrela; 1258 base = findbase(ef, ef->relatab[i].sec); 1259 if (base == 0) 1260 panic("lost base for relatab"); 1261 for ( ; rela < relalim; rela++) { 1262 symidx = ELF_R_SYM(rela->r_info); 1263 if (symidx >= ef->ddbsymcnt) 1264 continue; 1265 sym = ef->ddbsymtab + symidx; 1266 /* Only do local relocs */ 1267 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) 1268 continue; 1269 elf_reloc_local(lf, base, rela, ELF_RELOC_RELA, 1270 elf_obj_lookup); 1271 } 1272 } 1273 } 1274