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