1/*- 2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3 * Copyright (c) 1998 Peter Wemm <peter@freebsd.org> 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 <sys/param.h> 32#include <sys/endian.h> 33#include <sys/exec.h> 34#include <sys/linker.h> 35#include <sys/module.h> 36#include <sys/stdint.h> 37#include <string.h> 38#include <machine/elf.h> 39#include <stand.h> 40#define FREEBSD_ELF 41#include <sys/link_elf.h> 42 43#include "bootstrap.h" 44 45#define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l) 46 47#if defined(__i386__) && __ELF_WORD_SIZE == 64 48#undef ELF_TARG_CLASS 49#undef ELF_TARG_MACH 50#define ELF_TARG_CLASS ELFCLASS64 51#define ELF_TARG_MACH EM_X86_64 52#endif 53 54typedef struct elf_file { 55 Elf_Phdr *ph; 56 Elf_Ehdr *ehdr; 57 Elf_Sym *symtab; 58 Elf_Hashelt *hashtab; 59 Elf_Hashelt nbuckets; 60 Elf_Hashelt nchains; 61 Elf_Hashelt *buckets; 62 Elf_Hashelt *chains; 63 Elf_Rel *rel; 64 size_t relsz; 65 Elf_Rela *rela; 66 size_t relasz; 67 char *strtab; 68 size_t strsz; 69 int fd; 70 caddr_t firstpage; 71 size_t firstlen; 72 int kernel; 73 uint64_t off; 74#ifdef LOADER_VERIEXEC_VECTX 75 struct vectx *vctx; 76#endif 77} *elf_file_t; 78 79#ifdef LOADER_VERIEXEC_VECTX 80#define VECTX_HANDLE(ef) (ef)->vctx 81#else 82#define VECTX_HANDLE(ef) (ef)->fd 83#endif 84 85static int __elfN(loadimage)(struct preloaded_file *mp, elf_file_t ef, 86 uint64_t loadaddr); 87static int __elfN(lookup_symbol)(struct preloaded_file *mp, elf_file_t ef, 88 const char* name, Elf_Sym* sym); 89static int __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, 90 Elf_Addr p, void *val, size_t len); 91static int __elfN(parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef, 92 Elf_Addr p_start, Elf_Addr p_end); 93static symaddr_fn __elfN(symaddr); 94static char *fake_modname(const char *name); 95 96const char *__elfN(kerneltype) = "elf kernel"; 97const char *__elfN(moduletype) = "elf module"; 98 99uint64_t __elfN(relocation_offset) = 0; 100 101extern void elf_wrong_field_size(void); 102#define CONVERT_FIELD(b, f, e) \ 103 switch (sizeof((b)->f)) { \ 104 case 2: \ 105 (b)->f = e ## 16toh((b)->f); \ 106 break; \ 107 case 4: \ 108 (b)->f = e ## 32toh((b)->f); \ 109 break; \ 110 case 8: \ 111 (b)->f = e ## 64toh((b)->f); \ 112 break; \ 113 default: \ 114 /* Force a link time error. */ \ 115 elf_wrong_field_size(); \ 116 break; \ 117 } 118 119#define CONVERT_SWITCH(h, d, f) \ 120 switch ((h)->e_ident[EI_DATA]) { \ 121 case ELFDATA2MSB: \ 122 f(d, be); \ 123 break; \ 124 case ELFDATA2LSB: \ 125 f(d, le); \ 126 break; \ 127 default: \ 128 return (EINVAL); \ 129 } 130 131 132static int elf_header_convert(Elf_Ehdr *ehdr) 133{ 134 /* 135 * Fixup ELF header endianness. 136 * 137 * The Xhdr structure was loaded using block read call to optimize file 138 * accesses. It might happen, that the endianness of the system memory 139 * is different that endianness of the ELF header. Swap fields here to 140 * guarantee that Xhdr always contain valid data regardless of 141 * architecture. 142 */ 143#define HEADER_FIELDS(b, e) \ 144 CONVERT_FIELD(b, e_type, e); \ 145 CONVERT_FIELD(b, e_machine, e); \ 146 CONVERT_FIELD(b, e_version, e); \ 147 CONVERT_FIELD(b, e_entry, e); \ 148 CONVERT_FIELD(b, e_phoff, e); \ 149 CONVERT_FIELD(b, e_shoff, e); \ 150 CONVERT_FIELD(b, e_flags, e); \ 151 CONVERT_FIELD(b, e_ehsize, e); \ 152 CONVERT_FIELD(b, e_phentsize, e); \ 153 CONVERT_FIELD(b, e_phnum, e); \ 154 CONVERT_FIELD(b, e_shentsize, e); \ 155 CONVERT_FIELD(b, e_shnum, e); \ 156 CONVERT_FIELD(b, e_shstrndx, e) 157 158 CONVERT_SWITCH(ehdr, ehdr, HEADER_FIELDS); 159 160#undef HEADER_FIELDS 161 162 return (0); 163} 164 165static int elf_program_header_convert(const Elf_Ehdr *ehdr, Elf_Phdr *phdr) 166{ 167#define PROGRAM_HEADER_FIELDS(b, e) \ 168 CONVERT_FIELD(b, p_type, e); \ 169 CONVERT_FIELD(b, p_flags, e); \ 170 CONVERT_FIELD(b, p_offset, e); \ 171 CONVERT_FIELD(b, p_vaddr, e); \ 172 CONVERT_FIELD(b, p_paddr, e); \ 173 CONVERT_FIELD(b, p_filesz, e); \ 174 CONVERT_FIELD(b, p_memsz, e); \ 175 CONVERT_FIELD(b, p_align, e) 176 177 CONVERT_SWITCH(ehdr, phdr, PROGRAM_HEADER_FIELDS); 178 179#undef PROGRAM_HEADER_FIELDS 180 181 return (0); 182} 183 184static int elf_section_header_convert(const Elf_Ehdr *ehdr, Elf_Shdr *shdr) 185{ 186#define SECTION_HEADER_FIELDS(b, e) \ 187 CONVERT_FIELD(b, sh_name, e); \ 188 CONVERT_FIELD(b, sh_type, e); \ 189 CONVERT_FIELD(b, sh_link, e); \ 190 CONVERT_FIELD(b, sh_info, e); \ 191 CONVERT_FIELD(b, sh_flags, e); \ 192 CONVERT_FIELD(b, sh_addr, e); \ 193 CONVERT_FIELD(b, sh_offset, e); \ 194 CONVERT_FIELD(b, sh_size, e); \ 195 CONVERT_FIELD(b, sh_addralign, e); \ 196 CONVERT_FIELD(b, sh_entsize, e) 197 198 CONVERT_SWITCH(ehdr, shdr, SECTION_HEADER_FIELDS); 199 200#undef SECTION_HEADER_FIELDS 201 202 return (0); 203} 204#undef CONVERT_SWITCH 205#undef CONVERT_FIELD 206 207static int 208__elfN(load_elf_header)(char *filename, elf_file_t ef) 209{ 210 ssize_t bytes_read; 211 Elf_Ehdr *ehdr; 212 int err; 213 214 /* 215 * Open the image, read and validate the ELF header 216 */ 217 if (filename == NULL) /* can't handle nameless */ 218 return (EFTYPE); 219 if ((ef->fd = open(filename, O_RDONLY)) == -1) 220 return (errno); 221 ef->firstpage = malloc(PAGE_SIZE); 222 if (ef->firstpage == NULL) { 223 close(ef->fd); 224 return (ENOMEM); 225 } 226#ifdef LOADER_VERIEXEC_VECTX 227 { 228 int verror; 229 230 ef->vctx = vectx_open(ef->fd, filename, 0L, NULL, &verror, __func__); 231 if (verror) { 232 printf("Unverified %s: %s\n", filename, ve_error_get()); 233 close(ef->fd); 234 free(ef->vctx); 235 return (EAUTH); 236 } 237 } 238#endif 239 bytes_read = VECTX_READ(VECTX_HANDLE(ef), ef->firstpage, PAGE_SIZE); 240 ef->firstlen = (size_t)bytes_read; 241 if (bytes_read < 0 || ef->firstlen <= sizeof(Elf_Ehdr)) { 242 err = EFTYPE; /* could be EIO, but may be small file */ 243 goto error; 244 } 245 ehdr = ef->ehdr = (Elf_Ehdr *)ef->firstpage; 246 247 /* Is it ELF? */ 248 if (!IS_ELF(*ehdr)) { 249 err = EFTYPE; 250 goto error; 251 } 252 253 if (ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */ 254 ehdr->e_ident[EI_DATA] != ELF_TARG_DATA || 255 ehdr->e_ident[EI_VERSION] != EV_CURRENT) /* Version ? */ { 256 err = EFTYPE; 257 goto error; 258 } 259 260 err = elf_header_convert(ehdr); 261 if (err) 262 goto error; 263 264 if (ehdr->e_version != EV_CURRENT || ehdr->e_machine != ELF_TARG_MACH) { 265 /* Machine ? */ 266 err = EFTYPE; 267 goto error; 268 } 269 270#if defined(LOADER_VERIEXEC) && !defined(LOADER_VERIEXEC_VECTX) 271 if (verify_file(ef->fd, filename, bytes_read, VE_MUST, __func__) < 0) { 272 err = EAUTH; 273 goto error; 274 } 275#endif 276 return (0); 277 278error: 279 if (ef->firstpage != NULL) { 280 free(ef->firstpage); 281 ef->firstpage = NULL; 282 } 283 if (ef->fd != -1) { 284#ifdef LOADER_VERIEXEC_VECTX 285 free(ef->vctx); 286#endif 287 close(ef->fd); 288 ef->fd = -1; 289 } 290 return (err); 291} 292 293/* 294 * Attempt to load the file (file) as an ELF module. It will be stored at 295 * (dest), and a pointer to a module structure describing the loaded object 296 * will be saved in (result). 297 */ 298int 299__elfN(loadfile)(char *filename, uint64_t dest, struct preloaded_file **result) 300{ 301 return (__elfN(loadfile_raw)(filename, dest, result, 0)); 302} 303 304int 305__elfN(loadfile_raw)(char *filename, uint64_t dest, 306 struct preloaded_file **result, int multiboot) 307{ 308 struct preloaded_file *fp, *kfp; 309 struct elf_file ef; 310 Elf_Ehdr *ehdr; 311 int err; 312 313 fp = NULL; 314 bzero(&ef, sizeof(struct elf_file)); 315 ef.fd = -1; 316 317 err = __elfN(load_elf_header)(filename, &ef); 318 if (err != 0) 319 return (err); 320 321 ehdr = ef.ehdr; 322 323 /* 324 * Check to see what sort of module we are. 325 */ 326 kfp = file_findfile(NULL, __elfN(kerneltype)); 327#ifdef __powerpc__ 328 /* 329 * Kernels can be ET_DYN, so just assume the first loaded object is the 330 * kernel. This assumption will be checked later. 331 */ 332 if (kfp == NULL) 333 ef.kernel = 1; 334#endif 335 if (ef.kernel || ehdr->e_type == ET_EXEC) { 336 /* Looks like a kernel */ 337 if (kfp != NULL) { 338 printf("elf" __XSTRING(__ELF_WORD_SIZE) 339 "_loadfile: kernel already loaded\n"); 340 err = EPERM; 341 goto oerr; 342 } 343 /* 344 * Calculate destination address based on kernel entrypoint. 345 * 346 * For ARM, the destination address is independent of any values 347 * in the elf header (an ARM kernel can be loaded at any 2MB 348 * boundary), so we leave dest set to the value calculated by 349 * archsw.arch_loadaddr() and passed in to this function. 350 */ 351#ifndef __arm__ 352 if (ehdr->e_type == ET_EXEC) 353 dest = (ehdr->e_entry & ~PAGE_MASK); 354#endif 355 if ((ehdr->e_entry & ~PAGE_MASK) == 0) { 356 printf("elf" __XSTRING(__ELF_WORD_SIZE) 357 "_loadfile: not a kernel (maybe static binary?)\n"); 358 err = EPERM; 359 goto oerr; 360 } 361 ef.kernel = 1; 362 363 } else if (ehdr->e_type == ET_DYN) { 364 /* Looks like a kld module */ 365 if (multiboot != 0) { 366 printf("elf" __XSTRING(__ELF_WORD_SIZE) 367 "_loadfile: can't load module as multiboot\n"); 368 err = EPERM; 369 goto oerr; 370 } 371 if (kfp == NULL) { 372 printf("elf" __XSTRING(__ELF_WORD_SIZE) 373 "_loadfile: can't load module before kernel\n"); 374 err = EPERM; 375 goto oerr; 376 } 377 if (strcmp(__elfN(kerneltype), kfp->f_type)) { 378 printf("elf" __XSTRING(__ELF_WORD_SIZE) 379 "_loadfile: can't load module with kernel type '%s'\n", 380 kfp->f_type); 381 err = EPERM; 382 goto oerr; 383 } 384 /* Looks OK, got ahead */ 385 ef.kernel = 0; 386 387 } else { 388 err = EFTYPE; 389 goto oerr; 390 } 391 392 if (archsw.arch_loadaddr != NULL) 393 dest = archsw.arch_loadaddr(LOAD_ELF, ehdr, dest); 394 else 395 dest = roundup(dest, PAGE_SIZE); 396 397 /* 398 * Ok, we think we should handle this. 399 */ 400 fp = file_alloc(); 401 if (fp == NULL) { 402 printf("elf" __XSTRING(__ELF_WORD_SIZE) 403 "_loadfile: cannot allocate module info\n"); 404 err = EPERM; 405 goto out; 406 } 407 if (ef.kernel == 1 && multiboot == 0) 408 setenv("kernelname", filename, 1); 409 fp->f_name = strdup(filename); 410 if (multiboot == 0) 411 fp->f_type = strdup(ef.kernel ? 412 __elfN(kerneltype) : __elfN(moduletype)); 413 else 414 fp->f_type = strdup("elf multiboot kernel"); 415 416#ifdef ELF_VERBOSE 417 if (ef.kernel) 418 printf("%s entry at 0x%jx\n", filename, 419 (uintmax_t)ehdr->e_entry); 420#else 421 printf("%s ", filename); 422#endif 423 424 fp->f_size = __elfN(loadimage)(fp, &ef, dest); 425 if (fp->f_size == 0 || fp->f_addr == 0) 426 goto ioerr; 427 428 /* save exec header as metadata */ 429 file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr); 430 431 /* Load OK, return module pointer */ 432 *result = (struct preloaded_file *)fp; 433 err = 0; 434 goto out; 435 436ioerr: 437 err = EIO; 438oerr: 439 file_discard(fp); 440out: 441 if (ef.firstpage) 442 free(ef.firstpage); 443 if (ef.fd != -1) { 444#ifdef LOADER_VERIEXEC_VECTX 445 if (!err && ef.vctx) { 446 int verror; 447 448 verror = vectx_close(ef.vctx, VE_MUST, __func__); 449 if (verror) { 450 err = EAUTH; 451 file_discard(fp); 452 } 453 } 454#endif 455 close(ef.fd); 456 } 457 return (err); 458} 459 460/* 461 * With the file (fd) open on the image, and (ehdr) containing 462 * the Elf header, load the image at (off) 463 */ 464static int 465__elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off) 466{ 467 int i; 468 u_int j; 469 Elf_Ehdr *ehdr; 470 Elf_Phdr *phdr, *php; 471 Elf_Shdr *shdr; 472 char *shstr; 473 int ret; 474 vm_offset_t firstaddr; 475 vm_offset_t lastaddr; 476 size_t chunk; 477 ssize_t result; 478 Elf_Addr ssym, esym; 479 Elf_Dyn *dp; 480 Elf_Addr adp; 481 Elf_Addr ctors; 482 int ndp; 483 int symstrindex; 484 int symtabindex; 485 Elf_Size size; 486 u_int fpcopy; 487 Elf_Sym sym; 488 Elf_Addr p_start, p_end; 489 490 dp = NULL; 491 shdr = NULL; 492 ret = 0; 493 firstaddr = lastaddr = 0; 494 ehdr = ef->ehdr; 495 if (ehdr->e_type == ET_EXEC) { 496#if defined(__i386__) || defined(__amd64__) 497#if __ELF_WORD_SIZE == 64 498 /* x86_64 relocates after locore */ 499 off = - (off & 0xffffffffff000000ull); 500#else 501 /* i386 relocates after locore */ 502 off = - (off & 0xff000000u); 503#endif 504#elif defined(__powerpc__) 505 /* 506 * On the purely virtual memory machines like e500, the kernel 507 * is linked against its final VA range, which is most often 508 * not available at the loader stage, but only after kernel 509 * initializes and completes its VM settings. In such cases we 510 * cannot use p_vaddr field directly to load ELF segments, but 511 * put them at some 'load-time' locations. 512 */ 513 if (off & 0xf0000000u) { 514 off = -(off & 0xf0000000u); 515 /* 516 * XXX the physical load address should not be 517 * hardcoded. Note that the Book-E kernel assumes that 518 * it's loaded at a 16MB boundary for now... 519 */ 520 off += 0x01000000; 521 ehdr->e_entry += off; 522#ifdef ELF_VERBOSE 523 printf("Converted entry 0x%jx\n", (uintmax_t)ehdr->e_entry); 524#endif 525 } else 526 off = 0; 527#elif defined(__arm__) && !defined(EFI) 528 /* 529 * The elf headers in arm kernels specify virtual addresses in 530 * all header fields, even the ones that should be physical 531 * addresses. We assume the entry point is in the first page, 532 * and masking the page offset will leave us with the virtual 533 * address the kernel was linked at. We subtract that from the 534 * load offset, making 'off' into the value which, when added 535 * to a virtual address in an elf header, translates it to a 536 * physical address. We do the va->pa conversion on the entry 537 * point address in the header now, so that later we can launch 538 * the kernel by just jumping to that address. 539 * 540 * When booting from UEFI the copyin and copyout functions 541 * handle adjusting the location relative to the first virtual 542 * address. Because of this there is no need to adjust the 543 * offset or entry point address as these will both be handled 544 * by the efi code. 545 */ 546 off -= ehdr->e_entry & ~PAGE_MASK; 547 ehdr->e_entry += off; 548#ifdef ELF_VERBOSE 549 printf("ehdr->e_entry 0x%jx, va<->pa off %llx\n", 550 (uintmax_t)ehdr->e_entry, off); 551#endif 552#else 553 off = 0; /* other archs use direct mapped kernels */ 554#endif 555 } 556 ef->off = off; 557 558 if (ef->kernel) 559 __elfN(relocation_offset) = off; 560 561 if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > ef->firstlen) { 562 printf("elf" __XSTRING(__ELF_WORD_SIZE) 563 "_loadimage: program header not within first page\n"); 564 goto out; 565 } 566 phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff); 567 568 for (i = 0; i < ehdr->e_phnum; i++) { 569 if (elf_program_header_convert(ehdr, phdr)) 570 continue; 571 572 /* We want to load PT_LOAD segments only.. */ 573 if (phdr[i].p_type != PT_LOAD) 574 continue; 575 576#ifdef ELF_VERBOSE 577 printf("Segment: 0x%lx@0x%lx -> 0x%lx-0x%lx", 578 (long)phdr[i].p_filesz, (long)phdr[i].p_offset, 579 (long)(phdr[i].p_vaddr + off), 580 (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1)); 581#else 582 if ((phdr[i].p_flags & PF_W) == 0) { 583 printf("text=0x%lx ", (long)phdr[i].p_filesz); 584 } else { 585 printf("data=0x%lx", (long)phdr[i].p_filesz); 586 if (phdr[i].p_filesz < phdr[i].p_memsz) 587 printf("+0x%lx", (long)(phdr[i].p_memsz - 588 phdr[i].p_filesz)); 589 printf(" "); 590 } 591#endif 592 fpcopy = 0; 593 if (ef->firstlen > phdr[i].p_offset) { 594 fpcopy = ef->firstlen - phdr[i].p_offset; 595 archsw.arch_copyin(ef->firstpage + phdr[i].p_offset, 596 phdr[i].p_vaddr + off, fpcopy); 597 } 598 if (phdr[i].p_filesz > fpcopy) { 599 if (kern_pread(VECTX_HANDLE(ef), 600 phdr[i].p_vaddr + off + fpcopy, 601 phdr[i].p_filesz - fpcopy, 602 phdr[i].p_offset + fpcopy) != 0) { 603 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 604 "_loadimage: read failed\n"); 605 goto out; 606 } 607 } 608 /* clear space from oversized segments; eg: bss */ 609 if (phdr[i].p_filesz < phdr[i].p_memsz) { 610#ifdef ELF_VERBOSE 611 printf(" (bss: 0x%lx-0x%lx)", 612 (long)(phdr[i].p_vaddr + off + phdr[i].p_filesz), 613 (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz -1)); 614#endif 615 616 kern_bzero(phdr[i].p_vaddr + off + phdr[i].p_filesz, 617 phdr[i].p_memsz - phdr[i].p_filesz); 618 } 619#ifdef ELF_VERBOSE 620 printf("\n"); 621#endif 622 623 if (archsw.arch_loadseg != NULL) 624 archsw.arch_loadseg(ehdr, phdr + i, off); 625 626 if (firstaddr == 0 || firstaddr > (phdr[i].p_vaddr + off)) 627 firstaddr = phdr[i].p_vaddr + off; 628 if (lastaddr == 0 || lastaddr < 629 (phdr[i].p_vaddr + off + phdr[i].p_memsz)) 630 lastaddr = phdr[i].p_vaddr + off + phdr[i].p_memsz; 631 } 632 lastaddr = roundup(lastaddr, sizeof(long)); 633 634 /* 635 * Get the section headers. We need this for finding the .ctors 636 * section as well as for loading any symbols. Both may be hard 637 * to do if reading from a .gz file as it involves seeking. I 638 * think the rule is going to have to be that you must strip a 639 * file to remove symbols before gzipping it. 640 */ 641 chunk = (size_t)ehdr->e_shnum * (size_t)ehdr->e_shentsize; 642 if (chunk == 0 || ehdr->e_shoff == 0) 643 goto nosyms; 644 shdr = alloc_pread(VECTX_HANDLE(ef), ehdr->e_shoff, chunk); 645 if (shdr == NULL) { 646 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 647 "_loadimage: failed to read section headers"); 648 goto nosyms; 649 } 650 651 for (i = 0; i < ehdr->e_shnum; i++) 652 elf_section_header_convert(ehdr, &shdr[i]); 653 654 file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr); 655 656 /* 657 * Read the section string table and look for the .ctors section. 658 * We need to tell the kernel where it is so that it can call the 659 * ctors. 660 */ 661 chunk = shdr[ehdr->e_shstrndx].sh_size; 662 if (chunk) { 663 shstr = alloc_pread(VECTX_HANDLE(ef), 664 shdr[ehdr->e_shstrndx].sh_offset, chunk); 665 if (shstr) { 666 for (i = 0; i < ehdr->e_shnum; i++) { 667 if (strcmp(shstr + shdr[i].sh_name, 668 ".ctors") != 0) 669 continue; 670 ctors = shdr[i].sh_addr; 671 file_addmetadata(fp, MODINFOMD_CTORS_ADDR, 672 sizeof(ctors), &ctors); 673 size = shdr[i].sh_size; 674 file_addmetadata(fp, MODINFOMD_CTORS_SIZE, 675 sizeof(size), &size); 676 break; 677 } 678 free(shstr); 679 } 680 } 681 682 /* 683 * Now load any symbols. 684 */ 685 symtabindex = -1; 686 symstrindex = -1; 687 for (i = 0; i < ehdr->e_shnum; i++) { 688 if (shdr[i].sh_type != SHT_SYMTAB) 689 continue; 690 for (j = 0; j < ehdr->e_phnum; j++) { 691 if (phdr[j].p_type != PT_LOAD) 692 continue; 693 if (shdr[i].sh_offset >= phdr[j].p_offset && 694 (shdr[i].sh_offset + shdr[i].sh_size <= 695 phdr[j].p_offset + phdr[j].p_filesz)) { 696 shdr[i].sh_offset = 0; 697 shdr[i].sh_size = 0; 698 break; 699 } 700 } 701 if (shdr[i].sh_offset == 0 || shdr[i].sh_size == 0) 702 continue; /* alread loaded in a PT_LOAD above */ 703 /* Save it for loading below */ 704 symtabindex = i; 705 symstrindex = shdr[i].sh_link; 706 } 707 if (symtabindex < 0 || symstrindex < 0) 708 goto nosyms; 709 710 /* Ok, committed to a load. */ 711#ifndef ELF_VERBOSE 712 printf("syms=["); 713#endif 714 ssym = lastaddr; 715 for (i = symtabindex; i >= 0; i = symstrindex) { 716#ifdef ELF_VERBOSE 717 char *secname; 718 719 switch(shdr[i].sh_type) { 720 case SHT_SYMTAB: /* Symbol table */ 721 secname = "symtab"; 722 break; 723 case SHT_STRTAB: /* String table */ 724 secname = "strtab"; 725 break; 726 default: 727 secname = "WHOA!!"; 728 break; 729 } 730#endif 731 size = shdr[i].sh_size; 732#if defined(__powerpc__) 733 #if __ELF_WORD_SIZE == 64 734 size = htobe64(size); 735 #else 736 size = htobe32(size); 737 #endif 738#endif 739 740 archsw.arch_copyin(&size, lastaddr, sizeof(size)); 741 lastaddr += sizeof(size); 742 743#ifdef ELF_VERBOSE 744 printf("\n%s: 0x%jx@0x%jx -> 0x%jx-0x%jx", secname, 745 (uintmax_t)shdr[i].sh_size, (uintmax_t)shdr[i].sh_offset, 746 (uintmax_t)lastaddr, 747 (uintmax_t)(lastaddr + shdr[i].sh_size)); 748#else 749 if (i == symstrindex) 750 printf("+"); 751 printf("0x%lx+0x%lx", (long)sizeof(size), (long)size); 752#endif 753 754 if (VECTX_LSEEK(VECTX_HANDLE(ef), (off_t)shdr[i].sh_offset, SEEK_SET) == -1) { 755 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 756 "_loadimage: could not seek for symbols - skipped!"); 757 lastaddr = ssym; 758 ssym = 0; 759 goto nosyms; 760 } 761 result = archsw.arch_readin(VECTX_HANDLE(ef), lastaddr, shdr[i].sh_size); 762 if (result < 0 || (size_t)result != shdr[i].sh_size) { 763 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 764 "_loadimage: could not read symbols - skipped! " 765 "(%ju != %ju)", (uintmax_t)result, 766 (uintmax_t)shdr[i].sh_size); 767 lastaddr = ssym; 768 ssym = 0; 769 goto nosyms; 770 } 771 /* Reset offsets relative to ssym */ 772 lastaddr += shdr[i].sh_size; 773 lastaddr = roundup(lastaddr, sizeof(size)); 774 if (i == symtabindex) 775 symtabindex = -1; 776 else if (i == symstrindex) 777 symstrindex = -1; 778 } 779 esym = lastaddr; 780#ifndef ELF_VERBOSE 781 printf("]"); 782#endif 783 784#if defined(__powerpc__) 785 /* On PowerPC we always need to provide BE data to the kernel */ 786 #if __ELF_WORD_SIZE == 64 787 ssym = htobe64((uint64_t)ssym); 788 esym = htobe64((uint64_t)esym); 789 #else 790 ssym = htobe32((uint32_t)ssym); 791 esym = htobe32((uint32_t)esym); 792 #endif 793#endif 794 795 file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym); 796 file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym); 797 798nosyms: 799 printf("\n"); 800 801 ret = lastaddr - firstaddr; 802 fp->f_addr = firstaddr; 803 804 php = NULL; 805 for (i = 0; i < ehdr->e_phnum; i++) { 806 if (phdr[i].p_type == PT_DYNAMIC) { 807 php = phdr + i; 808 adp = php->p_vaddr; 809 file_addmetadata(fp, MODINFOMD_DYNAMIC, sizeof(adp), 810 &adp); 811 break; 812 } 813 } 814 815 if (php == NULL) /* this is bad, we cannot get to symbols or _DYNAMIC */ 816 goto out; 817 818 ndp = php->p_filesz / sizeof(Elf_Dyn); 819 if (ndp == 0) 820 goto out; 821 dp = malloc(php->p_filesz); 822 if (dp == NULL) 823 goto out; 824 archsw.arch_copyout(php->p_vaddr + off, dp, php->p_filesz); 825 826 ef->strsz = 0; 827 for (i = 0; i < ndp; i++) { 828 if (dp[i].d_tag == 0) 829 break; 830 switch (dp[i].d_tag) { 831 case DT_HASH: 832 ef->hashtab = 833 (Elf_Hashelt*)(uintptr_t)(dp[i].d_un.d_ptr + off); 834 break; 835 case DT_STRTAB: 836 ef->strtab = 837 (char *)(uintptr_t)(dp[i].d_un.d_ptr + off); 838 break; 839 case DT_STRSZ: 840 ef->strsz = dp[i].d_un.d_val; 841 break; 842 case DT_SYMTAB: 843 ef->symtab = 844 (Elf_Sym *)(uintptr_t)(dp[i].d_un.d_ptr + off); 845 break; 846 case DT_REL: 847 ef->rel = 848 (Elf_Rel *)(uintptr_t)(dp[i].d_un.d_ptr + off); 849 break; 850 case DT_RELSZ: 851 ef->relsz = dp[i].d_un.d_val; 852 break; 853 case DT_RELA: 854 ef->rela = 855 (Elf_Rela *)(uintptr_t)(dp[i].d_un.d_ptr + off); 856 break; 857 case DT_RELASZ: 858 ef->relasz = dp[i].d_un.d_val; 859 break; 860 default: 861 break; 862 } 863 } 864 if (ef->hashtab == NULL || ef->symtab == NULL || 865 ef->strtab == NULL || ef->strsz == 0) 866 goto out; 867 COPYOUT(ef->hashtab, &ef->nbuckets, sizeof(ef->nbuckets)); 868 COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof(ef->nchains)); 869 ef->buckets = ef->hashtab + 2; 870 ef->chains = ef->buckets + ef->nbuckets; 871 872 if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set", 873 &sym) != 0) 874 return 0; 875 p_start = sym.st_value + ef->off; 876 if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set", 877 &sym) != 0) 878 return 0; 879 p_end = sym.st_value + ef->off; 880 881 if (__elfN(parse_modmetadata)(fp, ef, p_start, p_end) == 0) 882 goto out; 883 884 if (ef->kernel) /* kernel must not depend on anything */ 885 goto out; 886 887out: 888 if (dp) 889 free(dp); 890 if (shdr) 891 free(shdr); 892 return ret; 893} 894 895static char invalid_name[] = "bad"; 896 897char * 898fake_modname(const char *name) 899{ 900 const char *sp, *ep; 901 char *fp; 902 size_t len; 903 904 sp = strrchr(name, '/'); 905 if (sp) 906 sp++; 907 else 908 sp = name; 909 910 ep = strrchr(sp, '.'); 911 if (ep == NULL) { 912 ep = sp + strlen(sp); 913 } 914 if (ep == sp) { 915 sp = invalid_name; 916 ep = invalid_name + sizeof(invalid_name) - 1; 917 } 918 919 len = ep - sp; 920 fp = malloc(len + 1); 921 if (fp == NULL) 922 return NULL; 923 memcpy(fp, sp, len); 924 fp[len] = '\0'; 925 return fp; 926} 927 928#if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 929struct mod_metadata64 { 930 int md_version; /* structure version MDTV_* */ 931 int md_type; /* type of entry MDT_* */ 932 uint64_t md_data; /* specific data */ 933 uint64_t md_cval; /* common string label */ 934}; 935#endif 936#if defined(__amd64__) && __ELF_WORD_SIZE == 32 937struct mod_metadata32 { 938 int md_version; /* structure version MDTV_* */ 939 int md_type; /* type of entry MDT_* */ 940 uint32_t md_data; /* specific data */ 941 uint32_t md_cval; /* common string label */ 942}; 943#endif 944 945int 946__elfN(load_modmetadata)(struct preloaded_file *fp, uint64_t dest) 947{ 948 struct elf_file ef; 949 int err, i, j; 950 Elf_Shdr *sh_meta, *shdr = NULL; 951 Elf_Shdr *sh_data[2]; 952 char *shstrtab = NULL; 953 size_t size; 954 Elf_Addr p_start, p_end; 955 956 bzero(&ef, sizeof(struct elf_file)); 957 ef.fd = -1; 958 959 err = __elfN(load_elf_header)(fp->f_name, &ef); 960 if (err != 0) 961 goto out; 962 963 if (ef.kernel == 1 || ef.ehdr->e_type == ET_EXEC) { 964 ef.kernel = 1; 965 } else if (ef.ehdr->e_type != ET_DYN) { 966 err = EFTYPE; 967 goto out; 968 } 969 970 size = (size_t)ef.ehdr->e_shnum * (size_t)ef.ehdr->e_shentsize; 971 shdr = alloc_pread(VECTX_HANDLE(&ef), ef.ehdr->e_shoff, size); 972 if (shdr == NULL) { 973 err = ENOMEM; 974 goto out; 975 } 976 977 /* Load shstrtab. */ 978 shstrtab = alloc_pread(VECTX_HANDLE(&ef), shdr[ef.ehdr->e_shstrndx].sh_offset, 979 shdr[ef.ehdr->e_shstrndx].sh_size); 980 if (shstrtab == NULL) { 981 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 982 "load_modmetadata: unable to load shstrtab\n"); 983 err = EFTYPE; 984 goto out; 985 } 986 987 /* Find set_modmetadata_set and data sections. */ 988 sh_data[0] = sh_data[1] = sh_meta = NULL; 989 for (i = 0, j = 0; i < ef.ehdr->e_shnum; i++) { 990 if (strcmp(&shstrtab[shdr[i].sh_name], 991 "set_modmetadata_set") == 0) { 992 sh_meta = &shdr[i]; 993 } 994 if ((strcmp(&shstrtab[shdr[i].sh_name], ".data") == 0) || 995 (strcmp(&shstrtab[shdr[i].sh_name], ".rodata") == 0)) { 996 sh_data[j++] = &shdr[i]; 997 } 998 } 999 if (sh_meta == NULL || sh_data[0] == NULL || sh_data[1] == NULL) { 1000 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 1001 "load_modmetadata: unable to find set_modmetadata_set or data sections\n"); 1002 err = EFTYPE; 1003 goto out; 1004 } 1005 1006 /* Load set_modmetadata_set into memory */ 1007 err = kern_pread(VECTX_HANDLE(&ef), dest, sh_meta->sh_size, sh_meta->sh_offset); 1008 if (err != 0) { 1009 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 1010 "load_modmetadata: unable to load set_modmetadata_set: %d\n", err); 1011 goto out; 1012 } 1013 p_start = dest; 1014 p_end = dest + sh_meta->sh_size; 1015 dest += sh_meta->sh_size; 1016 1017 /* Load data sections into memory. */ 1018 err = kern_pread(VECTX_HANDLE(&ef), dest, sh_data[0]->sh_size, 1019 sh_data[0]->sh_offset); 1020 if (err != 0) { 1021 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 1022 "load_modmetadata: unable to load data: %d\n", err); 1023 goto out; 1024 } 1025 1026 /* 1027 * We have to increment the dest, so that the offset is the same into 1028 * both the .rodata and .data sections. 1029 */ 1030 ef.off = -(sh_data[0]->sh_addr - dest); 1031 dest += (sh_data[1]->sh_addr - sh_data[0]->sh_addr); 1032 1033 err = kern_pread(VECTX_HANDLE(&ef), dest, sh_data[1]->sh_size, 1034 sh_data[1]->sh_offset); 1035 if (err != 0) { 1036 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 1037 "load_modmetadata: unable to load data: %d\n", err); 1038 goto out; 1039 } 1040 1041 err = __elfN(parse_modmetadata)(fp, &ef, p_start, p_end); 1042 if (err != 0) { 1043 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 1044 "load_modmetadata: unable to parse metadata: %d\n", err); 1045 goto out; 1046 } 1047 1048out: 1049 if (shstrtab != NULL) 1050 free(shstrtab); 1051 if (shdr != NULL) 1052 free(shdr); 1053 if (ef.firstpage != NULL) 1054 free(ef.firstpage); 1055 if (ef.fd != -1) { 1056#ifdef LOADER_VERIEXEC_VECTX 1057 if (!err && ef.vctx) { 1058 int verror; 1059 1060 verror = vectx_close(ef.vctx, VE_MUST, __func__); 1061 if (verror) { 1062 err = EAUTH; 1063 file_discard(fp); 1064 } 1065 } 1066#endif 1067 close(ef.fd); 1068 } 1069 return (err); 1070} 1071 1072int 1073__elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef, 1074 Elf_Addr p_start, Elf_Addr p_end) 1075{ 1076 struct mod_metadata md; 1077#if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 1078 struct mod_metadata64 md64; 1079#elif defined(__amd64__) && __ELF_WORD_SIZE == 32 1080 struct mod_metadata32 md32; 1081#endif 1082 struct mod_depend *mdepend; 1083 struct mod_version mver; 1084 char *s; 1085 int error, modcnt, minfolen; 1086 Elf_Addr v, p; 1087 1088 modcnt = 0; 1089 p = p_start; 1090 while (p < p_end) { 1091 COPYOUT(p, &v, sizeof(v)); 1092 error = __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v)); 1093 if (error == EOPNOTSUPP) 1094 v += ef->off; 1095 else if (error != 0) 1096 return (error); 1097#if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 1098 COPYOUT(v, &md64, sizeof(md64)); 1099 error = __elfN(reloc_ptr)(fp, ef, v, &md64, sizeof(md64)); 1100 if (error == EOPNOTSUPP) { 1101 md64.md_cval += ef->off; 1102 md64.md_data += ef->off; 1103 } else if (error != 0) 1104 return (error); 1105 md.md_version = md64.md_version; 1106 md.md_type = md64.md_type; 1107 md.md_cval = (const char *)(uintptr_t)md64.md_cval; 1108 md.md_data = (void *)(uintptr_t)md64.md_data; 1109#elif defined(__amd64__) && __ELF_WORD_SIZE == 32 1110 COPYOUT(v, &md32, sizeof(md32)); 1111 error = __elfN(reloc_ptr)(fp, ef, v, &md32, sizeof(md32)); 1112 if (error == EOPNOTSUPP) { 1113 md32.md_cval += ef->off; 1114 md32.md_data += ef->off; 1115 } else if (error != 0) 1116 return (error); 1117 md.md_version = md32.md_version; 1118 md.md_type = md32.md_type; 1119 md.md_cval = (const char *)(uintptr_t)md32.md_cval; 1120 md.md_data = (void *)(uintptr_t)md32.md_data; 1121#else 1122 COPYOUT(v, &md, sizeof(md)); 1123 error = __elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md)); 1124 if (error == EOPNOTSUPP) { 1125 md.md_cval += ef->off; 1126 md.md_data = (void *)((uintptr_t)md.md_data + 1127 (uintptr_t)ef->off); 1128 } else if (error != 0) 1129 return (error); 1130#endif 1131 p += sizeof(Elf_Addr); 1132 switch(md.md_type) { 1133 case MDT_DEPEND: 1134 if (ef->kernel) /* kernel must not depend on anything */ 1135 break; 1136 s = strdupout((vm_offset_t)md.md_cval); 1137 minfolen = sizeof(*mdepend) + strlen(s) + 1; 1138 mdepend = malloc(minfolen); 1139 if (mdepend == NULL) 1140 return ENOMEM; 1141 COPYOUT((vm_offset_t)md.md_data, mdepend, 1142 sizeof(*mdepend)); 1143 strcpy((char*)(mdepend + 1), s); 1144 free(s); 1145 file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen, 1146 mdepend); 1147 free(mdepend); 1148 break; 1149 case MDT_VERSION: 1150 s = strdupout((vm_offset_t)md.md_cval); 1151 COPYOUT((vm_offset_t)md.md_data, &mver, sizeof(mver)); 1152 file_addmodule(fp, s, mver.mv_version, NULL); 1153 free(s); 1154 modcnt++; 1155 break; 1156 } 1157 } 1158 if (modcnt == 0) { 1159 s = fake_modname(fp->f_name); 1160 file_addmodule(fp, s, 1, NULL); 1161 free(s); 1162 } 1163 return 0; 1164} 1165 1166static unsigned long 1167elf_hash(const char *name) 1168{ 1169 const unsigned char *p = (const unsigned char *) name; 1170 unsigned long h = 0; 1171 unsigned long g; 1172 1173 while (*p != '\0') { 1174 h = (h << 4) + *p++; 1175 if ((g = h & 0xf0000000) != 0) 1176 h ^= g >> 24; 1177 h &= ~g; 1178 } 1179 return h; 1180} 1181 1182static const char __elfN(bad_symtable)[] = "elf" __XSTRING(__ELF_WORD_SIZE) 1183 "_lookup_symbol: corrupt symbol table\n"; 1184int 1185__elfN(lookup_symbol)(struct preloaded_file *fp, elf_file_t ef, 1186 const char* name, Elf_Sym *symp) 1187{ 1188 Elf_Hashelt symnum; 1189 Elf_Sym sym; 1190 char *strp; 1191 unsigned long hash; 1192 1193 hash = elf_hash(name); 1194 COPYOUT(&ef->buckets[hash % ef->nbuckets], &symnum, sizeof(symnum)); 1195 1196 while (symnum != STN_UNDEF) { 1197 if (symnum >= ef->nchains) { 1198 printf(__elfN(bad_symtable)); 1199 return ENOENT; 1200 } 1201 1202 COPYOUT(ef->symtab + symnum, &sym, sizeof(sym)); 1203 if (sym.st_name == 0) { 1204 printf(__elfN(bad_symtable)); 1205 return ENOENT; 1206 } 1207 1208 strp = strdupout((vm_offset_t)(ef->strtab + sym.st_name)); 1209 if (strcmp(name, strp) == 0) { 1210 free(strp); 1211 if (sym.st_shndx != SHN_UNDEF || 1212 (sym.st_value != 0 && 1213 ELF_ST_TYPE(sym.st_info) == STT_FUNC)) { 1214 *symp = sym; 1215 return 0; 1216 } 1217 return ENOENT; 1218 } 1219 free(strp); 1220 COPYOUT(&ef->chains[symnum], &symnum, sizeof(symnum)); 1221 } 1222 return ENOENT; 1223} 1224 1225/* 1226 * Apply any intra-module relocations to the value. p is the load address 1227 * of the value and val/len is the value to be modified. This does NOT modify 1228 * the image in-place, because this is done by kern_linker later on. 1229 * 1230 * Returns EOPNOTSUPP if no relocation method is supplied. 1231 */ 1232static int 1233__elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, 1234 Elf_Addr p, void *val, size_t len) 1235{ 1236 size_t n; 1237 Elf_Rela a; 1238 Elf_Rel r; 1239 int error; 1240 1241 /* 1242 * The kernel is already relocated, but we still want to apply 1243 * offset adjustments. 1244 */ 1245 if (ef->kernel) 1246 return (EOPNOTSUPP); 1247 1248 for (n = 0; n < ef->relsz / sizeof(r); n++) { 1249 COPYOUT(ef->rel + n, &r, sizeof(r)); 1250 1251 error = __elfN(reloc)(ef, __elfN(symaddr), &r, ELF_RELOC_REL, 1252 ef->off, p, val, len); 1253 if (error != 0) 1254 return (error); 1255 } 1256 for (n = 0; n < ef->relasz / sizeof(a); n++) { 1257 COPYOUT(ef->rela + n, &a, sizeof(a)); 1258 1259 error = __elfN(reloc)(ef, __elfN(symaddr), &a, ELF_RELOC_RELA, 1260 ef->off, p, val, len); 1261 if (error != 0) 1262 return (error); 1263 } 1264 1265 return (0); 1266} 1267 1268static Elf_Addr 1269__elfN(symaddr)(struct elf_file *ef, Elf_Size symidx) 1270{ 1271 1272 /* Symbol lookup by index not required here. */ 1273 return (0); 1274} 1275