1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/sysmacros.h> 27 #include <sys/types.h> 28 #include <sys/exechdr.h> 29 #include <sys/elf.h> 30 #include <sys/elf_notes.h> 31 #include <sys/bootconf.h> 32 #include <sys/reboot.h> 33 #include <sys/fcntl.h> 34 #include <sys/stat.h> 35 #include <sys/modctl.h> 36 #include <sys/link.h> 37 #include <sys/auxv.h> 38 #include <sys/salib.h> 39 #include <sys/bootvfs.h> 40 #include <sys/platnames.h> 41 42 #include "util.h" 43 44 #ifdef BOOTAMD64 45 #include <amd64/amd64_page.h> 46 #endif /* BOOTAMD64 */ 47 48 union { 49 struct exec X; 50 Elf32_Ehdr Elfhdr; 51 Elf64_Ehdr Elfhdr64; 52 } ex; 53 54 #define x ex.X 55 #define elfhdr ex.Elfhdr 56 #define elfhdr64 ex.Elfhdr64 57 58 typedef int (*func_t)(); 59 60 #define FAIL ((func_t)-1) 61 #define ALIGN(x, a) \ 62 ((a) == 0 ? (uintptr_t)(x) : (((uintptr_t)(x) + (a) - 1) & ~((a) - 1))) 63 64 #define __BOOT_NAUXV_IMPL 22 65 66 int use_align = 0; 67 int npagesize = 0; 68 uint_t icache_flush = 0; 69 char *cpulist = NULL; 70 char *mmulist = NULL; 71 char *module_path; /* path for kernel modules */ 72 73 /* 74 * This file gets compiled in LP64 (for sun4u) and ILP32 models. 75 * For LP64 compilation, the "client" file we load and run may be LP64 or ILP32, 76 * and during bringup, the LP64 clients may have ELF32 headers. 77 */ 78 #ifdef _ELF64_SUPPORT 79 #ifndef BOOTAMD64 80 /* 81 * Bootstrap vector for ELF32 LP64 client - neither supported nor needed for 82 * AMD64 83 */ 84 Elf32_Boot *elfbootvecELF32_64; 85 #endif /* !BOOTAMD64 */ 86 87 Elf64_Boot *elfbootvecELF64; /* ELF bootstrap vector for Elf64 LP64 */ 88 89 #define OK ((func_t)0) 90 91 #define FAIL_READELF64 ((uint64_t)0) 92 #define FAIL_ILOAD64 ((Elf64_Addr)-1) 93 #endif /* _ELF64_SUPPORT */ 94 95 /* 96 * And by an ILP32 client. The non-sun4u/LP64 booters use these. 97 * Also, the sun4u booter must create this for ILP32 clients. 98 */ 99 Elf32_Boot *elfbootvec; /* ELF bootstrap vector normal ILP32 */ 100 101 /* 102 * Read in a Unix executable file and return its entry point. 103 * Handle the various a.out formats correctly. 104 * "fd" is the standalone file descriptor to read from. 105 * Print informative little messages if "print" is on. 106 * Returns -1 for errors. 107 */ 108 109 #ifdef DEBUG 110 static int debug = 1; 111 #else /* DEBUG */ 112 static int debug = 0; 113 #endif /* DEBUG */ 114 115 #define dprintf if (debug) printf 116 117 #ifdef _ELF64_SUPPORT 118 typedef struct { 119 uint_t a_type; 120 #ifdef BOOTAMD64 121 uint_t a_pad; /* needed to 8-byte align uint64_ts below for AMD64 */ 122 #endif /* BOOTAMD64 */ 123 union { 124 uint64_t a_val; 125 uint64_t a_ptr; 126 #ifndef BOOTAMD64 127 void (*a_fcn)(); /* XXX - UNUSED? */ 128 #endif /* !BOOTAMD64 */ 129 } a_un; 130 } auxv64_t; 131 132 #if defined(__sparcv9) 133 extern int client_isLP64; 134 #endif /* __sparcv9 */ 135 136 static uint64_t read_elf64(int, int, Elf64_Ehdr *); 137 static Elf64_Addr iload64(char *, Elf64_Phdr *, Elf64_Phdr *, auxv64_t **); 138 #endif /* _ELF64_SUPPORT */ 139 140 #if defined(i386) && !defined(_SYSCALL32) 141 typedef auxv_t auxv32_t; 142 #endif 143 144 static func_t read_elf32(int, int, Elf32_Ehdr *); 145 static func_t iload32(char *, Elf32_Phdr *, Elf32_Phdr *, auxv32_t **); 146 static caddr_t segbrk(caddr_t *, size_t, size_t); 147 static int openpath(char *, char *, int); 148 static char *getmodpath(char *); 149 extern void setup_aux(void); 150 151 extern void *kmem_alloc(size_t, int); 152 extern void kmem_free(void *, size_t); 153 extern int cons_gets(char *, int); 154 155 #ifdef BOOTAMD64 156 extern const char *amd64_getmmulist(void); 157 158 extern int amd64_elf64; 159 extern int is_amd64; 160 #endif /* BOOTAMD64 */ 161 162 #ifdef lint 163 /* 164 * This function is currently inlined 165 */ 166 /*ARGSUSED*/ 167 void 168 sync_instruction_memory(caddr_t v, size_t len) 169 {} 170 #else /* lint */ 171 extern void sync_instruction_memory(caddr_t v, size_t len); 172 #endif /* lint */ 173 174 extern int verbosemode; 175 extern int boothowto; 176 extern int pagesize; 177 extern char filename[]; 178 179 /* 180 * repeat reads (forever) until size of request is satisfied 181 * (Thus, you don't want to use this cases where short reads are ok) 182 */ 183 ssize_t 184 xread(int fd, char *p, size_t nbytes) 185 { 186 size_t bytesread = 0; 187 int errorcount = 0; 188 ssize_t i; 189 190 while (bytesread < nbytes) { 191 i = read(fd, p, nbytes - bytesread); 192 if (i < 0) { 193 ++errorcount; 194 if (verbosemode) 195 printf("read error (0x%x times)\n", errorcount); 196 continue; 197 } 198 bytesread += i; 199 p += i; 200 } 201 return (bytesread); 202 } 203 204 func_t 205 readfile(int fd, int print) 206 { 207 #ifdef _ELF64_SUPPORT 208 #ifdef BOOTAMD64 209 extern int bsetprop(struct bootops *, char *, void *, int); 210 extern struct bootops *bop; 211 extern uint64_t elf64_go2; 212 #else /* !BOOTAMD64 */ 213 uint64_t elf64_go2; 214 #endif /* BOOTAMD64 */ 215 #endif /* _ELF64_SUPPORT */ 216 217 ssize_t i; 218 int shared = 0; 219 220 if (verbosemode) { 221 dprintf("fd = %x\n", fd); 222 } 223 224 i = xread(fd, (char *)&elfhdr, sizeof (Elf64_Ehdr)); 225 if (x.a_magic == ZMAGIC || x.a_magic == NMAGIC) 226 shared = 1; 227 if (i != sizeof (Elf64_Ehdr)) { 228 printf("Error reading ELF header.\n"); 229 return (FAIL); 230 } 231 if (!shared && x.a_magic != OMAGIC) { 232 if (*(int *)&elfhdr.e_ident == *(int *)(ELFMAG)) { 233 if (verbosemode) { 234 int is64 = (elfhdr.e_ident[EI_CLASS] == 235 ELFCLASS64); 236 237 dprintf("calling readelf, elfheader is:\n"); 238 dprintf("e_ident\t0x%x, 0x%x, 0x%x, 0x%x\n", 239 *(int *)&elfhdr.e_ident[0], 240 *(int *)&elfhdr.e_ident[4], 241 *(int *)&elfhdr.e_ident[8], 242 *(int *)&elfhdr.e_ident[12]); 243 dprintf("e_machine\t0x%x\n", elfhdr.e_machine); 244 245 dprintf("e_entry\t\t0x%llx\n", (is64 ? 246 elfhdr64.e_entry : 247 (u_longlong_t)elfhdr.e_entry)); 248 dprintf("e_shoff\t\t0x%llx\n", (is64 ? 249 elfhdr64.e_shoff : 250 (u_longlong_t)elfhdr.e_shoff)); 251 dprintf("e_shnentsize\t%d\n", (is64 ? 252 elfhdr64.e_shentsize : elfhdr.e_shentsize)); 253 dprintf("e_shnum\t\t%d\n", (is64 ? 254 elfhdr64.e_shnum : elfhdr.e_shnum)); 255 dprintf("e_shstrndx\t%d\n", (is64 ? 256 elfhdr64.e_shstrndx : elfhdr.e_shstrndx)); 257 } 258 259 260 #ifdef _ELF64_SUPPORT 261 dprintf("ELF file CLASS 0x%x 32 is %x 64 is %x\n", 262 elfhdr.e_ident[EI_CLASS], ELFCLASS32, ELFCLASS64); 263 264 if (elfhdr.e_ident[EI_CLASS] == ELFCLASS64) { 265 #ifdef BOOTAMD64 266 if (elfhdr.e_machine != EM_AMD64) { 267 printf("FATAL: 64-bit ELF executable " 268 "not for AMD64\n (e_machine " 269 "= %d).\n", elfhdr.e_machine); 270 return (FAIL); 271 } 272 273 /* 274 * OK, we know the executable is for an AMD64 275 * CPU. Make sure we ARE an AMD64 CPU before 276 * proceeding. 277 */ 278 if (is_amd64 == 0) { 279 printf("FATAL: AMD64 executables not " 280 " supported on this CPU.\n"); 281 return (FAIL); 282 } 283 284 amd64_elf64 = (elfhdr.e_ident[EI_CLASS] == 285 ELFCLASS64); 286 #endif /* BOOTAMD64 */ 287 288 elf64_go2 = read_elf64(fd, print, 289 (Elf64_Ehdr *)&elfhdr); 290 291 #ifdef BOOTAMD64 292 if (elf64_go2 != FAIL_READELF64) 293 (void) bsetprop(bop, "mmu-modlist", 294 "mmu64", 0); 295 296 return ((elf64_go2 == FAIL_READELF64) ? FAIL : 297 OK); 298 #else /* !BOOTAMD64 */ 299 return ((elf64_go2 == FAIL_READELF64) ? FAIL : 300 (func_t)elf64_go2); 301 #endif /* BOOTAMD64 */ 302 303 } else 304 #endif /* _ELF64_SUPPORT */ 305 return (read_elf32(fd, print, &elfhdr)); 306 } else { 307 printf("File not executable.\n"); 308 return (FAIL); 309 } 310 } 311 return (FAIL); 312 } 313 314 /* 315 * Macros to add attribute/values to the ELF bootstrap vector 316 * and the aux vector. Use the type-cast to convert integers 317 * to pointers first to suppress the gcc warning. 318 */ 319 #define AUX(p, a, v) { (p)->a_type = (a); \ 320 ((p)++)->a_un.a_val = (int32_t)(uintptr_t)(v); } 321 322 #define EBV(p, a, v) { (p)->eb_tag = (a); \ 323 ((p)++)->eb_un.eb_val = (Elf32_Word)(uintptr_t)(v); } 324 325 static func_t 326 read_elf32(int fd, int print, Elf32_Ehdr *elfhdrp) 327 { 328 Elf32_Phdr *phdr; /* program header */ 329 Elf32_Nhdr *nhdr; /* note header */ 330 int nphdrs, phdrsize; 331 caddr_t allphdrs; 332 caddr_t namep, descp; 333 Elf32_Addr loadaddr, base; 334 size_t offset = 0; 335 size_t size; 336 uintptr_t off; 337 int i; 338 int bss_seen = 0; 339 int interp = 0; /* interpreter required */ 340 static char dlname[MAXPATHLEN]; /* name of interpeter */ 341 uint_t dynamic; /* dynamic tags array */ 342 Elf32_Phdr *thdr; /* "text" program header */ 343 Elf32_Phdr *dhdr; /* "data" program header */ 344 func_t entrypt; /* entry point of standalone */ 345 346 /* Initialize pointers so we won't free bogus ones on elferror */ 347 allphdrs = NULL; 348 nhdr = NULL; 349 350 #ifdef _ELF64_SUPPORT 351 if (verbosemode) 352 printf("Elf32 client\n"); 353 #endif /* _ELF64_SUPPORT */ 354 355 if (elfhdrp->e_phnum == 0 || elfhdrp->e_phoff == 0) 356 goto elferror; 357 358 /* use uintptr_t to suppress the gcc warning */ 359 entrypt = (func_t)(uintptr_t)elfhdrp->e_entry; 360 if (verbosemode) 361 dprintf("Entry point: %p\n", (void *)entrypt); 362 363 /* 364 * Allocate and read in all the program headers. 365 */ 366 nphdrs = elfhdrp->e_phnum; 367 phdrsize = nphdrs * elfhdrp->e_phentsize; 368 allphdrs = (caddr_t)kmem_alloc(phdrsize, 0); 369 if (allphdrs == NULL) 370 goto elferror; 371 if (verbosemode) 372 dprintf("lseek: args = %x %x %x\n", fd, elfhdrp->e_phoff, 0); 373 if (lseek(fd, elfhdrp->e_phoff, 0) == -1) 374 goto elferror; 375 if (xread(fd, allphdrs, phdrsize) != phdrsize) 376 goto elferror; 377 378 /* 379 * First look for PT_NOTE headers that tell us what pagesize to 380 * use in allocating program memory. 381 */ 382 npagesize = 0; 383 for (i = 0; i < nphdrs; i++) { 384 void *note_buf; 385 386 phdr = (Elf32_Phdr *)(allphdrs + elfhdrp->e_phentsize * i); 387 if (phdr->p_type != PT_NOTE) 388 continue; 389 if (verbosemode) { 390 dprintf("allocating 0x%x bytes for note hdr\n", 391 phdr->p_filesz); 392 } 393 if ((note_buf = kmem_alloc(phdr->p_filesz, 0)) == NULL) 394 goto elferror; 395 if (verbosemode) 396 dprintf("seeking to 0x%x\n", phdr->p_offset); 397 if (lseek(fd, phdr->p_offset, 0) == -1) 398 goto elferror; 399 if (verbosemode) { 400 dprintf("reading 0x%x bytes into %p\n", 401 phdr->p_filesz, (void *)nhdr); 402 } 403 nhdr = (Elf32_Nhdr *)note_buf; 404 if (xread(fd, (caddr_t)nhdr, phdr->p_filesz) != phdr->p_filesz) 405 goto elferror; 406 if (verbosemode) { 407 dprintf("p_note namesz %x descsz %x type %x\n", 408 nhdr->n_namesz, nhdr->n_descsz, nhdr->n_type); 409 } 410 411 /* 412 * Iterate through all ELF PT_NOTE elements looking for 413 * ELF_NOTE_SOLARIS which, if present, will specify the 414 * executable's preferred pagesize. 415 */ 416 do { 417 namep = (caddr_t)(nhdr + 1); 418 419 if (nhdr->n_namesz == strlen(ELF_NOTE_SOLARIS) + 1 && 420 strcmp(namep, ELF_NOTE_SOLARIS) == 0 && 421 nhdr->n_type == ELF_NOTE_PAGESIZE_HINT) { 422 descp = namep + roundup(nhdr->n_namesz, 4); 423 npagesize = *(int *)descp; 424 if (verbosemode) 425 dprintf("pagesize is %x\n", npagesize); 426 } 427 428 offset += sizeof (Elf32_Nhdr) + roundup(nhdr->n_namesz, 429 4) + roundup(nhdr->n_descsz, 4); 430 431 nhdr = (Elf32_Nhdr *)((char *)note_buf + offset); 432 } while (offset < phdr->p_filesz); 433 434 kmem_free(note_buf, phdr->p_filesz); 435 nhdr = NULL; 436 } 437 438 /* 439 * Next look for PT_LOAD headers to read in. 440 */ 441 if (print) 442 printf("Size: "); 443 for (i = 0; i < nphdrs; i++) { 444 phdr = (Elf32_Phdr *)(allphdrs + elfhdrp->e_phentsize * i); 445 if (verbosemode) { 446 dprintf("Doing header 0x%x\n", i); 447 dprintf("phdr\n"); 448 dprintf("\tp_offset = %x, p_vaddr = %x\n", 449 phdr->p_offset, phdr->p_vaddr); 450 dprintf("\tp_memsz = %x, p_filesz = %x\n", 451 phdr->p_memsz, phdr->p_filesz); 452 } 453 if (phdr->p_type == PT_LOAD) { 454 if (verbosemode) 455 dprintf("seeking to 0x%x\n", phdr->p_offset); 456 if (lseek(fd, phdr->p_offset, 0) == -1) 457 goto elferror; 458 459 if (phdr->p_flags == (PF_R | PF_W) && 460 phdr->p_vaddr == 0) { 461 /* 462 * It's a PT_LOAD segment that is RW but 463 * not executable and has a vaddr 464 * of zero. This is relocation info that 465 * doesn't need to stick around after 466 * krtld is done with it. We allocate boot 467 * memory for this segment, since we don't want 468 * it mapped in permanently as part of 469 * the kernel image. 470 */ 471 if ((loadaddr = (uintptr_t) 472 kmem_alloc(phdr->p_memsz, 0)) == NULL) 473 goto elferror; 474 /* 475 * Save this to pass on 476 * to the interpreter. 477 */ 478 phdr->p_vaddr = (Elf32_Addr)loadaddr; 479 } else { 480 if (print) 481 printf("0x%x+", phdr->p_filesz); 482 /* 483 * If we found a new pagesize above, use it 484 * to adjust the memory allocation. 485 */ 486 loadaddr = phdr->p_vaddr; 487 if (use_align && npagesize != 0) { 488 off = loadaddr & (npagesize - 1); 489 size = roundup(phdr->p_memsz + off, 490 npagesize); 491 base = loadaddr - off; 492 } else { 493 npagesize = 0; 494 size = phdr->p_memsz; 495 base = loadaddr; 496 } 497 /* 498 * Check if it's text or data. 499 */ 500 if (phdr->p_flags & PF_W) 501 dhdr = phdr; 502 else 503 thdr = phdr; 504 505 /* 506 * If memory size is zero just ignore this 507 * header. 508 */ 509 if (size == 0) 510 continue; 511 512 if (verbosemode) 513 dprintf("allocating memory: %x %lx " 514 "%x\n", base, size, npagesize); 515 /* 516 * We're all set up to read. 517 * Now let's allocate some memory. 518 */ 519 520 #ifdef i386 521 /* 522 * If vaddr == paddr and npagesize is 0, that 523 * means the executable needs to be identity 524 * mapped in memory (va == pa, mapped 1:1) 525 * 526 * Otherwise load as usual. 527 */ 528 if ((phdr->p_vaddr == phdr->p_paddr) && 529 (npagesize == 0)) { 530 extern caddr_t idmap_mem(uint32_t, 531 size_t, int); 532 533 uint_t n; 534 535 n = (uint_t)base & (pagesize - 1); 536 if (n) { 537 base -= n; 538 size += n; 539 } 540 541 if (!idmap_mem((uint32_t)base, 542 (size_t)size, pagesize)) 543 goto elferror; 544 } else 545 #endif /* i386 */ 546 /* use uintptr_t to suppress the gcc warning */ 547 if (get_progmemory((caddr_t)(uintptr_t)base, 548 size, npagesize)) 549 goto elferror; 550 } 551 552 if (verbosemode) { 553 dprintf("reading 0x%x bytes into 0x%x\n", 554 phdr->p_filesz, loadaddr); 555 } 556 /* use uintptr_t to suppress the gcc warning */ 557 if (xread(fd, (caddr_t)(uintptr_t)loadaddr, 558 phdr->p_filesz) != phdr->p_filesz) 559 goto elferror; 560 561 /* zero out BSS */ 562 if (phdr->p_memsz > phdr->p_filesz) { 563 loadaddr += phdr->p_filesz; 564 if (verbosemode) { 565 dprintf("bss from 0x%x size 0x%x\n", 566 loadaddr, 567 phdr->p_memsz - phdr->p_filesz); 568 } 569 /* use uintptr_t to suppress the gcc warning */ 570 bzero((void *)(uintptr_t)loadaddr, 571 phdr->p_memsz - phdr->p_filesz); 572 bss_seen++; 573 if (print) 574 printf("0x%x Bytes\n", 575 phdr->p_memsz - phdr->p_filesz); 576 } 577 578 /* force instructions to be visible to icache */ 579 if (phdr->p_flags & PF_X) { 580 sync_instruction_memory( 581 (caddr_t)(uintptr_t)phdr->p_vaddr, 582 phdr->p_memsz); 583 } 584 } else if (phdr->p_type == PT_INTERP) { 585 /* 586 * Dynamically-linked executable. 587 */ 588 interp = 1; 589 if (lseek(fd, phdr->p_offset, 0) == -1) { 590 goto elferror; 591 } 592 /* 593 * Get the name of the interpreter. 594 */ 595 if (xread(fd, dlname, phdr->p_filesz) != 596 phdr->p_filesz || 597 dlname[phdr->p_filesz - 1] != '\0') 598 goto elferror; 599 } else if (phdr->p_type == PT_DYNAMIC) { 600 dynamic = phdr->p_vaddr; 601 } 602 } 603 604 if (!bss_seen && print) 605 printf("0 Bytes\n"); 606 607 /* 608 * Load the interpreter 609 * if there is one. 610 */ 611 if (interp) { 612 Elf32_Boot bootv[EB_MAX]; /* Bootstrap vector */ 613 auxv32_t auxv[__BOOT_NAUXV_IMPL]; /* Aux vector */ 614 Elf32_Boot *bv = bootv; 615 auxv32_t *av = auxv; 616 size_t vsize; 617 618 /* 619 * Load it. 620 */ 621 if ((entrypt = iload32(dlname, thdr, dhdr, &av)) == FAIL) 622 goto elferror; 623 /* 624 * Build bootstrap and aux vectors. 625 */ 626 setup_aux(); 627 EBV(bv, EB_AUXV, 0); /* fill in later */ 628 EBV(bv, EB_PAGESIZE, pagesize); 629 EBV(bv, EB_DYNAMIC, dynamic); 630 EBV(bv, EB_NULL, 0); 631 632 AUX(av, AT_BASE, entrypt); 633 AUX(av, AT_ENTRY, elfhdrp->e_entry); 634 AUX(av, AT_PAGESZ, pagesize); 635 AUX(av, AT_PHDR, allphdrs); 636 AUX(av, AT_PHNUM, elfhdrp->e_phnum); 637 AUX(av, AT_PHENT, elfhdrp->e_phentsize); 638 if (use_align) 639 AUX(av, AT_SUN_LPAGESZ, npagesize); 640 AUX(av, AT_SUN_IFLUSH, icache_flush); 641 if (cpulist != NULL) 642 AUX(av, AT_SUN_CPU, cpulist); 643 if (mmulist != NULL) 644 AUX(av, AT_SUN_MMU, mmulist); 645 AUX(av, AT_NULL, 0); 646 /* 647 * Realloc vectors and copy them. 648 */ 649 vsize = (caddr_t)bv - (caddr_t)bootv; 650 if ((elfbootvec = (Elf32_Boot *)kmem_alloc(vsize, 0)) == NULL) 651 goto elferror; 652 bcopy((char *)bootv, (char *)elfbootvec, vsize); 653 654 size = (caddr_t)av - (caddr_t)auxv; 655 if (size > sizeof (auxv)) { 656 printf("readelf: overrun of available aux vectors\n"); 657 kmem_free(elfbootvec, vsize); 658 goto elferror; 659 } 660 /* use uintptr_t to suppress the gcc warning */ 661 if ((elfbootvec->eb_un.eb_ptr = 662 (Elf32_Addr)(uintptr_t)kmem_alloc(size, 0)) == NULL) { 663 kmem_free(elfbootvec, vsize); 664 goto elferror; 665 } 666 /* use uintptr_t to suppress the gcc warning */ 667 bcopy(auxv, 668 (void *)(uintptr_t)(elfbootvec->eb_un.eb_ptr), size); 669 670 #if defined(_ELF64_SUPPORT) && !defined(BOOTAMD64) 671 /* 672 * Make an LP64 copy of the vector for use by 64-bit standalones 673 * even if they have ELF32. 674 */ 675 if ((elfbootvecELF32_64 = (Elf32_Boot *)kmem_alloc(vsize, 0)) 676 == NULL) 677 goto elferror; 678 bcopy(bootv, elfbootvecELF32_64, vsize); 679 680 size = (av - auxv) * sizeof (auxv64_t); 681 /* use uintptr_t to suppress the gcc warning */ 682 if ((elfbootvecELF32_64->eb_un.eb_ptr = 683 (Elf32_Addr)(uintptr_t)kmem_alloc(size, 0)) == NULL) { 684 kmem_free(elfbootvecELF32_64, vsize); 685 goto elferror; 686 } else { 687 auxv64_t *a64 = 688 (auxv64_t *)(uintptr_t) 689 elfbootvecELF32_64->eb_un.eb_ptr; 690 auxv32_t *a = auxv; 691 692 for (a = auxv; a < av; a++) { 693 a64->a_type = a->a_type; 694 a64->a_un.a_val = a->a_un.a_val; 695 a64++; 696 } 697 } 698 #endif /* _ELF64_SUPPORT && !BOOTAMD64 */ 699 } else { 700 kmem_free(allphdrs, phdrsize); 701 } 702 return (entrypt); 703 704 elferror: 705 if (allphdrs != NULL) 706 kmem_free(allphdrs, phdrsize); 707 if (nhdr != NULL) 708 kmem_free(nhdr, phdr->p_filesz); 709 printf("Elf32 read error.\n"); 710 return (FAIL); 711 } 712 713 #ifdef _ELF64_SUPPORT 714 /* 715 * Macros to add attribute/values to the ELF bootstrap vector 716 * and the aux vector. 717 */ 718 #define AUX64(p, a, v) { (p)->a_type = (a); \ 719 ((p)++)->a_un.a_val = (uint64_t)(v); } 720 721 #define EBV64(p, a, v) { (p)->eb_tag = (a); \ 722 ((p)++)->eb_un.eb_val = (Elf64_Xword)(v); } 723 724 static uint64_t 725 read_elf64(int fd, int print, Elf64_Ehdr *elfhdrp) 726 { 727 Elf64_Phdr *phdr; /* program header */ 728 Elf64_Nhdr *nhdr; /* note header */ 729 int nphdrs, phdrsize; 730 caddr_t allphdrs; 731 caddr_t namep, descp; 732 Elf64_Addr loadaddr, base; 733 size_t offset = 0; 734 size_t size; 735 int i; 736 uintptr_t off; 737 int bss_seen = 0; 738 int interp = 0; /* interpreter required */ 739 static char dlname[MAXPATHLEN]; /* name of interpeter */ 740 uintptr_t dynamic; /* dynamic tags array */ 741 Elf64_Phdr *thdr; /* "text" program header */ 742 Elf64_Phdr *dhdr; /* "data" program header */ 743 Elf64_Addr entrypt; /* entry point of standalone */ 744 745 /* Initialize pointers so we won't free bogus ones on elf64error */ 746 allphdrs = NULL; 747 nhdr = NULL; 748 #if defined(__sparcv9) 749 client_isLP64 = 1; 750 #endif /* __sparcv9 */ 751 752 if (verbosemode) 753 printf("Elf64 client\n"); 754 755 if (elfhdrp->e_phnum == 0 || elfhdrp->e_phoff == 0) 756 goto elf64error; 757 758 entrypt = elfhdrp->e_entry; 759 if (verbosemode) 760 dprintf("Entry point: 0x%llx\n", (u_longlong_t)entrypt); 761 762 /* 763 * Allocate and read in all the program headers. 764 */ 765 nphdrs = elfhdrp->e_phnum; 766 phdrsize = nphdrs * elfhdrp->e_phentsize; 767 allphdrs = (caddr_t)kmem_alloc(phdrsize, 0); 768 if (allphdrs == NULL) 769 goto elf64error; 770 if (verbosemode) 771 dprintf("lseek: args = %x %llx %x\n", fd, 772 (u_longlong_t)elfhdrp->e_phoff, 0); 773 if (lseek(fd, elfhdrp->e_phoff, 0) == -1) 774 goto elf64error; 775 if (xread(fd, allphdrs, phdrsize) != phdrsize) 776 goto elf64error; 777 778 /* 779 * First look for PT_NOTE headers that tell us what pagesize to 780 * use in allocating program memory. 781 */ 782 npagesize = 0; 783 for (i = 0; i < nphdrs; i++) { 784 void *note_buf; 785 786 phdr = (Elf64_Phdr *)(allphdrs + elfhdrp->e_phentsize * i); 787 if (phdr->p_type != PT_NOTE) 788 continue; 789 if (verbosemode) { 790 dprintf("allocating 0x%llx bytes for note hdr\n", 791 (u_longlong_t)phdr->p_filesz); 792 } 793 if ((note_buf = kmem_alloc(phdr->p_filesz, 0)) == NULL) 794 goto elf64error; 795 if (verbosemode) 796 dprintf("seeking to 0x%llx\n", 797 (u_longlong_t)phdr->p_offset); 798 if (lseek(fd, phdr->p_offset, 0) == -1) 799 goto elf64error; 800 if (verbosemode) { 801 dprintf("reading 0x%llx bytes into 0x%p\n", 802 (u_longlong_t)phdr->p_filesz, (void *)nhdr); 803 } 804 nhdr = (Elf64_Nhdr *)note_buf; 805 if (xread(fd, (caddr_t)nhdr, phdr->p_filesz) != phdr->p_filesz) 806 goto elf64error; 807 if (verbosemode) { 808 dprintf("p_note namesz %x descsz %x type %x\n", 809 nhdr->n_namesz, nhdr->n_descsz, nhdr->n_type); 810 } 811 812 /* 813 * Iterate through all ELF PT_NOTE elements looking for 814 * ELF_NOTE_SOLARIS which, if present, will specify the 815 * executable's preferred pagesize. 816 */ 817 do { 818 namep = (caddr_t)(nhdr + 1); 819 820 if (nhdr->n_namesz == strlen(ELF_NOTE_SOLARIS) + 1 && 821 strcmp(namep, ELF_NOTE_SOLARIS) == 0 && 822 nhdr->n_type == ELF_NOTE_PAGESIZE_HINT) { 823 descp = namep + roundup(nhdr->n_namesz, 4); 824 npagesize = *(int *)descp; 825 if (verbosemode) 826 dprintf("pagesize is %x\n", npagesize); 827 } 828 829 offset += sizeof (Elf64_Nhdr) + roundup(nhdr->n_namesz, 830 4) + roundup(nhdr->n_descsz, 4); 831 832 nhdr = (Elf64_Nhdr *)((char *)note_buf + offset); 833 } while (offset < phdr->p_filesz); 834 835 kmem_free(note_buf, phdr->p_filesz); 836 nhdr = NULL; 837 } 838 839 /* 840 * Next look for PT_LOAD headers to read in. 841 */ 842 if (print) 843 printf("Size: "); 844 for (i = 0; i < nphdrs; i++) { 845 phdr = (Elf64_Phdr *)(allphdrs + elfhdrp->e_phentsize * i); 846 if (verbosemode) { 847 dprintf("Doing header 0x%x\n", i); 848 dprintf("phdr\n"); 849 dprintf("\tp_offset = %llx, p_vaddr = %llx\n", 850 (u_longlong_t)phdr->p_offset, 851 (u_longlong_t)phdr->p_vaddr); 852 dprintf("\tp_memsz = %llx, p_filesz = %llx\n", 853 (u_longlong_t)phdr->p_memsz, 854 (u_longlong_t)phdr->p_filesz); 855 dprintf("\tp_type = %x, p_flags = %x\n", 856 phdr->p_type, phdr->p_flags); 857 } 858 if (phdr->p_type == PT_LOAD) { 859 if (verbosemode) 860 dprintf("seeking to 0x%llx\n", 861 (u_longlong_t)phdr->p_offset); 862 if (lseek(fd, phdr->p_offset, 0) == -1) 863 goto elf64error; 864 865 if (phdr->p_flags == (PF_R | PF_W) && 866 phdr->p_vaddr == 0) { 867 /* 868 * It's a PT_LOAD segment that is RW but 869 * not executable and has a vaddr 870 * of zero. This is relocation info that 871 * doesn't need to stick around after 872 * krtld is done with it. We allocate boot 873 * memory for this segment, since we don't want 874 * it mapped in permanently as part of 875 * the kernel image. 876 */ 877 #ifdef BOOTAMD64 878 if ((loadaddr = (Elf64_Addr) 879 (ADDR_XTND(kmem_alloc(phdr->p_memsz, 0)))) 880 == NULL) 881 #else /* !BOOTAMD64 */ 882 if ((loadaddr = (Elf64_Addr)(uintptr_t) 883 kmem_alloc(phdr->p_memsz, 0)) == NULL) 884 #endif /* BOOTAMD64 */ 885 goto elf64error; 886 887 /* 888 * Save this to pass on 889 * to the interpreter. 890 */ 891 phdr->p_vaddr = loadaddr; 892 } else { 893 if (print) 894 printf("0x%llx+", 895 (u_longlong_t)phdr->p_filesz); 896 /* 897 * If we found a new pagesize above, use it 898 * to adjust the memory allocation. 899 */ 900 loadaddr = phdr->p_vaddr; 901 if (use_align && npagesize != 0) { 902 off = loadaddr & (npagesize - 1); 903 size = roundup(phdr->p_memsz + off, 904 npagesize); 905 base = loadaddr - off; 906 } else { 907 npagesize = 0; 908 size = phdr->p_memsz; 909 base = loadaddr; 910 } 911 /* 912 * Check if it's text or data. 913 */ 914 if (phdr->p_flags & PF_W) 915 dhdr = phdr; 916 else 917 thdr = phdr; 918 919 if (verbosemode) 920 dprintf( 921 "allocating memory: %llx %lx %x\n", 922 (u_longlong_t)base, 923 size, npagesize); 924 925 /* 926 * If memory size is zero just ignore this 927 * header. 928 */ 929 if (size == 0) 930 continue; 931 932 /* 933 * We're all set up to read. 934 * Now let's allocate some memory. 935 */ 936 if (get_progmemory((caddr_t)(uintptr_t)base, 937 size, npagesize)) 938 goto elf64error; 939 } 940 941 if (verbosemode) { 942 dprintf("reading 0x%llx bytes into 0x%llx\n", 943 (u_longlong_t)phdr->p_filesz, 944 (u_longlong_t)loadaddr); 945 } 946 if (xread(fd, (caddr_t)(uintptr_t) 947 loadaddr, phdr->p_filesz) != phdr->p_filesz) 948 goto elf64error; 949 950 /* zero out BSS */ 951 if (phdr->p_memsz > phdr->p_filesz) { 952 loadaddr += phdr->p_filesz; 953 if (verbosemode) { 954 dprintf("bss from 0x%llx size 0x%llx\n", 955 (u_longlong_t)loadaddr, 956 (u_longlong_t)(phdr->p_memsz - 957 phdr->p_filesz)); 958 } 959 960 bzero((caddr_t)(uintptr_t)loadaddr, 961 phdr->p_memsz - phdr->p_filesz); 962 bss_seen++; 963 if (print) 964 printf("0x%llx Bytes\n", 965 (u_longlong_t)(phdr->p_memsz - 966 phdr->p_filesz)); 967 } 968 969 /* force instructions to be visible to icache */ 970 if (phdr->p_flags & PF_X) 971 sync_instruction_memory((caddr_t)(uintptr_t) 972 phdr->p_vaddr, phdr->p_memsz); 973 974 } else if (phdr->p_type == PT_INTERP) { 975 /* 976 * Dynamically-linked executable. 977 */ 978 interp = 1; 979 if (lseek(fd, phdr->p_offset, 0) == -1) { 980 goto elf64error; 981 } 982 /* 983 * Get the name of the interpreter. 984 */ 985 if (xread(fd, dlname, phdr->p_filesz) != 986 phdr->p_filesz || 987 dlname[phdr->p_filesz - 1] != '\0') 988 goto elf64error; 989 } else if (phdr->p_type == PT_DYNAMIC) { 990 dynamic = phdr->p_vaddr; 991 } 992 } 993 994 if (!bss_seen && print) 995 printf("0 Bytes\n"); 996 997 /* 998 * Load the interpreter 999 * if there is one. 1000 */ 1001 if (interp) { 1002 Elf64_Boot bootv[EB_MAX]; /* Bootstrap vector */ 1003 auxv64_t auxv[__BOOT_NAUXV_IMPL]; /* Aux vector */ 1004 Elf64_Boot *bv = bootv; 1005 auxv64_t *av = auxv; 1006 size_t vsize; 1007 1008 /* 1009 * Load it. 1010 */ 1011 if ((entrypt = iload64(dlname, thdr, dhdr, &av)) == 1012 FAIL_ILOAD64) 1013 goto elf64error; 1014 /* 1015 * Build bootstrap and aux vectors. 1016 */ 1017 setup_aux(); 1018 EBV64(bv, EB_AUXV, 0); /* fill in later */ 1019 EBV64(bv, EB_PAGESIZE, pagesize); 1020 EBV64(bv, EB_DYNAMIC, dynamic); 1021 EBV64(bv, EB_NULL, 0); 1022 1023 AUX64(av, AT_BASE, entrypt); 1024 AUX64(av, AT_ENTRY, elfhdrp->e_entry); 1025 AUX64(av, AT_PAGESZ, pagesize); 1026 AUX64(av, AT_PHDR, (uintptr_t)allphdrs); 1027 AUX64(av, AT_PHNUM, elfhdrp->e_phnum); 1028 AUX64(av, AT_PHENT, elfhdrp->e_phentsize); 1029 if (npagesize) 1030 AUX64(av, AT_SUN_LPAGESZ, npagesize); 1031 1032 #ifdef BOOTAMD64 1033 vsize = strlen(amd64_getmmulist()) + 1; 1034 if ((mmulist = kmem_alloc(vsize, 0)) == NULL) 1035 goto elf64error; 1036 1037 bcopy(amd64_getmmulist(), mmulist, vsize); 1038 AUX64(av, AT_SUN_MMU, (uintptr_t)mmulist); 1039 #endif /* BOOTAMD64 */ 1040 1041 AUX64(av, AT_SUN_IFLUSH, icache_flush); 1042 if (cpulist != NULL) 1043 AUX64(av, AT_SUN_CPU, (uintptr_t)cpulist); 1044 AUX64(av, AT_NULL, 0); 1045 /* 1046 * Realloc vectors and copy them. 1047 */ 1048 vsize = (caddr_t)bv - (caddr_t)bootv; 1049 if ((elfbootvecELF64 = 1050 (Elf64_Boot *)kmem_alloc(vsize, 0)) == NULL) 1051 goto elf64error; 1052 bcopy((char *)bootv, (char *)elfbootvecELF64, vsize); 1053 1054 size = (caddr_t)av - (caddr_t)auxv; 1055 if (size > sizeof (auxv)) { 1056 printf("readelf: overrun of available aux vectors\n"); 1057 kmem_free(elfbootvecELF64, vsize); 1058 goto elf64error; 1059 } 1060 1061 #ifdef BOOTAMD64 1062 if ((elfbootvecELF64->eb_un.eb_ptr = 1063 ADDR_XTND(kmem_alloc(size, 0))) == NULL) { 1064 kmem_free(elfbootvecELF64, vsize); 1065 goto elf64error; 1066 } 1067 1068 bcopy((char *)auxv, 1069 (char *)ADDR_TRUNC((elfbootvecELF64->eb_un.eb_ptr)), size); 1070 #else /* !BOOTAMD64 */ 1071 if ((elfbootvecELF64->eb_un.eb_ptr = 1072 (Elf64_Addr)kmem_alloc(size, 0)) == NULL) { 1073 kmem_free(elfbootvecELF64, vsize); 1074 goto elf64error; 1075 } 1076 1077 bcopy((char *)auxv, (char *)(elfbootvecELF64->eb_un.eb_ptr), 1078 size); 1079 #endif /* BOOTAMD64 */ 1080 } else { 1081 kmem_free(allphdrs, phdrsize); 1082 } 1083 return ((uint64_t)entrypt); 1084 1085 elf64error: 1086 if (allphdrs != NULL) 1087 kmem_free(allphdrs, phdrsize); 1088 if (nhdr != NULL) 1089 kmem_free(nhdr, phdr->p_filesz); 1090 printf("Elf64 read error.\n"); 1091 return (FAIL_READELF64); 1092 } 1093 #endif /* _ELF64_SUPPORT */ 1094 1095 /* 1096 * Load the interpreter. It expects a 1097 * relocatable .o capable of bootstrapping 1098 * itself. 1099 */ 1100 static func_t 1101 iload32(char *rtld, Elf32_Phdr *thdr, Elf32_Phdr *dhdr, auxv32_t **avp) 1102 { 1103 Elf32_Ehdr *ehdr = NULL; 1104 uintptr_t dl_entry = 0; 1105 uint_t i; 1106 int fd; 1107 int size; 1108 caddr_t shdrs = NULL; 1109 caddr_t etext, edata; 1110 1111 /* use uintptr_t to suppress the gcc warning */ 1112 etext = (caddr_t)(uintptr_t)thdr->p_vaddr + thdr->p_memsz; 1113 edata = (caddr_t)(uintptr_t)dhdr->p_vaddr + dhdr->p_memsz; 1114 1115 /* 1116 * Get the module path. 1117 */ 1118 module_path = getmodpath(filename); 1119 1120 if ((fd = openpath(module_path, rtld, O_RDONLY)) < 0) { 1121 printf("boot: cannot find %s\n", rtld); 1122 goto errorx; 1123 } 1124 dprintf("Opened %s OK\n", rtld); 1125 AUX(*avp, AT_SUN_LDNAME, rtld); 1126 /* 1127 * Allocate and read the ELF header. 1128 */ 1129 if ((ehdr = (Elf32_Ehdr *)kmem_alloc(sizeof (Elf32_Ehdr), 0)) == NULL) { 1130 printf("boot: alloc error reading ELF header (%s).\n", rtld); 1131 goto error; 1132 } 1133 1134 if (xread(fd, (char *)ehdr, sizeof (*ehdr)) != sizeof (*ehdr)) { 1135 printf("boot: error reading ELF header (%s).\n", rtld); 1136 goto error; 1137 } 1138 1139 size = ehdr->e_shentsize * ehdr->e_shnum; 1140 if ((shdrs = (caddr_t)kmem_alloc(size, 0)) == NULL) { 1141 printf("boot: alloc error reading ELF header (%s).\n", rtld); 1142 goto error; 1143 } 1144 /* 1145 * Read the section headers. 1146 */ 1147 if (lseek(fd, ehdr->e_shoff, 0) == -1 || 1148 xread(fd, shdrs, size) != size) { 1149 printf("boot: error reading section headers\n"); 1150 goto error; 1151 } 1152 AUX(*avp, AT_SUN_LDELF, ehdr); 1153 AUX(*avp, AT_SUN_LDSHDR, shdrs); 1154 /* 1155 * Load sections into the appropriate dynamic segment. 1156 */ 1157 for (i = 1; i < ehdr->e_shnum; i++) { 1158 Elf32_Shdr *sp; 1159 caddr_t *spp; 1160 caddr_t load; 1161 1162 sp = (Elf32_Shdr *)(shdrs + (i*ehdr->e_shentsize)); 1163 /* 1164 * If it's not allocated and not required 1165 * to do relocation, skip it. 1166 */ 1167 if (!(sp->sh_flags & SHF_ALLOC) && 1168 #ifdef i386 1169 sp->sh_type != SHT_REL && 1170 #else 1171 sp->sh_type != SHT_RELA && 1172 #endif 1173 sp->sh_type != SHT_SYMTAB && 1174 sp->sh_type != SHT_STRTAB) 1175 continue; 1176 /* 1177 * If the section is read-only, 1178 * it goes in as text. 1179 */ 1180 spp = (sp->sh_flags & SHF_WRITE)? &edata: &etext; 1181 /* 1182 * Make some room for it. 1183 */ 1184 load = segbrk(spp, sp->sh_size, sp->sh_addralign); 1185 if (load == NULL) { 1186 printf("boot: allocating memory for sections failed\n"); 1187 goto error; 1188 } 1189 /* 1190 * Compute the entry point of the linker. 1191 */ 1192 if (dl_entry == 0 && 1193 !(sp->sh_flags & SHF_WRITE) && 1194 (sp->sh_flags & SHF_EXECINSTR)) { 1195 dl_entry = (uintptr_t)load + ehdr->e_entry; 1196 } 1197 /* 1198 * If it's bss, just zero it out. 1199 */ 1200 if (sp->sh_type == SHT_NOBITS) { 1201 bzero(load, sp->sh_size); 1202 } else { 1203 /* 1204 * Read the section contents. 1205 */ 1206 if (lseek(fd, sp->sh_offset, 0) == -1 || 1207 xread(fd, load, sp->sh_size) != sp->sh_size) { 1208 printf("boot: error reading sections\n"); 1209 goto error; 1210 } 1211 } 1212 /* 1213 * Assign the section's virtual addr. Use uintptr_t to 1214 * suppress the gcc warning. 1215 */ 1216 sp->sh_addr = (Elf32_Off)(uintptr_t)load; 1217 /* 1218 * Force instructions to be visible to icache. Use 1219 * uintptr_t to suppress the gcc warning as well. 1220 */ 1221 if (sp->sh_flags & SHF_EXECINSTR) 1222 sync_instruction_memory((caddr_t)(uintptr_t)sp->sh_addr, 1223 sp->sh_size); 1224 } 1225 /* 1226 * Update sizes of segments. 1227 */ 1228 thdr->p_memsz = (Elf32_Word)((uintptr_t)etext - thdr->p_vaddr); 1229 dhdr->p_memsz = (Elf32_Word)((uintptr_t)edata - dhdr->p_vaddr); 1230 1231 /* load and relocate symbol tables in SAS */ 1232 (void) close(fd); 1233 return ((func_t)dl_entry); 1234 1235 error: 1236 (void) close(fd); 1237 errorx: 1238 if (ehdr) 1239 kmem_free(ehdr, sizeof (Elf32_Ehdr)); 1240 if (shdrs) 1241 kmem_free(shdrs, size); 1242 printf("boot: error loading interpreter (%s)\n", rtld); 1243 return (FAIL); 1244 } 1245 1246 #ifdef _ELF64_SUPPORT 1247 /* 1248 * Load the interpreter. It expects a 1249 * relocatable .o capable of bootstrapping 1250 * itself. 1251 */ 1252 static Elf64_Addr 1253 iload64(char *rtld, Elf64_Phdr *thdr, Elf64_Phdr *dhdr, auxv64_t **avp) 1254 { 1255 Elf64_Ehdr *ehdr = NULL; 1256 Elf64_Addr dl_entry = (Elf64_Addr)0; 1257 Elf64_Addr etext, edata; 1258 uint_t i; 1259 int fd; 1260 int size; 1261 caddr_t shdrs = NULL; 1262 1263 etext = thdr->p_vaddr + thdr->p_memsz; 1264 edata = dhdr->p_vaddr + dhdr->p_memsz; 1265 1266 /* 1267 * Get the module path. 1268 */ 1269 module_path = getmodpath(filename); 1270 1271 if ((fd = openpath(module_path, rtld, O_RDONLY)) < 0) { 1272 printf("boot: cannot find %s\n", rtld); 1273 goto errorx; 1274 } 1275 dprintf("Opened %s OK\n", rtld); 1276 AUX64(*avp, AT_SUN_LDNAME, (uintptr_t)rtld); 1277 /* 1278 * Allocate and read the ELF header. 1279 */ 1280 #ifdef BOOTAMD64 1281 if ((ehdr = (Elf64_Ehdr *)(uintptr_t)kmem_alloc(sizeof (Elf64_Ehdr), 1282 0)) == NULL) { 1283 #else /* !BOOTAMD64 */ 1284 if ((ehdr = (Elf64_Ehdr *)kmem_alloc(sizeof (Elf64_Ehdr), 0)) == NULL) { 1285 #endif /* BOOTAMD64 */ 1286 printf("boot: alloc error reading ELF header (%s).\n", rtld); 1287 goto error; 1288 } 1289 1290 if (xread(fd, (char *)ehdr, sizeof (*ehdr)) != sizeof (*ehdr)) { 1291 printf("boot: error reading ELF header (%s).\n", rtld); 1292 goto error; 1293 } 1294 1295 size = ehdr->e_shentsize * ehdr->e_shnum; 1296 if ((shdrs = (caddr_t)kmem_alloc(size, 0)) == NULL) { 1297 printf("boot: alloc error reading ELF header (%s).\n", rtld); 1298 goto error; 1299 } 1300 /* 1301 * Read the section headers. 1302 */ 1303 if (lseek(fd, ehdr->e_shoff, 0) == -1 || 1304 xread(fd, shdrs, size) != size) { 1305 printf("boot: error reading section headers\n"); 1306 goto error; 1307 } 1308 1309 #ifdef BOOTAMD64 1310 AUX64(*avp, AT_SUN_LDELF, (uintptr_t)ehdr); 1311 AUX64(*avp, AT_SUN_LDSHDR, (uintptr_t)shdrs); 1312 #else /* !BOOTAMD64 */ 1313 AUX64(*avp, AT_SUN_LDELF, ehdr); 1314 AUX64(*avp, AT_SUN_LDSHDR, shdrs); 1315 #endif /* BOOTAMD64 */ 1316 1317 /* 1318 * Load sections into the appropriate dynamic segment. 1319 */ 1320 for (i = 1; i < ehdr->e_shnum; i++) { 1321 Elf64_Shdr *sp; 1322 Elf64_Addr *spp, load; 1323 1324 sp = (Elf64_Shdr *)(shdrs + (i*ehdr->e_shentsize)); 1325 /* 1326 * If it's not allocated and not required 1327 * to do relocation, skip it. 1328 */ 1329 if (!(sp->sh_flags & SHF_ALLOC) && 1330 sp->sh_type != SHT_SYMTAB && 1331 sp->sh_type != SHT_STRTAB && 1332 sp->sh_type != SHT_RELA) 1333 continue; 1334 /* 1335 * If the section is read-only, 1336 * it goes in as text. 1337 */ 1338 spp = (sp->sh_flags & SHF_WRITE)? &edata: &etext; 1339 1340 /* 1341 * Make some room for it. 1342 */ 1343 #ifdef BOOTAMD64 1344 load = ADDR_XTND(segbrk((caddr_t *)spp, 1345 sp->sh_size, sp->sh_addralign)); 1346 #else /* !BOOTAMD64 */ 1347 load = (Elf64_Addr)segbrk((caddr_t *)spp, sp->sh_size, 1348 sp->sh_addralign); 1349 #endif /* BOOTAMD64 */ 1350 1351 if (load == NULL) { 1352 printf("boot: allocating memory for section %d " 1353 "failed\n", i); 1354 goto error; 1355 } 1356 1357 /* 1358 * Compute the entry point of the linker. 1359 */ 1360 if (dl_entry == 0 && 1361 !(sp->sh_flags & SHF_WRITE) && 1362 (sp->sh_flags & SHF_EXECINSTR)) { 1363 dl_entry = load + ehdr->e_entry; 1364 if (verbosemode) 1365 dprintf("boot: loading linker @ 0x%llx\n", 1366 (u_longlong_t)dl_entry); 1367 } 1368 1369 /* 1370 * If it's bss, just zero it out. 1371 */ 1372 if (sp->sh_type == SHT_NOBITS) { 1373 bzero((caddr_t)(uintptr_t)load, sp->sh_size); 1374 } else { 1375 /* 1376 * Read the section contents. 1377 */ 1378 if (lseek(fd, sp->sh_offset, 0) == -1 || 1379 xread(fd, (caddr_t)(uintptr_t)load, sp->sh_size) != 1380 sp->sh_size) { 1381 printf("boot: error reading section %d\n", i); 1382 goto error; 1383 } 1384 } 1385 /* 1386 * Assign the section's virtual addr. 1387 */ 1388 1389 sp->sh_addr = load; 1390 1391 if (verbosemode) 1392 dprintf("boot: section %d, type %d, loaded @ 0x%llx, " 1393 "size 0x%llx\n", i, sp->sh_type, (u_longlong_t)load, 1394 (u_longlong_t)sp->sh_size); 1395 1396 /* force instructions to be visible to icache */ 1397 if (sp->sh_flags & SHF_EXECINSTR) 1398 sync_instruction_memory((caddr_t)(uintptr_t)sp->sh_addr, 1399 sp->sh_size); 1400 } 1401 /* 1402 * Update sizes of segments. 1403 */ 1404 thdr->p_memsz = etext - thdr->p_vaddr; 1405 dhdr->p_memsz = edata - dhdr->p_vaddr; 1406 1407 /* load and relocate symbol tables in SAS */ 1408 (void) close(fd); 1409 return (dl_entry); 1410 1411 error: 1412 (void) close(fd); 1413 errorx: 1414 if (ehdr) 1415 kmem_free((caddr_t)ehdr, sizeof (Elf64_Ehdr)); 1416 if (shdrs) 1417 kmem_free(shdrs, size); 1418 printf("boot: error loading interpreter (%s)\n", rtld); 1419 return (FAIL_ILOAD64); 1420 } 1421 #endif /* _ELF64_SUPPORT */ 1422 1423 /* 1424 * Extend the segment's "break" value by bytes. 1425 */ 1426 static caddr_t 1427 segbrk(caddr_t *spp, size_t bytes, size_t align) 1428 { 1429 caddr_t va, pva; 1430 size_t size = 0; 1431 unsigned int alloc_pagesize = pagesize; 1432 unsigned int alloc_align = 0; 1433 1434 if (npagesize) { 1435 alloc_align = npagesize; 1436 alloc_pagesize = npagesize; 1437 } 1438 1439 va = (caddr_t)ALIGN(*spp, align); 1440 pva = (caddr_t)roundup((uintptr_t)*spp, alloc_pagesize); 1441 /* 1442 * Need more pages? 1443 */ 1444 if (va + bytes > pva) { 1445 size = roundup((bytes - (pva - va)), alloc_pagesize); 1446 1447 if (get_progmemory(pva, size, alloc_align)) { 1448 printf("boot: segbrk allocation failed, " 1449 "0x%lx bytes @ %p\n", bytes, (void *)pva); 1450 return (NULL); 1451 } 1452 } 1453 *spp = va + bytes; 1454 1455 return (va); 1456 } 1457 1458 /* 1459 * Open the file using a search path and 1460 * return the file descriptor (or -1 on failure). 1461 */ 1462 static int 1463 openpath(path, fname, flags) 1464 char *path; 1465 char *fname; 1466 int flags; 1467 { 1468 register char *p, *q; 1469 char buf[MAXPATHLEN]; 1470 int fd; 1471 1472 /* 1473 * If the file name is absolute, 1474 * don't use the module search path. 1475 */ 1476 if (fname[0] == '/') 1477 return (open(fname, flags)); 1478 1479 q = NULL; 1480 for (p = path; /* forever */; p = q) { 1481 1482 while (*p == ' ' || *p == '\t' || *p == ':') 1483 p++; 1484 if (*p == '\0') 1485 break; 1486 q = p; 1487 while (*q && *q != ' ' && *q != '\t' && *q != ':') 1488 q++; 1489 (void) strncpy(buf, p, q - p); 1490 if (q[-1] != '/') { 1491 buf[q - p] = '/'; 1492 (void) strcpy(&buf[q - p + 1], fname); 1493 } else { 1494 /* 1495 * This checks for paths that end in '/' 1496 */ 1497 (void) strcpy(&buf[q - p], fname); 1498 } 1499 1500 if ((fd = open(buf, flags)) > 0) 1501 return (fd); 1502 } 1503 return (-1); 1504 } 1505 1506 /* 1507 * Get the module search path. 1508 */ 1509 static char * 1510 getmodpath(fname) 1511 char *fname; 1512 { 1513 register char *p = strrchr(fname, '/'); 1514 static char mod_path[MOD_MAXPATH]; 1515 size_t len; 1516 extern char *impl_arch_name; 1517 #if defined(__sparcv9) || defined(BOOTAMD64) 1518 #ifdef __sparcv9 1519 char *isastr = "/sparcv9"; 1520 #endif /* __sparcv9 */ 1521 #ifdef BOOTAMD64 1522 char *isastr = "/amd64"; 1523 #endif /* BOOTAMD64 */ 1524 size_t isalen = strlen(isastr); 1525 #endif /* __sparcv9 || BOOTAMD64 */ 1526 1527 if (p == NULL) { 1528 /* strchr could not find a "/" */ 1529 printf("%s is not a legal kernel pathname", fname); 1530 return (NULL); 1531 } 1532 while (p > fname && *(p - 1) == '/') 1533 p--; /* remove trailing "/"s */ 1534 if (p == fname) 1535 p++; /* "/" is the modpath in this case */ 1536 1537 len = p - fname; 1538 (void) strncpy(mod_path, fname, len); 1539 mod_path[len] = 0; 1540 1541 #if defined(__sparcv9) || defined(BOOTAMD64) 1542 len = strlen(mod_path); 1543 if ((len > isalen) && (strcmp(&mod_path[len - isalen], isastr) == 0)) { 1544 mod_path[len - isalen] = '\0'; 1545 #if defined(__sparcv9) 1546 if ((client_isLP64 == 0) && verbosemode) 1547 printf("Assuming LP64 %s client.\n", isastr); 1548 client_isLP64 = 1; 1549 #endif /* __sparcv9 */ 1550 } 1551 #endif /* __sparcv9 || BOOTAMD64 */ 1552 mod_path_uname_m(mod_path, impl_arch_name); 1553 (void) strcat(mod_path, " "); 1554 (void) strcat(mod_path, MOD_DEFPATH); 1555 1556 if (boothowto & RB_ASKNAME) { 1557 char buf[MOD_MAXPATH]; 1558 1559 printf("Enter default directory for modules [%s]: ", mod_path); 1560 (void) cons_gets(buf, sizeof (buf)); 1561 if (buf[0] != '\0') 1562 (void) strcpy(mod_path, buf); 1563 } 1564 if (verbosemode) 1565 printf("modpath: %s\n", mod_path); 1566 return (mod_path); 1567 } 1568