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