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