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  * $FreeBSD: src/sys/kern/subr_module.c,v 1.6 1999/10/11 15:19:10 peter Exp $
   27  * $DragonFly: src/sys/kern/subr_module.c,v 1.4 2004/05/26 08:32:41 dillon Exp $
   28  */
   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 caddr_t preload_metadata;
   39 
   40 /*
   41  * Search for the preloaded module (name)
   42  */
   43 caddr_t
   44 preload_search_by_name(const char *name)
   45 {
   46     caddr_t     curp;
   47     u_int32_t   *hdr;
   48     int         next;
   49     int         i;
   50     char        *scanname;
   51 
   52     if (preload_metadata == NULL)
   53         return(NULL);
   54 
   55     curp = preload_metadata;
   56     for (;;) {
   57         hdr = (u_int32_t *)curp;
   58         if (hdr[0] == 0 && hdr[1] == 0)
   59             break;
   60 
   61         /*
   62          * Search for a MODINFO_NAME field.  the boot loader really
   63          * ought to strip the path names
   64          */
   65         if (hdr[0] == MODINFO_NAME) {
   66             scanname = curp + sizeof(u_int32_t) * 2;
   67             i = strlen(scanname);
   68             while (i > 0 && scanname[i-1] != '/')
   69                 --i;
   70             if (strcmp(name, scanname) == 0)
   71                 return(curp);
   72             if (strcmp(name, scanname + i) == 0)
   73                 return(curp);
   74         }
   75         /* skip to next field */
   76         next = sizeof(u_int32_t) * 2 + hdr[1];
   77         next = roundup(next, sizeof(u_long));
   78         curp += next;
   79     }
   80     return(NULL);
   81 }
   82 
   83 /*
   84  * Search for the first preloaded module of (type)
   85  */
   86 caddr_t
   87 preload_search_by_type(const char *type)
   88 {
   89     caddr_t     curp, lname;
   90     u_int32_t   *hdr;
   91     int         next;
   92 
   93     if (preload_metadata != NULL) {
   94 
   95         curp = preload_metadata;
   96         lname = NULL;
   97         for (;;) {
   98             hdr = (u_int32_t *)curp;
   99             if (hdr[0] == 0 && hdr[1] == 0)
  100                 break;
  101 
  102             /* remember the start of each record */
  103             if (hdr[0] == MODINFO_NAME)
  104                 lname = curp;
  105 
  106             /* Search for a MODINFO_TYPE field */
  107             if ((hdr[0] == MODINFO_TYPE) &&
  108                 !strcmp(type, curp + sizeof(u_int32_t) * 2))
  109                 return(lname);
  110 
  111             /* skip to next field */
  112             next = sizeof(u_int32_t) * 2 + hdr[1];
  113             next = roundup(next, sizeof(u_long));
  114             curp += next;
  115         }
  116     }
  117     return(NULL);
  118 }
  119 
  120 /*
  121  * Walk through the preloaded module list
  122  */
  123 caddr_t
  124 preload_search_next_name(caddr_t base)
  125 {
  126     caddr_t     curp;
  127     u_int32_t   *hdr;
  128     int         next;
  129     
  130     if (preload_metadata != NULL) {
  131         
  132         /* Pick up where we left off last time */
  133         if (base) {
  134             /* skip to next field */
  135             curp = base;
  136             hdr = (u_int32_t *)curp;
  137             next = sizeof(u_int32_t) * 2 + hdr[1];
  138             next = roundup(next, sizeof(u_long));
  139             curp += next;
  140         } else
  141             curp = preload_metadata;
  142 
  143         for (;;) {
  144             hdr = (u_int32_t *)curp;
  145             if (hdr[0] == 0 && hdr[1] == 0)
  146                 break;
  147 
  148             /* Found a new record? */
  149             if (hdr[0] == MODINFO_NAME)
  150                 return curp;
  151 
  152             /* skip to next field */
  153             next = sizeof(u_int32_t) * 2 + hdr[1];
  154             next = roundup(next, sizeof(u_long));
  155             curp += next;
  156         }
  157     }
  158     return(NULL);
  159 }
  160 
  161 /*
  162  * Given a preloaded module handle (mod), return a pointer
  163  * to the data for the attribute (inf).
  164  */
  165 caddr_t
  166 preload_search_info(caddr_t mod, int inf)
  167 {
  168     caddr_t     curp;
  169     u_int32_t   *hdr;
  170     u_int32_t   type = 0;
  171     int         next;
  172 
  173     curp = mod;
  174     for (;;) {
  175         hdr = (u_int32_t *)curp;
  176         /* end of module data? */
  177         if (hdr[0] == 0 && hdr[1] == 0)
  178             break;
  179         /* 
  180          * We give up once we've looped back to what we were looking at 
  181          * first - this should normally be a MODINFO_NAME field.
  182          */
  183         if (type == 0) {
  184             type = hdr[0];
  185         } else {
  186             if (hdr[0] == type)
  187                 break;
  188         }
  189         
  190         /* 
  191          * Attribute match? Return pointer to data.
  192          * Consumer may safely assume that size value preceeds  
  193          * data.
  194          */
  195         if (hdr[0] == inf)
  196             return(curp + (sizeof(u_int32_t) * 2));
  197 
  198         /* skip to next field */
  199         next = sizeof(u_int32_t) * 2 + hdr[1];
  200         next = roundup(next, sizeof(u_long));
  201         curp += next;
  202     }
  203     return(NULL);
  204 }
  205 
  206 /*
  207  * Delete a preload record by name.
  208  *
  209  * XXX we should really pass the base of the preloaded module here and not
  210  * require rematching of the name.  If the wrong module (or no module) is
  211  * deleted, the original preloaded module might be loaded again, causing it's
  212  * data to be relocated twice.
  213  */
  214 void
  215 preload_delete_name(const char *name)
  216 {
  217     caddr_t     curp;
  218     u_int32_t   *hdr;
  219     int         next;
  220     int         clearing;
  221     int         i;
  222     char        *scanname;
  223     
  224     if (preload_metadata != NULL) {
  225         clearing = 0;
  226         curp = preload_metadata;
  227         for (;;) {
  228             hdr = (u_int32_t *)curp;
  229             if (hdr[0] == 0 && hdr[1] == 0)
  230                 break;
  231 
  232             /* Search for a MODINFO_NAME field */
  233             if (hdr[0] == MODINFO_NAME) {
  234                 scanname = curp + sizeof(u_int32_t) * 2;
  235                 i = strlen(scanname);
  236                 while (i > 0 && scanname[i-1] != '/')
  237                     --i;
  238                 if (strcmp(name, scanname) == 0)
  239                     clearing = 1;
  240                 else if (strcmp(name, scanname + i) == 0)
  241                     clearing = 1;
  242                 else
  243                     clearing = 0;       /* at next module now, stop clearing */
  244             }
  245             if (clearing)
  246                 hdr[0] = MODINFO_EMPTY;
  247 
  248             /* skip to next field */
  249             next = sizeof(u_int32_t) * 2 + hdr[1];
  250             next = roundup(next, sizeof(u_long));
  251             curp += next;
  252         }
  253     }
  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     u_int32_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 = (u_int32_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(u_int32_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(u_int32_t) * 2 + hdr[1];
  286             next = roundup(next, sizeof(u_long));
  287             curp += next;
  288         }
  289     }
  290 }

Cache object: 9a5efd45bfcbf441a4a4be34f76160c6


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