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