2 * Copyright (c) 1998-2000 Doug Rabson
3 * Copyright (c) 2004 Peter Wemm
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/mutex.h>
40 #include <sys/mount.h>
42 #include <sys/namei.h>
43 #include <sys/fcntl.h>
44 #include <sys/vnode.h>
45 #include <sys/linker.h>
47 #include <machine/elf.h>
49 #include <security/mac/mac_framework.h>
52 #include <vm/vm_param.h>
53 #include <vm/vm_object.h>
54 #include <vm/vm_kern.h>
55 #include <vm/vm_extern.h>
57 #include <vm/vm_map.h>
59 #include <sys/link_elf.h>
65 #include "linker_if.h"
71 int sec
; /* Original section */
88 typedef struct elf_file
{
89 struct linker_file lf
; /* Common fields */
92 caddr_t address
; /* Relocation address */
93 vm_object_t object
; /* VM object to hold file pages */
105 Elf_Sym
*ddbsymtab
; /* The symbol table we are using */
106 long ddbsymcnt
; /* Number of symbols */
107 caddr_t ddbstrtab
; /* String table */
108 long ddbstrcnt
; /* number of bytes in string table */
110 caddr_t shstrtab
; /* Section name string table */
111 long shstrcnt
; /* number of bytes in string table */
113 caddr_t ctftab
; /* CTF table */
114 long ctfcnt
; /* number of bytes in CTF table */
115 caddr_t ctfoff
; /* CTF offset table */
116 caddr_t typoff
; /* Type offset table */
117 long typlen
; /* Number of type entries. */
121 #include <kern/kern_ctf.c>
123 static int link_elf_link_preload(linker_class_t cls
,
124 const char *, linker_file_t
*);
125 static int link_elf_link_preload_finish(linker_file_t
);
126 static int link_elf_load_file(linker_class_t
, const char *, linker_file_t
*);
127 static int link_elf_lookup_symbol(linker_file_t
, const char *,
129 static int link_elf_symbol_values(linker_file_t
, c_linker_sym_t
,
131 static int link_elf_search_symbol(linker_file_t
, caddr_t value
,
132 c_linker_sym_t
*sym
, long *diffp
);
134 static void link_elf_unload_file(linker_file_t
);
135 static int link_elf_lookup_set(linker_file_t
, const char *,
136 void ***, void ***, int *);
137 static int link_elf_each_function_name(linker_file_t
,
138 int (*)(const char *, void *), void *);
139 static int link_elf_each_function_nameval(linker_file_t
,
140 linker_function_nameval_callback_t
,
142 static void link_elf_reloc_local(linker_file_t
);
144 static Elf_Addr
elf_obj_lookup(linker_file_t lf
, Elf_Size symidx
, int deps
);
146 static kobj_method_t link_elf_methods
[] = {
147 KOBJMETHOD(linker_lookup_symbol
, link_elf_lookup_symbol
),
148 KOBJMETHOD(linker_symbol_values
, link_elf_symbol_values
),
149 KOBJMETHOD(linker_search_symbol
, link_elf_search_symbol
),
150 KOBJMETHOD(linker_unload
, link_elf_unload_file
),
151 KOBJMETHOD(linker_load_file
, link_elf_load_file
),
152 KOBJMETHOD(linker_link_preload
, link_elf_link_preload
),
153 KOBJMETHOD(linker_link_preload_finish
, link_elf_link_preload_finish
),
154 KOBJMETHOD(linker_lookup_set
, link_elf_lookup_set
),
155 KOBJMETHOD(linker_each_function_name
, link_elf_each_function_name
),
156 KOBJMETHOD(linker_each_function_nameval
, link_elf_each_function_nameval
),
157 KOBJMETHOD(linker_ctf_get
, link_elf_ctf_get
),
161 static struct linker_class link_elf_class
= {
162 #if ELF_TARG_CLASS == ELFCLASS32
167 link_elf_methods
, sizeof(struct elf_file
)
170 static int relocate_file(elf_file_t ef
);
173 link_elf_error(const char *filename
, const char *s
)
175 if (filename
== NULL
)
176 printf("kldload: %s\n", s
);
178 printf("kldload: %s: %s\n", filename
, s
);
182 link_elf_init(void *arg
)
185 linker_add_class(&link_elf_class
);
188 SYSINIT(link_elf_obj
, SI_SUB_KLD
, SI_ORDER_SECOND
, link_elf_init
, 0);
191 link_elf_link_preload(linker_class_t cls
, const char *filename
,
192 linker_file_t
*result
)
197 void *modptr
, *baseptr
, *sizeptr
;
202 int error
, i
, j
, pb
, ra
, rl
, shstrindex
, symstrindex
, symtabindex
;
204 /* Look to see if we have the file preloaded */
205 modptr
= preload_search_by_name(filename
);
209 type
= (char *)preload_search_info(modptr
, MODINFO_TYPE
);
210 baseptr
= preload_search_info(modptr
, MODINFO_ADDR
);
211 sizeptr
= preload_search_info(modptr
, MODINFO_SIZE
);
212 hdr
= (Elf_Ehdr
*)preload_search_info(modptr
, MODINFO_METADATA
|
214 shdr
= (Elf_Shdr
*)preload_search_info(modptr
, MODINFO_METADATA
|
216 if (type
== NULL
|| (strcmp(type
, "elf" __XSTRING(__ELF_WORD_SIZE
)
217 " obj module") != 0 &&
218 strcmp(type
, "elf obj module") != 0)) {
221 if (baseptr
== NULL
|| sizeptr
== NULL
|| hdr
== NULL
||
225 lf
= linker_make_file(filename
, &link_elf_class
);
231 ef
->address
= *(caddr_t
*)baseptr
;
232 lf
->address
= *(caddr_t
*)baseptr
;
233 lf
->size
= *(size_t *)sizeptr
;
235 if (hdr
->e_ident
[EI_CLASS
] != ELF_TARG_CLASS
||
236 hdr
->e_ident
[EI_DATA
] != ELF_TARG_DATA
||
237 hdr
->e_ident
[EI_VERSION
] != EV_CURRENT
||
238 hdr
->e_version
!= EV_CURRENT
||
239 hdr
->e_type
!= ET_REL
||
240 hdr
->e_machine
!= ELF_TARG_MACH
) {
246 /* Scan the section header for information and table sizing. */
249 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
250 switch (shdr
[i
].sh_type
) {
257 symstrindex
= shdr
[i
].sh_link
;
268 shstrindex
= hdr
->e_shstrndx
;
269 if (ef
->nprogtab
== 0 || symstrindex
< 0 ||
270 symstrindex
>= hdr
->e_shnum
||
271 shdr
[symstrindex
].sh_type
!= SHT_STRTAB
|| shstrindex
== 0 ||
272 shstrindex
>= hdr
->e_shnum
||
273 shdr
[shstrindex
].sh_type
!= SHT_STRTAB
) {
274 printf("%s: bad/missing section headers\n", filename
);
279 /* Allocate space for tracking the load chunks */
280 if (ef
->nprogtab
!= 0)
281 ef
->progtab
= malloc(ef
->nprogtab
* sizeof(*ef
->progtab
),
282 M_LINKER
, M_WAITOK
| M_ZERO
);
283 if (ef
->nreltab
!= 0)
284 ef
->reltab
= malloc(ef
->nreltab
* sizeof(*ef
->reltab
),
285 M_LINKER
, M_WAITOK
| M_ZERO
);
286 if (ef
->nrelatab
!= 0)
287 ef
->relatab
= malloc(ef
->nrelatab
* sizeof(*ef
->relatab
),
288 M_LINKER
, M_WAITOK
| M_ZERO
);
289 if ((ef
->nprogtab
!= 0 && ef
->progtab
== NULL
) ||
290 (ef
->nreltab
!= 0 && ef
->reltab
== NULL
) ||
291 (ef
->nrelatab
!= 0 && ef
->relatab
== NULL
)) {
296 /* XXX, relocate the sh_addr fields saved by the loader. */
298 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
299 if (shdr
[i
].sh_addr
!= 0 && (off
== 0 || shdr
[i
].sh_addr
< off
))
300 off
= shdr
[i
].sh_addr
;
302 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
303 if (shdr
[i
].sh_addr
!= 0)
304 shdr
[i
].sh_addr
= shdr
[i
].sh_addr
- off
+
305 (Elf_Addr
)ef
->address
;
308 ef
->ddbsymcnt
= shdr
[symtabindex
].sh_size
/ sizeof(Elf_Sym
);
309 ef
->ddbsymtab
= (Elf_Sym
*)shdr
[symtabindex
].sh_addr
;
310 ef
->ddbstrcnt
= shdr
[symstrindex
].sh_size
;
311 ef
->ddbstrtab
= (char *)shdr
[symstrindex
].sh_addr
;
312 ef
->shstrcnt
= shdr
[shstrindex
].sh_size
;
313 ef
->shstrtab
= (char *)shdr
[shstrindex
].sh_addr
;
315 /* Now fill out progtab and the relocation tables. */
319 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
320 switch (shdr
[i
].sh_type
) {
323 ef
->progtab
[pb
].addr
= (void *)shdr
[i
].sh_addr
;
324 if (shdr
[i
].sh_type
== SHT_PROGBITS
)
325 ef
->progtab
[pb
].name
= "<<PROGBITS>>";
327 ef
->progtab
[pb
].name
= "<<NOBITS>>";
328 ef
->progtab
[pb
].size
= shdr
[i
].sh_size
;
329 ef
->progtab
[pb
].sec
= i
;
330 if (ef
->shstrtab
&& shdr
[i
].sh_name
!= 0)
331 ef
->progtab
[pb
].name
=
332 ef
->shstrtab
+ shdr
[i
].sh_name
;
334 /* Update all symbol values with the offset. */
335 for (j
= 0; j
< ef
->ddbsymcnt
; j
++) {
336 es
= &ef
->ddbsymtab
[j
];
337 if (es
->st_shndx
!= i
)
339 es
->st_value
+= (Elf_Addr
)ef
->progtab
[pb
].addr
;
344 ef
->reltab
[rl
].rel
= (Elf_Rel
*)shdr
[i
].sh_addr
;
345 ef
->reltab
[rl
].nrel
= shdr
[i
].sh_size
/ sizeof(Elf_Rel
);
346 ef
->reltab
[rl
].sec
= shdr
[i
].sh_info
;
350 ef
->relatab
[ra
].rela
= (Elf_Rela
*)shdr
[i
].sh_addr
;
351 ef
->relatab
[ra
].nrela
=
352 shdr
[i
].sh_size
/ sizeof(Elf_Rela
);
353 ef
->relatab
[ra
].sec
= shdr
[i
].sh_info
;
358 if (pb
!= ef
->nprogtab
)
359 panic("lost progbits");
360 if (rl
!= ef
->nreltab
)
361 panic("lost reltab");
362 if (ra
!= ef
->nrelatab
)
363 panic("lost relatab");
365 /* Local intra-module relocations */
366 link_elf_reloc_local(lf
);
372 /* preload not done this way */
373 linker_file_unload(lf
, LINKER_UNLOAD_FORCE
);
378 link_elf_link_preload_finish(linker_file_t lf
)
384 error
= relocate_file(ef
);
388 /* Notify MD code that a module is being loaded. */
389 error
= elf_cpu_load_file(lf
);
397 link_elf_load_file(linker_class_t cls
, const char *filename
,
398 linker_file_t
*result
)
401 struct thread
*td
= curthread
; /* XXX */
425 NDINIT(&nd
, LOOKUP
, FOLLOW
| MPSAFE
, UIO_SYSSPACE
, filename
, td
);
427 error
= vn_open(&nd
, &flags
, 0, NULL
);
430 vfslocked
= NDHASGIANT(&nd
);
431 NDFREE(&nd
, NDF_ONLY_PNBUF
);
432 if (nd
.ni_vp
->v_type
!= VREG
) {
437 error
= mac_kld_check_load(td
->td_ucred
, nd
.ni_vp
);
443 /* Read the elf header from the file. */
444 hdr
= malloc(sizeof(*hdr
), M_LINKER
, M_WAITOK
);
449 error
= vn_rdwr(UIO_READ
, nd
.ni_vp
, (void *)hdr
, sizeof(*hdr
), 0,
450 UIO_SYSSPACE
, IO_NODELOCKED
, td
->td_ucred
, NOCRED
,
464 if (hdr
->e_ident
[EI_CLASS
] != ELF_TARG_CLASS
465 || hdr
->e_ident
[EI_DATA
] != ELF_TARG_DATA
) {
466 link_elf_error(filename
, "Unsupported file layout");
470 if (hdr
->e_ident
[EI_VERSION
] != EV_CURRENT
471 || hdr
->e_version
!= EV_CURRENT
) {
472 link_elf_error(filename
, "Unsupported file version");
476 if (hdr
->e_type
!= ET_REL
) {
477 link_elf_error(filename
, "Unsupported file type");
481 if (hdr
->e_machine
!= ELF_TARG_MACH
) {
482 link_elf_error(filename
, "Unsupported machine");
487 lf
= linker_make_file(filename
, &link_elf_class
);
492 ef
= (elf_file_t
) lf
;
498 /* Allocate and read in the section header */
499 nbytes
= hdr
->e_shnum
* hdr
->e_shentsize
;
500 if (nbytes
== 0 || hdr
->e_shoff
== 0 ||
501 hdr
->e_shentsize
!= sizeof(Elf_Shdr
)) {
505 shdr
= malloc(nbytes
, M_LINKER
, M_WAITOK
);
511 error
= vn_rdwr(UIO_READ
, nd
.ni_vp
, (caddr_t
)shdr
, nbytes
, hdr
->e_shoff
,
512 UIO_SYSSPACE
, IO_NODELOCKED
, td
->td_ucred
, NOCRED
, &resid
, td
);
520 /* Scan the section header for information and table sizing. */
524 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
525 switch (shdr
[i
].sh_type
) {
533 symstrindex
= shdr
[i
].sh_link
;
545 if (ef
->nprogtab
== 0) {
546 link_elf_error(filename
, "file has no contents");
551 /* Only allow one symbol table for now */
552 link_elf_error(filename
, "file has no valid symbol table");
556 if (symstrindex
< 0 || symstrindex
> hdr
->e_shnum
||
557 shdr
[symstrindex
].sh_type
!= SHT_STRTAB
) {
558 link_elf_error(filename
, "file has invalid symbol strings");
563 /* Allocate space for tracking the load chunks */
564 if (ef
->nprogtab
!= 0)
565 ef
->progtab
= malloc(ef
->nprogtab
* sizeof(*ef
->progtab
),
566 M_LINKER
, M_WAITOK
| M_ZERO
);
567 if (ef
->nreltab
!= 0)
568 ef
->reltab
= malloc(ef
->nreltab
* sizeof(*ef
->reltab
),
569 M_LINKER
, M_WAITOK
| M_ZERO
);
570 if (ef
->nrelatab
!= 0)
571 ef
->relatab
= malloc(ef
->nrelatab
* sizeof(*ef
->relatab
),
572 M_LINKER
, M_WAITOK
| M_ZERO
);
573 if ((ef
->nprogtab
!= 0 && ef
->progtab
== NULL
) ||
574 (ef
->nreltab
!= 0 && ef
->reltab
== NULL
) ||
575 (ef
->nrelatab
!= 0 && ef
->relatab
== NULL
)) {
580 if (symtabindex
== -1)
581 panic("lost symbol table index");
582 /* Allocate space for and load the symbol table */
583 ef
->ddbsymcnt
= shdr
[symtabindex
].sh_size
/ sizeof(Elf_Sym
);
584 ef
->ddbsymtab
= malloc(shdr
[symtabindex
].sh_size
, M_LINKER
, M_WAITOK
);
585 if (ef
->ddbsymtab
== NULL
) {
589 error
= vn_rdwr(UIO_READ
, nd
.ni_vp
, (void *)ef
->ddbsymtab
,
590 shdr
[symtabindex
].sh_size
, shdr
[symtabindex
].sh_offset
,
591 UIO_SYSSPACE
, IO_NODELOCKED
, td
->td_ucred
, NOCRED
,
600 if (symstrindex
== -1)
601 panic("lost symbol string index");
602 /* Allocate space for and load the symbol strings */
603 ef
->ddbstrcnt
= shdr
[symstrindex
].sh_size
;
604 ef
->ddbstrtab
= malloc(shdr
[symstrindex
].sh_size
, M_LINKER
, M_WAITOK
);
605 if (ef
->ddbstrtab
== NULL
) {
609 error
= vn_rdwr(UIO_READ
, nd
.ni_vp
, ef
->ddbstrtab
,
610 shdr
[symstrindex
].sh_size
, shdr
[symstrindex
].sh_offset
,
611 UIO_SYSSPACE
, IO_NODELOCKED
, td
->td_ucred
, NOCRED
,
620 /* Do we have a string table for the section names? */
622 if (hdr
->e_shstrndx
!= 0 &&
623 shdr
[hdr
->e_shstrndx
].sh_type
== SHT_STRTAB
) {
624 shstrindex
= hdr
->e_shstrndx
;
625 ef
->shstrcnt
= shdr
[shstrindex
].sh_size
;
626 ef
->shstrtab
= malloc(shdr
[shstrindex
].sh_size
, M_LINKER
,
628 if (ef
->shstrtab
== NULL
) {
632 error
= vn_rdwr(UIO_READ
, nd
.ni_vp
, ef
->shstrtab
,
633 shdr
[shstrindex
].sh_size
, shdr
[shstrindex
].sh_offset
,
634 UIO_SYSSPACE
, IO_NODELOCKED
, td
->td_ucred
, NOCRED
,
644 /* Size up code/data(progbits) and bss(nobits). */
646 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
647 switch (shdr
[i
].sh_type
) {
650 alignmask
= shdr
[i
].sh_addralign
- 1;
651 mapsize
+= alignmask
;
652 mapsize
&= ~alignmask
;
653 mapsize
+= shdr
[i
].sh_size
;
659 * We know how much space we need for the text/data/bss/etc.
660 * This stuff needs to be in a single chunk so that profiling etc
661 * can get the bounds and gdb can associate offsets with modules
663 ef
->object
= vm_object_allocate(OBJT_DEFAULT
,
664 round_page(mapsize
) >> PAGE_SHIFT
);
665 if (ef
->object
== NULL
) {
669 ef
->address
= (caddr_t
) vm_map_min(kernel_map
);
672 * In order to satisfy amd64's architectural requirements on the
673 * location of code and data in the kernel's address space, request a
674 * mapping that is above the kernel.
677 error
= vm_map_find(kernel_map
, ef
->object
, 0, &mapbase
,
678 round_page(mapsize
), TRUE
, VM_PROT_ALL
, VM_PROT_ALL
, FALSE
);
680 vm_object_deallocate(ef
->object
);
686 error
= vm_map_wire(kernel_map
, mapbase
,
687 mapbase
+ round_page(mapsize
),
688 VM_MAP_WIRE_SYSTEM
|VM_MAP_WIRE_NOHOLES
);
689 if (error
!= KERN_SUCCESS
) {
694 /* Inform the kld system about the situation */
695 lf
->address
= ef
->address
= (caddr_t
)mapbase
;
699 * Now load code/data(progbits), zero bss(nobits), allocate space for
706 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
707 switch (shdr
[i
].sh_type
) {
710 alignmask
= shdr
[i
].sh_addralign
- 1;
711 mapbase
+= alignmask
;
712 mapbase
&= ~alignmask
;
713 ef
->progtab
[pb
].addr
= (void *)(uintptr_t)mapbase
;
714 if (shdr
[i
].sh_type
== SHT_PROGBITS
) {
715 ef
->progtab
[pb
].name
= "<<PROGBITS>>";
716 error
= vn_rdwr(UIO_READ
, nd
.ni_vp
,
717 ef
->progtab
[pb
].addr
,
718 shdr
[i
].sh_size
, shdr
[i
].sh_offset
,
719 UIO_SYSSPACE
, IO_NODELOCKED
, td
->td_ucred
,
728 ef
->progtab
[pb
].name
= "<<NOBITS>>";
729 bzero(ef
->progtab
[pb
].addr
, shdr
[i
].sh_size
);
731 ef
->progtab
[pb
].size
= shdr
[i
].sh_size
;
732 ef
->progtab
[pb
].sec
= i
;
733 if (ef
->shstrtab
&& shdr
[i
].sh_name
!= 0)
734 ef
->progtab
[pb
].name
=
735 ef
->shstrtab
+ shdr
[i
].sh_name
;
737 /* Update all symbol values with the offset. */
738 for (j
= 0; j
< ef
->ddbsymcnt
; j
++) {
739 es
= &ef
->ddbsymtab
[j
];
740 if (es
->st_shndx
!= i
)
742 es
->st_value
+= (Elf_Addr
)ef
->progtab
[pb
].addr
;
744 mapbase
+= shdr
[i
].sh_size
;
748 ef
->reltab
[rl
].rel
= malloc(shdr
[i
].sh_size
, M_LINKER
,
750 ef
->reltab
[rl
].nrel
= shdr
[i
].sh_size
/ sizeof(Elf_Rel
);
751 ef
->reltab
[rl
].sec
= shdr
[i
].sh_info
;
752 error
= vn_rdwr(UIO_READ
, nd
.ni_vp
,
753 (void *)ef
->reltab
[rl
].rel
,
754 shdr
[i
].sh_size
, shdr
[i
].sh_offset
,
755 UIO_SYSSPACE
, IO_NODELOCKED
, td
->td_ucred
, NOCRED
,
766 ef
->relatab
[ra
].rela
= malloc(shdr
[i
].sh_size
, M_LINKER
,
768 ef
->relatab
[ra
].nrela
=
769 shdr
[i
].sh_size
/ sizeof(Elf_Rela
);
770 ef
->relatab
[ra
].sec
= shdr
[i
].sh_info
;
771 error
= vn_rdwr(UIO_READ
, nd
.ni_vp
,
772 (void *)ef
->relatab
[ra
].rela
,
773 shdr
[i
].sh_size
, shdr
[i
].sh_offset
,
774 UIO_SYSSPACE
, IO_NODELOCKED
, td
->td_ucred
, NOCRED
,
786 if (pb
!= ef
->nprogtab
)
787 panic("lost progbits");
788 if (rl
!= ef
->nreltab
)
789 panic("lost reltab");
790 if (ra
!= ef
->nrelatab
)
791 panic("lost relatab");
792 if (mapbase
!= (vm_offset_t
)ef
->address
+ mapsize
)
793 panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n",
794 mapbase
, ef
->address
, mapsize
,
795 (vm_offset_t
)ef
->address
+ mapsize
);
797 /* Local intra-module relocations */
798 link_elf_reloc_local(lf
);
800 /* Pull in dependencies */
801 VOP_UNLOCK(nd
.ni_vp
, 0);
802 error
= linker_load_dependencies(lf
);
803 vn_lock(nd
.ni_vp
, LK_EXCLUSIVE
| LK_RETRY
);
807 /* External relocations */
808 error
= relocate_file(ef
);
812 /* Notify MD code that a module is being loaded. */
813 error
= elf_cpu_load_file(lf
);
821 linker_file_unload(lf
, LINKER_UNLOAD_FORCE
);
824 VOP_UNLOCK(nd
.ni_vp
, 0);
825 vn_close(nd
.ni_vp
, FREAD
, td
->td_ucred
, td
);
826 VFS_UNLOCK_GIANT(vfslocked
);
832 link_elf_unload_file(linker_file_t file
)
834 elf_file_t ef
= (elf_file_t
) file
;
837 /* Notify MD code that a module is being unloaded. */
838 elf_cpu_unload_file(file
);
842 free(ef
->reltab
, M_LINKER
);
844 free(ef
->relatab
, M_LINKER
);
846 free(ef
->progtab
, M_LINKER
);
848 free(ef
->ctftab
, M_LINKER
);
850 free(ef
->ctfoff
, M_LINKER
);
852 free(ef
->typoff
, M_LINKER
);
853 if (file
->filename
!= NULL
)
854 preload_delete_name(file
->filename
);
855 /* XXX reclaim module memory? */
859 for (i
= 0; i
< ef
->nreltab
; i
++)
860 if (ef
->reltab
[i
].rel
)
861 free(ef
->reltab
[i
].rel
, M_LINKER
);
862 for (i
= 0; i
< ef
->nrelatab
; i
++)
863 if (ef
->relatab
[i
].rela
)
864 free(ef
->relatab
[i
].rela
, M_LINKER
);
866 free(ef
->reltab
, M_LINKER
);
868 free(ef
->relatab
, M_LINKER
);
870 free(ef
->progtab
, M_LINKER
);
873 vm_map_remove(kernel_map
, (vm_offset_t
) ef
->address
,
874 (vm_offset_t
) ef
->address
+
875 (ef
->object
->size
<< PAGE_SHIFT
));
878 free(ef
->e_shdr
, M_LINKER
);
880 free(ef
->ddbsymtab
, M_LINKER
);
882 free(ef
->ddbstrtab
, M_LINKER
);
884 free(ef
->shstrtab
, M_LINKER
);
886 free(ef
->ctftab
, M_LINKER
);
888 free(ef
->ctfoff
, M_LINKER
);
890 free(ef
->typoff
, M_LINKER
);
894 symbol_name(elf_file_t ef
, Elf_Size r_info
)
898 if (ELF_R_SYM(r_info
)) {
899 ref
= ef
->ddbsymtab
+ ELF_R_SYM(r_info
);
900 return ef
->ddbstrtab
+ ref
->st_name
;
906 findbase(elf_file_t ef
, int sec
)
911 for (i
= 0; i
< ef
->nprogtab
; i
++) {
912 if (sec
== ef
->progtab
[i
].sec
) {
913 base
= (Elf_Addr
)ef
->progtab
[i
].addr
;
921 relocate_file(elf_file_t ef
)
923 const Elf_Rel
*rellim
;
925 const Elf_Rela
*relalim
;
926 const Elf_Rela
*rela
;
934 /* Perform relocations without addend if there are any: */
935 for (i
= 0; i
< ef
->nreltab
; i
++) {
936 rel
= ef
->reltab
[i
].rel
;
938 panic("lost a reltab!");
939 rellim
= rel
+ ef
->reltab
[i
].nrel
;
940 base
= findbase(ef
, ef
->reltab
[i
].sec
);
942 panic("lost base for reltab");
943 for ( ; rel
< rellim
; rel
++) {
944 symidx
= ELF_R_SYM(rel
->r_info
);
945 if (symidx
>= ef
->ddbsymcnt
)
947 sym
= ef
->ddbsymtab
+ symidx
;
948 /* Local relocs are already done */
949 if (ELF_ST_BIND(sym
->st_info
) == STB_LOCAL
)
951 if (elf_reloc(&ef
->lf
, base
, rel
, ELF_RELOC_REL
,
953 symname
= symbol_name(ef
, rel
->r_info
);
954 printf("link_elf_obj: symbol %s undefined\n",
961 /* Perform relocations with addend if there are any: */
962 for (i
= 0; i
< ef
->nrelatab
; i
++) {
963 rela
= ef
->relatab
[i
].rela
;
965 panic("lost a relatab!");
966 relalim
= rela
+ ef
->relatab
[i
].nrela
;
967 base
= findbase(ef
, ef
->relatab
[i
].sec
);
969 panic("lost base for relatab");
970 for ( ; rela
< relalim
; rela
++) {
971 symidx
= ELF_R_SYM(rela
->r_info
);
972 if (symidx
>= ef
->ddbsymcnt
)
974 sym
= ef
->ddbsymtab
+ symidx
;
975 /* Local relocs are already done */
976 if (ELF_ST_BIND(sym
->st_info
) == STB_LOCAL
)
978 if (elf_reloc(&ef
->lf
, base
, rela
, ELF_RELOC_RELA
,
980 symname
= symbol_name(ef
, rela
->r_info
);
981 printf("link_elf_obj: symbol %s undefined\n",
992 link_elf_lookup_symbol(linker_file_t lf
, const char *name
, c_linker_sym_t
*sym
)
994 elf_file_t ef
= (elf_file_t
) lf
;
999 for (i
= 0, symp
= ef
->ddbsymtab
; i
< ef
->ddbsymcnt
; i
++, symp
++) {
1000 strp
= ef
->ddbstrtab
+ symp
->st_name
;
1001 if (symp
->st_shndx
!= SHN_UNDEF
&& strcmp(name
, strp
) == 0) {
1002 *sym
= (c_linker_sym_t
) symp
;
1010 link_elf_symbol_values(linker_file_t lf
, c_linker_sym_t sym
,
1011 linker_symval_t
*symval
)
1013 elf_file_t ef
= (elf_file_t
) lf
;
1014 const Elf_Sym
*es
= (const Elf_Sym
*) sym
;
1016 if (es
>= ef
->ddbsymtab
&& es
< (ef
->ddbsymtab
+ ef
->ddbsymcnt
)) {
1017 symval
->name
= ef
->ddbstrtab
+ es
->st_name
;
1018 symval
->value
= (caddr_t
)es
->st_value
;
1019 symval
->size
= es
->st_size
;
1026 link_elf_search_symbol(linker_file_t lf
, caddr_t value
,
1027 c_linker_sym_t
*sym
, long *diffp
)
1029 elf_file_t ef
= (elf_file_t
) lf
;
1030 u_long off
= (uintptr_t) (void *) value
;
1034 const Elf_Sym
*best
= 0;
1037 for (i
= 0, es
= ef
->ddbsymtab
; i
< ef
->ddbsymcnt
; i
++, es
++) {
1038 if (es
->st_name
== 0)
1040 st_value
= es
->st_value
;
1041 if (off
>= st_value
) {
1042 if (off
- st_value
< diff
) {
1043 diff
= off
- st_value
;
1047 } else if (off
- st_value
== diff
) {
1056 *sym
= (c_linker_sym_t
) best
;
1062 * Look up a linker set on an ELF system.
1065 link_elf_lookup_set(linker_file_t lf
, const char *name
,
1066 void ***startp
, void ***stopp
, int *countp
)
1068 elf_file_t ef
= (elf_file_t
)lf
;
1069 void **start
, **stop
;
1072 /* Relative to section number */
1073 for (i
= 0; i
< ef
->nprogtab
; i
++) {
1074 if ((strncmp(ef
->progtab
[i
].name
, "set_", 4) == 0) &&
1075 strcmp(ef
->progtab
[i
].name
+ 4, name
) == 0) {
1076 start
= (void **)ef
->progtab
[i
].addr
;
1077 stop
= (void **)((char *)ef
->progtab
[i
].addr
+
1078 ef
->progtab
[i
].size
);
1079 count
= stop
- start
;
1093 link_elf_each_function_name(linker_file_t file
,
1094 int (*callback
)(const char *, void *), void *opaque
)
1096 elf_file_t ef
= (elf_file_t
)file
;
1097 const Elf_Sym
*symp
;
1100 /* Exhaustive search */
1101 for (i
= 0, symp
= ef
->ddbsymtab
; i
< ef
->ddbsymcnt
; i
++, symp
++) {
1102 if (symp
->st_value
!= 0 &&
1103 ELF_ST_TYPE(symp
->st_info
) == STT_FUNC
) {
1104 error
= callback(ef
->ddbstrtab
+ symp
->st_name
, opaque
);
1113 link_elf_each_function_nameval(linker_file_t file
,
1114 linker_function_nameval_callback_t callback
, void *opaque
)
1116 linker_symval_t symval
;
1117 elf_file_t ef
= (elf_file_t
)file
;
1118 const Elf_Sym
* symp
;
1121 /* Exhaustive search */
1122 for (i
= 0, symp
= ef
->ddbsymtab
; i
< ef
->ddbsymcnt
; i
++, symp
++) {
1123 if (symp
->st_value
!= 0 &&
1124 ELF_ST_TYPE(symp
->st_info
) == STT_FUNC
) {
1125 error
= link_elf_symbol_values(file
, (c_linker_sym_t
) symp
, &symval
);
1128 error
= callback(file
, i
, &symval
, opaque
);
1137 * Symbol lookup function that can be used when the symbol index is known (ie
1138 * in relocations). It uses the symbol index instead of doing a fully fledged
1139 * hash table based lookup when such is valid. For example for local symbols.
1140 * This is not only more efficient, it's also more correct. It's not always
1141 * the case that the symbol can be found through the hash table.
1144 elf_obj_lookup(linker_file_t lf
, Elf_Size symidx
, int deps
)
1146 elf_file_t ef
= (elf_file_t
)lf
;
1151 /* Don't even try to lookup the symbol if the index is bogus. */
1152 if (symidx
>= ef
->ddbsymcnt
)
1155 sym
= ef
->ddbsymtab
+ symidx
;
1157 /* Quick answer if there is a definition included. */
1158 if (sym
->st_shndx
!= SHN_UNDEF
)
1159 return (sym
->st_value
);
1161 /* If we get here, then it is undefined and needs a lookup. */
1162 switch (ELF_ST_BIND(sym
->st_info
)) {
1164 /* Local, but undefined? huh? */
1168 /* Relative to Data or Function name */
1169 symbol
= ef
->ddbstrtab
+ sym
->st_name
;
1171 /* Force a lookup failure if the symbol name is bogus. */
1174 ret
= ((Elf_Addr
)linker_file_lookup_symbol(lf
, symbol
, deps
));
1178 printf("link_elf_obj: Weak symbols not supported\n");
1187 link_elf_fix_link_set(elf_file_t ef
)
1189 static const char startn
[] = "__start_";
1190 static const char stopn
[] = "__stop_";
1192 const char *sym_name
, *linkset_name
;
1193 Elf_Addr startp
, stopp
;
1198 for (symidx
= 1 /* zero entry is special */;
1199 symidx
< ef
->ddbsymcnt
; symidx
++) {
1200 sym
= ef
->ddbsymtab
+ symidx
;
1201 if (sym
->st_shndx
!= SHN_UNDEF
)
1204 sym_name
= ef
->ddbstrtab
+ sym
->st_name
;
1205 if (strncmp(sym_name
, startn
, sizeof(startn
) - 1) == 0) {
1207 linkset_name
= sym_name
+ sizeof(startn
) - 1;
1209 else if (strncmp(sym_name
, stopn
, sizeof(stopn
) - 1) == 0) {
1211 linkset_name
= sym_name
+ sizeof(stopn
) - 1;
1216 for (i
= 0; i
< ef
->nprogtab
; i
++) {
1217 if (strcmp(ef
->progtab
[i
].name
, linkset_name
) == 0) {
1218 startp
= (Elf_Addr
)ef
->progtab
[i
].addr
;
1219 stopp
= (Elf_Addr
)(startp
+ ef
->progtab
[i
].size
);
1223 if (i
== ef
->nprogtab
)
1226 sym
->st_value
= start
? startp
: stopp
;
1232 link_elf_reloc_local(linker_file_t lf
)
1234 elf_file_t ef
= (elf_file_t
)lf
;
1235 const Elf_Rel
*rellim
;
1237 const Elf_Rela
*relalim
;
1238 const Elf_Rela
*rela
;
1244 link_elf_fix_link_set(ef
);
1246 /* Perform relocations without addend if there are any: */
1247 for (i
= 0; i
< ef
->nreltab
; i
++) {
1248 rel
= ef
->reltab
[i
].rel
;
1250 panic("lost a reltab!");
1251 rellim
= rel
+ ef
->reltab
[i
].nrel
;
1252 base
= findbase(ef
, ef
->reltab
[i
].sec
);
1254 panic("lost base for reltab");
1255 for ( ; rel
< rellim
; rel
++) {
1256 symidx
= ELF_R_SYM(rel
->r_info
);
1257 if (symidx
>= ef
->ddbsymcnt
)
1259 sym
= ef
->ddbsymtab
+ symidx
;
1260 /* Only do local relocs */
1261 if (ELF_ST_BIND(sym
->st_info
) != STB_LOCAL
)
1263 elf_reloc_local(lf
, base
, rel
, ELF_RELOC_REL
,
1268 /* Perform relocations with addend if there are any: */
1269 for (i
= 0; i
< ef
->nrelatab
; i
++) {
1270 rela
= ef
->relatab
[i
].rela
;
1272 panic("lost a relatab!");
1273 relalim
= rela
+ ef
->relatab
[i
].nrela
;
1274 base
= findbase(ef
, ef
->relatab
[i
].sec
);
1276 panic("lost base for relatab");
1277 for ( ; rela
< relalim
; rela
++) {
1278 symidx
= ELF_R_SYM(rela
->r_info
);
1279 if (symidx
>= ef
->ddbsymcnt
)
1281 sym
= ef
->ddbsymtab
+ symidx
;
1282 /* Only do local relocs */
1283 if (ELF_ST_BIND(sym
->st_info
) != STB_LOCAL
)
1285 elf_reloc_local(lf
, base
, rela
, ELF_RELOC_RELA
,