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 $
28 * $DragonFly: src/sys/kern/link_elf.c,v 1.29 2008/08/01 23:11:16 dillon Exp $
31 #include <sys/param.h>
32 #include <sys/kernel.h>
33 #include <sys/systm.h>
34 #include <sys/malloc.h>
36 #include <sys/nlookup.h>
37 #include <sys/fcntl.h>
38 #include <sys/vnode.h>
39 #include <sys/linker.h>
40 #include <machine/elf.h>
43 #include <vm/vm_param.h>
44 #include <vm/vm_zone.h>
45 #include <vm/vm_object.h>
46 #include <vm/vm_kern.h>
47 #include <vm/vm_extern.h>
50 #include <vm/vm_map.h>
52 static int link_elf_obj_preload_file(const char *, linker_file_t
*);
53 static int link_elf_obj_preload_finish(linker_file_t
);
54 static int link_elf_obj_load_file(const char *, linker_file_t
*);
56 link_elf_obj_lookup_symbol(linker_file_t
, const char *,
58 static int link_elf_obj_symbol_values(linker_file_t
, c_linker_sym_t
, linker_symval_t
*);
60 link_elf_obj_search_symbol(linker_file_t
, caddr_t value
,
61 c_linker_sym_t
* sym
, long *diffp
);
63 static void link_elf_obj_unload_file(linker_file_t
);
65 link_elf_obj_lookup_set(linker_file_t
, const char *,
66 void ***, void ***, int *);
67 static void link_elf_obj_reloc_local(linker_file_t lf
);
68 static int elf_obj_lookup(linker_file_t lf
, Elf_Size symidx
, int deps
, Elf_Addr
*);
70 static struct linker_class_ops link_elf_obj_class_ops
= {
71 link_elf_obj_load_file
,
72 link_elf_obj_preload_file
,
75 static struct linker_file_ops link_elf_obj_file_ops
= {
76 .lookup_symbol
= link_elf_obj_lookup_symbol
,
77 .symbol_values
= link_elf_obj_symbol_values
,
78 .search_symbol
= link_elf_obj_search_symbol
,
79 .preload_finish
= link_elf_obj_preload_finish
,
80 .unload
= link_elf_obj_unload_file
,
81 .lookup_set
= link_elf_obj_lookup_set
,
88 int sec
; /* Original section */
105 typedef struct elf_file
{
108 caddr_t address
; /* Relocation address */
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
;
201 lf
= linker_make_file(filename
, ef
, &link_elf_obj_file_ops
);
206 lf
->address
= ef
->address
;
207 lf
->size
= *(size_t *) sizeptr
;
209 if (hdr
->e_ident
[EI_CLASS
] != ELF_TARG_CLASS
||
210 hdr
->e_ident
[EI_DATA
] != ELF_TARG_DATA
||
211 hdr
->e_ident
[EI_VERSION
] != EV_CURRENT
||
212 hdr
->e_version
!= EV_CURRENT
||
213 hdr
->e_type
!= ET_REL
||
214 hdr
->e_machine
!= ELF_TARG_MACH
) {
220 /* Scan the section header for information and table sizing. */
223 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
224 switch (shdr
[i
].sh_type
) {
231 symstrindex
= shdr
[i
].sh_link
;
242 shstrindex
= hdr
->e_shstrndx
;
243 if (ef
->nprogtab
== 0 || symstrindex
< 0 ||
244 symstrindex
>= hdr
->e_shnum
||
245 shdr
[symstrindex
].sh_type
!= SHT_STRTAB
|| shstrindex
== 0 ||
246 shstrindex
>= hdr
->e_shnum
||
247 shdr
[shstrindex
].sh_type
!= SHT_STRTAB
) {
251 /* Allocate space for tracking the load chunks */
252 if (ef
->nprogtab
!= 0)
253 ef
->progtab
= kmalloc(ef
->nprogtab
* sizeof(*ef
->progtab
),
254 M_LINKER
, M_WAITOK
| M_ZERO
);
255 if (ef
->nreltab
!= 0)
256 ef
->reltab
= kmalloc(ef
->nreltab
* sizeof(*ef
->reltab
),
257 M_LINKER
, M_WAITOK
| M_ZERO
);
258 if (ef
->nrelatab
!= 0)
259 ef
->relatab
= kmalloc(ef
->nrelatab
* sizeof(*ef
->relatab
),
260 M_LINKER
, M_WAITOK
| M_ZERO
);
261 if ((ef
->nprogtab
!= 0 && ef
->progtab
== NULL
) ||
262 (ef
->nreltab
!= 0 && ef
->reltab
== NULL
) ||
263 (ef
->nrelatab
!= 0 && ef
->relatab
== NULL
)) {
267 /* XXX, relocate the sh_addr fields saved by the loader. */
269 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
270 if (shdr
[i
].sh_addr
!= 0 && (off
== 0 || shdr
[i
].sh_addr
< off
))
271 off
= shdr
[i
].sh_addr
;
273 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
274 if (shdr
[i
].sh_addr
!= 0)
275 shdr
[i
].sh_addr
= shdr
[i
].sh_addr
- off
+
276 (Elf_Addr
) ef
->address
;
279 ef
->ddbsymcnt
= shdr
[symtabindex
].sh_size
/ sizeof(Elf_Sym
);
280 ef
->ddbsymtab
= (Elf_Sym
*) shdr
[symtabindex
].sh_addr
;
281 ef
->ddbstrcnt
= shdr
[symstrindex
].sh_size
;
282 ef
->ddbstrtab
= (char *)shdr
[symstrindex
].sh_addr
;
283 ef
->shstrcnt
= shdr
[shstrindex
].sh_size
;
284 ef
->shstrtab
= (char *)shdr
[shstrindex
].sh_addr
;
286 /* Now fill out progtab and the relocation tables. */
290 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
291 switch (shdr
[i
].sh_type
) {
294 ef
->progtab
[pb
].addr
= (void *)shdr
[i
].sh_addr
;
295 if (shdr
[i
].sh_type
== SHT_PROGBITS
)
296 ef
->progtab
[pb
].name
= "<<PROGBITS>>";
298 ef
->progtab
[pb
].name
= "<<NOBITS>>";
299 ef
->progtab
[pb
].size
= shdr
[i
].sh_size
;
300 ef
->progtab
[pb
].sec
= i
;
301 if (ef
->shstrtab
&& shdr
[i
].sh_name
!= 0)
302 ef
->progtab
[pb
].name
=
303 ef
->shstrtab
+ shdr
[i
].sh_name
;
305 if (ef
->progtab
[pb
].name
!= NULL
&&
306 !strcmp(ef
->progtab
[pb
].name
, "set_pcpu")) {
309 dpcpu
= dpcpu_alloc(shdr
[i
].sh_size
);
314 memcpy(dpcpu
, ef
->progtab
[pb
].addr
,
315 ef
->progtab
[pb
].size
);
316 dpcpu_copy(dpcpu
, shdr
[i
].sh_size
);
317 ef
->progtab
[pb
].addr
= dpcpu
;
319 } else if (ef
->progtab
[pb
].name
!= NULL
&&
320 !strcmp(ef
->progtab
[pb
].name
, VNET_SETNAME
)) {
323 vnet_data
= vnet_data_alloc(shdr
[i
].sh_size
);
324 if (vnet_data
== NULL
) {
328 memcpy(vnet_data
, ef
->progtab
[pb
].addr
,
329 ef
->progtab
[pb
].size
);
330 vnet_data_copy(vnet_data
, shdr
[i
].sh_size
);
331 ef
->progtab
[pb
].addr
= vnet_data
;
335 /* Update all symbol values with the offset. */
336 for (j
= 0; j
< ef
->ddbsymcnt
; j
++) {
337 es
= &ef
->ddbsymtab
[j
];
338 if (es
->st_shndx
!= i
)
340 es
->st_value
+= (Elf_Addr
) ef
->progtab
[pb
].addr
;
345 ef
->reltab
[rl
].rel
= (Elf_Rel
*) shdr
[i
].sh_addr
;
346 ef
->reltab
[rl
].nrel
= shdr
[i
].sh_size
/ sizeof(Elf_Rel
);
347 ef
->reltab
[rl
].sec
= shdr
[i
].sh_info
;
351 ef
->relatab
[ra
].rela
= (Elf_Rela
*) shdr
[i
].sh_addr
;
352 ef
->relatab
[ra
].nrela
=
353 shdr
[i
].sh_size
/ sizeof(Elf_Rela
);
354 ef
->relatab
[ra
].sec
= shdr
[i
].sh_info
;
359 if (pb
!= ef
->nprogtab
)
360 panic("lost progbits");
361 if (rl
!= ef
->nreltab
)
362 panic("lost reltab");
363 if (ra
!= ef
->nrelatab
)
364 panic("lost relatab");
366 /* Local intra-module relocations */
367 link_elf_obj_reloc_local(lf
);
373 /* preload not done this way */
374 linker_file_unload(lf
/* , LINKER_UNLOAD_FORCE */ );
379 link_elf_obj_preload_finish(linker_file_t lf
)
383 error
= relocate_file(lf
);
389 link_elf_obj_load_file(const char *filename
, linker_file_t
* result
)
391 struct nlookupdata nd
;
392 struct thread
*td
= curthread
; /* XXX */
393 struct proc
*p
= td
->td_proc
;
414 if (p
->p_ucred
== NULL
) {
415 kprintf("link_elf_obj_load_file: cannot load '%s' from filesystem"
416 " this early\n", filename
);
423 pathname
= linker_search_path(filename
);
424 if (pathname
== NULL
)
427 error
= nlookup_init(&nd
, pathname
, UIO_SYSSPACE
, NLC_FOLLOW
| NLC_LOCKVP
);
429 error
= vn_open(&nd
, NULL
, FREAD
, 0);
430 kfree(pathname
, M_LINKER
);
436 nd
.nl_open_vp
= NULL
;
440 * Read the elf header from the file.
442 hdr
= kmalloc(sizeof(*hdr
), M_LINKER
, M_WAITOK
);
447 error
= vn_rdwr(UIO_READ
, vp
, (void *)hdr
, sizeof(*hdr
), 0,
448 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
460 if (hdr
->e_ident
[EI_CLASS
] != ELF_TARG_CLASS
461 || hdr
->e_ident
[EI_DATA
] != ELF_TARG_DATA
) {
462 link_elf_obj_error(filename
, "Unsupported file layout");
466 if (hdr
->e_ident
[EI_VERSION
] != EV_CURRENT
467 || hdr
->e_version
!= EV_CURRENT
) {
468 link_elf_obj_error(filename
, "Unsupported file version");
472 if (hdr
->e_type
!= ET_REL
) {
476 if (hdr
->e_machine
!= ELF_TARG_MACH
) {
477 link_elf_obj_error(filename
, "Unsupported machine");
482 ef
= kmalloc(sizeof(struct elf_file
), M_LINKER
, M_WAITOK
| M_ZERO
);
483 lf
= linker_make_file(filename
, ef
, &link_elf_obj_file_ops
);
494 /* Allocate and read in the section header */
495 nbytes
= hdr
->e_shnum
* hdr
->e_shentsize
;
496 if (nbytes
== 0 || hdr
->e_shoff
== 0 ||
497 hdr
->e_shentsize
!= sizeof(Elf_Shdr
)) {
501 shdr
= kmalloc(nbytes
, M_LINKER
, M_WAITOK
);
507 error
= vn_rdwr(UIO_READ
, vp
, (caddr_t
) shdr
, nbytes
, hdr
->e_shoff
,
508 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
515 /* Scan the section header for information and table sizing. */
519 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
520 switch (shdr
[i
].sh_type
) {
528 symstrindex
= shdr
[i
].sh_link
;
540 if (ef
->nprogtab
== 0) {
541 link_elf_obj_error(filename
, "file has no contents");
546 /* Only allow one symbol table for now */
547 link_elf_obj_error(filename
, "file has no valid symbol table");
551 if (symstrindex
< 0 || symstrindex
> hdr
->e_shnum
||
552 shdr
[symstrindex
].sh_type
!= SHT_STRTAB
) {
553 link_elf_obj_error(filename
, "file has invalid symbol strings");
557 /* Allocate space for tracking the load chunks */
558 if (ef
->nprogtab
!= 0)
559 ef
->progtab
= kmalloc(ef
->nprogtab
* sizeof(*ef
->progtab
),
560 M_LINKER
, M_WAITOK
| M_ZERO
);
561 if (ef
->nreltab
!= 0)
562 ef
->reltab
= kmalloc(ef
->nreltab
* sizeof(*ef
->reltab
),
563 M_LINKER
, M_WAITOK
| M_ZERO
);
564 if (ef
->nrelatab
!= 0)
565 ef
->relatab
= kmalloc(ef
->nrelatab
* sizeof(*ef
->relatab
),
566 M_LINKER
, M_WAITOK
| M_ZERO
);
567 if ((ef
->nprogtab
!= 0 && ef
->progtab
== NULL
) ||
568 (ef
->nreltab
!= 0 && ef
->reltab
== NULL
) ||
569 (ef
->nrelatab
!= 0 && ef
->relatab
== NULL
)) {
573 if (symtabindex
== -1)
574 panic("lost symbol table index");
575 /* Allocate space for and load the symbol table */
576 ef
->ddbsymcnt
= shdr
[symtabindex
].sh_size
/ sizeof(Elf_Sym
);
577 ef
->ddbsymtab
= kmalloc(shdr
[symtabindex
].sh_size
, M_LINKER
, M_WAITOK
);
578 if (ef
->ddbsymtab
== NULL
) {
582 error
= vn_rdwr(UIO_READ
, vp
, (void *)ef
->ddbsymtab
,
583 shdr
[symtabindex
].sh_size
, shdr
[symtabindex
].sh_offset
,
584 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
591 if (symstrindex
== -1)
592 panic("lost symbol string index");
593 /* Allocate space for and load the symbol strings */
594 ef
->ddbstrcnt
= shdr
[symstrindex
].sh_size
;
595 ef
->ddbstrtab
= kmalloc(shdr
[symstrindex
].sh_size
, M_LINKER
, M_WAITOK
);
596 if (ef
->ddbstrtab
== NULL
) {
600 error
= vn_rdwr(UIO_READ
, vp
, ef
->ddbstrtab
,
601 shdr
[symstrindex
].sh_size
, shdr
[symstrindex
].sh_offset
,
602 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
609 /* Do we have a string table for the section names? */
611 if (hdr
->e_shstrndx
!= 0 &&
612 shdr
[hdr
->e_shstrndx
].sh_type
== SHT_STRTAB
) {
613 shstrindex
= hdr
->e_shstrndx
;
614 ef
->shstrcnt
= shdr
[shstrindex
].sh_size
;
615 ef
->shstrtab
= kmalloc(shdr
[shstrindex
].sh_size
, M_LINKER
,
617 if (ef
->shstrtab
== NULL
) {
621 error
= vn_rdwr(UIO_READ
, vp
, ef
->shstrtab
,
622 shdr
[shstrindex
].sh_size
, shdr
[shstrindex
].sh_offset
,
623 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
631 /* Size up code/data(progbits) and bss(nobits). */
633 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
634 switch (shdr
[i
].sh_type
) {
637 alignmask
= shdr
[i
].sh_addralign
- 1;
638 mapsize
+= alignmask
;
639 mapsize
&= ~alignmask
;
640 mapsize
+= shdr
[i
].sh_size
;
646 * We know how much space we need for the text/data/bss/etc. This
647 * stuff needs to be in a single chunk so that profiling etc can get
648 * the bounds and gdb can associate offsets with modules
650 ef
->object
= vm_object_allocate(OBJT_DEFAULT
,
651 round_page(mapsize
) >> PAGE_SHIFT
);
652 if (ef
->object
== NULL
) {
656 ef
->address
= (caddr_t
) vm_map_min(&kernel_map
);
659 * In order to satisfy x86_64's architectural requirements on the
660 * location of code and data in the kernel's address space, request a
661 * mapping that is above the kernel.
664 error
= vm_map_find(&kernel_map
, ef
->object
, 0, &mapbase
,
665 round_page(mapsize
), TRUE
, VM_MAPTYPE_NORMAL
,
666 VM_PROT_ALL
, VM_PROT_ALL
, FALSE
);
668 vm_object_deallocate(ef
->object
);
673 error
= vm_map_wire(&kernel_map
, mapbase
,
674 mapbase
+ round_page(mapsize
), 0);
675 if (error
!= KERN_SUCCESS
) {
679 /* Inform the kld system about the situation */
680 lf
->address
= ef
->address
= (caddr_t
) mapbase
;
684 * Now load code/data(progbits), zero bss(nobits), allocate space for
691 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
692 switch (shdr
[i
].sh_type
) {
695 alignmask
= shdr
[i
].sh_addralign
- 1;
696 mapbase
+= alignmask
;
697 mapbase
&= ~alignmask
;
698 if (ef
->shstrtab
&& shdr
[i
].sh_name
!= 0)
699 ef
->progtab
[pb
].name
=
700 ef
->shstrtab
+ shdr
[i
].sh_name
;
701 else if (shdr
[i
].sh_type
== SHT_PROGBITS
)
702 ef
->progtab
[pb
].name
= "<<PROGBITS>>";
704 ef
->progtab
[pb
].name
= "<<NOBITS>>";
706 if (ef
->progtab
[pb
].name
!= NULL
&&
707 !strcmp(ef
->progtab
[pb
].name
, "set_pcpu"))
708 ef
->progtab
[pb
].addr
=
709 dpcpu_alloc(shdr
[i
].sh_size
);
711 else if (ef
->progtab
[pb
].name
!= NULL
&&
712 !strcmp(ef
->progtab
[pb
].name
, VNET_SETNAME
))
713 ef
->progtab
[pb
].addr
=
714 vnet_data_alloc(shdr
[i
].sh_size
);
718 ef
->progtab
[pb
].addr
=
719 (void *)(uintptr_t) mapbase
;
720 if (ef
->progtab
[pb
].addr
== NULL
) {
724 ef
->progtab
[pb
].size
= shdr
[i
].sh_size
;
725 ef
->progtab
[pb
].sec
= i
;
726 if (shdr
[i
].sh_type
== SHT_PROGBITS
) {
727 error
= vn_rdwr(UIO_READ
, vp
,
728 ef
->progtab
[pb
].addr
,
729 shdr
[i
].sh_size
, shdr
[i
].sh_offset
,
730 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
,
739 /* Initialize the per-cpu or vnet area. */
740 if (ef
->progtab
[pb
].addr
!= (void *)mapbase
&&
741 !strcmp(ef
->progtab
[pb
].name
, "set_pcpu"))
742 dpcpu_copy(ef
->progtab
[pb
].addr
,
745 else if (ef
->progtab
[pb
].addr
!=
747 !strcmp(ef
->progtab
[pb
].name
, VNET_SETNAME
))
748 vnet_data_copy(ef
->progtab
[pb
].addr
,
753 bzero(ef
->progtab
[pb
].addr
, shdr
[i
].sh_size
);
755 /* Update all symbol values with the offset. */
756 for (j
= 0; j
< ef
->ddbsymcnt
; j
++) {
757 es
= &ef
->ddbsymtab
[j
];
758 if (es
->st_shndx
!= i
)
760 es
->st_value
+= (Elf_Addr
) ef
->progtab
[pb
].addr
;
762 mapbase
+= shdr
[i
].sh_size
;
766 ef
->reltab
[rl
].rel
= kmalloc(shdr
[i
].sh_size
, M_LINKER
, M_WAITOK
);
767 ef
->reltab
[rl
].nrel
= shdr
[i
].sh_size
/ sizeof(Elf_Rel
);
768 ef
->reltab
[rl
].sec
= shdr
[i
].sh_info
;
769 error
= vn_rdwr(UIO_READ
, vp
,
770 (void *)ef
->reltab
[rl
].rel
,
771 shdr
[i
].sh_size
, shdr
[i
].sh_offset
,
772 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
782 ef
->relatab
[ra
].rela
= kmalloc(shdr
[i
].sh_size
, M_LINKER
, M_WAITOK
);
783 ef
->relatab
[ra
].nrela
= shdr
[i
].sh_size
/ sizeof(Elf_Rela
);
784 ef
->relatab
[ra
].sec
= shdr
[i
].sh_info
;
785 error
= vn_rdwr(UIO_READ
, vp
,
786 (void *)ef
->relatab
[ra
].rela
,
787 shdr
[i
].sh_size
, shdr
[i
].sh_offset
,
788 UIO_SYSSPACE
, IO_NODELOCKED
, p
->p_ucred
, &resid
);
799 if (pb
!= ef
->nprogtab
)
800 panic("lost progbits");
801 if (rl
!= ef
->nreltab
)
802 panic("lost reltab");
803 if (ra
!= ef
->nrelatab
)
804 panic("lost relatab");
805 if (mapbase
!= (vm_offset_t
) ef
->address
+ mapsize
)
806 panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n",
807 mapbase
, ef
->address
, mapsize
,
808 (vm_offset_t
) ef
->address
+ mapsize
);
810 /* Local intra-module relocations */
811 link_elf_obj_reloc_local(lf
);
813 /* Pull in dependencies */
814 error
= linker_load_dependencies(lf
);
818 /* External relocations */
819 error
= relocate_file(lf
);
827 linker_file_unload(lf
/*, LINKER_UNLOAD_FORCE */);
829 kfree(hdr
, M_LINKER
);
837 link_elf_obj_unload_file(linker_file_t file
)
839 elf_file_t ef
= file
->priv
;
843 for (i
= 0; i
< ef
->nprogtab
; i
++) {
844 if (ef
->progtab
[i
].size
== 0)
846 if (ef
->progtab
[i
].name
== NULL
)
849 if (!strcmp(ef
->progtab
[i
].name
, "set_pcpu"))
850 dpcpu_free(ef
->progtab
[i
].addr
,
851 ef
->progtab
[i
].size
);
853 else if (!strcmp(ef
->progtab
[i
].name
, VNET_SETNAME
))
854 vnet_data_free(ef
->progtab
[i
].addr
,
855 ef
->progtab
[i
].size
);
862 kfree(ef
->reltab
, M_LINKER
);
864 kfree(ef
->relatab
, M_LINKER
);
866 kfree(ef
->progtab
, M_LINKER
);
868 kfree(ef
->ctftab
, M_LINKER
);
870 kfree(ef
->ctfoff
, M_LINKER
);
872 kfree(ef
->typoff
, M_LINKER
);
873 if (file
->filename
!= NULL
)
874 preload_delete_name(file
->filename
);
876 /* XXX reclaim module memory? */
880 for (i
= 0; i
< ef
->nreltab
; i
++)
881 if (ef
->reltab
[i
].rel
)
882 kfree(ef
->reltab
[i
].rel
, M_LINKER
);
883 for (i
= 0; i
< ef
->nrelatab
; i
++)
884 if (ef
->relatab
[i
].rela
)
885 kfree(ef
->relatab
[i
].rela
, M_LINKER
);
887 kfree(ef
->reltab
, M_LINKER
);
889 kfree(ef
->relatab
, M_LINKER
);
891 kfree(ef
->progtab
, M_LINKER
);
894 vm_map_remove(&kernel_map
, (vm_offset_t
) ef
->address
,
895 (vm_offset_t
) ef
->address
+
896 (ef
->object
->size
<< PAGE_SHIFT
));
899 kfree(ef
->e_shdr
, M_LINKER
);
901 kfree(ef
->ddbsymtab
, M_LINKER
);
903 kfree(ef
->ddbstrtab
, M_LINKER
);
905 kfree(ef
->shstrtab
, M_LINKER
);
907 kfree(ef
->ctftab
, M_LINKER
);
909 kfree(ef
->ctfoff
, M_LINKER
);
911 kfree(ef
->typoff
, M_LINKER
);
916 symbol_name(elf_file_t ef
, Elf_Size r_info
)
920 if (ELF_R_SYM(r_info
)) {
921 ref
= ef
->ddbsymtab
+ ELF_R_SYM(r_info
);
922 return ef
->ddbstrtab
+ ref
->st_name
;
928 findbase(elf_file_t ef
, int sec
)
933 for (i
= 0; i
< ef
->nprogtab
; i
++) {
934 if (sec
== ef
->progtab
[i
].sec
) {
935 base
= (Elf_Addr
)ef
->progtab
[i
].addr
;
943 relocate_file(linker_file_t lf
)
945 elf_file_t ef
= lf
->priv
;
946 const Elf_Rel
*rellim
;
948 const Elf_Rela
*relalim
;
949 const Elf_Rela
*rela
;
956 /* Perform relocations without addend if there are any: */
957 for (i
= 0; i
< ef
->nreltab
; i
++) {
958 rel
= ef
->reltab
[i
].rel
;
960 panic("lost a reltab!");
961 rellim
= rel
+ ef
->reltab
[i
].nrel
;
962 base
= findbase(ef
, ef
->reltab
[i
].sec
);
964 panic("lost base for reltab");
965 for ( ; rel
< rellim
; rel
++) {
966 symidx
= ELF_R_SYM(rel
->r_info
);
967 if (symidx
>= ef
->ddbsymcnt
)
969 sym
= ef
->ddbsymtab
+ symidx
;
970 /* Local relocs are already done */
971 if (ELF_ST_BIND(sym
->st_info
) == STB_LOCAL
)
973 if (elf_reloc(lf
, base
, rel
, ELF_RELOC_REL
,
975 symname
= symbol_name(ef
, rel
->r_info
);
976 kprintf("link_elf_obj_obj: symbol %s undefined\n",
983 /* Perform relocations with addend if there are any: */
984 for (i
= 0; i
< ef
->nrelatab
; i
++) {
985 rela
= ef
->relatab
[i
].rela
;
987 panic("lost a relatab!");
988 relalim
= rela
+ ef
->relatab
[i
].nrela
;
989 base
= findbase(ef
, ef
->relatab
[i
].sec
);
991 panic("lost base for relatab");
992 for ( ; rela
< relalim
; rela
++) {
993 symidx
= ELF_R_SYM(rela
->r_info
);
994 if (symidx
>= ef
->ddbsymcnt
)
996 sym
= ef
->ddbsymtab
+ symidx
;
997 /* Local relocs are already done */
998 if (ELF_ST_BIND(sym
->st_info
) == STB_LOCAL
)
1000 if (elf_reloc(lf
, base
, rela
, ELF_RELOC_RELA
,
1002 symname
= symbol_name(ef
, rela
->r_info
);
1003 kprintf("link_elf_obj_obj: symbol %s undefined\n",
1014 link_elf_obj_lookup_symbol(linker_file_t lf
, const char *name
, c_linker_sym_t
*sym
)
1016 elf_file_t ef
= lf
->priv
;
1017 const Elf_Sym
*symp
;
1021 for (i
= 0, symp
= ef
->ddbsymtab
; i
< ef
->ddbsymcnt
; i
++, symp
++) {
1022 strp
= ef
->ddbstrtab
+ symp
->st_name
;
1023 if (symp
->st_shndx
!= SHN_UNDEF
&& strcmp(name
, strp
) == 0) {
1024 *sym
= (c_linker_sym_t
) symp
;
1032 link_elf_obj_symbol_values(linker_file_t lf
, c_linker_sym_t sym
,
1033 linker_symval_t
*symval
)
1035 elf_file_t ef
= lf
->priv
;
1036 const Elf_Sym
*es
= (const Elf_Sym
*) sym
;
1038 if (es
>= ef
->ddbsymtab
&& es
< (ef
->ddbsymtab
+ ef
->ddbsymcnt
)) {
1039 symval
->name
= ef
->ddbstrtab
+ es
->st_name
;
1040 symval
->value
= (caddr_t
)es
->st_value
;
1041 symval
->size
= es
->st_size
;
1048 link_elf_obj_search_symbol(linker_file_t lf
, caddr_t value
,
1049 c_linker_sym_t
*sym
, long *diffp
)
1051 elf_file_t ef
= lf
->priv
;
1052 u_long off
= (uintptr_t) (void *) value
;
1056 const Elf_Sym
*best
= 0;
1059 for (i
= 0, es
= ef
->ddbsymtab
; i
< ef
->ddbsymcnt
; i
++, es
++) {
1060 if (es
->st_name
== 0)
1062 st_value
= es
->st_value
;
1063 if (off
>= st_value
) {
1064 if (off
- st_value
< diff
) {
1065 diff
= off
- st_value
;
1069 } else if (off
- st_value
== diff
) {
1078 *sym
= (c_linker_sym_t
) best
;
1084 * Look up a linker set on an ELF system.
1087 link_elf_obj_lookup_set(linker_file_t lf
, const char *name
,
1088 void ***startp
, void ***stopp
, int *countp
)
1090 elf_file_t ef
= lf
->priv
;
1091 void **start
, **stop
;
1094 /* Relative to section number */
1095 for (i
= 0; i
< ef
->nprogtab
; i
++) {
1096 if ((strncmp(ef
->progtab
[i
].name
, "set_", 4) == 0) &&
1097 strcmp(ef
->progtab
[i
].name
+ 4, name
) == 0) {
1098 start
= (void **)ef
->progtab
[i
].addr
;
1099 stop
= (void **)((char *)ef
->progtab
[i
].addr
+
1100 ef
->progtab
[i
].size
);
1101 count
= stop
- start
;
1115 * Symbol lookup function that can be used when the symbol index is known (ie
1116 * in relocations). It uses the symbol index instead of doing a fully fledged
1117 * hash table based lookup when such is valid. For example for local symbols.
1118 * This is not only more efficient, it's also more correct. It's not always
1119 * the case that the symbol can be found through the hash table.
1122 elf_obj_lookup(linker_file_t lf
, Elf_Size symidx
, int deps
, Elf_Addr
*result
)
1124 elf_file_t ef
= lf
->priv
;
1128 /* Don't even try to lookup the symbol if the index is bogus. */
1129 if (symidx
>= ef
->ddbsymcnt
)
1132 sym
= ef
->ddbsymtab
+ symidx
;
1134 /* Quick answer if there is a definition included. */
1135 if (sym
->st_shndx
!= SHN_UNDEF
) {
1136 *result
= sym
->st_value
;
1140 /* If we get here, then it is undefined and needs a lookup. */
1141 switch (ELF_ST_BIND(sym
->st_info
)) {
1143 /* Local, but undefined? huh? */
1147 /* Relative to Data or Function name */
1148 symbol
= ef
->ddbstrtab
+ sym
->st_name
;
1150 /* Force a lookup failure if the symbol name is bogus. */
1153 return (linker_file_lookup_symbol(lf
, symbol
, deps
, (caddr_t
*)result
));
1156 kprintf("link_elf_obj_obj: Weak symbols not supported\n");
1165 link_elf_obj_fix_link_set(elf_file_t ef
)
1167 static const char startn
[] = "__start_";
1168 static const char stopn
[] = "__stop_";
1170 const char *sym_name
, *linkset_name
;
1171 Elf_Addr startp
, stopp
;
1176 for (symidx
= 1 /* zero entry is special */;
1177 symidx
< ef
->ddbsymcnt
; symidx
++) {
1178 sym
= ef
->ddbsymtab
+ symidx
;
1179 if (sym
->st_shndx
!= SHN_UNDEF
)
1182 sym_name
= ef
->ddbstrtab
+ sym
->st_name
;
1183 if (strncmp(sym_name
, startn
, sizeof(startn
) - 1) == 0) {
1185 linkset_name
= sym_name
+ sizeof(startn
) - 1;
1187 else if (strncmp(sym_name
, stopn
, sizeof(stopn
) - 1) == 0) {
1189 linkset_name
= sym_name
+ sizeof(stopn
) - 1;
1194 for (i
= 0; i
< ef
->nprogtab
; i
++) {
1195 if (strcmp(ef
->progtab
[i
].name
, linkset_name
) == 0) {
1196 startp
= (Elf_Addr
)ef
->progtab
[i
].addr
;
1197 stopp
= (Elf_Addr
)(startp
+ ef
->progtab
[i
].size
);
1201 if (i
== ef
->nprogtab
)
1204 sym
->st_value
= start
? startp
: stopp
;
1210 link_elf_obj_reloc_local(linker_file_t lf
)
1212 elf_file_t ef
= lf
->priv
;
1213 const Elf_Rel
*rellim
;
1215 const Elf_Rela
*relalim
;
1216 const Elf_Rela
*rela
;
1222 link_elf_obj_fix_link_set(ef
);
1224 /* Perform relocations without addend if there are any: */
1225 for (i
= 0; i
< ef
->nreltab
; i
++) {
1226 rel
= ef
->reltab
[i
].rel
;
1228 panic("lost a reltab!");
1229 rellim
= rel
+ ef
->reltab
[i
].nrel
;
1230 base
= findbase(ef
, ef
->reltab
[i
].sec
);
1232 panic("lost base for reltab");
1233 for ( ; rel
< rellim
; rel
++) {
1234 symidx
= ELF_R_SYM(rel
->r_info
);
1235 if (symidx
>= ef
->ddbsymcnt
)
1237 sym
= ef
->ddbsymtab
+ symidx
;
1238 /* Only do local relocs */
1239 if (ELF_ST_BIND(sym
->st_info
) != STB_LOCAL
)
1241 elf_reloc_local(lf
, base
, rel
, ELF_RELOC_REL
,
1246 /* Perform relocations with addend if there are any: */
1247 for (i
= 0; i
< ef
->nrelatab
; i
++) {
1248 rela
= ef
->relatab
[i
].rela
;
1250 panic("lost a relatab!");
1251 relalim
= rela
+ ef
->relatab
[i
].nrela
;
1252 base
= findbase(ef
, ef
->relatab
[i
].sec
);
1254 panic("lost base for relatab");
1255 for ( ; rela
< relalim
; rela
++) {
1256 symidx
= ELF_R_SYM(rela
->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
, rela
, ELF_RELOC_RELA
,