2 * Copyright (c) 1998 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
27 * $FreeBSD: src/sys/kern/link_elf.c,v 1.24 1999/12/24 15:33:36 bde Exp $
30 #include <sys/param.h>
31 #include <sys/kernel.h>
32 #include <sys/systm.h>
33 #include <sys/malloc.h>
35 #include <sys/nlookup.h>
36 #include <sys/fcntl.h>
37 #include <sys/vnode.h>
38 #include <sys/linker.h>
39 #include <machine/elf.h>
42 #include <vm/vm_param.h>
43 #include <vm/vm_zone.h>
44 #include <vm/vm_object.h>
45 #include <vm/vm_kern.h>
46 #include <vm/vm_extern.h>
49 #include <vm/vm_map.h>
51 static int link_elf_obj_preload_file(const char *, linker_file_t
*);
52 static int link_elf_obj_preload_finish(linker_file_t
);
53 static int link_elf_obj_load_file(const char *, linker_file_t
*);
55 link_elf_obj_lookup_symbol(linker_file_t
, const char *,
57 static int link_elf_obj_symbol_values(linker_file_t
, c_linker_sym_t
, linker_symval_t
*);
59 link_elf_obj_search_symbol(linker_file_t
, caddr_t value
,
60 c_linker_sym_t
* sym
, long *diffp
);
62 static void link_elf_obj_unload_file(linker_file_t
);
64 link_elf_obj_lookup_set(linker_file_t
, const char *,
65 void ***, void ***, int *);
66 static void link_elf_obj_reloc_local(linker_file_t lf
);
67 static int elf_obj_lookup(linker_file_t lf
, Elf_Size symidx
, int deps
, Elf_Addr
*);
69 static struct linker_class_ops link_elf_obj_class_ops
= {
70 link_elf_obj_load_file
,
71 link_elf_obj_preload_file
,
74 static struct linker_file_ops link_elf_obj_file_ops
= {
75 .lookup_symbol
= link_elf_obj_lookup_symbol
,
76 .symbol_values
= link_elf_obj_symbol_values
,
77 .search_symbol
= link_elf_obj_search_symbol
,
78 .preload_finish
= link_elf_obj_preload_finish
,
79 .unload
= link_elf_obj_unload_file
,
80 .lookup_set
= link_elf_obj_lookup_set
,
87 int sec
; /* Original section */
104 typedef struct elf_file
{
107 caddr_t address
; /* Relocation address */
108 size_t bytes
; /* Chunk size in bytes */
109 vm_object_t object
; /* VM object to hold file pages */
112 Elf_progent
*progtab
;
115 Elf_relaent
*relatab
;
121 Elf_Sym
*ddbsymtab
; /* The symbol table we are using */
122 long ddbsymcnt
; /* Number of symbols */
123 caddr_t ddbstrtab
; /* String table */
124 long ddbstrcnt
; /* number of bytes in string table */
126 caddr_t shstrtab
; /* Section name string table */
127 long shstrcnt
; /* number of bytes in string table */
129 caddr_t ctftab
; /* CTF table */
130 long ctfcnt
; /* number of bytes in CTF table */
131 caddr_t ctfoff
; /* CTF offset table */
132 caddr_t typoff
; /* Type offset table */
133 long typlen
; /* Number of type entries. */
137 static int relocate_file(linker_file_t lf
);
140 * The kernel symbol table starts here.
142 extern struct _dynamic _DYNAMIC
;
145 link_elf_obj_init(void *arg
)
147 #if ELF_TARG_CLASS == ELFCLASS32
148 linker_add_class("elf32", NULL
, &link_elf_obj_class_ops
);
150 linker_add_class("elf64", NULL
, &link_elf_obj_class_ops
);
154 SYSINIT(link_elf
, SI_BOOT2_KLD
, SI_ORDER_SECOND
, link_elf_obj_init
, 0);
157 link_elf_obj_error(const char *file
, const char *s
)
159 kprintf("kldload: %s: %s\n", file
, s
);
163 link_elf_obj_preload_file(const char *filename
, linker_file_t
*result
)
168 caddr_t modptr
, baseptr
, sizeptr
;
173 int error
, i
, j
, pb
, ra
, rl
, shstrindex
, symstrindex
, symtabindex
;
176 * Look to see if we have the module preloaded.
178 modptr
= preload_search_by_name(filename
);
182 /* It's preloaded, check we can handle it and collect information */
183 type
= (char *)preload_search_info(modptr
, MODINFO_TYPE
);
184 baseptr
= preload_search_info(modptr
, MODINFO_ADDR
);
185 sizeptr
= preload_search_info(modptr
, MODINFO_SIZE
);
186 hdr
= (Elf_Ehdr
*) preload_search_info(modptr
, MODINFO_METADATA
|
188 shdr
= (Elf_Shdr
*) preload_search_info(modptr
, MODINFO_METADATA
|
191 (strcmp(type
, "elf" __XSTRING(__ELF_WORD_SIZE
) " obj module") != 0 &&
192 strcmp(type
, "elf obj module") != 0)) {
195 if (baseptr
== NULL
|| sizeptr
== NULL
|| hdr
== NULL
|| shdr
== NULL
)
198 ef
= kmalloc(sizeof(struct elf_file
), M_LINKER
, M_WAITOK
| M_ZERO
);
200 ef
->address
= *(caddr_t
*) baseptr
;
202 lf
= linker_make_file(filename
, ef
, &link_elf_obj_file_ops
);
207 lf
->address
= ef
->address
;
208 lf
->size
= *(size_t *) sizeptr
;
210 if (hdr
->e_ident
[EI_CLASS
] != ELF_TARG_CLASS
||
211 hdr
->e_ident
[EI_DATA
] != ELF_TARG_DATA
||
212 hdr
->e_ident
[EI_VERSION
] != EV_CURRENT
||
213 hdr
->e_version
!= EV_CURRENT
||
214 hdr
->e_type
!= ET_REL
||
215 hdr
->e_machine
!= ELF_TARG_MACH
) {
221 /* Scan the section header for information and table sizing. */
224 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
225 switch (shdr
[i
].sh_type
) {
232 symstrindex
= shdr
[i
].sh_link
;
243 shstrindex
= hdr
->e_shstrndx
;
244 if (ef
->nprogtab
== 0 || symstrindex
< 0 ||
245 symstrindex
>= hdr
->e_shnum
||
246 shdr
[symstrindex
].sh_type
!= SHT_STRTAB
|| shstrindex
== 0 ||
247 shstrindex
>= hdr
->e_shnum
||
248 shdr
[shstrindex
].sh_type
!= SHT_STRTAB
) {
252 /* Allocate space for tracking the load chunks */
253 if (ef
->nprogtab
!= 0)
254 ef
->progtab
= kmalloc(ef
->nprogtab
* sizeof(*ef
->progtab
),
255 M_LINKER
, M_WAITOK
| M_ZERO
);
256 if (ef
->nreltab
!= 0)
257 ef
->reltab
= kmalloc(ef
->nreltab
* sizeof(*ef
->reltab
),
258 M_LINKER
, M_WAITOK
| M_ZERO
);
259 if (ef
->nrelatab
!= 0)
260 ef
->relatab
= kmalloc(ef
->nrelatab
* sizeof(*ef
->relatab
),
261 M_LINKER
, M_WAITOK
| M_ZERO
);
262 if ((ef
->nprogtab
!= 0 && ef
->progtab
== NULL
) ||
263 (ef
->nreltab
!= 0 && ef
->reltab
== NULL
) ||
264 (ef
->nrelatab
!= 0 && ef
->relatab
== NULL
)) {
268 /* XXX, relocate the sh_addr fields saved by the loader. */
270 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
271 if (shdr
[i
].sh_addr
!= 0 && (off
== 0 || shdr
[i
].sh_addr
< off
))
272 off
= shdr
[i
].sh_addr
;
274 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
275 if (shdr
[i
].sh_addr
!= 0)
276 shdr
[i
].sh_addr
= shdr
[i
].sh_addr
- off
+
277 (Elf_Addr
) ef
->address
;
280 ef
->ddbsymcnt
= shdr
[symtabindex
].sh_size
/ sizeof(Elf_Sym
);
281 ef
->ddbsymtab
= (Elf_Sym
*) shdr
[symtabindex
].sh_addr
;
282 ef
->ddbstrcnt
= shdr
[symstrindex
].sh_size
;
283 ef
->ddbstrtab
= (char *)shdr
[symstrindex
].sh_addr
;
284 ef
->shstrcnt
= shdr
[shstrindex
].sh_size
;
285 ef
->shstrtab
= (char *)shdr
[shstrindex
].sh_addr
;
287 /* Now fill out progtab and the relocation tables. */
291 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
292 switch (shdr
[i
].sh_type
) {
295 ef
->progtab
[pb
].addr
= (void *)shdr
[i
].sh_addr
;
296 if (shdr
[i
].sh_type
== SHT_PROGBITS
)
297 ef
->progtab
[pb
].name
= "<<PROGBITS>>";
299 ef
->progtab
[pb
].name
= "<<NOBITS>>";
300 ef
->progtab
[pb
].size
= shdr
[i
].sh_size
;
301 ef
->progtab
[pb
].sec
= i
;
302 if (ef
->shstrtab
&& shdr
[i
].sh_name
!= 0)
303 ef
->progtab
[pb
].name
=
304 ef
->shstrtab
+ shdr
[i
].sh_name
;
306 if (ef
->progtab
[pb
].name
!= NULL
&&
307 !strcmp(ef
->progtab
[pb
].name
, "set_pcpu")) {
310 dpcpu
= dpcpu_alloc(shdr
[i
].sh_size
);
315 memcpy(dpcpu
, ef
->progtab
[pb
].addr
,
316 ef
->progtab
[pb
].size
);
317 dpcpu_copy(dpcpu
, shdr
[i
].sh_size
);
318 ef
->progtab
[pb
].addr
= dpcpu
;
320 } else if (ef
->progtab
[pb
].name
!= NULL
&&
321 !strcmp(ef
->progtab
[pb
].name
, VNET_SETNAME
)) {
324 vnet_data
= vnet_data_alloc(shdr
[i
].sh_size
);
325 if (vnet_data
== NULL
) {
329 memcpy(vnet_data
, ef
->progtab
[pb
].addr
,
330 ef
->progtab
[pb
].size
);
331 vnet_data_copy(vnet_data
, shdr
[i
].sh_size
);
332 ef
->progtab
[pb
].addr
= vnet_data
;
336 /* Update all symbol values with the offset. */
337 for (j
= 0; j
< ef
->ddbsymcnt
; j
++) {
338 es
= &ef
->ddbsymtab
[j
];
339 if (es
->st_shndx
!= i
)
341 es
->st_value
+= (Elf_Addr
) ef
->progtab
[pb
].addr
;
346 ef
->reltab
[rl
].rel
= (Elf_Rel
*) shdr
[i
].sh_addr
;
347 ef
->reltab
[rl
].nrel
= shdr
[i
].sh_size
/ sizeof(Elf_Rel
);
348 ef
->reltab
[rl
].sec
= shdr
[i
].sh_info
;
352 ef
->relatab
[ra
].rela
= (Elf_Rela
*) shdr
[i
].sh_addr
;
353 ef
->relatab
[ra
].nrela
=
354 shdr
[i
].sh_size
/ sizeof(Elf_Rela
);
355 ef
->relatab
[ra
].sec
= shdr
[i
].sh_info
;
360 if (pb
!= ef
->nprogtab
)
361 panic("lost progbits");
362 if (rl
!= ef
->nreltab
)
363 panic("lost reltab");
364 if (ra
!= ef
->nrelatab
)
365 panic("lost relatab");
367 /* Local intra-module relocations */
368 link_elf_obj_reloc_local(lf
);
374 /* preload not done this way */
375 linker_file_unload(lf
/* , LINKER_UNLOAD_FORCE */ );
380 link_elf_obj_preload_finish(linker_file_t lf
)
384 error
= relocate_file(lf
);
390 link_elf_obj_load_file(const char *filename
, linker_file_t
* result
)
392 struct nlookupdata nd
;
393 struct thread
*td
= curthread
; /* XXX */
394 struct proc
*p
= td
->td_proc
;
414 /* XXX Hack for firmware loading where p == NULL */
420 if (p
->p_ucred
== NULL
) {
421 kprintf("link_elf_obj_load_file: cannot load '%s' from filesystem"
422 " this early\n", filename
);
429 pathname
= linker_search_path(filename
);
430 if (pathname
== NULL
)
433 error
= nlookup_init(&nd
, pathname
, UIO_SYSSPACE
, NLC_FOLLOW
| NLC_LOCKVP
);
435 error
= vn_open(&nd
, NULL
, FREAD
, 0);
436 kfree(pathname
, M_LINKER
);
442 nd
.nl_open_vp
= NULL
;
446 * Read the elf header from the file.
448 hdr
= kmalloc(sizeof(*hdr
), M_LINKER
, M_WAITOK
);
449 error
= vn_rdwr(UIO_READ
, vp
, (void *)hdr
, sizeof(*hdr
), 0,
450 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
462 if (hdr
->e_ident
[EI_CLASS
] != ELF_TARG_CLASS
463 || hdr
->e_ident
[EI_DATA
] != ELF_TARG_DATA
) {
464 link_elf_obj_error(filename
, "Unsupported file layout");
468 if (hdr
->e_ident
[EI_VERSION
] != EV_CURRENT
469 || hdr
->e_version
!= EV_CURRENT
) {
470 link_elf_obj_error(filename
, "Unsupported file version");
474 if (hdr
->e_type
!= ET_REL
) {
478 if (hdr
->e_machine
!= ELF_TARG_MACH
) {
479 link_elf_obj_error(filename
, "Unsupported machine");
484 ef
= kmalloc(sizeof(struct elf_file
), M_LINKER
, M_WAITOK
| M_ZERO
);
485 lf
= linker_make_file(filename
, ef
, &link_elf_obj_file_ops
);
496 /* Allocate and read in the section header */
497 nbytes
= hdr
->e_shnum
* hdr
->e_shentsize
;
498 if (nbytes
== 0 || hdr
->e_shoff
== 0 ||
499 hdr
->e_shentsize
!= sizeof(Elf_Shdr
)) {
503 shdr
= kmalloc(nbytes
, M_LINKER
, M_WAITOK
);
505 error
= vn_rdwr(UIO_READ
, vp
, (caddr_t
) shdr
, nbytes
, hdr
->e_shoff
,
506 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
513 /* Scan the section header for information and table sizing. */
517 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
518 switch (shdr
[i
].sh_type
) {
526 symstrindex
= shdr
[i
].sh_link
;
538 if (ef
->nprogtab
== 0) {
539 link_elf_obj_error(filename
, "file has no contents");
544 /* Only allow one symbol table for now */
545 link_elf_obj_error(filename
, "file has no valid symbol table");
549 if (symstrindex
< 0 || symstrindex
> hdr
->e_shnum
||
550 shdr
[symstrindex
].sh_type
!= SHT_STRTAB
) {
551 link_elf_obj_error(filename
, "file has invalid symbol strings");
555 /* Allocate space for tracking the load chunks */
556 if (ef
->nprogtab
!= 0)
557 ef
->progtab
= kmalloc(ef
->nprogtab
* sizeof(*ef
->progtab
),
558 M_LINKER
, M_WAITOK
| M_ZERO
);
559 if (ef
->nreltab
!= 0)
560 ef
->reltab
= kmalloc(ef
->nreltab
* sizeof(*ef
->reltab
),
561 M_LINKER
, M_WAITOK
| M_ZERO
);
562 if (ef
->nrelatab
!= 0)
563 ef
->relatab
= kmalloc(ef
->nrelatab
* sizeof(*ef
->relatab
),
564 M_LINKER
, M_WAITOK
| M_ZERO
);
565 if ((ef
->nprogtab
!= 0 && ef
->progtab
== NULL
) ||
566 (ef
->nreltab
!= 0 && ef
->reltab
== NULL
) ||
567 (ef
->nrelatab
!= 0 && ef
->relatab
== NULL
)) {
571 if (symtabindex
== -1)
572 panic("lost symbol table index");
573 /* Allocate space for and load the symbol table */
574 ef
->ddbsymcnt
= shdr
[symtabindex
].sh_size
/ sizeof(Elf_Sym
);
575 ef
->ddbsymtab
= kmalloc(shdr
[symtabindex
].sh_size
, M_LINKER
, M_WAITOK
);
576 error
= vn_rdwr(UIO_READ
, vp
, (void *)ef
->ddbsymtab
,
577 shdr
[symtabindex
].sh_size
, shdr
[symtabindex
].sh_offset
,
578 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
585 if (symstrindex
== -1)
586 panic("lost symbol string index");
587 /* Allocate space for and load the symbol strings */
588 ef
->ddbstrcnt
= shdr
[symstrindex
].sh_size
;
589 ef
->ddbstrtab
= kmalloc(shdr
[symstrindex
].sh_size
, M_LINKER
, M_WAITOK
);
590 error
= vn_rdwr(UIO_READ
, vp
, ef
->ddbstrtab
,
591 shdr
[symstrindex
].sh_size
, shdr
[symstrindex
].sh_offset
,
592 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
599 /* Do we have a string table for the section names? */
601 if (hdr
->e_shstrndx
!= 0 &&
602 shdr
[hdr
->e_shstrndx
].sh_type
== SHT_STRTAB
) {
603 shstrindex
= hdr
->e_shstrndx
;
604 ef
->shstrcnt
= shdr
[shstrindex
].sh_size
;
605 ef
->shstrtab
= kmalloc(shdr
[shstrindex
].sh_size
, M_LINKER
,
607 error
= vn_rdwr(UIO_READ
, vp
, ef
->shstrtab
,
608 shdr
[shstrindex
].sh_size
, shdr
[shstrindex
].sh_offset
,
609 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
617 /* Size up code/data(progbits) and bss(nobits). */
619 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
620 switch (shdr
[i
].sh_type
) {
623 alignmask
= shdr
[i
].sh_addralign
- 1;
626 mapsize
+= alignmask
;
627 mapsize
&= ~alignmask
;
628 mapsize
+= shdr
[i
].sh_size
;
634 * We know how much space we need for the text/data/bss/etc. This
635 * stuff needs to be in a single chunk so that profiling etc can get
636 * the bounds and gdb can associate offsets with modules
638 ef
->object
= vm_object_allocate(OBJT_DEFAULT
,
639 round_page(mapsize
) >> PAGE_SHIFT
);
640 if (ef
->object
== NULL
) {
644 vm_object_hold(ef
->object
);
645 vm_object_reference_locked(ef
->object
);
646 ef
->address
= (caddr_t
) vm_map_min(&kernel_map
);
650 * In order to satisfy x86_64's architectural requirements on the
651 * location of code and data in the kernel's address space, request a
652 * mapping that is above the kernel.
654 * vkernel64's text+data is outside the managed VM space entirely.
656 #if defined(__x86_64__) && defined(_KERNEL_VIRTUAL)
657 error
= vkernel_module_memory_alloc(&mapbase
, round_page(mapsize
));
658 vm_object_drop(ef
->object
);
661 error
= vm_map_find(&kernel_map
, ef
->object
, NULL
,
662 0, &mapbase
, round_page(mapsize
),
664 TRUE
, VM_MAPTYPE_NORMAL
,
665 VM_PROT_ALL
, VM_PROT_ALL
, FALSE
);
666 vm_object_drop(ef
->object
);
668 vm_object_deallocate(ef
->object
);
673 error
= vm_map_wire(&kernel_map
, mapbase
,
674 mapbase
+ round_page(mapsize
), 0);
676 if (error
!= KERN_SUCCESS
) {
680 /* Inform the kld system about the situation */
681 lf
->address
= ef
->address
= (caddr_t
) mapbase
;
682 lf
->size
= round_page(mapsize
);
686 * Now load code/data(progbits), zero bss(nobits), allocate space for
693 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
694 switch (shdr
[i
].sh_type
) {
697 alignmask
= shdr
[i
].sh_addralign
- 1;
700 alignmask
= shdr
[i
].sh_addralign
- 1;
701 mapbase
+= alignmask
;
702 mapbase
&= ~alignmask
;
703 if (ef
->shstrtab
&& shdr
[i
].sh_name
!= 0)
704 ef
->progtab
[pb
].name
=
705 ef
->shstrtab
+ shdr
[i
].sh_name
;
706 else if (shdr
[i
].sh_type
== SHT_PROGBITS
)
707 ef
->progtab
[pb
].name
= "<<PROGBITS>>";
709 ef
->progtab
[pb
].name
= "<<NOBITS>>";
711 if (ef
->progtab
[pb
].name
!= NULL
&&
712 !strcmp(ef
->progtab
[pb
].name
, "set_pcpu"))
713 ef
->progtab
[pb
].addr
=
714 dpcpu_alloc(shdr
[i
].sh_size
);
716 else if (ef
->progtab
[pb
].name
!= NULL
&&
717 !strcmp(ef
->progtab
[pb
].name
, VNET_SETNAME
))
718 ef
->progtab
[pb
].addr
=
719 vnet_data_alloc(shdr
[i
].sh_size
);
723 ef
->progtab
[pb
].addr
=
724 (void *)(uintptr_t) mapbase
;
725 if (ef
->progtab
[pb
].addr
== NULL
) {
729 ef
->progtab
[pb
].size
= shdr
[i
].sh_size
;
730 ef
->progtab
[pb
].sec
= i
;
731 if (shdr
[i
].sh_type
== SHT_PROGBITS
) {
732 error
= vn_rdwr(UIO_READ
, vp
,
733 ef
->progtab
[pb
].addr
,
734 shdr
[i
].sh_size
, shdr
[i
].sh_offset
,
735 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
,
744 /* Initialize the per-cpu or vnet area. */
745 if (ef
->progtab
[pb
].addr
!= (void *)mapbase
&&
746 !strcmp(ef
->progtab
[pb
].name
, "set_pcpu"))
747 dpcpu_copy(ef
->progtab
[pb
].addr
,
750 else if (ef
->progtab
[pb
].addr
!=
752 !strcmp(ef
->progtab
[pb
].name
, VNET_SETNAME
))
753 vnet_data_copy(ef
->progtab
[pb
].addr
,
758 bzero(ef
->progtab
[pb
].addr
, shdr
[i
].sh_size
);
760 /* Update all symbol values with the offset. */
761 for (j
= 0; j
< ef
->ddbsymcnt
; j
++) {
762 es
= &ef
->ddbsymtab
[j
];
763 if (es
->st_shndx
!= i
)
765 es
->st_value
+= (Elf_Addr
) ef
->progtab
[pb
].addr
;
767 mapbase
+= shdr
[i
].sh_size
;
771 ef
->reltab
[rl
].rel
= kmalloc(shdr
[i
].sh_size
, M_LINKER
, M_WAITOK
);
772 ef
->reltab
[rl
].nrel
= shdr
[i
].sh_size
/ sizeof(Elf_Rel
);
773 ef
->reltab
[rl
].sec
= shdr
[i
].sh_info
;
774 error
= vn_rdwr(UIO_READ
, vp
,
775 (void *)ef
->reltab
[rl
].rel
,
776 shdr
[i
].sh_size
, shdr
[i
].sh_offset
,
777 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
787 ef
->relatab
[ra
].rela
= kmalloc(shdr
[i
].sh_size
, M_LINKER
, M_WAITOK
);
788 ef
->relatab
[ra
].nrela
= shdr
[i
].sh_size
/ sizeof(Elf_Rela
);
789 ef
->relatab
[ra
].sec
= shdr
[i
].sh_info
;
790 error
= vn_rdwr(UIO_READ
, vp
,
791 (void *)ef
->relatab
[ra
].rela
,
792 shdr
[i
].sh_size
, shdr
[i
].sh_offset
,
793 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
804 if (pb
!= ef
->nprogtab
)
805 panic("lost progbits");
806 if (rl
!= ef
->nreltab
)
807 panic("lost reltab");
808 if (ra
!= ef
->nrelatab
)
809 panic("lost relatab");
810 if (mapbase
!= (vm_offset_t
) ef
->address
+ mapsize
)
811 panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)",
812 mapbase
, ef
->address
, mapsize
,
813 (vm_offset_t
) ef
->address
+ mapsize
);
815 /* Local intra-module relocations */
816 link_elf_obj_reloc_local(lf
);
818 /* Pull in dependencies */
819 error
= linker_load_dependencies(lf
);
823 /* External relocations */
824 error
= relocate_file(lf
);
832 linker_file_unload(lf
/*, LINKER_UNLOAD_FORCE */);
834 kfree(hdr
, M_LINKER
);
836 vn_close(vp
, FREAD
, NULL
);
842 link_elf_obj_unload_file(linker_file_t file
)
844 elf_file_t ef
= file
->priv
;
848 for (i
= 0; i
< ef
->nprogtab
; i
++) {
849 if (ef
->progtab
[i
].size
== 0)
851 if (ef
->progtab
[i
].name
== NULL
)
854 if (!strcmp(ef
->progtab
[i
].name
, "set_pcpu"))
855 dpcpu_free(ef
->progtab
[i
].addr
,
856 ef
->progtab
[i
].size
);
858 else if (!strcmp(ef
->progtab
[i
].name
, VNET_SETNAME
))
859 vnet_data_free(ef
->progtab
[i
].addr
,
860 ef
->progtab
[i
].size
);
867 kfree(ef
->reltab
, M_LINKER
);
869 kfree(ef
->relatab
, M_LINKER
);
871 kfree(ef
->progtab
, M_LINKER
);
873 kfree(ef
->ctftab
, M_LINKER
);
875 kfree(ef
->ctfoff
, M_LINKER
);
877 kfree(ef
->typoff
, M_LINKER
);
878 if (file
->filename
!= NULL
)
879 preload_delete_name(file
->filename
);
881 /* XXX reclaim module memory? */
885 for (i
= 0; i
< ef
->nreltab
; i
++)
886 if (ef
->reltab
[i
].rel
)
887 kfree(ef
->reltab
[i
].rel
, M_LINKER
);
888 for (i
= 0; i
< ef
->nrelatab
; i
++)
889 if (ef
->relatab
[i
].rela
)
890 kfree(ef
->relatab
[i
].rela
, M_LINKER
);
892 kfree(ef
->reltab
, M_LINKER
);
894 kfree(ef
->relatab
, M_LINKER
);
896 kfree(ef
->progtab
, M_LINKER
);
899 #if defined(__x86_64__) && defined(_KERNEL_VIRTUAL)
900 vkernel_module_memory_free((vm_offset_t
)ef
->address
, ef
->bytes
);
902 vm_map_remove(&kernel_map
, (vm_offset_t
) ef
->address
,
903 (vm_offset_t
) ef
->address
+
904 (ef
->object
->size
<< PAGE_SHIFT
));
906 vm_object_deallocate(ef
->object
);
910 kfree(ef
->e_shdr
, M_LINKER
);
912 kfree(ef
->ddbsymtab
, M_LINKER
);
914 kfree(ef
->ddbstrtab
, M_LINKER
);
916 kfree(ef
->shstrtab
, M_LINKER
);
918 kfree(ef
->ctftab
, M_LINKER
);
920 kfree(ef
->ctfoff
, M_LINKER
);
922 kfree(ef
->typoff
, M_LINKER
);
927 symbol_name(elf_file_t ef
, Elf_Size r_info
)
931 if (ELF_R_SYM(r_info
)) {
932 ref
= ef
->ddbsymtab
+ ELF_R_SYM(r_info
);
933 return ef
->ddbstrtab
+ ref
->st_name
;
939 findbase(elf_file_t ef
, int sec
)
944 for (i
= 0; i
< ef
->nprogtab
; i
++) {
945 if (sec
== ef
->progtab
[i
].sec
) {
946 base
= (Elf_Addr
)ef
->progtab
[i
].addr
;
954 relocate_file(linker_file_t lf
)
956 elf_file_t ef
= lf
->priv
;
957 const Elf_Rel
*rellim
;
959 const Elf_Rela
*relalim
;
960 const Elf_Rela
*rela
;
967 /* Perform relocations without addend if there are any: */
968 for (i
= 0; i
< ef
->nreltab
; i
++) {
969 rel
= ef
->reltab
[i
].rel
;
971 panic("lost a reltab!");
972 rellim
= rel
+ ef
->reltab
[i
].nrel
;
973 base
= findbase(ef
, ef
->reltab
[i
].sec
);
975 panic("lost base for reltab");
976 for ( ; rel
< rellim
; rel
++) {
977 symidx
= ELF_R_SYM(rel
->r_info
);
978 if (symidx
>= ef
->ddbsymcnt
)
980 sym
= ef
->ddbsymtab
+ symidx
;
981 /* Local relocs are already done */
982 if (ELF_ST_BIND(sym
->st_info
) == STB_LOCAL
)
984 if (elf_reloc(lf
, base
, rel
, ELF_RELOC_REL
,
986 symname
= symbol_name(ef
, rel
->r_info
);
987 kprintf("link_elf_obj_obj: symbol %s undefined\n",
994 /* Perform relocations with addend if there are any: */
995 for (i
= 0; i
< ef
->nrelatab
; i
++) {
996 rela
= ef
->relatab
[i
].rela
;
998 panic("lost a relatab!");
999 relalim
= rela
+ ef
->relatab
[i
].nrela
;
1000 base
= findbase(ef
, ef
->relatab
[i
].sec
);
1002 panic("lost base for relatab");
1003 for ( ; rela
< relalim
; rela
++) {
1004 symidx
= ELF_R_SYM(rela
->r_info
);
1005 if (symidx
>= ef
->ddbsymcnt
)
1007 sym
= ef
->ddbsymtab
+ symidx
;
1008 /* Local relocs are already done */
1009 if (ELF_ST_BIND(sym
->st_info
) == STB_LOCAL
)
1011 if (elf_reloc(lf
, base
, rela
, ELF_RELOC_RELA
,
1013 symname
= symbol_name(ef
, rela
->r_info
);
1014 kprintf("link_elf_obj_obj: symbol %s undefined\n",
1025 link_elf_obj_lookup_symbol(linker_file_t lf
, const char *name
, c_linker_sym_t
*sym
)
1027 elf_file_t ef
= lf
->priv
;
1028 const Elf_Sym
*symp
;
1032 for (i
= 0, symp
= ef
->ddbsymtab
; i
< ef
->ddbsymcnt
; i
++, symp
++) {
1033 strp
= ef
->ddbstrtab
+ symp
->st_name
;
1034 if (symp
->st_shndx
!= SHN_UNDEF
&& strcmp(name
, strp
) == 0) {
1035 *sym
= (c_linker_sym_t
) symp
;
1043 link_elf_obj_symbol_values(linker_file_t lf
, c_linker_sym_t sym
,
1044 linker_symval_t
*symval
)
1046 elf_file_t ef
= lf
->priv
;
1047 const Elf_Sym
*es
= (const Elf_Sym
*) sym
;
1049 if (es
>= ef
->ddbsymtab
&& es
< (ef
->ddbsymtab
+ ef
->ddbsymcnt
)) {
1050 symval
->name
= ef
->ddbstrtab
+ es
->st_name
;
1051 symval
->value
= (caddr_t
)es
->st_value
;
1052 symval
->size
= es
->st_size
;
1059 link_elf_obj_search_symbol(linker_file_t lf
, caddr_t value
,
1060 c_linker_sym_t
*sym
, long *diffp
)
1062 elf_file_t ef
= lf
->priv
;
1063 u_long off
= (uintptr_t) (void *) value
;
1067 const Elf_Sym
*best
= NULL
;
1070 for (i
= 0, es
= ef
->ddbsymtab
; i
< ef
->ddbsymcnt
; i
++, es
++) {
1071 if (es
->st_name
== 0)
1073 st_value
= es
->st_value
;
1074 if (off
>= st_value
) {
1075 if (off
- st_value
< diff
) {
1076 diff
= off
- st_value
;
1080 } else if (off
- st_value
== diff
) {
1089 *sym
= (c_linker_sym_t
) best
;
1095 * Look up a linker set on an ELF system.
1098 link_elf_obj_lookup_set(linker_file_t lf
, const char *name
,
1099 void ***startp
, void ***stopp
, int *countp
)
1101 elf_file_t ef
= lf
->priv
;
1102 void **start
, **stop
;
1105 /* Relative to section number */
1106 for (i
= 0; i
< ef
->nprogtab
; i
++) {
1107 if ((strncmp(ef
->progtab
[i
].name
, "set_", 4) == 0) &&
1108 strcmp(ef
->progtab
[i
].name
+ 4, name
) == 0) {
1109 start
= (void **)ef
->progtab
[i
].addr
;
1110 stop
= (void **)((char *)ef
->progtab
[i
].addr
+
1111 ef
->progtab
[i
].size
);
1112 count
= stop
- start
;
1126 * Symbol lookup function that can be used when the symbol index is known (ie
1127 * in relocations). It uses the symbol index instead of doing a fully fledged
1128 * hash table based lookup when such is valid. For example for local symbols.
1129 * This is not only more efficient, it's also more correct. It's not always
1130 * the case that the symbol can be found through the hash table.
1133 elf_obj_lookup(linker_file_t lf
, Elf_Size symidx
, int deps
, Elf_Addr
*result
)
1135 elf_file_t ef
= lf
->priv
;
1139 /* Don't even try to lookup the symbol if the index is bogus. */
1140 if (symidx
>= ef
->ddbsymcnt
)
1143 sym
= ef
->ddbsymtab
+ symidx
;
1145 /* Quick answer if there is a definition included. */
1146 if (sym
->st_shndx
!= SHN_UNDEF
) {
1147 *result
= sym
->st_value
;
1151 /* If we get here, then it is undefined and needs a lookup. */
1152 switch (ELF_ST_BIND(sym
->st_info
)) {
1154 /* Local, but undefined? huh? */
1158 /* Relative to Data or Function name */
1159 symbol
= ef
->ddbstrtab
+ sym
->st_name
;
1161 /* Force a lookup failure if the symbol name is bogus. */
1164 return (linker_file_lookup_symbol(lf
, symbol
, deps
, (caddr_t
*)result
));
1167 kprintf("link_elf_obj_obj: Weak symbols not supported\n");
1176 link_elf_obj_fix_link_set(elf_file_t ef
)
1178 static const char startn
[] = "__start_";
1179 static const char stopn
[] = "__stop_";
1181 const char *sym_name
, *linkset_name
;
1182 Elf_Addr startp
, stopp
;
1187 for (symidx
= 1 /* zero entry is special */;
1188 symidx
< ef
->ddbsymcnt
; symidx
++) {
1189 sym
= ef
->ddbsymtab
+ symidx
;
1190 if (sym
->st_shndx
!= SHN_UNDEF
)
1193 sym_name
= ef
->ddbstrtab
+ sym
->st_name
;
1194 if (strncmp(sym_name
, startn
, sizeof(startn
) - 1) == 0) {
1196 linkset_name
= sym_name
+ sizeof(startn
) - 1;
1198 else if (strncmp(sym_name
, stopn
, sizeof(stopn
) - 1) == 0) {
1200 linkset_name
= sym_name
+ sizeof(stopn
) - 1;
1205 for (i
= 0; i
< ef
->nprogtab
; i
++) {
1206 if (strcmp(ef
->progtab
[i
].name
, linkset_name
) == 0) {
1207 startp
= (Elf_Addr
)ef
->progtab
[i
].addr
;
1208 stopp
= (Elf_Addr
)(startp
+ ef
->progtab
[i
].size
);
1212 if (i
== ef
->nprogtab
)
1215 sym
->st_value
= start
? startp
: stopp
;
1221 link_elf_obj_reloc_local(linker_file_t lf
)
1223 elf_file_t ef
= lf
->priv
;
1224 const Elf_Rel
*rellim
;
1226 const Elf_Rela
*relalim
;
1227 const Elf_Rela
*rela
;
1233 link_elf_obj_fix_link_set(ef
);
1235 /* Perform relocations without addend if there are any: */
1236 for (i
= 0; i
< ef
->nreltab
; i
++) {
1237 rel
= ef
->reltab
[i
].rel
;
1239 panic("lost a reltab!");
1240 rellim
= rel
+ ef
->reltab
[i
].nrel
;
1241 base
= findbase(ef
, ef
->reltab
[i
].sec
);
1243 panic("lost base for reltab");
1244 for ( ; rel
< rellim
; rel
++) {
1245 symidx
= ELF_R_SYM(rel
->r_info
);
1246 if (symidx
>= ef
->ddbsymcnt
)
1248 sym
= ef
->ddbsymtab
+ symidx
;
1249 /* Only do local relocs */
1250 if (ELF_ST_BIND(sym
->st_info
) != STB_LOCAL
)
1252 elf_reloc_local(lf
, base
, rel
, ELF_RELOC_REL
,
1257 /* Perform relocations with addend if there are any: */
1258 for (i
= 0; i
< ef
->nrelatab
; i
++) {
1259 rela
= ef
->relatab
[i
].rela
;
1261 panic("lost a relatab!");
1262 relalim
= rela
+ ef
->relatab
[i
].nrela
;
1263 base
= findbase(ef
, ef
->relatab
[i
].sec
);
1265 panic("lost base for relatab");
1266 for ( ; rela
< relalim
; rela
++) {
1267 symidx
= ELF_R_SYM(rela
->r_info
);
1268 if (symidx
>= ef
->ddbsymcnt
)
1270 sym
= ef
->ddbsymtab
+ symidx
;
1271 /* Only do local relocs */
1272 if (ELF_ST_BIND(sym
->st_info
) != STB_LOCAL
)
1274 elf_reloc_local(lf
, base
, rela
, ELF_RELOC_RELA
,