FreeBSD/Linux Kernel Cross Reference
sys/lib/libsa/exec.c
1 /* $NetBSD: exec.c,v 1.23 2003/08/31 22:40:48 fvdl Exp $ */
2
3 /*-
4 * Copyright (c) 1982, 1986, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #ifdef _KERNEL_OPT
33 #include "opt_insecure.h"
34 #endif
35
36 #include <sys/param.h>
37 #include <sys/reboot.h>
38 #ifndef INSECURE
39 #include <sys/stat.h>
40 #endif
41 #include <sys/exec.h>
42 #ifdef _STANDALONE
43 #include <lib/libkern/libkern.h>
44 #else
45 #include <string.h>
46 #endif
47
48 #include "stand.h"
49
50 void
51 exec(path, loadaddr, howto)
52 char *path;
53 char *loadaddr;
54 int howto;
55 {
56 #ifndef INSECURE
57 struct stat sb;
58 #endif
59 struct exec x;
60 int io, i;
61 char *addr, *ssym, *esym;
62
63 io = open(path, 0);
64 if (io < 0)
65 return;
66
67 #ifndef INSECURE
68 (void) fstat(io, &sb);
69 if (sb.st_uid || (sb.st_mode & 2)) {
70 printf("non-secure file, will not load\n");
71 close(io);
72 errno = EPERM;
73 return;
74 }
75 #endif
76
77 i = read(io, (char *)&x, sizeof(x));
78 if (i != sizeof(x) || N_BADMAG(x)) {
79 errno = EFTYPE;
80 return;
81 }
82
83 /* Text */
84 printf("%ld", x.a_text);
85 addr = loadaddr;
86 if (N_GETMAGIC(x) == ZMAGIC) {
87 bcopy(&x, addr, sizeof(x));
88 addr += sizeof(x);
89 x.a_text -= sizeof(x);
90 }
91 if (read(io, (char *)addr, x.a_text) != (ssize_t)x.a_text)
92 goto shread;
93 addr += x.a_text;
94 if (N_GETMAGIC(x) == ZMAGIC || N_GETMAGIC(x) == NMAGIC)
95 while ((long)addr & (N_PAGSIZ(x) - 1))
96 *addr++ = 0;
97
98 /* Data */
99 printf("+%ld", x.a_data);
100 if (read(io, addr, x.a_data) != (ssize_t)x.a_data)
101 goto shread;
102 addr += x.a_data;
103
104 /* Bss */
105 printf("+%ld", x.a_bss);
106 for (i = 0; i < (int)x.a_bss; i++)
107 *addr++ = 0;
108
109 /* Symbols */
110 ssym = addr;
111 bcopy(&x.a_syms, addr, sizeof(x.a_syms));
112 addr += sizeof(x.a_syms);
113 if (x.a_syms) {
114 printf("+[%ld", x.a_syms);
115 if (read(io, addr, x.a_syms) != (ssize_t)x.a_syms)
116 goto shread;
117 addr += x.a_syms;
118 }
119
120 i = 0;
121 if (x.a_syms && read(io, &i, sizeof(int)) != sizeof(int))
122 goto shread;
123
124 bcopy(&i, addr, sizeof(int));
125 if (i) {
126 i -= sizeof(int);
127 addr += sizeof(int);
128 if (read(io, addr, i) != i)
129 goto shread;
130 addr += i;
131 }
132
133 if (x.a_syms) {
134 /* and that many bytes of (debug symbols?) */
135 printf("+%d]", i);
136 }
137
138 close(io);
139
140 #define round_to_size(x) \
141 (((int)(x) + sizeof(int) - 1) & ~(sizeof(int) - 1))
142 esym = (char *)round_to_size(addr - loadaddr);
143 #undef round_to_size
144
145 /* and note the end address of all this */
146 printf(" total=0x%lx\n", (u_long)addr);
147
148 /*
149 * Machine-dependent code must now adjust the
150 * entry point. This used to be done here,
151 * but some systems may need to relocate the
152 * loaded file before jumping to it, and the
153 * displayed start address would be wrong.
154 */
155
156 #ifdef EXEC_DEBUG
157 printf("ssym=0x%x esym=0x%x\n", ssym, esym);
158 printf("\n\nReturn to boot...\n");
159 getchar();
160 #endif
161
162 machdep_start((char *)x.a_entry, howto, loadaddr, ssym, esym);
163
164 /* exec failed */
165 errno = ENOEXEC;
166 return;
167
168 shread:
169 close(io);
170 errno = EIO;
171 return;
172 }
Cache object: 6738208c03523d11151eb6582a8091dc
|