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