This source file includes following definitions.
- loadfile
- coff_exec
- aout_exec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 #ifdef _STANDALONE
76 #include <lib/libkern/libkern.h>
77 #include <lib/libsa/stand.h>
78 #else
79 #include <stdio.h>
80 #include <string.h>
81 #include <errno.h>
82 #include <stdlib.h>
83 #include <unistd.h>
84 #include <fcntl.h>
85 #include <err.h>
86 #endif
87
88 #include <sys/param.h>
89 #include <sys/exec.h>
90
91 #include "loadfile.h"
92
93 #ifdef BOOT_ECOFF
94 #include <sys/exec_ecoff.h>
95 static int coff_exec(int, struct ecoff_exechdr *, u_long *, int);
96 #endif
97 #ifdef BOOT_AOUT
98 #include <sys/exec_aout.h>
99 static int aout_exec(int, struct exec *, u_long *, int);
100 #endif
101
102 #ifdef BOOT_ELF
103 #include <sys/exec_elf.h>
104 #if defined(BOOT_ELF32) && defined(BOOT_ELF64)
105
106
107
108
109 int elf32_exec(int, Elf32_Ehdr *, u_long *, int);
110 int elf64_exec(int, Elf64_Ehdr *, u_long *, int);
111 #else
112 #include "loadfile_elf.c"
113 #endif
114 #endif
115
116
117
118
119
120
121 int
122 loadfile(const char *fname, u_long *marks, int flags)
123 {
124 union {
125 #ifdef BOOT_ECOFF
126 struct ecoff_exechdr coff;
127 #endif
128 #if defined(BOOT_ELF32) || (defined(BOOT_ELF) && ELFSIZE == 32)
129 Elf32_Ehdr elf32;
130 #endif
131 #if defined(BOOT_ELF64) || (defined(BOOT_ELF) && ELFSIZE == 64)
132 Elf64_Ehdr elf64;
133 #endif
134 #ifdef BOOT_AOUT
135 struct exec aout;
136 #endif
137
138 } hdr;
139 ssize_t nr;
140 int fd, rval;
141
142
143 if ((fd = open(fname, 0)) < 0) {
144 WARN(("open %s", fname ? fname : "<default>"));
145 return -1;
146 }
147
148
149 if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) {
150 WARN(("read header"));
151 goto err;
152 }
153
154 #ifdef BOOT_ECOFF
155 if (!ECOFF_BADMAG(&hdr.coff)) {
156 rval = coff_exec(fd, &hdr.coff, marks, flags);
157 } else
158 #endif
159 #if defined(BOOT_ELF32) || (defined(BOOT_ELF) && ELFSIZE == 32)
160 if (memcmp(hdr.elf32.e_ident, ELFMAG, SELFMAG) == 0 &&
161 hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) {
162 rval = elf32_exec(fd, &hdr.elf32, marks, flags);
163 } else
164 #endif
165 #if defined(BOOT_ELF64) || (defined(BOOT_ELF) && ELFSIZE == 64)
166 if (memcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 &&
167 hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) {
168 rval = elf64_exec(fd, &hdr.elf64, marks, flags);
169 } else
170 #endif
171 #ifdef BOOT_AOUT
172 if (OKMAGIC(N_GETMAGIC(hdr.aout))
173 #ifndef NO_MID_CHECK
174 && N_GETMID(hdr.aout) == MID_MACHINE
175 #endif
176 ) {
177 rval = aout_exec(fd, &hdr.aout, marks, flags);
178 } else
179 #endif
180 {
181 rval = 1;
182 errno = EFTYPE;
183 WARN(("%s", fname ? fname : "<default>"));
184 }
185
186 if (rval == 0) {
187 PROGRESS(("=0x%lx\n", marks[MARK_END] - marks[MARK_START]));
188 return fd;
189 }
190 err:
191 (void)close(fd);
192 return -1;
193 }
194
195 #ifdef BOOT_ECOFF
196 static int
197 coff_exec(int fd, struct ecoff_exechdr *coff, u_long *marks, int flags)
198 {
199 paddr_t offset = marks[MARK_START];
200 paddr_t minp = ~0, maxp = 0, pos;
201
202
203 if (lseek(fd, ECOFF_TXTOFF(coff), SEEK_SET) == -1) {
204 WARN(("lseek text"));
205 return 1;
206 }
207
208 if (coff->a.tsize != 0) {
209 if (flags & LOAD_TEXT) {
210 PROGRESS(("%lu", coff->a.tsize));
211 if (READ(fd, coff->a.text_start, coff->a.tsize) !=
212 coff->a.tsize) {
213 return 1;
214 }
215 }
216 else {
217 if (lseek(fd, coff->a.tsize, SEEK_CUR) == -1) {
218 WARN(("read text"));
219 return 1;
220 }
221 }
222 if (flags & (COUNT_TEXT|LOAD_TEXT)) {
223 pos = coff->a.text_start;
224 if (minp > pos)
225 minp = pos;
226 pos += coff->a.tsize;
227 if (maxp < pos)
228 maxp = pos;
229 }
230 }
231
232
233 if (coff->a.dsize != 0) {
234 if (flags & LOAD_DATA) {
235 PROGRESS(("+%lu", coff->a.dsize));
236 if (READ(fd, coff->a.data_start, coff->a.dsize) !=
237 coff->a.dsize) {
238 WARN(("read data"));
239 return 1;
240 }
241 }
242 if (flags & (COUNT_DATA|LOAD_DATA)) {
243 pos = coff->a.data_start;
244 if (minp > pos)
245 minp = pos;
246 pos += coff->a.dsize;
247 if (maxp < pos)
248 maxp = pos;
249 }
250 }
251
252
253 if (coff->a.bsize != 0) {
254 if (flags & LOAD_BSS) {
255 PROGRESS(("+%lu", coff->a.bsize));
256 BZERO(coff->a.bss_start, coff->a.bsize);
257 }
258 if (flags & (COUNT_BSS|LOAD_BSS)) {
259 pos = coff->a.bss_start;
260 if (minp > pos)
261 minp = pos;
262 pos = coff->a.bsize;
263 if (maxp < pos)
264 maxp = pos;
265 }
266 }
267
268 marks[MARK_START] = LOADADDR(minp);
269 marks[MARK_ENTRY] = LOADADDR(coff->a.entry);
270 marks[MARK_NSYM] = 1;
271 marks[MARK_SYM] = LOADADDR(maxp);
272 marks[MARK_END] = LOADADDR(maxp);
273 return 0;
274 }
275 #endif
276
277 #ifdef BOOT_AOUT
278 static int
279 aout_exec(int fd, struct exec *x, u_long *marks, int flags)
280 {
281 u_long entry = x->a_entry;
282 paddr_t aoutp = 0;
283 paddr_t minp, maxp;
284 int cc;
285 paddr_t offset = marks[MARK_START];
286 u_long magic = N_GETMAGIC(*x);
287 int sub;
288
289
290 if (magic == OMAGIC || magic == NMAGIC)
291 sub = 0;
292 else
293 sub = sizeof(*x);
294
295 minp = maxp = ALIGNENTRY(entry);
296
297 if (lseek(fd, sizeof(*x), SEEK_SET) == -1) {
298 WARN(("lseek text"));
299 return 1;
300 }
301
302
303
304
305
306
307 if (magic == OMAGIC || magic == NMAGIC) {
308 if (flags & LOAD_HDR && maxp >= sizeof(*x))
309 BCOPY(x, maxp - sizeof(*x), sizeof(*x));
310 }
311 else {
312 if (flags & LOAD_HDR)
313 BCOPY(x, maxp, sizeof(*x));
314 if (flags & (LOAD_HDR|COUNT_HDR))
315 maxp += sizeof(*x);
316 }
317
318
319
320
321 if (flags & LOAD_TEXT) {
322 PROGRESS(("%ld", x->a_text));
323
324 if (READ(fd, maxp, x->a_text - sub) != x->a_text - sub) {
325 WARN(("read text"));
326 return 1;
327 }
328 } else {
329 if (lseek(fd, x->a_text - sub, SEEK_CUR) == -1) {
330 WARN(("seek text"));
331 return 1;
332 }
333 }
334 if (flags & (LOAD_TEXT|COUNT_TEXT))
335 maxp += x->a_text - sub;
336
337
338
339
340 if (magic == ZMAGIC || magic == NMAGIC) {
341 int size = -(unsigned int)maxp & (__LDPGSZ - 1);
342
343 if (flags & LOAD_TEXTA) {
344 PROGRESS(("/%d", size));
345 BZERO(maxp, size);
346 }
347
348 if (flags & (LOAD_TEXTA|COUNT_TEXTA))
349 maxp += size;
350 }
351
352
353
354
355 if (flags & LOAD_DATA) {
356 PROGRESS(("+%ld", x->a_data));
357
358 if (READ(fd, maxp, x->a_data) != x->a_data) {
359 WARN(("read data"));
360 return 1;
361 }
362 }
363 else {
364 if (lseek(fd, x->a_data, SEEK_CUR) == -1) {
365 WARN(("seek data"));
366 return 1;
367 }
368 }
369 if (flags & (LOAD_DATA|COUNT_DATA))
370 maxp += x->a_data;
371
372
373
374
375
376 if (flags & LOAD_BSS) {
377 PROGRESS(("+%ld", x->a_bss));
378
379 BZERO(maxp, x->a_bss);
380 }
381
382 if (flags & (LOAD_BSS|COUNT_BSS))
383 maxp += x->a_bss;
384
385
386
387
388
389 if (flags & LOAD_SYM)
390 BCOPY(&x->a_syms, maxp, sizeof(x->a_syms));
391
392 if (flags & (LOAD_SYM|COUNT_SYM)) {
393 maxp += sizeof(x->a_syms);
394 aoutp = maxp;
395 }
396
397 if (x->a_syms > 0) {
398
399
400 if (flags & LOAD_SYM) {
401 PROGRESS(("+[%ld", x->a_syms));
402
403 if (READ(fd, maxp, x->a_syms) != x->a_syms) {
404 WARN(("read symbols"));
405 return 1;
406 }
407 } else {
408 if (lseek(fd, x->a_syms, SEEK_CUR) == -1) {
409 WARN(("seek symbols"));
410 return 1;
411 }
412 }
413 if (flags & (LOAD_SYM|COUNT_SYM))
414 maxp += x->a_syms;
415
416 if (read(fd, &cc, sizeof(cc)) != sizeof(cc)) {
417 WARN(("read string table"));
418 return 1;
419 }
420
421 if (flags & LOAD_SYM) {
422 BCOPY(&cc, maxp, sizeof(cc));
423
424
425
426 PROGRESS(("+%d]", cc));
427 }
428 if (flags & (LOAD_SYM|COUNT_SYM))
429 maxp += sizeof(cc);
430
431 cc -= sizeof(int);
432 if (cc <= 0) {
433 WARN(("symbol table too short"));
434 return 1;
435 }
436
437 if (flags & LOAD_SYM) {
438 if (READ(fd, maxp, cc) != cc) {
439 WARN(("read strings"));
440 return 1;
441 }
442 } else {
443 if (lseek(fd, cc, SEEK_CUR) == -1) {
444 WARN(("seek strings"));
445 return 1;
446 }
447 }
448 if (flags & (LOAD_SYM|COUNT_SYM))
449 maxp += cc;
450 }
451
452 marks[MARK_START] = LOADADDR(minp);
453 marks[MARK_ENTRY] = LOADADDR(entry);
454 marks[MARK_NSYM] = x->a_syms;
455 marks[MARK_SYM] = LOADADDR(aoutp);
456 marks[MARK_END] = LOADADDR(maxp);
457 return 0;
458 }
459 #endif