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