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/10.4/sys/kern/subr_module.c 218494 2011-02-09 19:08:21Z marcel $");
   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     curp = mod;
  164     for (;;) {
  165         hdr = (uint32_t *)curp;
  166         /* end of module data? */
  167         if (hdr[0] == 0 && hdr[1] == 0)
  168             break;
  169         /* 
  170          * We give up once we've looped back to what we were looking at 
  171          * first - this should normally be a MODINFO_NAME field.
  172          */
  173         if (type == 0) {
  174             type = hdr[0];
  175         } else {
  176             if (hdr[0] == type)
  177                 break;
  178         }
  179         
  180         /* 
  181          * Attribute match? Return pointer to data.
  182          * Consumer may safely assume that size value precedes  
  183          * data.
  184          */
  185         if (hdr[0] == inf)
  186             return(curp + (sizeof(uint32_t) * 2));
  187 
  188         /* skip to next field */
  189         next = sizeof(uint32_t) * 2 + hdr[1];
  190         next = roundup(next, sizeof(u_long));
  191         curp += next;
  192     }
  193     return(NULL);
  194 }
  195 
  196 /*
  197  * Delete a preload record by name.
  198  */
  199 void
  200 preload_delete_name(const char *name)
  201 {
  202     caddr_t     curp;
  203     uint32_t    *hdr;
  204     int         next;
  205     int         clearing;
  206     
  207     if (preload_metadata != NULL) {
  208         
  209         clearing = 0;
  210         curp = preload_metadata;
  211         for (;;) {
  212             hdr = (uint32_t *)curp;
  213             if (hdr[0] == 0 && hdr[1] == 0)
  214                 break;
  215 
  216             /* Search for a MODINFO_NAME field */
  217             if (hdr[0] == MODINFO_NAME) {
  218                 if (!strcmp(name, curp + sizeof(uint32_t) * 2))
  219                     clearing = 1;       /* got it, start clearing */
  220                 else if (clearing)
  221                     clearing = 0;       /* at next one now.. better stop */
  222             }
  223             if (clearing)
  224                 hdr[0] = MODINFO_EMPTY;
  225 
  226             /* skip to next field */
  227             next = sizeof(uint32_t) * 2 + hdr[1];
  228             next = roundup(next, sizeof(u_long));
  229             curp += next;
  230         }
  231     }
  232 }
  233 
  234 void *
  235 preload_fetch_addr(caddr_t mod)
  236 {
  237         caddr_t *mdp;
  238 
  239         mdp = (caddr_t *)preload_search_info(mod, MODINFO_ADDR);
  240         if (mdp == NULL)
  241                 return (NULL);
  242         return (*mdp + preload_addr_relocate);
  243 }
  244 
  245 size_t
  246 preload_fetch_size(caddr_t mod)
  247 {
  248         size_t *mdp;
  249 
  250         mdp = (size_t *)preload_search_info(mod, MODINFO_SIZE);
  251         if (mdp == NULL)
  252                 return (0);
  253         return (*mdp);
  254 }
  255 
  256 /* Called from locore on i386.  Convert physical pointers to kvm. Sigh. */
  257 void
  258 preload_bootstrap_relocate(vm_offset_t offset)
  259 {
  260     caddr_t     curp;
  261     uint32_t    *hdr;
  262     vm_offset_t *ptr;
  263     int         next;
  264     
  265     if (preload_metadata != NULL) {
  266         
  267         curp = preload_metadata;
  268         for (;;) {
  269             hdr = (uint32_t *)curp;
  270             if (hdr[0] == 0 && hdr[1] == 0)
  271                 break;
  272 
  273             /* Deal with the ones that we know we have to fix */
  274             switch (hdr[0]) {
  275             case MODINFO_ADDR:
  276             case MODINFO_METADATA|MODINFOMD_SSYM:
  277             case MODINFO_METADATA|MODINFOMD_ESYM:
  278                 ptr = (vm_offset_t *)(curp + (sizeof(uint32_t) * 2));
  279                 *ptr += offset;
  280                 break;
  281             }
  282             /* The rest is beyond us for now */
  283 
  284             /* skip to next field */
  285             next = sizeof(uint32_t) * 2 + hdr[1];
  286             next = roundup(next, sizeof(u_long));
  287             curp += next;
  288         }
  289     }
  290 }

Cache object: e50724559c288649590aeed4f3313bf5


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