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