Thu Aug 23 17:35:42 2018 UTC ()
Support loading read-only data sections. ARM64 ELF kernels need this. ok skrll@


(jmcneill)
diff -r1.52 -r1.53 src/sys/lib/libsa/loadfile_elf32.c

cvs diff -r1.52 -r1.53 src/sys/lib/libsa/loadfile_elf32.c (switch to unified diff)

--- src/sys/lib/libsa/loadfile_elf32.c 2017/12/21 14:28:39 1.52
+++ src/sys/lib/libsa/loadfile_elf32.c 2018/08/23 17:35:42 1.53
@@ -1,816 +1,816 @@ @@ -1,816 +1,816 @@
1/* $NetBSD: loadfile_elf32.c,v 1.52 2017/12/21 14:28:39 maxv Exp $ */ 1/* $NetBSD: loadfile_elf32.c,v 1.53 2018/08/23 17:35:42 jmcneill Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1997, 2008, 2017 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997, 2008, 2017 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center, by Christos Zoulas, and by Maxime Villard. 9 * NASA Ames Research Center, by Christos Zoulas, and by Maxime Villard.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* If not included by exec_elf64.c, ELFSIZE won't be defined. */ 33/* If not included by exec_elf64.c, ELFSIZE won't be defined. */
34#ifndef ELFSIZE 34#ifndef ELFSIZE
35#define ELFSIZE 32 35#define ELFSIZE 32
36#endif 36#endif
37 37
38#ifdef _STANDALONE 38#ifdef _STANDALONE
39#include <lib/libsa/stand.h> 39#include <lib/libsa/stand.h>
40#include <lib/libkern/libkern.h> 40#include <lib/libkern/libkern.h>
41#else 41#else
42#include <stdio.h> 42#include <stdio.h>
43#include <string.h> 43#include <string.h>
44#include <errno.h> 44#include <errno.h>
45#include <stdlib.h> 45#include <stdlib.h>
46#include <unistd.h> 46#include <unistd.h>
47#include <fcntl.h> 47#include <fcntl.h>
48#include <err.h> 48#include <err.h>
49#endif 49#endif
50 50
51#include <sys/param.h> 51#include <sys/param.h>
52#include <sys/exec.h> 52#include <sys/exec.h>
53 53
54#include "loadfile.h" 54#include "loadfile.h"
55 55
56#if ((ELFSIZE == 32) && defined(BOOT_ELF32)) || \ 56#if ((ELFSIZE == 32) && defined(BOOT_ELF32)) || \
57 ((ELFSIZE == 64) && defined(BOOT_ELF64)) 57 ((ELFSIZE == 64) && defined(BOOT_ELF64))
58 58
59#define ELFROUND (ELFSIZE / 8) 59#define ELFROUND (ELFSIZE / 8)
60 60
61#ifndef _STANDALONE 61#ifndef _STANDALONE
62#include "byteorder.h" 62#include "byteorder.h"
63 63
64/* 64/*
65 * Byte swapping may be necessary in the non-_STANDLONE case because 65 * Byte swapping may be necessary in the non-_STANDLONE case because
66 * we may be built with a host compiler. 66 * we may be built with a host compiler.
67 */ 67 */
68#define E16(f) \ 68#define E16(f) \
69 f = (bo == ELFDATA2LSB) ? sa_htole16(f) : sa_htobe16(f) 69 f = (bo == ELFDATA2LSB) ? sa_htole16(f) : sa_htobe16(f)
70#define E32(f) \ 70#define E32(f) \
71 f = (bo == ELFDATA2LSB) ? sa_htole32(f) : sa_htobe32(f) 71 f = (bo == ELFDATA2LSB) ? sa_htole32(f) : sa_htobe32(f)
72#define E64(f) \ 72#define E64(f) \
73 f = (bo == ELFDATA2LSB) ? sa_htole64(f) : sa_htobe64(f) 73 f = (bo == ELFDATA2LSB) ? sa_htole64(f) : sa_htobe64(f)
74 74
75#define I16(f) \ 75#define I16(f) \
76 f = (bo == ELFDATA2LSB) ? sa_le16toh(f) : sa_be16toh(f) 76 f = (bo == ELFDATA2LSB) ? sa_le16toh(f) : sa_be16toh(f)
77#define I32(f) \ 77#define I32(f) \
78 f = (bo == ELFDATA2LSB) ? sa_le32toh(f) : sa_be32toh(f) 78 f = (bo == ELFDATA2LSB) ? sa_le32toh(f) : sa_be32toh(f)
79#define I64(f) \ 79#define I64(f) \
80 f = (bo == ELFDATA2LSB) ? sa_le64toh(f) : sa_be64toh(f) 80 f = (bo == ELFDATA2LSB) ? sa_le64toh(f) : sa_be64toh(f)
81 81
82static void 82static void
83internalize_ehdr(Elf_Byte bo, Elf_Ehdr *ehdr) 83internalize_ehdr(Elf_Byte bo, Elf_Ehdr *ehdr)
84{ 84{
85 85
86#if ELFSIZE == 32 86#if ELFSIZE == 32
87 I16(ehdr->e_type); 87 I16(ehdr->e_type);
88 I16(ehdr->e_machine); 88 I16(ehdr->e_machine);
89 I32(ehdr->e_version); 89 I32(ehdr->e_version);
90 I32(ehdr->e_entry); 90 I32(ehdr->e_entry);
91 I32(ehdr->e_phoff); 91 I32(ehdr->e_phoff);
92 I32(ehdr->e_shoff); 92 I32(ehdr->e_shoff);
93 I32(ehdr->e_flags); 93 I32(ehdr->e_flags);
94 I16(ehdr->e_ehsize); 94 I16(ehdr->e_ehsize);
95 I16(ehdr->e_phentsize); 95 I16(ehdr->e_phentsize);
96 I16(ehdr->e_phnum); 96 I16(ehdr->e_phnum);
97 I16(ehdr->e_shentsize); 97 I16(ehdr->e_shentsize);
98 I16(ehdr->e_shnum); 98 I16(ehdr->e_shnum);
99 I16(ehdr->e_shstrndx); 99 I16(ehdr->e_shstrndx);
100#elif ELFSIZE == 64 100#elif ELFSIZE == 64
101 I16(ehdr->e_type); 101 I16(ehdr->e_type);
102 I16(ehdr->e_machine); 102 I16(ehdr->e_machine);
103 I32(ehdr->e_version); 103 I32(ehdr->e_version);
104 I64(ehdr->e_entry); 104 I64(ehdr->e_entry);
105 I64(ehdr->e_phoff); 105 I64(ehdr->e_phoff);
106 I64(ehdr->e_shoff); 106 I64(ehdr->e_shoff);
107 I32(ehdr->e_flags); 107 I32(ehdr->e_flags);
108 I16(ehdr->e_ehsize); 108 I16(ehdr->e_ehsize);
109 I16(ehdr->e_phentsize); 109 I16(ehdr->e_phentsize);
110 I16(ehdr->e_phnum); 110 I16(ehdr->e_phnum);
111 I16(ehdr->e_shentsize); 111 I16(ehdr->e_shentsize);
112 I16(ehdr->e_shnum); 112 I16(ehdr->e_shnum);
113 I16(ehdr->e_shstrndx); 113 I16(ehdr->e_shstrndx);
114#else 114#else
115#error ELFSIZE is not 32 or 64 115#error ELFSIZE is not 32 or 64
116#endif 116#endif
117} 117}
118 118
119static void 119static void
120externalize_ehdr(Elf_Byte bo, Elf_Ehdr *ehdr) 120externalize_ehdr(Elf_Byte bo, Elf_Ehdr *ehdr)
121{ 121{
122 122
123#if ELFSIZE == 32 123#if ELFSIZE == 32
124 E16(ehdr->e_type); 124 E16(ehdr->e_type);
125 E16(ehdr->e_machine); 125 E16(ehdr->e_machine);
126 E32(ehdr->e_version); 126 E32(ehdr->e_version);
127 E32(ehdr->e_entry); 127 E32(ehdr->e_entry);
128 E32(ehdr->e_phoff); 128 E32(ehdr->e_phoff);
129 E32(ehdr->e_shoff); 129 E32(ehdr->e_shoff);
130 E32(ehdr->e_flags); 130 E32(ehdr->e_flags);
131 E16(ehdr->e_ehsize); 131 E16(ehdr->e_ehsize);
132 E16(ehdr->e_phentsize); 132 E16(ehdr->e_phentsize);
133 E16(ehdr->e_phnum); 133 E16(ehdr->e_phnum);
134 E16(ehdr->e_shentsize); 134 E16(ehdr->e_shentsize);
135 E16(ehdr->e_shnum); 135 E16(ehdr->e_shnum);
136 E16(ehdr->e_shstrndx); 136 E16(ehdr->e_shstrndx);
137#elif ELFSIZE == 64 137#elif ELFSIZE == 64
138 E16(ehdr->e_type); 138 E16(ehdr->e_type);
139 E16(ehdr->e_machine); 139 E16(ehdr->e_machine);
140 E32(ehdr->e_version); 140 E32(ehdr->e_version);
141 E64(ehdr->e_entry); 141 E64(ehdr->e_entry);
142 E64(ehdr->e_phoff); 142 E64(ehdr->e_phoff);
143 E64(ehdr->e_shoff); 143 E64(ehdr->e_shoff);
144 E32(ehdr->e_flags); 144 E32(ehdr->e_flags);
145 E16(ehdr->e_ehsize); 145 E16(ehdr->e_ehsize);
146 E16(ehdr->e_phentsize); 146 E16(ehdr->e_phentsize);
147 E16(ehdr->e_phnum); 147 E16(ehdr->e_phnum);
148 E16(ehdr->e_shentsize); 148 E16(ehdr->e_shentsize);
149 E16(ehdr->e_shnum); 149 E16(ehdr->e_shnum);
150 E16(ehdr->e_shstrndx); 150 E16(ehdr->e_shstrndx);
151#else 151#else
152#error ELFSIZE is not 32 or 64 152#error ELFSIZE is not 32 or 64
153#endif 153#endif
154} 154}
155 155
156static void 156static void
157internalize_phdr(Elf_Byte bo, Elf_Phdr *phdr) 157internalize_phdr(Elf_Byte bo, Elf_Phdr *phdr)
158{ 158{
159 159
160#if ELFSIZE == 32 160#if ELFSIZE == 32
161 I32(phdr->p_type); 161 I32(phdr->p_type);
162 I32(phdr->p_offset); 162 I32(phdr->p_offset);
163 I32(phdr->p_vaddr); 163 I32(phdr->p_vaddr);
164 I32(phdr->p_paddr); 164 I32(phdr->p_paddr);
165 I32(phdr->p_filesz); 165 I32(phdr->p_filesz);
166 I32(phdr->p_memsz); 166 I32(phdr->p_memsz);
167 I32(phdr->p_flags); 167 I32(phdr->p_flags);
168 I32(phdr->p_align); 168 I32(phdr->p_align);
169#elif ELFSIZE == 64 169#elif ELFSIZE == 64
170 I32(phdr->p_type); 170 I32(phdr->p_type);
171 I32(phdr->p_offset); 171 I32(phdr->p_offset);
172 I64(phdr->p_vaddr); 172 I64(phdr->p_vaddr);
173 I64(phdr->p_paddr); 173 I64(phdr->p_paddr);
174 I64(phdr->p_filesz); 174 I64(phdr->p_filesz);
175 I64(phdr->p_memsz); 175 I64(phdr->p_memsz);
176 I64(phdr->p_flags); 176 I64(phdr->p_flags);
177 I64(phdr->p_align); 177 I64(phdr->p_align);
178#else 178#else
179#error ELFSIZE is not 32 or 64 179#error ELFSIZE is not 32 or 64
180#endif 180#endif
181} 181}
182 182
183static void 183static void
184internalize_shdr(Elf_Byte bo, Elf_Shdr *shdr) 184internalize_shdr(Elf_Byte bo, Elf_Shdr *shdr)
185{ 185{
186 186
187#if ELFSIZE == 32 187#if ELFSIZE == 32
188 I32(shdr->sh_name); 188 I32(shdr->sh_name);
189 I32(shdr->sh_type); 189 I32(shdr->sh_type);
190 I32(shdr->sh_flags); 190 I32(shdr->sh_flags);
191 I32(shdr->sh_addr); 191 I32(shdr->sh_addr);
192 I32(shdr->sh_offset); 192 I32(shdr->sh_offset);
193 I32(shdr->sh_size); 193 I32(shdr->sh_size);
194 I32(shdr->sh_link); 194 I32(shdr->sh_link);
195 I32(shdr->sh_info); 195 I32(shdr->sh_info);
196 I32(shdr->sh_addralign); 196 I32(shdr->sh_addralign);
197 I32(shdr->sh_entsize); 197 I32(shdr->sh_entsize);
198#elif ELFSIZE == 64 198#elif ELFSIZE == 64
199 I32(shdr->sh_name); 199 I32(shdr->sh_name);
200 I32(shdr->sh_type); 200 I32(shdr->sh_type);
201 I64(shdr->sh_flags); 201 I64(shdr->sh_flags);
202 I64(shdr->sh_addr); 202 I64(shdr->sh_addr);
203 I64(shdr->sh_offset); 203 I64(shdr->sh_offset);
204 I64(shdr->sh_size); 204 I64(shdr->sh_size);
205 I32(shdr->sh_link); 205 I32(shdr->sh_link);
206 I32(shdr->sh_info); 206 I32(shdr->sh_info);
207 I64(shdr->sh_addralign); 207 I64(shdr->sh_addralign);
208 I64(shdr->sh_entsize); 208 I64(shdr->sh_entsize);
209#else 209#else
210#error ELFSIZE is not 32 or 64 210#error ELFSIZE is not 32 or 64
211#endif 211#endif
212} 212}
213 213
214static void 214static void
215externalize_shdr(Elf_Byte bo, Elf_Shdr *shdr) 215externalize_shdr(Elf_Byte bo, Elf_Shdr *shdr)
216{ 216{
217 217
218#if ELFSIZE == 32 218#if ELFSIZE == 32
219 E32(shdr->sh_name); 219 E32(shdr->sh_name);
220 E32(shdr->sh_type); 220 E32(shdr->sh_type);
221 E32(shdr->sh_flags); 221 E32(shdr->sh_flags);
222 E32(shdr->sh_addr); 222 E32(shdr->sh_addr);
223 E32(shdr->sh_offset); 223 E32(shdr->sh_offset);
224 E32(shdr->sh_size); 224 E32(shdr->sh_size);
225 E32(shdr->sh_link); 225 E32(shdr->sh_link);
226 E32(shdr->sh_info); 226 E32(shdr->sh_info);
227 E32(shdr->sh_addralign); 227 E32(shdr->sh_addralign);
228 E32(shdr->sh_entsize); 228 E32(shdr->sh_entsize);
229#elif ELFSIZE == 64 229#elif ELFSIZE == 64
230 E32(shdr->sh_name); 230 E32(shdr->sh_name);
231 E32(shdr->sh_type); 231 E32(shdr->sh_type);
232 E64(shdr->sh_flags); 232 E64(shdr->sh_flags);
233 E64(shdr->sh_addr); 233 E64(shdr->sh_addr);
234 E64(shdr->sh_offset); 234 E64(shdr->sh_offset);
235 E64(shdr->sh_size); 235 E64(shdr->sh_size);
236 E32(shdr->sh_link); 236 E32(shdr->sh_link);
237 E32(shdr->sh_info); 237 E32(shdr->sh_info);
238 E64(shdr->sh_addralign); 238 E64(shdr->sh_addralign);
239 E64(shdr->sh_entsize); 239 E64(shdr->sh_entsize);
240#else 240#else
241#error ELFSIZE is not 32 or 64 241#error ELFSIZE is not 32 or 64
242#endif 242#endif
243} 243}
244#else /* _STANDALONE */ 244#else /* _STANDALONE */
245/* 245/*
246 * Byte swapping is never necessary in the _STANDALONE case because 246 * Byte swapping is never necessary in the _STANDALONE case because
247 * we are being built with the target compiler. 247 * we are being built with the target compiler.
248 */ 248 */
249#define internalize_ehdr(bo, ehdr) /* nothing */ 249#define internalize_ehdr(bo, ehdr) /* nothing */
250#define externalize_ehdr(bo, ehdr) /* nothing */ 250#define externalize_ehdr(bo, ehdr) /* nothing */
251 251
252#define internalize_phdr(bo, phdr) /* nothing */ 252#define internalize_phdr(bo, phdr) /* nothing */
253 253
254#define internalize_shdr(bo, shdr) /* nothing */ 254#define internalize_shdr(bo, shdr) /* nothing */
255#define externalize_shdr(bo, shdr) /* nothing */ 255#define externalize_shdr(bo, shdr) /* nothing */
256#endif /* _STANDALONE */ 256#endif /* _STANDALONE */
257 257
258#define IS_TEXT(p) (p.p_flags & PF_X) 258#define IS_TEXT(p) (p.p_flags & PF_X)
259#define IS_DATA(p) (p.p_flags & PF_W) 259#define IS_DATA(p) ((p.p_flags & PF_X) == 0)
260#define IS_BSS(p) (p.p_filesz < p.p_memsz) 260#define IS_BSS(p) (p.p_filesz < p.p_memsz)
261 261
262#ifndef MD_LOADSEG /* Allow processor ABI specific segment loads */ 262#ifndef MD_LOADSEG /* Allow processor ABI specific segment loads */
263#define MD_LOADSEG(a) /*CONSTCOND*/0 263#define MD_LOADSEG(a) /*CONSTCOND*/0
264#endif 264#endif
265 265
266/* -------------------------------------------------------------------------- */ 266/* -------------------------------------------------------------------------- */
267 267
268#define KERNALIGN_SMALL (1 << 12) /* XXX should depend on marks[] */ 268#define KERNALIGN_SMALL (1 << 12) /* XXX should depend on marks[] */
269#define KERNALIGN_LARGE (1 << 21) /* XXX should depend on marks[] */ 269#define KERNALIGN_LARGE (1 << 21) /* XXX should depend on marks[] */
270 270
271/* 271/*
272 * Read some data from a file, and put it in the bootloader memory (local). 272 * Read some data from a file, and put it in the bootloader memory (local).
273 */ 273 */
274static int 274static int
275ELFNAMEEND(readfile_local)(int fd, Elf_Off elfoff, void *addr, size_t size) 275ELFNAMEEND(readfile_local)(int fd, Elf_Off elfoff, void *addr, size_t size)
276{ 276{
277 ssize_t nr; 277 ssize_t nr;
278 278
279 if (lseek(fd, elfoff, SEEK_SET) == -1) { 279 if (lseek(fd, elfoff, SEEK_SET) == -1) {
280 WARN(("lseek section headers")); 280 WARN(("lseek section headers"));
281 return -1; 281 return -1;
282 } 282 }
283 nr = read(fd, addr, size); 283 nr = read(fd, addr, size);
284 if (nr == -1) { 284 if (nr == -1) {
285 WARN(("read section headers")); 285 WARN(("read section headers"));
286 return -1; 286 return -1;
287 } 287 }
288 if (nr != (ssize_t)size) { 288 if (nr != (ssize_t)size) {
289 errno = EIO; 289 errno = EIO;
290 WARN(("read section headers")); 290 WARN(("read section headers"));
291 return -1; 291 return -1;
292 } 292 }
293 293
294 return 0; 294 return 0;
295} 295}
296 296
297/* 297/*
298 * Read some data from a file, and put it in wherever in memory (global). 298 * Read some data from a file, and put it in wherever in memory (global).
299 */ 299 */
300static int 300static int
301ELFNAMEEND(readfile_global)(int fd, u_long offset, Elf_Off elfoff, 301ELFNAMEEND(readfile_global)(int fd, u_long offset, Elf_Off elfoff,
302 Elf_Addr addr, size_t size) 302 Elf_Addr addr, size_t size)
303{ 303{
304 ssize_t nr; 304 ssize_t nr;
305 305
306 /* some ports dont use the offset */ 306 /* some ports dont use the offset */
307 (void)&offset; 307 (void)&offset;
308 308
309 if (lseek(fd, elfoff, SEEK_SET) == -1) { 309 if (lseek(fd, elfoff, SEEK_SET) == -1) {
310 WARN(("lseek section")); 310 WARN(("lseek section"));
311 return -1; 311 return -1;
312 } 312 }
313 nr = READ(fd, addr, size); 313 nr = READ(fd, addr, size);
314 if (nr == -1) { 314 if (nr == -1) {
315 WARN(("read section")); 315 WARN(("read section"));
316 return -1; 316 return -1;
317 } 317 }
318 if (nr != (ssize_t)size) { 318 if (nr != (ssize_t)size) {
319 errno = EIO; 319 errno = EIO;
320 WARN(("read section")); 320 WARN(("read section"));
321 return -1; 321 return -1;
322 } 322 }
323 323
324 return 0; 324 return 0;
325} 325}
326 326
327/* 327/*
328 * Load a dynamic ELF binary into memory. Layout of the memory: 328 * Load a dynamic ELF binary into memory. Layout of the memory:
329 * +------------+-----------------+-----------------+------------------+ 329 * +------------+-----------------+-----------------+------------------+
330 * | ELF HEADER | SECTION HEADERS | KERNEL SECTIONS | SYM+REL SECTIONS | 330 * | ELF HEADER | SECTION HEADERS | KERNEL SECTIONS | SYM+REL SECTIONS |
331 * +------------+-----------------+-----------------+------------------+ 331 * +------------+-----------------+-----------------+------------------+
332 * The ELF HEADER start address is marks[MARK_END]. We then map the rest 332 * The ELF HEADER start address is marks[MARK_END]. We then map the rest
333 * by increasing maxp. An alignment is enforced between the code sections. 333 * by increasing maxp. An alignment is enforced between the code sections.
334 * 334 *
335 * The offsets of the KERNEL and SYM+REL sections are relative to the start 335 * The offsets of the KERNEL and SYM+REL sections are relative to the start
336 * address of the ELF HEADER. We just give the kernel a pointer to the ELF 336 * address of the ELF HEADER. We just give the kernel a pointer to the ELF
337 * HEADER, and we let the kernel find the location and number of symbols by 337 * HEADER, and we let the kernel find the location and number of symbols by
338 * itself. 338 * itself.
339 */ 339 */
340static int 340static int
341ELFNAMEEND(loadfile_dynamic)(int fd, Elf_Ehdr *elf, u_long *marks, int flags) 341ELFNAMEEND(loadfile_dynamic)(int fd, Elf_Ehdr *elf, u_long *marks, int flags)
342{ 342{
343 const u_long offset = 0; 343 const u_long offset = 0;
344 Elf_Shdr *shdr; 344 Elf_Shdr *shdr;
345 Elf_Addr shpp, addr; 345 Elf_Addr shpp, addr;
346 int i, j, loaded; 346 int i, j, loaded;
347 size_t size, shdrsz, align; 347 size_t size, shdrsz, align;
348 Elf_Addr maxp, elfp = 0; 348 Elf_Addr maxp, elfp = 0;
349 int ret; 349 int ret;
350 350
351 maxp = marks[MARK_END]; 351 maxp = marks[MARK_END];
352 352
353 internalize_ehdr(elf->e_ident[EI_DATA], elf); 353 internalize_ehdr(elf->e_ident[EI_DATA], elf);
354 354
355 if (elf->e_type != ET_REL) { 355 if (elf->e_type != ET_REL) {
356 errno = EINVAL; 356 errno = EINVAL;
357 return 1; 357 return 1;
358 } 358 }
359 359
360 /* Create a local copy of the SECTION HEADERS. */ 360 /* Create a local copy of the SECTION HEADERS. */
361 shdrsz = elf->e_shnum * sizeof(Elf_Shdr); 361 shdrsz = elf->e_shnum * sizeof(Elf_Shdr);
362 shdr = ALLOC(shdrsz); 362 shdr = ALLOC(shdrsz);
363 ret = ELFNAMEEND(readfile_local)(fd, elf->e_shoff, shdr, shdrsz); 363 ret = ELFNAMEEND(readfile_local)(fd, elf->e_shoff, shdr, shdrsz);
364 if (ret == -1) { 364 if (ret == -1) {
365 goto out; 365 goto out;
366 } 366 }
367 367
368 /* 368 /*
369 * Load the ELF HEADER. Update the section offset, to be relative to 369 * Load the ELF HEADER. Update the section offset, to be relative to
370 * elfp. 370 * elfp.
371 */ 371 */
372 elf->e_phoff = 0; 372 elf->e_phoff = 0;
373 elf->e_shoff = sizeof(Elf_Ehdr); 373 elf->e_shoff = sizeof(Elf_Ehdr);
374 elf->e_phentsize = 0; 374 elf->e_phentsize = 0;
375 elf->e_phnum = 0; 375 elf->e_phnum = 0;
376 elfp = maxp; 376 elfp = maxp;
377 externalize_ehdr(elf->e_ident[EI_DATA], elf); 377 externalize_ehdr(elf->e_ident[EI_DATA], elf);
378 BCOPY(elf, elfp, sizeof(*elf)); 378 BCOPY(elf, elfp, sizeof(*elf));
379 internalize_ehdr(elf->e_ident[EI_DATA], elf); 379 internalize_ehdr(elf->e_ident[EI_DATA], elf);
380 maxp += sizeof(Elf_Ehdr); 380 maxp += sizeof(Elf_Ehdr);
381 381
382#ifndef _STANDALONE 382#ifndef _STANDALONE
383 for (i = 0; i < elf->e_shnum; i++) 383 for (i = 0; i < elf->e_shnum; i++)
384 internalize_shdr(elf->e_ident[EI_DATA], &shdr[i]); 384 internalize_shdr(elf->e_ident[EI_DATA], &shdr[i]);
385#endif 385#endif
386 386
387 /* Save location of the SECTION HEADERS. */ 387 /* Save location of the SECTION HEADERS. */
388 shpp = maxp; 388 shpp = maxp;
389 maxp += roundup(shdrsz, ELFROUND); 389 maxp += roundup(shdrsz, ELFROUND);
390 390
391 /* 391 /*
392 * Load the KERNEL SECTIONS. 392 * Load the KERNEL SECTIONS.
393 */ 393 */
394 maxp = roundup(maxp, KERNALIGN_SMALL); 394 maxp = roundup(maxp, KERNALIGN_SMALL);
395 for (i = 0; i < elf->e_shnum; i++) { 395 for (i = 0; i < elf->e_shnum; i++) {
396 if (!(shdr[i].sh_flags & SHF_ALLOC)) { 396 if (!(shdr[i].sh_flags & SHF_ALLOC)) {
397 continue; 397 continue;
398 } 398 }
399 size = (size_t)shdr[i].sh_size; 399 size = (size_t)shdr[i].sh_size;
400 if (size <= KERNALIGN_SMALL) { 400 if (size <= KERNALIGN_SMALL) {
401 align = KERNALIGN_SMALL; 401 align = KERNALIGN_SMALL;
402 } else { 402 } else {
403 align = KERNALIGN_LARGE; 403 align = KERNALIGN_LARGE;
404 } 404 }
405 addr = roundup(maxp, align); 405 addr = roundup(maxp, align);
406 406
407 loaded = 0; 407 loaded = 0;
408 switch (shdr[i].sh_type) { 408 switch (shdr[i].sh_type) {
409 case SHT_NOBITS: 409 case SHT_NOBITS:
410 /* Zero out bss. */ 410 /* Zero out bss. */
411 BZERO(addr, size); 411 BZERO(addr, size);
412 loaded = 1; 412 loaded = 1;
413 break; 413 break;
414 case SHT_PROGBITS: 414 case SHT_PROGBITS:
415 ret = ELFNAMEEND(readfile_global)(fd, offset, 415 ret = ELFNAMEEND(readfile_global)(fd, offset,
416 shdr[i].sh_offset, addr, size); 416 shdr[i].sh_offset, addr, size);
417 if (ret == -1) { 417 if (ret == -1) {
418 goto out; 418 goto out;
419 } 419 }
420 loaded = 1; 420 loaded = 1;
421 break; 421 break;
422 default: 422 default:
423 loaded = 0; 423 loaded = 0;
424 break; 424 break;
425 } 425 }
426 426
427 if (loaded) { 427 if (loaded) {
428 shdr[i].sh_offset = addr - elfp; 428 shdr[i].sh_offset = addr - elfp;
429 maxp = roundup(addr + size, align); 429 maxp = roundup(addr + size, align);
430 } 430 }
431 } 431 }
432 maxp = roundup(maxp, KERNALIGN_LARGE); 432 maxp = roundup(maxp, KERNALIGN_LARGE);
433 433
434 /* 434 /*
435 * Load the SYM+REL SECTIONS. 435 * Load the SYM+REL SECTIONS.
436 */ 436 */
437 maxp = roundup(maxp, ELFROUND); 437 maxp = roundup(maxp, ELFROUND);
438 for (i = 0; i < elf->e_shnum; i++) { 438 for (i = 0; i < elf->e_shnum; i++) {
439 addr = maxp; 439 addr = maxp;
440 size = (size_t)shdr[i].sh_size; 440 size = (size_t)shdr[i].sh_size;
441 441
442 switch (shdr[i].sh_type) { 442 switch (shdr[i].sh_type) {
443 case SHT_STRTAB: 443 case SHT_STRTAB:
444 for (j = 0; j < elf->e_shnum; j++) 444 for (j = 0; j < elf->e_shnum; j++)
445 if (shdr[j].sh_type == SHT_SYMTAB && 445 if (shdr[j].sh_type == SHT_SYMTAB &&
446 shdr[j].sh_link == (unsigned int)i) 446 shdr[j].sh_link == (unsigned int)i)
447 goto havesym; 447 goto havesym;
448 if (elf->e_shstrndx == i) 448 if (elf->e_shstrndx == i)
449 goto havesym; 449 goto havesym;
450 /* 450 /*
451 * Don't bother with any string table that isn't 451 * Don't bother with any string table that isn't
452 * referenced by a symbol table. 452 * referenced by a symbol table.
453 */ 453 */
454 shdr[i].sh_offset = 0; 454 shdr[i].sh_offset = 0;
455 break; 455 break;
456 havesym: 456 havesym:
457 case SHT_REL: 457 case SHT_REL:
458 case SHT_RELA: 458 case SHT_RELA:
459 case SHT_SYMTAB: 459 case SHT_SYMTAB:
460 ret = ELFNAMEEND(readfile_global)(fd, offset, 460 ret = ELFNAMEEND(readfile_global)(fd, offset,
461 shdr[i].sh_offset, addr, size); 461 shdr[i].sh_offset, addr, size);
462 if (ret == -1) { 462 if (ret == -1) {
463 goto out; 463 goto out;
464 } 464 }
465 shdr[i].sh_offset = maxp - elfp; 465 shdr[i].sh_offset = maxp - elfp;
466 maxp += roundup(size, ELFROUND); 466 maxp += roundup(size, ELFROUND);
467 break; 467 break;
468 } 468 }
469 } 469 }
470 maxp = roundup(maxp, KERNALIGN_SMALL); 470 maxp = roundup(maxp, KERNALIGN_SMALL);
471 471
472 /* 472 /*
473 * Finally, load the SECTION HEADERS. 473 * Finally, load the SECTION HEADERS.
474 */ 474 */
475#ifndef _STANDALONE 475#ifndef _STANDALONE
476 for (i = 0; i < elf->e_shnum; i++) 476 for (i = 0; i < elf->e_shnum; i++)
477 externalize_shdr(elf->e_ident[EI_DATA], &shdr[i]); 477 externalize_shdr(elf->e_ident[EI_DATA], &shdr[i]);
478#endif 478#endif
479 BCOPY(shdr, shpp, shdrsz); 479 BCOPY(shdr, shpp, shdrsz);
480 480
481 DEALLOC(shdr, shdrsz); 481 DEALLOC(shdr, shdrsz);
482 482
483 /* 483 /*
484 * Just update MARK_SYM and MARK_END without touching the rest. 484 * Just update MARK_SYM and MARK_END without touching the rest.
485 */ 485 */
486 marks[MARK_SYM] = LOADADDR(elfp); 486 marks[MARK_SYM] = LOADADDR(elfp);
487 marks[MARK_END] = LOADADDR(maxp); 487 marks[MARK_END] = LOADADDR(maxp);
488 return 0; 488 return 0;
489 489
490out: 490out:
491 DEALLOC(shdr, shdrsz); 491 DEALLOC(shdr, shdrsz);
492 return 1; 492 return 1;
493} 493}
494 494
495/* -------------------------------------------------------------------------- */ 495/* -------------------------------------------------------------------------- */
496 496
497/* 497/*
498 * See comment below. This function is in charge of loading the SECTION HEADERS. 498 * See comment below. This function is in charge of loading the SECTION HEADERS.
499 */ 499 */
500static int 500static int
501ELFNAMEEND(loadsym)(int fd, Elf_Ehdr *elf, Elf_Addr maxp, Elf_Addr elfp, 501ELFNAMEEND(loadsym)(int fd, Elf_Ehdr *elf, Elf_Addr maxp, Elf_Addr elfp,
502 u_long *marks, int flags, Elf_Addr *nmaxp) 502 u_long *marks, int flags, Elf_Addr *nmaxp)
503{ 503{
504 const u_long offset = marks[MARK_START]; 504 const u_long offset = marks[MARK_START];
505 int boot_load_ctf = 1; 505 int boot_load_ctf = 1;
506 Elf_Shdr *shp; 506 Elf_Shdr *shp;
507 Elf_Addr shpp; 507 Elf_Addr shpp;
508 char *shstr = NULL; 508 char *shstr = NULL;
509 size_t sz; 509 size_t sz;
510 size_t i, j, shstrsz = 0; 510 size_t i, j, shstrsz = 0;
511 struct __packed { 511 struct __packed {
512 Elf_Nhdr nh; 512 Elf_Nhdr nh;
513 uint8_t name[ELF_NOTE_NETBSD_NAMESZ + 1]; 513 uint8_t name[ELF_NOTE_NETBSD_NAMESZ + 1];
514 uint8_t desc[ELF_NOTE_NETBSD_DESCSZ]; 514 uint8_t desc[ELF_NOTE_NETBSD_DESCSZ];
515 } note; 515 } note;
516 int first; 516 int first;
517 int ret; 517 int ret;
518 518
519 sz = elf->e_shnum * sizeof(Elf_Shdr); 519 sz = elf->e_shnum * sizeof(Elf_Shdr);
520 shp = ALLOC(sz); 520 shp = ALLOC(sz);
521 ret = ELFNAMEEND(readfile_local)(fd, elf->e_shoff, shp, sz); 521 ret = ELFNAMEEND(readfile_local)(fd, elf->e_shoff, shp, sz);
522 if (ret == -1) { 522 if (ret == -1) {
523 goto out; 523 goto out;
524 } 524 }
525 525
526 shpp = maxp; 526 shpp = maxp;
527 maxp += roundup(sz, ELFROUND); 527 maxp += roundup(sz, ELFROUND);
528 528
529#ifndef _STANDALONE 529#ifndef _STANDALONE
530 for (i = 0; i < elf->e_shnum; i++) 530 for (i = 0; i < elf->e_shnum; i++)
531 internalize_shdr(elf->e_ident[EI_DATA], &shp[i]); 531 internalize_shdr(elf->e_ident[EI_DATA], &shp[i]);
532#endif 532#endif
533 533
534 /* 534 /*
535 * First load the section names section. Only useful for CTF. 535 * First load the section names section. Only useful for CTF.
536 */ 536 */
537 if (boot_load_ctf && (elf->e_shstrndx != SHN_UNDEF)) { 537 if (boot_load_ctf && (elf->e_shstrndx != SHN_UNDEF)) {
538 Elf_Off shstroff = shp[elf->e_shstrndx].sh_offset; 538 Elf_Off shstroff = shp[elf->e_shstrndx].sh_offset;
539 shstrsz = shp[elf->e_shstrndx].sh_size; 539 shstrsz = shp[elf->e_shstrndx].sh_size;
540 if (flags & LOAD_SYM) { 540 if (flags & LOAD_SYM) {
541 ret = ELFNAMEEND(readfile_global)(fd, offset, 541 ret = ELFNAMEEND(readfile_global)(fd, offset,
542 shstroff, maxp, shstrsz); 542 shstroff, maxp, shstrsz);
543 if (ret == -1) { 543 if (ret == -1) {
544 goto out; 544 goto out;
545 } 545 }
546 } 546 }
547 547
548 /* Create a local copy */ 548 /* Create a local copy */
549 shstr = ALLOC(shstrsz); 549 shstr = ALLOC(shstrsz);
550 ret = ELFNAMEEND(readfile_local)(fd, shstroff, shstr, shstrsz); 550 ret = ELFNAMEEND(readfile_local)(fd, shstroff, shstr, shstrsz);
551 if (ret == -1) { 551 if (ret == -1) {
552 goto out; 552 goto out;
553 } 553 }
554 shp[elf->e_shstrndx].sh_offset = maxp - elfp; 554 shp[elf->e_shstrndx].sh_offset = maxp - elfp;
555 maxp += roundup(shstrsz, ELFROUND); 555 maxp += roundup(shstrsz, ELFROUND);
556 } 556 }
557 557
558 /* 558 /*
559 * Now load the symbol sections themselves. Make sure the sections are 559 * Now load the symbol sections themselves. Make sure the sections are
560 * ELFROUND-aligned. Update sh_offset to be relative to elfp. Set it to 560 * ELFROUND-aligned. Update sh_offset to be relative to elfp. Set it to
561 * zero when we don't want the sections to be taken care of, the kernel 561 * zero when we don't want the sections to be taken care of, the kernel
562 * will properly skip them. 562 * will properly skip them.
563 */ 563 */
564 first = 1; 564 first = 1;
565 for (i = 1; i < elf->e_shnum; i++) { 565 for (i = 1; i < elf->e_shnum; i++) {
566 if (i == elf->e_shstrndx) { 566 if (i == elf->e_shstrndx) {
567 /* already loaded this section */ 567 /* already loaded this section */
568 continue; 568 continue;
569 } 569 }
570 570
571 switch (shp[i].sh_type) { 571 switch (shp[i].sh_type) {
572 case SHT_PROGBITS: 572 case SHT_PROGBITS:
573 if (boot_load_ctf && shstr) { 573 if (boot_load_ctf && shstr) {
574 /* got a CTF section? */ 574 /* got a CTF section? */
575 if (strncmp(&shstr[shp[i].sh_name], 575 if (strncmp(&shstr[shp[i].sh_name],
576 ".SUNW_ctf", 10) == 0) { 576 ".SUNW_ctf", 10) == 0) {
577 goto havesym; 577 goto havesym;
578 } 578 }
579 } 579 }
580 580
581 shp[i].sh_offset = 0; 581 shp[i].sh_offset = 0;
582 break; 582 break;
583 case SHT_STRTAB: 583 case SHT_STRTAB:
584 for (j = 1; j < elf->e_shnum; j++) 584 for (j = 1; j < elf->e_shnum; j++)
585 if (shp[j].sh_type == SHT_SYMTAB && 585 if (shp[j].sh_type == SHT_SYMTAB &&
586 shp[j].sh_link == (unsigned int)i) 586 shp[j].sh_link == (unsigned int)i)
587 goto havesym; 587 goto havesym;
588 /* 588 /*
589 * Don't bother with any string table that isn't 589 * Don't bother with any string table that isn't
590 * referenced by a symbol table. 590 * referenced by a symbol table.
591 */ 591 */
592 shp[i].sh_offset = 0; 592 shp[i].sh_offset = 0;
593 break; 593 break;
594havesym: 594havesym:
595 case SHT_SYMTAB: 595 case SHT_SYMTAB:
596 if (flags & LOAD_SYM) { 596 if (flags & LOAD_SYM) {
597 PROGRESS(("%s%ld", first ? " [" : "+", 597 PROGRESS(("%s%ld", first ? " [" : "+",
598 (u_long)shp[i].sh_size)); 598 (u_long)shp[i].sh_size));
599 ret = ELFNAMEEND(readfile_global)(fd, offset, 599 ret = ELFNAMEEND(readfile_global)(fd, offset,
600 shp[i].sh_offset, maxp, shp[i].sh_size); 600 shp[i].sh_offset, maxp, shp[i].sh_size);
601 if (ret == -1) { 601 if (ret == -1) {
602 goto out; 602 goto out;
603 } 603 }
604 } 604 }
605 shp[i].sh_offset = maxp - elfp; 605 shp[i].sh_offset = maxp - elfp;
606 maxp += roundup(shp[i].sh_size, ELFROUND); 606 maxp += roundup(shp[i].sh_size, ELFROUND);
607 first = 0; 607 first = 0;
608 break; 608 break;
609 case SHT_NOTE: 609 case SHT_NOTE:
610 if ((flags & LOAD_NOTE) == 0) 610 if ((flags & LOAD_NOTE) == 0)
611 break; 611 break;
612 if (shp[i].sh_size < sizeof(note)) { 612 if (shp[i].sh_size < sizeof(note)) {
613 shp[i].sh_offset = 0; 613 shp[i].sh_offset = 0;
614 break; 614 break;
615 } 615 }
616 616
617 ret = ELFNAMEEND(readfile_local)(fd, shp[i].sh_offset, 617 ret = ELFNAMEEND(readfile_local)(fd, shp[i].sh_offset,
618 &note, sizeof(note)); 618 &note, sizeof(note));
619 if (ret == -1) { 619 if (ret == -1) {
620 goto out; 620 goto out;
621 } 621 }
622 622
623 if (note.nh.n_namesz == ELF_NOTE_NETBSD_NAMESZ && 623 if (note.nh.n_namesz == ELF_NOTE_NETBSD_NAMESZ &&
624 note.nh.n_descsz == ELF_NOTE_NETBSD_DESCSZ && 624 note.nh.n_descsz == ELF_NOTE_NETBSD_DESCSZ &&
625 note.nh.n_type == ELF_NOTE_TYPE_NETBSD_TAG && 625 note.nh.n_type == ELF_NOTE_TYPE_NETBSD_TAG &&
626 memcmp(note.name, ELF_NOTE_NETBSD_NAME, 626 memcmp(note.name, ELF_NOTE_NETBSD_NAME,
627 sizeof(note.name)) == 0) { 627 sizeof(note.name)) == 0) {
628 memcpy(&netbsd_version, &note.desc, 628 memcpy(&netbsd_version, &note.desc,
629 sizeof(netbsd_version)); 629 sizeof(netbsd_version));
630 } 630 }
631 shp[i].sh_offset = 0; 631 shp[i].sh_offset = 0;
632 break; 632 break;
633 default: 633 default:
634 shp[i].sh_offset = 0; 634 shp[i].sh_offset = 0;
635 break; 635 break;
636 } 636 }
637 } 637 }
638 if (flags & LOAD_SYM) { 638 if (flags & LOAD_SYM) {
639#ifndef _STANDALONE 639#ifndef _STANDALONE
640 for (i = 0; i < elf->e_shnum; i++) 640 for (i = 0; i < elf->e_shnum; i++)
641 externalize_shdr(elf->e_ident[EI_DATA], &shp[i]); 641 externalize_shdr(elf->e_ident[EI_DATA], &shp[i]);
642#endif 642#endif
643 BCOPY(shp, shpp, sz); 643 BCOPY(shp, shpp, sz);
644 644
645 if (first == 0) 645 if (first == 0)
646 PROGRESS(("]")); 646 PROGRESS(("]"));
647 } 647 }
648 648
649 *nmaxp = maxp; 649 *nmaxp = maxp;
650 DEALLOC(shp, sz); 650 DEALLOC(shp, sz);
651 if (shstr != NULL) 651 if (shstr != NULL)
652 DEALLOC(shstr, shstrsz); 652 DEALLOC(shstr, shstrsz);
653 return 0; 653 return 0;
654 654
655out: 655out:
656 DEALLOC(shp, sz); 656 DEALLOC(shp, sz);
657 if (shstr != NULL) 657 if (shstr != NULL)
658 DEALLOC(shstr, shstrsz); 658 DEALLOC(shstr, shstrsz);
659 return -1; 659 return -1;
660} 660}
661 661
662/* -------------------------------------------------------------------------- */ 662/* -------------------------------------------------------------------------- */
663 663
664/* 664/*
665 * Load a static ELF binary into memory. Layout of the memory: 665 * Load a static ELF binary into memory. Layout of the memory:
666 * +-----------------+------------+-----------------+-----------------+ 666 * +-----------------+------------+-----------------+-----------------+
667 * | KERNEL SEGMENTS | ELF HEADER | SECTION HEADERS | SYMBOL SECTIONS | 667 * | KERNEL SEGMENTS | ELF HEADER | SECTION HEADERS | SYMBOL SECTIONS |
668 * +-----------------+------------+-----------------+-----------------+ 668 * +-----------------+------------+-----------------+-----------------+
669 * The KERNEL SEGMENTS start address is fixed by the segments themselves. We 669 * The KERNEL SEGMENTS start address is fixed by the segments themselves. We
670 * then map the rest by increasing maxp. 670 * then map the rest by increasing maxp.
671 * 671 *
672 * The offsets of the SYMBOL SECTIONS are relative to the start address of the 672 * The offsets of the SYMBOL SECTIONS are relative to the start address of the
673 * ELF HEADER. The shdr offset of ELF HEADER points to SECTION HEADERS. 673 * ELF HEADER. The shdr offset of ELF HEADER points to SECTION HEADERS.
674 * 674 *
675 * We just give the kernel a pointer to the ELF HEADER, which is enough for it 675 * We just give the kernel a pointer to the ELF HEADER, which is enough for it
676 * to find the location and number of symbols by itself later. 676 * to find the location and number of symbols by itself later.
677 */ 677 */
678static int 678static int
679ELFNAMEEND(loadfile_static)(int fd, Elf_Ehdr *elf, u_long *marks, int flags) 679ELFNAMEEND(loadfile_static)(int fd, Elf_Ehdr *elf, u_long *marks, int flags)
680{ 680{
681 const u_long offset = marks[MARK_START]; 681 const u_long offset = marks[MARK_START];
682 Elf_Phdr *phdr; 682 Elf_Phdr *phdr;
683 int i, first; 683 int i, first;
684 size_t sz; 684 size_t sz;
685 Elf_Addr minp = ~0, maxp = 0, pos = 0, elfp = 0; 685 Elf_Addr minp = ~0, maxp = 0, pos = 0, elfp = 0;
686 int ret; 686 int ret;
687 687
688 /* for ports that define progress to nothing */ 688 /* for ports that define progress to nothing */
689 (void)&first; 689 (void)&first;
690 690
691 /* have not seen a data segment so far */ 691 /* have not seen a data segment so far */
692 marks[MARK_DATA] = 0; 692 marks[MARK_DATA] = 0;
693 693
694 internalize_ehdr(elf->e_ident[EI_DATA], elf); 694 internalize_ehdr(elf->e_ident[EI_DATA], elf);
695 695
696 sz = elf->e_phnum * sizeof(Elf_Phdr); 696 sz = elf->e_phnum * sizeof(Elf_Phdr);
697 phdr = ALLOC(sz); 697 phdr = ALLOC(sz);
698 ret = ELFNAMEEND(readfile_local)(fd, elf->e_phoff, phdr, sz); 698 ret = ELFNAMEEND(readfile_local)(fd, elf->e_phoff, phdr, sz);
699 if (ret == -1) { 699 if (ret == -1) {
700 goto freephdr; 700 goto freephdr;
701 } 701 }
702 702
703 first = 1; 703 first = 1;
704 for (i = 0; i < elf->e_phnum; i++) { 704 for (i = 0; i < elf->e_phnum; i++) {
705 internalize_phdr(elf->e_ident[EI_DATA], &phdr[i]); 705 internalize_phdr(elf->e_ident[EI_DATA], &phdr[i]);
706 706
707 if (MD_LOADSEG(&phdr[i])) 707 if (MD_LOADSEG(&phdr[i]))
708 goto loadseg; 708 goto loadseg;
709 709
710 if (phdr[i].p_type != PT_LOAD || 710 if (phdr[i].p_type != PT_LOAD ||
711 (phdr[i].p_flags & (PF_W|PF_X)) == 0) 711 (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0)
712 continue; 712 continue;
713 713
714 if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) || 714 if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) ||
715 (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) { 715 (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) {
716 loadseg: 716 loadseg:
717 /* XXX: Assume first address is lowest */ 717 /* XXX: Assume first address is lowest */
718 if (marks[MARK_DATA] == 0 && IS_DATA(phdr[i])) 718 if (marks[MARK_DATA] == 0 && IS_DATA(phdr[i]))
719 marks[MARK_DATA] = LOADADDR(phdr[i].p_vaddr); 719 marks[MARK_DATA] = LOADADDR(phdr[i].p_vaddr);
720 720
721 /* Read in segment. */ 721 /* Read in segment. */
722 PROGRESS(("%s%lu", first ? "" : "+", 722 PROGRESS(("%s%lu", first ? "" : "+",
723 (u_long)phdr[i].p_filesz)); 723 (u_long)phdr[i].p_filesz));
724 724
725 ret = ELFNAMEEND(readfile_global)(fd, offset, 725 ret = ELFNAMEEND(readfile_global)(fd, offset,
726 phdr[i].p_offset, phdr[i].p_vaddr, 726 phdr[i].p_offset, phdr[i].p_vaddr,
727 phdr[i].p_filesz); 727 phdr[i].p_filesz);
728 if (ret == -1) { 728 if (ret == -1) {
729 goto freephdr; 729 goto freephdr;
730 } 730 }
731 731
732 first = 0; 732 first = 0;
733 } 733 }
734 if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT|COUNT_TEXT))) || 734 if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT|COUNT_TEXT))) ||
735 (IS_DATA(phdr[i]) && (flags & (LOAD_DATA|COUNT_DATA)))) { 735 (IS_DATA(phdr[i]) && (flags & (LOAD_DATA|COUNT_DATA)))) {
736 /* XXX: Assume first address is lowest */ 736 /* XXX: Assume first address is lowest */
737 if (marks[MARK_DATA] == 0 && IS_DATA(phdr[i])) 737 if (marks[MARK_DATA] == 0 && IS_DATA(phdr[i]))
738 marks[MARK_DATA] = LOADADDR(phdr[i].p_vaddr); 738 marks[MARK_DATA] = LOADADDR(phdr[i].p_vaddr);
739 739
740 pos = phdr[i].p_vaddr; 740 pos = phdr[i].p_vaddr;
741 if (minp > pos) 741 if (minp > pos)
742 minp = pos; 742 minp = pos;
743 pos += phdr[i].p_filesz; 743 pos += phdr[i].p_filesz;
744 if (maxp < pos) 744 if (maxp < pos)
745 maxp = pos; 745 maxp = pos;
746 } 746 }
747 747
748 /* Zero out bss. */ 748 /* Zero out bss. */
749 if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) { 749 if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) {
750 PROGRESS(("+%lu", 750 PROGRESS(("+%lu",
751 (u_long)(phdr[i].p_memsz - phdr[i].p_filesz))); 751 (u_long)(phdr[i].p_memsz - phdr[i].p_filesz)));
752 BZERO((phdr[i].p_vaddr + phdr[i].p_filesz), 752 BZERO((phdr[i].p_vaddr + phdr[i].p_filesz),
753 phdr[i].p_memsz - phdr[i].p_filesz); 753 phdr[i].p_memsz - phdr[i].p_filesz);
754 } 754 }
755 if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) { 755 if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) {
756 pos += phdr[i].p_memsz - phdr[i].p_filesz; 756 pos += phdr[i].p_memsz - phdr[i].p_filesz;
757 if (maxp < pos) 757 if (maxp < pos)
758 maxp = pos; 758 maxp = pos;
759 } 759 }
760 } 760 }
761 DEALLOC(phdr, sz); 761 DEALLOC(phdr, sz);
762 maxp = roundup(maxp, ELFROUND); 762 maxp = roundup(maxp, ELFROUND);
763 763
764 /* 764 /*
765 * Load the ELF HEADER, SECTION HEADERS and possibly the SYMBOL 765 * Load the ELF HEADER, SECTION HEADERS and possibly the SYMBOL
766 * SECTIONS. 766 * SECTIONS.
767 */ 767 */
768 if (flags & (LOAD_HDR|COUNT_HDR)) { 768 if (flags & (LOAD_HDR|COUNT_HDR)) {
769 elfp = maxp; 769 elfp = maxp;
770 maxp += sizeof(Elf_Ehdr); 770 maxp += sizeof(Elf_Ehdr);
771 } 771 }
772 if (flags & (LOAD_SYM|COUNT_SYM)) { 772 if (flags & (LOAD_SYM|COUNT_SYM)) {
773 if (ELFNAMEEND(loadsym)(fd, elf, maxp, elfp, marks, flags, 773 if (ELFNAMEEND(loadsym)(fd, elf, maxp, elfp, marks, flags,
774 &maxp) == -1) { 774 &maxp) == -1) {
775 return 1; 775 return 1;
776 } 776 }
777 } 777 }
778 778
779 /* 779 /*
780 * Update the ELF HEADER to give information relative to elfp. 780 * Update the ELF HEADER to give information relative to elfp.
781 */ 781 */
782 if (flags & LOAD_HDR) { 782 if (flags & LOAD_HDR) {
783 elf->e_phoff = 0; 783 elf->e_phoff = 0;
784 elf->e_shoff = sizeof(Elf_Ehdr); 784 elf->e_shoff = sizeof(Elf_Ehdr);
785 elf->e_phentsize = 0; 785 elf->e_phentsize = 0;
786 elf->e_phnum = 0; 786 elf->e_phnum = 0;
787 externalize_ehdr(elf->e_ident[EI_DATA], elf); 787 externalize_ehdr(elf->e_ident[EI_DATA], elf);
788 BCOPY(elf, elfp, sizeof(*elf)); 788 BCOPY(elf, elfp, sizeof(*elf));
789 internalize_ehdr(elf->e_ident[EI_DATA], elf); 789 internalize_ehdr(elf->e_ident[EI_DATA], elf);
790 } 790 }
791 791
792 marks[MARK_START] = LOADADDR(minp); 792 marks[MARK_START] = LOADADDR(minp);
793 marks[MARK_ENTRY] = LOADADDR(elf->e_entry); 793 marks[MARK_ENTRY] = LOADADDR(elf->e_entry);
794 marks[MARK_NSYM] = 1; /* XXX: Kernel needs >= 0 */ 794 marks[MARK_NSYM] = 1; /* XXX: Kernel needs >= 0 */
795 marks[MARK_SYM] = LOADADDR(elfp); 795 marks[MARK_SYM] = LOADADDR(elfp);
796 marks[MARK_END] = LOADADDR(maxp); 796 marks[MARK_END] = LOADADDR(maxp);
797 return 0; 797 return 0;
798 798
799freephdr: 799freephdr:
800 DEALLOC(phdr, sz); 800 DEALLOC(phdr, sz);
801 return 1; 801 return 1;
802} 802}
803 803
804/* -------------------------------------------------------------------------- */ 804/* -------------------------------------------------------------------------- */
805 805
806int 806int
807ELFNAMEEND(loadfile)(int fd, Elf_Ehdr *elf, u_long *marks, int flags) 807ELFNAMEEND(loadfile)(int fd, Elf_Ehdr *elf, u_long *marks, int flags)
808{ 808{
809 if (flags & LOAD_DYN) { 809 if (flags & LOAD_DYN) {
810 return ELFNAMEEND(loadfile_dynamic)(fd, elf, marks, flags); 810 return ELFNAMEEND(loadfile_dynamic)(fd, elf, marks, flags);
811 } else { 811 } else {
812 return ELFNAMEEND(loadfile_static)(fd, elf, marks, flags); 812 return ELFNAMEEND(loadfile_static)(fd, elf, marks, flags);
813 } 813 }
814} 814}
815 815
816#endif /* (ELFSIZE == 32 && BOOT_ELF32) || (ELFSIZE == 64 && BOOT_ELF64) */ 816#endif /* (ELFSIZE == 32 && BOOT_ELF32) || (ELFSIZE == 64 && BOOT_ELF64) */