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