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/link_elf.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 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 1998-2000 Doug Rabson
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include "opt_ddb.h"
   33 #include "opt_gdb.h"
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #ifdef GPROF
   38 #include <sys/gmon.h>
   39 #endif
   40 #include <sys/kernel.h>
   41 #include <sys/lock.h>
   42 #include <sys/malloc.h>
   43 #ifdef SPARSE_MAPPING
   44 #include <sys/mman.h>
   45 #endif
   46 #include <sys/mutex.h>
   47 #include <sys/mount.h>
   48 #include <sys/pcpu.h>
   49 #include <sys/proc.h>
   50 #include <sys/namei.h>
   51 #include <sys/fcntl.h>
   52 #include <sys/vnode.h>
   53 #include <sys/linker.h>
   54 
   55 #include <machine/elf.h>
   56 
   57 #include <net/vnet.h>
   58 
   59 #include <security/mac/mac_framework.h>
   60 
   61 #include <vm/vm.h>
   62 #include <vm/vm_param.h>
   63 #ifdef SPARSE_MAPPING
   64 #include <vm/vm_object.h>
   65 #include <vm/vm_kern.h>
   66 #include <vm/vm_extern.h>
   67 #endif
   68 #include <vm/pmap.h>
   69 #include <vm/vm_map.h>
   70 
   71 #include <sys/link_elf.h>
   72 
   73 #include "linker_if.h"
   74 
   75 #define MAXSEGS 4
   76 
   77 typedef struct elf_file {
   78         struct linker_file lf;          /* Common fields */
   79         int             preloaded;      /* Was file pre-loaded */
   80         caddr_t         address;        /* Relocation address */
   81 #ifdef SPARSE_MAPPING
   82         vm_object_t     object;         /* VM object to hold file pages */
   83 #endif
   84         Elf_Dyn         *dynamic;       /* Symbol table etc. */
   85         Elf_Hashelt     nbuckets;       /* DT_HASH info */
   86         Elf_Hashelt     nchains;
   87         const Elf_Hashelt *buckets;
   88         const Elf_Hashelt *chains;
   89         caddr_t         hash;
   90         caddr_t         strtab;         /* DT_STRTAB */
   91         int             strsz;          /* DT_STRSZ */
   92         const Elf_Sym   *symtab;                /* DT_SYMTAB */
   93         Elf_Addr        *got;           /* DT_PLTGOT */
   94         const Elf_Rel   *pltrel;        /* DT_JMPREL */
   95         int             pltrelsize;     /* DT_PLTRELSZ */
   96         const Elf_Rela  *pltrela;       /* DT_JMPREL */
   97         int             pltrelasize;    /* DT_PLTRELSZ */
   98         const Elf_Rel   *rel;           /* DT_REL */
   99         int             relsize;        /* DT_RELSZ */
  100         const Elf_Rela  *rela;          /* DT_RELA */
  101         int             relasize;       /* DT_RELASZ */
  102         caddr_t         modptr;
  103         const Elf_Sym   *ddbsymtab;     /* The symbol table we are using */
  104         long            ddbsymcnt;      /* Number of symbols */
  105         caddr_t         ddbstrtab;      /* String table */
  106         long            ddbstrcnt;      /* number of bytes in string table */
  107         caddr_t         symbase;        /* malloc'ed symbold base */
  108         caddr_t         strbase;        /* malloc'ed string base */
  109         caddr_t         ctftab;         /* CTF table */
  110         long            ctfcnt;         /* number of bytes in CTF table */
  111         caddr_t         ctfoff;         /* CTF offset table */
  112         caddr_t         typoff;         /* Type offset table */
  113         long            typlen;         /* Number of type entries. */
  114         Elf_Addr        pcpu_start;     /* Pre-relocation pcpu set start. */
  115         Elf_Addr        pcpu_stop;      /* Pre-relocation pcpu set stop. */
  116         Elf_Addr        pcpu_base;      /* Relocated pcpu set address. */
  117 #ifdef VIMAGE
  118         Elf_Addr        vnet_start;     /* Pre-relocation vnet set start. */
  119         Elf_Addr        vnet_stop;      /* Pre-relocation vnet set stop. */
  120         Elf_Addr        vnet_base;      /* Relocated vnet set address. */
  121 #endif
  122 #ifdef GDB
  123         struct link_map gdb;            /* hooks for gdb */
  124 #endif
  125 } *elf_file_t;
  126 
  127 struct elf_set {
  128         Elf_Addr        es_start;
  129         Elf_Addr        es_stop;
  130         Elf_Addr        es_base;
  131         TAILQ_ENTRY(elf_set)    es_link;
  132 };
  133 
  134 TAILQ_HEAD(elf_set_head, elf_set);
  135 
  136 #include <kern/kern_ctf.c>
  137 
  138 static int      link_elf_link_common_finish(linker_file_t);
  139 static int      link_elf_link_preload(linker_class_t cls,
  140                                       const char *, linker_file_t *);
  141 static int      link_elf_link_preload_finish(linker_file_t);
  142 static int      link_elf_load_file(linker_class_t, const char *,
  143                     linker_file_t *);
  144 static int      link_elf_lookup_symbol(linker_file_t, const char *,
  145                     c_linker_sym_t *);
  146 static int      link_elf_symbol_values(linker_file_t, c_linker_sym_t,
  147                     linker_symval_t *);
  148 static int      link_elf_search_symbol(linker_file_t, caddr_t,
  149                     c_linker_sym_t *, long *);
  150 
  151 static void     link_elf_unload_file(linker_file_t);
  152 static void     link_elf_unload_preload(linker_file_t);
  153 static int      link_elf_lookup_set(linker_file_t, const char *,
  154                     void ***, void ***, int *);
  155 static int      link_elf_each_function_name(linker_file_t,
  156                     int (*)(const char *, void *), void *);
  157 static int      link_elf_each_function_nameval(linker_file_t,
  158                     linker_function_nameval_callback_t, void *);
  159 static void     link_elf_reloc_local(linker_file_t);
  160 static long     link_elf_symtab_get(linker_file_t, const Elf_Sym **);
  161 static long     link_elf_strtab_get(linker_file_t, caddr_t *);
  162 static int      elf_lookup(linker_file_t, Elf_Size, int, Elf_Addr *);
  163 
  164 static kobj_method_t link_elf_methods[] = {
  165         KOBJMETHOD(linker_lookup_symbol,        link_elf_lookup_symbol),
  166         KOBJMETHOD(linker_symbol_values,        link_elf_symbol_values),
  167         KOBJMETHOD(linker_search_symbol,        link_elf_search_symbol),
  168         KOBJMETHOD(linker_unload,               link_elf_unload_file),
  169         KOBJMETHOD(linker_load_file,            link_elf_load_file),
  170         KOBJMETHOD(linker_link_preload,         link_elf_link_preload),
  171         KOBJMETHOD(linker_link_preload_finish,  link_elf_link_preload_finish),
  172         KOBJMETHOD(linker_lookup_set,           link_elf_lookup_set),
  173         KOBJMETHOD(linker_each_function_name,   link_elf_each_function_name),
  174         KOBJMETHOD(linker_each_function_nameval, link_elf_each_function_nameval),
  175         KOBJMETHOD(linker_ctf_get,              link_elf_ctf_get),
  176         KOBJMETHOD(linker_symtab_get,           link_elf_symtab_get),
  177         KOBJMETHOD(linker_strtab_get,           link_elf_strtab_get),
  178         KOBJMETHOD_END
  179 };
  180 
  181 static struct linker_class link_elf_class = {
  182 #if ELF_TARG_CLASS == ELFCLASS32
  183         "elf32",
  184 #else
  185         "elf64",
  186 #endif
  187         link_elf_methods, sizeof(struct elf_file)
  188 };
  189 
  190 typedef int (*elf_reloc_fn)(linker_file_t lf, Elf_Addr relocbase,
  191     const void *data, int type, elf_lookup_fn lookup);
  192 
  193 static int      parse_dynamic(elf_file_t);
  194 static int      relocate_file(elf_file_t);
  195 static int      relocate_file1(elf_file_t ef, elf_lookup_fn lookup,
  196                     elf_reloc_fn reloc, bool ifuncs);
  197 static int      link_elf_preload_parse_symbols(elf_file_t);
  198 
  199 static struct elf_set_head set_pcpu_list;
  200 #ifdef VIMAGE
  201 static struct elf_set_head set_vnet_list;
  202 #endif
  203 
  204 static void
  205 elf_set_add(struct elf_set_head *list, Elf_Addr start, Elf_Addr stop, Elf_Addr base)
  206 {
  207         struct elf_set *set, *iter;
  208 
  209         set = malloc(sizeof(*set), M_LINKER, M_WAITOK);
  210         set->es_start = start;
  211         set->es_stop = stop;
  212         set->es_base = base;
  213 
  214         TAILQ_FOREACH(iter, list, es_link) {
  215 
  216                 KASSERT((set->es_start < iter->es_start && set->es_stop < iter->es_stop) ||
  217                     (set->es_start > iter->es_start && set->es_stop > iter->es_stop),
  218                     ("linker sets intersection: to insert: 0x%jx-0x%jx; inserted: 0x%jx-0x%jx",
  219                     (uintmax_t)set->es_start, (uintmax_t)set->es_stop,
  220                     (uintmax_t)iter->es_start, (uintmax_t)iter->es_stop));
  221 
  222                 if (iter->es_start > set->es_start) {
  223                         TAILQ_INSERT_BEFORE(iter, set, es_link);
  224                         break;
  225                 }
  226         }
  227 
  228         if (iter == NULL)
  229                 TAILQ_INSERT_TAIL(list, set, es_link);
  230 }
  231 
  232 static int
  233 elf_set_find(struct elf_set_head *list, Elf_Addr addr, Elf_Addr *start, Elf_Addr *base)
  234 {
  235         struct elf_set *set;
  236 
  237         TAILQ_FOREACH(set, list, es_link) {
  238                 if (addr < set->es_start)
  239                         return (0);
  240                 if (addr < set->es_stop) {
  241                         *start = set->es_start;
  242                         *base = set->es_base;
  243                         return (1);
  244                 }
  245         }
  246 
  247         return (0);
  248 }
  249 
  250 static void
  251 elf_set_delete(struct elf_set_head *list, Elf_Addr start)
  252 {
  253         struct elf_set *set;
  254 
  255         TAILQ_FOREACH(set, list, es_link) {
  256                 if (start < set->es_start)
  257                         break;
  258                 if (start == set->es_start) {
  259                         TAILQ_REMOVE(list, set, es_link);
  260                         free(set, M_LINKER);
  261                         return;
  262                 }
  263         }
  264         KASSERT(0, ("deleting unknown linker set (start = 0x%jx)",
  265             (uintmax_t)start));
  266 }
  267 
  268 #ifdef GDB
  269 static void     r_debug_state(struct r_debug *, struct link_map *);
  270 
  271 /*
  272  * A list of loaded modules for GDB to use for loading symbols.
  273  */
  274 struct r_debug r_debug;
  275 
  276 #define GDB_STATE(s) do {                               \
  277         r_debug.r_state = s; r_debug_state(NULL, NULL); \
  278 } while (0)
  279 
  280 /*
  281  * Function for the debugger to set a breakpoint on to gain control.
  282  */
  283 static void
  284 r_debug_state(struct r_debug *dummy_one __unused,
  285               struct link_map *dummy_two __unused)
  286 {
  287 }
  288 
  289 static void
  290 link_elf_add_gdb(struct link_map *l)
  291 {
  292         struct link_map *prev;
  293 
  294         l->l_next = NULL;
  295 
  296         if (r_debug.r_map == NULL) {
  297                 /* Add first. */
  298                 l->l_prev = NULL;
  299                 r_debug.r_map = l;
  300         } else {
  301                 /* Append to list. */
  302                 for (prev = r_debug.r_map;
  303                     prev->l_next != NULL;
  304                     prev = prev->l_next)
  305                         ;
  306                 l->l_prev = prev;
  307                 prev->l_next = l;
  308         }
  309 }
  310 
  311 static void
  312 link_elf_delete_gdb(struct link_map *l)
  313 {
  314         if (l->l_prev == NULL) {
  315                 /* Remove first. */
  316                 if ((r_debug.r_map = l->l_next) != NULL)
  317                         l->l_next->l_prev = NULL;
  318         } else {
  319                 /* Remove any but first. */
  320                 if ((l->l_prev->l_next = l->l_next) != NULL)
  321                         l->l_next->l_prev = l->l_prev;
  322         }
  323 }
  324 #endif /* GDB */
  325 
  326 /*
  327  * The kernel symbol table starts here.
  328  */
  329 extern struct _dynamic _DYNAMIC;
  330 
  331 static void
  332 link_elf_error(const char *filename, const char *s)
  333 {
  334         if (filename == NULL)
  335                 printf("kldload: %s\n", s);
  336         else
  337                 printf("kldload: %s: %s\n", filename, s);
  338 }
  339 
  340 static void
  341 link_elf_invoke_ctors(caddr_t addr, size_t size)
  342 {
  343         void (**ctor)(void);
  344         size_t i, cnt;
  345 
  346         if (addr == NULL || size == 0)
  347                 return;
  348         cnt = size / sizeof(*ctor);
  349         ctor = (void *)addr;
  350         for (i = 0; i < cnt; i++) {
  351                 if (ctor[i] != NULL)
  352                         (*ctor[i])();
  353         }
  354 }
  355 
  356 /*
  357  * Actions performed after linking/loading both the preloaded kernel and any
  358  * modules; whether preloaded or dynamicly loaded.
  359  */
  360 static int
  361 link_elf_link_common_finish(linker_file_t lf)
  362 {
  363 #ifdef GDB
  364         elf_file_t ef = (elf_file_t)lf;
  365         char *newfilename;
  366 #endif
  367         int error;
  368 
  369         /* Notify MD code that a module is being loaded. */
  370         error = elf_cpu_load_file(lf);
  371         if (error != 0)
  372                 return (error);
  373 
  374 #ifdef GDB
  375         GDB_STATE(RT_ADD);
  376         ef->gdb.l_addr = lf->address;
  377         newfilename = malloc(strlen(lf->filename) + 1, M_LINKER, M_WAITOK);
  378         strcpy(newfilename, lf->filename);
  379         ef->gdb.l_name = newfilename;
  380         ef->gdb.l_ld = ef->dynamic;
  381         link_elf_add_gdb(&ef->gdb);
  382         GDB_STATE(RT_CONSISTENT);
  383 #endif
  384 
  385         /* Invoke .ctors */
  386         link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size);
  387         return (0);
  388 }
  389 
  390 extern vm_offset_t __startkernel, __endkernel;
  391 
  392 static void
  393 link_elf_init(void* arg)
  394 {
  395         Elf_Dyn *dp;
  396         Elf_Addr *ctors_addrp;
  397         Elf_Size *ctors_sizep;
  398         caddr_t modptr, baseptr, sizeptr;
  399         elf_file_t ef;
  400         char *modname;
  401 
  402         linker_add_class(&link_elf_class);
  403 
  404         dp = (Elf_Dyn *)&_DYNAMIC;
  405         modname = NULL;
  406         modptr = preload_search_by_type("elf" __XSTRING(__ELF_WORD_SIZE) " kernel");
  407         if (modptr == NULL)
  408                 modptr = preload_search_by_type("elf kernel");
  409         modname = (char *)preload_search_info(modptr, MODINFO_NAME);
  410         if (modname == NULL)
  411                 modname = "kernel";
  412         linker_kernel_file = linker_make_file(modname, &link_elf_class);
  413         if (linker_kernel_file == NULL)
  414                 panic("%s: Can't create linker structures for kernel",
  415                     __func__);
  416 
  417         ef = (elf_file_t) linker_kernel_file;
  418         ef->preloaded = 1;
  419 #ifdef __powerpc__
  420         ef->address = (caddr_t) (__startkernel - KERNBASE);
  421 #else
  422         ef->address = 0;
  423 #endif
  424 #ifdef SPARSE_MAPPING
  425         ef->object = NULL;
  426 #endif
  427         ef->dynamic = dp;
  428 
  429         if (dp != NULL)
  430                 parse_dynamic(ef);
  431 #ifdef __powerpc__
  432         linker_kernel_file->address = (caddr_t)__startkernel;
  433         linker_kernel_file->size = (intptr_t)(__endkernel - __startkernel);
  434 #else
  435         linker_kernel_file->address += KERNBASE;
  436         linker_kernel_file->size = -(intptr_t)linker_kernel_file->address;
  437 #endif
  438 
  439         if (modptr != NULL) {
  440                 ef->modptr = modptr;
  441                 baseptr = preload_search_info(modptr, MODINFO_ADDR);
  442                 if (baseptr != NULL)
  443                         linker_kernel_file->address = *(caddr_t *)baseptr;
  444                 sizeptr = preload_search_info(modptr, MODINFO_SIZE);
  445                 if (sizeptr != NULL)
  446                         linker_kernel_file->size = *(size_t *)sizeptr;
  447                 ctors_addrp = (Elf_Addr *)preload_search_info(modptr,
  448                         MODINFO_METADATA | MODINFOMD_CTORS_ADDR);
  449                 ctors_sizep = (Elf_Size *)preload_search_info(modptr,
  450                         MODINFO_METADATA | MODINFOMD_CTORS_SIZE);
  451                 if (ctors_addrp != NULL && ctors_sizep != NULL) {
  452                         linker_kernel_file->ctors_addr = ef->address +
  453                             *ctors_addrp;
  454                         linker_kernel_file->ctors_size = *ctors_sizep;
  455                 }
  456         }
  457         (void)link_elf_preload_parse_symbols(ef);
  458 
  459 #ifdef GDB
  460         r_debug.r_map = NULL;
  461         r_debug.r_brk = r_debug_state;
  462         r_debug.r_state = RT_CONSISTENT;
  463 #endif
  464 
  465         (void)link_elf_link_common_finish(linker_kernel_file);
  466         linker_kernel_file->flags |= LINKER_FILE_LINKED;
  467         TAILQ_INIT(&set_pcpu_list);
  468 #ifdef VIMAGE
  469         TAILQ_INIT(&set_vnet_list);
  470 #endif
  471 }
  472 
  473 SYSINIT(link_elf, SI_SUB_KLD, SI_ORDER_THIRD, link_elf_init, NULL);
  474 
  475 static int
  476 link_elf_preload_parse_symbols(elf_file_t ef)
  477 {
  478         caddr_t pointer;
  479         caddr_t ssym, esym, base;
  480         caddr_t strtab;
  481         int strcnt;
  482         Elf_Sym *symtab;
  483         int symcnt;
  484 
  485         if (ef->modptr == NULL)
  486                 return (0);
  487         pointer = preload_search_info(ef->modptr,
  488             MODINFO_METADATA | MODINFOMD_SSYM);
  489         if (pointer == NULL)
  490                 return (0);
  491         ssym = *(caddr_t *)pointer;
  492         pointer = preload_search_info(ef->modptr,
  493             MODINFO_METADATA | MODINFOMD_ESYM);
  494         if (pointer == NULL)
  495                 return (0);
  496         esym = *(caddr_t *)pointer;
  497 
  498         base = ssym;
  499 
  500         symcnt = *(long *)base;
  501         base += sizeof(long);
  502         symtab = (Elf_Sym *)base;
  503         base += roundup(symcnt, sizeof(long));
  504 
  505         if (base > esym || base < ssym) {
  506                 printf("Symbols are corrupt!\n");
  507                 return (EINVAL);
  508         }
  509 
  510         strcnt = *(long *)base;
  511         base += sizeof(long);
  512         strtab = base;
  513         base += roundup(strcnt, sizeof(long));
  514 
  515         if (base > esym || base < ssym) {
  516                 printf("Symbols are corrupt!\n");
  517                 return (EINVAL);
  518         }
  519 
  520         ef->ddbsymtab = symtab;
  521         ef->ddbsymcnt = symcnt / sizeof(Elf_Sym);
  522         ef->ddbstrtab = strtab;
  523         ef->ddbstrcnt = strcnt;
  524 
  525         return (0);
  526 }
  527 
  528 static int
  529 parse_dynamic(elf_file_t ef)
  530 {
  531         Elf_Dyn *dp;
  532         int plttype = DT_REL;
  533 
  534         for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) {
  535                 switch (dp->d_tag) {
  536                 case DT_HASH:
  537                 {
  538                         /* From src/libexec/rtld-elf/rtld.c */
  539                         const Elf_Hashelt *hashtab = (const Elf_Hashelt *)
  540                             (ef->address + dp->d_un.d_ptr);
  541                         ef->nbuckets = hashtab[0];
  542                         ef->nchains = hashtab[1];
  543                         ef->buckets = hashtab + 2;
  544                         ef->chains = ef->buckets + ef->nbuckets;
  545                         break;
  546                 }
  547                 case DT_STRTAB:
  548                         ef->strtab = (caddr_t) (ef->address + dp->d_un.d_ptr);
  549                         break;
  550                 case DT_STRSZ:
  551                         ef->strsz = dp->d_un.d_val;
  552                         break;
  553                 case DT_SYMTAB:
  554                         ef->symtab = (Elf_Sym*) (ef->address + dp->d_un.d_ptr);
  555                         break;
  556                 case DT_SYMENT:
  557                         if (dp->d_un.d_val != sizeof(Elf_Sym))
  558                                 return (ENOEXEC);
  559                         break;
  560                 case DT_PLTGOT:
  561                         ef->got = (Elf_Addr *) (ef->address + dp->d_un.d_ptr);
  562                         break;
  563                 case DT_REL:
  564                         ef->rel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr);
  565                         break;
  566                 case DT_RELSZ:
  567                         ef->relsize = dp->d_un.d_val;
  568                         break;
  569                 case DT_RELENT:
  570                         if (dp->d_un.d_val != sizeof(Elf_Rel))
  571                                 return (ENOEXEC);
  572                         break;
  573                 case DT_JMPREL:
  574                         ef->pltrel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr);
  575                         break;
  576                 case DT_PLTRELSZ:
  577                         ef->pltrelsize = dp->d_un.d_val;
  578                         break;
  579                 case DT_RELA:
  580                         ef->rela = (const Elf_Rela *) (ef->address + dp->d_un.d_ptr);
  581                         break;
  582                 case DT_RELASZ:
  583                         ef->relasize = dp->d_un.d_val;
  584                         break;
  585                 case DT_RELAENT:
  586                         if (dp->d_un.d_val != sizeof(Elf_Rela))
  587                                 return (ENOEXEC);
  588                         break;
  589                 case DT_PLTREL:
  590                         plttype = dp->d_un.d_val;
  591                         if (plttype != DT_REL && plttype != DT_RELA)
  592                                 return (ENOEXEC);
  593                         break;
  594 #ifdef GDB
  595                 case DT_DEBUG:
  596                         dp->d_un.d_ptr = (Elf_Addr)&r_debug;
  597                         break;
  598 #endif
  599                 }
  600         }
  601 
  602         if (plttype == DT_RELA) {
  603                 ef->pltrela = (const Elf_Rela *)ef->pltrel;
  604                 ef->pltrel = NULL;
  605                 ef->pltrelasize = ef->pltrelsize;
  606                 ef->pltrelsize = 0;
  607         }
  608 
  609         ef->ddbsymtab = ef->symtab;
  610         ef->ddbsymcnt = ef->nchains;
  611         ef->ddbstrtab = ef->strtab;
  612         ef->ddbstrcnt = ef->strsz;
  613 
  614         return (0);
  615 }
  616 
  617 static int
  618 parse_dpcpu(elf_file_t ef)
  619 {
  620         int error, size;
  621 
  622         ef->pcpu_start = 0;
  623         ef->pcpu_stop = 0;
  624         error = link_elf_lookup_set(&ef->lf, "pcpu", (void ***)&ef->pcpu_start,
  625             (void ***)&ef->pcpu_stop, NULL);
  626         /* Error just means there is no pcpu set to relocate. */
  627         if (error != 0)
  628                 return (0);
  629         size = (uintptr_t)ef->pcpu_stop - (uintptr_t)ef->pcpu_start;
  630         /* Empty set? */
  631         if (size < 1)
  632                 return (0);
  633         /*
  634          * Allocate space in the primary pcpu area.  Copy in our
  635          * initialization from the data section and then initialize
  636          * all per-cpu storage from that.
  637          */
  638         ef->pcpu_base = (Elf_Addr)(uintptr_t)dpcpu_alloc(size);
  639         if (ef->pcpu_base == 0) {
  640                 printf("%s: pcpu module space is out of space; "
  641                     "cannot allocate %d for %s\n",
  642                     __func__, size, ef->lf.pathname);
  643                 return (ENOSPC);
  644         }
  645         memcpy((void *)ef->pcpu_base, (void *)ef->pcpu_start, size);
  646         dpcpu_copy((void *)ef->pcpu_base, size);
  647         elf_set_add(&set_pcpu_list, ef->pcpu_start, ef->pcpu_stop,
  648             ef->pcpu_base);
  649 
  650         return (0);
  651 }
  652 
  653 #ifdef VIMAGE
  654 static int
  655 parse_vnet(elf_file_t ef)
  656 {
  657         int error, size;
  658 
  659         ef->vnet_start = 0;
  660         ef->vnet_stop = 0;
  661         error = link_elf_lookup_set(&ef->lf, "vnet", (void ***)&ef->vnet_start,
  662             (void ***)&ef->vnet_stop, NULL);
  663         /* Error just means there is no vnet data set to relocate. */
  664         if (error != 0)
  665                 return (0);
  666         size = (uintptr_t)ef->vnet_stop - (uintptr_t)ef->vnet_start;
  667         /* Empty set? */
  668         if (size < 1)
  669                 return (0);
  670         /*
  671          * Allocate space in the primary vnet area.  Copy in our
  672          * initialization from the data section and then initialize
  673          * all per-vnet storage from that.
  674          */
  675         ef->vnet_base = (Elf_Addr)(uintptr_t)vnet_data_alloc(size);
  676         if (ef->vnet_base == 0) {
  677                 printf("%s: vnet module space is out of space; "
  678                     "cannot allocate %d for %s\n",
  679                     __func__, size, ef->lf.pathname);
  680                 return (ENOSPC);
  681         }
  682         memcpy((void *)ef->vnet_base, (void *)ef->vnet_start, size);
  683         vnet_data_copy((void *)ef->vnet_base, size);
  684         elf_set_add(&set_vnet_list, ef->vnet_start, ef->vnet_stop,
  685             ef->vnet_base);
  686 
  687         return (0);
  688 }
  689 #endif
  690 
  691 #ifdef __arm__
  692 /*
  693  * Locate the ARM exception/unwind table info for DDB and stack(9) use by
  694  * searching for the section header that describes it.  There may be no unwind
  695  * info, for example in a module containing only data.
  696  */
  697 static void
  698 link_elf_locate_exidx(linker_file_t lf, Elf_Shdr *shdr, int nhdr)
  699 {
  700         int i;
  701 
  702         for (i = 0; i < nhdr; i++) {
  703                 if (shdr[i].sh_type == SHT_ARM_EXIDX) {
  704                         lf->exidx_addr = shdr[i].sh_addr + lf->address;
  705                         lf->exidx_size = shdr[i].sh_size;
  706                         break;
  707                 }
  708         }
  709 }
  710 
  711 /*
  712  * Locate the section headers metadata in a preloaded module, then use it to
  713  * locate the exception/unwind table in the module.  The size of the metadata
  714  * block is stored in a uint32 word immediately before the data itself, and a
  715  * comment in preload_search_info() says it is safe to rely on that.
  716  */
  717 static void
  718 link_elf_locate_exidx_preload(struct linker_file *lf, caddr_t modptr)
  719 {
  720         uint32_t *modinfo;
  721         Elf_Shdr *shdr;
  722         uint32_t  nhdr;
  723 
  724         modinfo = (uint32_t *)preload_search_info(modptr,
  725             MODINFO_METADATA | MODINFOMD_SHDR);
  726         if (modinfo != NULL) {
  727                 shdr = (Elf_Shdr *)modinfo;
  728                 nhdr = modinfo[-1] / sizeof(Elf_Shdr);
  729                 link_elf_locate_exidx(lf, shdr, nhdr);
  730         }
  731 }
  732 
  733 #endif /* __arm__ */
  734 
  735 static int
  736 link_elf_link_preload(linker_class_t cls,
  737     const char* filename, linker_file_t *result)
  738 {
  739         Elf_Addr *ctors_addrp;
  740         Elf_Size *ctors_sizep;
  741         caddr_t modptr, baseptr, sizeptr, dynptr;
  742         char *type;
  743         elf_file_t ef;
  744         linker_file_t lf;
  745         int error;
  746         vm_offset_t dp;
  747 
  748         /* Look to see if we have the file preloaded */
  749         modptr = preload_search_by_name(filename);
  750         if (modptr == NULL)
  751                 return (ENOENT);
  752 
  753         type = (char *)preload_search_info(modptr, MODINFO_TYPE);
  754         baseptr = preload_search_info(modptr, MODINFO_ADDR);
  755         sizeptr = preload_search_info(modptr, MODINFO_SIZE);
  756         dynptr = preload_search_info(modptr,
  757             MODINFO_METADATA | MODINFOMD_DYNAMIC);
  758         if (type == NULL ||
  759             (strcmp(type, "elf" __XSTRING(__ELF_WORD_SIZE) " module") != 0 &&
  760              strcmp(type, "elf module") != 0))
  761                 return (EFTYPE);
  762         if (baseptr == NULL || sizeptr == NULL || dynptr == NULL)
  763                 return (EINVAL);
  764 
  765         lf = linker_make_file(filename, &link_elf_class);
  766         if (lf == NULL)
  767                 return (ENOMEM);
  768 
  769         ef = (elf_file_t) lf;
  770         ef->preloaded = 1;
  771         ef->modptr = modptr;
  772         ef->address = *(caddr_t *)baseptr;
  773 #ifdef SPARSE_MAPPING
  774         ef->object = NULL;
  775 #endif
  776         dp = (vm_offset_t)ef->address + *(vm_offset_t *)dynptr;
  777         ef->dynamic = (Elf_Dyn *)dp;
  778         lf->address = ef->address;
  779         lf->size = *(size_t *)sizeptr;
  780 
  781         ctors_addrp = (Elf_Addr *)preload_search_info(modptr,
  782             MODINFO_METADATA | MODINFOMD_CTORS_ADDR);
  783         ctors_sizep = (Elf_Size *)preload_search_info(modptr,
  784             MODINFO_METADATA | MODINFOMD_CTORS_SIZE);
  785         if (ctors_addrp != NULL && ctors_sizep != NULL) {
  786                 lf->ctors_addr = ef->address + *ctors_addrp;
  787                 lf->ctors_size = *ctors_sizep;
  788         }
  789 
  790 #ifdef __arm__
  791         link_elf_locate_exidx_preload(lf, modptr);
  792 #endif
  793 
  794         error = parse_dynamic(ef);
  795         if (error == 0)
  796                 error = parse_dpcpu(ef);
  797 #ifdef VIMAGE
  798         if (error == 0)
  799                 error = parse_vnet(ef);
  800 #endif
  801         if (error != 0) {
  802                 linker_file_unload(lf, LINKER_UNLOAD_FORCE);
  803                 return (error);
  804         }
  805         link_elf_reloc_local(lf);
  806         *result = lf;
  807         return (0);
  808 }
  809 
  810 static int
  811 link_elf_link_preload_finish(linker_file_t lf)
  812 {
  813         elf_file_t ef;
  814         int error;
  815 
  816         ef = (elf_file_t) lf;
  817         error = relocate_file(ef);
  818         if (error != 0)
  819                 return (error);
  820         (void)link_elf_preload_parse_symbols(ef);
  821 
  822         return (link_elf_link_common_finish(lf));
  823 }
  824 
  825 static int
  826 link_elf_load_file(linker_class_t cls, const char* filename,
  827     linker_file_t* result)
  828 {
  829         struct nameidata nd;
  830         struct thread* td = curthread;  /* XXX */
  831         Elf_Ehdr *hdr;
  832         caddr_t firstpage, segbase;
  833         int nbytes, i;
  834         Elf_Phdr *phdr;
  835         Elf_Phdr *phlimit;
  836         Elf_Phdr *segs[MAXSEGS];
  837         int nsegs;
  838         Elf_Phdr *phdyn;
  839         caddr_t mapbase;
  840         size_t mapsize;
  841         Elf_Addr base_vaddr;
  842         Elf_Addr base_vlimit;
  843         int error = 0;
  844         ssize_t resid;
  845         int flags;
  846         elf_file_t ef;
  847         linker_file_t lf;
  848         Elf_Shdr *shdr;
  849         int symtabindex;
  850         int symstrindex;
  851         int shstrindex;
  852         int symcnt;
  853         int strcnt;
  854         char *shstrs;
  855 
  856         shdr = NULL;
  857         lf = NULL;
  858         shstrs = NULL;
  859 
  860         NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td);
  861         flags = FREAD;
  862         error = vn_open(&nd, &flags, 0, NULL);
  863         if (error != 0)
  864                 return (error);
  865         NDFREE(&nd, NDF_ONLY_PNBUF);
  866         if (nd.ni_vp->v_type != VREG) {
  867                 error = ENOEXEC;
  868                 firstpage = NULL;
  869                 goto out;
  870         }
  871 #ifdef MAC
  872         error = mac_kld_check_load(curthread->td_ucred, nd.ni_vp);
  873         if (error != 0) {
  874                 firstpage = NULL;
  875                 goto out;
  876         }
  877 #endif
  878 
  879         /*
  880          * Read the elf header from the file.
  881          */
  882         firstpage = malloc(PAGE_SIZE, M_LINKER, M_WAITOK);
  883         hdr = (Elf_Ehdr *)firstpage;
  884         error = vn_rdwr(UIO_READ, nd.ni_vp, firstpage, PAGE_SIZE, 0,
  885             UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
  886             &resid, td);
  887         nbytes = PAGE_SIZE - resid;
  888         if (error != 0)
  889                 goto out;
  890 
  891         if (!IS_ELF(*hdr)) {
  892                 error = ENOEXEC;
  893                 goto out;
  894         }
  895 
  896         if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
  897             hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
  898                 link_elf_error(filename, "Unsupported file layout");
  899                 error = ENOEXEC;
  900                 goto out;
  901         }
  902         if (hdr->e_ident[EI_VERSION] != EV_CURRENT ||
  903             hdr->e_version != EV_CURRENT) {
  904                 link_elf_error(filename, "Unsupported file version");
  905                 error = ENOEXEC;
  906                 goto out;
  907         }
  908         if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) {
  909                 error = ENOSYS;
  910                 goto out;
  911         }
  912         if (hdr->e_machine != ELF_TARG_MACH) {
  913                 link_elf_error(filename, "Unsupported machine");
  914                 error = ENOEXEC;
  915                 goto out;
  916         }
  917 
  918         /*
  919          * We rely on the program header being in the first page.
  920          * This is not strictly required by the ABI specification, but
  921          * it seems to always true in practice.  And, it simplifies
  922          * things considerably.
  923          */
  924         if (!((hdr->e_phentsize == sizeof(Elf_Phdr)) &&
  925               (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= PAGE_SIZE) &&
  926               (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= nbytes)))
  927                 link_elf_error(filename, "Unreadable program headers");
  928 
  929         /*
  930          * Scan the program header entries, and save key information.
  931          *
  932          * We rely on there being exactly two load segments, text and data,
  933          * in that order.
  934          */
  935         phdr = (Elf_Phdr *) (firstpage + hdr->e_phoff);
  936         phlimit = phdr + hdr->e_phnum;
  937         nsegs = 0;
  938         phdyn = NULL;
  939         while (phdr < phlimit) {
  940                 switch (phdr->p_type) {
  941                 case PT_LOAD:
  942                         if (nsegs == MAXSEGS) {
  943                                 link_elf_error(filename, "Too many sections");
  944                                 error = ENOEXEC;
  945                                 goto out;
  946                         }
  947                         /*
  948                          * XXX: We just trust they come in right order ??
  949                          */
  950                         segs[nsegs] = phdr;
  951                         ++nsegs;
  952                         break;
  953 
  954                 case PT_DYNAMIC:
  955                         phdyn = phdr;
  956                         break;
  957 
  958                 case PT_INTERP:
  959                         error = ENOSYS;
  960                         goto out;
  961                 }
  962 
  963                 ++phdr;
  964         }
  965         if (phdyn == NULL) {
  966                 link_elf_error(filename, "Object is not dynamically-linked");
  967                 error = ENOEXEC;
  968                 goto out;
  969         }
  970         if (nsegs == 0) {
  971                 link_elf_error(filename, "No sections");
  972                 error = ENOEXEC;
  973                 goto out;
  974         }
  975 
  976         /*
  977          * Allocate the entire address space of the object, to stake
  978          * out our contiguous region, and to establish the base
  979          * address for relocation.
  980          */
  981         base_vaddr = trunc_page(segs[0]->p_vaddr);
  982         base_vlimit = round_page(segs[nsegs - 1]->p_vaddr +
  983             segs[nsegs - 1]->p_memsz);
  984         mapsize = base_vlimit - base_vaddr;
  985 
  986         lf = linker_make_file(filename, &link_elf_class);
  987         if (lf == NULL) {
  988                 error = ENOMEM;
  989                 goto out;
  990         }
  991 
  992         ef = (elf_file_t) lf;
  993 #ifdef SPARSE_MAPPING
  994         ef->object = vm_pager_allocate(OBJT_PHYS, NULL, mapsize, VM_PROT_ALL,
  995             0, thread0.td_ucred);
  996         if (ef->object == NULL) {
  997                 error = ENOMEM;
  998                 goto out;
  999         }
 1000 #ifdef __amd64__
 1001         mapbase = (caddr_t)KERNBASE;
 1002 #else
 1003         mapbase = (caddr_t)vm_map_min(kernel_map);
 1004 #endif
 1005         /*
 1006          * Mapping protections are downgraded after relocation processing.
 1007          */
 1008         error = vm_map_find(kernel_map, ef->object, 0,
 1009             (vm_offset_t *)&mapbase, mapsize, 0, VMFS_OPTIMAL_SPACE,
 1010             VM_PROT_ALL, VM_PROT_ALL, 0);
 1011         if (error != 0) {
 1012                 vm_object_deallocate(ef->object);
 1013                 ef->object = NULL;
 1014                 goto out;
 1015         }
 1016 #else
 1017         mapbase = malloc(mapsize, M_LINKER, M_EXEC | M_WAITOK);
 1018 #endif
 1019         ef->address = mapbase;
 1020 
 1021         /*
 1022          * Read the text and data sections and zero the bss.
 1023          */
 1024         for (i = 0; i < nsegs; i++) {
 1025                 segbase = mapbase + segs[i]->p_vaddr - base_vaddr;
 1026 
 1027 #ifdef SPARSE_MAPPING
 1028                 /*
 1029                  * Consecutive segments may have different mapping permissions,
 1030                  * so be strict and verify that their mappings do not overlap.
 1031                  */
 1032                 if (((vm_offset_t)segbase & PAGE_MASK) != 0) {
 1033                         error = EINVAL;
 1034                         goto out;
 1035                 }
 1036 
 1037                 error = vm_map_wire(kernel_map,
 1038                     (vm_offset_t)segbase,
 1039                     (vm_offset_t)segbase + round_page(segs[i]->p_memsz),
 1040                     VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES);
 1041                 if (error != KERN_SUCCESS) {
 1042                         error = ENOMEM;
 1043                         goto out;
 1044                 }
 1045 #endif
 1046 
 1047                 error = vn_rdwr(UIO_READ, nd.ni_vp,
 1048                     segbase, segs[i]->p_filesz, segs[i]->p_offset,
 1049                     UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
 1050                     &resid, td);
 1051                 if (error != 0)
 1052                         goto out;
 1053                 bzero(segbase + segs[i]->p_filesz,
 1054                     segs[i]->p_memsz - segs[i]->p_filesz);
 1055         }
 1056 
 1057 #ifdef GPROF
 1058         /* Update profiling information with the new text segment. */
 1059         mtx_lock(&Giant);
 1060         kmupetext((uintfptr_t)(mapbase + segs[0]->p_vaddr - base_vaddr +
 1061             segs[0]->p_memsz));
 1062         mtx_unlock(&Giant);
 1063 #endif
 1064 
 1065         ef->dynamic = (Elf_Dyn *) (mapbase + phdyn->p_vaddr - base_vaddr);
 1066 
 1067         lf->address = ef->address;
 1068         lf->size = mapsize;
 1069 
 1070         error = parse_dynamic(ef);
 1071         if (error != 0)
 1072                 goto out;
 1073         error = parse_dpcpu(ef);
 1074         if (error != 0)
 1075                 goto out;
 1076 #ifdef VIMAGE
 1077         error = parse_vnet(ef);
 1078         if (error != 0)
 1079                 goto out;
 1080 #endif
 1081         link_elf_reloc_local(lf);
 1082 
 1083         VOP_UNLOCK(nd.ni_vp, 0);
 1084         error = linker_load_dependencies(lf);
 1085         vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY);
 1086         if (error != 0)
 1087                 goto out;
 1088         error = relocate_file(ef);
 1089         if (error != 0)
 1090                 goto out;
 1091 
 1092 #ifdef SPARSE_MAPPING
 1093         /*
 1094          * Downgrade permissions on text segment mappings now that relocation
 1095          * processing is complete.  Restrict permissions on read-only segments.
 1096          */
 1097         for (i = 0; i < nsegs; i++) {
 1098                 vm_prot_t prot;
 1099 
 1100                 if (segs[i]->p_type != PT_LOAD)
 1101                         continue;
 1102 
 1103                 prot = VM_PROT_READ;
 1104                 if ((segs[i]->p_flags & PF_W) != 0)
 1105                         prot |= VM_PROT_WRITE;
 1106                 if ((segs[i]->p_flags & PF_X) != 0)
 1107                         prot |= VM_PROT_EXECUTE;
 1108                 segbase = mapbase + segs[i]->p_vaddr - base_vaddr;
 1109                 error = vm_map_protect(kernel_map,
 1110                     (vm_offset_t)segbase,
 1111                     (vm_offset_t)segbase + round_page(segs[i]->p_memsz),
 1112                     prot, FALSE);
 1113                 if (error != KERN_SUCCESS) {
 1114                         error = ENOMEM;
 1115                         goto out;
 1116                 }
 1117         }
 1118 #endif
 1119 
 1120         /*
 1121          * Try and load the symbol table if it's present.  (you can
 1122          * strip it!)
 1123          */
 1124         nbytes = hdr->e_shnum * hdr->e_shentsize;
 1125         if (nbytes == 0 || hdr->e_shoff == 0)
 1126                 goto nosyms;
 1127         shdr = malloc(nbytes, M_LINKER, M_WAITOK | M_ZERO);
 1128         error = vn_rdwr(UIO_READ, nd.ni_vp,
 1129             (caddr_t)shdr, nbytes, hdr->e_shoff,
 1130             UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
 1131             &resid, td);
 1132         if (error != 0)
 1133                 goto out;
 1134 
 1135         /* Read section string table */
 1136         shstrindex = hdr->e_shstrndx;
 1137         if (shstrindex != 0 && shdr[shstrindex].sh_type == SHT_STRTAB &&
 1138             shdr[shstrindex].sh_size != 0) {
 1139                 nbytes = shdr[shstrindex].sh_size;
 1140                 shstrs = malloc(nbytes, M_LINKER, M_WAITOK | M_ZERO);
 1141                 error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shstrs, nbytes,
 1142                     shdr[shstrindex].sh_offset, UIO_SYSSPACE, IO_NODELOCKED,
 1143                     td->td_ucred, NOCRED, &resid, td);
 1144                 if (error)
 1145                         goto out;
 1146         }
 1147 
 1148         symtabindex = -1;
 1149         symstrindex = -1;
 1150         for (i = 0; i < hdr->e_shnum; i++) {
 1151                 if (shdr[i].sh_type == SHT_SYMTAB) {
 1152                         symtabindex = i;
 1153                         symstrindex = shdr[i].sh_link;
 1154                 } else if (shstrs != NULL && shdr[i].sh_name != 0 &&
 1155                     strcmp(shstrs + shdr[i].sh_name, ".ctors") == 0) {
 1156                         /* Record relocated address and size of .ctors. */
 1157                         lf->ctors_addr = mapbase + shdr[i].sh_addr - base_vaddr;
 1158                         lf->ctors_size = shdr[i].sh_size;
 1159                 }
 1160         }
 1161         if (symtabindex < 0 || symstrindex < 0)
 1162                 goto nosyms;
 1163 
 1164         symcnt = shdr[symtabindex].sh_size;
 1165         ef->symbase = malloc(symcnt, M_LINKER, M_WAITOK);
 1166         strcnt = shdr[symstrindex].sh_size;
 1167         ef->strbase = malloc(strcnt, M_LINKER, M_WAITOK);
 1168 
 1169         error = vn_rdwr(UIO_READ, nd.ni_vp,
 1170             ef->symbase, symcnt, shdr[symtabindex].sh_offset,
 1171             UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
 1172             &resid, td);
 1173         if (error != 0)
 1174                 goto out;
 1175         error = vn_rdwr(UIO_READ, nd.ni_vp,
 1176             ef->strbase, strcnt, shdr[symstrindex].sh_offset,
 1177             UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
 1178             &resid, td);
 1179         if (error != 0)
 1180                 goto out;
 1181 
 1182         ef->ddbsymcnt = symcnt / sizeof(Elf_Sym);
 1183         ef->ddbsymtab = (const Elf_Sym *)ef->symbase;
 1184         ef->ddbstrcnt = strcnt;
 1185         ef->ddbstrtab = ef->strbase;
 1186 
 1187 nosyms:
 1188 
 1189 #ifdef __arm__
 1190         link_elf_locate_exidx(lf, shdr, hdr->e_shnum);
 1191 #endif
 1192 
 1193         error = link_elf_link_common_finish(lf);
 1194         if (error != 0)
 1195                 goto out;
 1196 
 1197         *result = lf;
 1198 
 1199 out:
 1200         VOP_UNLOCK(nd.ni_vp, 0);
 1201         vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
 1202         if (error != 0 && lf != NULL)
 1203                 linker_file_unload(lf, LINKER_UNLOAD_FORCE);
 1204         free(shdr, M_LINKER);
 1205         free(firstpage, M_LINKER);
 1206         free(shstrs, M_LINKER);
 1207 
 1208         return (error);
 1209 }
 1210 
 1211 Elf_Addr
 1212 elf_relocaddr(linker_file_t lf, Elf_Addr x)
 1213 {
 1214         elf_file_t ef;
 1215 
 1216         KASSERT(lf->ops->cls == (kobj_class_t)&link_elf_class,
 1217             ("elf_relocaddr: unexpected linker file %p", lf));
 1218 
 1219         ef = (elf_file_t)lf;
 1220         if (x >= ef->pcpu_start && x < ef->pcpu_stop)
 1221                 return ((x - ef->pcpu_start) + ef->pcpu_base);
 1222 #ifdef VIMAGE
 1223         if (x >= ef->vnet_start && x < ef->vnet_stop)
 1224                 return ((x - ef->vnet_start) + ef->vnet_base);
 1225 #endif
 1226         return (x);
 1227 }
 1228 
 1229 
 1230 static void
 1231 link_elf_unload_file(linker_file_t file)
 1232 {
 1233         elf_file_t ef = (elf_file_t) file;
 1234 
 1235         if (ef->pcpu_base != 0) {
 1236                 dpcpu_free((void *)ef->pcpu_base,
 1237                     ef->pcpu_stop - ef->pcpu_start);
 1238                 elf_set_delete(&set_pcpu_list, ef->pcpu_start);
 1239         }
 1240 #ifdef VIMAGE
 1241         if (ef->vnet_base != 0) {
 1242                 vnet_data_free((void *)ef->vnet_base,
 1243                     ef->vnet_stop - ef->vnet_start);
 1244                 elf_set_delete(&set_vnet_list, ef->vnet_start);
 1245         }
 1246 #endif
 1247 #ifdef GDB
 1248         if (ef->gdb.l_ld != NULL) {
 1249                 GDB_STATE(RT_DELETE);
 1250                 free((void *)(uintptr_t)ef->gdb.l_name, M_LINKER);
 1251                 link_elf_delete_gdb(&ef->gdb);
 1252                 GDB_STATE(RT_CONSISTENT);
 1253         }
 1254 #endif
 1255 
 1256         /* Notify MD code that a module is being unloaded. */
 1257         elf_cpu_unload_file(file);
 1258 
 1259         if (ef->preloaded) {
 1260                 link_elf_unload_preload(file);
 1261                 return;
 1262         }
 1263 
 1264 #ifdef SPARSE_MAPPING
 1265         if (ef->object != NULL) {
 1266                 vm_map_remove(kernel_map, (vm_offset_t) ef->address,
 1267                     (vm_offset_t) ef->address
 1268                     + (ef->object->size << PAGE_SHIFT));
 1269         }
 1270 #else
 1271         free(ef->address, M_LINKER);
 1272 #endif
 1273         free(ef->symbase, M_LINKER);
 1274         free(ef->strbase, M_LINKER);
 1275         free(ef->ctftab, M_LINKER);
 1276         free(ef->ctfoff, M_LINKER);
 1277         free(ef->typoff, M_LINKER);
 1278 }
 1279 
 1280 static void
 1281 link_elf_unload_preload(linker_file_t file)
 1282 {
 1283         if (file->pathname != NULL)
 1284                 preload_delete_name(file->pathname);
 1285 }
 1286 
 1287 static const char *
 1288 symbol_name(elf_file_t ef, Elf_Size r_info)
 1289 {
 1290         const Elf_Sym *ref;
 1291 
 1292         if (ELF_R_SYM(r_info)) {
 1293                 ref = ef->symtab + ELF_R_SYM(r_info);
 1294                 return (ef->strtab + ref->st_name);
 1295         }
 1296         return (NULL);
 1297 }
 1298 
 1299 static int
 1300 symbol_type(elf_file_t ef, Elf_Size r_info)
 1301 {
 1302         const Elf_Sym *ref;
 1303 
 1304         if (ELF_R_SYM(r_info)) {
 1305                 ref = ef->symtab + ELF_R_SYM(r_info);
 1306                 return (ELF_ST_TYPE(ref->st_info));
 1307         }
 1308         return (STT_NOTYPE);
 1309 }
 1310 
 1311 static int
 1312 relocate_file1(elf_file_t ef, elf_lookup_fn lookup, elf_reloc_fn reloc,
 1313     bool ifuncs)
 1314 {
 1315         const Elf_Rel *rel;
 1316         const Elf_Rela *rela;
 1317         const char *symname;
 1318 
 1319 #define APPLY_RELOCS(iter, tbl, tblsize, type) do {                     \
 1320         for ((iter) = (tbl); (iter) != NULL &&                          \
 1321             (iter) < (tbl) + (tblsize) / sizeof(*(iter)); (iter)++) {   \
 1322                 if ((symbol_type(ef, (iter)->r_info) ==                 \
 1323                     STT_GNU_IFUNC ||                                    \
 1324                     elf_is_ifunc_reloc((iter)->r_info)) != ifuncs)      \
 1325                         continue;                                       \
 1326                 if (reloc(&ef->lf, (Elf_Addr)ef->address,               \
 1327                     (iter), (type), lookup)) {                          \
 1328                         symname = symbol_name(ef, (iter)->r_info);      \
 1329                         printf("link_elf: symbol %s undefined\n",       \
 1330                             symname);                                   \
 1331                         return (ENOENT);                                \
 1332                 }                                                       \
 1333         }                                                               \
 1334 } while (0)
 1335 
 1336         APPLY_RELOCS(rel, ef->rel, ef->relsize, ELF_RELOC_REL);
 1337         APPLY_RELOCS(rela, ef->rela, ef->relasize, ELF_RELOC_RELA);
 1338         APPLY_RELOCS(rel, ef->pltrel, ef->pltrelsize, ELF_RELOC_REL);
 1339         APPLY_RELOCS(rela, ef->pltrela, ef->pltrelasize, ELF_RELOC_RELA);
 1340 
 1341 #undef APPLY_RELOCS
 1342 
 1343         return (0);
 1344 }
 1345 
 1346 static int
 1347 relocate_file(elf_file_t ef)
 1348 {
 1349         int error;
 1350 
 1351         error = relocate_file1(ef, elf_lookup, elf_reloc, false);
 1352         if (error == 0)
 1353                 error = relocate_file1(ef, elf_lookup, elf_reloc, true);
 1354         return (error);
 1355 }
 1356 
 1357 /*
 1358  * Hash function for symbol table lookup.  Don't even think about changing
 1359  * this.  It is specified by the System V ABI.
 1360  */
 1361 static unsigned long
 1362 elf_hash(const char *name)
 1363 {
 1364         const unsigned char *p = (const unsigned char *) name;
 1365         unsigned long h = 0;
 1366         unsigned long g;
 1367 
 1368         while (*p != '\0') {
 1369                 h = (h << 4) + *p++;
 1370                 if ((g = h & 0xf0000000) != 0)
 1371                         h ^= g >> 24;
 1372                 h &= ~g;
 1373         }
 1374         return (h);
 1375 }
 1376 
 1377 static int
 1378 link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
 1379 {
 1380         elf_file_t ef = (elf_file_t) lf;
 1381         unsigned long symnum;
 1382         const Elf_Sym* symp;
 1383         const char *strp;
 1384         unsigned long hash;
 1385         int i;
 1386 
 1387         /* If we don't have a hash, bail. */
 1388         if (ef->buckets == NULL || ef->nbuckets == 0) {
 1389                 printf("link_elf_lookup_symbol: missing symbol hash table\n");
 1390                 return (ENOENT);
 1391         }
 1392 
 1393         /* First, search hashed global symbols */
 1394         hash = elf_hash(name);
 1395         symnum = ef->buckets[hash % ef->nbuckets];
 1396 
 1397         while (symnum != STN_UNDEF) {
 1398                 if (symnum >= ef->nchains) {
 1399                         printf("%s: corrupt symbol table\n", __func__);
 1400                         return (ENOENT);
 1401                 }
 1402 
 1403                 symp = ef->symtab + symnum;
 1404                 if (symp->st_name == 0) {
 1405                         printf("%s: corrupt symbol table\n", __func__);
 1406                         return (ENOENT);
 1407                 }
 1408 
 1409                 strp = ef->strtab + symp->st_name;
 1410 
 1411                 if (strcmp(name, strp) == 0) {
 1412                         if (symp->st_shndx != SHN_UNDEF ||
 1413                             (symp->st_value != 0 &&
 1414                             (ELF_ST_TYPE(symp->st_info) == STT_FUNC ||
 1415                             ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC))) {
 1416                                 *sym = (c_linker_sym_t) symp;
 1417                                 return (0);
 1418                         }
 1419                         return (ENOENT);
 1420                 }
 1421 
 1422                 symnum = ef->chains[symnum];
 1423         }
 1424 
 1425         /* If we have not found it, look at the full table (if loaded) */
 1426         if (ef->symtab == ef->ddbsymtab)
 1427                 return (ENOENT);
 1428 
 1429         /* Exhaustive search */
 1430         for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
 1431                 strp = ef->ddbstrtab + symp->st_name;
 1432                 if (strcmp(name, strp) == 0) {
 1433                         if (symp->st_shndx != SHN_UNDEF ||
 1434                             (symp->st_value != 0 &&
 1435                             (ELF_ST_TYPE(symp->st_info) == STT_FUNC ||
 1436                             ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC))) {
 1437                                 *sym = (c_linker_sym_t) symp;
 1438                                 return (0);
 1439                         }
 1440                         return (ENOENT);
 1441                 }
 1442         }
 1443 
 1444         return (ENOENT);
 1445 }
 1446 
 1447 static int
 1448 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
 1449     linker_symval_t *symval)
 1450 {
 1451         elf_file_t ef;
 1452         const Elf_Sym *es;
 1453         caddr_t val;
 1454 
 1455         ef = (elf_file_t)lf;
 1456         es = (const Elf_Sym *)sym;
 1457         if (es >= ef->symtab && es < (ef->symtab + ef->nchains)) {
 1458                 symval->name = ef->strtab + es->st_name;
 1459                 val = (caddr_t)ef->address + es->st_value;
 1460                 if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC)
 1461                         val = ((caddr_t (*)(void))val)();
 1462                 symval->value = val;
 1463                 symval->size = es->st_size;
 1464                 return (0);
 1465         }
 1466         if (ef->symtab == ef->ddbsymtab)
 1467                 return (ENOENT);
 1468         if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) {
 1469                 symval->name = ef->ddbstrtab + es->st_name;
 1470                 val = (caddr_t)ef->address + es->st_value;
 1471                 if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC)
 1472                         val = ((caddr_t (*)(void))val)();
 1473                 symval->value = val;
 1474                 symval->size = es->st_size;
 1475                 return (0);
 1476         }
 1477         return (ENOENT);
 1478 }
 1479 
 1480 static int
 1481 link_elf_search_symbol(linker_file_t lf, caddr_t value,
 1482     c_linker_sym_t *sym, long *diffp)
 1483 {
 1484         elf_file_t ef = (elf_file_t) lf;
 1485         u_long off = (uintptr_t) (void *) value;
 1486         u_long diff = off;
 1487         u_long st_value;
 1488         const Elf_Sym* es;
 1489         const Elf_Sym* best = NULL;
 1490         int i;
 1491 
 1492         for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) {
 1493                 if (es->st_name == 0)
 1494                         continue;
 1495                 st_value = es->st_value + (uintptr_t) (void *) ef->address;
 1496                 if (off >= st_value) {
 1497                         if (off - st_value < diff) {
 1498                                 diff = off - st_value;
 1499                                 best = es;
 1500                                 if (diff == 0)
 1501                                         break;
 1502                         } else if (off - st_value == diff) {
 1503                                 best = es;
 1504                         }
 1505                 }
 1506         }
 1507         if (best == NULL)
 1508                 *diffp = off;
 1509         else
 1510                 *diffp = diff;
 1511         *sym = (c_linker_sym_t) best;
 1512 
 1513         return (0);
 1514 }
 1515 
 1516 /*
 1517  * Look up a linker set on an ELF system.
 1518  */
 1519 static int
 1520 link_elf_lookup_set(linker_file_t lf, const char *name,
 1521     void ***startp, void ***stopp, int *countp)
 1522 {
 1523         c_linker_sym_t sym;
 1524         linker_symval_t symval;
 1525         char *setsym;
 1526         void **start, **stop;
 1527         int len, error = 0, count;
 1528 
 1529         len = strlen(name) + sizeof("__start_set_"); /* sizeof includes \0 */
 1530         setsym = malloc(len, M_LINKER, M_WAITOK);
 1531 
 1532         /* get address of first entry */
 1533         snprintf(setsym, len, "%s%s", "__start_set_", name);
 1534         error = link_elf_lookup_symbol(lf, setsym, &sym);
 1535         if (error != 0)
 1536                 goto out;
 1537         link_elf_symbol_values(lf, sym, &symval);
 1538         if (symval.value == 0) {
 1539                 error = ESRCH;
 1540                 goto out;
 1541         }
 1542         start = (void **)symval.value;
 1543 
 1544         /* get address of last entry */
 1545         snprintf(setsym, len, "%s%s", "__stop_set_", name);
 1546         error = link_elf_lookup_symbol(lf, setsym, &sym);
 1547         if (error != 0)
 1548                 goto out;
 1549         link_elf_symbol_values(lf, sym, &symval);
 1550         if (symval.value == 0) {
 1551                 error = ESRCH;
 1552                 goto out;
 1553         }
 1554         stop = (void **)symval.value;
 1555 
 1556         /* and the number of entries */
 1557         count = stop - start;
 1558 
 1559         /* and copy out */
 1560         if (startp != NULL)
 1561                 *startp = start;
 1562         if (stopp != NULL)
 1563                 *stopp = stop;
 1564         if (countp != NULL)
 1565                 *countp = count;
 1566 
 1567 out:
 1568         free(setsym, M_LINKER);
 1569         return (error);
 1570 }
 1571 
 1572 static int
 1573 link_elf_each_function_name(linker_file_t file,
 1574   int (*callback)(const char *, void *), void *opaque)
 1575 {
 1576         elf_file_t ef = (elf_file_t)file;
 1577         const Elf_Sym *symp;
 1578         int i, error;
 1579 
 1580         /* Exhaustive search */
 1581         for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
 1582                 if (symp->st_value != 0 &&
 1583                     (ELF_ST_TYPE(symp->st_info) == STT_FUNC ||
 1584                     ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC)) {
 1585                         error = callback(ef->ddbstrtab + symp->st_name, opaque);
 1586                         if (error != 0)
 1587                                 return (error);
 1588                 }
 1589         }
 1590         return (0);
 1591 }
 1592 
 1593 static int
 1594 link_elf_each_function_nameval(linker_file_t file,
 1595     linker_function_nameval_callback_t callback, void *opaque)
 1596 {
 1597         linker_symval_t symval;
 1598         elf_file_t ef = (elf_file_t)file;
 1599         const Elf_Sym* symp;
 1600         int i, error;
 1601 
 1602         /* Exhaustive search */
 1603         for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
 1604                 if (symp->st_value != 0 &&
 1605                     (ELF_ST_TYPE(symp->st_info) == STT_FUNC ||
 1606                     ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC)) {
 1607                         error = link_elf_symbol_values(file,
 1608                             (c_linker_sym_t) symp, &symval);
 1609                         if (error != 0)
 1610                                 return (error);
 1611                         error = callback(file, i, &symval, opaque);
 1612                         if (error != 0)
 1613                                 return (error);
 1614                 }
 1615         }
 1616         return (0);
 1617 }
 1618 
 1619 const Elf_Sym *
 1620 elf_get_sym(linker_file_t lf, Elf_Size symidx)
 1621 {
 1622         elf_file_t ef = (elf_file_t)lf;
 1623 
 1624         if (symidx >= ef->nchains)
 1625                 return (NULL);
 1626         return (ef->symtab + symidx);
 1627 }
 1628 
 1629 const char *
 1630 elf_get_symname(linker_file_t lf, Elf_Size symidx)
 1631 {
 1632         elf_file_t ef = (elf_file_t)lf;
 1633         const Elf_Sym *sym;
 1634 
 1635         if (symidx >= ef->nchains)
 1636                 return (NULL);
 1637         sym = ef->symtab + symidx;
 1638         return (ef->strtab + sym->st_name);
 1639 }
 1640 
 1641 /*
 1642  * Symbol lookup function that can be used when the symbol index is known (ie
 1643  * in relocations). It uses the symbol index instead of doing a fully fledged
 1644  * hash table based lookup when such is valid. For example for local symbols.
 1645  * This is not only more efficient, it's also more correct. It's not always
 1646  * the case that the symbol can be found through the hash table.
 1647  */
 1648 static int
 1649 elf_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *res)
 1650 {
 1651         elf_file_t ef = (elf_file_t)lf;
 1652         const Elf_Sym *sym;
 1653         const char *symbol;
 1654         Elf_Addr addr, start, base;
 1655 
 1656         /* Don't even try to lookup the symbol if the index is bogus. */
 1657         if (symidx >= ef->nchains) {
 1658                 *res = 0;
 1659                 return (EINVAL);
 1660         }
 1661 
 1662         sym = ef->symtab + symidx;
 1663 
 1664         /*
 1665          * Don't do a full lookup when the symbol is local. It may even
 1666          * fail because it may not be found through the hash table.
 1667          */
 1668         if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
 1669                 /* Force lookup failure when we have an insanity. */
 1670                 if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0) {
 1671                         *res = 0;
 1672                         return (EINVAL);
 1673                 }
 1674                 *res = ((Elf_Addr)ef->address + sym->st_value);
 1675                 return (0);
 1676         }
 1677 
 1678         /*
 1679          * XXX we can avoid doing a hash table based lookup for global
 1680          * symbols as well. This however is not always valid, so we'll
 1681          * just do it the hard way for now. Performance tweaks can
 1682          * always be added.
 1683          */
 1684 
 1685         symbol = ef->strtab + sym->st_name;
 1686 
 1687         /* Force a lookup failure if the symbol name is bogus. */
 1688         if (*symbol == 0) {
 1689                 *res = 0;
 1690                 return (EINVAL);
 1691         }
 1692 
 1693         addr = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
 1694         if (addr == 0 && ELF_ST_BIND(sym->st_info) != STB_WEAK) {
 1695                 *res = 0;
 1696                 return (EINVAL);
 1697         }
 1698 
 1699         if (elf_set_find(&set_pcpu_list, addr, &start, &base))
 1700                 addr = addr - start + base;
 1701 #ifdef VIMAGE
 1702         else if (elf_set_find(&set_vnet_list, addr, &start, &base))
 1703                 addr = addr - start + base;
 1704 #endif
 1705         *res = addr;
 1706         return (0);
 1707 }
 1708 
 1709 static void
 1710 link_elf_reloc_local(linker_file_t lf)
 1711 {
 1712         const Elf_Rel *rellim;
 1713         const Elf_Rel *rel;
 1714         const Elf_Rela *relalim;
 1715         const Elf_Rela *rela;
 1716         elf_file_t ef = (elf_file_t)lf;
 1717 
 1718         /* Perform relocations without addend if there are any: */
 1719         if ((rel = ef->rel) != NULL) {
 1720                 rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
 1721                 while (rel < rellim) {
 1722                         elf_reloc_local(lf, (Elf_Addr)ef->address, rel,
 1723                             ELF_RELOC_REL, elf_lookup);
 1724                         rel++;
 1725                 }
 1726         }
 1727 
 1728         /* Perform relocations with addend if there are any: */
 1729         if ((rela = ef->rela) != NULL) {
 1730                 relalim = (const Elf_Rela *)
 1731                     ((const char *)ef->rela + ef->relasize);
 1732                 while (rela < relalim) {
 1733                         elf_reloc_local(lf, (Elf_Addr)ef->address, rela,
 1734                             ELF_RELOC_RELA, elf_lookup);
 1735                         rela++;
 1736                 }
 1737         }
 1738 }
 1739 
 1740 static long
 1741 link_elf_symtab_get(linker_file_t lf, const Elf_Sym **symtab)
 1742 {
 1743         elf_file_t ef = (elf_file_t)lf;
 1744 
 1745         *symtab = ef->ddbsymtab;
 1746 
 1747         if (*symtab == NULL)
 1748                 return (0);
 1749 
 1750         return (ef->ddbsymcnt);
 1751 }
 1752 
 1753 static long
 1754 link_elf_strtab_get(linker_file_t lf, caddr_t *strtab)
 1755 {
 1756         elf_file_t ef = (elf_file_t)lf;
 1757 
 1758         *strtab = ef->ddbstrtab;
 1759 
 1760         if (*strtab == NULL)
 1761                 return (0);
 1762 
 1763         return (ef->ddbstrcnt);
 1764 }
 1765 
 1766 #if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
 1767 /*
 1768  * Use this lookup routine when performing relocations early during boot.
 1769  * The generic lookup routine depends on kobj, which is not initialized
 1770  * at that point.
 1771  */
 1772 static int
 1773 elf_lookup_ifunc(linker_file_t lf, Elf_Size symidx, int deps __unused,
 1774     Elf_Addr *res)
 1775 {
 1776         elf_file_t ef;
 1777         const Elf_Sym *symp;
 1778         caddr_t val;
 1779 
 1780         ef = (elf_file_t)lf;
 1781         symp = ef->symtab + symidx;
 1782         if (ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC) {
 1783                 val = (caddr_t)ef->address + symp->st_value;
 1784                 *res = ((Elf_Addr (*)(void))val)();
 1785                 return (0);
 1786         }
 1787         return (ENOENT);
 1788 }
 1789 
 1790 void
 1791 link_elf_ireloc(caddr_t kmdp)
 1792 {
 1793         struct elf_file eff;
 1794         elf_file_t ef;
 1795 
 1796         ef = &eff;
 1797 
 1798         bzero_early(ef, sizeof(*ef));
 1799 
 1800         ef->modptr = kmdp;
 1801         ef->dynamic = (Elf_Dyn *)&_DYNAMIC;
 1802         parse_dynamic(ef);
 1803         ef->address = 0;
 1804         link_elf_preload_parse_symbols(ef);
 1805         relocate_file1(ef, elf_lookup_ifunc, elf_reloc, true);
 1806 }
 1807 #endif

Cache object: 7b5f76ceb49185f9645847a986333b75


[ 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.