1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 1998-2000 Doug Rabson 5 * Copyright (c) 2004 Peter Wemm 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include "opt_ddb.h" 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/lock.h> 39 #include <sys/malloc.h> 40 #include <sys/mutex.h> 41 #include <sys/mount.h> 42 #include <sys/proc.h> 43 #include <sys/namei.h> 44 #include <sys/fcntl.h> 45 #include <sys/vnode.h> 46 #include <sys/linker.h> 47 48 #include <machine/elf.h> 49 50 #include <net/vnet.h> 51 52 #include <security/mac/mac_framework.h> 53 54 #include <vm/vm.h> 55 #include <vm/vm_param.h> 56 #include <vm/vm_object.h> 57 #include <vm/vm_kern.h> 58 #include <vm/vm_extern.h> 59 #include <vm/pmap.h> 60 #include <vm/vm_map.h> 61 62 #include <sys/link_elf.h> 63 64 #ifdef DDB_CTF 65 #include <sys/zlib.h> 66 #endif 67 68 #include "linker_if.h" 69 70 typedef struct { 71 void *addr; 72 Elf_Off size; 73 int flags; 74 int sec; /* Original section */ 75 char *name; 76 } Elf_progent; 77 78 typedef struct { 79 Elf_Rel *rel; 80 int nrel; 81 int sec; 82 } Elf_relent; 83 84 typedef struct { 85 Elf_Rela *rela; 86 int nrela; 87 int sec; 88 } Elf_relaent; 89 90 91 typedef struct elf_file { 92 struct linker_file lf; /* Common fields */ 93 94 int preloaded; 95 caddr_t address; /* Relocation address */ 96 vm_object_t object; /* VM object to hold file pages */ 97 Elf_Shdr *e_shdr; 98 99 Elf_progent *progtab; 100 u_int nprogtab; 101 102 Elf_relaent *relatab; 103 u_int nrelatab; 104 105 Elf_relent *reltab; 106 int nreltab; 107 108 Elf_Sym *ddbsymtab; /* The symbol table we are using */ 109 long ddbsymcnt; /* Number of symbols */ 110 caddr_t ddbstrtab; /* String table */ 111 long ddbstrcnt; /* number of bytes in string table */ 112 113 caddr_t shstrtab; /* Section name string table */ 114 long shstrcnt; /* number of bytes in string table */ 115 116 caddr_t ctftab; /* CTF table */ 117 long ctfcnt; /* number of bytes in CTF table */ 118 caddr_t ctfoff; /* CTF offset table */ 119 caddr_t typoff; /* Type offset table */ 120 long typlen; /* Number of type entries. */ 121 122 } *elf_file_t; 123 124 #include <kern/kern_ctf.c> 125 126 static int link_elf_link_preload(linker_class_t cls, 127 const char *, linker_file_t *); 128 static int link_elf_link_preload_finish(linker_file_t); 129 static int link_elf_load_file(linker_class_t, const char *, linker_file_t *); 130 static int link_elf_lookup_symbol(linker_file_t, const char *, 131 c_linker_sym_t *); 132 static int link_elf_symbol_values(linker_file_t, c_linker_sym_t, 133 linker_symval_t *); 134 static int link_elf_search_symbol(linker_file_t, caddr_t value, 135 c_linker_sym_t *sym, long *diffp); 136 137 static void link_elf_unload_file(linker_file_t); 138 static int link_elf_lookup_set(linker_file_t, const char *, 139 void ***, void ***, int *); 140 static int link_elf_each_function_name(linker_file_t, 141 int (*)(const char *, void *), void *); 142 static int link_elf_each_function_nameval(linker_file_t, 143 linker_function_nameval_callback_t, 144 void *); 145 static int link_elf_reloc_local(linker_file_t); 146 static long link_elf_symtab_get(linker_file_t, const Elf_Sym **); 147 static long link_elf_strtab_get(linker_file_t, caddr_t *); 148 149 static int elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps, 150 Elf_Addr *); 151 152 static kobj_method_t link_elf_methods[] = { 153 KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol), 154 KOBJMETHOD(linker_symbol_values, link_elf_symbol_values), 155 KOBJMETHOD(linker_search_symbol, link_elf_search_symbol), 156 KOBJMETHOD(linker_unload, link_elf_unload_file), 157 KOBJMETHOD(linker_load_file, link_elf_load_file), 158 KOBJMETHOD(linker_link_preload, link_elf_link_preload), 159 KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish), 160 KOBJMETHOD(linker_lookup_set, link_elf_lookup_set), 161 KOBJMETHOD(linker_each_function_name, link_elf_each_function_name), 162 KOBJMETHOD(linker_each_function_nameval, link_elf_each_function_nameval), 163 KOBJMETHOD(linker_ctf_get, link_elf_ctf_get), 164 KOBJMETHOD(linker_symtab_get, link_elf_symtab_get), 165 KOBJMETHOD(linker_strtab_get, link_elf_strtab_get), 166 { 0, 0 } 167 }; 168 169 static struct linker_class link_elf_class = { 170 #if ELF_TARG_CLASS == ELFCLASS32 171 "elf32_obj", 172 #else 173 "elf64_obj", 174 #endif 175 link_elf_methods, sizeof(struct elf_file) 176 }; 177 178 static int relocate_file(elf_file_t ef); 179 static void elf_obj_cleanup_globals_cache(elf_file_t); 180 181 static void 182 link_elf_error(const char *filename, const char *s) 183 { 184 if (filename == NULL) 185 printf("kldload: %s\n", s); 186 else 187 printf("kldload: %s: %s\n", filename, s); 188 } 189 190 static void 191 link_elf_init(void *arg) 192 { 193 194 linker_add_class(&link_elf_class); 195 } 196 197 SYSINIT(link_elf_obj, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0); 198 199 static int 200 link_elf_link_preload(linker_class_t cls, const char *filename, 201 linker_file_t *result) 202 { 203 Elf_Ehdr *hdr; 204 Elf_Shdr *shdr; 205 Elf_Sym *es; 206 void *modptr, *baseptr, *sizeptr; 207 char *type; 208 elf_file_t ef; 209 linker_file_t lf; 210 Elf_Addr off; 211 int error, i, j, pb, ra, rl, shstrindex, symstrindex, symtabindex; 212 213 /* Look to see if we have the file preloaded */ 214 modptr = preload_search_by_name(filename); 215 if (modptr == NULL) 216 return ENOENT; 217 218 type = (char *)preload_search_info(modptr, MODINFO_TYPE); 219 baseptr = preload_search_info(modptr, MODINFO_ADDR); 220 sizeptr = preload_search_info(modptr, MODINFO_SIZE); 221 hdr = (Elf_Ehdr *)preload_search_info(modptr, MODINFO_METADATA | 222 MODINFOMD_ELFHDR); 223 shdr = (Elf_Shdr *)preload_search_info(modptr, MODINFO_METADATA | 224 MODINFOMD_SHDR); 225 if (type == NULL || (strcmp(type, "elf" __XSTRING(__ELF_WORD_SIZE) 226 " obj module") != 0 && 227 strcmp(type, "elf obj module") != 0)) { 228 return (EFTYPE); 229 } 230 if (baseptr == NULL || sizeptr == NULL || hdr == NULL || 231 shdr == NULL) 232 return (EINVAL); 233 234 lf = linker_make_file(filename, &link_elf_class); 235 if (lf == NULL) 236 return (ENOMEM); 237 238 ef = (elf_file_t)lf; 239 ef->preloaded = 1; 240 ef->address = *(caddr_t *)baseptr; 241 lf->address = *(caddr_t *)baseptr; 242 lf->size = *(size_t *)sizeptr; 243 244 if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || 245 hdr->e_ident[EI_DATA] != ELF_TARG_DATA || 246 hdr->e_ident[EI_VERSION] != EV_CURRENT || 247 hdr->e_version != EV_CURRENT || 248 hdr->e_type != ET_REL || 249 hdr->e_machine != ELF_TARG_MACH) { 250 error = EFTYPE; 251 goto out; 252 } 253 ef->e_shdr = shdr; 254 255 /* Scan the section header for information and table sizing. */ 256 symtabindex = -1; 257 symstrindex = -1; 258 for (i = 0; i < hdr->e_shnum; i++) { 259 switch (shdr[i].sh_type) { 260 case SHT_PROGBITS: 261 case SHT_NOBITS: 262 #ifdef __amd64__ 263 case SHT_X86_64_UNWIND: 264 #endif 265 /* Ignore sections not loaded by the loader. */ 266 if (shdr[i].sh_addr == 0) 267 break; 268 ef->nprogtab++; 269 break; 270 case SHT_SYMTAB: 271 symtabindex = i; 272 symstrindex = shdr[i].sh_link; 273 break; 274 case SHT_REL: 275 /* 276 * Ignore relocation tables for sections not 277 * loaded by the loader. 278 */ 279 if (shdr[shdr[i].sh_info].sh_addr == 0) 280 break; 281 ef->nreltab++; 282 break; 283 case SHT_RELA: 284 if (shdr[shdr[i].sh_info].sh_addr == 0) 285 break; 286 ef->nrelatab++; 287 break; 288 } 289 } 290 291 shstrindex = hdr->e_shstrndx; 292 if (ef->nprogtab == 0 || symstrindex < 0 || 293 symstrindex >= hdr->e_shnum || 294 shdr[symstrindex].sh_type != SHT_STRTAB || shstrindex == 0 || 295 shstrindex >= hdr->e_shnum || 296 shdr[shstrindex].sh_type != SHT_STRTAB) { 297 printf("%s: bad/missing section headers\n", filename); 298 error = ENOEXEC; 299 goto out; 300 } 301 302 /* Allocate space for tracking the load chunks */ 303 if (ef->nprogtab != 0) 304 ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab), 305 M_LINKER, M_WAITOK | M_ZERO); 306 if (ef->nreltab != 0) 307 ef->reltab = malloc(ef->nreltab * sizeof(*ef->reltab), 308 M_LINKER, M_WAITOK | M_ZERO); 309 if (ef->nrelatab != 0) 310 ef->relatab = malloc(ef->nrelatab * sizeof(*ef->relatab), 311 M_LINKER, M_WAITOK | M_ZERO); 312 if ((ef->nprogtab != 0 && ef->progtab == NULL) || 313 (ef->nreltab != 0 && ef->reltab == NULL) || 314 (ef->nrelatab != 0 && ef->relatab == NULL)) { 315 error = ENOMEM; 316 goto out; 317 } 318 319 /* XXX, relocate the sh_addr fields saved by the loader. */ 320 off = 0; 321 for (i = 0; i < hdr->e_shnum; i++) { 322 if (shdr[i].sh_addr != 0 && (off == 0 || shdr[i].sh_addr < off)) 323 off = shdr[i].sh_addr; 324 } 325 for (i = 0; i < hdr->e_shnum; i++) { 326 if (shdr[i].sh_addr != 0) 327 shdr[i].sh_addr = shdr[i].sh_addr - off + 328 (Elf_Addr)ef->address; 329 } 330 331 ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym); 332 ef->ddbsymtab = (Elf_Sym *)shdr[symtabindex].sh_addr; 333 ef->ddbstrcnt = shdr[symstrindex].sh_size; 334 ef->ddbstrtab = (char *)shdr[symstrindex].sh_addr; 335 ef->shstrcnt = shdr[shstrindex].sh_size; 336 ef->shstrtab = (char *)shdr[shstrindex].sh_addr; 337 338 /* Now fill out progtab and the relocation tables. */ 339 pb = 0; 340 rl = 0; 341 ra = 0; 342 for (i = 0; i < hdr->e_shnum; i++) { 343 switch (shdr[i].sh_type) { 344 case SHT_PROGBITS: 345 case SHT_NOBITS: 346 #ifdef __amd64__ 347 case SHT_X86_64_UNWIND: 348 #endif 349 if (shdr[i].sh_addr == 0) 350 break; 351 ef->progtab[pb].addr = (void *)shdr[i].sh_addr; 352 if (shdr[i].sh_type == SHT_PROGBITS) 353 ef->progtab[pb].name = "<<PROGBITS>>"; 354 #ifdef __amd64__ 355 else if (shdr[i].sh_type == SHT_X86_64_UNWIND) 356 ef->progtab[pb].name = "<<UNWIND>>"; 357 #endif 358 else 359 ef->progtab[pb].name = "<<NOBITS>>"; 360 ef->progtab[pb].size = shdr[i].sh_size; 361 ef->progtab[pb].sec = i; 362 if (ef->shstrtab && shdr[i].sh_name != 0) 363 ef->progtab[pb].name = 364 ef->shstrtab + shdr[i].sh_name; 365 if (ef->progtab[pb].name != NULL && 366 !strcmp(ef->progtab[pb].name, DPCPU_SETNAME)) { 367 void *dpcpu; 368 369 dpcpu = dpcpu_alloc(shdr[i].sh_size); 370 if (dpcpu == NULL) { 371 error = ENOSPC; 372 goto out; 373 } 374 memcpy(dpcpu, ef->progtab[pb].addr, 375 ef->progtab[pb].size); 376 dpcpu_copy(dpcpu, shdr[i].sh_size); 377 ef->progtab[pb].addr = dpcpu; 378 #ifdef VIMAGE 379 } else if (ef->progtab[pb].name != NULL && 380 !strcmp(ef->progtab[pb].name, VNET_SETNAME)) { 381 void *vnet_data; 382 383 vnet_data = vnet_data_alloc(shdr[i].sh_size); 384 if (vnet_data == NULL) { 385 error = ENOSPC; 386 goto out; 387 } 388 memcpy(vnet_data, ef->progtab[pb].addr, 389 ef->progtab[pb].size); 390 vnet_data_copy(vnet_data, shdr[i].sh_size); 391 ef->progtab[pb].addr = vnet_data; 392 #endif 393 } else if (ef->progtab[pb].name != NULL && 394 !strcmp(ef->progtab[pb].name, ".ctors")) { 395 lf->ctors_addr = ef->progtab[pb].addr; 396 lf->ctors_size = shdr[i].sh_size; 397 } 398 399 /* Update all symbol values with the offset. */ 400 for (j = 0; j < ef->ddbsymcnt; j++) { 401 es = &ef->ddbsymtab[j]; 402 if (es->st_shndx != i) 403 continue; 404 es->st_value += (Elf_Addr)ef->progtab[pb].addr; 405 } 406 pb++; 407 break; 408 case SHT_REL: 409 if (shdr[shdr[i].sh_info].sh_addr == 0) 410 break; 411 ef->reltab[rl].rel = (Elf_Rel *)shdr[i].sh_addr; 412 ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel); 413 ef->reltab[rl].sec = shdr[i].sh_info; 414 rl++; 415 break; 416 case SHT_RELA: 417 if (shdr[shdr[i].sh_info].sh_addr == 0) 418 break; 419 ef->relatab[ra].rela = (Elf_Rela *)shdr[i].sh_addr; 420 ef->relatab[ra].nrela = 421 shdr[i].sh_size / sizeof(Elf_Rela); 422 ef->relatab[ra].sec = shdr[i].sh_info; 423 ra++; 424 break; 425 } 426 } 427 if (pb != ef->nprogtab) { 428 printf("%s: lost progbits\n", filename); 429 error = ENOEXEC; 430 goto out; 431 } 432 if (rl != ef->nreltab) { 433 printf("%s: lost reltab\n", filename); 434 error = ENOEXEC; 435 goto out; 436 } 437 if (ra != ef->nrelatab) { 438 printf("%s: lost relatab\n", filename); 439 error = ENOEXEC; 440 goto out; 441 } 442 443 /* Local intra-module relocations */ 444 error = link_elf_reloc_local(lf); 445 if (error != 0) 446 goto out; 447 448 *result = lf; 449 return (0); 450 451 out: 452 /* preload not done this way */ 453 linker_file_unload(lf, LINKER_UNLOAD_FORCE); 454 return (error); 455 } 456 457 static void 458 link_elf_invoke_ctors(caddr_t addr, size_t size) 459 { 460 void (**ctor)(void); 461 size_t i, cnt; 462 463 if (addr == NULL || size == 0) 464 return; 465 cnt = size / sizeof(*ctor); 466 ctor = (void *)addr; 467 for (i = 0; i < cnt; i++) { 468 if (ctor[i] != NULL) 469 (*ctor[i])(); 470 } 471 } 472 473 static int 474 link_elf_link_preload_finish(linker_file_t lf) 475 { 476 elf_file_t ef; 477 int error; 478 479 ef = (elf_file_t)lf; 480 error = relocate_file(ef); 481 if (error) 482 return error; 483 484 /* Notify MD code that a module is being loaded. */ 485 error = elf_cpu_load_file(lf); 486 if (error) 487 return (error); 488 489 /* Invoke .ctors */ 490 link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size); 491 return (0); 492 } 493 494 static int 495 link_elf_load_file(linker_class_t cls, const char *filename, 496 linker_file_t *result) 497 { 498 struct nameidata *nd; 499 struct thread *td = curthread; /* XXX */ 500 Elf_Ehdr *hdr; 501 Elf_Shdr *shdr; 502 Elf_Sym *es; 503 int nbytes, i, j; 504 vm_offset_t mapbase; 505 size_t mapsize; 506 int error = 0; 507 ssize_t resid; 508 int flags; 509 elf_file_t ef; 510 linker_file_t lf; 511 int symtabindex; 512 int symstrindex; 513 int shstrindex; 514 int nsym; 515 int pb, rl, ra; 516 int alignmask; 517 518 shdr = NULL; 519 lf = NULL; 520 mapsize = 0; 521 hdr = NULL; 522 523 nd = malloc(sizeof(struct nameidata), M_TEMP, M_WAITOK); 524 NDINIT(nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td); 525 flags = FREAD; 526 error = vn_open(nd, &flags, 0, NULL); 527 if (error) { 528 free(nd, M_TEMP); 529 return error; 530 } 531 NDFREE(nd, NDF_ONLY_PNBUF); 532 if (nd->ni_vp->v_type != VREG) { 533 error = ENOEXEC; 534 goto out; 535 } 536 #ifdef MAC 537 error = mac_kld_check_load(td->td_ucred, nd->ni_vp); 538 if (error) { 539 goto out; 540 } 541 #endif 542 543 /* Read the elf header from the file. */ 544 hdr = malloc(sizeof(*hdr), M_LINKER, M_WAITOK); 545 error = vn_rdwr(UIO_READ, nd->ni_vp, (void *)hdr, sizeof(*hdr), 0, 546 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 547 &resid, td); 548 if (error) 549 goto out; 550 if (resid != 0){ 551 error = ENOEXEC; 552 goto out; 553 } 554 555 if (!IS_ELF(*hdr)) { 556 error = ENOEXEC; 557 goto out; 558 } 559 560 if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS 561 || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) { 562 link_elf_error(filename, "Unsupported file layout"); 563 error = ENOEXEC; 564 goto out; 565 } 566 if (hdr->e_ident[EI_VERSION] != EV_CURRENT 567 || hdr->e_version != EV_CURRENT) { 568 link_elf_error(filename, "Unsupported file version"); 569 error = ENOEXEC; 570 goto out; 571 } 572 if (hdr->e_type != ET_REL) { 573 error = ENOSYS; 574 goto out; 575 } 576 if (hdr->e_machine != ELF_TARG_MACH) { 577 link_elf_error(filename, "Unsupported machine"); 578 error = ENOEXEC; 579 goto out; 580 } 581 582 lf = linker_make_file(filename, &link_elf_class); 583 if (!lf) { 584 error = ENOMEM; 585 goto out; 586 } 587 ef = (elf_file_t) lf; 588 ef->nprogtab = 0; 589 ef->e_shdr = 0; 590 ef->nreltab = 0; 591 ef->nrelatab = 0; 592 593 /* Allocate and read in the section header */ 594 nbytes = hdr->e_shnum * hdr->e_shentsize; 595 if (nbytes == 0 || hdr->e_shoff == 0 || 596 hdr->e_shentsize != sizeof(Elf_Shdr)) { 597 error = ENOEXEC; 598 goto out; 599 } 600 shdr = malloc(nbytes, M_LINKER, M_WAITOK); 601 ef->e_shdr = shdr; 602 error = vn_rdwr(UIO_READ, nd->ni_vp, (caddr_t)shdr, nbytes, 603 hdr->e_shoff, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, 604 NOCRED, &resid, td); 605 if (error) 606 goto out; 607 if (resid) { 608 error = ENOEXEC; 609 goto out; 610 } 611 612 /* Scan the section header for information and table sizing. */ 613 nsym = 0; 614 symtabindex = -1; 615 symstrindex = -1; 616 for (i = 0; i < hdr->e_shnum; i++) { 617 if (shdr[i].sh_size == 0) 618 continue; 619 switch (shdr[i].sh_type) { 620 case SHT_PROGBITS: 621 case SHT_NOBITS: 622 #ifdef __amd64__ 623 case SHT_X86_64_UNWIND: 624 #endif 625 if ((shdr[i].sh_flags & SHF_ALLOC) == 0) 626 break; 627 ef->nprogtab++; 628 break; 629 case SHT_SYMTAB: 630 nsym++; 631 symtabindex = i; 632 symstrindex = shdr[i].sh_link; 633 break; 634 case SHT_REL: 635 /* 636 * Ignore relocation tables for unallocated 637 * sections. 638 */ 639 if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0) 640 break; 641 ef->nreltab++; 642 break; 643 case SHT_RELA: 644 if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0) 645 break; 646 ef->nrelatab++; 647 break; 648 case SHT_STRTAB: 649 break; 650 } 651 } 652 if (ef->nprogtab == 0) { 653 link_elf_error(filename, "file has no contents"); 654 error = ENOEXEC; 655 goto out; 656 } 657 if (nsym != 1) { 658 /* Only allow one symbol table for now */ 659 link_elf_error(filename, "file has no valid symbol table"); 660 error = ENOEXEC; 661 goto out; 662 } 663 if (symstrindex < 0 || symstrindex > hdr->e_shnum || 664 shdr[symstrindex].sh_type != SHT_STRTAB) { 665 link_elf_error(filename, "file has invalid symbol strings"); 666 error = ENOEXEC; 667 goto out; 668 } 669 670 /* Allocate space for tracking the load chunks */ 671 if (ef->nprogtab != 0) 672 ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab), 673 M_LINKER, M_WAITOK | M_ZERO); 674 if (ef->nreltab != 0) 675 ef->reltab = malloc(ef->nreltab * sizeof(*ef->reltab), 676 M_LINKER, M_WAITOK | M_ZERO); 677 if (ef->nrelatab != 0) 678 ef->relatab = malloc(ef->nrelatab * sizeof(*ef->relatab), 679 M_LINKER, M_WAITOK | M_ZERO); 680 681 if (symtabindex == -1) { 682 link_elf_error(filename, "lost symbol table index"); 683 error = ENOEXEC; 684 goto out; 685 } 686 /* Allocate space for and load the symbol table */ 687 ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym); 688 ef->ddbsymtab = malloc(shdr[symtabindex].sh_size, M_LINKER, M_WAITOK); 689 error = vn_rdwr(UIO_READ, nd->ni_vp, (void *)ef->ddbsymtab, 690 shdr[symtabindex].sh_size, shdr[symtabindex].sh_offset, 691 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 692 &resid, td); 693 if (error) 694 goto out; 695 if (resid != 0){ 696 error = EINVAL; 697 goto out; 698 } 699 700 if (symstrindex == -1) { 701 link_elf_error(filename, "lost symbol string index"); 702 error = ENOEXEC; 703 goto out; 704 } 705 /* Allocate space for and load the symbol strings */ 706 ef->ddbstrcnt = shdr[symstrindex].sh_size; 707 ef->ddbstrtab = malloc(shdr[symstrindex].sh_size, M_LINKER, M_WAITOK); 708 error = vn_rdwr(UIO_READ, nd->ni_vp, ef->ddbstrtab, 709 shdr[symstrindex].sh_size, shdr[symstrindex].sh_offset, 710 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 711 &resid, td); 712 if (error) 713 goto out; 714 if (resid != 0){ 715 error = EINVAL; 716 goto out; 717 } 718 719 /* Do we have a string table for the section names? */ 720 shstrindex = -1; 721 if (hdr->e_shstrndx != 0 && 722 shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) { 723 shstrindex = hdr->e_shstrndx; 724 ef->shstrcnt = shdr[shstrindex].sh_size; 725 ef->shstrtab = malloc(shdr[shstrindex].sh_size, M_LINKER, 726 M_WAITOK); 727 error = vn_rdwr(UIO_READ, nd->ni_vp, ef->shstrtab, 728 shdr[shstrindex].sh_size, shdr[shstrindex].sh_offset, 729 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 730 &resid, td); 731 if (error) 732 goto out; 733 if (resid != 0){ 734 error = EINVAL; 735 goto out; 736 } 737 } 738 739 /* Size up code/data(progbits) and bss(nobits). */ 740 alignmask = 0; 741 for (i = 0; i < hdr->e_shnum; i++) { 742 if (shdr[i].sh_size == 0) 743 continue; 744 switch (shdr[i].sh_type) { 745 case SHT_PROGBITS: 746 case SHT_NOBITS: 747 #ifdef __amd64__ 748 case SHT_X86_64_UNWIND: 749 #endif 750 if ((shdr[i].sh_flags & SHF_ALLOC) == 0) 751 break; 752 alignmask = shdr[i].sh_addralign - 1; 753 mapsize += alignmask; 754 mapsize &= ~alignmask; 755 mapsize += shdr[i].sh_size; 756 break; 757 } 758 } 759 760 /* 761 * We know how much space we need for the text/data/bss/etc. 762 * This stuff needs to be in a single chunk so that profiling etc 763 * can get the bounds and gdb can associate offsets with modules 764 */ 765 ef->object = vm_object_allocate(OBJT_DEFAULT, 766 round_page(mapsize) >> PAGE_SHIFT); 767 if (ef->object == NULL) { 768 error = ENOMEM; 769 goto out; 770 } 771 ef->address = (caddr_t) vm_map_min(kernel_map); 772 773 /* 774 * In order to satisfy amd64's architectural requirements on the 775 * location of code and data in the kernel's address space, request a 776 * mapping that is above the kernel. 777 */ 778 #ifdef __amd64__ 779 mapbase = KERNBASE; 780 #else 781 mapbase = VM_MIN_KERNEL_ADDRESS; 782 #endif 783 error = vm_map_find(kernel_map, ef->object, 0, &mapbase, 784 round_page(mapsize), 0, VMFS_OPTIMAL_SPACE, VM_PROT_ALL, 785 VM_PROT_ALL, 0); 786 if (error) { 787 vm_object_deallocate(ef->object); 788 ef->object = 0; 789 goto out; 790 } 791 792 /* Wire the pages */ 793 error = vm_map_wire(kernel_map, mapbase, 794 mapbase + round_page(mapsize), 795 VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES); 796 if (error != KERN_SUCCESS) { 797 error = ENOMEM; 798 goto out; 799 } 800 801 /* Inform the kld system about the situation */ 802 lf->address = ef->address = (caddr_t)mapbase; 803 lf->size = mapsize; 804 805 /* 806 * Now load code/data(progbits), zero bss(nobits), allocate space for 807 * and load relocs 808 */ 809 pb = 0; 810 rl = 0; 811 ra = 0; 812 alignmask = 0; 813 for (i = 0; i < hdr->e_shnum; i++) { 814 if (shdr[i].sh_size == 0) 815 continue; 816 switch (shdr[i].sh_type) { 817 case SHT_PROGBITS: 818 case SHT_NOBITS: 819 #ifdef __amd64__ 820 case SHT_X86_64_UNWIND: 821 #endif 822 if ((shdr[i].sh_flags & SHF_ALLOC) == 0) 823 break; 824 alignmask = shdr[i].sh_addralign - 1; 825 mapbase += alignmask; 826 mapbase &= ~alignmask; 827 if (ef->shstrtab != NULL && shdr[i].sh_name != 0) { 828 ef->progtab[pb].name = 829 ef->shstrtab + shdr[i].sh_name; 830 if (!strcmp(ef->progtab[pb].name, ".ctors")) { 831 lf->ctors_addr = (caddr_t)mapbase; 832 lf->ctors_size = shdr[i].sh_size; 833 } 834 } else if (shdr[i].sh_type == SHT_PROGBITS) 835 ef->progtab[pb].name = "<<PROGBITS>>"; 836 #ifdef __amd64__ 837 else if (shdr[i].sh_type == SHT_X86_64_UNWIND) 838 ef->progtab[pb].name = "<<UNWIND>>"; 839 #endif 840 else 841 ef->progtab[pb].name = "<<NOBITS>>"; 842 if (ef->progtab[pb].name != NULL && 843 !strcmp(ef->progtab[pb].name, DPCPU_SETNAME)) 844 ef->progtab[pb].addr = 845 dpcpu_alloc(shdr[i].sh_size); 846 #ifdef VIMAGE 847 else if (ef->progtab[pb].name != NULL && 848 !strcmp(ef->progtab[pb].name, VNET_SETNAME)) 849 ef->progtab[pb].addr = 850 vnet_data_alloc(shdr[i].sh_size); 851 #endif 852 else 853 ef->progtab[pb].addr = 854 (void *)(uintptr_t)mapbase; 855 if (ef->progtab[pb].addr == NULL) { 856 error = ENOSPC; 857 goto out; 858 } 859 ef->progtab[pb].size = shdr[i].sh_size; 860 ef->progtab[pb].sec = i; 861 if (shdr[i].sh_type == SHT_PROGBITS 862 #ifdef __amd64__ 863 || shdr[i].sh_type == SHT_X86_64_UNWIND 864 #endif 865 ) { 866 error = vn_rdwr(UIO_READ, nd->ni_vp, 867 ef->progtab[pb].addr, 868 shdr[i].sh_size, shdr[i].sh_offset, 869 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, 870 NOCRED, &resid, td); 871 if (error) 872 goto out; 873 if (resid != 0){ 874 error = EINVAL; 875 goto out; 876 } 877 /* Initialize the per-cpu or vnet area. */ 878 if (ef->progtab[pb].addr != (void *)mapbase && 879 !strcmp(ef->progtab[pb].name, DPCPU_SETNAME)) 880 dpcpu_copy(ef->progtab[pb].addr, 881 shdr[i].sh_size); 882 #ifdef VIMAGE 883 else if (ef->progtab[pb].addr != 884 (void *)mapbase && 885 !strcmp(ef->progtab[pb].name, VNET_SETNAME)) 886 vnet_data_copy(ef->progtab[pb].addr, 887 shdr[i].sh_size); 888 #endif 889 } else 890 bzero(ef->progtab[pb].addr, shdr[i].sh_size); 891 892 /* Update all symbol values with the offset. */ 893 for (j = 0; j < ef->ddbsymcnt; j++) { 894 es = &ef->ddbsymtab[j]; 895 if (es->st_shndx != i) 896 continue; 897 es->st_value += (Elf_Addr)ef->progtab[pb].addr; 898 } 899 mapbase += shdr[i].sh_size; 900 pb++; 901 break; 902 case SHT_REL: 903 if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0) 904 break; 905 ef->reltab[rl].rel = malloc(shdr[i].sh_size, M_LINKER, 906 M_WAITOK); 907 ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel); 908 ef->reltab[rl].sec = shdr[i].sh_info; 909 error = vn_rdwr(UIO_READ, nd->ni_vp, 910 (void *)ef->reltab[rl].rel, 911 shdr[i].sh_size, shdr[i].sh_offset, 912 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 913 &resid, td); 914 if (error) 915 goto out; 916 if (resid != 0){ 917 error = EINVAL; 918 goto out; 919 } 920 rl++; 921 break; 922 case SHT_RELA: 923 if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0) 924 break; 925 ef->relatab[ra].rela = malloc(shdr[i].sh_size, M_LINKER, 926 M_WAITOK); 927 ef->relatab[ra].nrela = 928 shdr[i].sh_size / sizeof(Elf_Rela); 929 ef->relatab[ra].sec = shdr[i].sh_info; 930 error = vn_rdwr(UIO_READ, nd->ni_vp, 931 (void *)ef->relatab[ra].rela, 932 shdr[i].sh_size, shdr[i].sh_offset, 933 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 934 &resid, td); 935 if (error) 936 goto out; 937 if (resid != 0){ 938 error = EINVAL; 939 goto out; 940 } 941 ra++; 942 break; 943 } 944 } 945 if (pb != ef->nprogtab) { 946 link_elf_error(filename, "lost progbits"); 947 error = ENOEXEC; 948 goto out; 949 } 950 if (rl != ef->nreltab) { 951 link_elf_error(filename, "lost reltab"); 952 error = ENOEXEC; 953 goto out; 954 } 955 if (ra != ef->nrelatab) { 956 link_elf_error(filename, "lost relatab"); 957 error = ENOEXEC; 958 goto out; 959 } 960 if (mapbase != (vm_offset_t)ef->address + mapsize) { 961 printf( 962 "%s: mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n", 963 filename != NULL ? filename : "<none>", 964 (u_long)mapbase, ef->address, (u_long)mapsize, 965 (u_long)(vm_offset_t)ef->address + mapsize); 966 error = ENOMEM; 967 goto out; 968 } 969 970 /* Local intra-module relocations */ 971 error = link_elf_reloc_local(lf); 972 if (error != 0) 973 goto out; 974 975 /* Pull in dependencies */ 976 VOP_UNLOCK(nd->ni_vp, 0); 977 error = linker_load_dependencies(lf); 978 vn_lock(nd->ni_vp, LK_EXCLUSIVE | LK_RETRY); 979 if (error) 980 goto out; 981 982 /* External relocations */ 983 error = relocate_file(ef); 984 if (error) 985 goto out; 986 987 /* Notify MD code that a module is being loaded. */ 988 error = elf_cpu_load_file(lf); 989 if (error) 990 goto out; 991 992 /* Invoke .ctors */ 993 link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size); 994 995 *result = lf; 996 997 out: 998 VOP_UNLOCK(nd->ni_vp, 0); 999 vn_close(nd->ni_vp, FREAD, td->td_ucred, td); 1000 free(nd, M_TEMP); 1001 if (error && lf) 1002 linker_file_unload(lf, LINKER_UNLOAD_FORCE); 1003 free(hdr, M_LINKER); 1004 1005 return error; 1006 } 1007 1008 static void 1009 link_elf_unload_file(linker_file_t file) 1010 { 1011 elf_file_t ef = (elf_file_t) file; 1012 u_int i; 1013 1014 /* Notify MD code that a module is being unloaded. */ 1015 elf_cpu_unload_file(file); 1016 1017 if (ef->progtab) { 1018 for (i = 0; i < ef->nprogtab; i++) { 1019 if (ef->progtab[i].size == 0) 1020 continue; 1021 if (ef->progtab[i].name == NULL) 1022 continue; 1023 if (!strcmp(ef->progtab[i].name, DPCPU_SETNAME)) 1024 dpcpu_free(ef->progtab[i].addr, 1025 ef->progtab[i].size); 1026 #ifdef VIMAGE 1027 else if (!strcmp(ef->progtab[i].name, VNET_SETNAME)) 1028 vnet_data_free(ef->progtab[i].addr, 1029 ef->progtab[i].size); 1030 #endif 1031 } 1032 } 1033 if (ef->preloaded) { 1034 free(ef->reltab, M_LINKER); 1035 free(ef->relatab, M_LINKER); 1036 free(ef->progtab, M_LINKER); 1037 free(ef->ctftab, M_LINKER); 1038 free(ef->ctfoff, M_LINKER); 1039 free(ef->typoff, M_LINKER); 1040 if (file->filename != NULL) 1041 preload_delete_name(file->filename); 1042 /* XXX reclaim module memory? */ 1043 return; 1044 } 1045 1046 for (i = 0; i < ef->nreltab; i++) 1047 free(ef->reltab[i].rel, M_LINKER); 1048 for (i = 0; i < ef->nrelatab; i++) 1049 free(ef->relatab[i].rela, M_LINKER); 1050 free(ef->reltab, M_LINKER); 1051 free(ef->relatab, M_LINKER); 1052 free(ef->progtab, M_LINKER); 1053 1054 if (ef->object) { 1055 vm_map_remove(kernel_map, (vm_offset_t) ef->address, 1056 (vm_offset_t) ef->address + 1057 (ef->object->size << PAGE_SHIFT)); 1058 } 1059 free(ef->e_shdr, M_LINKER); 1060 free(ef->ddbsymtab, M_LINKER); 1061 free(ef->ddbstrtab, M_LINKER); 1062 free(ef->shstrtab, M_LINKER); 1063 free(ef->ctftab, M_LINKER); 1064 free(ef->ctfoff, M_LINKER); 1065 free(ef->typoff, M_LINKER); 1066 } 1067 1068 static const char * 1069 symbol_name(elf_file_t ef, Elf_Size r_info) 1070 { 1071 const Elf_Sym *ref; 1072 1073 if (ELF_R_SYM(r_info)) { 1074 ref = ef->ddbsymtab + ELF_R_SYM(r_info); 1075 return ef->ddbstrtab + ref->st_name; 1076 } else 1077 return NULL; 1078 } 1079 1080 static Elf_Addr 1081 findbase(elf_file_t ef, int sec) 1082 { 1083 int i; 1084 Elf_Addr base = 0; 1085 1086 for (i = 0; i < ef->nprogtab; i++) { 1087 if (sec == ef->progtab[i].sec) { 1088 base = (Elf_Addr)ef->progtab[i].addr; 1089 break; 1090 } 1091 } 1092 return base; 1093 } 1094 1095 static int 1096 relocate_file(elf_file_t ef) 1097 { 1098 const Elf_Rel *rellim; 1099 const Elf_Rel *rel; 1100 const Elf_Rela *relalim; 1101 const Elf_Rela *rela; 1102 const char *symname; 1103 const Elf_Sym *sym; 1104 int i; 1105 Elf_Size symidx; 1106 Elf_Addr base; 1107 1108 1109 /* Perform relocations without addend if there are any: */ 1110 for (i = 0; i < ef->nreltab; i++) { 1111 rel = ef->reltab[i].rel; 1112 if (rel == NULL) { 1113 link_elf_error(ef->lf.filename, "lost a reltab!"); 1114 return (ENOEXEC); 1115 } 1116 rellim = rel + ef->reltab[i].nrel; 1117 base = findbase(ef, ef->reltab[i].sec); 1118 if (base == 0) { 1119 link_elf_error(ef->lf.filename, "lost base for reltab"); 1120 return (ENOEXEC); 1121 } 1122 for ( ; rel < rellim; rel++) { 1123 symidx = ELF_R_SYM(rel->r_info); 1124 if (symidx >= ef->ddbsymcnt) 1125 continue; 1126 sym = ef->ddbsymtab + symidx; 1127 /* Local relocs are already done */ 1128 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 1129 continue; 1130 if (elf_reloc(&ef->lf, base, rel, ELF_RELOC_REL, 1131 elf_obj_lookup)) { 1132 symname = symbol_name(ef, rel->r_info); 1133 printf("link_elf_obj: symbol %s undefined\n", 1134 symname); 1135 return (ENOENT); 1136 } 1137 } 1138 } 1139 1140 /* Perform relocations with addend if there are any: */ 1141 for (i = 0; i < ef->nrelatab; i++) { 1142 rela = ef->relatab[i].rela; 1143 if (rela == NULL) { 1144 link_elf_error(ef->lf.filename, "lost a relatab!"); 1145 return (ENOEXEC); 1146 } 1147 relalim = rela + ef->relatab[i].nrela; 1148 base = findbase(ef, ef->relatab[i].sec); 1149 if (base == 0) { 1150 link_elf_error(ef->lf.filename, 1151 "lost base for relatab"); 1152 return (ENOEXEC); 1153 } 1154 for ( ; rela < relalim; rela++) { 1155 symidx = ELF_R_SYM(rela->r_info); 1156 if (symidx >= ef->ddbsymcnt) 1157 continue; 1158 sym = ef->ddbsymtab + symidx; 1159 /* Local relocs are already done */ 1160 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) 1161 continue; 1162 if (elf_reloc(&ef->lf, base, rela, ELF_RELOC_RELA, 1163 elf_obj_lookup)) { 1164 symname = symbol_name(ef, rela->r_info); 1165 printf("link_elf_obj: symbol %s undefined\n", 1166 symname); 1167 return (ENOENT); 1168 } 1169 } 1170 } 1171 1172 /* 1173 * Only clean SHN_FBSD_CACHED for successful return. If we 1174 * modified symbol table for the object but found an 1175 * unresolved symbol, there is no reason to roll back. 1176 */ 1177 elf_obj_cleanup_globals_cache(ef); 1178 1179 return (0); 1180 } 1181 1182 static int 1183 link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) 1184 { 1185 elf_file_t ef = (elf_file_t) lf; 1186 const Elf_Sym *symp; 1187 const char *strp; 1188 int i; 1189 1190 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1191 strp = ef->ddbstrtab + symp->st_name; 1192 if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) { 1193 *sym = (c_linker_sym_t) symp; 1194 return 0; 1195 } 1196 } 1197 return ENOENT; 1198 } 1199 1200 static int 1201 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, 1202 linker_symval_t *symval) 1203 { 1204 elf_file_t ef = (elf_file_t) lf; 1205 const Elf_Sym *es = (const Elf_Sym*) sym; 1206 1207 if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { 1208 symval->name = ef->ddbstrtab + es->st_name; 1209 symval->value = (caddr_t)es->st_value; 1210 symval->size = es->st_size; 1211 return 0; 1212 } 1213 return ENOENT; 1214 } 1215 1216 static int 1217 link_elf_search_symbol(linker_file_t lf, caddr_t value, 1218 c_linker_sym_t *sym, long *diffp) 1219 { 1220 elf_file_t ef = (elf_file_t) lf; 1221 u_long off = (uintptr_t) (void *) value; 1222 u_long diff = off; 1223 u_long st_value; 1224 const Elf_Sym *es; 1225 const Elf_Sym *best = NULL; 1226 int i; 1227 1228 for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) { 1229 if (es->st_name == 0) 1230 continue; 1231 st_value = es->st_value; 1232 if (off >= st_value) { 1233 if (off - st_value < diff) { 1234 diff = off - st_value; 1235 best = es; 1236 if (diff == 0) 1237 break; 1238 } else if (off - st_value == diff) { 1239 best = es; 1240 } 1241 } 1242 } 1243 if (best == NULL) 1244 *diffp = off; 1245 else 1246 *diffp = diff; 1247 *sym = (c_linker_sym_t) best; 1248 1249 return 0; 1250 } 1251 1252 /* 1253 * Look up a linker set on an ELF system. 1254 */ 1255 static int 1256 link_elf_lookup_set(linker_file_t lf, const char *name, 1257 void ***startp, void ***stopp, int *countp) 1258 { 1259 elf_file_t ef = (elf_file_t)lf; 1260 void **start, **stop; 1261 int i, count; 1262 1263 /* Relative to section number */ 1264 for (i = 0; i < ef->nprogtab; i++) { 1265 if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) && 1266 strcmp(ef->progtab[i].name + 4, name) == 0) { 1267 start = (void **)ef->progtab[i].addr; 1268 stop = (void **)((char *)ef->progtab[i].addr + 1269 ef->progtab[i].size); 1270 count = stop - start; 1271 if (startp) 1272 *startp = start; 1273 if (stopp) 1274 *stopp = stop; 1275 if (countp) 1276 *countp = count; 1277 return (0); 1278 } 1279 } 1280 return (ESRCH); 1281 } 1282 1283 static int 1284 link_elf_each_function_name(linker_file_t file, 1285 int (*callback)(const char *, void *), void *opaque) 1286 { 1287 elf_file_t ef = (elf_file_t)file; 1288 const Elf_Sym *symp; 1289 int i, error; 1290 1291 /* Exhaustive search */ 1292 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1293 if (symp->st_value != 0 && 1294 ELF_ST_TYPE(symp->st_info) == STT_FUNC) { 1295 error = callback(ef->ddbstrtab + symp->st_name, opaque); 1296 if (error) 1297 return (error); 1298 } 1299 } 1300 return (0); 1301 } 1302 1303 static int 1304 link_elf_each_function_nameval(linker_file_t file, 1305 linker_function_nameval_callback_t callback, void *opaque) 1306 { 1307 linker_symval_t symval; 1308 elf_file_t ef = (elf_file_t)file; 1309 const Elf_Sym* symp; 1310 int i, error; 1311 1312 /* Exhaustive search */ 1313 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1314 if (symp->st_value != 0 && 1315 ELF_ST_TYPE(symp->st_info) == STT_FUNC) { 1316 error = link_elf_symbol_values(file, (c_linker_sym_t) symp, &symval); 1317 if (error) 1318 return (error); 1319 error = callback(file, i, &symval, opaque); 1320 if (error) 1321 return (error); 1322 } 1323 } 1324 return (0); 1325 } 1326 1327 static void 1328 elf_obj_cleanup_globals_cache(elf_file_t ef) 1329 { 1330 Elf_Sym *sym; 1331 Elf_Size i; 1332 1333 for (i = 0; i < ef->ddbsymcnt; i++) { 1334 sym = ef->ddbsymtab + i; 1335 if (sym->st_shndx == SHN_FBSD_CACHED) { 1336 sym->st_shndx = SHN_UNDEF; 1337 sym->st_value = 0; 1338 } 1339 } 1340 } 1341 1342 /* 1343 * Symbol lookup function that can be used when the symbol index is known (ie 1344 * in relocations). It uses the symbol index instead of doing a fully fledged 1345 * hash table based lookup when such is valid. For example for local symbols. 1346 * This is not only more efficient, it's also more correct. It's not always 1347 * the case that the symbol can be found through the hash table. 1348 */ 1349 static int 1350 elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *res) 1351 { 1352 elf_file_t ef = (elf_file_t)lf; 1353 Elf_Sym *sym; 1354 const char *symbol; 1355 Elf_Addr res1; 1356 1357 /* Don't even try to lookup the symbol if the index is bogus. */ 1358 if (symidx >= ef->ddbsymcnt) { 1359 *res = 0; 1360 return (EINVAL); 1361 } 1362 1363 sym = ef->ddbsymtab + symidx; 1364 1365 /* Quick answer if there is a definition included. */ 1366 if (sym->st_shndx != SHN_UNDEF) { 1367 *res = sym->st_value; 1368 return (0); 1369 } 1370 1371 /* If we get here, then it is undefined and needs a lookup. */ 1372 switch (ELF_ST_BIND(sym->st_info)) { 1373 case STB_LOCAL: 1374 /* Local, but undefined? huh? */ 1375 *res = 0; 1376 return (EINVAL); 1377 1378 case STB_GLOBAL: 1379 case STB_WEAK: 1380 /* Relative to Data or Function name */ 1381 symbol = ef->ddbstrtab + sym->st_name; 1382 1383 /* Force a lookup failure if the symbol name is bogus. */ 1384 if (*symbol == 0) { 1385 *res = 0; 1386 return (EINVAL); 1387 } 1388 res1 = (Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps); 1389 1390 /* 1391 * Cache global lookups during module relocation. The failure 1392 * case is particularly expensive for callers, who must scan 1393 * through the entire globals table doing strcmp(). Cache to 1394 * avoid doing such work repeatedly. 1395 * 1396 * After relocation is complete, undefined globals will be 1397 * restored to SHN_UNDEF in elf_obj_cleanup_globals_cache(), 1398 * above. 1399 */ 1400 if (res1 != 0) { 1401 sym->st_shndx = SHN_FBSD_CACHED; 1402 sym->st_value = res1; 1403 *res = res1; 1404 return (0); 1405 } else if (ELF_ST_BIND(sym->st_info) == STB_WEAK) { 1406 sym->st_value = 0; 1407 *res = 0; 1408 return (0); 1409 } 1410 return (EINVAL); 1411 1412 default: 1413 return (EINVAL); 1414 } 1415 } 1416 1417 static void 1418 link_elf_fix_link_set(elf_file_t ef) 1419 { 1420 static const char startn[] = "__start_"; 1421 static const char stopn[] = "__stop_"; 1422 Elf_Sym *sym; 1423 const char *sym_name, *linkset_name; 1424 Elf_Addr startp, stopp; 1425 Elf_Size symidx; 1426 int start, i; 1427 1428 startp = stopp = 0; 1429 for (symidx = 1 /* zero entry is special */; 1430 symidx < ef->ddbsymcnt; symidx++) { 1431 sym = ef->ddbsymtab + symidx; 1432 if (sym->st_shndx != SHN_UNDEF) 1433 continue; 1434 1435 sym_name = ef->ddbstrtab + sym->st_name; 1436 if (strncmp(sym_name, startn, sizeof(startn) - 1) == 0) { 1437 start = 1; 1438 linkset_name = sym_name + sizeof(startn) - 1; 1439 } 1440 else if (strncmp(sym_name, stopn, sizeof(stopn) - 1) == 0) { 1441 start = 0; 1442 linkset_name = sym_name + sizeof(stopn) - 1; 1443 } 1444 else 1445 continue; 1446 1447 for (i = 0; i < ef->nprogtab; i++) { 1448 if (strcmp(ef->progtab[i].name, linkset_name) == 0) { 1449 startp = (Elf_Addr)ef->progtab[i].addr; 1450 stopp = (Elf_Addr)(startp + ef->progtab[i].size); 1451 break; 1452 } 1453 } 1454 if (i == ef->nprogtab) 1455 continue; 1456 1457 sym->st_value = start ? startp : stopp; 1458 sym->st_shndx = i; 1459 } 1460 } 1461 1462 static int 1463 link_elf_reloc_local(linker_file_t lf) 1464 { 1465 elf_file_t ef = (elf_file_t)lf; 1466 const Elf_Rel *rellim; 1467 const Elf_Rel *rel; 1468 const Elf_Rela *relalim; 1469 const Elf_Rela *rela; 1470 const Elf_Sym *sym; 1471 Elf_Addr base; 1472 int i; 1473 Elf_Size symidx; 1474 1475 link_elf_fix_link_set(ef); 1476 1477 /* Perform relocations without addend if there are any: */ 1478 for (i = 0; i < ef->nreltab; i++) { 1479 rel = ef->reltab[i].rel; 1480 if (rel == NULL) { 1481 link_elf_error(ef->lf.filename, "lost a reltab"); 1482 return (ENOEXEC); 1483 } 1484 rellim = rel + ef->reltab[i].nrel; 1485 base = findbase(ef, ef->reltab[i].sec); 1486 if (base == 0) { 1487 link_elf_error(ef->lf.filename, "lost base for reltab"); 1488 return (ENOEXEC); 1489 } 1490 for ( ; rel < rellim; rel++) { 1491 symidx = ELF_R_SYM(rel->r_info); 1492 if (symidx >= ef->ddbsymcnt) 1493 continue; 1494 sym = ef->ddbsymtab + symidx; 1495 /* Only do local relocs */ 1496 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) 1497 continue; 1498 elf_reloc_local(lf, base, rel, ELF_RELOC_REL, 1499 elf_obj_lookup); 1500 } 1501 } 1502 1503 /* Perform relocations with addend if there are any: */ 1504 for (i = 0; i < ef->nrelatab; i++) { 1505 rela = ef->relatab[i].rela; 1506 if (rela == NULL) { 1507 link_elf_error(ef->lf.filename, "lost a relatab!"); 1508 return (ENOEXEC); 1509 } 1510 relalim = rela + ef->relatab[i].nrela; 1511 base = findbase(ef, ef->relatab[i].sec); 1512 if (base == 0) { 1513 link_elf_error(ef->lf.filename, "lost base for reltab"); 1514 return (ENOEXEC); 1515 } 1516 for ( ; rela < relalim; rela++) { 1517 symidx = ELF_R_SYM(rela->r_info); 1518 if (symidx >= ef->ddbsymcnt) 1519 continue; 1520 sym = ef->ddbsymtab + symidx; 1521 /* Only do local relocs */ 1522 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) 1523 continue; 1524 elf_reloc_local(lf, base, rela, ELF_RELOC_RELA, 1525 elf_obj_lookup); 1526 } 1527 } 1528 return (0); 1529 } 1530 1531 static long 1532 link_elf_symtab_get(linker_file_t lf, const Elf_Sym **symtab) 1533 { 1534 elf_file_t ef = (elf_file_t)lf; 1535 1536 *symtab = ef->ddbsymtab; 1537 1538 if (*symtab == NULL) 1539 return (0); 1540 1541 return (ef->ddbsymcnt); 1542 } 1543 1544 static long 1545 link_elf_strtab_get(linker_file_t lf, caddr_t *strtab) 1546 { 1547 elf_file_t ef = (elf_file_t)lf; 1548 1549 *strtab = ef->ddbstrtab; 1550 1551 if (*strtab == NULL) 1552 return (0); 1553 1554 return (ef->ddbstrcnt); 1555 } 1556