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