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 #ifdef __powerpc__ 459 if (ef->kernel) { 460 #else 461 if (ehdr->e_type == ET_EXEC) { 462 #endif 463 #if defined(__i386__) || defined(__amd64__) 464 #if __ELF_WORD_SIZE == 64 465 /* x86_64 relocates after locore */ 466 off = - (off & 0xffffffffff000000ull); 467 #else 468 /* i386 relocates after locore */ 469 off = - (off & 0xff000000u); 470 #endif 471 #elif defined(__powerpc__) 472 /* 473 * On the purely virtual memory machines like e500, the kernel 474 * is linked against its final VA range, which is most often 475 * not available at the loader stage, but only after kernel 476 * initializes and completes its VM settings. In such cases we 477 * cannot use p_vaddr field directly to load ELF segments, but 478 * put them at some 'load-time' locations. 479 */ 480 if (off & 0xf0000000u) { 481 off = -(off & 0xf0000000u); 482 /* 483 * XXX the physical load address should not be 484 * hardcoded. Note that the Book-E kernel assumes that 485 * it's loaded at a 16MB boundary for now... 486 */ 487 off += 0x01000000; 488 } 489 ehdr->e_entry += off; 490 #ifdef ELF_VERBOSE 491 printf("Converted entry 0x%jx\n", (uintmax_t)ehdr->e_entry); 492 #endif 493 #elif defined(__arm__) && !defined(EFI) 494 /* 495 * The elf headers in arm kernels specify virtual addresses in 496 * all header fields, even the ones that should be physical 497 * addresses. We assume the entry point is in the first page, 498 * and masking the page offset will leave us with the virtual 499 * address the kernel was linked at. We subtract that from the 500 * load offset, making 'off' into the value which, when added 501 * to a virtual address in an elf header, translates it to a 502 * physical address. We do the va->pa conversion on the entry 503 * point address in the header now, so that later we can launch 504 * the kernel by just jumping to that address. 505 * 506 * When booting from UEFI the copyin and copyout functions 507 * handle adjusting the location relative to the first virtual 508 * address. Because of this there is no need to adjust the 509 * offset or entry point address as these will both be handled 510 * by the efi code. 511 */ 512 off -= ehdr->e_entry & ~PAGE_MASK; 513 ehdr->e_entry += off; 514 #ifdef ELF_VERBOSE 515 printf("ehdr->e_entry 0x%jx, va<->pa off %llx\n", 516 (uintmax_t)ehdr->e_entry, off); 517 #endif 518 #else 519 off = 0; /* other archs use direct mapped kernels */ 520 #endif 521 } 522 ef->off = off; 523 524 if (ef->kernel) 525 __elfN(relocation_offset) = off; 526 527 if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > ef->firstlen) { 528 printf("elf" __XSTRING(__ELF_WORD_SIZE) 529 "_loadimage: program header not within first page\n"); 530 goto out; 531 } 532 phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff); 533 534 for (i = 0; i < ehdr->e_phnum; i++) { 535 if (elf_program_header_convert(ehdr, phdr)) 536 continue; 537 538 /* We want to load PT_LOAD segments only.. */ 539 if (phdr[i].p_type != PT_LOAD) 540 continue; 541 542 #ifdef ELF_VERBOSE 543 printf("Segment: 0x%lx@0x%lx -> 0x%lx-0x%lx", 544 (long)phdr[i].p_filesz, (long)phdr[i].p_offset, 545 (long)(phdr[i].p_vaddr + off), 546 (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1)); 547 #else 548 if ((phdr[i].p_flags & PF_W) == 0) { 549 printf("text=0x%lx ", (long)phdr[i].p_filesz); 550 } else { 551 printf("data=0x%lx", (long)phdr[i].p_filesz); 552 if (phdr[i].p_filesz < phdr[i].p_memsz) 553 printf("+0x%lx", (long)(phdr[i].p_memsz - 554 phdr[i].p_filesz)); 555 printf(" "); 556 } 557 #endif 558 fpcopy = 0; 559 if (ef->firstlen > phdr[i].p_offset) { 560 fpcopy = ef->firstlen - phdr[i].p_offset; 561 archsw.arch_copyin(ef->firstpage + phdr[i].p_offset, 562 phdr[i].p_vaddr + off, fpcopy); 563 } 564 if (phdr[i].p_filesz > fpcopy) { 565 if (kern_pread(ef->fd, phdr[i].p_vaddr + off + fpcopy, 566 phdr[i].p_filesz - fpcopy, 567 phdr[i].p_offset + fpcopy) != 0) { 568 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 569 "_loadimage: read failed\n"); 570 goto out; 571 } 572 } 573 /* clear space from oversized segments; eg: bss */ 574 if (phdr[i].p_filesz < phdr[i].p_memsz) { 575 #ifdef ELF_VERBOSE 576 printf(" (bss: 0x%lx-0x%lx)", 577 (long)(phdr[i].p_vaddr + off + phdr[i].p_filesz), 578 (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz -1)); 579 #endif 580 581 kern_bzero(phdr[i].p_vaddr + off + phdr[i].p_filesz, 582 phdr[i].p_memsz - phdr[i].p_filesz); 583 } 584 #ifdef ELF_VERBOSE 585 printf("\n"); 586 #endif 587 588 if (archsw.arch_loadseg != NULL) 589 archsw.arch_loadseg(ehdr, phdr + i, off); 590 591 if (firstaddr == 0 || firstaddr > (phdr[i].p_vaddr + off)) 592 firstaddr = phdr[i].p_vaddr + off; 593 if (lastaddr == 0 || lastaddr < 594 (phdr[i].p_vaddr + off + phdr[i].p_memsz)) 595 lastaddr = phdr[i].p_vaddr + off + phdr[i].p_memsz; 596 } 597 lastaddr = roundup(lastaddr, sizeof(long)); 598 599 /* 600 * Get the section headers. We need this for finding the .ctors 601 * section as well as for loading any symbols. Both may be hard 602 * to do if reading from a .gz file as it involves seeking. I 603 * think the rule is going to have to be that you must strip a 604 * file to remove symbols before gzipping it. 605 */ 606 chunk = (size_t)ehdr->e_shnum * (size_t)ehdr->e_shentsize; 607 if (chunk == 0 || ehdr->e_shoff == 0) 608 goto nosyms; 609 shdr = alloc_pread(ef->fd, ehdr->e_shoff, chunk); 610 if (shdr == NULL) { 611 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 612 "_loadimage: failed to read section headers"); 613 goto nosyms; 614 } 615 616 for (i = 0; i < ehdr->e_shnum; i++) 617 elf_section_header_convert(ehdr, &shdr[i]); 618 619 file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr); 620 621 /* 622 * Read the section string table and look for the .ctors section. 623 * We need to tell the kernel where it is so that it can call the 624 * ctors. 625 */ 626 chunk = shdr[ehdr->e_shstrndx].sh_size; 627 if (chunk) { 628 shstr = alloc_pread(ef->fd, shdr[ehdr->e_shstrndx].sh_offset, 629 chunk); 630 if (shstr) { 631 for (i = 0; i < ehdr->e_shnum; i++) { 632 if (strcmp(shstr + shdr[i].sh_name, 633 ".ctors") != 0) 634 continue; 635 ctors = shdr[i].sh_addr; 636 file_addmetadata(fp, MODINFOMD_CTORS_ADDR, 637 sizeof(ctors), &ctors); 638 size = shdr[i].sh_size; 639 file_addmetadata(fp, MODINFOMD_CTORS_SIZE, 640 sizeof(size), &size); 641 break; 642 } 643 free(shstr); 644 } 645 } 646 647 /* 648 * Now load any symbols. 649 */ 650 symtabindex = -1; 651 symstrindex = -1; 652 for (i = 0; i < ehdr->e_shnum; i++) { 653 if (shdr[i].sh_type != SHT_SYMTAB) 654 continue; 655 for (j = 0; j < ehdr->e_phnum; j++) { 656 if (phdr[j].p_type != PT_LOAD) 657 continue; 658 if (shdr[i].sh_offset >= phdr[j].p_offset && 659 (shdr[i].sh_offset + shdr[i].sh_size <= 660 phdr[j].p_offset + phdr[j].p_filesz)) { 661 shdr[i].sh_offset = 0; 662 shdr[i].sh_size = 0; 663 break; 664 } 665 } 666 if (shdr[i].sh_offset == 0 || shdr[i].sh_size == 0) 667 continue; /* alread loaded in a PT_LOAD above */ 668 /* Save it for loading below */ 669 symtabindex = i; 670 symstrindex = shdr[i].sh_link; 671 } 672 if (symtabindex < 0 || symstrindex < 0) 673 goto nosyms; 674 675 /* Ok, committed to a load. */ 676 #ifndef ELF_VERBOSE 677 printf("syms=["); 678 #endif 679 ssym = lastaddr; 680 for (i = symtabindex; i >= 0; i = symstrindex) { 681 #ifdef ELF_VERBOSE 682 char *secname; 683 684 switch(shdr[i].sh_type) { 685 case SHT_SYMTAB: /* Symbol table */ 686 secname = "symtab"; 687 break; 688 case SHT_STRTAB: /* String table */ 689 secname = "strtab"; 690 break; 691 default: 692 secname = "WHOA!!"; 693 break; 694 } 695 #endif 696 size = shdr[i].sh_size; 697 #if defined(__powerpc__) 698 #if __ELF_WORD_SIZE == 64 699 size = htobe64(size); 700 #else 701 size = htobe32(size); 702 #endif 703 #endif 704 705 archsw.arch_copyin(&size, lastaddr, sizeof(size)); 706 lastaddr += sizeof(size); 707 708 #ifdef ELF_VERBOSE 709 printf("\n%s: 0x%jx@0x%jx -> 0x%jx-0x%jx", secname, 710 (uintmax_t)shdr[i].sh_size, (uintmax_t)shdr[i].sh_offset, 711 (uintmax_t)lastaddr, 712 (uintmax_t)(lastaddr + shdr[i].sh_size)); 713 #else 714 if (i == symstrindex) 715 printf("+"); 716 printf("0x%lx+0x%lx", (long)sizeof(size), (long)size); 717 #endif 718 719 if (lseek(ef->fd, (off_t)shdr[i].sh_offset, SEEK_SET) == -1) { 720 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 721 "_loadimage: could not seek for symbols - skipped!"); 722 lastaddr = ssym; 723 ssym = 0; 724 goto nosyms; 725 } 726 result = archsw.arch_readin(ef->fd, lastaddr, shdr[i].sh_size); 727 if (result < 0 || (size_t)result != shdr[i].sh_size) { 728 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 729 "_loadimage: could not read symbols - skipped! " 730 "(%ju != %ju)", (uintmax_t)result, 731 (uintmax_t)shdr[i].sh_size); 732 lastaddr = ssym; 733 ssym = 0; 734 goto nosyms; 735 } 736 /* Reset offsets relative to ssym */ 737 lastaddr += shdr[i].sh_size; 738 lastaddr = roundup(lastaddr, sizeof(size)); 739 if (i == symtabindex) 740 symtabindex = -1; 741 else if (i == symstrindex) 742 symstrindex = -1; 743 } 744 esym = lastaddr; 745 #ifndef ELF_VERBOSE 746 printf("]"); 747 #endif 748 749 #if defined(__powerpc__) 750 /* On PowerPC we always need to provide BE data to the kernel */ 751 #if __ELF_WORD_SIZE == 64 752 ssym = htobe64((uint64_t)ssym); 753 esym = htobe64((uint64_t)esym); 754 #else 755 ssym = htobe32((uint32_t)ssym); 756 esym = htobe32((uint32_t)esym); 757 #endif 758 #endif 759 760 file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym); 761 file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym); 762 763 nosyms: 764 printf("\n"); 765 766 ret = lastaddr - firstaddr; 767 fp->f_addr = firstaddr; 768 769 php = NULL; 770 for (i = 0; i < ehdr->e_phnum; i++) { 771 if (phdr[i].p_type == PT_DYNAMIC) { 772 php = phdr + i; 773 adp = php->p_vaddr; 774 file_addmetadata(fp, MODINFOMD_DYNAMIC, sizeof(adp), 775 &adp); 776 break; 777 } 778 } 779 780 if (php == NULL) /* this is bad, we cannot get to symbols or _DYNAMIC */ 781 goto out; 782 783 ndp = php->p_filesz / sizeof(Elf_Dyn); 784 if (ndp == 0) 785 goto out; 786 dp = malloc(php->p_filesz); 787 if (dp == NULL) 788 goto out; 789 archsw.arch_copyout(php->p_vaddr + off, dp, php->p_filesz); 790 791 ef->strsz = 0; 792 for (i = 0; i < ndp; i++) { 793 if (dp[i].d_tag == 0) 794 break; 795 switch (dp[i].d_tag) { 796 case DT_HASH: 797 ef->hashtab = 798 (Elf_Hashelt*)(uintptr_t)(dp[i].d_un.d_ptr + off); 799 break; 800 case DT_STRTAB: 801 ef->strtab = 802 (char *)(uintptr_t)(dp[i].d_un.d_ptr + off); 803 break; 804 case DT_STRSZ: 805 ef->strsz = dp[i].d_un.d_val; 806 break; 807 case DT_SYMTAB: 808 ef->symtab = 809 (Elf_Sym *)(uintptr_t)(dp[i].d_un.d_ptr + off); 810 break; 811 case DT_REL: 812 ef->rel = 813 (Elf_Rel *)(uintptr_t)(dp[i].d_un.d_ptr + off); 814 break; 815 case DT_RELSZ: 816 ef->relsz = dp[i].d_un.d_val; 817 break; 818 case DT_RELA: 819 ef->rela = 820 (Elf_Rela *)(uintptr_t)(dp[i].d_un.d_ptr + off); 821 break; 822 case DT_RELASZ: 823 ef->relasz = dp[i].d_un.d_val; 824 break; 825 default: 826 break; 827 } 828 } 829 if (ef->hashtab == NULL || ef->symtab == NULL || 830 ef->strtab == NULL || ef->strsz == 0) 831 goto out; 832 COPYOUT(ef->hashtab, &ef->nbuckets, sizeof(ef->nbuckets)); 833 COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof(ef->nchains)); 834 ef->buckets = ef->hashtab + 2; 835 ef->chains = ef->buckets + ef->nbuckets; 836 837 if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set", 838 &sym) != 0) 839 return 0; 840 p_start = sym.st_value + ef->off; 841 if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set", 842 &sym) != 0) 843 return ENOENT; 844 p_end = sym.st_value + ef->off; 845 846 if (__elfN(parse_modmetadata)(fp, ef, p_start, p_end) == 0) 847 goto out; 848 849 if (ef->kernel) /* kernel must not depend on anything */ 850 goto out; 851 852 out: 853 if (dp) 854 free(dp); 855 if (shdr) 856 free(shdr); 857 return ret; 858 } 859 860 static char invalid_name[] = "bad"; 861 862 char * 863 fake_modname(const char *name) 864 { 865 const char *sp, *ep; 866 char *fp; 867 size_t len; 868 869 sp = strrchr(name, '/'); 870 if (sp) 871 sp++; 872 else 873 sp = name; 874 875 ep = strrchr(sp, '.'); 876 if (ep == NULL) { 877 ep = sp + strlen(sp); 878 } 879 if (ep == sp) { 880 sp = invalid_name; 881 ep = invalid_name + sizeof(invalid_name) - 1; 882 } 883 884 len = ep - sp; 885 fp = malloc(len + 1); 886 if (fp == NULL) 887 return NULL; 888 memcpy(fp, sp, len); 889 fp[len] = '\0'; 890 return fp; 891 } 892 893 #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 894 struct mod_metadata64 { 895 int md_version; /* structure version MDTV_* */ 896 int md_type; /* type of entry MDT_* */ 897 uint64_t md_data; /* specific data */ 898 uint64_t md_cval; /* common string label */ 899 }; 900 #endif 901 #if defined(__amd64__) && __ELF_WORD_SIZE == 32 902 struct mod_metadata32 { 903 int md_version; /* structure version MDTV_* */ 904 int md_type; /* type of entry MDT_* */ 905 uint32_t md_data; /* specific data */ 906 uint32_t md_cval; /* common string label */ 907 }; 908 #endif 909 910 int 911 __elfN(load_modmetadata)(struct preloaded_file *fp, uint64_t dest) 912 { 913 struct elf_file ef; 914 int err, i, j; 915 Elf_Shdr *sh_meta, *shdr = NULL; 916 Elf_Shdr *sh_data[2]; 917 char *shstrtab = NULL; 918 size_t size; 919 Elf_Addr p_start, p_end; 920 921 bzero(&ef, sizeof(struct elf_file)); 922 ef.fd = -1; 923 924 err = __elfN(load_elf_header)(fp->f_name, &ef); 925 if (err != 0) 926 goto out; 927 928 if (ef.kernel == 1 || ef.ehdr->e_type == ET_EXEC) { 929 ef.kernel = 1; 930 } else if (ef.ehdr->e_type != ET_DYN) { 931 err = EFTYPE; 932 goto out; 933 } 934 935 size = (size_t)ef.ehdr->e_shnum * (size_t)ef.ehdr->e_shentsize; 936 shdr = alloc_pread(ef.fd, ef.ehdr->e_shoff, size); 937 if (shdr == NULL) { 938 err = ENOMEM; 939 goto out; 940 } 941 942 /* Load shstrtab. */ 943 shstrtab = alloc_pread(ef.fd, shdr[ef.ehdr->e_shstrndx].sh_offset, 944 shdr[ef.ehdr->e_shstrndx].sh_size); 945 if (shstrtab == NULL) { 946 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 947 "load_modmetadata: unable to load shstrtab\n"); 948 err = EFTYPE; 949 goto out; 950 } 951 952 /* Find set_modmetadata_set and data sections. */ 953 sh_data[0] = sh_data[1] = sh_meta = NULL; 954 for (i = 0, j = 0; i < ef.ehdr->e_shnum; i++) { 955 if (strcmp(&shstrtab[shdr[i].sh_name], 956 "set_modmetadata_set") == 0) { 957 sh_meta = &shdr[i]; 958 } 959 if ((strcmp(&shstrtab[shdr[i].sh_name], ".data") == 0) || 960 (strcmp(&shstrtab[shdr[i].sh_name], ".rodata") == 0)) { 961 sh_data[j++] = &shdr[i]; 962 } 963 } 964 if (sh_meta == NULL || sh_data[0] == NULL || sh_data[1] == NULL) { 965 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 966 "load_modmetadata: unable to find set_modmetadata_set or data sections\n"); 967 err = EFTYPE; 968 goto out; 969 } 970 971 /* Load set_modmetadata_set into memory */ 972 err = kern_pread(ef.fd, dest, sh_meta->sh_size, sh_meta->sh_offset); 973 if (err != 0) { 974 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 975 "load_modmetadata: unable to load set_modmetadata_set: %d\n", err); 976 goto out; 977 } 978 p_start = dest; 979 p_end = dest + sh_meta->sh_size; 980 dest += sh_meta->sh_size; 981 982 /* Load data sections into memory. */ 983 err = kern_pread(ef.fd, dest, sh_data[0]->sh_size, 984 sh_data[0]->sh_offset); 985 if (err != 0) { 986 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 987 "load_modmetadata: unable to load data: %d\n", err); 988 goto out; 989 } 990 991 /* 992 * We have to increment the dest, so that the offset is the same into 993 * both the .rodata and .data sections. 994 */ 995 ef.off = -(sh_data[0]->sh_addr - dest); 996 dest += (sh_data[1]->sh_addr - sh_data[0]->sh_addr); 997 998 err = kern_pread(ef.fd, dest, sh_data[1]->sh_size, 999 sh_data[1]->sh_offset); 1000 if (err != 0) { 1001 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 1002 "load_modmetadata: unable to load data: %d\n", err); 1003 goto out; 1004 } 1005 1006 err = __elfN(parse_modmetadata)(fp, &ef, p_start, p_end); 1007 if (err != 0) { 1008 printf("\nelf" __XSTRING(__ELF_WORD_SIZE) 1009 "load_modmetadata: unable to parse metadata: %d\n", err); 1010 goto out; 1011 } 1012 1013 out: 1014 if (shstrtab != NULL) 1015 free(shstrtab); 1016 if (shdr != NULL) 1017 free(shdr); 1018 if (ef.firstpage != NULL) 1019 free(ef.firstpage); 1020 if (ef.fd != -1) 1021 close(ef.fd); 1022 return (err); 1023 } 1024 1025 int 1026 __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef, 1027 Elf_Addr p_start, Elf_Addr p_end) 1028 { 1029 struct mod_metadata md; 1030 #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 1031 struct mod_metadata64 md64; 1032 #elif defined(__amd64__) && __ELF_WORD_SIZE == 32 1033 struct mod_metadata32 md32; 1034 #endif 1035 struct mod_depend *mdepend; 1036 struct mod_version mver; 1037 char *s; 1038 int error, modcnt, minfolen; 1039 Elf_Addr v, p; 1040 1041 modcnt = 0; 1042 p = p_start; 1043 while (p < p_end) { 1044 COPYOUT(p, &v, sizeof(v)); 1045 error = __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v)); 1046 if (error == EOPNOTSUPP) 1047 v += ef->off; 1048 else if (error != 0) 1049 return (error); 1050 #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 1051 COPYOUT(v, &md64, sizeof(md64)); 1052 error = __elfN(reloc_ptr)(fp, ef, v, &md64, sizeof(md64)); 1053 if (error == EOPNOTSUPP) { 1054 md64.md_cval += ef->off; 1055 md64.md_data += ef->off; 1056 } else if (error != 0) 1057 return (error); 1058 md.md_version = md64.md_version; 1059 md.md_type = md64.md_type; 1060 md.md_cval = (const char *)(uintptr_t)md64.md_cval; 1061 md.md_data = (void *)(uintptr_t)md64.md_data; 1062 #elif defined(__amd64__) && __ELF_WORD_SIZE == 32 1063 COPYOUT(v, &md32, sizeof(md32)); 1064 error = __elfN(reloc_ptr)(fp, ef, v, &md32, sizeof(md32)); 1065 if (error == EOPNOTSUPP) { 1066 md32.md_cval += ef->off; 1067 md32.md_data += ef->off; 1068 } else if (error != 0) 1069 return (error); 1070 md.md_version = md32.md_version; 1071 md.md_type = md32.md_type; 1072 md.md_cval = (const char *)(uintptr_t)md32.md_cval; 1073 md.md_data = (void *)(uintptr_t)md32.md_data; 1074 #else 1075 COPYOUT(v, &md, sizeof(md)); 1076 error = __elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md)); 1077 if (error == EOPNOTSUPP) { 1078 md.md_cval += ef->off; 1079 md.md_data = (void *)((uintptr_t)md.md_data + 1080 (uintptr_t)ef->off); 1081 } else if (error != 0) 1082 return (error); 1083 #endif 1084 p += sizeof(Elf_Addr); 1085 switch(md.md_type) { 1086 case MDT_DEPEND: 1087 if (ef->kernel) /* kernel must not depend on anything */ 1088 break; 1089 s = strdupout((vm_offset_t)md.md_cval); 1090 minfolen = sizeof(*mdepend) + strlen(s) + 1; 1091 mdepend = malloc(minfolen); 1092 if (mdepend == NULL) 1093 return ENOMEM; 1094 COPYOUT((vm_offset_t)md.md_data, mdepend, 1095 sizeof(*mdepend)); 1096 strcpy((char*)(mdepend + 1), s); 1097 free(s); 1098 file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen, 1099 mdepend); 1100 free(mdepend); 1101 break; 1102 case MDT_VERSION: 1103 s = strdupout((vm_offset_t)md.md_cval); 1104 COPYOUT((vm_offset_t)md.md_data, &mver, sizeof(mver)); 1105 file_addmodule(fp, s, mver.mv_version, NULL); 1106 free(s); 1107 modcnt++; 1108 break; 1109 } 1110 } 1111 if (modcnt == 0) { 1112 s = fake_modname(fp->f_name); 1113 file_addmodule(fp, s, 1, NULL); 1114 free(s); 1115 } 1116 return 0; 1117 } 1118 1119 static unsigned long 1120 elf_hash(const char *name) 1121 { 1122 const unsigned char *p = (const unsigned char *) name; 1123 unsigned long h = 0; 1124 unsigned long g; 1125 1126 while (*p != '\0') { 1127 h = (h << 4) + *p++; 1128 if ((g = h & 0xf0000000) != 0) 1129 h ^= g >> 24; 1130 h &= ~g; 1131 } 1132 return h; 1133 } 1134 1135 static const char __elfN(bad_symtable)[] = "elf" __XSTRING(__ELF_WORD_SIZE) 1136 "_lookup_symbol: corrupt symbol table\n"; 1137 int 1138 __elfN(lookup_symbol)(struct preloaded_file *fp, elf_file_t ef, 1139 const char* name, Elf_Sym *symp) 1140 { 1141 Elf_Hashelt symnum; 1142 Elf_Sym sym; 1143 char *strp; 1144 unsigned long hash; 1145 1146 hash = elf_hash(name); 1147 COPYOUT(&ef->buckets[hash % ef->nbuckets], &symnum, sizeof(symnum)); 1148 1149 while (symnum != STN_UNDEF) { 1150 if (symnum >= ef->nchains) { 1151 printf(__elfN(bad_symtable)); 1152 return ENOENT; 1153 } 1154 1155 COPYOUT(ef->symtab + symnum, &sym, sizeof(sym)); 1156 if (sym.st_name == 0) { 1157 printf(__elfN(bad_symtable)); 1158 return ENOENT; 1159 } 1160 1161 strp = strdupout((vm_offset_t)(ef->strtab + sym.st_name)); 1162 if (strcmp(name, strp) == 0) { 1163 free(strp); 1164 if (sym.st_shndx != SHN_UNDEF || 1165 (sym.st_value != 0 && 1166 ELF_ST_TYPE(sym.st_info) == STT_FUNC)) { 1167 *symp = sym; 1168 return 0; 1169 } 1170 return ENOENT; 1171 } 1172 free(strp); 1173 COPYOUT(&ef->chains[symnum], &symnum, sizeof(symnum)); 1174 } 1175 return ENOENT; 1176 } 1177 1178 /* 1179 * Apply any intra-module relocations to the value. p is the load address 1180 * of the value and val/len is the value to be modified. This does NOT modify 1181 * the image in-place, because this is done by kern_linker later on. 1182 * 1183 * Returns EOPNOTSUPP if no relocation method is supplied. 1184 */ 1185 static int 1186 __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, 1187 Elf_Addr p, void *val, size_t len) 1188 { 1189 size_t n; 1190 Elf_Rela a; 1191 Elf_Rel r; 1192 int error; 1193 1194 /* 1195 * The kernel is already relocated, but we still want to apply 1196 * offset adjustments. 1197 */ 1198 if (ef->kernel) 1199 return (EOPNOTSUPP); 1200 1201 for (n = 0; n < ef->relsz / sizeof(r); n++) { 1202 COPYOUT(ef->rel + n, &r, sizeof(r)); 1203 1204 error = __elfN(reloc)(ef, __elfN(symaddr), &r, ELF_RELOC_REL, 1205 ef->off, p, val, len); 1206 if (error != 0) 1207 return (error); 1208 } 1209 for (n = 0; n < ef->relasz / sizeof(a); n++) { 1210 COPYOUT(ef->rela + n, &a, sizeof(a)); 1211 1212 error = __elfN(reloc)(ef, __elfN(symaddr), &a, ELF_RELOC_RELA, 1213 ef->off, p, val, len); 1214 if (error != 0) 1215 return (error); 1216 } 1217 1218 return (0); 1219 } 1220 1221 static Elf_Addr 1222 __elfN(symaddr)(struct elf_file *ef, Elf_Size symidx) 1223 { 1224 1225 /* Symbol lookup by index not required here. */ 1226 return (0); 1227 } 1228