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
48union {
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
58typedef 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
66int 	use_align = 0;
67int 	npagesize = 0;
68uint_t 	icache_flush = 0;
69char 	*cpulist = NULL;
70char	*mmulist = NULL;
71char	*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 */
84Elf32_Boot *elfbootvecELF32_64;
85#endif	/* !BOOTAMD64 */
86
87Elf64_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 */
99Elf32_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
110static int debug = 1;
111#else /* DEBUG */
112static int debug = 0;
113#endif /* DEBUG */
114
115#define	dprintf		if (debug) printf
116
117#ifdef	_ELF64_SUPPORT
118typedef 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)
133extern int client_isLP64;
134#endif	/* __sparcv9 */
135
136static uint64_t read_elf64(int, int, Elf64_Ehdr *);
137static Elf64_Addr iload64(char *, Elf64_Phdr *, Elf64_Phdr *, auxv64_t **);
138#endif	/* _ELF64_SUPPORT */
139
140#if defined(i386) && !defined(_SYSCALL32)
141typedef auxv_t	auxv32_t;
142#endif
143
144static func_t 	read_elf32(int, int, Elf32_Ehdr *);
145static func_t	iload32(char *, Elf32_Phdr *, Elf32_Phdr *, auxv32_t **);
146static caddr_t	segbrk(caddr_t *, size_t, size_t);
147static int	openpath(char *, char *, int);
148static char	*getmodpath(char *);
149extern void	setup_aux(void);
150
151extern void	*kmem_alloc(size_t, int);
152extern void	kmem_free(void *, size_t);
153extern int	cons_gets(char *, int);
154
155#ifdef	BOOTAMD64
156extern const char *amd64_getmmulist(void);
157
158extern int amd64_elf64;
159extern int is_amd64;
160#endif	/* BOOTAMD64 */
161
162#ifdef	lint
163/*
164 * This function is currently inlined
165 */
166/*ARGSUSED*/
167void
168sync_instruction_memory(caddr_t v, size_t len)
169{}
170#else	/* lint */
171extern void sync_instruction_memory(caddr_t v, size_t len);
172#endif	/* lint */
173
174extern int 	verbosemode;
175extern int	boothowto;
176extern int	pagesize;
177extern 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 */
183ssize_t
184xread(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
204func_t
205readfile(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
325static func_t
326read_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
704elferror:
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
724static uint64_t
725read_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
1085elf64error:
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 */
1100static func_t
1101iload32(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
1235error:
1236	(void) close(fd);
1237errorx:
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 */
1252static Elf64_Addr
1253iload64(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
1411error:
1412	(void) close(fd);
1413errorx:
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 */
1426static caddr_t
1427segbrk(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 */
1462static int
1463openpath(path, fname, flags)
1464char *path;
1465char *fname;
1466int 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 */
1509static char *
1510getmodpath(fname)
1511char *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