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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/sysmacros.h>
27 #include <sys/types.h>
28 #include <sys/exechdr.h>
30 #include <sys/elf_notes.h>
31 #include <sys/bootconf.h>
32 #include <sys/reboot.h>
33 #include <sys/fcntl.h>
35 #include <sys/modctl.h>
38 #include <sys/salib.h>
39 #include <sys/bootvfs.h>
40 #include <sys/platnames.h>
45 #include <amd64/amd64_page.h>
46 #endif /* BOOTAMD64 */
55 #define elfhdr ex.Elfhdr
56 #define elfhdr64 ex.Elfhdr64
58 typedef int (*func_t
)();
60 #define FAIL ((func_t)-1)
62 ((a) == 0 ? (uintptr_t)(x) : (((uintptr_t)(x) + (a) - 1) & ~((a) - 1)))
64 #define __BOOT_NAUXV_IMPL 22
68 uint_t icache_flush
= 0;
71 char *module_path
; /* path for kernel modules */
74 * This file gets compiled in LP64 (for sun4u) and ILP32 models.
75 * For LP64 compilation, the "client" file we load and run may be LP64 or ILP32,
76 * and during bringup, the LP64 clients may have ELF32 headers.
81 * Bootstrap vector for ELF32 LP64 client - neither supported nor needed for
84 Elf32_Boot
*elfbootvecELF32_64
;
85 #endif /* !BOOTAMD64 */
87 Elf64_Boot
*elfbootvecELF64
; /* ELF bootstrap vector for Elf64 LP64 */
89 #define OK ((func_t)0)
91 #define FAIL_READELF64 ((uint64_t)0)
92 #define FAIL_ILOAD64 ((Elf64_Addr)-1)
93 #endif /* _ELF64_SUPPORT */
96 * And by an ILP32 client. The non-sun4u/LP64 booters use these.
97 * Also, the sun4u booter must create this for ILP32 clients.
99 Elf32_Boot
*elfbootvec
; /* ELF bootstrap vector normal ILP32 */
102 * Read in a Unix executable file and return its entry point.
103 * Handle the various a.out formats correctly.
104 * "fd" is the standalone file descriptor to read from.
105 * Print informative little messages if "print" is on.
106 * Returns -1 for errors.
110 static int debug
= 1;
112 static int debug
= 0;
115 #define dprintf if (debug) printf
117 #ifdef _ELF64_SUPPORT
121 uint_t a_pad
; /* needed to 8-byte align uint64_ts below for AMD64 */
122 #endif /* BOOTAMD64 */
127 void (*a_fcn
)(); /* XXX - UNUSED? */
128 #endif /* !BOOTAMD64 */
132 #if defined(__sparcv9)
133 extern int client_isLP64
;
134 #endif /* __sparcv9 */
136 static uint64_t read_elf64(int, int, Elf64_Ehdr
*);
137 static Elf64_Addr
iload64(char *, Elf64_Phdr
*, Elf64_Phdr
*, auxv64_t
**);
138 #endif /* _ELF64_SUPPORT */
140 #if defined(i386) && !defined(_SYSCALL32)
141 typedef auxv_t auxv32_t
;
144 static func_t
read_elf32(int, int, Elf32_Ehdr
*);
145 static func_t
iload32(char *, Elf32_Phdr
*, Elf32_Phdr
*, auxv32_t
**);
146 static caddr_t
segbrk(caddr_t
*, size_t, size_t);
147 static int openpath(char *, char *, int);
148 static char *getmodpath(char *);
149 extern void setup_aux(void);
151 extern void *kmem_alloc(size_t, int);
152 extern void kmem_free(void *, size_t);
153 extern int cons_gets(char *, int);
156 extern const char *amd64_getmmulist(void);
158 extern int amd64_elf64
;
160 #endif /* BOOTAMD64 */
162 extern void sync_instruction_memory(caddr_t v
, size_t len
);
164 extern int verbosemode
;
165 extern int boothowto
;
167 extern char filename
[];
170 * repeat reads (forever) until size of request is satisfied
171 * (Thus, you don't want to use this cases where short reads are ok)
174 xread(int fd
, char *p
, size_t nbytes
)
176 size_t bytesread
= 0;
180 while (bytesread
< nbytes
) {
181 i
= read(fd
, p
, nbytes
- bytesread
);
185 printf("read error (0x%x times)\n", errorcount
);
195 readfile(int fd
, int print
)
197 #ifdef _ELF64_SUPPORT
199 extern int bsetprop(struct bootops
*, char *, void *, int);
200 extern struct bootops
*bop
;
201 extern uint64_t elf64_go2
;
202 #else /* !BOOTAMD64 */
204 #endif /* BOOTAMD64 */
205 #endif /* _ELF64_SUPPORT */
211 dprintf("fd = %x\n", fd
);
214 i
= xread(fd
, (char *)&elfhdr
, sizeof (Elf64_Ehdr
));
215 if (x
.a_magic
== ZMAGIC
|| x
.a_magic
== NMAGIC
)
217 if (i
!= sizeof (Elf64_Ehdr
)) {
218 printf("Error reading ELF header.\n");
221 if (!shared
&& x
.a_magic
!= OMAGIC
) {
222 if (*(int *)&elfhdr
.e_ident
== *(int *)(ELFMAG
)) {
224 int is64
= (elfhdr
.e_ident
[EI_CLASS
] ==
227 dprintf("calling readelf, elfheader is:\n");
228 dprintf("e_ident\t0x%x, 0x%x, 0x%x, 0x%x\n",
229 *(int *)&elfhdr
.e_ident
[0],
230 *(int *)&elfhdr
.e_ident
[4],
231 *(int *)&elfhdr
.e_ident
[8],
232 *(int *)&elfhdr
.e_ident
[12]);
233 dprintf("e_machine\t0x%x\n", elfhdr
.e_machine
);
235 dprintf("e_entry\t\t0x%llx\n", (is64
?
237 (u_longlong_t
)elfhdr
.e_entry
));
238 dprintf("e_shoff\t\t0x%llx\n", (is64
?
240 (u_longlong_t
)elfhdr
.e_shoff
));
241 dprintf("e_shnentsize\t%d\n", (is64
?
242 elfhdr64
.e_shentsize
: elfhdr
.e_shentsize
));
243 dprintf("e_shnum\t\t%d\n", (is64
?
244 elfhdr64
.e_shnum
: elfhdr
.e_shnum
));
245 dprintf("e_shstrndx\t%d\n", (is64
?
246 elfhdr64
.e_shstrndx
: elfhdr
.e_shstrndx
));
250 #ifdef _ELF64_SUPPORT
251 dprintf("ELF file CLASS 0x%x 32 is %x 64 is %x\n",
252 elfhdr
.e_ident
[EI_CLASS
], ELFCLASS32
, ELFCLASS64
);
254 if (elfhdr
.e_ident
[EI_CLASS
] == ELFCLASS64
) {
256 if (elfhdr
.e_machine
!= EM_AMD64
) {
257 printf("FATAL: 64-bit ELF executable "
258 "not for AMD64\n (e_machine "
259 "= %d).\n", elfhdr
.e_machine
);
264 * OK, we know the executable is for an AMD64
265 * CPU. Make sure we ARE an AMD64 CPU before
269 printf("FATAL: AMD64 executables not "
270 " supported on this CPU.\n");
274 amd64_elf64
= (elfhdr
.e_ident
[EI_CLASS
] ==
276 #endif /* BOOTAMD64 */
278 elf64_go2
= read_elf64(fd
, print
,
279 (Elf64_Ehdr
*)&elfhdr
);
282 if (elf64_go2
!= FAIL_READELF64
)
283 (void) bsetprop(bop
, "mmu-modlist",
286 return ((elf64_go2
== FAIL_READELF64
) ? FAIL
:
288 #else /* !BOOTAMD64 */
289 return ((elf64_go2
== FAIL_READELF64
) ? FAIL
:
291 #endif /* BOOTAMD64 */
294 #endif /* _ELF64_SUPPORT */
295 return (read_elf32(fd
, print
, &elfhdr
));
297 printf("File not executable.\n");
305 * Macros to add attribute/values to the ELF bootstrap vector
306 * and the aux vector. Use the type-cast to convert integers
307 * to pointers first to suppress the gcc warning.
309 #define AUX(p, a, v) { (p)->a_type = (a); \
310 ((p)++)->a_un.a_val = (int32_t)(uintptr_t)(v); }
312 #define EBV(p, a, v) { (p)->eb_tag = (a); \
313 ((p)++)->eb_un.eb_val = (Elf32_Word)(uintptr_t)(v); }
316 read_elf32(int fd
, int print
, Elf32_Ehdr
*elfhdrp
)
318 Elf32_Phdr
*phdr
; /* program header */
319 Elf32_Nhdr
*nhdr
; /* note header */
320 int nphdrs
, phdrsize
;
322 caddr_t namep
, descp
;
323 Elf32_Addr loadaddr
, base
;
329 int interp
= 0; /* interpreter required */
330 static char dlname
[MAXPATHLEN
]; /* name of interpeter */
331 uint_t dynamic
; /* dynamic tags array */
332 Elf32_Phdr
*thdr
; /* "text" program header */
333 Elf32_Phdr
*dhdr
; /* "data" program header */
334 func_t entrypt
; /* entry point of standalone */
336 /* Initialize pointers so we won't free bogus ones on elferror */
340 #ifdef _ELF64_SUPPORT
342 printf("Elf32 client\n");
343 #endif /* _ELF64_SUPPORT */
345 if (elfhdrp
->e_phnum
== 0 || elfhdrp
->e_phoff
== 0)
348 /* use uintptr_t to suppress the gcc warning */
349 entrypt
= (func_t
)(uintptr_t)elfhdrp
->e_entry
;
351 dprintf("Entry point: %p\n", (void *)entrypt
);
354 * Allocate and read in all the program headers.
356 nphdrs
= elfhdrp
->e_phnum
;
357 phdrsize
= nphdrs
* elfhdrp
->e_phentsize
;
358 allphdrs
= kmem_alloc(phdrsize
, 0);
359 if (allphdrs
== NULL
)
362 dprintf("lseek: args = %x %x %x\n", fd
, elfhdrp
->e_phoff
, 0);
363 if (lseek(fd
, elfhdrp
->e_phoff
, 0) == -1)
365 if (xread(fd
, allphdrs
, phdrsize
) != phdrsize
)
369 * First look for PT_NOTE headers that tell us what pagesize to
370 * use in allocating program memory.
373 for (i
= 0; i
< nphdrs
; i
++) {
376 phdr
= (Elf32_Phdr
*)(allphdrs
+ elfhdrp
->e_phentsize
* i
);
377 if (phdr
->p_type
!= PT_NOTE
)
380 dprintf("allocating 0x%x bytes for note hdr\n",
383 if ((note_buf
= kmem_alloc(phdr
->p_filesz
, 0)) == NULL
)
386 dprintf("seeking to 0x%x\n", phdr
->p_offset
);
387 if (lseek(fd
, phdr
->p_offset
, 0) == -1)
390 dprintf("reading 0x%x bytes into %p\n",
391 phdr
->p_filesz
, (void *)nhdr
);
393 nhdr
= (Elf32_Nhdr
*)note_buf
;
394 if (xread(fd
, (caddr_t
)nhdr
, phdr
->p_filesz
) != phdr
->p_filesz
)
397 dprintf("p_note namesz %x descsz %x type %x\n",
398 nhdr
->n_namesz
, nhdr
->n_descsz
, nhdr
->n_type
);
402 * Iterate through all ELF PT_NOTE elements looking for
403 * ELF_NOTE_SOLARIS which, if present, will specify the
404 * executable's preferred pagesize.
407 namep
= (caddr_t
)(nhdr
+ 1);
409 if (nhdr
->n_namesz
== strlen(ELF_NOTE_SOLARIS
) + 1 &&
410 strcmp(namep
, ELF_NOTE_SOLARIS
) == 0 &&
411 nhdr
->n_type
== ELF_NOTE_PAGESIZE_HINT
) {
412 descp
= namep
+ roundup(nhdr
->n_namesz
, 4);
413 npagesize
= *(int *)descp
;
415 dprintf("pagesize is %x\n", npagesize
);
418 offset
+= sizeof (Elf32_Nhdr
) + roundup(nhdr
->n_namesz
,
419 4) + roundup(nhdr
->n_descsz
, 4);
421 nhdr
= (Elf32_Nhdr
*)((char *)note_buf
+ offset
);
422 } while (offset
< phdr
->p_filesz
);
424 kmem_free(note_buf
, phdr
->p_filesz
);
429 * Next look for PT_LOAD headers to read in.
433 for (i
= 0; i
< nphdrs
; i
++) {
434 phdr
= (Elf32_Phdr
*)(allphdrs
+ elfhdrp
->e_phentsize
* i
);
436 dprintf("Doing header 0x%x\n", i
);
438 dprintf("\tp_offset = %x, p_vaddr = %x\n",
439 phdr
->p_offset
, phdr
->p_vaddr
);
440 dprintf("\tp_memsz = %x, p_filesz = %x\n",
441 phdr
->p_memsz
, phdr
->p_filesz
);
443 if (phdr
->p_type
== PT_LOAD
) {
445 dprintf("seeking to 0x%x\n", phdr
->p_offset
);
446 if (lseek(fd
, phdr
->p_offset
, 0) == -1)
449 if (phdr
->p_flags
== (PF_R
| PF_W
) &&
450 phdr
->p_vaddr
== 0) {
452 * It's a PT_LOAD segment that is RW but
453 * not executable and has a vaddr
454 * of zero. This is relocation info that
455 * doesn't need to stick around after
456 * krtld is done with it. We allocate boot
457 * memory for this segment, since we don't want
458 * it mapped in permanently as part of
461 if ((loadaddr
= (uintptr_t)
462 kmem_alloc(phdr
->p_memsz
, 0)) == NULL
)
465 * Save this to pass on
466 * to the interpreter.
468 phdr
->p_vaddr
= (Elf32_Addr
)loadaddr
;
471 printf("0x%x+", phdr
->p_filesz
);
473 * If we found a new pagesize above, use it
474 * to adjust the memory allocation.
476 loadaddr
= phdr
->p_vaddr
;
477 if (use_align
&& npagesize
!= 0) {
478 off
= loadaddr
& (npagesize
- 1);
479 size
= roundup(phdr
->p_memsz
+ off
,
481 base
= loadaddr
- off
;
484 size
= phdr
->p_memsz
;
488 * Check if it's text or data.
490 if (phdr
->p_flags
& PF_W
)
496 * If memory size is zero just ignore this
503 dprintf("allocating memory: %x %lx "
504 "%x\n", base
, size
, npagesize
);
506 * We're all set up to read.
507 * Now let's allocate some memory.
512 * If vaddr == paddr and npagesize is 0, that
513 * means the executable needs to be identity
514 * mapped in memory (va == pa, mapped 1:1)
516 * Otherwise load as usual.
518 if ((phdr
->p_vaddr
== phdr
->p_paddr
) &&
520 extern caddr_t
idmap_mem(uint32_t,
525 n
= (uint_t
)base
& (pagesize
- 1);
531 if (!idmap_mem((uint32_t)base
,
532 (size_t)size
, pagesize
))
536 /* use uintptr_t to suppress the gcc warning */
537 if (get_progmemory((caddr_t
)(uintptr_t)base
,
543 dprintf("reading 0x%x bytes into 0x%x\n",
544 phdr
->p_filesz
, loadaddr
);
546 /* use uintptr_t to suppress the gcc warning */
547 if (xread(fd
, (caddr_t
)(uintptr_t)loadaddr
,
548 phdr
->p_filesz
) != phdr
->p_filesz
)
552 if (phdr
->p_memsz
> phdr
->p_filesz
) {
553 loadaddr
+= phdr
->p_filesz
;
555 dprintf("bss from 0x%x size 0x%x\n",
557 phdr
->p_memsz
- phdr
->p_filesz
);
559 /* use uintptr_t to suppress the gcc warning */
560 bzero((void *)(uintptr_t)loadaddr
,
561 phdr
->p_memsz
- phdr
->p_filesz
);
564 printf("0x%x Bytes\n",
565 phdr
->p_memsz
- phdr
->p_filesz
);
568 /* force instructions to be visible to icache */
569 if (phdr
->p_flags
& PF_X
) {
570 sync_instruction_memory(
571 (caddr_t
)(uintptr_t)phdr
->p_vaddr
,
574 } else if (phdr
->p_type
== PT_INTERP
) {
576 * Dynamically-linked executable.
579 if (lseek(fd
, phdr
->p_offset
, 0) == -1) {
583 * Get the name of the interpreter.
585 if (xread(fd
, dlname
, phdr
->p_filesz
) !=
587 dlname
[phdr
->p_filesz
- 1] != '\0')
589 } else if (phdr
->p_type
== PT_DYNAMIC
) {
590 dynamic
= phdr
->p_vaddr
;
594 if (!bss_seen
&& print
)
598 * Load the interpreter
602 Elf32_Boot bootv
[EB_MAX
]; /* Bootstrap vector */
603 auxv32_t auxv
[__BOOT_NAUXV_IMPL
]; /* Aux vector */
604 Elf32_Boot
*bv
= bootv
;
611 if ((entrypt
= iload32(dlname
, thdr
, dhdr
, &av
)) == FAIL
)
614 * Build bootstrap and aux vectors.
617 EBV(bv
, EB_AUXV
, 0); /* fill in later */
618 EBV(bv
, EB_PAGESIZE
, pagesize
);
619 EBV(bv
, EB_DYNAMIC
, dynamic
);
622 AUX(av
, AT_BASE
, entrypt
);
623 AUX(av
, AT_ENTRY
, elfhdrp
->e_entry
);
624 AUX(av
, AT_PAGESZ
, pagesize
);
625 AUX(av
, AT_PHDR
, allphdrs
);
626 AUX(av
, AT_PHNUM
, elfhdrp
->e_phnum
);
627 AUX(av
, AT_PHENT
, elfhdrp
->e_phentsize
);
629 AUX(av
, AT_SUN_LPAGESZ
, npagesize
);
630 AUX(av
, AT_SUN_IFLUSH
, icache_flush
);
632 AUX(av
, AT_SUN_CPU
, cpulist
);
634 AUX(av
, AT_SUN_MMU
, mmulist
);
637 * Realloc vectors and copy them.
639 vsize
= (caddr_t
)bv
- (caddr_t
)bootv
;
640 if ((elfbootvec
= (Elf32_Boot
*)kmem_alloc(vsize
, 0)) == NULL
)
642 bcopy((char *)bootv
, (char *)elfbootvec
, vsize
);
644 size
= (caddr_t
)av
- (caddr_t
)auxv
;
645 if (size
> sizeof (auxv
)) {
646 printf("readelf: overrun of available aux vectors\n");
647 kmem_free(elfbootvec
, vsize
);
650 /* use uintptr_t to suppress the gcc warning */
651 if ((elfbootvec
->eb_un
.eb_ptr
=
652 (Elf32_Addr
)(uintptr_t)kmem_alloc(size
, 0)) == NULL
) {
653 kmem_free(elfbootvec
, vsize
);
656 /* use uintptr_t to suppress the gcc warning */
658 (void *)(uintptr_t)(elfbootvec
->eb_un
.eb_ptr
), size
);
660 #if defined(_ELF64_SUPPORT) && !defined(BOOTAMD64)
662 * Make an LP64 copy of the vector for use by 64-bit standalones
663 * even if they have ELF32.
665 if ((elfbootvecELF32_64
= (Elf32_Boot
*)kmem_alloc(vsize
, 0))
668 bcopy(bootv
, elfbootvecELF32_64
, vsize
);
670 size
= (av
- auxv
) * sizeof (auxv64_t
);
671 /* use uintptr_t to suppress the gcc warning */
672 if ((elfbootvecELF32_64
->eb_un
.eb_ptr
=
673 (Elf32_Addr
)(uintptr_t)kmem_alloc(size
, 0)) == NULL
) {
674 kmem_free(elfbootvecELF32_64
, vsize
);
678 (auxv64_t
*)(uintptr_t)
679 elfbootvecELF32_64
->eb_un
.eb_ptr
;
682 for (a
= auxv
; a
< av
; a
++) {
683 a64
->a_type
= a
->a_type
;
684 a64
->a_un
.a_val
= a
->a_un
.a_val
;
688 #endif /* _ELF64_SUPPORT && !BOOTAMD64 */
690 kmem_free(allphdrs
, phdrsize
);
695 if (allphdrs
!= NULL
)
696 kmem_free(allphdrs
, phdrsize
);
698 kmem_free(nhdr
, phdr
->p_filesz
);
699 printf("Elf32 read error.\n");
703 #ifdef _ELF64_SUPPORT
705 * Macros to add attribute/values to the ELF bootstrap vector
706 * and the aux vector.
708 #define AUX64(p, a, v) { (p)->a_type = (a); \
709 ((p)++)->a_un.a_val = (uint64_t)(v); }
711 #define EBV64(p, a, v) { (p)->eb_tag = (a); \
712 ((p)++)->eb_un.eb_val = (Elf64_Xword)(v); }
715 read_elf64(int fd
, int print
, Elf64_Ehdr
*elfhdrp
)
717 Elf64_Phdr
*phdr
; /* program header */
718 Elf64_Nhdr
*nhdr
; /* note header */
719 int nphdrs
, phdrsize
;
721 caddr_t namep
, descp
;
722 Elf64_Addr loadaddr
, base
;
728 int interp
= 0; /* interpreter required */
729 static char dlname
[MAXPATHLEN
]; /* name of interpeter */
730 uintptr_t dynamic
; /* dynamic tags array */
731 Elf64_Phdr
*thdr
; /* "text" program header */
732 Elf64_Phdr
*dhdr
; /* "data" program header */
733 Elf64_Addr entrypt
; /* entry point of standalone */
735 /* Initialize pointers so we won't free bogus ones on elf64error */
738 #if defined(__sparcv9)
740 #endif /* __sparcv9 */
743 printf("Elf64 client\n");
745 if (elfhdrp
->e_phnum
== 0 || elfhdrp
->e_phoff
== 0)
748 entrypt
= elfhdrp
->e_entry
;
750 dprintf("Entry point: 0x%llx\n", (u_longlong_t
)entrypt
);
753 * Allocate and read in all the program headers.
755 nphdrs
= elfhdrp
->e_phnum
;
756 phdrsize
= nphdrs
* elfhdrp
->e_phentsize
;
757 allphdrs
= kmem_alloc(phdrsize
, 0);
758 if (allphdrs
== NULL
)
761 dprintf("lseek: args = %x %llx %x\n", fd
,
762 (u_longlong_t
)elfhdrp
->e_phoff
, 0);
763 if (lseek(fd
, elfhdrp
->e_phoff
, 0) == -1)
765 if (xread(fd
, allphdrs
, phdrsize
) != phdrsize
)
769 * First look for PT_NOTE headers that tell us what pagesize to
770 * use in allocating program memory.
773 for (i
= 0; i
< nphdrs
; i
++) {
776 phdr
= (Elf64_Phdr
*)(allphdrs
+ elfhdrp
->e_phentsize
* i
);
777 if (phdr
->p_type
!= PT_NOTE
)
780 dprintf("allocating 0x%llx bytes for note hdr\n",
781 (u_longlong_t
)phdr
->p_filesz
);
783 if ((note_buf
= kmem_alloc(phdr
->p_filesz
, 0)) == NULL
)
786 dprintf("seeking to 0x%llx\n",
787 (u_longlong_t
)phdr
->p_offset
);
788 if (lseek(fd
, phdr
->p_offset
, 0) == -1)
791 dprintf("reading 0x%llx bytes into 0x%p\n",
792 (u_longlong_t
)phdr
->p_filesz
, (void *)nhdr
);
794 nhdr
= (Elf64_Nhdr
*)note_buf
;
795 if (xread(fd
, (caddr_t
)nhdr
, phdr
->p_filesz
) != phdr
->p_filesz
)
798 dprintf("p_note namesz %x descsz %x type %x\n",
799 nhdr
->n_namesz
, nhdr
->n_descsz
, nhdr
->n_type
);
803 * Iterate through all ELF PT_NOTE elements looking for
804 * ELF_NOTE_SOLARIS which, if present, will specify the
805 * executable's preferred pagesize.
808 namep
= (caddr_t
)(nhdr
+ 1);
810 if (nhdr
->n_namesz
== strlen(ELF_NOTE_SOLARIS
) + 1 &&
811 strcmp(namep
, ELF_NOTE_SOLARIS
) == 0 &&
812 nhdr
->n_type
== ELF_NOTE_PAGESIZE_HINT
) {
813 descp
= namep
+ roundup(nhdr
->n_namesz
, 4);
814 npagesize
= *(int *)descp
;
816 dprintf("pagesize is %x\n", npagesize
);
819 offset
+= sizeof (Elf64_Nhdr
) + roundup(nhdr
->n_namesz
,
820 4) + roundup(nhdr
->n_descsz
, 4);
822 nhdr
= (Elf64_Nhdr
*)((char *)note_buf
+ offset
);
823 } while (offset
< phdr
->p_filesz
);
825 kmem_free(note_buf
, phdr
->p_filesz
);
830 * Next look for PT_LOAD headers to read in.
834 for (i
= 0; i
< nphdrs
; i
++) {
835 phdr
= (Elf64_Phdr
*)(allphdrs
+ elfhdrp
->e_phentsize
* i
);
837 dprintf("Doing header 0x%x\n", i
);
839 dprintf("\tp_offset = %llx, p_vaddr = %llx\n",
840 (u_longlong_t
)phdr
->p_offset
,
841 (u_longlong_t
)phdr
->p_vaddr
);
842 dprintf("\tp_memsz = %llx, p_filesz = %llx\n",
843 (u_longlong_t
)phdr
->p_memsz
,
844 (u_longlong_t
)phdr
->p_filesz
);
845 dprintf("\tp_type = %x, p_flags = %x\n",
846 phdr
->p_type
, phdr
->p_flags
);
848 if (phdr
->p_type
== PT_LOAD
) {
850 dprintf("seeking to 0x%llx\n",
851 (u_longlong_t
)phdr
->p_offset
);
852 if (lseek(fd
, phdr
->p_offset
, 0) == -1)
855 if (phdr
->p_flags
== (PF_R
| PF_W
) &&
856 phdr
->p_vaddr
== 0) {
858 * It's a PT_LOAD segment that is RW but
859 * not executable and has a vaddr
860 * of zero. This is relocation info that
861 * doesn't need to stick around after
862 * krtld is done with it. We allocate boot
863 * memory for this segment, since we don't want
864 * it mapped in permanently as part of
868 if ((loadaddr
= (Elf64_Addr
)
869 (ADDR_XTND(kmem_alloc(phdr
->p_memsz
, 0))))
871 #else /* !BOOTAMD64 */
872 if ((loadaddr
= (Elf64_Addr
)(uintptr_t)
873 kmem_alloc(phdr
->p_memsz
, 0)) == NULL
)
874 #endif /* BOOTAMD64 */
878 * Save this to pass on
879 * to the interpreter.
881 phdr
->p_vaddr
= loadaddr
;
885 (u_longlong_t
)phdr
->p_filesz
);
887 * If we found a new pagesize above, use it
888 * to adjust the memory allocation.
890 loadaddr
= phdr
->p_vaddr
;
891 if (use_align
&& npagesize
!= 0) {
892 off
= loadaddr
& (npagesize
- 1);
893 size
= roundup(phdr
->p_memsz
+ off
,
895 base
= loadaddr
- off
;
898 size
= phdr
->p_memsz
;
902 * Check if it's text or data.
904 if (phdr
->p_flags
& PF_W
)
911 "allocating memory: %llx %lx %x\n",
916 * If memory size is zero just ignore this
923 * We're all set up to read.
924 * Now let's allocate some memory.
926 if (get_progmemory((caddr_t
)(uintptr_t)base
,
932 dprintf("reading 0x%llx bytes into 0x%llx\n",
933 (u_longlong_t
)phdr
->p_filesz
,
934 (u_longlong_t
)loadaddr
);
936 if (xread(fd
, (caddr_t
)(uintptr_t)
937 loadaddr
, phdr
->p_filesz
) != phdr
->p_filesz
)
941 if (phdr
->p_memsz
> phdr
->p_filesz
) {
942 loadaddr
+= phdr
->p_filesz
;
944 dprintf("bss from 0x%llx size 0x%llx\n",
945 (u_longlong_t
)loadaddr
,
946 (u_longlong_t
)(phdr
->p_memsz
-
950 bzero((caddr_t
)(uintptr_t)loadaddr
,
951 phdr
->p_memsz
- phdr
->p_filesz
);
954 printf("0x%llx Bytes\n",
955 (u_longlong_t
)(phdr
->p_memsz
-
959 /* force instructions to be visible to icache */
960 if (phdr
->p_flags
& PF_X
)
961 sync_instruction_memory((caddr_t
)(uintptr_t)
962 phdr
->p_vaddr
, phdr
->p_memsz
);
964 } else if (phdr
->p_type
== PT_INTERP
) {
966 * Dynamically-linked executable.
969 if (lseek(fd
, phdr
->p_offset
, 0) == -1) {
973 * Get the name of the interpreter.
975 if (xread(fd
, dlname
, phdr
->p_filesz
) !=
977 dlname
[phdr
->p_filesz
- 1] != '\0')
979 } else if (phdr
->p_type
== PT_DYNAMIC
) {
980 dynamic
= phdr
->p_vaddr
;
984 if (!bss_seen
&& print
)
988 * Load the interpreter
992 Elf64_Boot bootv
[EB_MAX
]; /* Bootstrap vector */
993 auxv64_t auxv
[__BOOT_NAUXV_IMPL
]; /* Aux vector */
994 Elf64_Boot
*bv
= bootv
;
1001 if ((entrypt
= iload64(dlname
, thdr
, dhdr
, &av
)) ==
1005 * Build bootstrap and aux vectors.
1008 EBV64(bv
, EB_AUXV
, 0); /* fill in later */
1009 EBV64(bv
, EB_PAGESIZE
, pagesize
);
1010 EBV64(bv
, EB_DYNAMIC
, dynamic
);
1011 EBV64(bv
, EB_NULL
, 0);
1013 AUX64(av
, AT_BASE
, entrypt
);
1014 AUX64(av
, AT_ENTRY
, elfhdrp
->e_entry
);
1015 AUX64(av
, AT_PAGESZ
, pagesize
);
1016 AUX64(av
, AT_PHDR
, (uintptr_t)allphdrs
);
1017 AUX64(av
, AT_PHNUM
, elfhdrp
->e_phnum
);
1018 AUX64(av
, AT_PHENT
, elfhdrp
->e_phentsize
);
1020 AUX64(av
, AT_SUN_LPAGESZ
, npagesize
);
1023 vsize
= strlen(amd64_getmmulist()) + 1;
1024 if ((mmulist
= kmem_alloc(vsize
, 0)) == NULL
)
1027 bcopy(amd64_getmmulist(), mmulist
, vsize
);
1028 AUX64(av
, AT_SUN_MMU
, (uintptr_t)mmulist
);
1029 #endif /* BOOTAMD64 */
1031 AUX64(av
, AT_SUN_IFLUSH
, icache_flush
);
1032 if (cpulist
!= NULL
)
1033 AUX64(av
, AT_SUN_CPU
, (uintptr_t)cpulist
);
1034 AUX64(av
, AT_NULL
, 0);
1036 * Realloc vectors and copy them.
1038 vsize
= (caddr_t
)bv
- (caddr_t
)bootv
;
1039 if ((elfbootvecELF64
=
1040 (Elf64_Boot
*)kmem_alloc(vsize
, 0)) == NULL
)
1042 bcopy((char *)bootv
, (char *)elfbootvecELF64
, vsize
);
1044 size
= (caddr_t
)av
- (caddr_t
)auxv
;
1045 if (size
> sizeof (auxv
)) {
1046 printf("readelf: overrun of available aux vectors\n");
1047 kmem_free(elfbootvecELF64
, vsize
);
1052 if ((elfbootvecELF64
->eb_un
.eb_ptr
=
1053 ADDR_XTND(kmem_alloc(size
, 0))) == NULL
) {
1054 kmem_free(elfbootvecELF64
, vsize
);
1059 (char *)ADDR_TRUNC((elfbootvecELF64
->eb_un
.eb_ptr
)), size
);
1060 #else /* !BOOTAMD64 */
1061 if ((elfbootvecELF64
->eb_un
.eb_ptr
=
1062 (Elf64_Addr
)kmem_alloc(size
, 0)) == NULL
) {
1063 kmem_free(elfbootvecELF64
, vsize
);
1067 bcopy((char *)auxv
, (char *)(elfbootvecELF64
->eb_un
.eb_ptr
),
1069 #endif /* BOOTAMD64 */
1071 kmem_free(allphdrs
, phdrsize
);
1073 return ((uint64_t)entrypt
);
1076 if (allphdrs
!= NULL
)
1077 kmem_free(allphdrs
, phdrsize
);
1079 kmem_free(nhdr
, phdr
->p_filesz
);
1080 printf("Elf64 read error.\n");
1081 return (FAIL_READELF64
);
1083 #endif /* _ELF64_SUPPORT */
1086 * Load the interpreter. It expects a
1087 * relocatable .o capable of bootstrapping
1091 iload32(char *rtld
, Elf32_Phdr
*thdr
, Elf32_Phdr
*dhdr
, auxv32_t
**avp
)
1093 Elf32_Ehdr
*ehdr
= NULL
;
1094 uintptr_t dl_entry
= 0;
1098 caddr_t shdrs
= NULL
;
1099 caddr_t etext
, edata
;
1101 /* use uintptr_t to suppress the gcc warning */
1102 etext
= (caddr_t
)(uintptr_t)thdr
->p_vaddr
+ thdr
->p_memsz
;
1103 edata
= (caddr_t
)(uintptr_t)dhdr
->p_vaddr
+ dhdr
->p_memsz
;
1106 * Get the module path.
1108 module_path
= getmodpath(filename
);
1110 if ((fd
= openpath(module_path
, rtld
, O_RDONLY
)) < 0) {
1111 printf("boot: cannot find %s\n", rtld
);
1114 dprintf("Opened %s OK\n", rtld
);
1115 AUX(*avp
, AT_SUN_LDNAME
, rtld
);
1117 * Allocate and read the ELF header.
1119 if ((ehdr
= (Elf32_Ehdr
*)kmem_alloc(sizeof (Elf32_Ehdr
), 0)) == NULL
) {
1120 printf("boot: alloc error reading ELF header (%s).\n", rtld
);
1124 if (xread(fd
, (char *)ehdr
, sizeof (*ehdr
)) != sizeof (*ehdr
)) {
1125 printf("boot: error reading ELF header (%s).\n", rtld
);
1129 size
= ehdr
->e_shentsize
* ehdr
->e_shnum
;
1130 if ((shdrs
= kmem_alloc(size
, 0)) == NULL
) {
1131 printf("boot: alloc error reading ELF header (%s).\n", rtld
);
1135 * Read the section headers.
1137 if (lseek(fd
, ehdr
->e_shoff
, 0) == -1 ||
1138 xread(fd
, shdrs
, size
) != size
) {
1139 printf("boot: error reading section headers\n");
1142 AUX(*avp
, AT_SUN_LDELF
, ehdr
);
1143 AUX(*avp
, AT_SUN_LDSHDR
, shdrs
);
1145 * Load sections into the appropriate dynamic segment.
1147 for (i
= 1; i
< ehdr
->e_shnum
; i
++) {
1152 sp
= (Elf32_Shdr
*)(shdrs
+ (i
*ehdr
->e_shentsize
));
1154 * If it's not allocated and not required
1155 * to do relocation, skip it.
1157 if (!(sp
->sh_flags
& SHF_ALLOC
) &&
1159 sp
->sh_type
!= SHT_REL
&&
1161 sp
->sh_type
!= SHT_RELA
&&
1163 sp
->sh_type
!= SHT_SYMTAB
&&
1164 sp
->sh_type
!= SHT_STRTAB
)
1167 * If the section is read-only,
1168 * it goes in as text.
1170 spp
= (sp
->sh_flags
& SHF_WRITE
)? &edata
: &etext
;
1172 * Make some room for it.
1174 load
= segbrk(spp
, sp
->sh_size
, sp
->sh_addralign
);
1176 printf("boot: allocating memory for sections failed\n");
1180 * Compute the entry point of the linker.
1182 if (dl_entry
== 0 &&
1183 !(sp
->sh_flags
& SHF_WRITE
) &&
1184 (sp
->sh_flags
& SHF_EXECINSTR
)) {
1185 dl_entry
= (uintptr_t)load
+ ehdr
->e_entry
;
1188 * If it's bss, just zero it out.
1190 if (sp
->sh_type
== SHT_NOBITS
) {
1191 bzero(load
, sp
->sh_size
);
1194 * Read the section contents.
1196 if (lseek(fd
, sp
->sh_offset
, 0) == -1 ||
1197 xread(fd
, load
, sp
->sh_size
) != sp
->sh_size
) {
1198 printf("boot: error reading sections\n");
1203 * Assign the section's virtual addr. Use uintptr_t to
1204 * suppress the gcc warning.
1206 sp
->sh_addr
= (Elf32_Off
)(uintptr_t)load
;
1208 * Force instructions to be visible to icache. Use
1209 * uintptr_t to suppress the gcc warning as well.
1211 if (sp
->sh_flags
& SHF_EXECINSTR
)
1212 sync_instruction_memory((caddr_t
)(uintptr_t)sp
->sh_addr
,
1216 * Update sizes of segments.
1218 thdr
->p_memsz
= (Elf32_Word
)((uintptr_t)etext
- thdr
->p_vaddr
);
1219 dhdr
->p_memsz
= (Elf32_Word
)((uintptr_t)edata
- dhdr
->p_vaddr
);
1221 /* load and relocate symbol tables in SAS */
1223 return ((func_t
)dl_entry
);
1229 kmem_free(ehdr
, sizeof (Elf32_Ehdr
));
1231 kmem_free(shdrs
, size
);
1232 printf("boot: error loading interpreter (%s)\n", rtld
);
1236 #ifdef _ELF64_SUPPORT
1238 * Load the interpreter. It expects a
1239 * relocatable .o capable of bootstrapping
1243 iload64(char *rtld
, Elf64_Phdr
*thdr
, Elf64_Phdr
*dhdr
, auxv64_t
**avp
)
1245 Elf64_Ehdr
*ehdr
= NULL
;
1246 Elf64_Addr dl_entry
= (Elf64_Addr
)0;
1247 Elf64_Addr etext
, edata
;
1251 caddr_t shdrs
= NULL
;
1253 etext
= thdr
->p_vaddr
+ thdr
->p_memsz
;
1254 edata
= dhdr
->p_vaddr
+ dhdr
->p_memsz
;
1257 * Get the module path.
1259 module_path
= getmodpath(filename
);
1261 if ((fd
= openpath(module_path
, rtld
, O_RDONLY
)) < 0) {
1262 printf("boot: cannot find %s\n", rtld
);
1265 dprintf("Opened %s OK\n", rtld
);
1266 AUX64(*avp
, AT_SUN_LDNAME
, (uintptr_t)rtld
);
1268 * Allocate and read the ELF header.
1271 if ((ehdr
= (Elf64_Ehdr
*)(uintptr_t)kmem_alloc(sizeof (Elf64_Ehdr
),
1273 #else /* !BOOTAMD64 */
1274 if ((ehdr
= (Elf64_Ehdr
*)kmem_alloc(sizeof (Elf64_Ehdr
), 0)) == NULL
) {
1275 #endif /* BOOTAMD64 */
1276 printf("boot: alloc error reading ELF header (%s).\n", rtld
);
1280 if (xread(fd
, (char *)ehdr
, sizeof (*ehdr
)) != sizeof (*ehdr
)) {
1281 printf("boot: error reading ELF header (%s).\n", rtld
);
1285 size
= ehdr
->e_shentsize
* ehdr
->e_shnum
;
1286 if ((shdrs
= kmem_alloc(size
, 0)) == NULL
) {
1287 printf("boot: alloc error reading ELF header (%s).\n", rtld
);
1291 * Read the section headers.
1293 if (lseek(fd
, ehdr
->e_shoff
, 0) == -1 ||
1294 xread(fd
, shdrs
, size
) != size
) {
1295 printf("boot: error reading section headers\n");
1300 AUX64(*avp
, AT_SUN_LDELF
, (uintptr_t)ehdr
);
1301 AUX64(*avp
, AT_SUN_LDSHDR
, (uintptr_t)shdrs
);
1302 #else /* !BOOTAMD64 */
1303 AUX64(*avp
, AT_SUN_LDELF
, ehdr
);
1304 AUX64(*avp
, AT_SUN_LDSHDR
, shdrs
);
1305 #endif /* BOOTAMD64 */
1308 * Load sections into the appropriate dynamic segment.
1310 for (i
= 1; i
< ehdr
->e_shnum
; i
++) {
1312 Elf64_Addr
*spp
, load
;
1314 sp
= (Elf64_Shdr
*)(shdrs
+ (i
*ehdr
->e_shentsize
));
1316 * If it's not allocated and not required
1317 * to do relocation, skip it.
1319 if (!(sp
->sh_flags
& SHF_ALLOC
) &&
1320 sp
->sh_type
!= SHT_SYMTAB
&&
1321 sp
->sh_type
!= SHT_STRTAB
&&
1322 sp
->sh_type
!= SHT_RELA
)
1325 * If the section is read-only,
1326 * it goes in as text.
1328 spp
= (sp
->sh_flags
& SHF_WRITE
)? &edata
: &etext
;
1331 * Make some room for it.
1334 load
= ADDR_XTND(segbrk((caddr_t
*)spp
,
1335 sp
->sh_size
, sp
->sh_addralign
));
1336 #else /* !BOOTAMD64 */
1337 load
= (Elf64_Addr
)segbrk((caddr_t
*)spp
, sp
->sh_size
,
1339 #endif /* BOOTAMD64 */
1342 printf("boot: allocating memory for section %d "
1348 * Compute the entry point of the linker.
1350 if (dl_entry
== 0 &&
1351 !(sp
->sh_flags
& SHF_WRITE
) &&
1352 (sp
->sh_flags
& SHF_EXECINSTR
)) {
1353 dl_entry
= load
+ ehdr
->e_entry
;
1355 dprintf("boot: loading linker @ 0x%llx\n",
1356 (u_longlong_t
)dl_entry
);
1360 * If it's bss, just zero it out.
1362 if (sp
->sh_type
== SHT_NOBITS
) {
1363 bzero((caddr_t
)(uintptr_t)load
, sp
->sh_size
);
1366 * Read the section contents.
1368 if (lseek(fd
, sp
->sh_offset
, 0) == -1 ||
1369 xread(fd
, (caddr_t
)(uintptr_t)load
, sp
->sh_size
) !=
1371 printf("boot: error reading section %d\n", i
);
1376 * Assign the section's virtual addr.
1382 dprintf("boot: section %d, type %d, loaded @ 0x%llx, "
1383 "size 0x%llx\n", i
, sp
->sh_type
, (u_longlong_t
)load
,
1384 (u_longlong_t
)sp
->sh_size
);
1386 /* force instructions to be visible to icache */
1387 if (sp
->sh_flags
& SHF_EXECINSTR
)
1388 sync_instruction_memory((caddr_t
)(uintptr_t)sp
->sh_addr
,
1392 * Update sizes of segments.
1394 thdr
->p_memsz
= etext
- thdr
->p_vaddr
;
1395 dhdr
->p_memsz
= edata
- dhdr
->p_vaddr
;
1397 /* load and relocate symbol tables in SAS */
1405 kmem_free((caddr_t
)ehdr
, sizeof (Elf64_Ehdr
));
1407 kmem_free(shdrs
, size
);
1408 printf("boot: error loading interpreter (%s)\n", rtld
);
1409 return (FAIL_ILOAD64
);
1411 #endif /* _ELF64_SUPPORT */
1414 * Extend the segment's "break" value by bytes.
1417 segbrk(caddr_t
*spp
, size_t bytes
, size_t align
)
1421 unsigned int alloc_pagesize
= pagesize
;
1422 unsigned int alloc_align
= 0;
1425 alloc_align
= npagesize
;
1426 alloc_pagesize
= npagesize
;
1429 va
= (caddr_t
)ALIGN(*spp
, align
);
1430 pva
= (caddr_t
)roundup((uintptr_t)*spp
, alloc_pagesize
);
1434 if (va
+ bytes
> pva
) {
1435 size
= roundup((bytes
- (pva
- va
)), alloc_pagesize
);
1437 if (get_progmemory(pva
, size
, alloc_align
)) {
1438 printf("boot: segbrk allocation failed, "
1439 "0x%lx bytes @ %p\n", bytes
, (void *)pva
);
1449 * Open the file using a search path and
1450 * return the file descriptor (or -1 on failure).
1453 openpath(path
, fname
, flags
)
1458 register char *p
, *q
;
1459 char buf
[MAXPATHLEN
];
1463 * If the file name is absolute,
1464 * don't use the module search path.
1466 if (fname
[0] == '/')
1467 return (open(fname
, flags
));
1470 for (p
= path
; /* forever */; p
= q
) {
1472 while (*p
== ' ' || *p
== '\t' || *p
== ':')
1477 while (*q
&& *q
!= ' ' && *q
!= '\t' && *q
!= ':')
1479 (void) strncpy(buf
, p
, q
- p
);
1482 (void) strcpy(&buf
[q
- p
+ 1], fname
);
1485 * This checks for paths that end in '/'
1487 (void) strcpy(&buf
[q
- p
], fname
);
1490 if ((fd
= open(buf
, flags
)) > 0)
1497 * Get the module search path.
1503 register char *p
= strrchr(fname
, '/');
1504 static char mod_path
[MOD_MAXPATH
];
1506 extern char *impl_arch_name
;
1507 #if defined(__sparcv9) || defined(BOOTAMD64)
1509 char *isastr
= "/sparcv9";
1510 #endif /* __sparcv9 */
1512 char *isastr
= "/amd64";
1513 #endif /* BOOTAMD64 */
1514 size_t isalen
= strlen(isastr
);
1515 #endif /* __sparcv9 || BOOTAMD64 */
1518 /* strchr could not find a "/" */
1519 printf("%s is not a legal kernel pathname", fname
);
1522 while (p
> fname
&& *(p
- 1) == '/')
1523 p
--; /* remove trailing "/"s */
1525 p
++; /* "/" is the modpath in this case */
1528 (void) strncpy(mod_path
, fname
, len
);
1531 #if defined(__sparcv9) || defined(BOOTAMD64)
1532 len
= strlen(mod_path
);
1533 if ((len
> isalen
) && (strcmp(&mod_path
[len
- isalen
], isastr
) == 0)) {
1534 mod_path
[len
- isalen
] = '\0';
1535 #if defined(__sparcv9)
1536 if ((client_isLP64
== 0) && verbosemode
)
1537 printf("Assuming LP64 %s client.\n", isastr
);
1539 #endif /* __sparcv9 */
1541 #endif /* __sparcv9 || BOOTAMD64 */
1542 mod_path_uname_m(mod_path
, impl_arch_name
);
1543 (void) strcat(mod_path
, " ");
1544 (void) strcat(mod_path
, MOD_DEFPATH
);
1546 if (boothowto
& RB_ASKNAME
) {
1547 char buf
[MOD_MAXPATH
];
1549 printf("Enter default directory for modules [%s]: ", mod_path
);
1550 (void) cons_gets(buf
, sizeof (buf
));
1552 (void) strcpy(mod_path
, buf
);
1555 printf("modpath: %s\n", mod_path
);