Mon Apr 17 08:14:51 2023 UTC ()
KNF


(skrll)
diff -r1.76 -r1.77 src/sys/kern/subr_kobj.c

cvs diff -r1.76 -r1.77 src/sys/kern/subr_kobj.c (switch to unified diff)

--- src/sys/kern/subr_kobj.c 2023/01/29 17:20:48 1.76
+++ src/sys/kern/subr_kobj.c 2023/04/17 08:14:51 1.77
@@ -1,1080 +1,1081 @@ @@ -1,1080 +1,1081 @@
1/* $NetBSD: subr_kobj.c,v 1.76 2023/01/29 17:20:48 skrll Exp $ */ 1/* $NetBSD: subr_kobj.c,v 1.77 2023/04/17 08:14:51 skrll Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software developed for The NetBSD Foundation 7 * This code is derived from software developed for The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1998-2000 Doug Rabson 33 * Copyright (c) 1998-2000 Doug Rabson
34 * Copyright (c) 2004 Peter Wemm 34 * Copyright (c) 2004 Peter Wemm
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions 38 * modification, are permitted provided that the following conditions
39 * are met: 39 * are met:
40 * 1. Redistributions of source code must retain the above copyright 40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer. 41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright 42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the 43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution. 44 * documentation and/or other materials provided with the distribution.
45 * 45 *
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE. 56 * SUCH DAMAGE.
57 */ 57 */
58 58
59/* 59/*
60 * Kernel loader for ELF objects. 60 * Kernel loader for ELF objects.
61 * 61 *
62 * TODO: adjust kmem_alloc() calls to avoid needless fragmentation. 62 * TODO: adjust kmem_alloc() calls to avoid needless fragmentation.
63 */ 63 */
64 64
65#include <sys/cdefs.h> 65#include <sys/cdefs.h>
66__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.76 2023/01/29 17:20:48 skrll Exp $"); 66__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.77 2023/04/17 08:14:51 skrll Exp $");
67 67
68#ifdef _KERNEL_OPT 68#ifdef _KERNEL_OPT
69#include "opt_modular.h" 69#include "opt_modular.h"
70#endif 70#endif
71 71
72#include <sys/kobj_impl.h> 72#include <sys/kobj_impl.h>
73 73
74#ifdef MODULAR 74#ifdef MODULAR
75 75
76#include <sys/param.h> 76#include <sys/param.h>
 77
77#include <sys/kernel.h> 78#include <sys/kernel.h>
78#include <sys/kmem.h> 79#include <sys/kmem.h>
79#include <sys/proc.h> 
80#include <sys/ksyms.h> 80#include <sys/ksyms.h>
81#include <sys/module.h> 81#include <sys/module.h>
 82#include <sys/proc.h>
