1 1.33 jmcneill /* $NetBSD: loadfile.c,v 1.33 2021/05/21 21:52:15 jmcneill Exp $ */ 2 1.1 christos 3 1.1 christos /*- 4 1.29 ad * Copyright (c) 1997, 2008 The NetBSD Foundation, Inc. 5 1.1 christos * All rights reserved. 6 1.1 christos * 7 1.1 christos * This code is derived from software contributed to The NetBSD Foundation 8 1.1 christos * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 1.1 christos * NASA Ames Research Center and by Christos Zoulas. 10 1.1 christos * 11 1.1 christos * Redistribution and use in source and binary forms, with or without 12 1.1 christos * modification, are permitted provided that the following conditions 13 1.1 christos * are met: 14 1.1 christos * 1. Redistributions of source code must retain the above copyright 15 1.1 christos * notice, this list of conditions and the following disclaimer. 16 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 christos * notice, this list of conditions and the following disclaimer in the 18 1.1 christos * documentation and/or other materials provided with the distribution. 19 1.1 christos * 20 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.1 christos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 christos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 christos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.1 christos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.1 christos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.1 christos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.1 christos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 christos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 christos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 christos * POSSIBILITY OF SUCH DAMAGE. 31 1.1 christos */ 32 1.1 christos 33 1.1 christos /* 34 1.1 christos * Copyright (c) 1992, 1993 35 1.1 christos * The Regents of the University of California. All rights reserved. 36 1.1 christos * 37 1.1 christos * This code is derived from software contributed to Berkeley by 38 1.1 christos * Ralph Campbell. 39 1.1 christos * 40 1.1 christos * Redistribution and use in source and binary forms, with or without 41 1.1 christos * modification, are permitted provided that the following conditions 42 1.1 christos * are met: 43 1.1 christos * 1. Redistributions of source code must retain the above copyright 44 1.1 christos * notice, this list of conditions and the following disclaimer. 45 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright 46 1.1 christos * notice, this list of conditions and the following disclaimer in the 47 1.1 christos * documentation and/or other materials provided with the distribution. 48 1.23 agc * 3. Neither the name of the University nor the names of its contributors 49 1.1 christos * may be used to endorse or promote products derived from this software 50 1.1 christos * without specific prior written permission. 51 1.1 christos * 52 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 1.1 christos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 1.1 christos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 1.1 christos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 1.1 christos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 1.1 christos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 1.1 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 1.1 christos * SUCH DAMAGE. 63 1.1 christos * 64 1.1 christos * @(#)boot.c 8.1 (Berkeley) 6/10/93 65 1.1 christos */ 66 1.1 christos 67 1.1 christos #ifdef _STANDALONE 68 1.1 christos #include <lib/libsa/stand.h> 69 1.6 thorpej #include <lib/libkern/libkern.h> 70 1.1 christos #else 71 1.1 christos #include <stdio.h> 72 1.1 christos #include <string.h> 73 1.1 christos #include <errno.h> 74 1.1 christos #include <stdlib.h> 75 1.1 christos #include <unistd.h> 76 1.1 christos #include <fcntl.h> 77 1.1 christos #include <err.h> 78 1.1 christos #endif 79 1.1 christos 80 1.1 christos #include <sys/param.h> 81 1.1 christos #include <sys/exec.h> 82 1.1 christos 83 1.1 christos #include "loadfile.h" 84 1.1 christos 85 1.29 ad uint32_t netbsd_version; 86 1.30 ad u_int netbsd_elf_class; 87 1.33 jmcneill u_int netbsd_elf_data; 88 1.29 ad 89 1.1 christos /* 90 1.21 pk * Open 'filename', read in program and return the opened file 91 1.21 pk * descriptor if ok, or -1 on error. 92 1.1 christos * Fill in marks 93 1.1 christos */ 94 1.1 christos int 95 1.27 tsutsui loadfile(const char *fname, u_long *marks, int flags) 96 1.1 christos { 97 1.22 pk int fd, error; 98 1.22 pk 99 1.22 pk /* Open the file. */ 100 1.22 pk if ((fd = open(fname, 0)) < 0) { 101 1.22 pk WARN(("open %s", fname ? fname : "<default>")); 102 1.26 isaki return -1; 103 1.22 pk } 104 1.22 pk 105 1.22 pk /* Load it; save the value of errno across the close() call */ 106 1.22 pk if ((error = fdloadfile(fd, marks, flags)) != 0) { 107 1.22 pk (void)close(fd); 108 1.22 pk errno = error; 109 1.26 isaki return -1; 110 1.22 pk } 111 1.22 pk 112 1.26 isaki return fd; 113 1.22 pk } 114 1.22 pk 115 1.22 pk /* 116 1.22 pk * Read in program from the given file descriptor. 117 1.22 pk * Return error code (0 on success). 118 1.22 pk * Fill in marks. 119 1.22 pk */ 120 1.22 pk int 121 1.27 tsutsui fdloadfile(int fd, u_long *marks, int flags) 122 1.22 pk { 123 1.1 christos union { 124 1.1 christos #ifdef BOOT_ECOFF 125 1.1 christos struct ecoff_exechdr coff; 126 1.1 christos #endif 127 1.20 thorpej #ifdef BOOT_ELF32 128 1.20 thorpej Elf32_Ehdr elf32; 129 1.20 thorpej #endif 130 1.20 thorpej #ifdef BOOT_ELF64 131 1.20 thorpej Elf64_Ehdr elf64; 132 1.1 christos #endif 133 1.1 christos #ifdef BOOT_AOUT 134 1.1 christos struct exec aout; 135 1.1 christos #endif 136 1.1 christos } hdr; 137 1.1 christos ssize_t nr; 138 1.22 pk int rval; 139 1.1 christos 140 1.1 christos /* Read the exec header. */ 141 1.22 pk if (lseek(fd, 0, SEEK_SET) == (off_t)-1) 142 1.22 pk goto err; 143 1.25 chs nr = read(fd, &hdr, sizeof(hdr)); 144 1.25 chs if (nr == -1) { 145 1.25 chs WARN(("read header failed")); 146 1.25 chs goto err; 147 1.25 chs } 148 1.25 chs if (nr != sizeof(hdr)) { 149 1.25 chs WARN(("read header short")); 150 1.25 chs errno = EFTYPE; 151 1.1 christos goto err; 152 1.1 christos } 153 1.1 christos 154 1.1 christos #ifdef BOOT_ECOFF 155 1.1 christos if (!ECOFF_BADMAG(&hdr.coff)) { 156 1.19 thorpej rval = loadfile_coff(fd, &hdr.coff, marks, flags); 157 1.1 christos } else 158 1.1 christos #endif 159 1.20 thorpej #ifdef BOOT_ELF32 160 1.20 thorpej if (memcmp(hdr.elf32.e_ident, ELFMAG, SELFMAG) == 0 && 161 1.20 thorpej hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) { 162 1.30 ad netbsd_elf_class = ELFCLASS32; 163 1.33 jmcneill netbsd_elf_data = hdr.elf32.e_ident[EI_DATA]; 164 1.20 thorpej rval = loadfile_elf32(fd, &hdr.elf32, marks, flags); 165 1.20 thorpej } else 166 1.20 thorpej #endif 167 1.20 thorpej #ifdef BOOT_ELF64 168 1.20 thorpej if (memcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 && 169 1.20 thorpej hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) { 170 1.30 ad netbsd_elf_class = ELFCLASS64; 171 1.33 jmcneill netbsd_elf_data = hdr.elf64.e_ident[EI_DATA]; 172 1.20 thorpej rval = loadfile_elf64(fd, &hdr.elf64, marks, flags); 173 1.1 christos } else 174 1.1 christos #endif 175 1.1 christos #ifdef BOOT_AOUT 176 1.8 ragge if (OKMAGIC(N_GETMAGIC(hdr.aout)) 177 1.8 ragge #ifndef NO_MID_CHECK 178 1.8 ragge && N_GETMID(hdr.aout) == MID_MACHINE 179 1.8 ragge #endif 180 1.8 ragge ) { 181 1.19 thorpej rval = loadfile_aout(fd, &hdr.aout, marks, flags); 182 1.1 christos } else 183 1.1 christos #endif 184 1.1 christos { 185 1.1 christos rval = 1; 186 1.1 christos errno = EFTYPE; 187 1.1 christos } 188 1.1 christos 189 1.1 christos if (rval == 0) { 190 1.21 pk if ((flags & LOAD_ALL) != 0) 191 1.32 christos PROGRESS(("=0x%lx\n", 192 1.21 pk marks[MARK_END] - marks[MARK_START])); 193 1.26 isaki return 0; 194 1.1 christos } 195 1.1 christos err: 196 1.26 isaki return errno; 197 1.1 christos } 198