1 /*-
2 * Copyright (c) 1998-2000 Doug Rabson
3 * Copyright (c) 2004 Peter Wemm
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include "opt_ddb.h"
32 #include "opt_mac.h"
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/lock.h>
38 #include <sys/mac.h>
39 #include <sys/malloc.h>
40 #include <sys/mutex.h>
41 #include <sys/proc.h>
42 #include <sys/namei.h>
43 #include <sys/fcntl.h>
44 #include <sys/vnode.h>
45 #include <sys/linker.h>
46
47 #include <machine/elf.h>
48
49 #include <vm/vm.h>
50 #include <vm/vm_param.h>
51 #include <vm/vm_object.h>
52 #include <vm/vm_kern.h>
53 #include <vm/vm_extern.h>
54 #include <vm/pmap.h>
55 #include <vm/vm_map.h>
56
57 #include <sys/link_elf.h>
58
59 #include "linker_if.h"
60
61 typedef struct {
62 void *addr;
63 Elf_Off size;
64 int flags;
65 int sec; /* Original section */
66 char *name;
67 } Elf_progent;
68
69 typedef struct {
70 Elf_Rel *rel;
71 int nrel;
72 int sec;
73 } Elf_relent;
74
75 typedef struct {
76 Elf_Rela *rela;
77 int nrela;
78 int sec;
79 } Elf_relaent;
80
81
82 typedef struct elf_file {
83 struct linker_file lf; /* Common fields */
84
85 int preloaded;
86 caddr_t address; /* Relocation address */
87 vm_object_t object; /* VM object to hold file pages */
88 Elf_Shdr *e_shdr;
89
90 Elf_progent *progtab;
91 int nprogtab;
92
93 Elf_relaent *relatab;
94 int nrelatab;
95
96 Elf_relent *reltab;
97 int nreltab;
98
99 Elf_Sym *ddbsymtab; /* The symbol table we are using */
100 long ddbsymcnt; /* Number of symbols */
101 caddr_t ddbstrtab; /* String table */
102 long ddbstrcnt; /* number of bytes in string table */
103
104 caddr_t shstrtab; /* Section name string table */
105 long shstrcnt; /* number of bytes in string table */
106
107 } *elf_file_t;
108
109 static int link_elf_link_preload(linker_class_t cls,
110 const char *, linker_file_t *);
111 static int link_elf_link_preload_finish(linker_file_t);
112 static int link_elf_load_file(linker_class_t, const char *, linker_file_t *);
113 static int link_elf_lookup_symbol(linker_file_t, const char *,
114 c_linker_sym_t *);
115 static int link_elf_symbol_values(linker_file_t, c_linker_sym_t,
116 linker_symval_t *);
117 static int link_elf_search_symbol(linker_file_t, caddr_t value,
118 c_linker_sym_t *sym, long *diffp);
119
120 static void link_elf_unload_file(linker_file_t);
121 static int link_elf_lookup_set(linker_file_t, const char *,
122 void ***, void ***, int *);
123 static int link_elf_each_function_name(linker_file_t,
124 int (*)(const char *, void *), void *);
125 static void link_elf_reloc_local(linker_file_t);
126
127 static Elf_Addr elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps);
128
129 static kobj_method_t link_elf_methods[] = {
130 KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
131 KOBJMETHOD(linker_symbol_values, link_elf_symbol_values),
132 KOBJMETHOD(linker_search_symbol, link_elf_search_symbol),
133 KOBJMETHOD(linker_unload, link_elf_unload_file),
134 KOBJMETHOD(linker_load_file, link_elf_load_file),
135 KOBJMETHOD(linker_link_preload, link_elf_link_preload),
136 KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish),
137 KOBJMETHOD(linker_lookup_set, link_elf_lookup_set),
138 KOBJMETHOD(linker_each_function_name, link_elf_each_function_name),
139 { 0, 0 }
140 };
141
142 static struct linker_class link_elf_class = {
143 #if ELF_TARG_CLASS == ELFCLASS32
144 "elf32_obj",
145 #else
146 "elf64_obj",
147 #endif
148 link_elf_methods, sizeof(struct elf_file)
149 };
150
151 static int relocate_file(elf_file_t ef);
152
153 static void
154 link_elf_error(const char *filename, const char *s)
155 {
156 if (filename == NULL)
157 printf("kldload: %s\n", s);
158 else
159 printf("kldload: %s: %s\n", filename, s);
160 }
161
162 static void
163 link_elf_init(void *arg)
164 {
165
166 linker_add_class(&link_elf_class);
167 }
168
169 SYSINIT(link_elf_obj, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0);
170
171 static int
172 link_elf_link_preload(linker_class_t cls, const char *filename,
173 linker_file_t *result)
174 {
175 Elf_Ehdr *hdr;
176 Elf_Shdr *shdr;
177 Elf_Sym *es;
178 void *modptr, *baseptr, *sizeptr;
179 char *type;
180 elf_file_t ef;
181 linker_file_t lf;
182 Elf_Addr off;
183 int error, i, j, pb, ra, rl, shstrindex, symstrindex, symtabindex;
184
185 /* Look to see if we have the file preloaded */
186 modptr = preload_search_by_name(filename);
187 if (modptr == NULL)
188 return ENOENT;
189
190 type = (char *)preload_search_info(modptr, MODINFO_TYPE);
191 baseptr = preload_search_info(modptr, MODINFO_ADDR);
192 sizeptr = preload_search_info(modptr, MODINFO_SIZE);
193 hdr = (Elf_Ehdr *)preload_search_info(modptr, MODINFO_METADATA |
194 MODINFOMD_ELFHDR);
195 shdr = (Elf_Shdr *)preload_search_info(modptr, MODINFO_METADATA |
196 MODINFOMD_SHDR);
197 if (type == NULL || (strcmp(type, "elf" __XSTRING(__ELF_WORD_SIZE)
198 " obj module") != 0 &&
199 strcmp(type, "elf obj module") != 0)) {
200 return (EFTYPE);
201 }
202 if (baseptr == NULL || sizeptr == NULL || hdr == NULL ||
203 shdr == NULL)
204 return (EINVAL);
205
206 lf = linker_make_file(filename, &link_elf_class);
207 if (lf == NULL)
208 return (ENOMEM);
209
210 ef = (elf_file_t)lf;
211 ef->preloaded = 1;
212 ef->address = *(caddr_t *)baseptr;
213 lf->address = *(caddr_t *)baseptr;
214 lf->size = *(size_t *)sizeptr;
215
216 if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
217 hdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
218 hdr->e_ident[EI_VERSION] != EV_CURRENT ||
219 hdr->e_version != EV_CURRENT ||
220 hdr->e_type != ET_REL ||
221 hdr->e_machine != ELF_TARG_MACH) {
222 error = EFTYPE;
223 goto out;
224 }
225 ef->e_shdr = shdr;
226
227 /* Scan the section header for information and table sizing. */
228 symtabindex = -1;
229 symstrindex = -1;
230 for (i = 0; i < hdr->e_shnum; i++) {
231 switch (shdr[i].sh_type) {
232 case SHT_PROGBITS:
233 case SHT_NOBITS:
234 ef->nprogtab++;
235 break;
236 case SHT_SYMTAB:
237 symtabindex = i;
238 symstrindex = shdr[i].sh_link;
239 break;
240 case SHT_REL:
241 ef->nreltab++;
242 break;
243 case SHT_RELA:
244 ef->nrelatab++;
245 break;
246 }
247 }
248
249 shstrindex = hdr->e_shstrndx;
250 if (ef->nprogtab == 0 || symstrindex < 0 ||
251 symstrindex >= hdr->e_shnum ||
252 shdr[symstrindex].sh_type != SHT_STRTAB || shstrindex == 0 ||
253 shstrindex >= hdr->e_shnum ||
254 shdr[shstrindex].sh_type != SHT_STRTAB) {
255 printf("%s: bad/missing section headers\n", filename);
256 error = ENOEXEC;
257 goto out;
258 }
259
260 /* Allocate space for tracking the load chunks */
261 if (ef->nprogtab != 0)
262 ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab),
263 M_LINKER, M_WAITOK | M_ZERO);
264 if (ef->nreltab != 0)
265 ef->reltab = malloc(ef->nreltab * sizeof(*ef->reltab),
266 M_LINKER, M_WAITOK | M_ZERO);
267 if (ef->nrelatab != 0)
268 ef->relatab = malloc(ef->nrelatab * sizeof(*ef->relatab),
269 M_LINKER, M_WAITOK | M_ZERO);
270 if ((ef->nprogtab != 0 && ef->progtab == NULL) ||
271 (ef->nreltab != 0 && ef->reltab == NULL) ||
272 (ef->nrelatab != 0 && ef->relatab == NULL)) {
273 error = ENOMEM;
274 goto out;
275 }
276
277 /* XXX, relocate the sh_addr fields saved by the loader. */
278 off = 0;
279 for (i = 0; i < hdr->e_shnum; i++) {
280 if (shdr[i].sh_addr != 0 && (off == 0 || shdr[i].sh_addr < off))
281 off = shdr[i].sh_addr;
282 }
283 for (i = 0; i < hdr->e_shnum; i++) {
284 if (shdr[i].sh_addr != 0)
285 shdr[i].sh_addr = shdr[i].sh_addr - off +
286 (Elf_Addr)ef->address;
287 }
288
289 ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym);
290 ef->ddbsymtab = (Elf_Sym *)shdr[symtabindex].sh_addr;
291 ef->ddbstrcnt = shdr[symstrindex].sh_size;
292 ef->ddbstrtab = (char *)shdr[symstrindex].sh_addr;
293 ef->shstrcnt = shdr[shstrindex].sh_size;
294 ef->shstrtab = (char *)shdr[shstrindex].sh_addr;
295
296 /* Now fill out progtab and the relocation tables. */
297 pb = 0;
298 rl = 0;
299 ra = 0;
300 for (i = 0; i < hdr->e_shnum; i++) {
301 switch (shdr[i].sh_type) {
302 case SHT_PROGBITS:
303 case SHT_NOBITS:
304 ef->progtab[pb].addr = (void *)shdr[i].sh_addr;
305 if (shdr[i].sh_type == SHT_PROGBITS)
306 ef->progtab[pb].name = "<<PROGBITS>>";
307 else
308 ef->progtab[pb].name = "<<NOBITS>>";
309 ef->progtab[pb].size = shdr[i].sh_size;
310 ef->progtab[pb].sec = i;
311 if (ef->shstrtab && shdr[i].sh_name != 0)
312 ef->progtab[pb].name =
313 ef->shstrtab + shdr[i].sh_name;
314
315 /* Update all symbol values with the offset. */
316 for (j = 0; j < ef->ddbsymcnt; j++) {
317 es = &ef->ddbsymtab[j];
318 if (es->st_shndx != i)
319 continue;
320 es->st_value += (Elf_Addr)ef->progtab[pb].addr;
321 }
322 pb++;
323 break;
324 case SHT_REL:
325 ef->reltab[rl].rel = (Elf_Rel *)shdr[i].sh_addr;
326 ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel);
327 ef->reltab[rl].sec = shdr[i].sh_info;
328 rl++;
329 break;
330 case SHT_RELA:
331 ef->relatab[ra].rela = (Elf_Rela *)shdr[i].sh_addr;
332 ef->relatab[ra].nrela =
333 shdr[i].sh_size / sizeof(Elf_Rela);
334 ef->relatab[ra].sec = shdr[i].sh_info;
335 ra++;
336 break;
337 }
338 }
339 if (pb != ef->nprogtab)
340 panic("lost progbits");
341 if (rl != ef->nreltab)
342 panic("lost reltab");
343 if (ra != ef->nrelatab)
344 panic("lost relatab");
345
346 /* Local intra-module relocations */
347 link_elf_reloc_local(lf);
348
349 *result = lf;
350 return (0);
351
352 out:
353 /* preload not done this way */
354 linker_file_unload(lf, LINKER_UNLOAD_FORCE);
355 return (error);
356 }
357
358 static int
359 link_elf_link_preload_finish(linker_file_t lf)
360 {
361 elf_file_t ef;
362 int error;
363
364 ef = (elf_file_t)lf;
365 error = relocate_file(ef);
366 if (error)
367 return error;
368
369 /* Notify MD code that a module is being loaded. */
370 error = elf_cpu_load_file(lf);
371 if (error)
372 return (error);
373
374 return (0);
375 }
376
377 static int
378 link_elf_load_file(linker_class_t cls, const char *filename,
379 linker_file_t *result)
380 {
381 struct nameidata nd;
382 struct thread *td = curthread; /* XXX */
383 Elf_Ehdr *hdr;
384 Elf_Shdr *shdr;
385 Elf_Sym *es;
386 int nbytes, i, j;
387 vm_offset_t mapbase;
388 size_t mapsize;
389 int error = 0;
390 int resid, flags;
391 elf_file_t ef;
392 linker_file_t lf;
393 int symtabindex;
394 int symstrindex;
395 int shstrindex;
396 int nsym;
397 int pb, rl, ra;
398 int alignmask;
399
400 GIANT_REQUIRED;
401
402 shdr = NULL;
403 lf = NULL;
404 mapsize = 0;
405 hdr = NULL;
406
407 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td);
408 flags = FREAD;
409 error = vn_open(&nd, &flags, 0, -1);
410 if (error)
411 return error;
412 NDFREE(&nd, NDF_ONLY_PNBUF);
413 if (nd.ni_vp->v_type != VREG) {
414 error = ENOEXEC;
415 goto out;
416 }
417 #ifdef MAC
418 error = mac_check_kld_load(td->td_ucred, nd.ni_vp);
419 if (error) {
420 goto out;
421 }
422 #endif
423
424 /* Read the elf header from the file. */
425 hdr = malloc(sizeof(*hdr), M_LINKER, M_WAITOK);
426 if (hdr == NULL) {
427 error = ENOMEM;
428 goto out;
429 }
430 error = vn_rdwr(UIO_READ, nd.ni_vp, (void *)hdr, sizeof(*hdr), 0,
431 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
432 &resid, td);
433 if (error)
434 goto out;
435 if (resid != 0){
436 error = ENOEXEC;
437 goto out;
438 }
439
440 if (!IS_ELF(*hdr)) {
441 error = ENOEXEC;
442 goto out;
443 }
444
445 if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS
446 || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
447 link_elf_error(filename, "Unsupported file layout");
448 error = ENOEXEC;
449 goto out;
450 }
451 if (hdr->e_ident[EI_VERSION] != EV_CURRENT
452 || hdr->e_version != EV_CURRENT) {
453 link_elf_error(filename, "Unsupported file version");
454 error = ENOEXEC;
455 goto out;
456 }
457 if (hdr->e_type != ET_REL) {
458 link_elf_error(filename, "Unsupported file type");
459 error = ENOEXEC;
460 goto out;
461 }
462 if (hdr->e_machine != ELF_TARG_MACH) {
463 link_elf_error(filename, "Unsupported machine");
464 error = ENOEXEC;
465 goto out;
466 }
467
468 lf = linker_make_file(filename, &link_elf_class);
469 if (!lf) {
470 error = ENOMEM;
471 goto out;
472 }
473 ef = (elf_file_t) lf;
474 ef->nprogtab = 0;
475 ef->e_shdr = 0;
476 ef->nreltab = 0;
477 ef->nrelatab = 0;
478
479 /* Allocate and read in the section header */
480 nbytes = hdr->e_shnum * hdr->e_shentsize;
481 if (nbytes == 0 || hdr->e_shoff == 0 ||
482 hdr->e_shentsize != sizeof(Elf_Shdr)) {
483 error = ENOEXEC;
484 goto out;
485 }
486 shdr = malloc(nbytes, M_LINKER, M_WAITOK);
487 if (shdr == NULL) {
488 error = ENOMEM;
489 goto out;
490 }
491 ef->e_shdr = shdr;
492 error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shdr, nbytes, hdr->e_shoff,
493 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td);
494 if (error)
495 goto out;
496 if (resid) {
497 error = ENOEXEC;
498 goto out;
499 }
500
501 /* Scan the section header for information and table sizing. */
502 nsym = 0;
503 symtabindex = -1;
504 symstrindex = -1;
505 for (i = 0; i < hdr->e_shnum; i++) {
506 switch (shdr[i].sh_type) {
507 case SHT_PROGBITS:
508 case SHT_NOBITS:
509 ef->nprogtab++;
510 break;
511 case SHT_SYMTAB:
512 nsym++;
513 symtabindex = i;
514 symstrindex = shdr[i].sh_link;
515 break;
516 case SHT_REL:
517 ef->nreltab++;
518 break;
519 case SHT_RELA:
520 ef->nrelatab++;
521 break;
522 case SHT_STRTAB:
523 break;
524 }
525 }
526 if (ef->nprogtab == 0) {
527 link_elf_error(filename, "file has no contents");
528 error = ENOEXEC;
529 goto out;
530 }
531 if (nsym != 1) {
532 /* Only allow one symbol table for now */
533 link_elf_error(filename, "file has no valid symbol table");
534 error = ENOEXEC;
535 goto out;
536 }
537 if (symstrindex < 0 || symstrindex > hdr->e_shnum ||
538 shdr[symstrindex].sh_type != SHT_STRTAB) {
539 link_elf_error(filename, "file has invalid symbol strings");
540 error = ENOEXEC;
541 goto out;
542 }
543
544 /* Allocate space for tracking the load chunks */
545 if (ef->nprogtab != 0)
546 ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab),
547 M_LINKER, M_WAITOK | M_ZERO);
548 if (ef->nreltab != 0)
549 ef->reltab = malloc(ef->nreltab * sizeof(*ef->reltab),
550 M_LINKER, M_WAITOK | M_ZERO);
551 if (ef->nrelatab != 0)
552 ef->relatab = malloc(ef->nrelatab * sizeof(*ef->relatab),
553 M_LINKER, M_WAITOK | M_ZERO);
554 if ((ef->nprogtab != 0 && ef->progtab == NULL) ||
555 (ef->nreltab != 0 && ef->reltab == NULL) ||
556 (ef->nrelatab != 0 && ef->relatab == NULL)) {
557 error = ENOMEM;
558 goto out;
559 }
560
561 if (symtabindex == -1)
562 panic("lost symbol table index");
563 /* Allocate space for and load the symbol table */
564 ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym);
565 ef->ddbsymtab = malloc(shdr[symtabindex].sh_size, M_LINKER, M_WAITOK);
566 if (ef->ddbsymtab == NULL) {
567 error = ENOMEM;
568 goto out;
569 }
570 error = vn_rdwr(UIO_READ, nd.ni_vp, (void *)ef->ddbsymtab,
571 shdr[symtabindex].sh_size, shdr[symtabindex].sh_offset,
572 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
573 &resid, td);
574 if (error)
575 goto out;
576 if (resid != 0){
577 error = EINVAL;
578 goto out;
579 }
580
581 if (symstrindex == -1)
582 panic("lost symbol string index");
583 /* Allocate space for and load the symbol strings */
584 ef->ddbstrcnt = shdr[symstrindex].sh_size;
585 ef->ddbstrtab = malloc(shdr[symstrindex].sh_size, M_LINKER, M_WAITOK);
586 if (ef->ddbstrtab == NULL) {
587 error = ENOMEM;
588 goto out;
589 }
590 error = vn_rdwr(UIO_READ, nd.ni_vp, ef->ddbstrtab,
591 shdr[symstrindex].sh_size, shdr[symstrindex].sh_offset,
592 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
593 &resid, td);
594 if (error)
595 goto out;
596 if (resid != 0){
597 error = EINVAL;
598 goto out;
599 }
600
601 /* Do we have a string table for the section names? */
602 shstrindex = -1;
603 if (hdr->e_shstrndx != 0 &&
604 shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) {
605 shstrindex = hdr->e_shstrndx;
606 ef->shstrcnt = shdr[shstrindex].sh_size;
607 ef->shstrtab = malloc(shdr[shstrindex].sh_size, M_LINKER,
608 M_WAITOK);
609 if (ef->shstrtab == NULL) {
610 error = ENOMEM;
611 goto out;
612 }
613 error = vn_rdwr(UIO_READ, nd.ni_vp, ef->shstrtab,
614 shdr[shstrindex].sh_size, shdr[shstrindex].sh_offset,
615 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
616 &resid, td);
617 if (error)
618 goto out;
619 if (resid != 0){
620 error = EINVAL;
621 goto out;
622 }
623 }
624
625 /* Size up code/data(progbits) and bss(nobits). */
626 alignmask = 0;
627 for (i = 0; i < hdr->e_shnum; i++) {
628 switch (shdr[i].sh_type) {
629 case SHT_PROGBITS:
630 case SHT_NOBITS:
631 alignmask = shdr[i].sh_addralign - 1;
632 mapsize += alignmask;
633 mapsize &= ~alignmask;
634 mapsize += shdr[i].sh_size;
635 break;
636 }
637 }
638
639 /*
640 * We know how much space we need for the text/data/bss/etc.
641 * This stuff needs to be in a single chunk so that profiling etc
642 * can get the bounds and gdb can associate offsets with modules
643 */
644 ef->object = vm_object_allocate(OBJT_DEFAULT,
645 round_page(mapsize) >> PAGE_SHIFT);
646 if (ef->object == NULL) {
647 error = ENOMEM;
648 goto out;
649 }
650 ef->address = (caddr_t) vm_map_min(kernel_map);
651 error = vm_map_find(kernel_map, ef->object, 0, &mapbase,
652 round_page(mapsize), TRUE, VM_PROT_ALL, VM_PROT_ALL, FALSE);
653 if (error) {
654 vm_object_deallocate(ef->object);
655 ef->object = 0;
656 goto out;
657 }
658
659 /* Wire the pages */
660 error = vm_map_wire(kernel_map, mapbase,
661 mapbase + round_page(mapsize),
662 VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES);
663 if (error != KERN_SUCCESS) {
664 error = ENOMEM;
665 goto out;
666 }
667
668 /* Inform the kld system about the situation */
669 lf->address = ef->address = (caddr_t)mapbase;
670 lf->size = mapsize;
671
672 /*
673 * Now load code/data(progbits), zero bss(nobits), allocate space for
674 * and load relocs
675 */
676 pb = 0;
677 rl = 0;
678 ra = 0;
679 alignmask = 0;
680 for (i = 0; i < hdr->e_shnum; i++) {
681 switch (shdr[i].sh_type) {
682 case SHT_PROGBITS:
683 case SHT_NOBITS:
684 alignmask = shdr[i].sh_addralign - 1;
685 mapbase += alignmask;
686 mapbase &= ~alignmask;
687 ef->progtab[pb].addr = (void *)(uintptr_t)mapbase;
688 if (shdr[i].sh_type == SHT_PROGBITS) {
689 ef->progtab[pb].name = "<<PROGBITS>>";
690 error = vn_rdwr(UIO_READ, nd.ni_vp,
691 ef->progtab[pb].addr,
692 shdr[i].sh_size, shdr[i].sh_offset,
693 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
694 NOCRED, &resid, td);
695 if (error)
696 goto out;
697 if (resid != 0){
698 error = EINVAL;
699 goto out;
700 }
701 } else {
702 ef->progtab[pb].name = "<<NOBITS>>";
703 bzero(ef->progtab[pb].addr, shdr[i].sh_size);
704 }
705 ef->progtab[pb].size = shdr[i].sh_size;
706 ef->progtab[pb].sec = i;
707 if (ef->shstrtab && shdr[i].sh_name != 0)
708 ef->progtab[pb].name =
709 ef->shstrtab + shdr[i].sh_name;
710
711 /* Update all symbol values with the offset. */
712 for (j = 0; j < ef->ddbsymcnt; j++) {
713 es = &ef->ddbsymtab[j];
714 if (es->st_shndx != i)
715 continue;
716 es->st_value += (Elf_Addr)ef->progtab[pb].addr;
717 }
718 mapbase += shdr[i].sh_size;
719 pb++;
720 break;
721 case SHT_REL:
722 ef->reltab[rl].rel = malloc(shdr[i].sh_size, M_LINKER,
723 M_WAITOK);
724 ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel);
725 ef->reltab[rl].sec = shdr[i].sh_info;
726 error = vn_rdwr(UIO_READ, nd.ni_vp,
727 (void *)ef->reltab[rl].rel,
728 shdr[i].sh_size, shdr[i].sh_offset,
729 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
730 &resid, td);
731 if (error)
732 goto out;
733 if (resid != 0){
734 error = EINVAL;
735 goto out;
736 }
737 rl++;
738 break;
739 case SHT_RELA:
740 ef->relatab[ra].rela = malloc(shdr[i].sh_size, M_LINKER,
741 M_WAITOK);
742 ef->relatab[ra].nrela =
743 shdr[i].sh_size / sizeof(Elf_Rela);
744 ef->relatab[ra].sec = shdr[i].sh_info;
745 error = vn_rdwr(UIO_READ, nd.ni_vp,
746 (void *)ef->relatab[ra].rela,
747 shdr[i].sh_size, shdr[i].sh_offset,
748 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
749 &resid, td);
750 if (error)
751 goto out;
752 if (resid != 0){
753 error = EINVAL;
754 goto out;
755 }
756 ra++;
757 break;
758 }
759 }
760 if (pb != ef->nprogtab)
761 panic("lost progbits");
762 if (rl != ef->nreltab)
763 panic("lost reltab");
764 if (ra != ef->nrelatab)
765 panic("lost relatab");
766 if (mapbase != (vm_offset_t)ef->address + mapsize)
767 panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n",
768 mapbase, ef->address, mapsize,
769 (vm_offset_t)ef->address + mapsize);
770
771 /* Local intra-module relocations */
772 link_elf_reloc_local(lf);
773
774 /* Pull in dependencies */
775 error = linker_load_dependencies(lf);
776 if (error)
777 goto out;
778
779 /* External relocations */
780 error = relocate_file(ef);
781 if (error)
782 goto out;
783
784 /* Notify MD code that a module is being loaded. */
785 error = elf_cpu_load_file(lf);
786 if (error)
787 goto out;
788
789 *result = lf;
790
791 out:
792 if (error && lf)
793 linker_file_unload(lf, LINKER_UNLOAD_FORCE);
794 if (hdr)
795 free(hdr, M_LINKER);
796 VOP_UNLOCK(nd.ni_vp, 0, td);
797 vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
798
799 return error;
800 }
801
802 static void
803 link_elf_unload_file(linker_file_t file)
804 {
805 elf_file_t ef = (elf_file_t) file;
806 int i;
807
808 /* Notify MD code that a module is being unloaded. */
809 elf_cpu_unload_file(file);
810
811 if (ef->preloaded) {
812 if (ef->reltab)
813 free(ef->reltab, M_LINKER);
814 if (ef->relatab)
815 free(ef->relatab, M_LINKER);
816 if (ef->progtab)
817 free(ef->progtab, M_LINKER);
818 if (file->filename != NULL)
819 preload_delete_name(file->filename);
820 /* XXX reclaim module memory? */
821 return;
822 }
823
824 for (i = 0; i < ef->nreltab; i++)
825 if (ef->reltab[i].rel)
826 free(ef->reltab[i].rel, M_LINKER);
827 for (i = 0; i < ef->nrelatab; i++)
828 if (ef->relatab[i].rela)
829 free(ef->relatab[i].rela, M_LINKER);
830 if (ef->reltab)
831 free(ef->reltab, M_LINKER);
832 if (ef->relatab)
833 free(ef->relatab, M_LINKER);
834 if (ef->progtab)
835 free(ef->progtab, M_LINKER);
836
837 if (ef->object) {
838 vm_map_remove(kernel_map, (vm_offset_t) ef->address,
839 (vm_offset_t) ef->address +
840 (ef->object->size << PAGE_SHIFT));
841 }
842 if (ef->e_shdr)
843 free(ef->e_shdr, M_LINKER);
844 if (ef->ddbsymtab)
845 free(ef->ddbsymtab, M_LINKER);
846 if (ef->ddbstrtab)
847 free(ef->ddbstrtab, M_LINKER);
848 if (ef->shstrtab)
849 free(ef->shstrtab, M_LINKER);
850 }
851
852 static const char *
853 symbol_name(elf_file_t ef, Elf_Size r_info)
854 {
855 const Elf_Sym *ref;
856
857 if (ELF_R_SYM(r_info)) {
858 ref = ef->ddbsymtab + ELF_R_SYM(r_info);
859 return ef->ddbstrtab + ref->st_name;
860 } else
861 return NULL;
862 }
863
864 static Elf_Addr
865 findbase(elf_file_t ef, int sec)
866 {
867 int i;
868 Elf_Addr base = 0;
869
870 for (i = 0; i < ef->nprogtab; i++) {
871 if (sec == ef->progtab[i].sec) {
872 base = (Elf_Addr)ef->progtab[i].addr;
873 break;
874 }
875 }
876 return base;
877 }
878
879 static int
880 relocate_file(elf_file_t ef)
881 {
882 const Elf_Rel *rellim;
883 const Elf_Rel *rel;
884 const Elf_Rela *relalim;
885 const Elf_Rela *rela;
886 const char *symname;
887 const Elf_Sym *sym;
888 int i;
889 Elf_Size symidx;
890 Elf_Addr base;
891
892
893 /* Perform relocations without addend if there are any: */
894 for (i = 0; i < ef->nreltab; i++) {
895 rel = ef->reltab[i].rel;
896 if (rel == NULL)
897 panic("lost a reltab!");
898 rellim = rel + ef->reltab[i].nrel;
899 base = findbase(ef, ef->reltab[i].sec);
900 if (base == 0)
901 panic("lost base for reltab");
902 for ( ; rel < rellim; rel++) {
903 symidx = ELF_R_SYM(rel->r_info);
904 if (symidx >= ef->ddbsymcnt)
905 continue;
906 sym = ef->ddbsymtab + symidx;
907 /* Local relocs are already done */
908 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
909 continue;
910 if (elf_reloc(&ef->lf, base, rel, ELF_RELOC_REL,
911 elf_obj_lookup)) {
912 symname = symbol_name(ef, rel->r_info);
913 printf("link_elf_obj: symbol %s undefined\n",
914 symname);
915 return ENOENT;
916 }
917 }
918 }
919
920 /* Perform relocations with addend if there are any: */
921 for (i = 0; i < ef->nrelatab; i++) {
922 rela = ef->relatab[i].rela;
923 if (rela == NULL)
924 panic("lost a relatab!");
925 relalim = rela + ef->relatab[i].nrela;
926 base = findbase(ef, ef->relatab[i].sec);
927 if (base == 0)
928 panic("lost base for relatab");
929 for ( ; rela < relalim; rela++) {
930 symidx = ELF_R_SYM(rela->r_info);
931 if (symidx >= ef->ddbsymcnt)
932 continue;
933 sym = ef->ddbsymtab + symidx;
934 /* Local relocs are already done */
935 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
936 continue;
937 if (elf_reloc(&ef->lf, base, rela, ELF_RELOC_RELA,
938 elf_obj_lookup)) {
939 symname = symbol_name(ef, rela->r_info);
940 printf("link_elf_obj: symbol %s undefined\n",
941 symname);
942 return ENOENT;
943 }
944 }
945 }
946
947 return 0;
948 }
949
950 static int
951 link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
952 {
953 elf_file_t ef = (elf_file_t) lf;
954 const Elf_Sym *symp;
955 const char *strp;
956 int i;
957
958 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
959 strp = ef->ddbstrtab + symp->st_name;
960 if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) {
961 *sym = (c_linker_sym_t) symp;
962 return 0;
963 }
964 }
965 return ENOENT;
966 }
967
968 static int
969 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
970 linker_symval_t *symval)
971 {
972 elf_file_t ef = (elf_file_t) lf;
973 const Elf_Sym *es = (const Elf_Sym*) sym;
974
975 if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) {
976 symval->name = ef->ddbstrtab + es->st_name;
977 symval->value = (caddr_t)es->st_value;
978 symval->size = es->st_size;
979 return 0;
980 }
981 return ENOENT;
982 }
983
984 static int
985 link_elf_search_symbol(linker_file_t lf, caddr_t value,
986 c_linker_sym_t *sym, long *diffp)
987 {
988 elf_file_t ef = (elf_file_t) lf;
989 u_long off = (uintptr_t) (void *) value;
990 u_long diff = off;
991 u_long st_value;
992 const Elf_Sym *es;
993 const Elf_Sym *best = 0;
994 int i;
995
996 for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) {
997 if (es->st_name == 0)
998 continue;
999 st_value = es->st_value;
1000 if (off >= st_value) {
1001 if (off - st_value < diff) {
1002 diff = off - st_value;
1003 best = es;
1004 if (diff == 0)
1005 break;
1006 } else if (off - st_value == diff) {
1007 best = es;
1008 }
1009 }
1010 }
1011 if (best == 0)
1012 *diffp = off;
1013 else
1014 *diffp = diff;
1015 *sym = (c_linker_sym_t) best;
1016
1017 return 0;
1018 }
1019
1020 /*
1021 * Look up a linker set on an ELF system.
1022 */
1023 static int
1024 link_elf_lookup_set(linker_file_t lf, const char *name,
1025 void ***startp, void ***stopp, int *countp)
1026 {
1027 elf_file_t ef = (elf_file_t)lf;
1028 void **start, **stop;
1029 int i, count;
1030
1031 /* Relative to section number */
1032 for (i = 0; i < ef->nprogtab; i++) {
1033 if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) &&
1034 strcmp(ef->progtab[i].name + 4, name) == 0) {
1035 start = (void **)ef->progtab[i].addr;
1036 stop = (void **)((char *)ef->progtab[i].addr +
1037 ef->progtab[i].size);
1038 count = stop - start;
1039 if (startp)
1040 *startp = start;
1041 if (stopp)
1042 *stopp = stop;
1043 if (countp)
1044 *countp = count;
1045 return (0);
1046 }
1047 }
1048 return (ESRCH);
1049 }
1050
1051 static int
1052 link_elf_each_function_name(linker_file_t file,
1053 int (*callback)(const char *, void *), void *opaque)
1054 {
1055 elf_file_t ef = (elf_file_t)file;
1056 const Elf_Sym *symp;
1057 int i, error;
1058
1059 /* Exhaustive search */
1060 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
1061 if (symp->st_value != 0 &&
1062 ELF_ST_TYPE(symp->st_info) == STT_FUNC) {
1063 error = callback(ef->ddbstrtab + symp->st_name, opaque);
1064 if (error)
1065 return (error);
1066 }
1067 }
1068 return (0);
1069 }
1070
1071 /*
1072 * Symbol lookup function that can be used when the symbol index is known (ie
1073 * in relocations). It uses the symbol index instead of doing a fully fledged
1074 * hash table based lookup when such is valid. For example for local symbols.
1075 * This is not only more efficient, it's also more correct. It's not always
1076 * the case that the symbol can be found through the hash table.
1077 */
1078 static Elf_Addr
1079 elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps)
1080 {
1081 elf_file_t ef = (elf_file_t)lf;
1082 const Elf_Sym *sym;
1083 const char *symbol;
1084 Elf_Addr ret;
1085
1086 /* Don't even try to lookup the symbol if the index is bogus. */
1087 if (symidx >= ef->ddbsymcnt)
1088 return (0);
1089
1090 sym = ef->ddbsymtab + symidx;
1091
1092 /* Quick answer if there is a definition included. */
1093 if (sym->st_shndx != SHN_UNDEF)
1094 return (sym->st_value);
1095
1096 /* If we get here, then it is undefined and needs a lookup. */
1097 switch (ELF_ST_BIND(sym->st_info)) {
1098 case STB_LOCAL:
1099 /* Local, but undefined? huh? */
1100 return (0);
1101
1102 case STB_GLOBAL:
1103 /* Relative to Data or Function name */
1104 symbol = ef->ddbstrtab + sym->st_name;
1105
1106 /* Force a lookup failure if the symbol name is bogus. */
1107 if (*symbol == 0)
1108 return (0);
1109 ret = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
1110 return ret;
1111
1112 case STB_WEAK:
1113 printf("link_elf_obj: Weak symbols not supported\n");
1114 return (0);
1115
1116 default:
1117 return (0);
1118 }
1119 }
1120
1121 static void
1122 link_elf_fix_link_set(elf_file_t ef)
1123 {
1124 static const char startn[] = "__start_";
1125 static const char stopn[] = "__stop_";
1126 Elf_Sym *sym;
1127 const char *sym_name, *linkset_name;
1128 Elf_Addr startp, stopp;
1129 Elf_Size symidx;
1130 int start, i;
1131
1132 startp = stopp = 0;
1133 for (symidx = 1 /* zero entry is special */;
1134 symidx < ef->ddbsymcnt; symidx++) {
1135 sym = ef->ddbsymtab + symidx;
1136 if (sym->st_shndx != SHN_UNDEF)
1137 continue;
1138
1139 sym_name = ef->ddbstrtab + sym->st_name;
1140 if (strncmp(sym_name, startn, sizeof(startn) - 1) == 0) {
1141 start = 1;
1142 linkset_name = sym_name + sizeof(startn) - 1;
1143 }
1144 else if (strncmp(sym_name, stopn, sizeof(stopn) - 1) == 0) {
1145 start = 0;
1146 linkset_name = sym_name + sizeof(stopn) - 1;
1147 }
1148 else
1149 continue;
1150
1151 for (i = 0; i < ef->nprogtab; i++) {
1152 if (strcmp(ef->progtab[i].name, linkset_name) == 0) {
1153 startp = (Elf_Addr)ef->progtab[i].addr;
1154 stopp = (Elf_Addr)(startp + ef->progtab[i].size);
1155 break;
1156 }
1157 }
1158 if (i == ef->nprogtab)
1159 continue;
1160
1161 sym->st_value = start ? startp : stopp;
1162 sym->st_shndx = i;
1163 }
1164 }
1165
1166 static void
1167 link_elf_reloc_local(linker_file_t lf)
1168 {
1169 elf_file_t ef = (elf_file_t)lf;
1170 const Elf_Rel *rellim;
1171 const Elf_Rel *rel;
1172 const Elf_Rela *relalim;
1173 const Elf_Rela *rela;
1174 const Elf_Sym *sym;
1175 Elf_Addr base;
1176 int i;
1177 Elf_Size symidx;
1178
1179 link_elf_fix_link_set(ef);
1180
1181 /* Perform relocations without addend if there are any: */
1182 for (i = 0; i < ef->nreltab; i++) {
1183 rel = ef->reltab[i].rel;
1184 if (rel == NULL)
1185 panic("lost a reltab!");
1186 rellim = rel + ef->reltab[i].nrel;
1187 base = findbase(ef, ef->reltab[i].sec);
1188 if (base == 0)
1189 panic("lost base for reltab");
1190 for ( ; rel < rellim; rel++) {
1191 symidx = ELF_R_SYM(rel->r_info);
1192 if (symidx >= ef->ddbsymcnt)
1193 continue;
1194 sym = ef->ddbsymtab + symidx;
1195 /* Only do local relocs */
1196 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL)
1197 continue;
1198 elf_reloc_local(lf, base, rel, ELF_RELOC_REL,
1199 elf_obj_lookup);
1200 }
1201 }
1202
1203 /* Perform relocations with addend if there are any: */
1204 for (i = 0; i < ef->nrelatab; i++) {
1205 rela = ef->relatab[i].rela;
1206 if (rela == NULL)
1207 panic("lost a relatab!");
1208 relalim = rela + ef->relatab[i].nrela;
1209 base = findbase(ef, ef->relatab[i].sec);
1210 if (base == 0)
1211 panic("lost base for relatab");
1212 for ( ; rela < relalim; rela++) {
1213 symidx = ELF_R_SYM(rela->r_info);
1214 if (symidx >= ef->ddbsymcnt)
1215 continue;
1216 sym = ef->ddbsymtab + symidx;
1217 /* Only do local relocs */
1218 if (ELF_ST_BIND(sym->st_info) != STB_LOCAL)
1219 continue;
1220 elf_reloc_local(lf, base, rela, ELF_RELOC_RELA,
1221 elf_obj_lookup);
1222 }
1223 }
1224 }
Cache object: 917c4207d776dd9b12582ac685389f94
|