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