Annotation of sys/arch/alpha/stand/loadfile.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: loadfile.c,v 1.17 2005/08/10 16:58:42 todd Exp $ */
! 2: /* $NetBSD: loadfile.c,v 1.3 1997/04/06 08:40:59 cgd Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1992, 1993
! 6: * The Regents of the University of California. All rights reserved.
! 7: *
! 8: * This code is derived from software contributed to Berkeley by
! 9: * Ralph Campbell.
! 10: *
! 11: * Redistribution and use in source and binary forms, with or without
! 12: * modification, are permitted provided that the following conditions
! 13: * are met:
! 14: * 1. Redistributions of source code must retain the above copyright
! 15: * notice, this list of conditions and the following disclaimer.
! 16: * 2. Redistributions in binary form must reproduce the above copyright
! 17: * notice, this list of conditions and the following disclaimer in the
! 18: * documentation and/or other materials provided with the distribution.
! 19: * 3. Neither the name of the University nor the names of its contributors
! 20: * may be used to endorse or promote products derived from this software
! 21: * without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 33: * SUCH DAMAGE.
! 34: *
! 35: * @(#)boot.c 8.1 (Berkeley) 6/10/93
! 36: */
! 37:
! 38: #define ELFSIZE 64
! 39:
! 40: #include <lib/libkern/libkern.h>
! 41: #include <lib/libsa/stand.h>
! 42:
! 43: #include <sys/param.h>
! 44: #include <sys/exec.h>
! 45: #include <sys/exec_ecoff.h>
! 46: #include <sys/exec_elf.h>
! 47:
! 48: #include <machine/rpb.h>
! 49: #include <machine/prom.h>
! 50:
! 51: #include <ddb/db_aout.h>
! 52:
! 53: #define _KERNEL
! 54: #include "include/pte.h"
! 55:
! 56: #ifdef ALPHA_BOOT_ELF
! 57: static int elf_exec(int, Elf64_Ehdr *, u_int64_t *);
! 58: #endif
! 59: int loadfile(char *, u_int64_t *);
! 60:
! 61: paddr_t ffp_save, ptbr_save;
! 62: vaddr_t ssym, esym;
! 63:
! 64: #define WARN(...)
! 65:
! 66: /*
! 67: * Open 'filename', read in program and return the entry point or -1 if error.
! 68: */
! 69: int
! 70: loadfile(fname, entryp)
! 71: char *fname;
! 72: u_int64_t *entryp;
! 73: {
! 74: struct devices *dp;
! 75: union {
! 76: #ifdef ALPHA_BOOT_ELF
! 77: Elf64_Ehdr elf;
! 78: #endif
! 79: } hdr;
! 80: int fd, rval;
! 81:
! 82: (void)printf("Loading %s...\n", fname);
! 83:
! 84: /* Open the file. */
! 85: rval = 1;
! 86: if ((fd = open(fname, 0)) < 0) {
! 87: WARN(("open %s: errno %d\n", fname, errno));
! 88: goto err;
! 89: }
! 90:
! 91: /* Read the exec header. */
! 92: if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
! 93: WARN(("read header: %s\n", strerror(errno)));
! 94: goto err;
! 95: }
! 96:
! 97: #ifdef ALPHA_BOOT_ELF
! 98: if (memcmp(ELFMAG, hdr.elf.e_ident, SELFMAG) == 0) {
! 99: rval = elf_exec(fd, &hdr.elf, entryp);
! 100: } else
! 101: #endif
! 102: {
! 103: (void)printf("%s: unknown executable format\n", fname);
! 104: }
! 105:
! 106: err:
! 107: if (fd >= 0)
! 108: (void)close(fd);
! 109: return (rval);
! 110: }
! 111:
! 112: #ifdef ALPHA_BOOT_ELF
! 113: static int
! 114: elf_exec(fd, elf, entryp)
! 115: int fd;
! 116: Elf64_Ehdr *elf;
! 117: u_int64_t *entryp;
! 118: {
! 119: int i;
! 120: int first = 1, havesyms;
! 121: Elf64_Shdr *shp;
! 122: Elf64_Off off;
! 123: size_t sz;
! 124:
! 125: for (i = 0; i < elf->e_phnum; i++) {
! 126: Elf64_Phdr phdr;
! 127: (void)lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET);
! 128: if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
! 129: WARN(("read phdr: %s\n", strerror(errno)));
! 130: return (1);
! 131: }
! 132: if (phdr.p_type != PT_LOAD ||
! 133: (phdr.p_flags & (PF_W|PF_X)) == 0)
! 134: continue;
! 135:
! 136: /* Read in segment. */
! 137: (void)printf("%s%lu", first ? "" : "+", phdr.p_filesz);
! 138: (void)lseek(fd, phdr.p_offset, SEEK_SET);
! 139: if (read(fd, (void *)phdr.p_vaddr, phdr.p_filesz) !=
! 140: phdr.p_filesz) {
! 141: WARN(("read text: %s\n", strerror(errno)));
! 142: return (1);
! 143: }
! 144: if (first || ffp_save < phdr.p_vaddr + phdr.p_memsz)
! 145: ffp_save = phdr.p_vaddr + phdr.p_memsz;
! 146:
! 147: /* Zero out bss. */
! 148: if (phdr.p_filesz < phdr.p_memsz) {
! 149: (void)printf("+%lu", phdr.p_memsz - phdr.p_filesz);
! 150: bzero((caddr_t)phdr.p_vaddr + phdr.p_filesz,
! 151: phdr.p_memsz - phdr.p_filesz);
! 152: }
! 153: first = 0;
! 154: }
! 155:
! 156: ffp_save = roundup(ffp_save, sizeof(long));
! 157:
! 158: /*
! 159: * Retrieve symbols.
! 160: */
! 161: ssym = ffp_save;
! 162: ffp_save += sizeof(Elf64_Ehdr);
! 163:
! 164: if (lseek(fd, elf->e_shoff, SEEK_SET) == -1) {
! 165: WARN(("seek to section headers: %s\n", strerror(errno)));
! 166: return (1);
! 167: }
! 168:
! 169: sz = elf->e_shnum * sizeof(Elf64_Shdr);
! 170: shp = (Elf64_Shdr *)ffp_save;
! 171: ffp_save += roundup(sz, sizeof(long));
! 172:
! 173: if (read(fd, shp, sz) != sz) {
! 174: WARN(("read section headers: %d\n", strerror(errno)));
! 175: return (1);
! 176: }
! 177:
! 178: /*
! 179: * Now load the symbol sections themselves. Make sure the
! 180: * sections are aligned. Don't bother with string tables if
! 181: * there are no symbol sections.
! 182: */
! 183: off = roundup((sizeof(Elf64_Ehdr) + sz), sizeof(long));
! 184:
! 185: for (havesyms = i = 0; i < elf->e_shnum; i++)
! 186: if (shp[i].sh_type == SHT_SYMTAB)
! 187: havesyms = 1;
! 188:
! 189: if (!havesyms)
! 190: goto no_syms;
! 191:
! 192: for (first = 1, i = 0; i < elf->e_shnum; i++) {
! 193: if (shp[i].sh_type == SHT_SYMTAB ||
! 194: shp[i].sh_type == SHT_STRTAB) {
! 195: printf("%s%ld", first ? " [" : "+",
! 196: (u_long)shp[i].sh_size);
! 197: if (lseek(fd, shp[i].sh_offset, SEEK_SET) == -1) {
! 198: WARN(("lseek symbols: %s\n", strerror(errno)));
! 199: return (1);
! 200: }
! 201: if (read(fd, (void *)ffp_save, shp[i].sh_size) !=
! 202: shp[i].sh_size) {
! 203: WARN(("read symbols: %s\n", strerror(errno)));
! 204: return (1);
! 205: }
! 206: ffp_save += roundup(shp[i].sh_size, sizeof(long));
! 207: shp[i].sh_offset = off;
! 208: off += roundup(shp[i].sh_size, sizeof(long));
! 209: first = 0;
! 210: }
! 211: }
! 212: if (havesyms && first == 0)
! 213: printf("]");
! 214:
! 215: elf->e_phoff = 0;
! 216: elf->e_shoff = sizeof(Elf64_Ehdr);
! 217: elf->e_phentsize = 0;
! 218: elf->e_phnum = 0;
! 219: bcopy(elf, (void *)ssym, sizeof(*elf));
! 220:
! 221: no_syms:
! 222: esym = ffp_save;
! 223: ffp_save = ALPHA_K0SEG_TO_PHYS((ffp_save + PGOFSET & ~PGOFSET)) >> PGSHIFT;
! 224: ffp_save += 2; /* XXX OSF/1 does this, no idea why. */
! 225:
! 226: (void)printf("\n");
! 227: *entryp = elf->e_entry;
! 228: return (0);
! 229: }
! 230: #endif /* ALPHA_BOOT_ELF */
CVSweb