summaryrefslogtreecommitdiff
path: root/sys/arch/sparc/stand/boot/loadfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/sparc/stand/boot/loadfile.c')
-rw-r--r--sys/arch/sparc/stand/boot/loadfile.c371
1 files changed, 0 insertions, 371 deletions
diff --git a/sys/arch/sparc/stand/boot/loadfile.c b/sys/arch/sparc/stand/boot/loadfile.c
deleted file mode 100644
index 470512a1bea..00000000000
--- a/sys/arch/sparc/stand/boot/loadfile.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/* $OpenBSD: loadfile.c,v 1.5 2003/08/14 17:13:57 deraadt Exp $ */
-/* $NetBSD: loadfile.c,v 1.3 1997/04/06 08:40:59 cgd Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)boot.c 8.1 (Berkeley) 6/10/93
- */
-
-#define ELFSIZE 32
-
-#include <lib/libkern/libkern.h>
-#include <lib/libsa/stand.h>
-#include <sparc/stand/common/promdev.h>
-
-#include <sys/param.h>
-#include <sys/exec.h>
-#include <sys/exec_elf.h>
-
-#include <ddb/db_aout.h>
-
-#ifdef SPARC_BOOT_AOUT
-static int aout_exec(int, struct exec *, vaddr_t *);
-#endif
-#ifdef SPARC_BOOT_ELF
-static int elf_exec(int, Elf_Ehdr *, vaddr_t *);
-#endif
-int loadfile(int, vaddr_t *);
-
-vaddr_t ssym, esym;
-
-union {
-#ifdef SPARC_BOOT_AOUT
- struct exec aout;
-#endif
-#ifdef SPARC_BOOT_ELF
- Elf_Ehdr elf;
-#endif
-} hdr;
-
-/*
- * Open 'filename', read in program and return the entry point or -1 if error.
- */
-int
-loadfile(int fd, vaddr_t *entryp)
-{
- struct devices *dp;
- int rval;
-
- /* Read the exec header. */
- if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
- printf("read header: %s\n", strerror(errno));
- goto err;
- }
-
-#ifdef SPARC_BOOT_ELF
- if (memcmp(ELFMAG, hdr.elf.e_ident, SELFMAG) == 0) {
- rval = elf_exec(fd, &hdr.elf, entryp);
- } else
-#endif
-#ifdef SPARC_BOOT_AOUT
- if (!N_BADMAG(hdr.aout)) {
- rval = aout_exec(fd, &hdr.aout, entryp);
- } else
-#endif
- {
- printf("unknown executable format\n");
- }
-
-err:
- if (fd >= 0)
- close(fd);
- return (rval);
-}
-
-#ifdef SPARC_BOOT_AOUT
-static int
-aout_exec(int fd, struct exec *aout, vaddr_t *entryp)
-{
- caddr_t addr = (caddr_t)LOADADDR;
- int strtablen;
- char *strtab;
- vaddr_t entry = (vaddr_t)LOADADDR;
- int i;
-
- printf("%d", aout->a_text);
- if (N_GETMAGIC(*aout) == ZMAGIC) {
- entry = (vaddr_t)(addr+sizeof(struct exec));
- addr += sizeof(struct exec);
- }
- /* we can't lseek() here - we may be booting off tape */
- bcopy((char *)aout + sizeof(struct exec), addr,
- sizeof(hdr) - sizeof(struct exec));
- if (read(fd, (char *)addr + sizeof(hdr) - sizeof(struct exec),
- aout->a_text - (sizeof(hdr) - sizeof(struct exec))) !=
- aout->a_text - (sizeof(hdr) - sizeof(struct exec)))
- goto shread;
- addr += aout->a_text;
- if (N_GETMAGIC(*aout) == ZMAGIC || N_GETMAGIC(*aout) == NMAGIC)
- while ((int)addr & __LDPGSZ)
- *addr++ = 0;
- printf("+%d", aout->a_data);
- if (read(fd, addr, aout->a_data) != aout->a_data)
- goto shread;
- addr += aout->a_data;
- printf("+%d", aout->a_bss);
- for (i = aout->a_bss; i ; --i)
- *addr++ = 0;
- if (aout->a_syms != 0) {
- bcopy(&aout->a_syms, addr, sizeof(aout->a_syms));
- addr += sizeof(aout->a_syms);
- printf("+[%d", aout->a_syms);
- if (read(fd, addr, aout->a_syms) != aout->a_syms)
- goto shread;
- addr += aout->a_syms;
-
- if (read(fd, &strtablen, sizeof(int)) != sizeof(int))
- goto shread;
-
- bcopy(&strtablen, addr, sizeof(int));
- if (i = strtablen) {
- i -= sizeof(int);
- addr += sizeof(int);
- if (read(fd, addr, i) != i)
- goto shread;
- addr += i;
- }
- printf("+%d]", i);
- esym = ((u_int)aout->a_entry - (u_int)LOADADDR) +
- (((int)addr + sizeof(int) - 1) & ~(sizeof(int) - 1));
- }
- printf("=0x%x\n", addr);
- close(fd);
-
- *entryp = entry;
- return (0);
-
-shread:
- printf("boot: short read\n");
- return (1);
-}
-#endif /* SPARC_BOOT_AOUT */
-
-#ifdef SPARC_BOOT_ELF
-
-/*
- * If we're booting off tape, we can't seek.
- * Emulate forward moves with reads, and give up on backwards moves.
- * bsd.rd ought to be correctly ordered.
- */
-static int
-elf_seek(int fd, off_t relpos)
-{
-#define DUMBBUFSIZE 4096
- char dumbbuf[DUMBBUFSIZE];
- int len;
-
- if (relpos < 0) {
-#ifdef DEBUG
- printf("elf_seek: attempting to seek backwards from %llx bytes, "
- "may fail!\n", -relpos);
-#endif
- if (lseek(fd, relpos, SEEK_CUR) < 0)
- return (-1);
- return (0);
- }
-
- while (relpos != 0) {
- len = relpos > DUMBBUFSIZE ? DUMBBUFSIZE : relpos;
- if (read(fd, dumbbuf, len) != len)
- return (-1);
- relpos -= len;
- }
-
- return (0);
-#undef DUMBBUFSIZE
-}
-
-static int
-elf_exec(int fd, Elf_Ehdr *elf, vaddr_t *entryp)
-{
- int i;
- int first = 1, havesyms;
- Elf_Shdr *shp;
- Elf_Off off;
- size_t sz;
- vaddr_t addr = 0;
- Elf_Ehdr *fake_elf;
-#define NUM_HEADERS 12 /* should be more than enough */
- Elf_Phdr headers[NUM_HEADERS], *phdr;
- off_t pos, newpos;
-
- *entryp = 0;
-
-#define A(x) ((x) - *entryp + (vaddr_t)LOADADDR)
-
- pos = sizeof(hdr);
-
- /* load the headers */
- if (elf->e_phnum > NUM_HEADERS)
- elf->e_phnum = NUM_HEADERS; /* amnesia rules */
- newpos = elf->e_phoff;
- if (elf_seek(fd, newpos - pos))
- return (1);
- pos = newpos;
- if (read(fd, (void *)headers, elf->e_phnum * sizeof(Elf_Phdr)) !=
- elf->e_phnum * sizeof(Elf_Phdr)) {
- printf("read phdr: %s\n", strerror(errno));
- return (1);
- }
- pos += elf->e_phnum * sizeof(Elf_Phdr);
-
- /* loop through the pheaders and find the entry point. */
- for (i = 0; i < elf->e_phnum; i++) {
- phdr = &headers[i];
- if (phdr->p_type != PT_LOAD ||
- (phdr->p_flags & (PF_W|PF_X)) == 0 ||
- (phdr->p_vaddr != elf->e_entry))
- continue;
-
- *entryp = phdr->p_vaddr;
- }
-
- if (*entryp == 0) {
- printf("Can't find entry point.\n");
- return (-1);
- }
-
- for (i = 0; i < elf->e_phnum; i++) {
- phdr = &headers[i];
- if (phdr->p_type != PT_LOAD ||
- (phdr->p_flags & (PF_W|PF_X)) == 0)
- continue;
-
- /* Read in segment. */
- printf("%s%lu", first ? "" : "+", phdr->p_filesz);
- newpos = phdr->p_offset;
- if (elf_seek(fd, newpos - pos))
- return (1);
- pos = newpos;
-
- if (read(fd, (caddr_t)A(phdr->p_vaddr), phdr->p_filesz) !=
- phdr->p_filesz) {
- (void)printf("read text: %s\n", strerror(errno));
- return (1);
- }
- pos += phdr->p_filesz;
-
- /* keep track of highest addr we loaded. */
- if (first || addr < (phdr->p_vaddr + phdr->p_memsz))
- addr = (phdr->p_vaddr + phdr->p_memsz);
-
- /* Zero out bss. */
- if (phdr->p_filesz < phdr->p_memsz) {
- printf("+%lu", phdr->p_memsz - phdr->p_filesz);
- bzero((caddr_t)A(phdr->p_vaddr) + phdr->p_filesz,
- phdr->p_memsz - phdr->p_filesz);
- }
- first = 0;
- }
-
- addr = A(addr);
- addr = roundup(addr, sizeof(long));
-
- ssym = addr;
- /*
- * Retrieve symbols.
- */
- addr += sizeof(Elf_Ehdr);
-
- newpos = elf->e_shoff;
- if (elf_seek(fd, newpos - pos)) {
- printf("seek to section headers: %s\n", strerror(errno));
- return (1);
- }
- pos = newpos;
-
- sz = elf->e_shnum * sizeof(Elf_Shdr);
- shp = (Elf_Shdr *)addr;
- addr += roundup(sz, sizeof(long));
-
- if (read(fd, shp, sz) != sz) {
- printf("read section headers: %d\n", strerror(errno));
- return (1);
- }
- pos += sz;
-
- /*
- * Now load the symbol sections themselves. Make sure the
- * sections are aligned. Don't bother with string tables if
- * there are no symbol sections.
- */
- off = roundup((sizeof(Elf_Ehdr) + sz), sizeof(long));
-
- for (havesyms = i = 0; i < elf->e_shnum; i++)
- if (shp[i].sh_type == SHT_SYMTAB)
- havesyms = 1;
-
- if (!havesyms)
- goto no_syms;
-
- for (first = 1, i = 0; i < elf->e_shnum; i++) {
- if (shp[i].sh_type == SHT_SYMTAB ||
- shp[i].sh_type == SHT_STRTAB) {
- printf("%s%ld", first ? " [" : "+",
- (u_long)shp[i].sh_size);
- newpos = shp[i].sh_offset;
- if (elf_seek(fd, newpos - pos)) {
- printf("lseek symbols: %s\n", strerror(errno));
- return (1);
- }
- pos = newpos;
- if (read(fd, (void *)addr, shp[i].sh_size) !=
- shp[i].sh_size) {
- printf("read symbols: %s\n", strerror(errno));
- return (1);
- }
- pos += shp[i].sh_size;
- addr += roundup(shp[i].sh_size, sizeof(long));
- shp[i].sh_offset = off;
- off += roundup(shp[i].sh_size, sizeof(long));
- first = 0;
- }
- }
- if (havesyms && first == 0)
- printf("]");
-
- elf->e_phoff = 0;
- elf->e_shoff = sizeof(Elf_Ehdr);
- elf->e_phentsize = 0;
- elf->e_phnum = 0;
- bcopy(elf, (void *)ssym, sizeof(*elf));
-
-no_syms:
- esym = (addr - (vaddr_t)LOADADDR) + *entryp;
-
- *entryp = (vaddr_t)LOADADDR;
-
- printf("\n");
- return (0);
-#undef NUM_HEADERS
-}
-#endif /* SPARC_BOOT_ELF */