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