1 /* $NetBSD: subr_kobj.c,v 1.39 2009/06/17 21:04:25 dyoung Exp $ */
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * This code is derived from software developed for The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1998-2000 Doug Rabson
34 * Copyright (c) 2004 Peter Wemm
35 * All rights reserved.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * Kernel loader for ELF objects.
62 * TODO: adjust kmem_alloc() calls to avoid needless fragmentation.
65 #include <sys/cdefs.h>
66 __KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.39 2009/06/17 21:04:25 dyoung Exp $");
68 #include "opt_modular.h"
70 #include <sys/kobj_impl.h>
74 #include <sys/param.h>
75 #include <sys/kernel.h>
78 #include <sys/ksyms.h>
79 #include <sys/module.h>
81 #include <machine/stdarg.h>
83 #include <uvm/uvm_extern.h>
85 static int kobj_relocate(kobj_t
, bool);
86 static int kobj_checksyms(kobj_t
, bool);
87 static void kobj_error(const char *, ...);
88 static void kobj_jettison(kobj_t
);
89 static void kobj_free(kobj_t
, void *, size_t);
90 static void kobj_close(kobj_t
);
91 static int kobj_read_mem(kobj_t
, void **, size_t, off_t
, bool);
92 static void kobj_close_mem(kobj_t
);
94 extern struct vm_map
*module_map
;
99 * Load an object already resident in memory. If size is not -1,
100 * the complete size of the object is known.
103 kobj_load_mem(kobj_t
*kop
, void *base
, ssize_t size
)
107 ko
= kmem_zalloc(sizeof(*ko
), KM_SLEEP
);
112 ko
->ko_type
= KT_MEMORY
;
113 ko
->ko_source
= base
;
114 ko
->ko_memsize
= size
;
115 ko
->ko_read
= kobj_read_mem
;
116 ko
->ko_close
= kobj_close_mem
;
119 return kobj_load(ko
);
125 * Close an open ELF object.
128 kobj_close(kobj_t ko
)
131 if (ko
->ko_source
== NULL
) {
136 ko
->ko_source
= NULL
;
140 kobj_close_mem(kobj_t ko
)
149 * Load an ELF object and prepare to link into the running kernel
169 KASSERT(ko
->ko_type
!= KT_UNSET
);
170 KASSERT(ko
->ko_source
!= NULL
);
178 * Read the elf header from the file.
180 error
= ko
->ko_read(ko
, (void **)&hdr
, sizeof(*hdr
), 0, true);
183 if (memcmp(hdr
->e_ident
, ELFMAG
, SELFMAG
) != 0) {
184 kobj_error("not an ELF object");
189 if (hdr
->e_ident
[EI_VERSION
] != EV_CURRENT
||
190 hdr
->e_version
!= EV_CURRENT
) {
191 kobj_error("unsupported file version");
195 if (hdr
->e_type
!= ET_REL
) {
196 kobj_error("unsupported file type");
200 switch (hdr
->e_machine
) {
202 ELF32_MACHDEP_ID_CASES
204 ELF64_MACHDEP_ID_CASES
207 kobj_error("unsupported machine");
218 * Allocate and read in the section header.
220 ko
->ko_shdrsz
= hdr
->e_shnum
* hdr
->e_shentsize
;
221 if (ko
->ko_shdrsz
== 0 || hdr
->e_shoff
== 0 ||
222 hdr
->e_shentsize
!= sizeof(Elf_Shdr
)) {
226 error
= ko
->ko_read(ko
, (void **)&shdr
, ko
->ko_shdrsz
, hdr
->e_shoff
,
234 * Scan the section header for information and table sizing.
239 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
240 switch (shdr
[i
].sh_type
) {
248 symstrindex
= shdr
[i
].sh_link
;
260 if (ko
->ko_nprogtab
== 0) {
261 kobj_error("file has no contents");
266 /* Only allow one symbol table for now */
267 kobj_error("file has no valid symbol table");
271 if (symstrindex
< 0 || symstrindex
> hdr
->e_shnum
||
272 shdr
[symstrindex
].sh_type
!= SHT_STRTAB
) {
273 kobj_error("file has invalid symbol strings");
279 * Allocate space for tracking the load chunks.
281 if (ko
->ko_nprogtab
!= 0) {
282 ko
->ko_progtab
= kmem_zalloc(ko
->ko_nprogtab
*
283 sizeof(*ko
->ko_progtab
), KM_SLEEP
);
284 if (ko
->ko_progtab
== NULL
) {
289 if (ko
->ko_nrel
!= 0) {
290 ko
->ko_reltab
= kmem_zalloc(ko
->ko_nrel
*
291 sizeof(*ko
->ko_reltab
), KM_SLEEP
);
292 if (ko
->ko_reltab
== NULL
) {
297 if (ko
->ko_nrela
!= 0) {
298 ko
->ko_relatab
= kmem_zalloc(ko
->ko_nrela
*
299 sizeof(*ko
->ko_relatab
), KM_SLEEP
);
300 if (ko
->ko_relatab
== NULL
) {
305 if (symtabindex
== -1) {
306 kobj_error("lost symbol table index");
311 * Allocate space for and load the symbol table.
313 ko
->ko_symcnt
= shdr
[symtabindex
].sh_size
/ sizeof(Elf_Sym
);
314 if (ko
->ko_symcnt
== 0) {
315 kobj_error("no symbol table");
318 error
= ko
->ko_read(ko
, (void **)&ko
->ko_symtab
,
319 ko
->ko_symcnt
* sizeof(Elf_Sym
),
320 shdr
[symtabindex
].sh_offset
, true);
326 * Allocate space for and load the symbol strings.
328 ko
->ko_strtabsz
= shdr
[symstrindex
].sh_size
;
329 if (ko
->ko_strtabsz
== 0) {
330 kobj_error("no symbol strings");
333 error
= ko
->ko_read(ko
, (void *)&ko
->ko_strtab
, ko
->ko_strtabsz
,
334 shdr
[symstrindex
].sh_offset
, true);
340 * Do we have a string table for the section names?
342 if (hdr
->e_shstrndx
!= 0 && shdr
[hdr
->e_shstrndx
].sh_size
!= 0 &&
343 shdr
[hdr
->e_shstrndx
].sh_type
== SHT_STRTAB
) {
344 ko
->ko_shstrtabsz
= shdr
[hdr
->e_shstrndx
].sh_size
;
345 error
= ko
->ko_read(ko
, (void **)&ko
->ko_shstrtab
,
346 shdr
[hdr
->e_shstrndx
].sh_size
,
347 shdr
[hdr
->e_shstrndx
].sh_offset
, true);
354 * Size up code/data(progbits) and bss(nobits).
358 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
359 switch (shdr
[i
].sh_type
) {
363 mapbase
= shdr
[i
].sh_offset
;
364 alignmask
= shdr
[i
].sh_addralign
- 1;
365 mapsize
+= alignmask
;
366 mapsize
&= ~alignmask
;
367 mapsize
+= shdr
[i
].sh_size
;
373 * We know how much space we need for the text/data/bss/etc.
374 * This stuff needs to be in a single chunk so that profiling etc
375 * can get the bounds and gdb can associate offsets with modules.
378 kobj_error("no text/data/bss");
381 if (ko
->ko_type
== KT_MEMORY
) {
382 mapbase
+= (vaddr_t
)ko
->ko_source
;
384 mapbase
= uvm_km_alloc(module_map
, round_page(mapsize
),
385 0, UVM_KMF_WIRED
| UVM_KMF_EXEC
);
391 ko
->ko_address
= mapbase
;
392 ko
->ko_size
= mapsize
;
395 * Now load code/data(progbits), zero bss(nobits), allocate space
396 * for and load relocs
402 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
403 switch (shdr
[i
].sh_type
) {
406 alignmask
= shdr
[i
].sh_addralign
- 1;
407 if (ko
->ko_type
== KT_MEMORY
) {
408 addr
= (void *)(shdr
[i
].sh_offset
+
409 (vaddr_t
)ko
->ko_source
);
410 if (((vaddr_t
)addr
& alignmask
) != 0) {
411 kobj_error("section %d not aligned\n",
416 mapbase
+= alignmask
;
417 mapbase
&= ~alignmask
;
418 addr
= (void *)mapbase
;
419 mapbase
+= shdr
[i
].sh_size
;
421 ko
->ko_progtab
[pb
].addr
= addr
;
422 if (shdr
[i
].sh_type
== SHT_PROGBITS
) {
423 ko
->ko_progtab
[pb
].name
= "<<PROGBITS>>";
424 error
= ko
->ko_read(ko
, &addr
,
425 shdr
[i
].sh_size
, shdr
[i
].sh_offset
, false);
429 } else if (ko
->ko_type
== KT_MEMORY
&&
430 shdr
[i
].sh_size
!= 0) {
431 kobj_error("non-loadable BSS section in "
432 "pre-loaded module");
436 ko
->ko_progtab
[pb
].name
= "<<NOBITS>>";
437 memset(addr
, 0, shdr
[i
].sh_size
);
439 ko
->ko_progtab
[pb
].size
= shdr
[i
].sh_size
;
440 ko
->ko_progtab
[pb
].sec
= i
;
441 if (ko
->ko_shstrtab
!= NULL
&& shdr
[i
].sh_name
!= 0) {
442 ko
->ko_progtab
[pb
].name
=
443 ko
->ko_shstrtab
+ shdr
[i
].sh_name
;
446 /* Update all symbol values with the offset. */
447 for (j
= 0; j
< ko
->ko_symcnt
; j
++) {
448 es
= &ko
->ko_symtab
[j
];
449 if (es
->st_shndx
!= i
) {
452 es
->st_value
+= (Elf_Addr
)addr
;
457 ko
->ko_reltab
[rl
].size
= shdr
[i
].sh_size
;
458 ko
->ko_reltab
[rl
].size
-=
459 shdr
[i
].sh_size
% sizeof(Elf_Rel
);
460 if (ko
->ko_reltab
[rl
].size
!= 0) {
461 ko
->ko_reltab
[rl
].nrel
=
462 shdr
[i
].sh_size
/ sizeof(Elf_Rel
);
463 ko
->ko_reltab
[rl
].sec
= shdr
[i
].sh_info
;
464 error
= ko
->ko_read(ko
,
465 (void **)&ko
->ko_reltab
[rl
].rel
,
466 ko
->ko_reltab
[rl
].size
,
467 shdr
[i
].sh_offset
, true);
475 ko
->ko_relatab
[ra
].size
= shdr
[i
].sh_size
;
476 ko
->ko_relatab
[ra
].size
-=
477 shdr
[i
].sh_size
% sizeof(Elf_Rela
);
478 if (ko
->ko_relatab
[ra
].size
!= 0) {
479 ko
->ko_relatab
[ra
].nrela
=
480 shdr
[i
].sh_size
/ sizeof(Elf_Rela
);
481 ko
->ko_relatab
[ra
].sec
= shdr
[i
].sh_info
;
482 error
= ko
->ko_read(ko
,
483 (void **)&ko
->ko_relatab
[ra
].rela
,
485 shdr
[i
].sh_offset
, true);
496 if (pb
!= ko
->ko_nprogtab
) {
497 panic("lost progbits");
499 if (rl
!= ko
->ko_nrel
) {
502 if (ra
!= ko
->ko_nrela
) {
505 if (ko
->ko_type
!= KT_MEMORY
&& mapbase
!= ko
->ko_address
+ mapsize
) {
506 panic("mapbase 0x%lx != address %lx + mapsize %ld (0x%lx)\n",
507 (long)mapbase
, (long)ko
->ko_address
, (long)mapsize
,
508 (long)ko
->ko_address
+ mapsize
);
512 * Perform local relocations only. Relocations relating to global
513 * symbols will be done by kobj_affix().
515 error
= kobj_checksyms(ko
, false);
517 error
= kobj_relocate(ko
, true);
521 kobj_free(ko
, hdr
, sizeof(*hdr
));
534 * Unload an object previously loaded by kobj_load().
537 kobj_unload(kobj_t ko
)
545 * Notify MD code that a module has been unloaded.
548 error
= kobj_machdep(ko
, (void *)ko
->ko_address
, ko
->ko_size
,
551 kobj_error("machine dependent deinit failed");
554 if (ko
->ko_address
!= 0 && ko
->ko_type
!= KT_MEMORY
) {
555 uvm_km_free(module_map
, ko
->ko_address
, round_page(ko
->ko_size
),
558 if (ko
->ko_ksyms
== true) {
559 ksyms_modunload(ko
->ko_name
);
561 if (ko
->ko_symtab
!= NULL
) {
562 kobj_free(ko
, ko
->ko_symtab
, ko
->ko_symcnt
* sizeof(Elf_Sym
));
564 if (ko
->ko_strtab
!= NULL
) {
565 kobj_free(ko
, ko
->ko_strtab
, ko
->ko_strtabsz
);
567 if (ko
->ko_progtab
!= NULL
) {
568 kobj_free(ko
, ko
->ko_progtab
, ko
->ko_nprogtab
*
569 sizeof(*ko
->ko_progtab
));
570 ko
->ko_progtab
= NULL
;
572 if (ko
->ko_shstrtab
) {
573 kobj_free(ko
, ko
->ko_shstrtab
, ko
->ko_shstrtabsz
);
574 ko
->ko_shstrtab
= NULL
;
577 kmem_free(ko
, sizeof(*ko
));
583 * Return size and load address of an object.
586 kobj_stat(kobj_t ko
, vaddr_t
*address
, size_t *size
)
589 if (address
!= NULL
) {
590 *address
= ko
->ko_address
;
601 * Set an object's name and perform global relocs. May only be
602 * called after the module and any requisite modules are loaded.
605 kobj_affix(kobj_t ko
, const char *name
)
609 KASSERT(ko
->ko_ksyms
== false);
610 KASSERT(ko
->ko_loaded
== false);
612 strlcpy(ko
->ko_name
, name
, sizeof(ko
->ko_name
));
614 /* Cache addresses of undefined symbols. */
615 error
= kobj_checksyms(ko
, true);
617 /* Now do global relocations. */
619 error
= kobj_relocate(ko
, false);
622 * Now that we know the name, register the symbol table.
623 * Do after global relocations because ksyms will pack
627 ksyms_modload(ko
->ko_name
, ko
->ko_symtab
, ko
->ko_symcnt
*
628 sizeof(Elf_Sym
), ko
->ko_strtab
, ko
->ko_strtabsz
);
632 /* Jettison unneeded memory post-link. */
636 * Notify MD code that a module has been loaded.
638 * Most architectures use this opportunity to flush their caches.
641 error
= kobj_machdep(ko
, (void *)ko
->ko_address
, ko
->ko_size
,
644 kobj_error("machine dependent init failed");
646 ko
->ko_loaded
= true;
649 /* If there was an error, destroy the whole object. */
660 * Given a section name, search the loaded object and return
661 * virtual address if present and loaded.
664 kobj_find_section(kobj_t ko
, const char *name
, void **addr
, size_t *size
)
668 KASSERT(ko
->ko_progtab
!= NULL
);
670 for (i
= 0; i
< ko
->ko_nprogtab
; i
++) {
671 if (strcmp(ko
->ko_progtab
[i
].name
, name
) == 0) {
673 *addr
= ko
->ko_progtab
[i
].addr
;
676 *size
= ko
->ko_progtab
[i
].size
;
688 * Release object data not needed after performing relocations.
691 kobj_jettison(kobj_t ko
)
695 if (ko
->ko_reltab
!= NULL
) {
696 for (i
= 0; i
< ko
->ko_nrel
; i
++) {
697 if (ko
->ko_reltab
[i
].rel
) {
698 kobj_free(ko
, ko
->ko_reltab
[i
].rel
,
699 ko
->ko_reltab
[i
].size
);
702 kobj_free(ko
, ko
->ko_reltab
, ko
->ko_nrel
*
703 sizeof(*ko
->ko_reltab
));
704 ko
->ko_reltab
= NULL
;
707 if (ko
->ko_relatab
!= NULL
) {
708 for (i
= 0; i
< ko
->ko_nrela
; i
++) {
709 if (ko
->ko_relatab
[i
].rela
) {
710 kobj_free(ko
, ko
->ko_relatab
[i
].rela
,
711 ko
->ko_relatab
[i
].size
);
714 kobj_free(ko
, ko
->ko_relatab
, ko
->ko_nrela
*
715 sizeof(*ko
->ko_relatab
));
716 ko
->ko_relatab
= NULL
;
719 if (ko
->ko_shdr
!= NULL
) {
720 kobj_free(ko
, ko
->ko_shdr
, ko
->ko_shdrsz
);
728 * Symbol lookup function to be used when the symbol index
729 * is known (ie during relocation).
732 kobj_sym_lookup(kobj_t ko
, uintptr_t symidx
)
737 /* Don't even try to lookup the symbol if the index is bogus. */
738 if (symidx
>= ko
->ko_symcnt
)
741 sym
= ko
->ko_symtab
+ symidx
;
743 /* Quick answer if there is a definition included. */
744 if (sym
->st_shndx
!= SHN_UNDEF
) {
745 return (uintptr_t)sym
->st_value
;
748 /* If we get here, then it is undefined and needs a lookup. */
749 switch (ELF_ST_BIND(sym
->st_info
)) {
751 /* Local, but undefined? huh? */
752 kobj_error("local symbol undefined");
756 /* Relative to Data or Function name */
757 symbol
= ko
->ko_strtab
+ sym
->st_name
;
759 /* Force a lookup failure if the symbol name is bogus. */
761 kobj_error("bad symbol name");
765 return (uintptr_t)sym
->st_value
;
768 kobj_error("weak symbols not supported\n");
779 * Return base address of the given section.
782 kobj_findbase(kobj_t ko
, int sec
)
786 for (i
= 0; i
< ko
->ko_nprogtab
; i
++) {
787 if (sec
== ko
->ko_progtab
[i
].sec
) {
788 return (uintptr_t)ko
->ko_progtab
[i
].addr
;
797 * Scan symbol table for duplicates or resolve references to
801 kobj_checksyms(kobj_t ko
, bool undefined
)
810 for (ms
= (sym
= ko
->ko_symtab
) + ko
->ko_symcnt
; sym
< ms
; sym
++) {
811 /* Check validity of the symbol. */
812 if (ELF_ST_BIND(sym
->st_info
) != STB_GLOBAL
||
815 if (undefined
!= (sym
->st_shndx
== SHN_UNDEF
)) {
820 * Look it up. Don't need to lock, as it is known that
821 * the symbol tables aren't going to change (we hold
824 name
= ko
->ko_strtab
+ sym
->st_name
;
825 if (ksyms_getval_unlocked(NULL
, name
, &rval
,
826 KSYMS_EXTERN
) != 0) {
828 kobj_error("symbol `%s' not found", name
);
834 /* Save values of undefined globals. */
836 sym
->st_value
= (Elf_Addr
)rval
;
840 /* Check (and complain) about differing values. */
841 if (sym
->st_value
== rval
) {
844 if (strcmp(name
, "_bss_start") == 0 ||
845 strcmp(name
, "__bss_start") == 0 ||
846 strcmp(name
, "_bss_end__") == 0 ||
847 strcmp(name
, "__bss_end__") == 0 ||
848 strcmp(name
, "_edata") == 0 ||
849 strcmp(name
, "_end") == 0 ||
850 strcmp(name
, "__end") == 0 ||
851 strcmp(name
, "__end__") == 0 ||
852 strncmp(name
, "__start_link_set_", 17) == 0 ||
853 strncmp(name
, "__stop_link_set_", 16)) {
856 kobj_error("global symbol `%s' redefined\n", name
);
866 * Resolve relocations for the loaded object.
869 kobj_relocate(kobj_t ko
, bool local
)
871 const Elf_Rel
*rellim
;
873 const Elf_Rela
*relalim
;
874 const Elf_Rela
*rela
;
881 * Perform relocations without addend if there are any.
883 for (i
= 0; i
< ko
->ko_nrel
; i
++) {
884 rel
= ko
->ko_reltab
[i
].rel
;
888 rellim
= rel
+ ko
->ko_reltab
[i
].nrel
;
889 base
= kobj_findbase(ko
, ko
->ko_reltab
[i
].sec
);
891 panic("lost base for e_reltab");
893 for (; rel
< rellim
; rel
++) {
894 symidx
= ELF_R_SYM(rel
->r_info
);
895 if (symidx
>= ko
->ko_symcnt
) {
898 sym
= ko
->ko_symtab
+ symidx
;
899 if (local
!= (ELF_ST_BIND(sym
->st_info
) == STB_LOCAL
)) {
902 error
= kobj_reloc(ko
, base
, rel
, false, local
);
910 * Perform relocations with addend if there are any.
912 for (i
= 0; i
< ko
->ko_nrela
; i
++) {
913 rela
= ko
->ko_relatab
[i
].rela
;
917 relalim
= rela
+ ko
->ko_relatab
[i
].nrela
;
918 base
= kobj_findbase(ko
, ko
->ko_relatab
[i
].sec
);
920 panic("lost base for e_relatab");
922 for (; rela
< relalim
; rela
++) {
923 symidx
= ELF_R_SYM(rela
->r_info
);
924 if (symidx
>= ko
->ko_symcnt
) {
927 sym
= ko
->ko_symtab
+ symidx
;
928 if (local
!= (ELF_ST_BIND(sym
->st_info
) == STB_LOCAL
)) {
931 error
= kobj_reloc(ko
, base
, rela
, true, local
);
944 * Utility function: log an error.
947 kobj_error(const char *fmt
, ...)
952 printf("WARNING: linker error: ");
959 kobj_read_mem(kobj_t ko
, void **basep
, size_t size
, off_t off
,
965 if (ko
->ko_memsize
!= -1 && off
+ size
> ko
->ko_memsize
) {
966 kobj_error("kobj_read_mem: preloaded object short");
969 } else if (allocate
) {
970 base
= (uint8_t *)ko
->ko_source
+ off
;
972 } else if ((uint8_t *)base
!= (uint8_t *)ko
->ko_source
+ off
) {
973 kobj_error("kobj_read_mem: object not aligned");
974 kobj_error("source=%p base=%p off=%d size=%zd",
975 ko
->ko_source
, base
, (int)off
, size
);
978 /* Nothing to do. Loading in-situ. */
991 * Utility function: free memory if it was allocated from the heap.
994 kobj_free(kobj_t ko
, void *base
, size_t size
)
997 if (ko
->ko_type
!= KT_MEMORY
)
998 kmem_free(base
, size
);
1004 kobj_load_mem(kobj_t
*kop
, void *base
, ssize_t size
)
1011 kobj_unload(kobj_t ko
)
1014 panic("not modular");
1018 kobj_stat(kobj_t ko
, vaddr_t
*base
, size_t *size
)
1025 kobj_affix(kobj_t ko
, const char *name
)
1028 panic("not modular");
1032 kobj_find_section(kobj_t ko
, const char *name
, void **addr
, size_t *size
)
1035 panic("not modular");
1038 #endif /* MODULAR */