The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/subr_kobj.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: subr_kobj.c,v 1.76 2023/01/29 17:20:48 skrll Exp $     */
    2 
    3 /*
    4  * Copyright (c) 2008 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software developed for The NetBSD Foundation
    8  * by Andrew Doran.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   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.
   18  *
   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.
   30  */
   31 
   32 /*
   33  * Copyright (c) 1998-2000 Doug Rabson
   34  * Copyright (c) 2004 Peter Wemm
   35  * All rights reserved.
   36  *
   37  * Redistribution and use in source and binary forms, with or without
   38  * modification, are permitted provided that the following conditions
   39  * are met:
   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.
   45  *
   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
   56  * SUCH DAMAGE.
   57  */
   58 
   59 /*
   60  * Kernel loader for ELF objects.
   61  *
   62  * TODO: adjust kmem_alloc() calls to avoid needless fragmentation.
   63  */
   64 
   65 #include <sys/cdefs.h>
   66 __KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.76 2023/01/29 17:20:48 skrll Exp $");
   67 
   68 #ifdef _KERNEL_OPT
   69 #include "opt_modular.h"
   70 #endif
   71 
   72 #include <sys/kobj_impl.h>
   73 
   74 #ifdef MODULAR
   75 
   76 #include <sys/param.h>
   77 #include <sys/kernel.h>
   78 #include <sys/kmem.h>
   79 #include <sys/proc.h>
   80 #include <sys/ksyms.h>
   81 #include <sys/module.h>
   82 
   83 #include <uvm/uvm_extern.h>
   84 
   85 #define kobj_error(_kobj, ...) \
   86         kobj_out(__func__, __LINE__, _kobj, __VA_ARGS__)
   87 
   88 static int      kobj_relocate(kobj_t, bool);
   89 static int      kobj_checksyms(kobj_t, bool);
   90 static void     kobj_out(const char *, int, kobj_t, const char *, ...)
   91     __printflike(4, 5);
   92 static void     kobj_jettison(kobj_t);
   93 static void     kobj_free(kobj_t, void *, size_t);
   94 static void     kobj_close(kobj_t);
   95 static int      kobj_read_mem(kobj_t, void **, size_t, off_t, bool);
   96 static void     kobj_close_mem(kobj_t);
   97 
   98 /*
   99  * kobj_load_mem:
  100  *
  101  *      Load an object already resident in memory.  If size is not -1,
  102  *      the complete size of the object is known.
  103  */
  104 int
  105 kobj_load_mem(kobj_t *kop, const char *name, void *base, ssize_t size)
  106 {
  107         kobj_t ko;
  108 
  109         ko = kmem_zalloc(sizeof(*ko), KM_SLEEP);
  110         ko->ko_type = KT_MEMORY;
  111         kobj_setname(ko, name);
  112         ko->ko_source = base;
  113         ko->ko_memsize = size;
  114         ko->ko_read = kobj_read_mem;
  115         ko->ko_close = kobj_close_mem;
  116 
  117         *kop = ko;
  118         return kobj_load(ko);
  119 }
  120 
  121 /*
  122  * kobj_close:
  123  *
  124  *      Close an open ELF object.
  125  */
  126 static void
  127 kobj_close(kobj_t ko)
  128 {
  129 
  130         if (ko->ko_source == NULL) {
  131                 return;
  132         }
  133 
  134         ko->ko_close(ko);
  135         ko->ko_source = NULL;
  136 }
  137 
  138 static void
  139 kobj_close_mem(kobj_t ko)
  140 {
  141 
  142         return;
  143 }
  144 
  145 /*
  146  * kobj_load:
  147  *
  148  *      Load an ELF object and prepare to link into the running kernel
  149  *      image.
  150  */
  151 int
  152 kobj_load(kobj_t ko)
  153 {
  154         Elf_Ehdr *hdr;
  155         Elf_Shdr *shdr;
  156         Elf_Sym *es;
  157         vaddr_t map_text_base;
  158         vaddr_t map_data_base;
  159         vaddr_t map_rodata_base;
  160         size_t map_text_size;
  161         size_t map_data_size;
  162         size_t map_rodata_size;
  163         int error;
  164         int symtabindex;
  165         int symstrindex;
  166         int nsym;
  167         int pb, rl, ra;
  168         int alignmask;
  169         int i, j;
  170         void *addr;
  171 
  172         KASSERT(ko->ko_type != KT_UNSET);
  173         KASSERT(ko->ko_source != NULL);
  174 
  175         shdr = NULL;
  176         error = 0;
  177         hdr = NULL;
  178 
  179         /*
  180          * Read the elf header from the file.
  181          */
  182         error = ko->ko_read(ko, (void **)&hdr, sizeof(*hdr), 0, true);
  183         if (error != 0) {
  184                 kobj_error(ko, "read failed %d", error);
  185                 goto out;
  186         }
  187         if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0) {
  188                 kobj_error(ko, "not an ELF object");
  189                 error = ENOEXEC;
  190                 goto out;
  191         }
  192 
  193         if (hdr->e_ident[EI_VERSION] != EV_CURRENT ||
  194             hdr->e_version != EV_CURRENT) {
  195                 kobj_error(ko, "unsupported file version %d",
  196                     hdr->e_ident[EI_VERSION]);
  197                 error = ENOEXEC;
  198                 goto out;
  199         }
  200         if (hdr->e_type != ET_REL) {
  201                 kobj_error(ko, "unsupported file type %d", hdr->e_type);
  202                 error = ENOEXEC;
  203                 goto out;
  204         }
  205         switch (hdr->e_machine) {
  206 #if ELFSIZE == 32
  207         ELF32_MACHDEP_ID_CASES
  208 #elif ELFSIZE == 64
  209         ELF64_MACHDEP_ID_CASES
  210 #else
  211 #error not defined
  212 #endif
  213         default:
  214                 kobj_error(ko, "unsupported machine %d", hdr->e_machine);
  215                 error = ENOEXEC;
  216                 goto out;
  217         }
  218 
  219         ko->ko_nprogtab = 0;
  220         ko->ko_shdr = 0;
  221         ko->ko_nrel = 0;
  222         ko->ko_nrela = 0;
  223 
  224         /*
  225          * Allocate and read in the section header.
  226          */
  227         if (hdr->e_shnum == 0 || hdr->e_shnum > ELF_MAXSHNUM ||
  228             hdr->e_shoff == 0 || hdr->e_shentsize != sizeof(Elf_Shdr)) {
  229                 kobj_error(ko, "bad sizes");
  230                 error = ENOEXEC;
  231                 goto out;
  232         }
  233         ko->ko_shdrsz = hdr->e_shnum * sizeof(Elf_Shdr);
  234         error = ko->ko_read(ko, (void **)&shdr, ko->ko_shdrsz, hdr->e_shoff,
  235             true);
  236         if (error != 0) {
  237                 kobj_error(ko, "read failed %d", error);
  238                 goto out;
  239         }
  240         ko->ko_shdr = shdr;
  241 
  242         /*
  243          * Scan the section header for information and table sizing.
  244          */
  245         nsym = 0;
  246         symtabindex = symstrindex = -1;
  247         for (i = 0; i < hdr->e_shnum; i++) {
  248                 switch (shdr[i].sh_type) {
  249                 case SHT_PROGBITS:
  250                 case SHT_NOBITS:
  251                         ko->ko_nprogtab++;
  252                         break;
  253                 case SHT_SYMTAB:
  254                         nsym++;
  255                         symtabindex = i;
  256                         symstrindex = shdr[i].sh_link;
  257                         break;
  258                 case SHT_REL:
  259                         if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS)
  260                                 continue;
  261                         ko->ko_nrel++;
  262                         break;
  263                 case SHT_RELA:
  264                         if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS)
  265                                 continue;
  266                         ko->ko_nrela++;
  267                         break;
  268                 case SHT_STRTAB:
  269                         break;
  270                 }
  271         }
  272         if (ko->ko_nprogtab == 0) {
  273                 kobj_error(ko, "file has no contents");
  274                 error = ENOEXEC;
  275                 goto out;
  276         }
  277         if (nsym != 1) {
  278                 /* Only allow one symbol table for now */
  279                 kobj_error(ko, "file has no valid symbol table");
  280                 error = ENOEXEC;
  281                 goto out;
  282         }
  283         KASSERT(symtabindex != -1);
  284         KASSERT(symstrindex != -1);
  285 
  286         if (symstrindex == SHN_UNDEF || symstrindex >= hdr->e_shnum ||
  287             shdr[symstrindex].sh_type != SHT_STRTAB) {
  288                 kobj_error(ko, "file has invalid symbol strings");
  289                 error = ENOEXEC;
  290                 goto out;
  291         }
  292 
  293         /*
  294          * Allocate space for tracking the load chunks.
  295          */
  296         if (ko->ko_nprogtab != 0) {
  297                 ko->ko_progtab = kmem_zalloc(ko->ko_nprogtab *
  298                     sizeof(*ko->ko_progtab), KM_SLEEP);
  299                 if (ko->ko_progtab == NULL) {
  300                         error = ENOMEM;
  301                         kobj_error(ko, "out of memory");
  302                         goto out;
  303                 }
  304         }
  305         if (ko->ko_nrel != 0) {
  306                 ko->ko_reltab = kmem_zalloc(ko->ko_nrel *
  307                     sizeof(*ko->ko_reltab), KM_SLEEP);
  308                 if (ko->ko_reltab == NULL) {
  309                         error = ENOMEM;
  310                         kobj_error(ko, "out of memory");
  311                         goto out;
  312                 }
  313         }
  314         if (ko->ko_nrela != 0) {
  315                 ko->ko_relatab = kmem_zalloc(ko->ko_nrela *
  316                     sizeof(*ko->ko_relatab), KM_SLEEP);
  317                 if (ko->ko_relatab == NULL) {
  318                         error = ENOMEM;
  319                         kobj_error(ko, "out of memory");
  320                         goto out;
  321                 }
  322         }
  323 
  324         /*
  325          * Allocate space for and load the symbol table.
  326          */
  327         ko->ko_symcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym);
  328         if (ko->ko_symcnt == 0) {
  329                 kobj_error(ko, "no symbol table");
  330                 error = ENOEXEC;
  331                 goto out;
  332         }
  333         error = ko->ko_read(ko, (void **)&ko->ko_symtab,
  334             ko->ko_symcnt * sizeof(Elf_Sym),
  335             shdr[symtabindex].sh_offset, true);
  336         if (error != 0) {
  337                 kobj_error(ko, "read failed %d", error);
  338                 goto out;
  339         }
  340 
  341         /*
  342          * Allocate space for and load the symbol strings.
  343          */
  344         ko->ko_strtabsz = shdr[symstrindex].sh_size;
  345         if (ko->ko_strtabsz == 0) {
  346                 kobj_error(ko, "no symbol strings");
  347                 error = ENOEXEC;
  348                 goto out;
  349         }
  350         error = ko->ko_read(ko, (void *)&ko->ko_strtab, ko->ko_strtabsz,
  351             shdr[symstrindex].sh_offset, true);
  352         if (error != 0) {
  353                 kobj_error(ko, "read failed %d", error);
  354                 goto out;
  355         }
  356 
  357         /*
  358          * Adjust module symbol namespace, if necessary (e.g. with rump)
  359          */
  360         error = kobj_renamespace(ko->ko_symtab, ko->ko_symcnt,
  361             &ko->ko_strtab, &ko->ko_strtabsz);
  362         if (error != 0) {
  363                 kobj_error(ko, "renamespace failed %d", error);
  364                 goto out;
  365         }
  366 
  367         /*
  368          * Do we have a string table for the section names?
  369          */
  370         if (hdr->e_shstrndx != SHN_UNDEF) {
  371                 if (hdr->e_shstrndx >= hdr->e_shnum) {
  372                         kobj_error(ko, "bad shstrndx");
  373                         error = ENOEXEC;
  374                         goto out;
  375                 }
  376                 if (shdr[hdr->e_shstrndx].sh_size != 0 &&
  377                     shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) {
  378                         ko->ko_shstrtabsz = shdr[hdr->e_shstrndx].sh_size;
  379                         error = ko->ko_read(ko, (void **)&ko->ko_shstrtab,
  380                             shdr[hdr->e_shstrndx].sh_size,
  381                             shdr[hdr->e_shstrndx].sh_offset, true);
  382                         if (error != 0) {
  383                                 kobj_error(ko, "read failed %d", error);
  384                                 goto out;
  385                         }
  386                 }
  387         }
  388 
  389         /*
  390          * Size up code/data(progbits) and bss(nobits).
  391          */
  392         alignmask = 0;
  393         map_text_size = 0;
  394         map_data_size = 0;
  395         map_rodata_size = 0;
  396         for (i = 0; i < hdr->e_shnum; i++) {
  397                 if (shdr[i].sh_type != SHT_PROGBITS &&
  398                     shdr[i].sh_type != SHT_NOBITS)
  399                         continue;
  400                 alignmask = shdr[i].sh_addralign - 1;
  401                 if ((shdr[i].sh_flags & SHF_EXECINSTR)) {
  402                         map_text_size += alignmask;
  403                         map_text_size &= ~alignmask;
  404                         map_text_size += shdr[i].sh_size;
  405                 } else if (!(shdr[i].sh_flags & SHF_WRITE)) {
  406                         map_rodata_size += alignmask;
  407                         map_rodata_size &= ~alignmask;
  408                         map_rodata_size += shdr[i].sh_size;
  409                 } else {
  410                         map_data_size += alignmask;
  411                         map_data_size &= ~alignmask;
  412                         map_data_size += shdr[i].sh_size;
  413                 }
  414         }
  415 
  416         if (map_text_size == 0) {
  417                 kobj_error(ko, "no text");
  418                 error = ENOEXEC;
  419                 goto out;
  420         }
  421 
  422         if (map_data_size != 0) {
  423                 map_data_base = uvm_km_alloc(module_map, round_page(map_data_size),
  424                         0, UVM_KMF_WIRED);
  425                 if (map_data_base == 0) {
  426                         kobj_error(ko, "out of memory");
  427                         error = ENOMEM;
  428                         goto out;
  429                 }
  430                 ko->ko_data_address = map_data_base;
  431                 ko->ko_data_size = map_data_size;
  432         } else {
  433                 map_data_base = 0;
  434                 ko->ko_data_address = 0;
  435                 ko->ko_data_size = 0;
  436         }
  437 
  438         if (map_rodata_size != 0) {
  439                 map_rodata_base = uvm_km_alloc(module_map, round_page(map_rodata_size),
  440                         0, UVM_KMF_WIRED);
  441                 if (map_rodata_base == 0) {
  442                         kobj_error(ko, "out of memory");
  443                         error = ENOMEM;
  444                         goto out;
  445                 }
  446                 ko->ko_rodata_address = map_rodata_base;
  447                 ko->ko_rodata_size = map_rodata_size;
  448         } else {
  449                 map_rodata_base = 0;
  450                 ko->ko_rodata_address = 0;
  451                 ko->ko_rodata_size = 0;
  452         }
  453 
  454         map_text_base = uvm_km_alloc(module_map, round_page(map_text_size),
  455             0, UVM_KMF_WIRED | UVM_KMF_EXEC);
  456         if (map_text_base == 0) {
  457                 kobj_error(ko, "out of memory");
  458                 error = ENOMEM;
  459                 goto out;
  460         }
  461         ko->ko_text_address = map_text_base;
  462         ko->ko_text_size = map_text_size;
  463 
  464         /*
  465          * Now load code/data(progbits), zero bss(nobits), allocate space
  466          * for and load relocs
  467          */
  468         pb = 0;
  469         rl = 0;
  470         ra = 0;
  471         alignmask = 0;
  472         for (i = 0; i < hdr->e_shnum; i++) {
  473                 switch (shdr[i].sh_type) {
  474                 case SHT_PROGBITS:
  475                 case SHT_NOBITS:
  476                         alignmask = shdr[i].sh_addralign - 1;
  477                         if ((shdr[i].sh_flags & SHF_EXECINSTR)) {
  478                                 map_text_base += alignmask;
  479                                 map_text_base &= ~alignmask;
  480                                 addr = (void *)map_text_base;
  481                                 map_text_base += shdr[i].sh_size;
  482                         } else if (!(shdr[i].sh_flags & SHF_WRITE)) {
  483                                 map_rodata_base += alignmask;
  484                                 map_rodata_base &= ~alignmask;
  485                                 addr = (void *)map_rodata_base;
  486                                 map_rodata_base += shdr[i].sh_size;
  487                         } else {
  488                                 map_data_base += alignmask;
  489                                 map_data_base &= ~alignmask;
  490                                 addr = (void *)map_data_base;
  491                                 map_data_base += shdr[i].sh_size;
  492                         }
  493 
  494                         ko->ko_progtab[pb].addr = addr;
  495                         if (shdr[i].sh_type == SHT_PROGBITS) {
  496                                 ko->ko_progtab[pb].name = "<<PROGBITS>>";
  497                                 error = ko->ko_read(ko, &addr,
  498                                     shdr[i].sh_size, shdr[i].sh_offset, false);
  499                                 if (error != 0) {
  500                                         kobj_error(ko, "read failed %d", error);
  501                                         goto out;
  502                                 }
  503                         } else { /* SHT_NOBITS */
  504                                 ko->ko_progtab[pb].name = "<<NOBITS>>";
  505                                 memset(addr, 0, shdr[i].sh_size);
  506                         }
  507 
  508                         ko->ko_progtab[pb].size = shdr[i].sh_size;
  509                         ko->ko_progtab[pb].sec = i;
  510                         if (ko->ko_shstrtab != NULL && shdr[i].sh_name != 0) {
  511                                 ko->ko_progtab[pb].name =
  512                                     ko->ko_shstrtab + shdr[i].sh_name;
  513                         }
  514 
  515                         /* Update all symbol values with the offset. */
  516                         for (j = 0; j < ko->ko_symcnt; j++) {
  517                                 es = &ko->ko_symtab[j];
  518                                 if (es->st_shndx != i) {
  519                                         continue;
  520                                 }
  521                                 es->st_value += (Elf_Addr)addr;
  522                         }
  523                         pb++;
  524                         break;
  525                 case SHT_REL:
  526                         if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS)
  527                                 break;
  528                         ko->ko_reltab[rl].size = shdr[i].sh_size;
  529                         ko->ko_reltab[rl].size -=
  530                             shdr[i].sh_size % sizeof(Elf_Rel);
  531                         if (ko->ko_reltab[rl].size != 0) {
  532                                 ko->ko_reltab[rl].nrel =
  533                                     shdr[i].sh_size / sizeof(Elf_Rel);
  534                                 ko->ko_reltab[rl].sec = shdr[i].sh_info;
  535                                 error = ko->ko_read(ko,
  536                                     (void **)&ko->ko_reltab[rl].rel,
  537                                     ko->ko_reltab[rl].size,
  538                                     shdr[i].sh_offset, true);
  539                                 if (error != 0) {
  540                                         kobj_error(ko, "read failed %d",
  541                                             error);
  542                                         goto out;
  543                                 }
  544                         }
  545                         rl++;
  546                         break;
  547                 case SHT_RELA:
  548                         if (shdr[shdr[i].sh_info].sh_type != SHT_PROGBITS)
  549                                 break;
  550                         ko->ko_relatab[ra].size = shdr[i].sh_size;
  551                         ko->ko_relatab[ra].size -=
  552                             shdr[i].sh_size % sizeof(Elf_Rela);
  553                         if (ko->ko_relatab[ra].size != 0) {
  554                                 ko->ko_relatab[ra].nrela =
  555                                     shdr[i].sh_size / sizeof(Elf_Rela);
  556                                 ko->ko_relatab[ra].sec = shdr[i].sh_info;
  557                                 error = ko->ko_read(ko,
  558                                     (void **)&ko->ko_relatab[ra].rela,
  559                                     shdr[i].sh_size,
  560                                     shdr[i].sh_offset, true);
  561                                 if (error != 0) {
  562                                         kobj_error(ko, "read failed %d", error);
  563                                         goto out;
  564                                 }
  565                         }
  566                         ra++;
  567                         break;
  568                 default:
  569                         break;
  570                 }
  571         }
  572         if (pb != ko->ko_nprogtab) {
  573                 panic("%s:%d: %s: lost progbits", __func__, __LINE__,
  574                    ko->ko_name);
  575         }
  576         if (rl != ko->ko_nrel) {
  577                 panic("%s:%d: %s: lost rel", __func__, __LINE__,
  578                    ko->ko_name);
  579         }
  580         if (ra != ko->ko_nrela) {
  581                 panic("%s:%d: %s: lost rela", __func__, __LINE__,
  582                    ko->ko_name);
  583         }
  584         if (map_text_base != ko->ko_text_address + map_text_size) {
  585                 panic("%s:%d: %s: map_text_base 0x%lx != address %lx "
  586                     "+ map_text_size %ld (0x%lx)\n",
  587                     __func__, __LINE__, ko->ko_name, (long)map_text_base,
  588                     (long)ko->ko_text_address, (long)map_text_size,
  589                     (long)ko->ko_text_address + map_text_size);
  590         }
  591         if (map_data_base != ko->ko_data_address + map_data_size) {
  592                 panic("%s:%d: %s: map_data_base 0x%lx != address %lx "
  593                     "+ map_data_size %ld (0x%lx)\n",
  594                     __func__, __LINE__, ko->ko_name, (long)map_data_base,
  595                     (long)ko->ko_data_address, (long)map_data_size,
  596                     (long)ko->ko_data_address + map_data_size);
  597         }
  598         if (map_rodata_base != ko->ko_rodata_address + map_rodata_size) {
  599                 panic("%s:%d: %s: map_rodata_base 0x%lx != address %lx "
  600                     "+ map_rodata_size %ld (0x%lx)\n",
  601                     __func__, __LINE__, ko->ko_name, (long)map_rodata_base,
  602                     (long)ko->ko_rodata_address, (long)map_rodata_size,
  603                     (long)ko->ko_rodata_address + map_rodata_size);
  604         }
  605 
  606         /*
  607          * Perform local relocations only.  Relocations relating to global
  608          * symbols will be done by kobj_affix().
  609          */
  610         error = kobj_checksyms(ko, false);
  611         if (error)
  612                 goto out;
  613 
  614         error = kobj_relocate(ko, true);
  615         if (error)
  616                 goto out;
  617 out:
  618         if (hdr != NULL) {
  619                 kobj_free(ko, hdr, sizeof(*hdr));
  620         }
  621         kobj_close(ko);
  622         if (error != 0) {
  623                 kobj_unload(ko);
  624         }
  625 
  626         return error;
  627 }
  628 
  629 static void
  630 kobj_unload_notify(kobj_t ko, vaddr_t addr, size_t size, const char *note)
  631 {
  632         if (addr == 0)
  633                 return;
  634 
  635         int error = kobj_machdep(ko, (void *)addr, size, false);
  636         if (error)
  637                 kobj_error(ko, "machine dependent deinit failed (%s) %d",
  638                     note, error);
  639 }
  640 
  641 #define KOBJ_SEGMENT_NOTIFY(ko, what) \
  642     kobj_unload_notify(ko, (ko)->ko_ ## what ## _address, \
  643         (ko)->ko_ ## what ## _size, # what);
  644 
  645 #define KOBJ_SEGMENT_FREE(ko, what) \
  646     do \
  647         if ((ko)->ko_ ## what ## _address != 0) \
  648                 uvm_km_free(module_map, (ko)->ko_ ## what ## _address, \
  649                     round_page((ko)->ko_ ## what ## _size), UVM_KMF_WIRED); \
  650     while (/*CONSTCOND*/ 0)
  651 
  652 /*
  653  * kobj_unload:
  654  *
  655  *      Unload an object previously loaded by kobj_load().
  656  */
  657 void
  658 kobj_unload(kobj_t ko)
  659 {
  660         kobj_close(ko);
  661         kobj_jettison(ko);
  662 
  663 
  664         /*
  665          * Notify MD code that a module has been unloaded.
  666          */
  667         if (ko->ko_loaded) {
  668                 KOBJ_SEGMENT_NOTIFY(ko, text);
  669                 KOBJ_SEGMENT_NOTIFY(ko, data);
  670                 KOBJ_SEGMENT_NOTIFY(ko, rodata);
  671         }
  672 
  673         KOBJ_SEGMENT_FREE(ko, text);
  674         KOBJ_SEGMENT_FREE(ko, data);
  675         KOBJ_SEGMENT_FREE(ko, rodata);
  676 
  677         if (ko->ko_ksyms == true) {
  678                 ksyms_modunload(ko->ko_name);
  679         }
  680         if (ko->ko_symtab != NULL) {
  681                 kobj_free(ko, ko->ko_symtab, ko->ko_symcnt * sizeof(Elf_Sym));
  682         }
  683         if (ko->ko_strtab != NULL) {
  684                 kobj_free(ko, ko->ko_strtab, ko->ko_strtabsz);
  685         }
  686         if (ko->ko_progtab != NULL) {
  687                 kobj_free(ko, ko->ko_progtab, ko->ko_nprogtab *
  688                     sizeof(*ko->ko_progtab));
  689                 ko->ko_progtab = NULL;
  690         }
  691         if (ko->ko_shstrtab) {
  692                 kobj_free(ko, ko->ko_shstrtab, ko->ko_shstrtabsz);
  693                 ko->ko_shstrtab = NULL;
  694         }
  695 
  696         kmem_free(ko, sizeof(*ko));
  697 }
  698 
  699 /*
  700  * kobj_stat:
  701  *
  702  *      Return size and load address of an object.
  703  */
  704 int
  705 kobj_stat(kobj_t ko, vaddr_t *address, size_t *size)
  706 {
  707 
  708         if (address != NULL) {
  709                 *address = ko->ko_text_address;
  710         }
  711         if (size != NULL) {
  712                 *size = ko->ko_text_size;
  713         }
  714         return 0;
  715 }
  716 
  717 /*
  718  * kobj_affix:
  719  *
  720  *      Set an object's name and perform global relocs.  May only be
  721  *      called after the module and any requisite modules are loaded.
  722  */
  723 int
  724 kobj_affix(kobj_t ko, const char *name)
  725 {
  726         int error;
  727 
  728         KASSERT(ko->ko_ksyms == false);
  729         KASSERT(ko->ko_loaded == false);
  730 
  731         kobj_setname(ko, name);
  732 
  733         /* Cache addresses of undefined symbols. */
  734         error = kobj_checksyms(ko, true);
  735         if (error)
  736                 goto out;
  737 
  738         /* Now do global relocations. */
  739         error = kobj_relocate(ko, false);
  740         if (error)
  741                 goto out;
  742 
  743         /*
  744          * Now that we know the name, register the symbol table.
  745          * Do after global relocations because ksyms will pack
  746          * the table.
  747          */
  748         ksyms_modload(ko->ko_name, ko->ko_symtab,
  749             ko->ko_symcnt * sizeof(Elf_Sym), ko->ko_strtab, ko->ko_strtabsz);
  750         ko->ko_ksyms = true;
  751 
  752         /* Jettison unneeded memory post-link. */
  753         kobj_jettison(ko);
  754 
  755         /*
  756          * Notify MD code that a module has been loaded.
  757          *
  758          * Most architectures use this opportunity to flush their caches.
  759          */
  760         if (ko->ko_text_address != 0) {
  761                 error = kobj_machdep(ko, (void *)ko->ko_text_address,
  762                     ko->ko_text_size, true);
  763                 if (error) {
  764                         kobj_error(ko, "machine dependent init failed (text)"
  765                             " %d", error);
  766                         goto out;
  767                 }
  768         }
  769 
  770         if (ko->ko_data_address != 0) {
  771                 error = kobj_machdep(ko, (void *)ko->ko_data_address,
  772                     ko->ko_data_size, true);
  773                 if (error) {
  774                         kobj_error(ko, "machine dependent init failed (data)"
  775                             " %d", error);
  776                         goto out;
  777                 }
  778         }
  779 
  780         if (ko->ko_rodata_address != 0) {
  781                 error = kobj_machdep(ko, (void *)ko->ko_rodata_address,
  782                     ko->ko_rodata_size, true);
  783                 if (error) {
  784                         kobj_error(ko, "machine dependent init failed (rodata)"
  785                             " %d", error);
  786                         goto out;
  787                 }
  788         }
  789 
  790         ko->ko_loaded = true;
  791 
  792         /* Change the memory protections, when needed. */
  793         if (ko->ko_text_address != 0) {
  794                 uvm_km_protect(module_map, ko->ko_text_address,
  795                     ko->ko_text_size, VM_PROT_READ|VM_PROT_EXECUTE);
  796         }
  797         if (ko->ko_rodata_address != 0) {
  798                 uvm_km_protect(module_map, ko->ko_rodata_address,
  799                     ko->ko_rodata_size, VM_PROT_READ);
  800         }
  801 
  802         /* Success! */
  803         error = 0;
  804 
  805 out:    if (error) {
  806                 /* If there was an error, destroy the whole object. */
  807                 kobj_unload(ko);
  808         }
  809         return error;
  810 }
  811 
  812 /*
  813  * kobj_find_section:
  814  *
  815  *      Given a section name, search the loaded object and return
  816  *      virtual address if present and loaded.
  817  */
  818 int
  819 kobj_find_section(kobj_t ko, const char *name, void **addr, size_t *size)
  820 {
  821         int i;
  822 
  823         KASSERT(ko->ko_progtab != NULL);
  824 
  825         for (i = 0; i < ko->ko_nprogtab; i++) {
  826                 if (strcmp(ko->ko_progtab[i].name, name) == 0) {
  827                         if (addr != NULL) {
  828                                 *addr = ko->ko_progtab[i].addr;
  829                         }
  830                         if (size != NULL) {
  831                                 *size = ko->ko_progtab[i].size;
  832                         }
  833                         return 0;
  834                 }
  835         }
  836 
  837         return ENOENT;
  838 }
  839 
  840 /*
  841  * kobj_jettison:
  842  *
  843  *      Release object data not needed after performing relocations.
  844  */
  845 static void
  846 kobj_jettison(kobj_t ko)
  847 {
  848         int i;
  849 
  850         if (ko->ko_reltab != NULL) {
  851                 for (i = 0; i < ko->ko_nrel; i++) {
  852                         if (ko->ko_reltab[i].rel) {
  853                                 kobj_free(ko, ko->ko_reltab[i].rel,
  854                                     ko->ko_reltab[i].size);
  855                         }
  856                 }
  857                 kobj_free(ko, ko->ko_reltab, ko->ko_nrel *
  858                     sizeof(*ko->ko_reltab));
  859                 ko->ko_reltab = NULL;
  860                 ko->ko_nrel = 0;
  861         }
  862         if (ko->ko_relatab != NULL) {
  863                 for (i = 0; i < ko->ko_nrela; i++) {
  864                         if (ko->ko_relatab[i].rela) {
  865                                 kobj_free(ko, ko->ko_relatab[i].rela,
  866                                     ko->ko_relatab[i].size);
  867                         }
  868                 }
  869                 kobj_free(ko, ko->ko_relatab, ko->ko_nrela *
  870                     sizeof(*ko->ko_relatab));
  871                 ko->ko_relatab = NULL;
  872                 ko->ko_nrela = 0;
  873         }
  874         if (ko->ko_shdr != NULL) {
  875                 kobj_free(ko, ko->ko_shdr, ko->ko_shdrsz);
  876                 ko->ko_shdr = NULL;
  877         }
  878 }
  879 
  880 /*
  881  * kobj_sym_lookup:
  882  *
  883  *      Symbol lookup function to be used when the symbol index
  884  *      is known (ie during relocation).
  885  */
  886 int
  887 kobj_sym_lookup(kobj_t ko, uintptr_t symidx, Elf_Addr *val)
  888 {
  889         const Elf_Sym *sym;
  890         const char *symbol;
  891 
  892         sym = ko->ko_symtab + symidx;
  893 
  894         if (symidx == SHN_ABS || symidx == 0) {
  895                 *val = (uintptr_t)sym->st_value;
  896                 return 0;
  897         } else if (symidx >= ko->ko_symcnt) {
  898                 /*
  899                  * Don't even try to lookup the symbol if the index is
  900                  * bogus.
  901                  */
  902                 kobj_error(ko, "symbol index %ju out of range",
  903                     (uintmax_t)symidx);
  904                 return EINVAL;
  905         }
  906 
  907         /* Quick answer if there is a definition included. */
  908         if (sym->st_shndx != SHN_UNDEF) {
  909                 *val = (uintptr_t)sym->st_value;
  910                 return 0;
  911         }
  912 
  913         /* If we get here, then it is undefined and needs a lookup. */
  914         switch (ELF_ST_BIND(sym->st_info)) {
  915         case STB_LOCAL:
  916                 /* Local, but undefined? huh? */
  917                 kobj_error(ko, "local symbol @%ju undefined",
  918                     (uintmax_t)symidx);
  919                 return EINVAL;
  920 
  921         case STB_GLOBAL:
  922                 /* Relative to Data or Function name */
  923                 symbol = ko->ko_strtab + sym->st_name;
  924 
  925                 /* Force a lookup failure if the symbol name is bogus. */
  926                 if (*symbol == 0) {
  927                         kobj_error(ko, "bad symbol @%ju name",
  928                             (uintmax_t)symidx);
  929                         return EINVAL;
  930                 }
  931                 if (sym->st_value == 0) {
  932                         kobj_error(ko, "%s @%ju: bad value", symbol,
  933                             (uintmax_t)symidx);
  934                         return EINVAL;
  935                 }
  936 
  937                 *val = (uintptr_t)sym->st_value;
  938                 return 0;
  939 
  940         case STB_WEAK:
  941                 kobj_error(ko, "weak symbol @%ju not supported",
  942                     (uintmax_t)symidx);
  943                 return EINVAL;
  944 
  945         default:
  946                 kobj_error(ko, "bad binding %#x for symbol @%ju",
  947                     ELF_ST_BIND(sym->st_info), (uintmax_t)symidx);
  948                 return EINVAL;
  949         }
  950 }
  951 
  952 /*
  953  * kobj_findbase:
  954  *
  955  *      Return base address of the given section.
  956  */
  957 static uintptr_t
  958 kobj_findbase(kobj_t ko, int sec)
  959 {
  960         int i;
  961 
  962         for (i = 0; i < ko->ko_nprogtab; i++) {
  963                 if (sec == ko->ko_progtab[i].sec) {
  964                         return (uintptr_t)ko->ko_progtab[i].addr;
  965                 }
  966         }
  967         return 0;
  968 }
  969 
  970 /*
  971  * kobj_checksyms:
  972  *
  973  *      Scan symbol table for duplicates or resolve references to
  974  *      external symbols.
  975  */
  976 static int
  977 kobj_checksyms(kobj_t ko, bool undefined)
  978 {
  979         unsigned long rval;
  980         Elf_Sym *sym, *ksym, *ms;
  981         const char *name;
  982         int error;
  983 
  984         error = 0;
  985 
  986         for (ms = (sym = ko->ko_symtab) + ko->ko_symcnt; sym < ms; sym++) {
  987                 /* Check validity of the symbol. */
  988                 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL ||
  989                     sym->st_name == 0)
  990                         continue;
  991                 if (undefined != (sym->st_shndx == SHN_UNDEF)) {
  992                         continue;
  993                 }
  994 
  995                 /*
  996                  * Look it up.  Don't need to lock, as it is known that
  997                  * the symbol tables aren't going to change (we hold
  998                  * module_lock).
  999                  */
 1000                 name = ko->ko_strtab + sym->st_name;
 1001                 if (ksyms_getval_unlocked(NULL, name, &ksym, &rval,
 1002                     KSYMS_EXTERN) != 0) {
 1003                         if (undefined) {
 1004                                 kobj_error(ko, "symbol `%s' not found",
 1005                                     name);
 1006                                 error = ENOEXEC;
 1007                         }
 1008                         continue;
 1009                 }
 1010 
 1011                 /* Save values of undefined globals. */
 1012                 if (undefined) {
 1013                         if (ksym->st_shndx == SHN_ABS) {
 1014                                 sym->st_shndx = SHN_ABS;
 1015                         }
 1016                         sym->st_value = (Elf_Addr)rval;
 1017                         continue;
 1018                 }
 1019 
 1020                 /* Check (and complain) about differing values. */
 1021                 if (sym->st_value == rval) {
 1022                         continue;
 1023                 }
 1024                 if (strcmp(name, "_bss_start") == 0 ||
 1025                     strcmp(name, "__bss_start") == 0 ||
 1026                     strcmp(name, "_bss_end__") == 0 ||
 1027                     strcmp(name, "__bss_end__") == 0 ||
 1028                     strcmp(name, "_edata") == 0 ||
 1029                     strcmp(name, "_end") == 0 ||
 1030                     strcmp(name, "__end") == 0 ||
 1031                     strcmp(name, "__end__") == 0 ||
 1032                     strncmp(name, "__start_link_set_", 17) == 0 ||
 1033                     strncmp(name, "__stop_link_set_", 16) == 0) {
 1034                         continue;
 1035                 }
 1036                 kobj_error(ko, "global symbol `%s' redefined",
 1037                     name);
 1038                 error = ENOEXEC;
 1039         }
 1040 
 1041         return error;
 1042 }
 1043 
 1044 /*
 1045  * kobj_relocate:
 1046  *
 1047  *      Resolve relocations for the loaded object.
 1048  */
 1049 static int
 1050 kobj_relocate(kobj_t ko, bool local)
 1051 {
 1052         const Elf_Rel *rellim;
 1053         const Elf_Rel *rel;
 1054         const Elf_Rela *relalim;
 1055         const Elf_Rela *rela;
 1056         const Elf_Sym *sym;
 1057         uintptr_t base;
 1058         int i, error;
 1059         uintptr_t symidx;
 1060 
 1061         /*
 1062          * Perform relocations without addend if there are any.
 1063          */
 1064         for (i = 0; i < ko->ko_nrel; i++) {
 1065                 rel = ko->ko_reltab[i].rel;
 1066                 if (rel == NULL) {
 1067                         continue;
 1068                 }
 1069                 rellim = rel + ko->ko_reltab[i].nrel;
 1070                 base = kobj_findbase(ko, ko->ko_reltab[i].sec);
 1071                 if (base == 0) {
 1072                         panic("%s:%d: %s: lost base for e_reltab[%d] sec %d",
 1073                            __func__, __LINE__, ko->ko_name, i,
 1074                            ko->ko_reltab[i].sec);
 1075                 }
 1076                 for (; rel < rellim; rel++) {
 1077                         symidx = ELF_R_SYM(rel->r_info);
 1078                         if (symidx >= ko->ko_symcnt) {
 1079                                 continue;
 1080                         }
 1081                         sym = ko->ko_symtab + symidx;
 1082                         if (local != (ELF_ST_BIND(sym->st_info) == STB_LOCAL)) {
 1083                                 continue;
 1084                         }
 1085                         error = kobj_reloc(ko, base, rel, false, local);
 1086                         if (error != 0) {
 1087                                 kobj_error(ko, "unresolved rel relocation "
 1088                                     "@%#jx type=%d symidx=%d",
 1089                                     (intmax_t)rel->r_offset,
 1090                                     (int)ELF_R_TYPE(rel->r_info),
 1091                                     (int)ELF_R_SYM(rel->r_info));
 1092                                 return ENOEXEC;
 1093                         }
 1094                 }
 1095         }
 1096 
 1097         /*
 1098          * Perform relocations with addend if there are any.
 1099          */
 1100         for (i = 0; i < ko->ko_nrela; i++) {
 1101                 rela = ko->ko_relatab[i].rela;
 1102                 if (rela == NULL) {
 1103                         continue;
 1104                 }
 1105                 relalim = rela + ko->ko_relatab[i].nrela;
 1106                 base = kobj_findbase(ko, ko->ko_relatab[i].sec);
 1107                 if (base == 0) {
 1108                         panic("%s:%d: %s: lost base for e_relatab[%d] sec %d",
 1109                            __func__, __LINE__, ko->ko_name, i,
 1110                            ko->ko_relatab[i].sec);
 1111                 }
 1112                 for (; rela < relalim; rela++) {
 1113                         symidx = ELF_R_SYM(rela->r_info);
 1114                         if (symidx >= ko->ko_symcnt) {
 1115                                 continue;
 1116                         }
 1117                         sym = ko->ko_symtab + symidx;
 1118                         if (local != (ELF_ST_BIND(sym->st_info) == STB_LOCAL)) {
 1119                                 continue;
 1120                         }
 1121                         error = kobj_reloc(ko, base, rela, true, local);
 1122                         if (error != 0) {
 1123                                 kobj_error(ko, "unresolved rela relocation "
 1124                                     "@%#jx type=%d symidx=%d",
 1125                                     (intmax_t)rela->r_offset,
 1126                                     (int)ELF_R_TYPE(rela->r_info),
 1127                                     (int)ELF_R_SYM(rela->r_info));
 1128                                 return ENOEXEC;
 1129                         }
 1130                 }
 1131         }
 1132 
 1133         return 0;
 1134 }
 1135 
 1136 /*
 1137  * kobj_out:
 1138  *
 1139  *      Utility function: log an error.
 1140  */
 1141 static void
 1142 kobj_out(const char *fname, int lnum, kobj_t ko, const char *fmt, ...)
 1143 {
 1144         va_list ap;
 1145 
 1146         printf("%s, %d: [%s]: linker error: ", fname, lnum, ko->ko_name);
 1147         va_start(ap, fmt);
 1148         vprintf(fmt, ap);
 1149         va_end(ap);
 1150         printf("\n");
 1151 }
 1152 
 1153 static int
 1154 kobj_read_mem(kobj_t ko, void **basep, size_t size, off_t off,
 1155     bool allocate)
 1156 {
 1157         void *base = *basep;
 1158         int error = 0;
 1159 
 1160         KASSERT(ko->ko_source != NULL);
 1161 
 1162         if (off < 0) {
 1163                 kobj_error(ko, "negative offset %lld",
 1164                     (unsigned long long)off);
 1165                 error = EINVAL;
 1166                 base = NULL;
 1167                 goto out;
 1168         } else if (ko->ko_memsize != -1 &&
 1169             (size > ko->ko_memsize || off > ko->ko_memsize - size)) {
 1170                 kobj_error(ko, "preloaded object short");
 1171                 error = EINVAL;
 1172                 base = NULL;
 1173                 goto out;
 1174         }
 1175 
 1176         if (allocate)
 1177                 base = kmem_alloc(size, KM_SLEEP);
 1178 
 1179         /* Copy the section */
 1180         memcpy(base, (uint8_t *)ko->ko_source + off, size);
 1181 
 1182 out:    if (allocate)
 1183                 *basep = base;
 1184         return error;
 1185 }
 1186 
 1187 /*
 1188  * kobj_free:
 1189  *
 1190  *      Utility function: free memory if it was allocated from the heap.
 1191  */
 1192 static void
 1193 kobj_free(kobj_t ko, void *base, size_t size)
 1194 {
 1195 
 1196         kmem_free(base, size);
 1197 }
 1198 
 1199 void
 1200 kobj_setname(kobj_t ko, const char *name)
 1201 {
 1202         const char *d = name, *dots = "";
 1203         size_t len, dlen;
 1204 
 1205         for (char *s = module_base; *d == *s; d++, s++)
 1206                 continue;
 1207 
 1208         if (d == name)
 1209                 name = "";
 1210         else
 1211                 name = "%M";
 1212         dlen = strlen(d);
 1213         len = dlen + strlen(name);
 1214         if (len >= sizeof(ko->ko_name)) {
 1215                 len = (len - sizeof(ko->ko_name)) + 5; /* dots + NUL */
 1216                 if (dlen >= len) {
 1217                         d += len;
 1218                         dots = "/...";
 1219                 }
 1220         }
 1221         snprintf(ko->ko_name, sizeof(ko->ko_name), "%s%s%s", name, dots, d);
 1222 }
 1223 
 1224 #else   /* MODULAR */
 1225 
 1226 int
 1227 kobj_load_mem(kobj_t *kop, const char *name, void *base, ssize_t size)
 1228 {
 1229 
 1230         return ENOSYS;
 1231 }
 1232 
 1233 void
 1234 kobj_unload(kobj_t ko)
 1235 {
 1236 
 1237         panic("not modular");
 1238 }
 1239 
 1240 int
 1241 kobj_stat(kobj_t ko, vaddr_t *base, size_t *size)
 1242 {
 1243 
 1244         return ENOSYS;
 1245 }
 1246 
 1247 int
 1248 kobj_affix(kobj_t ko, const char *name)
 1249 {
 1250 
 1251         panic("not modular");
 1252 }
 1253 
 1254 int
 1255 kobj_find_section(kobj_t ko, const char *name, void **addr, size_t *size)
 1256 {
 1257 
 1258         panic("not modular");
 1259 }
 1260 
 1261 void
 1262 kobj_setname(kobj_t ko, const char *name)
 1263 {
 1264 
 1265         panic("not modular");
 1266 }
 1267 
 1268 #endif  /* MODULAR */

Cache object: 131911af7f51cc38293ecd0864ebb439


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.