xref: /minix3/sys/lib/libsa/loadfile.c (revision 58a2b0008e28f606a7f7f5faaeaba4faac57a1ea)
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