Annotation of sys/lib/libsa/loadfile_elf.c, Revision 1.1.1.1
1.1 nbrk 1: /* $NetBSD: loadfile.c,v 1.10 2000/12/03 02:53:04 tsutsui Exp $ */
2: /* $OpenBSD: loadfile_elf.c,v 1.1 2007/05/30 01:25:43 tom Exp $ */
3:
4: /*-
5: * Copyright (c) 1997 The NetBSD Foundation, Inc.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to The NetBSD Foundation
9: * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10: * NASA Ames Research Center and by Christos Zoulas.
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
20: * 3. All advertising materials mentioning features or use of this software
21: * must display the following acknowledgement:
22: * This product includes software developed by the NetBSD
23: * Foundation, Inc. and its contributors.
24: * 4. Neither the name of The NetBSD Foundation nor the names of its
25: * contributors may be used to endorse or promote products derived
26: * from this software without specific prior written permission.
27: *
28: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38: * POSSIBILITY OF SUCH DAMAGE.
39: */
40:
41: /*
42: * Copyright (c) 1992, 1993
43: * The Regents of the University of California. All rights reserved.
44: *
45: * This code is derived from software contributed to Berkeley by
46: * Ralph Campbell.
47: *
48: * Redistribution and use in source and binary forms, with or without
49: * modification, are permitted provided that the following conditions
50: * are met:
51: * 1. Redistributions of source code must retain the above copyright
52: * notice, this list of conditions and the following disclaimer.
53: * 2. Redistributions in binary form must reproduce the above copyright
54: * notice, this list of conditions and the following disclaimer in the
55: * documentation and/or other materials provided with the distribution.
56: * 3. Neither the name of the University nor the names of its contributors
57: * may be used to endorse or promote products derived from this software
58: * without specific prior written permission.
59: *
60: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
61: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
62: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
63: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
64: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
65: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
66: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70: * SUCH DAMAGE.
71: *
72: * @(#)boot.c 8.1 (Berkeley) 6/10/93
73: */
74:
75: int ELFNAME(exec)(int, Elf_Ehdr *, u_long *, int);
76:
77: int
78: ELFNAME(exec)(int fd, Elf_Ehdr *elf, u_long *marks, int flags)
79: {
80: Elf_Shdr *shp;
81: Elf_Phdr *phdr;
82: Elf_Off off;
83: int i;
84: size_t sz;
85: int first;
86: int havesyms;
87: paddr_t minp = ~0, maxp = 0, pos = 0;
88: paddr_t offset = marks[MARK_START], shpp, elfp;
89:
90: sz = elf->e_phnum * sizeof(Elf_Phdr);
91: phdr = ALLOC(sz);
92:
93: if (lseek(fd, (off_t)elf->e_phoff, SEEK_SET) == -1) {
94: WARN(("lseek phdr"));
95: FREE(phdr, sz);
96: return 1;
97: }
98: if (read(fd, phdr, sz) != sz) {
99: WARN(("read program headers"));
100: FREE(phdr, sz);
101: return 1;
102: }
103:
104: for (first = 1, i = 0; i < elf->e_phnum; i++) {
105:
106: if (phdr[i].p_type != PT_LOAD ||
107: (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0)
108: continue;
109:
110: #define IS_TEXT(p) (p.p_flags & PF_X)
111: #define IS_DATA(p) ((p.p_flags & PF_X) == 0)
112: #define IS_BSS(p) (p.p_filesz < p.p_memsz)
113: /*
114: * XXX: Assume first address is lowest
115: */
116: if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) ||
117: (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) {
118:
119: /* Read in segment. */
120: PROGRESS(("%s%lu", first ? "" : "+",
121: (u_long)phdr[i].p_filesz));
122:
123: if (lseek(fd, (off_t)phdr[i].p_offset, SEEK_SET) == -1) {
124: WARN(("lseek text"));
125: FREE(phdr, sz);
126: return 1;
127: }
128: if (READ(fd, phdr[i].p_vaddr, phdr[i].p_filesz) !=
129: phdr[i].p_filesz) {
130: WARN(("read text"));
131: FREE(phdr, sz);
132: return 1;
133: }
134: first = 0;
135:
136: }
137: if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT|COUNT_TEXT))) ||
138: (IS_DATA(phdr[i]) && (flags & (LOAD_DATA|COUNT_TEXT)))) {
139: pos = phdr[i].p_vaddr;
140: if (minp > pos)
141: minp = pos;
142: pos += phdr[i].p_filesz;
143: if (maxp < pos)
144: maxp = pos;
145: }
146:
147: /* Zero out bss. */
148: if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) {
149: PROGRESS(("+%lu",
150: (u_long)(phdr[i].p_memsz - phdr[i].p_filesz)));
151: BZERO((phdr[i].p_vaddr + phdr[i].p_filesz),
152: phdr[i].p_memsz - phdr[i].p_filesz);
153: }
154: if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) {
155: pos += phdr[i].p_memsz - phdr[i].p_filesz;
156: if (maxp < pos)
157: maxp = pos;
158: }
159: }
160: FREE(phdr, sz);
161:
162: /*
163: * Copy the ELF and section headers.
164: */
165: elfp = maxp = roundup(maxp, sizeof(long));
166: if (flags & (LOAD_HDR|COUNT_HDR))
167: maxp += sizeof(Elf_Ehdr);
168:
169: if (flags & (LOAD_SYM|COUNT_SYM)) {
170: if (lseek(fd, (off_t)elf->e_shoff, SEEK_SET) == -1) {
171: WARN(("lseek section headers"));
172: return 1;
173: }
174: sz = elf->e_shnum * sizeof(Elf_Shdr);
175: shp = ALLOC(sz);
176:
177: if (read(fd, shp, sz) != sz) {
178: WARN(("read section headers"));
179: FREE(shp, sz);
180: return 1;
181: }
182:
183: shpp = maxp;
184: maxp += roundup(sz, sizeof(long));
185:
186: /*
187: * Now load the symbol sections themselves. Make sure the
188: * sections are aligned. Don't bother with string tables if
189: * there are no symbol sections.
190: */
191: off = roundup((sizeof(Elf_Ehdr) + sz), sizeof(long));
192:
193: for (havesyms = i = 0; i < elf->e_shnum; i++)
194: if (shp[i].sh_type == SHT_SYMTAB)
195: havesyms = 1;
196:
197: for (first = 1, i = 0; i < elf->e_shnum; i++) {
198: if (shp[i].sh_type == SHT_SYMTAB ||
199: shp[i].sh_type == SHT_STRTAB) {
200: if (havesyms && (flags & LOAD_SYM)) {
201: PROGRESS(("%s%ld", first ? " [" : "+",
202: (u_long)shp[i].sh_size));
203: if (lseek(fd, (off_t)shp[i].sh_offset,
204: SEEK_SET) == -1) {
205: WARN(("lseek symbols"));
206: FREE(shp, sz);
207: return 1;
208: }
209: if (READ(fd, maxp, shp[i].sh_size) !=
210: shp[i].sh_size) {
211: WARN(("read symbols"));
212: FREE(shp, sz);
213: return 1;
214: }
215: }
216: maxp += roundup(shp[i].sh_size,
217: sizeof(long));
218: shp[i].sh_offset = off;
219: off += roundup(shp[i].sh_size, sizeof(long));
220: first = 0;
221: }
222: }
223: if (flags & LOAD_SYM) {
224: BCOPY(shp, shpp, sz);
225:
226: if (havesyms && first == 0)
227: PROGRESS(("]"));
228: }
229: FREE(shp, sz);
230: }
231:
232: /*
233: * Frob the copied ELF header to give information relative
234: * to elfp.
235: */
236: if (flags & LOAD_HDR) {
237: elf->e_phoff = 0;
238: elf->e_shoff = sizeof(Elf_Ehdr);
239: elf->e_phentsize = 0;
240: elf->e_phnum = 0;
241: BCOPY(elf, elfp, sizeof(*elf));
242: }
243:
244: marks[MARK_START] = LOADADDR(minp);
245: marks[MARK_ENTRY] = LOADADDR(elf->e_entry);
246: marks[MARK_NSYM] = 1; /* XXX: Kernel needs >= 0 */
247: marks[MARK_SYM] = LOADADDR(elfp);
248: marks[MARK_END] = LOADADDR(maxp);
249: return 0;
250: }
CVSweb