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