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