1 /* $NetBSD: loadfile.c,v 1.10 2000/12/03 02:53:04 tsutsui Exp $ */ 2 /* $OpenBSD: loadfile.c,v 1.19 2013/10/17 08:45:02 deraadt Exp $ */ 3 4 /*- 5 * Copyright (c) 1997 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center and by Christos Zoulas. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (c) 1992, 1993 36 * The Regents of the University of California. All rights reserved. 37 * 38 * This code is derived from software contributed to Berkeley by 39 * Ralph Campbell. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * @(#)boot.c 8.1 (Berkeley) 6/10/93 66 */ 67 68 #ifdef _STANDALONE 69 #include <lib/libkern/libkern.h> 70 #include <lib/libsa/stand.h> 71 #else 72 #include <stdio.h> 73 #include <string.h> 74 #include <errno.h> 75 #include <stdlib.h> 76 #include <unistd.h> 77 #include <fcntl.h> 78 #include <err.h> 79 #endif 80 81 #include <sys/param.h> 82 #include <sys/exec.h> 83 84 #include "loadfile.h" 85 86 #ifdef BOOT_ELF 87 #include <sys/exec_elf.h> 88 #if defined(BOOT_ELF32) && defined(BOOT_ELF64) 89 /* 90 * Both defined, so elf32_exec() and elf64_exec() need to be separately 91 * created (can't do it by including loadfile_elf.c here). 92 */ 93 int elf32_exec(int, Elf32_Ehdr *, u_long *, int); 94 int elf64_exec(int, Elf64_Ehdr *, u_long *, int); 95 #else 96 #include "loadfile_elf.c" 97 #endif 98 #endif 99 100 /* 101 * Open 'filename', read in program and return -1 on error otherwise fd, 102 * with file still open. 103 * Also fills in marks. 104 */ 105 int 106 loadfile(const char *fname, u_long *marks, int flags) 107 { 108 union { 109 #if defined(BOOT_ELF32) || (defined(BOOT_ELF) && ELFSIZE == 32) 110 Elf32_Ehdr elf32; 111 #endif 112 #if defined(BOOT_ELF64) || (defined(BOOT_ELF) && ELFSIZE == 64) 113 Elf64_Ehdr elf64; 114 #endif 115 116 } hdr; 117 ssize_t nr; 118 int fd, rval; 119 120 /* Open the file. */ 121 if ((fd = open(fname, 0)) < 0) { 122 WARN(("open %s", fname ? fname : "<default>")); 123 return -1; 124 } 125 126 /* Read the exec header. */ 127 if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) { 128 WARN(("read header")); 129 goto err; 130 } 131 132 #if defined(BOOT_ELF32) || (defined(BOOT_ELF) && ELFSIZE == 32) 133 if (memcmp(hdr.elf32.e_ident, ELFMAG, SELFMAG) == 0 && 134 hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) { 135 rval = elf32_exec(fd, &hdr.elf32, marks, flags); 136 } else 137 #endif 138 #if defined(BOOT_ELF64) || (defined(BOOT_ELF) && ELFSIZE == 64) 139 if (memcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 && 140 hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) { 141 rval = elf64_exec(fd, &hdr.elf64, marks, flags); 142 } else 143 #endif 144 { 145 rval = 1; 146 errno = EFTYPE; 147 WARN(("%s", fname ? fname : "<default>")); 148 } 149 150 if (rval == 0) { 151 PROGRESS(("=0x%lx\n", marks[MARK_END] - marks[MARK_START])); 152 return fd; 153 } 154 err: 155 (void)close(fd); 156 return -1; 157 } 158