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