82 83
83#include <uvm/uvm_extern.h> 84#include <uvm/uvm_extern.h>
84 85
85#define kobj_error(_kobj, ...) \ 86#define kobj_error(_kobj, ...) \
86 kobj_out(__func__, __LINE__, _kobj, __VA_ARGS__) 87 kobj_out(__func__, __LINE__, _kobj, __VA_ARGS__)
87 88
88static int kobj_relocate(kobj_t, bool); 89static int kobj_relocate(kobj_t, bool);
89static int kobj_checksyms(kobj_t, bool); 90static int kobj_checksyms(kobj_t, bool);
90static void kobj_out(const char *, int, kobj_t, const char *, ...) 91static void kobj_out(const char *, int, kobj_t, const char *, ...)
91 __printflike(4, 5); 92 __printflike(4, 5);
92static void kobj_jettison(kobj_t); 93static void kobj_jettison(kobj_t);
93static void kobj_free(kobj_t, void *, size_t); 94static void kobj_free(kobj_t, void *, size_t);
94static void kobj_close(kobj_t); 95static void kobj_close(kobj_t);
95static int kobj_read_mem(kobj_t, void **, size_t, off_t, bool); 96static int kobj_read_mem(kobj_t, void **, size_t, off_t, bool);
96static void kobj_close_mem(kobj_t); 97static void kobj_close_mem(kobj_t);
97 98
98/* 99/*
99 * kobj_load_mem: 100 * kobj_load_mem:
100 * 101 *
101 * Load an object already resident in memory. If size is not -1, 102 * Load an object already resident in memory. If size is not -1,
102 * the complete size of the object is known. 103 * the complete size of the object is known.
103 */ 104 */
104int 105int
105kobj_load_mem(kobj_t *kop, const char *name, void *base, ssize_t size) 106kobj_load_mem(kobj_t *kop, const char *name, void *base, ssize_t size)
106{ 107{
107 kobj_t ko; 108 kobj_t ko;
108 109
109 ko = kmem_zalloc(sizeof(*ko), KM_SLEEP); 110 ko = kmem_zalloc(sizeof(*ko), KM_SLEEP);
110 ko->ko_type = KT_MEMORY; 111 ko->ko_type = KT_MEMORY;
111 kobj_setname(ko, name); 112 kobj_setname(ko, name);
112 ko->ko_source = base; 113 ko->ko_source = base;
113 ko->ko_memsize = size; 114 ko->ko_memsize = size;
114 ko->ko_read = kobj_read_mem; 115 ko->ko_read = kobj_read_mem;
115 ko->ko_close = kobj_close_mem; 116 ko->ko_close = kobj_close_mem;
116 117
117 *kop = ko; 118 *kop = ko;
118 return kobj_load(ko); 119 return kobj_load(ko);
119} 120}
120 121
121/* 122/*
122 * kobj_close: 123 * kobj_close:
123 * 124 *
124 * Close an open ELF object. 125 * Close an open ELF object.
125 */ 126 */
126static void 127static void
127kobj_close(kobj_t ko) 128kobj_close(kobj_t ko)
128{ 129{
129 130
130 if (ko->ko_source == NULL) { 131 if (ko->ko_source == NULL) {
131 return; 132 return;
132 } 133 }
133 134
134 ko->ko_close(ko); 135 ko->ko_close(ko);
135 ko->ko_source = NULL; 136 ko->ko_source = NULL;
136} 137}
137 138
138static void 139static void
139kobj_close_mem(kobj_t ko) 140kobj_close_mem(kobj_t ko)
140{ 141{
141 142
142 return; 143 return;
143} 144}
144 145
145/* 146/*
146 * kobj_load: 147 * kobj_load:
147 * 148 *
148 * Load an ELF object and prepare to link into the running kernel 149 * Load an ELF object and prepare to link into the running kernel
149 * image. 150 * image.
150 */ 151 */
151int 152int
152kobj_load(kobj_t ko) 153kobj_load(kobj_t ko)
153{ 154{
154 Elf_Ehdr *hdr; 155 Elf_Ehdr *hdr;
155 Elf_Shdr *shdr; 156 Elf_Shdr *shdr;
156 Elf_Sym *es; 157 Elf_Sym *es;
157 vaddr_t map_text_base; 158 vaddr_t map_text_base;
158 vaddr_t map_data_base; 159 vaddr_t map_data_base;
159 vaddr_t map_rodata_base; 160 vaddr_t map_rodata_base;
160 size_t map_text_size; 161 size_t map_text_size;
161 size_t map_data_size; 162 size_t map_data_size;
162 size_t map_rodata_size; 163 size_t map_rodata_size;
163 int error; 164 int error;
164 int symtabindex; 165 int symtabindex;
165 int symstrindex; 166 int symstrindex;
166 int nsym; 167 int nsym;
167 int pb, rl, ra; 168 int pb, rl, ra;
168 int alignmask; 169 int alignmask;
169 int i, j; 170 int i, j;
170 void *addr; 171 void *addr;
171 172
172 KASSERT(ko->ko_type != KT_UNSET); 173 KASSERT(ko->ko_type != KT_UNSET);
173 KASSERT(ko->ko_source != NULL); 174 KASSERT(ko->ko_source != NULL);
174 175
175 shdr = NULL; 176 shdr = NULL;
176 error = 0; 177 error = 0;
177 hdr = NULL; 178 hdr = NULL;
178 179
179 /* 180 /*
180 * Read the elf header from the file. 181 * Read the elf header from the file.
181 */ 182 */
182 error = ko->ko_read(ko, (void **)&hdr, sizeof(*hdr), 0, true); 183 error = ko->ko_read(ko, (void **)&hdr, sizeof(*hdr), 0, true);
183 if (error != 0) { 184 if (error != 0) {
184 kobj_error(ko, "read failed %d", error); 185 kobj_error(ko, "read failed %d", error);
185 goto out; 186 goto out;
186 } 187 }
187 if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0) { 188 if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0) {
188 kobj_error(ko, "not an ELF object"); 189 kobj_error(ko, "not an ELF object");
189 error = ENOEXEC; 190 error = ENOEXEC;
190 goto out; 191 goto out;
191 } 192 }
192 193
193 if (hdr->e_ident[EI_VERSION] != EV_CURRENT || 194 if (hdr->e_ident[EI_VERSION] != EV_CURRENT ||
194 hdr->e_version != EV_CURRENT) { 195 hdr->e_version != EV_CURRENT) {
195 kobj_error(ko, "unsupported file version %d", 196 kobj_error(ko, "unsupported file version %d",
196 hdr->e_ident[EI_VERSION]); 197 hdr->e_ident[EI_VERSION]);
197 error = ENOEXEC; 198 error = ENOEXEC;
198 goto out; 199 goto out;
199 } 200 }
200 if (hdr->e_type != ET_REL) { 201 if (hdr->e_type != ET_REL) {
201 kobj_error(ko, "unsupported file type %d", hdr->e_type); 202 kobj_error(ko, "unsupported file type %d", hdr->e_type);
202 error = ENOEXEC; 203 error = ENOEXEC;
203 goto out; 204 goto out;
204 } 205 }
205 switch (hdr->e_machine) { 206 switch (hdr->e_machine) {
206#if ELFSIZE == 32 207#if ELFSIZE == 32
207 ELF32_MACHDEP_ID_CASES 208 ELF32_MACHDEP_ID_CASES
208#elif ELFSIZE == 64 209#elif ELFSIZE == 64
209 ELF64_MACHDEP_ID_CASES 210 ELF64_MACHDEP_ID_CASES
210#else 211#else
211#error not defined 212#error not defined
212#endif 213#endif
213 default: 214 default:
214 kobj_error(ko, "unsupported machine %d", hdr->e_machine); 215 kobj_error(ko, "unsupported machine %d", hdr->e_machine);
215 error = ENOEXEC; 216 error = ENOEXEC;
216 goto out; 217 goto out;
217 } 218 }
218 219
219 ko->ko_nprogtab = 0; 220 ko->ko_nprogtab = 0;
220 ko->ko_shdr = 0; 221 ko->ko_shdr = 0;
221 ko->ko_nrel = 0; 222 ko->ko_nrel = 0;
222 ko->ko_nrela = 0; 223 ko->ko_nrela = 0;
223 224
224 /* 225 /*
225 * Allocate and read in the section header. 226 * Allocate and read in the section header.
226 */ 227 */
227 if (hdr->e_shnum == 0 || hdr->e_shnum > ELF_MAXSHNUM || 228 if (hdr->e_shnum == 0 || hdr->e_shnum > ELF_MAXSHNUM ||
228 hdr->e_shoff == 0 || hdr->e_shentsize != sizeof(Elf_Shdr)) { 229 hdr->e_shoff == 0 || hdr->e_shentsize != sizeof(Elf_Shdr)) {
229 kobj_error(ko, "bad sizes"); 230 kobj_error(ko, "bad sizes");
230 error = ENOEXEC; 231 error = ENOEXEC;
231 goto out; 232 goto out;
232 } 233 }
233 ko->ko_shdrsz = hdr->e_shnum * sizeof(Elf_Shdr); 234 ko->ko_shdrsz = hdr->e_shnum * sizeof(Elf_Shdr);
234 error = ko->ko_read(ko, (void **)&shdr, ko->ko_shdrsz, hdr->e_shoff, 235 error = ko->ko_read(ko, (void **)&shdr, ko->ko_shdrsz, hdr->e_shoff,
235 true); 236 true);
236 if (error != 0) { 237 if (error != 0) {
237 kobj_error(ko, "read failed %d", error); 238 kobj_error(ko, "read failed %d", error);
238 goto out; 239 goto out;
239 } 240 }
240 ko->ko_shdr = shdr; 241 ko->ko_shdr = shdr;
241 242
242 /* 243 /*
243 * Scan the section header for information and table sizing. 244 * Scan the section header for information and table sizing.
244 */ 245 */
245 nsym = 0; 246 nsym = 0;
246 symtabindex = symstrindex = -1; 247 symtabindex = symstrindex = -1;
247 for (i = 0; i < hdr->e_shnum; i++) { 248 for (i = 0; i < hdr->e_shnum; i++) {
248 switch (shdr[i].sh_type) { 249 switch (shdr[i].sh_type) {
249 case SHT_PROGBITS: 250 case SHT_PROGBITS:
250 case SHT_NOBITS: 251 case SHT_NOBITS:
251 ko->ko_nprogtab++; 252 ko->ko_nprogtab++;
252 break; 253 break;
253 case SHT_SYMTAB: 254 case SHT_SYMTAB:
254 nsym++; 255 nsym++;
255 symtabindex = i; 256 symtabindex = i;
256 symstrindex = shdr[i].sh_link; 257 symstrindex = shdr[i].sh_link;
257 break; 258 break;
258 case SHT_REL: 259 case SHT_REL:
259 if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS) 260 if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS)
260 continue; 261 continue;
261 ko->ko_nrel++; 262 ko->ko_nrel++;
262 break; 263 break;
263 case SHT_RELA: 264 case SHT_RELA:
264 if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS) 265 if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS)
265 continue; 266 continue;
266 ko->ko_nrela++; 267 ko->ko_nrela++;
267 break; 268 break;
268 case SHT_STRTAB: 269 case SHT_STRTAB:
269 break; 270 break;
270 } 271 }
271 } 272 }
272 if (ko->ko_nprogtab == 0) { 273 if (ko->ko_nprogtab == 0) {
273 kobj_error(ko, "file has no contents"); 274 kobj_error(ko, "file has no contents");
274 error = ENOEXEC; 275 error = ENOEXEC;
275 goto out; 276 goto out;
276 } 277 }
277 if (nsym != 1) { 278 if (nsym != 1) {
278 /* Only allow one symbol table for now */ 279 /* Only allow one symbol table for now */
279 kobj_error(ko, "file has no valid symbol table"); 280 kobj_error(ko, "file has no valid symbol table");
280 error = ENOEXEC; 281 error = ENOEXEC;
281 goto out; 282 goto out;
282 } 283 }
283 KASSERT(symtabindex != -1); 284 KASSERT(symtabindex != -1);
284 KASSERT(symstrindex != -1); 285 KASSERT(symstrindex != -1);
285 286
286 if (symstrindex == SHN_UNDEF || symstrindex >= hdr->e_shnum || 287 if (symstrindex == SHN_UNDEF || symstrindex >= hdr->e_shnum ||
287 shdr[symstrindex].sh_type != SHT_STRTAB) { 288 shdr[symstrindex].sh_type != SHT_STRTAB) {
288 kobj_error(ko, "file has invalid symbol strings"); 289 kobj_error(ko, "file has invalid symbol strings");
289 error = ENOEXEC; 290 error = ENOEXEC;
290 goto out; 291 goto out;
291 } 292 }
292 293
293 /* 294 /*
294 * Allocate space for tracking the load chunks. 295 * Allocate space for tracking the load chunks.
295 */ 296 */
296 if (ko->ko_nprogtab != 0) { 297 if (ko->ko_nprogtab != 0) {
297 ko->ko_progtab = kmem_zalloc(ko->ko_nprogtab * 298 ko->ko_progtab = kmem_zalloc(ko->ko_nprogtab *
298 sizeof(*ko->ko_progtab), KM_SLEEP); 299 sizeof(*ko->ko_progtab), KM_SLEEP);
299 if (ko->ko_progtab == NULL) { 300 if (ko->ko_progtab == NULL) {
300 error = ENOMEM; 301 error = ENOMEM;
301 kobj_error(ko, "out of memory"); 302 kobj_error(ko, "out of memory");
302 goto out; 303 goto out;
303 } 304 }
304 } 305 }
305 if (ko->ko_nrel != 0) { 306 if (ko->ko_nrel != 0) {
306 ko->ko_reltab = kmem_zalloc(ko->ko_nrel * 307 ko->ko_reltab = kmem_zalloc(ko->ko_nrel *
307 sizeof(*ko->ko_reltab), KM_SLEEP); 308 sizeof(*ko->ko_reltab), KM_SLEEP);
308 if (ko->ko_reltab == NULL) { 309 if (ko->ko_reltab == NULL) {
309 error = ENOMEM; 310 error = ENOMEM;
310 kobj_error(ko, "out of memory"); 311 kobj_error(ko, "out of memory");
311 goto out; 312 goto out;
312 } 313 }
313 } 314 }
314 if (ko->ko_nrela != 0) { 315 if (ko->ko_nrela != 0) {
315 ko->ko_relatab = kmem_zalloc(ko->ko_nrela * 316 ko->ko_relatab = kmem_zalloc(ko->ko_nrela *
316 sizeof(*ko->ko_relatab), KM_SLEEP); 317 sizeof(*ko->ko_relatab), KM_SLEEP);
317 if (ko->ko_relatab == NULL) { 318 if (ko->ko_relatab == NULL) {
318 error = ENOMEM; 319 error = ENOMEM;
319 kobj_error(ko, "out of memory"); 320 kobj_error(ko, "out of memory");
320 goto out; 321 goto out;
321 } 322 }
322 } 323 }
323 324
324 /* 325 /*
325 * Allocate space for and load the symbol table. 326 * Allocate space for and load the symbol table.
326 */ 327 */
327 ko->ko_symcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym); 328 ko->ko_symcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym);
328 if (ko->ko_symcnt == 0) { 329 if (ko->ko_symcnt == 0) {
329 kobj_error(ko, "no symbol table"); 330 kobj_error(ko, "no symbol table");
330 error = ENOEXEC; 331 error = ENOEXEC;
331 goto out; 332 goto out;
332 } 333 }
333 error = ko->ko_read(ko, (void **)&ko->ko_symtab, 334 error = ko->ko_read(ko, (void **)&ko->ko_symtab,
334 ko->ko_symcnt * sizeof(Elf_Sym), 335 ko->ko_symcnt * sizeof(Elf_Sym),
335 shdr[symtabindex].sh_offset, true); 336 shdr[symtabindex].sh_offset, true);
336 if (error != 0) { 337 if (error != 0) {
337 kobj_error(ko, "read failed %d", error); 338 kobj_error(ko, "read failed %d", error);
338 goto out; 339 goto out;
339 } 340 }
340 341
341 /* 342 /*
342 * Allocate space for and load the symbol strings. 343 * Allocate space for and load the symbol strings.
343 */ 344 */
344 ko->ko_strtabsz = shdr[symstrindex].sh_size; 345 ko->ko_strtabsz = shdr[symstrindex].sh_size;
345 if (ko->ko_strtabsz == 0) { 346 if (ko->ko_strtabsz == 0) {
346 kobj_error(ko, "no symbol strings"); 347 kobj_error(ko, "no symbol strings");
347 error = ENOEXEC; 348 error = ENOEXEC;
348 goto out; 349 goto out;
349 } 350 }
350 error = ko->ko_read(ko, (void *)&ko->ko_strtab, ko->ko_strtabsz, 351 error = ko->ko_read(ko, (void *)&ko->ko_strtab, ko->ko_strtabsz,
351 shdr[symstrindex].sh_offset, true); 352 shdr[symstrindex].sh_offset, true);
352 if (error != 0) { 353 if (error != 0) {
353 kobj_error(ko, "read failed %d", error); 354 kobj_error(ko, "read failed %d", error);
354 goto out; 355 goto out;
355 } 356 }
356 357
357 /* 358 /*
358 * Adjust module symbol namespace, if necessary (e.g. with rump) 359 * Adjust module symbol namespace, if necessary (e.g. with rump)
359 */ 360 */
360 error = kobj_renamespace(ko->ko_symtab, ko->ko_symcnt, 361 error = kobj_renamespace(ko->ko_symtab, ko->ko_symcnt,
361 &ko->ko_strtab, &ko->ko_strtabsz); 362 &ko->ko_strtab, &ko->ko_strtabsz);
362 if (error != 0) { 363 if (error != 0) {
363 kobj_error(ko, "renamespace failed %d", error); 364 kobj_error(ko, "renamespace failed %d", error);
364 goto out; 365 goto out;
365 } 366 }
366 367
367 /* 368 /*
368 * Do we have a string table for the section names? 369 * Do we have a string table for the section names?
369 */ 370 */
370 if (hdr->e_shstrndx != SHN_UNDEF) { 371 if (hdr->e_shstrndx != SHN_UNDEF) {
371 if (hdr->e_shstrndx >= hdr->e_shnum) { 372 if (hdr->e_shstrndx >= hdr->e_shnum) {
372 kobj_error(ko, "bad shstrndx"); 373 kobj_error(ko, "bad shstrndx");
373 error = ENOEXEC; 374 error = ENOEXEC;
374 goto out; 375 goto out;
375 } 376 }
376 if (shdr[hdr->e_shstrndx].sh_size != 0 && 377 if (shdr[hdr->e_shstrndx].sh_size != 0 &&
377 shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) { 378 shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) {
378 ko->ko_shstrtabsz = shdr[hdr->e_shstrndx].sh_size; 379 ko->ko_shstrtabsz = shdr[hdr->e_shstrndx].sh_size;
379 error = ko->ko_read(ko, (void **)&ko->ko_shstrtab, 380 error = ko->ko_read(ko, (void **)&ko->ko_shstrtab,
380 shdr[hdr->e_shstrndx].sh_size, 381 shdr[hdr->e_shstrndx].sh_size,
381 shdr[hdr->e_shstrndx].sh_offset, true); 382 shdr[hdr->e_shstrndx].sh_offset, true);
382 if (error != 0) { 383 if (error != 0) {
383 kobj_error(ko, "read failed %d", error); 384 kobj_error(ko, "read failed %d", error);
384 goto out; 385 goto out;
385 } 386 }
386 } 387 }
387 } 388 }
388 389
389 /* 390 /*
390 * Size up code/data(progbits) and bss(nobits). 391 * Size up code/data(progbits) and bss(nobits).
391 */ 392 */
392 alignmask = 0; 393 alignmask = 0;
393 map_text_size = 0; 394 map_text_size = 0;
394 map_data_size = 0; 395 map_data_size = 0;
395 map_rodata_size = 0; 396 map_rodata_size = 0;
396 for (i = 0; i < hdr->e_shnum; i++) { 397 for (i = 0; i < hdr->e_shnum; i++) {
397 if (shdr[i].sh_type != SHT_PROGBITS && 398 if (shdr[i].sh_type != SHT_PROGBITS &&
398 shdr[i].sh_type != SHT_NOBITS) 399 shdr[i].sh_type != SHT_NOBITS)
399 continue; 400 continue;
400 alignmask = shdr[i].sh_addralign - 1; 401 alignmask = shdr[i].sh_addralign - 1;
401 if ((shdr[i].sh_flags & SHF_EXECINSTR)) { 402 if ((shdr[i].sh_flags & SHF_EXECINSTR)) {
402 map_text_size += alignmask; 403 map_text_size += alignmask;
403 map_text_size &= ~alignmask; 404 map_text_size &= ~alignmask;
404 map_text_size += shdr[i].sh_size; 405 map_text_size += shdr[i].sh_size;
405 } else if (!(shdr[i].sh_flags & SHF_WRITE)) { 406 } else if (!(shdr[i].sh_flags & SHF_WRITE)) {
406 map_rodata_size += alignmask; 407 map_rodata_size += alignmask;
407 map_rodata_size &= ~alignmask; 408 map_rodata_size &= ~alignmask;
408 map_rodata_size += shdr[i].sh_size; 409 map_rodata_size += shdr[i].sh_size;
409 } else { 410 } else {
410 map_data_size += alignmask; 411 map_data_size += alignmask;
411 map_data_size &= ~alignmask; 412 map_data_size &= ~alignmask;
412 map_data_size += shdr[i].sh_size; 413 map_data_size += shdr[i].sh_size;
413 } 414 }
414 } 415 }
415 416
416 if (map_text_size == 0) { 417 if (map_text_size == 0) {
417 kobj_error(ko, "no text"); 418 kobj_error(ko, "no text");
418 error = ENOEXEC; 419 error = ENOEXEC;
419 goto out; 420 goto out;
420 } 421 }
421 422
422 if (map_data_size != 0) { 423 if (map_data_size != 0) {
423 map_data_base = uvm_km_alloc(module_map, round_page(map_data_size), 424 map_data_base = uvm_km_alloc(module_map, round_page(map_data_size),
424 0, UVM_KMF_WIRED); 425 0, UVM_KMF_WIRED);
425 if (map_data_base == 0) { 426 if (map_data_base == 0) {
426 kobj_error(ko, "out of memory"); 427 kobj_error(ko, "out of memory");
427 error = ENOMEM; 428 error = ENOMEM;
428 goto out; 429 goto out;
429 } 430 }
430 ko->ko_data_address = map_data_base; 431 ko->ko_data_address = map_data_base;
431 ko->ko_data_size = map_data_size; 432 ko->ko_data_size = map_data_size;
432 } else { 433 } else {
433 map_data_base = 0; 434 map_data_base = 0;
434 ko->ko_data_address = 0; 435 ko->ko_data_address = 0;
435 ko->ko_data_size = 0; 436 ko->ko_data_size = 0;
436 } 437 }
437 438
438 if (map_rodata_size != 0) { 439 if (map_rodata_size != 0) {
439 map_rodata_base = uvm_km_alloc(module_map, round_page(map_rodata_size), 440 map_rodata_base = uvm_km_alloc(module_map, round_page(map_rodata_size),
440 0, UVM_KMF_WIRED); 441 0, UVM_KMF_WIRED);
441 if (map_rodata_base == 0) { 442 if (map_rodata_base == 0) {
442 kobj_error(ko, "out of memory"); 443 kobj_error(ko, "out of memory");
443 error = ENOMEM; 444 error = ENOMEM;
444 goto out; 445 goto out;
445 } 446 }
446 ko->ko_rodata_address = map_rodata_base; 447 ko->ko_rodata_address = map_rodata_base;
447 ko->ko_rodata_size = map_rodata_size; 448 ko->ko_rodata_size = map_rodata_size;
448 } else { 449 } else {
449 map_rodata_base = 0; 450 map_rodata_base = 0;
450 ko->ko_rodata_address = 0; 451 ko->ko_rodata_address = 0;
451 ko->ko_rodata_size = 0; 452 ko->ko_rodata_size = 0;
452 } 453 }
453 454
454 map_text_base = uvm_km_alloc(module_map, round_page(map_text_size), 455 map_text_base = uvm_km_alloc(module_map, round_page(map_text_size),
455 0, UVM_KMF_WIRED | UVM_KMF_EXEC); 456 0, UVM_KMF_WIRED | UVM_KMF_EXEC);
456 if (map_text_base == 0) { 457 if (map_text_base == 0) {
457 kobj_error(ko, "out of memory"); 458 kobj_error(ko, "out of memory");
458 error = ENOMEM; 459 error = ENOMEM;
459 goto out; 460 goto out;
460 } 461 }
461 ko->ko_text_address = map_text_base; 462 ko->ko_text_address = map_text_base;
462 ko->ko_text_size = map_text_size; 463 ko->ko_text_size = map_text_size;
463 464
464 /* 465 /*
465 * Now load code/data(progbits), zero bss(nobits), allocate space 466 * Now load code/data(progbits), zero bss(nobits), allocate space
466 * for and load relocs 467 * for and load relocs
467 */ 468 */
468 pb = 0; 469 pb = 0;
469 rl = 0; 470 rl = 0;
470 ra = 0; 471 ra = 0;
471 alignmask = 0; 472 alignmask = 0;
472 for (i = 0; i < hdr->e_shnum; i++) { 473 for (i = 0; i < hdr->e_shnum; i++) {
473 switch (shdr[i].sh_type) { 474 switch (shdr[i].sh_type) {
474 case SHT_PROGBITS: 475 case SHT_PROGBITS:
475 case SHT_NOBITS: 476 case SHT_NOBITS:
476 alignmask = shdr[i].sh_addralign - 1; 477 alignmask = shdr[i].sh_addralign - 1;
477 if ((shdr[i].sh_flags & SHF_EXECINSTR)) { 478 if ((shdr[i].sh_flags & SHF_EXECINSTR)) {
478 map_text_base += alignmask; 479 map_text_base += alignmask;
479 map_text_base &= ~alignmask; 480 map_text_base &= ~alignmask;
480 addr = (void *)map_text_base; 481 addr = (void *)map_text_base;
481 map_text_base += shdr[i].sh_size; 482 map_text_base += shdr[i].sh_size;
482 } else if (!(shdr[i].sh_flags & SHF_WRITE)) { 483 } else if (!(shdr[i].sh_flags & SHF_WRITE)) {
483 map_rodata_base += alignmask; 484 map_rodata_base += alignmask;
484 map_rodata_base &= ~alignmask; 485 map_rodata_base &= ~alignmask;
485 addr = (void *)map_rodata_base; 486 addr = (void *)map_rodata_base;
486 map_rodata_base += shdr[i].sh_size; 487 map_rodata_base += shdr[i].sh_size;
487 } else { 488 } else {
488 map_data_base += alignmask; 489 map_data_base += alignmask;
489 map_data_base &= ~alignmask; 490 map_data_base &= ~alignmask;
490 addr = (void *)map_data_base; 491 addr = (void *)map_data_base;
491 map_data_base += shdr[i].sh_size; 492 map_data_base += shdr[i].sh_size;
492 } 493 }
493 494
494 ko->ko_progtab[pb].addr = addr; 495 ko->ko_progtab[pb].addr = addr;
495 if (shdr[i].sh_type == SHT_PROGBITS) { 496 if (shdr[i].sh_type == SHT_PROGBITS) {
496 ko->ko_progtab[pb].name = "<<PROGBITS>>"; 497 ko->ko_progtab[pb].name = "<<PROGBITS>>";
497 error = ko->ko_read(ko, &addr, 498 error = ko->ko_read(ko, &addr,
498 shdr[i].sh_size, shdr[i].sh_offset, false); 499 shdr[i].sh_size, shdr[i].sh_offset, false);
499 if (error != 0) { 500 if (error != 0) {
500 kobj_error(ko, "read failed %d", error); 501 kobj_error(ko, "read failed %d", error);
501 goto out; 502 goto out;
502 } 503 }
503 } else { /* SHT_NOBITS */ 504 } else { /* SHT_NOBITS */
504 ko->ko_progtab[pb].name = "<<NOBITS>>"; 505 ko->ko_progtab[pb].name = "<<NOBITS>>";
505 memset(addr, 0, shdr[i].sh_size); 506 memset(addr, 0, shdr[i].sh_size);
506 } 507 }
507 508
508 ko->ko_progtab[pb].size = shdr[i].sh_size; 509 ko->ko_progtab[pb].size = shdr[i].sh_size;
509 ko->ko_progtab[pb].sec = i; 510 ko->ko_progtab[pb].sec = i;
510 if (ko->ko_shstrtab != NULL && shdr[i].sh_name != 0) { 511 if (ko->ko_shstrtab != NULL && shdr[i].sh_name != 0) {
511 ko->ko_progtab[pb].name = 512 ko->ko_progtab[pb].name =
512 ko->ko_shstrtab + shdr[i].sh_name; 513 ko->ko_shstrtab + shdr[i].sh_name;
513 } 514 }
514 515
515 /* Update all symbol values with the offset. */ 516 /* Update all symbol values with the offset. */
516 for (j = 0; j < ko->ko_symcnt; j++) { 517 for (j = 0; j < ko->ko_symcnt; j++) {
517 es = &ko->ko_symtab[j]; 518 es = &ko->ko_symtab[j];
518 if (es->st_shndx != i) { 519 if (es->st_shndx != i) {
519 continue; 520 continue;
520 } 521 }
521 es->st_value += (Elf_Addr)addr; 522 es->st_value += (Elf_Addr)addr;
522 } 523 }
523 pb++; 524 pb++;
524 break; 525 break;
525 case SHT_REL: 526 case SHT_REL:
526 if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS) 527 if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS)
527 break; 528 break;
528 ko->ko_reltab[rl].size = shdr[i].sh_size; 529 ko->ko_reltab[rl].size = shdr[i].sh_size;
529 ko->ko_reltab[rl].size -= 530 ko->ko_reltab[rl].size -=
530 shdr[i].sh_size % sizeof(Elf_Rel); 531 shdr[i].sh_size % sizeof(Elf_Rel);
531 if (ko->ko_reltab[rl].size != 0) { 532 if (ko->ko_reltab[rl].size != 0) {
532 ko->ko_reltab[rl].nrel = 533 ko->ko_reltab[rl].nrel =
533 shdr[i].sh_size / sizeof(Elf_Rel); 534 shdr[i].sh_size / sizeof(Elf_Rel);
534 ko->ko_reltab[rl].sec = shdr[i].sh_info; 535 ko->ko_reltab[rl].sec = shdr[i].sh_info;
535 error = ko->ko_read(ko, 536 error = ko->ko_read(ko,
536 (void **)&ko->ko_reltab[rl].rel, 537 (void **)&ko->ko_reltab[rl].rel,
537 ko->ko_reltab[rl].size, 538 ko->ko_reltab[rl].size,
538 shdr[i].sh_offset, true); 539 shdr[i].sh_offset, true);
539 if (error != 0) { 540 if (error != 0) {
540 kobj_error(ko, "read failed %d", 541 kobj_error(ko, "read failed %d",
541 error); 542 error);
542 goto out; 543 goto out;
543 } 544 }
544 } 545 }
545 rl++; 546 rl++;
546 break; 547 break;
547 case SHT_RELA: 548 case SHT_RELA:
548 if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS) 549 if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS)
549 break; 550 break;
550 ko->ko_relatab[ra].size = shdr[i].sh_size; 551 ko->ko_relatab[ra].size = shdr[i].sh_size;
551 ko->ko_relatab[ra].size -= 552 ko->ko_relatab[ra].size -=
552 shdr[i].sh_size % sizeof(Elf_Rela); 553 shdr[i].sh_size % sizeof(Elf_Rela);
553 if (ko->ko_relatab[ra].size != 0) { 554 if (ko->ko_relatab[ra].size != 0) {
554 ko->ko_relatab[ra].nrela = 555 ko->ko_relatab[ra].nrela =
555 shdr[i].sh_size / sizeof(Elf_Rela); 556 shdr[i].sh_size / sizeof(Elf_Rela);
556 ko->ko_relatab[ra].sec = shdr[i].sh_info; 557 ko->ko_relatab[ra].sec = shdr[i].sh_info;
557 error = ko->ko_read(ko, 558 error = ko->ko_read(ko,
558 (void **)&ko->ko_relatab[ra].rela, 559 (void **)&ko->ko_relatab[ra].rela,
559 shdr[i].sh_size, 560 shdr[i].sh_size,
560 shdr[i].sh_offset, true); 561 shdr[i].sh_offset, true);
561 if (error != 0) { 562 if (error != 0) {
562 kobj_error(ko, "read failed %d", error); 563 kobj_error(ko, "read failed %d", error);
563 goto out; 564 goto out;
564 } 565 }
565 } 566 }
566 ra++; 567 ra++;
567 break; 568 break;
568 default: 569 default:
569 break; 570 break;
570 } 571 }
571 } 572 }
572 if (pb != ko->ko_nprogtab) { 573 if (pb != ko->ko_nprogtab) {
573 panic("%s:%d: %s: lost progbits", __func__, __LINE__, 574 panic("%s:%d: %s: lost progbits", __func__, __LINE__,
574 ko->ko_name); 575 ko->ko_name);
575 } 576 }
576 if (rl != ko->ko_nrel) { 577 if (rl != ko->ko_nrel) {
577 panic("%s:%d: %s: lost rel", __func__, __LINE__, 578 panic("%s:%d: %s: lost rel", __func__, __LINE__,
578 ko->ko_name); 579 ko->ko_name);
579 } 580 }
580 if (ra != ko->ko_nrela) { 581 if (ra != ko->ko_nrela) {
581 panic("%s:%d: %s: lost rela", __func__, __LINE__, 582 panic("%s:%d: %s: lost rela", __func__, __LINE__,
582 ko->ko_name); 583 ko->ko_name);
583 } 584 }
584 if (map_text_base != ko->ko_text_address + map_text_size) { 585 if (map_text_base != ko->ko_text_address + map_text_size) {
585 panic("%s:%d: %s: map_text_base 0x%lx != address %lx " 586 panic("%s:%d: %s: map_text_base 0x%lx != address %lx "
586 "+ map_text_size %ld (0x%lx)\n", 587 "+ map_text_size %ld (0x%lx)\n",
587 __func__, __LINE__, ko->ko_name, (long)map_text_base, 588 __func__, __LINE__, ko->ko_name, (long)map_text_base,
588 (long)ko->ko_text_address, (long)map_text_size, 589 (long)ko->ko_text_address, (long)map_text_size,
589 (long)ko->ko_text_address + map_text_size); 590 (long)ko->ko_text_address + map_text_size);
590 } 591 }
591 if (map_data_base != ko->ko_data_address + map_data_size) { 592 if (map_data_base != ko->ko_data_address + map_data_size) {
592 panic("%s:%d: %s: map_data_base 0x%lx != address %lx " 593 panic("%s:%d: %s: map_data_base 0x%lx != address %lx "
593 "+ map_data_size %ld (0x%lx)\n", 594 "+ map_data_size %ld (0x%lx)\n",
594 __func__, __LINE__, ko->ko_name, (long)map_data_base, 595 __func__, __LINE__, ko->ko_name, (long)map_data_base,
595 (long)ko->ko_data_address, (long)map_data_size, 596 (long)ko->ko_data_address, (long)map_data_size,
596 (long)ko->ko_data_address + map_data_size); 597 (long)ko->ko_data_address + map_data_size);
597 } 598 }
598 if (map_rodata_base != ko->ko_rodata_address + map_rodata_size) { 599 if (map_rodata_base != ko->ko_rodata_address + map_rodata_size) {
599 panic("%s:%d: %s: map_rodata_base 0x%lx != address %lx " 600 panic("%s:%d: %s: map_rodata_base 0x%lx != address %lx "
600 "+ map_rodata_size %ld (0x%lx)\n", 601 "+ map_rodata_size %ld (0x%lx)\n",
601 __func__, __LINE__, ko->ko_name, (long)map_rodata_base, 602 __func__, __LINE__, ko->ko_name, (long)map_rodata_base,
602 (long)ko->ko_rodata_address, (long)map_rodata_size, 603 (long)ko->ko_rodata_address, (long)map_rodata_size,
603 (long)ko->ko_rodata_address + map_rodata_size); 604 (long)ko->ko_rodata_address + map_rodata_size);
604 } 605 }
605 606
606 /* 607 /*
607 * Perform local relocations only. Relocations relating to global 608 * Perform local relocations only. Relocations relating to global
608 * symbols will be done by kobj_affix(). 609 * symbols will be done by kobj_affix().
609 */ 610 */
610 error = kobj_checksyms(ko, false); 611 error = kobj_checksyms(ko, false);
611 if (error) 612 if (error)
612 goto out; 613 goto out;
613 614
614 error = kobj_relocate(ko, true); 615 error = kobj_relocate(ko, true);
615 if (error) 616 if (error)
616 goto out; 617 goto out;
617out: 618out:
618 if (hdr != NULL) { 619 if (hdr != NULL) {
619 kobj_free(ko, hdr, sizeof(*hdr)); 620 kobj_free(ko, hdr, sizeof(*hdr));
620 } 621 }
621 kobj_close(ko); 622 kobj_close(ko);
622 if (error != 0) { 623 if (error != 0) {
623 kobj_unload(ko); 624 kobj_unload(ko);
624 } 625 }
625 626
626 return error; 627 return error;
627} 628}
628 629
629static void 630static void
630kobj_unload_notify(kobj_t ko, vaddr_t addr, size_t size, const char *note) 631kobj_unload_notify(kobj_t ko, vaddr_t addr, size_t size, const char *note)
631{ 632{
632 if (addr == 0) 633 if (addr == 0)
633 return; 634 return;
634 635
635 int error = kobj_machdep(ko, (void *)addr, size, false); 636 int error = kobj_machdep(ko, (void *)addr, size, false);
636 if (error) 637 if (error)
637 kobj_error(ko, "machine dependent deinit failed (%s) %d", 638 kobj_error(ko, "machine dependent deinit failed (%s) %d",
638 note, error); 639 note, error);
639} 640}
640 641
641#define KOBJ_SEGMENT_NOTIFY(ko, what) \ 642#define KOBJ_SEGMENT_NOTIFY(ko, what) \
642 kobj_unload_notify(ko, (ko)->ko_ ## what ## _address, \ 643 kobj_unload_notify(ko, (ko)->ko_ ## what ## _address, \
643 (ko)->ko_ ## what ## _size, # what); 644 (ko)->ko_ ## what ## _size, # what);
644 645
645#define KOBJ_SEGMENT_FREE(ko, what) \ 646#define KOBJ_SEGMENT_FREE(ko, what) \
646 do \ 647 do \
647 if ((ko)->ko_ ## what ## _address != 0) \ 648 if ((ko)->ko_ ## what ## _address != 0) \
648 uvm_km_free(module_map, (ko)->ko_ ## what ## _address, \ 649 uvm_km_free(module_map, (ko)->ko_ ## what ## _address, \
649 round_page((ko)->ko_ ## what ## _size), UVM_KMF_WIRED); \ 650 round_page((ko)->ko_ ## what ## _size), UVM_KMF_WIRED); \
650 while (/*CONSTCOND*/ 0) 651 while (/*CONSTCOND*/ 0)
651 652
652/* 653/*
653 * kobj_unload: 654 * kobj_unload:
654 * 655 *
655 * Unload an object previously loaded by kobj_load(). 656 * Unload an object previously loaded by kobj_load().
656 */ 657 */
657void 658void
658kobj_unload(kobj_t ko) 659kobj_unload(kobj_t ko)
659{ 660{
660 kobj_close(ko); 661 kobj_close(ko);
661 kobj_jettison(ko); 662 kobj_jettison(ko);
662 663
663 664
664 /* 665 /*
665 * Notify MD code that a module has been unloaded. 666 * Notify MD code that a module has been unloaded.
666 */ 667 */
667 if (ko->ko_loaded) { 668 if (ko->ko_loaded) {
668 KOBJ_SEGMENT_NOTIFY(ko, text); 669 KOBJ_SEGMENT_NOTIFY(ko, text);
669 KOBJ_SEGMENT_NOTIFY(ko, data); 670 KOBJ_SEGMENT_NOTIFY(ko, data);
670 KOBJ_SEGMENT_NOTIFY(ko, rodata); 671 KOBJ_SEGMENT_NOTIFY(ko, rodata);
671 } 672 }
672 673
673 KOBJ_SEGMENT_FREE(ko, text); 674 KOBJ_SEGMENT_FREE(ko, text);
674 KOBJ_SEGMENT_FREE(ko, data); 675 KOBJ_SEGMENT_FREE(ko, data);
675 KOBJ_SEGMENT_FREE(ko, rodata); 676 KOBJ_SEGMENT_FREE(ko, rodata);
676 677
677 if (ko->ko_ksyms == true) { 678 if (ko->ko_ksyms == true) {
678 ksyms_modunload(ko->ko_name); 679 ksyms_modunload(ko->ko_name);
679 } 680 }
680 if (ko->ko_symtab != NULL) { 681 if (ko->ko_symtab != NULL) {
681 kobj_free(ko, ko->ko_symtab, ko->ko_symcnt * sizeof(Elf_Sym)); 682 kobj_free(ko, ko->ko_symtab, ko->ko_symcnt * sizeof(Elf_Sym));
682 } 683 }
683 if (ko->ko_strtab != NULL) { 684 if (ko->ko_strtab != NULL) {
684 kobj_free(ko, ko->ko_strtab, ko->ko_strtabsz); 685 kobj_free(ko, ko->ko_strtab, ko->ko_strtabsz);
685 } 686 }
686 if (ko->ko_progtab != NULL) { 687 if (ko->ko_progtab != NULL) {
687 kobj_free(ko, ko->ko_progtab, ko->ko_nprogtab * 688 kobj_free(ko, ko->ko_progtab, ko->ko_nprogtab *
688 sizeof(*ko->ko_progtab)); 689 sizeof(*ko->ko_progtab));
689 ko->ko_progtab = NULL; 690 ko->ko_progtab = NULL;
690 } 691 }
691 if (ko->ko_shstrtab) { 692 if (ko->ko_shstrtab) {
692 kobj_free(ko, ko->ko_shstrtab, ko->ko_shstrtabsz); 693 kobj_free(ko, ko->ko_shstrtab, ko->ko_shstrtabsz);
693 ko->ko_shstrtab = NULL; 694 ko->ko_shstrtab = NULL;
694 } 695 }
695 696
696 kmem_free(ko, sizeof(*ko)); 697 kmem_free(ko, sizeof(*ko));
697} 698}
698 699
699/* 700/*
700 * kobj_stat: 701 * kobj_stat:
701 * 702 *
702 * Return size and load address of an object. 703 * Return size and load address of an object.
703 */ 704 */
704int 705int
705kobj_stat(kobj_t ko, vaddr_t *address, size_t *size) 706kobj_stat(kobj_t ko, vaddr_t *address, size_t *size)
706{ 707{
707 708
708 if (address != NULL) { 709 if (address != NULL) {
709 *address = ko->ko_text_address; 710 *address = ko->ko_text_address;
710 } 711 }
711 if (size != NULL) { 712 if (size != NULL) {
712 *size = ko->ko_text_size; 713 *size = ko->ko_text_size;
713 } 714 }
714 return 0; 715 return 0;
715} 716}
716 717
717/* 718/*
718 * kobj_affix: 719 * kobj_affix:
719 * 720 *
720 * Set an object's name and perform global relocs. May only be 721 * Set an object's name and perform global relocs. May only be
721 * called after the module and any requisite modules are loaded. 722 * called after the module and any requisite modules are loaded.
722 */ 723 */
723int 724int
724kobj_affix(kobj_t ko, const char *name) 725kobj_affix(kobj_t ko, const char *name)
725{ 726{
726 int error; 727 int error;
727 728
728 KASSERT(ko->ko_ksyms == false); 729 KASSERT(ko->ko_ksyms == false);
729 KASSERT(ko->ko_loaded == false); 730 KASSERT(ko->ko_loaded == false);
730 731
731 kobj_setname(ko, name); 732 kobj_setname(ko, name);
732 733
733 /* Cache addresses of undefined symbols. */ 734 /* Cache addresses of undefined symbols. */
734 error = kobj_checksyms(ko, true); 735 error = kobj_checksyms(ko, true);
735 if (error) 736 if (error)
736 goto out; 737 goto out;
737 738
738 /* Now do global relocations. */ 739 /* Now do global relocations. */
739 error = kobj_relocate(ko, false); 740 error = kobj_relocate(ko, false);
740 if (error) 741 if (error)
741 goto out; 742 goto out;
742 743
743 /* 744 /*
744 * Now that we know the name, register the symbol table. 745 * Now that we know the name, register the symbol table.
745 * Do after global relocations because ksyms will pack 746 * Do after global relocations because ksyms will pack
746 * the table. 747 * the table.
747 */ 748 */
748 ksyms_modload(ko->ko_name, ko->ko_symtab, 749 ksyms_modload(ko->ko_name, ko->ko_symtab,
749 ko->ko_symcnt * sizeof(Elf_Sym), ko->ko_strtab, ko->ko_strtabsz); 750 ko->ko_symcnt * sizeof(Elf_Sym), ko->ko_strtab, ko->ko_strtabsz);
750 ko->ko_ksyms = true; 751 ko->ko_ksyms = true;
751 752
752 /* Jettison unneeded memory post-link. */ 753 /* Jettison unneeded memory post-link. */
753 kobj_jettison(ko); 754 kobj_jettison(ko);
754 755
755 /* 756 /*
756 * Notify MD code that a module has been loaded. 757 * Notify MD code that a module has been loaded.
757 * 758 *
758 * Most architectures use this opportunity to flush their caches. 759 * Most architectures use this opportunity to flush their caches.
759 */ 760 */
760 if (ko->ko_text_address != 0) { 761 if (ko->ko_text_address != 0) {
761 error = kobj_machdep(ko, (void *)ko->ko_text_address, 762 error = kobj_machdep(ko, (void *)ko->ko_text_address,
762 ko->ko_text_size, true); 763 ko->ko_text_size, true);
763 if (error) { 764 if (error) {
764 kobj_error(ko, "machine dependent init failed (text)" 765 kobj_error(ko, "machine dependent init failed (text)"
765 " %d", error); 766 " %d", error);
766 goto out; 767 goto out;
767 } 768 }
768 } 769 }
769 770
770 if (ko->ko_data_address != 0) { 771 if (ko->ko_data_address != 0) {
771 error = kobj_machdep(ko, (void *)ko->ko_data_address, 772 error = kobj_machdep(ko, (void *)ko->ko_data_address,
772 ko->ko_data_size, true); 773 ko->ko_data_size, true);
773 if (error) { 774 if (error) {
774 kobj_error(ko, "machine dependent init failed (data)" 775 kobj_error(ko, "machine dependent init failed (data)"
775 " %d", error); 776 " %d", error);
776 goto out; 777 goto out;
777 } 778 }
778 } 779 }
779 780
780 if (ko->ko_rodata_address != 0) { 781 if (ko->ko_rodata_address != 0) {
781 error = kobj_machdep(ko, (void *)ko->ko_rodata_address, 782 error = kobj_machdep(ko, (void *)ko->ko_rodata_address,
782 ko->ko_rodata_size, true); 783 ko->ko_rodata_size, true);
783 if (error) { 784 if (error) {
784 kobj_error(ko, "machine dependent init failed (rodata)" 785 kobj_error(ko, "machine dependent init failed (rodata)"
785 " %d", error); 786 " %d", error);
786 goto out; 787 goto out;
787 } 788 }
788 } 789 }
789 790
790 ko->ko_loaded = true; 791 ko->ko_loaded = true;
791 792
792 /* Change the memory protections, when needed. */ 793 /* Change the memory protections, when needed. */
793 if (ko->ko_text_address != 0) { 794 if (ko->ko_text_address != 0) {
794 uvm_km_protect(module_map, ko->ko_text_address, 795 uvm_km_protect(module_map, ko->ko_text_address,
795 ko->ko_text_size, VM_PROT_READ|VM_PROT_EXECUTE); 796 ko->ko_text_size, VM_PROT_READ|VM_PROT_EXECUTE);
796 } 797 }
797 if (ko->ko_rodata_address != 0) { 798 if (ko->ko_rodata_address != 0) {
798 uvm_km_protect(module_map, ko->ko_rodata_address, 799 uvm_km_protect(module_map, ko->ko_rodata_address,
799 ko->ko_rodata_size, VM_PROT_READ); 800 ko->ko_rodata_size, VM_PROT_READ);
800 } 801 }
801 802
802 /* Success! */ 803 /* Success! */
803 error = 0; 804 error = 0;
804 805
805out: if (error) { 806out: if (error) {
806 /* If there was an error, destroy the whole object. */ 807 /* If there was an error, destroy the whole object. */
807 kobj_unload(ko); 808 kobj_unload(ko);
808 } 809 }
809 return error; 810 return error;
810} 811}
811 812
812/* 813/*
813 * kobj_find_section: 814 * kobj_find_section:
814 * 815 *
815 * Given a section name, search the loaded object and return 816 * Given a section name, search the loaded object and return
816 * virtual address if present and loaded. 817 * virtual address if present and loaded.
817 */ 818 */
818int 819int
819kobj_find_section(kobj_t ko, const char *name, void **addr, size_t *size) 820kobj_find_section(kobj_t ko, const char *name, void **addr, size_t *size)
820{ 821{
821 int i; 822 int i;
822 823
823 KASSERT(ko->ko_progtab != NULL); 824 KASSERT(ko->ko_progtab != NULL);
824 825
825 for (i = 0; i < ko->ko_nprogtab; i++) { 826 for (i = 0; i < ko->ko_nprogtab; i++) {
826 if (strcmp(ko->ko_progtab[i].name, name) == 0) { 827 if (strcmp(ko->ko_progtab[i].name, name) == 0) {
827 if (addr != NULL) { 828 if (addr != NULL) {
828 *addr = ko->ko_progtab[i].addr; 829 *addr = ko->ko_progtab[i].addr;
829 } 830 }
830 if (size != NULL) { 831 if (size != NULL) {
831 *size = ko->ko_progtab[i].size; 832 *size = ko->ko_progtab[i].size;
832 } 833 }
833 return 0; 834 return 0;
834 } 835 }
835 } 836 }
836 837
837 return ENOENT; 838 return ENOENT;
838} 839}
839 840
840/* 841/*
841 * kobj_jettison: 842 * kobj_jettison:
842 * 843 *
843 * Release object data not needed after performing relocations. 844 * Release object data not needed after performing relocations.
844 */ 845 */
845static void 846static void
846kobj_jettison(kobj_t ko) 847kobj_jettison(kobj_t ko)
847{ 848{
848 int i; 849 int i;
849 850
850 if (ko->ko_reltab != NULL) { 851 if (ko->ko_reltab != NULL) {
851 for (i = 0; i < ko->ko_nrel; i++) { 852 for (i = 0; i < ko->ko_nrel; i++) {
852 if (ko->ko_reltab[i].rel) { 853 if (ko->ko_reltab[i].rel) {
853 kobj_free(ko, ko->ko_reltab[i].rel, 854 kobj_free(ko, ko->ko_reltab[i].rel,
854 ko->ko_reltab[i].size); 855 ko->ko_reltab[i].size);
855 } 856 }
856 } 857 }
857 kobj_free(ko, ko->ko_reltab, ko->ko_nrel * 858 kobj_free(ko, ko->ko_reltab, ko->ko_nrel *
858 sizeof(*ko->ko_reltab)); 859 sizeof(*ko->ko_reltab));
859 ko->ko_reltab = NULL; 860 ko->ko_reltab = NULL;
860 ko->ko_nrel = 0; 861 ko->ko_nrel = 0;
861 } 862 }
862 if (ko->ko_relatab != NULL) { 863 if (ko->ko_relatab != NULL) {
863 for (i = 0; i < ko->ko_nrela; i++) { 864 for (i = 0; i < ko->ko_nrela; i++) {
864 if (ko->ko_relatab[i].rela) { 865 if (ko->ko_relatab[i].rela) {
865 kobj_free(ko, ko->ko_relatab[i].rela, 866 kobj_free(ko, ko->ko_relatab[i].rela,
866 ko->ko_relatab[i].size); 867 ko->ko_relatab[i].size);
867 } 868 }
868 } 869 }
869 kobj_free(ko, ko->ko_relatab, ko->ko_nrela * 870 kobj_free(ko, ko->ko_relatab, ko->ko_nrela *
870 sizeof(*ko->ko_relatab)); 871 sizeof(*ko->ko_relatab));
871 ko->ko_relatab = NULL; 872 ko->ko_relatab = NULL;
872 ko->ko_nrela = 0; 873 ko->ko_nrela = 0;
873 } 874 }
874 if (ko->ko_shdr != NULL) { 875 if (ko->ko_shdr != NULL) {
875 kobj_free(ko, ko->ko_shdr, ko->ko_shdrsz); 876 kobj_free(ko, ko->ko_shdr, ko->ko_shdrsz);
876 ko->ko_shdr = NULL; 877 ko->ko_shdr = NULL;
877 } 878 }
878} 879}
879 880
880/* 881/*
881 * kobj_sym_lookup: 882 * kobj_sym_lookup:
882 * 883 *
883 * Symbol lookup function to be used when the symbol index 884 * Symbol lookup function to be used when the symbol index
884 * is known (ie during relocation). 885 * is known (ie during relocation).
885 */ 886 */
886int 887int
887kobj_sym_lookup(kobj_t ko, uintptr_t symidx, Elf_Addr *val) 888kobj_sym_lookup(kobj_t ko, uintptr_t symidx, Elf_Addr *val)
888{ 889{
889 const Elf_Sym *sym; 890 const Elf_Sym *sym;
890 const char *symbol; 891 const char *symbol;
891 892
892 sym = ko->ko_symtab + symidx; 893 sym = ko->ko_symtab + symidx;
893 894
894 if (symidx == SHN_ABS || symidx == 0) { 895 if (symidx == SHN_ABS || symidx == 0) {
895 *val = (uintptr_t)sym->st_value; 896 *val = (uintptr_t)sym->st_value;
896 return 0; 897 return 0;
897 } else if (symidx >= ko->ko_symcnt) { 898 } else if (symidx >= ko->ko_symcnt) {
898 /* 899 /*
899 * Don't even try to lookup the symbol if the index is 900 * Don't even try to lookup the symbol if the index is
900 * bogus. 901 * bogus.
901 */ 902 */
902 kobj_error(ko, "symbol index %ju out of range", 903 kobj_error(ko, "symbol index %ju out of range",
903 (uintmax_t)symidx); 904 (uintmax_t)symidx);
904 return EINVAL; 905 return EINVAL;
905 } 906 }
906 907
907 /* Quick answer if there is a definition included. */ 908 /* Quick answer if there is a definition included. */
908 if (sym->st_shndx != SHN_UNDEF) { 909 if (sym->st_shndx != SHN_UNDEF) {
909 *val = (uintptr_t)sym->st_value; 910 *val = (uintptr_t)sym->st_value;
910 return 0; 911 return 0;
911 } 912 }
912 913
913 /* If we get here, then it is undefined and needs a lookup. */ 914 /* If we get here, then it is undefined and needs a lookup. */
914 switch (ELF_ST_BIND(sym->st_info)) { 915 switch (ELF_ST_BIND(sym->st_info)) {
915 case STB_LOCAL: 916 case STB_LOCAL:
916 /* Local, but undefined? huh? */ 917 /* Local, but undefined? huh? */
917 kobj_error(ko, "local symbol @%ju undefined", 918 kobj_error(ko, "local symbol @%ju undefined",
918 (uintmax_t)symidx); 919 (uintmax_t)symidx);
919 return EINVAL; 920 return EINVAL;
920 921
921 case STB_GLOBAL: 922 case STB_GLOBAL:
922 /* Relative to Data or Function name */ 923 /* Relative to Data or Function name */
923 symbol = ko->ko_strtab + sym->st_name; 924 symbol = ko->ko_strtab + sym->st_name;
924 925
925 /* Force a lookup failure if the symbol name is bogus. */ 926 /* Force a lookup failure if the symbol name is bogus. */
926 if (*symbol == 0) { 927 if (*symbol == 0) {
927 kobj_error(ko, "bad symbol @%ju name", 928 kobj_error(ko, "bad symbol @%ju name",
928 (uintmax_t)symidx); 929 (uintmax_t)symidx);
929 return EINVAL; 930 return EINVAL;
930 } 931 }
931 if (sym->st_value == 0) { 932 if (sym->st_value == 0) {
932 kobj_error(ko, "%s @%ju: bad value", symbol, 933 kobj_error(ko, "%s @%ju: bad value", symbol,
933 (uintmax_t)symidx); 934 (uintmax_t)symidx);
934 return EINVAL; 935 return EINVAL;
935 } 936 }
936 937
937 *val = (uintptr_t)sym->st_value; 938 *val = (uintptr_t)sym->st_value;
938 return 0; 939 return 0;
939 940
940 case STB_WEAK: 941 case STB_WEAK:
941 kobj_error(ko, "weak symbol @%ju not supported", 942 kobj_error(ko, "weak symbol @%ju not supported",
942 (uintmax_t)symidx); 943 (uintmax_t)symidx);
943 return EINVAL; 944 return EINVAL;
944 945
945 default: 946 default:
946 kobj_error(ko, "bad binding %#x for symbol @%ju", 947 kobj_error(ko, "bad binding %#x for symbol @%ju",
947 ELF_ST_BIND(sym->st_info), (uintmax_t)symidx); 948 ELF_ST_BIND(sym->st_info), (uintmax_t)symidx);
948 return EINVAL; 949 return EINVAL;
949 } 950 }
950} 951}
951 952
952/* 953/*
953 * kobj_findbase: 954 * kobj_findbase:
954 * 955 *
955 * Return base address of the given section. 956 * Return base address of the given section.
956 */ 957 */
957static uintptr_t 958static uintptr_t
958kobj_findbase(kobj_t ko, int sec) 959kobj_findbase(kobj_t ko, int sec)
959{ 960{
960 int i; 961 int i;
961 962
962 for (i = 0; i < ko->ko_nprogtab; i++) { 963 for (i = 0; i < ko->ko_nprogtab; i++) {
963 if (sec == ko->ko_progtab[i].sec) { 964 if (sec == ko->ko_progtab[i].sec) {
964 return (uintptr_t)ko->ko_progtab[i].addr; 965 return (uintptr_t)ko->ko_progtab[i].addr;
965 } 966 }
966 } 967 }
967 return 0; 968 return 0;
968} 969}
969 970
970/* 971/*
971 * kobj_checksyms: 972 * kobj_checksyms:
972 * 973 *
973 * Scan symbol table for duplicates or resolve references to 974 * Scan symbol table for duplicates or resolve references to
974 * external symbols. 975 * external symbols.
975 */ 976 */
976static int 977static int
977kobj_checksyms(kobj_t ko, bool undefined) 978kobj_checksyms(kobj_t ko, bool undefined)
978{ 979{
979 unsigned long rval; 980 unsigned long rval;
980 Elf_Sym *sym, *ksym, *ms; 981 Elf_Sym *sym, *ksym, *ms;
981 const char *name; 982 const char *name;
982 int error; 983 int error;
983 984
984 error = 0; 985 error = 0;
985 986
986 for (ms = (sym = ko->ko_symtab) + ko->ko_symcnt; sym < ms; sym++) { 987 for (ms = (sym = ko->ko_symtab) + ko->ko_symcnt; sym < ms; sym++) {
987 /* Check validity of the symbol. */ 988 /* Check validity of the symbol. */
988 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL || 989 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL ||
989 sym->st_name == 0) 990 sym->st_name == 0)
990 continue; 991 continue;
991 if (undefined != (sym->st_shndx == SHN_UNDEF)) { 992 if (undefined != (sym->st_shndx == SHN_UNDEF)) {
992 continue; 993 continue;
993 } 994 }
994 995
995 /* 996 /*
996 * Look it up. Don't need to lock, as it is known that 997 * Look it up. Don't need to lock, as it is known that
997 * the symbol tables aren't going to change (we hold 998 * the symbol tables aren't going to change (we hold
998 * module_lock). 999 * module_lock).
999 */ 1000 */
1000 name = ko->ko_strtab + sym->st_name; 1001 name = ko->ko_strtab + sym->st_name;
1001 if (ksyms_getval_unlocked(NULL, name, &ksym, &rval, 1002 if (ksyms_getval_unlocked(NULL, name, &ksym, &rval,
1002 KSYMS_EXTERN) != 0) { 1003 KSYMS_EXTERN) != 0) {
1003 if (undefined) { 1004 if (undefined) {
1004 kobj_error(ko, "symbol `%s' not found", 1005 kobj_error(ko, "symbol `%s' not found",
1005 name); 1006 name);
1006 error = ENOEXEC; 1007 error = ENOEXEC;
1007 } 1008 }
1008 continue; 1009 continue;
1009 } 1010 }
1010 1011
1011 /* Save values of undefined globals. */ 1012 /* Save values of undefined globals. */
1012 if (undefined) { 1013 if (undefined) {
1013 if (ksym->st_shndx == SHN_ABS) { 1014 if (ksym->st_shndx == SHN_ABS) {
1014 sym->st_shndx = SHN_ABS; 1015 sym->st_shndx = SHN_ABS;
1015 } 1016 }
1016 sym->st_value = (Elf_Addr)rval; 1017 sym->st_value = (Elf_Addr)rval;
1017 continue; 1018 continue;
1018 } 1019 }
1019 1020
1020 /* Check (and complain) about differing values. */ 1021 /* Check (and complain) about differing values. */
1021 if (sym->st_value == rval) { 1022 if (sym->st_value == rval) {
1022 continue; 1023 continue;
1023 } 1024 }
1024 if (strcmp(name, "_bss_start") == 0 || 1025 if (strcmp(name, "_bss_start") == 0 ||
1025 strcmp(name, "__bss_start") == 0 || 1026 strcmp(name, "__bss_start") == 0 ||
1026 strcmp(name, "_bss_end__") == 0 || 1027 strcmp(name, "_bss_end__") == 0 ||
1027 strcmp(name, "__bss_end__") == 0 || 1028 strcmp(name, "__bss_end__") == 0 ||
1028 strcmp(name, "_edata") == 0 || 1029 strcmp(name, "_edata") == 0 ||
1029 strcmp(name, "_end") == 0 || 1030 strcmp(name, "_end") == 0 ||
1030 strcmp(name, "__end") == 0 || 1031 strcmp(name, "__end") == 0 ||
1031 strcmp(name, "__end__") == 0 || 1032 strcmp(name, "__end__") == 0 ||
1032 strncmp(name, "__start_link_set_", 17) == 0 || 1033 strncmp(name, "__start_link_set_", 17) == 0 ||
1033 strncmp(name, "__stop_link_set_", 16) == 0) { 1034 strncmp(name, "__stop_link_set_", 16) == 0) {
1034 continue; 1035 continue;
1035 } 1036 }
1036 kobj_error(ko, "global symbol `%s' redefined", 1037 kobj_error(ko, "global symbol `%s' redefined",
1037 name); 1038 name);
1038 error = ENOEXEC; 1039 error = ENOEXEC;
1039 } 1040 }
1040 1041
1041 return error; 1042 return error;
1042} 1043}
1043 1044
1044/* 1045/*
1045 * kobj_relocate: 1046 * kobj_relocate:
1046 * 1047 *
1047 * Resolve relocations for the loaded object. 1048 * Resolve relocations for the loaded object.
1048 */ 1049 */
1049static int 1050static int
1050kobj_relocate(kobj_t ko, bool local) 1051kobj_relocate(kobj_t ko, bool local)
1051{ 1052{
1052 const Elf_Rel *rellim; 1053 const Elf_Rel *rellim;
1053 const Elf_Rel *rel; 1054 const Elf_Rel *rel;
1054 const Elf_Rela *relalim; 1055 const Elf_Rela *relalim;
1055 const Elf_Rela *rela; 1056 const Elf_Rela *rela;
1056 const Elf_Sym *sym; 1057 const Elf_Sym *sym;
1057 uintptr_t base; 1058 uintptr_t base;
1058 int i, error; 1059 int i, error;
1059 uintptr_t symidx; 1060 uintptr_t symidx;
1060 1061
1061 /* 1062 /*
1062 * Perform relocations without addend if there are any. 1063 * Perform relocations without addend if there are any.
1063 */ 1064 */
1064 for (i = 0; i < ko->ko_nrel; i++) { 1065 for (i = 0; i < ko->ko_nrel; i++) {
1065 rel = ko->ko_reltab[i].rel; 1066 rel = ko->ko_reltab[i].rel;
1066 if (rel == NULL) { 1067 if (rel == NULL) {
1067 continue; 1068 continue;
1068 } 1069 }
1069 rellim = rel + ko->ko_reltab[i].nrel; 1070 rellim = rel + ko->ko_reltab[i].nrel;
1070 base = kobj_findbase(ko, ko->ko_reltab[i].sec); 1071 base = kobj_findbase(ko, ko->ko_reltab[i].sec);
1071 if (base == 0) { 1072 if (base == 0) {
1072 panic("%s:%d: %s: lost base for e_reltab[%d] sec %d", 1073 panic("%s:%d: %s: lost base for e_reltab[%d] sec %d",
1073 __func__, __LINE__, ko->ko_name, i, 1074 __func__, __LINE__, ko->ko_name, i,
1074 ko->ko_reltab[i].sec); 1075 ko->ko_reltab[i].sec);
1075 } 1076 }
1076 for (; rel < rellim; rel++) { 1077 for (; rel < rellim; rel++) {
1077 symidx = ELF_R_SYM(rel->r_info); 1078 symidx = ELF_R_SYM(rel->r_info);
1078 if (symidx >= ko->ko_symcnt) { 1079 if (symidx >= ko->ko_symcnt) {
1079 continue; 1080 continue;
1080 } 1081 }