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: releng/11.2/sys/kern/subr_module.c 287000 2015-08-21 15:57:57Z royger $");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/linker.h>
   33 
   34 /*
   35  * Preloaded module support
   36  */
   37 
   38 vm_offset_t preload_addr_relocate = 0;
   39 caddr_t preload_metadata;
   40 
   41 /*
   42  * Search for the preloaded module (name)
   43  */
   44 caddr_t
   45 preload_search_by_name(const char *name)
   46 {
   47     caddr_t     curp;
   48     uint32_t    *hdr;
   49     int         next;
   50     
   51     if (preload_metadata != NULL) {
   52         
   53         curp = preload_metadata;
   54         for (;;) {
   55             hdr = (uint32_t *)curp;
   56             if (hdr[0] == 0 && hdr[1] == 0)
   57                 break;
   58 
   59             /* Search for a MODINFO_NAME field */
   60             if ((hdr[0] == MODINFO_NAME) &&
   61                 !strcmp(name, curp + sizeof(uint32_t) * 2))
   62                 return(curp);
   63 
   64             /* skip to next field */
   65             next = sizeof(uint32_t) * 2 + hdr[1];
   66             next = roundup(next, sizeof(u_long));
   67             curp += next;
   68         }
   69     }
   70     return(NULL);
   71 }
   72 
   73 /*
   74  * Search for the first preloaded module of (type)
   75  */
   76 caddr_t
   77 preload_search_by_type(const char *type)
   78 {
   79     caddr_t     curp, lname;
   80     uint32_t    *hdr;
   81     int         next;
   82 
   83     if (preload_metadata != NULL) {
   84 
   85         curp = preload_metadata;
   86         lname = NULL;
   87         for (;;) {
   88             hdr = (uint32_t *)curp;
   89             if (hdr[0] == 0 && hdr[1] == 0)
   90                 break;
   91 
   92             /* remember the start of each record */
   93             if (hdr[0] == MODINFO_NAME)
   94                 lname = curp;
   95 
   96             /* Search for a MODINFO_TYPE field */
   97             if ((hdr[0] == MODINFO_TYPE) &&
   98                 !strcmp(type, curp + sizeof(uint32_t) * 2))
   99                 return(lname);
  100 
  101             /* skip to next field */
  102             next = sizeof(uint32_t) * 2 + hdr[1];
  103             next = roundup(next, sizeof(u_long));
  104             curp += next;
  105         }
  106     }
  107     return(NULL);
  108 }
  109 
  110 /*
  111  * Walk through the preloaded module list
  112  */
  113 caddr_t
  114 preload_search_next_name(caddr_t base)
  115 {
  116     caddr_t     curp;
  117     uint32_t    *hdr;
  118     int         next;
  119     
  120     if (preload_metadata != NULL) {
  121         
  122         /* Pick up where we left off last time */
  123         if (base) {
  124             /* skip to next field */
  125             curp = base;
  126             hdr = (uint32_t *)curp;
  127             next = sizeof(uint32_t) * 2 + hdr[1];
  128             next = roundup(next, sizeof(u_long));
  129             curp += next;
  130         } else
  131             curp = preload_metadata;
  132 
  133         for (;;) {
  134             hdr = (uint32_t *)curp;
  135             if (hdr[0] == 0 && hdr[1] == 0)
  136                 break;
  137 
  138             /* Found a new record? */
  139             if (hdr[0] == MODINFO_NAME)
  140                 return curp;
  141 
  142             /* skip to next field */
  143             next = sizeof(uint32_t) * 2 + hdr[1];
  144             next = roundup(next, sizeof(u_long));
  145             curp += next;
  146         }
  147     }
  148     return(NULL);
  149 }
  150 
  151 /*
  152  * Given a preloaded module handle (mod), return a pointer
  153  * to the data for the attribute (inf).
  154  */
  155 caddr_t
  156 preload_search_info(caddr_t mod, int inf)
  157 {
  158     caddr_t     curp;
  159     uint32_t    *hdr;
  160     uint32_t    type = 0;
  161     int         next;
  162 
  163     if (mod == NULL)
  164         return (NULL);
  165 
  166     curp = mod;
  167     for (;;) {
  168         hdr = (uint32_t *)curp;
  169         /* end of module data? */
  170         if (hdr[0] == 0 && hdr[1] == 0)
  171             break;
  172         /* 
  173          * We give up once we've looped back to what we were looking at 
  174          * first - this should normally be a MODINFO_NAME field.
  175          */
  176         if (type == 0) {
  177             type = hdr[0];
  178         } else {
  179             if (hdr[0] == type)
  180                 break;
  181         }
  182         
  183         /* 
  184          * Attribute match? Return pointer to data.
  185          * Consumer may safely assume that size value precedes  
  186          * data.
  187          */
  188         if (hdr[0] == inf)
  189             return(curp + (sizeof(uint32_t) * 2));
  190 
  191         /* skip to next field */
  192         next = sizeof(uint32_t) * 2 + hdr[1];
  193         next = roundup(next, sizeof(u_long));
  194         curp += next;
  195     }
  196     return(NULL);
  197 }
  198 
  199 /*
  200  * Delete a preload record by name.
  201  */
  202 void
  203 preload_delete_name(const char *name)
  204 {
  205     caddr_t     curp;
  206     uint32_t    *hdr;
  207     int         next;
  208     int         clearing;
  209     
  210     if (preload_metadata != NULL) {
  211         
  212         clearing = 0;
  213         curp = preload_metadata;
  214         for (;;) {
  215             hdr = (uint32_t *)curp;
  216             if (hdr[0] == 0 && hdr[1] == 0)
  217                 break;
  218 
  219             /* Search for a MODINFO_NAME field */
  220             if (hdr[0] == MODINFO_NAME) {
  221                 if (!strcmp(name, curp + sizeof(uint32_t) * 2))
  222                     clearing = 1;       /* got it, start clearing */
  223                 else if (clearing)
  224                     clearing = 0;       /* at next one now.. better stop */
  225             }
  226             if (clearing)
  227                 hdr[0] = MODINFO_EMPTY;
  228 
  229             /* skip to next field */
  230             next = sizeof(uint32_t) * 2 + hdr[1];
  231             next = roundup(next, sizeof(u_long));
  232             curp += next;
  233         }
  234     }
  235 }
  236 
  237 void *
  238 preload_fetch_addr(caddr_t mod)
  239 {
  240         caddr_t *mdp;
  241 
  242         mdp = (caddr_t *)preload_search_info(mod, MODINFO_ADDR);
  243         if (mdp == NULL)
  244                 return (NULL);
  245         return (*mdp + preload_addr_relocate);
  246 }
  247 
  248 size_t
  249 preload_fetch_size(caddr_t mod)
  250 {
  251         size_t *mdp;
  252 
  253         mdp = (size_t *)preload_search_info(mod, MODINFO_SIZE);
  254         if (mdp == NULL)
  255                 return (0);
  256         return (*mdp);
  257 }
  258 
  259 /* Called from locore.  Convert physical pointers to kvm. Sigh. */
  260 void
  261 preload_bootstrap_relocate(vm_offset_t offset)
  262 {
  263     caddr_t     curp;
  264     uint32_t    *hdr;
  265     vm_offset_t *ptr;
  266     int         next;
  267     
  268     if (preload_metadata != NULL) {
  269         
  270         curp = preload_metadata;
  271         for (;;) {
  272             hdr = (uint32_t *)curp;
  273             if (hdr[0] == 0 && hdr[1] == 0)
  274                 break;
  275 
  276             /* Deal with the ones that we know we have to fix */
  277             switch (hdr[0]) {
  278             case MODINFO_ADDR:
  279             case MODINFO_METADATA|MODINFOMD_SSYM:
  280             case MODINFO_METADATA|MODINFOMD_ESYM:
  281                 ptr = (vm_offset_t *)(curp + (sizeof(uint32_t) * 2));
  282                 *ptr += offset;
  283                 break;
  284             }
  285             /* The rest is beyond us for now */
  286 
  287             /* skip to next field */
  288             next = sizeof(uint32_t) * 2 + hdr[1];
  289             next = roundup(next, sizeof(u_long));
  290             curp += next;
  291         }
  292     }
  293 }

Cache object: 547f1edb25b23b83ceb8df79e91481d9


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