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