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