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_module.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  * Copyright (c) 1998 Michael Smith
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/linker.h>
   33 
   34 #include <vm/vm.h>
   35 #include <vm/vm_extern.h>
   36 
   37 /*
   38  * Preloaded module support
   39  */
   40 
   41 vm_offset_t preload_addr_relocate = 0;
   42 caddr_t preload_metadata;
   43 
   44 /*
   45  * Search for the preloaded module (name)
   46  */
   47 caddr_t
   48 preload_search_by_name(const char *name)
   49 {
   50     caddr_t     curp;
   51     uint32_t    *hdr;
   52     int         next;
   53     
   54     if (preload_metadata != NULL) {
   55         
   56         curp = preload_metadata;
   57         for (;;) {
   58             hdr = (uint32_t *)curp;
   59             if (hdr[0] == 0 && hdr[1] == 0)
   60                 break;
   61 
   62             /* Search for a MODINFO_NAME field */
   63             if ((hdr[0] == MODINFO_NAME) &&
   64                 !strcmp(name, curp + sizeof(uint32_t) * 2))
   65                 return(curp);
   66 
   67             /* skip to next field */
   68             next = sizeof(uint32_t) * 2 + hdr[1];
   69             next = roundup(next, sizeof(u_long));
   70             curp += next;
   71         }
   72     }
   73     return(NULL);
   74 }
   75 
   76 /*
   77  * Search for the first preloaded module of (type)
   78  */
   79 caddr_t
   80 preload_search_by_type(const char *type)
   81 {
   82     caddr_t     curp, lname;
   83     uint32_t    *hdr;
   84     int         next;
   85 
   86     if (preload_metadata != NULL) {
   87 
   88         curp = preload_metadata;
   89         lname = NULL;
   90         for (;;) {
   91             hdr = (uint32_t *)curp;
   92             if (hdr[0] == 0 && hdr[1] == 0)
   93                 break;
   94 
   95             /* remember the start of each record */
   96             if (hdr[0] == MODINFO_NAME)
   97                 lname = curp;
   98 
   99             /* Search for a MODINFO_TYPE field */
  100             if ((hdr[0] == MODINFO_TYPE) &&
  101                 !strcmp(type, curp + sizeof(uint32_t) * 2))
  102                 return(lname);
  103 
  104             /* skip to next field */
  105             next = sizeof(uint32_t) * 2 + hdr[1];
  106             next = roundup(next, sizeof(u_long));
  107             curp += next;
  108         }
  109     }
  110     return(NULL);
  111 }
  112 
  113 /*
  114  * Walk through the preloaded module list
  115  */
  116 caddr_t
  117 preload_search_next_name(caddr_t base)
  118 {
  119     caddr_t     curp;
  120     uint32_t    *hdr;
  121     int         next;
  122     
  123     if (preload_metadata != NULL) {
  124         
  125         /* Pick up where we left off last time */
  126         if (base) {
  127             /* skip to next field */
  128             curp = base;
  129             hdr = (uint32_t *)curp;
  130             next = sizeof(uint32_t) * 2 + hdr[1];
  131             next = roundup(next, sizeof(u_long));
  132             curp += next;
  133         } else
  134             curp = preload_metadata;
  135 
  136         for (;;) {
  137             hdr = (uint32_t *)curp;
  138             if (hdr[0] == 0 && hdr[1] == 0)
  139                 break;
  140 
  141             /* Found a new record? */
  142             if (hdr[0] == MODINFO_NAME)
  143                 return curp;
  144 
  145             /* skip to next field */
  146             next = sizeof(uint32_t) * 2 + hdr[1];
  147             next = roundup(next, sizeof(u_long));
  148             curp += next;
  149         }
  150     }
  151     return(NULL);
  152 }
  153 
  154 /*
  155  * Given a preloaded module handle (mod), return a pointer
  156  * to the data for the attribute (inf).
  157  */
  158 caddr_t
  159 preload_search_info(caddr_t mod, int inf)
  160 {
  161     caddr_t     curp;
  162     uint32_t    *hdr;
  163     uint32_t    type = 0;
  164     int         next;
  165 
  166     if (mod == NULL)
  167         return (NULL);
  168 
  169     curp = mod;
  170     for (;;) {
  171         hdr = (uint32_t *)curp;
  172         /* end of module data? */
  173         if (hdr[0] == 0 && hdr[1] == 0)
  174             break;
  175         /* 
  176          * We give up once we've looped back to what we were looking at 
  177          * first - this should normally be a MODINFO_NAME field.
  178          */
  179         if (type == 0) {
  180             type = hdr[0];
  181         } else {
  182             if (hdr[0] == type)
  183                 break;
  184         }
  185         
  186         /* 
  187          * Attribute match? Return pointer to data.
  188          * Consumer may safely assume that size value precedes  
  189          * data.
  190          */
  191         if (hdr[0] == inf)
  192             return(curp + (sizeof(uint32_t) * 2));
  193 
  194         /* skip to next field */
  195         next = sizeof(uint32_t) * 2 + hdr[1];
  196         next = roundup(next, sizeof(u_long));
  197         curp += next;
  198     }
  199     return(NULL);
  200 }
  201 
  202 /*
  203  * Delete a preload record by name.
  204  */
  205 void
  206 preload_delete_name(const char *name)
  207 {
  208     caddr_t     addr, curp;
  209     uint32_t    *hdr, sz;
  210     int         next;
  211     int         clearing;
  212 
  213     addr = 0;
  214     sz = 0;
  215     
  216     if (preload_metadata != NULL) {
  217 
  218         clearing = 0;
  219         curp = preload_metadata;
  220         for (;;) {
  221             hdr = (uint32_t *)curp;
  222             if (hdr[0] == MODINFO_NAME || (hdr[0] == 0 && hdr[1] == 0)) {
  223                 /* Free memory used to store the file. */
  224                 if (addr != 0 && sz != 0)
  225                     kmem_bootstrap_free((vm_offset_t)addr, sz);
  226                 addr = 0;
  227                 sz = 0;
  228 
  229                 if (hdr[0] == 0)
  230                     break;
  231                 if (!strcmp(name, curp + sizeof(uint32_t) * 2))
  232                     clearing = 1;       /* got it, start clearing */
  233                 else if (clearing) {
  234                     clearing = 0;       /* at next one now.. better stop */
  235                 }
  236             }
  237             if (clearing) {
  238                 if (hdr[0] == MODINFO_ADDR)
  239                     addr = *(caddr_t *)(curp + sizeof(uint32_t) * 2);
  240                 else if (hdr[0] == MODINFO_SIZE)
  241                     sz = *(uint32_t *)(curp + sizeof(uint32_t) * 2);
  242                 hdr[0] = MODINFO_EMPTY;
  243             }
  244 
  245             /* skip to next field */
  246             next = sizeof(uint32_t) * 2 + hdr[1];
  247             next = roundup(next, sizeof(u_long));
  248             curp += next;
  249         }
  250     }
  251 }
  252 
  253 void *
  254 preload_fetch_addr(caddr_t mod)
  255 {
  256         caddr_t *mdp;
  257 
  258         mdp = (caddr_t *)preload_search_info(mod, MODINFO_ADDR);
  259         if (mdp == NULL)
  260                 return (NULL);
  261         return (*mdp + preload_addr_relocate);
  262 }
  263 
  264 size_t
  265 preload_fetch_size(caddr_t mod)
  266 {
  267         size_t *mdp;
  268 
  269         mdp = (size_t *)preload_search_info(mod, MODINFO_SIZE);
  270         if (mdp == NULL)
  271                 return (0);
  272         return (*mdp);
  273 }
  274 
  275 /* Called from locore.  Convert physical pointers to kvm. Sigh. */
  276 void
  277 preload_bootstrap_relocate(vm_offset_t offset)
  278 {
  279     caddr_t     curp;
  280     uint32_t    *hdr;
  281     vm_offset_t *ptr;
  282     int         next;
  283     
  284     if (preload_metadata != NULL) {
  285         
  286         curp = preload_metadata;
  287         for (;;) {
  288             hdr = (uint32_t *)curp;
  289             if (hdr[0] == 0 && hdr[1] == 0)
  290                 break;
  291 
  292             /* Deal with the ones that we know we have to fix */
  293             switch (hdr[0]) {
  294             case MODINFO_ADDR:
  295             case MODINFO_METADATA|MODINFOMD_SSYM:
  296             case MODINFO_METADATA|MODINFOMD_ESYM:
  297                 ptr = (vm_offset_t *)(curp + (sizeof(uint32_t) * 2));
  298                 *ptr += offset;
  299                 break;
  300             }
  301             /* The rest is beyond us for now */
  302 
  303             /* skip to next field */
  304             next = sizeof(uint32_t) * 2 + hdr[1];
  305             next = roundup(next, sizeof(u_long));
  306             curp += next;
  307         }
  308     }
  309 }

Cache object: b9ea883016df3dbe5ea25da85257e5d8


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