subr_module.c revision 40157
140090Smsmith/*- 240090Smsmith * Copyright (c) 1998 Michael Smith 340090Smsmith * All rights reserved. 440090Smsmith * 540090Smsmith * Redistribution and use in source and binary forms, with or without 640090Smsmith * modification, are permitted provided that the following conditions 740090Smsmith * are met: 840090Smsmith * 1. Redistributions of source code must retain the above copyright 940090Smsmith * notice, this list of conditions and the following disclaimer. 1040090Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1140090Smsmith * notice, this list of conditions and the following disclaimer in the 1240090Smsmith * documentation and/or other materials provided with the distribution. 1340090Smsmith * 1440090Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1540090Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1640090Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1740090Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1840090Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1940090Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2040090Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2140090Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2240090Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2340090Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2440090Smsmith * SUCH DAMAGE. 2540090Smsmith * 2640157Speter * $Id: subr_module.c,v 1.1 1998/10/09 00:31:29 msmith Exp $ 2740090Smsmith */ 2840090Smsmith 2940090Smsmith#include <sys/param.h> 3040090Smsmith#include <sys/kernel.h> 3140090Smsmith#include <sys/systm.h> 3240090Smsmith#include <sys/linker.h> 3340090Smsmith 3440090Smsmith/* 3540090Smsmith * Preloaded module support 3640090Smsmith */ 3740090Smsmith 3840157Spetercaddr_t preload_metadata; 3940090Smsmith 4040090Smsmith/* 4140090Smsmith * Search for the preloaded module (name) 4240090Smsmith */ 4340090Smsmithcaddr_t 4440157Speterpreload_search_by_name(const char *name) 4540090Smsmith{ 4640090Smsmith caddr_t curp; 4740090Smsmith u_int32_t *hdr; 4840157Speter int next; 4940090Smsmith 5040157Speter if (preload_metadata != NULL) { 5140090Smsmith 5240157Speter curp = preload_metadata; 5340090Smsmith for (;;) { 5440090Smsmith hdr = (u_int32_t *)curp; 5540157Speter if (hdr[0] == 0 && hdr[1] == 0) 5640090Smsmith break; 5740090Smsmith 5840090Smsmith /* Search for a MODINFO_NAME field */ 5940090Smsmith if ((hdr[0] == MODINFO_NAME) && 6040090Smsmith !strcmp(name, curp + sizeof(u_int32_t) * 2)) 6140090Smsmith return(curp); 6240090Smsmith 6340090Smsmith /* skip to next field */ 6440157Speter next = sizeof(u_int32_t) * 2 + hdr[1]; 6540157Speter next = roundup(next, sizeof(u_int32_t)); 6640157Speter curp += next; 6740090Smsmith } 6840090Smsmith } 6940090Smsmith return(NULL); 7040090Smsmith} 7140090Smsmith 7240090Smsmith/* 7340090Smsmith * Search for the first preloaded module of (type) 7440090Smsmith */ 7540090Smsmithcaddr_t 7640157Speterpreload_search_by_type(const char *type) 7740090Smsmith{ 7840090Smsmith caddr_t curp, lname; 7940090Smsmith u_int32_t *hdr; 8040157Speter int next; 8140090Smsmith 8240157Speter if (preload_metadata != NULL) { 8340090Smsmith 8440157Speter curp = preload_metadata; 8540090Smsmith lname = NULL; 8640090Smsmith for (;;) { 8740090Smsmith hdr = (u_int32_t *)curp; 8840157Speter if (hdr[0] == 0 && hdr[1] == 0) 8940090Smsmith break; 9040090Smsmith 9140090Smsmith /* remember the start of each record */ 9240090Smsmith if (hdr[0] == MODINFO_NAME) 9340090Smsmith lname = curp; 9440090Smsmith 9540090Smsmith /* Search for a MODINFO_TYPE field */ 9640090Smsmith if ((hdr[0] == MODINFO_TYPE) && 9740090Smsmith !strcmp(type, curp + sizeof(u_int32_t) * 2)) 9840090Smsmith return(lname); 9940090Smsmith 10040090Smsmith /* skip to next field */ 10140157Speter next = sizeof(u_int32_t) * 2 + hdr[1]; 10240157Speter next = roundup(next, sizeof(u_int32_t)); 10340157Speter curp += next; 10440090Smsmith } 10540090Smsmith } 10640090Smsmith return(NULL); 10740090Smsmith} 10840090Smsmith 10940090Smsmith/* 11040157Speter * Walk through the preloaded module list 11140157Speter */ 11240157Spetercaddr_t 11340157Speterpreload_search_next_name(caddr_t base) 11440157Speter{ 11540157Speter caddr_t curp; 11640157Speter u_int32_t *hdr; 11740157Speter int next; 11840157Speter 11940157Speter if (preload_metadata != NULL) { 12040157Speter 12140157Speter /* Pick up where we left off last time */ 12240157Speter if (base) { 12340157Speter /* skip to next field */ 12440157Speter curp = base; 12540157Speter hdr = (u_int32_t *)curp; 12640157Speter next = sizeof(u_int32_t) * 2 + hdr[1]; 12740157Speter next = roundup(next, sizeof(u_int32_t)); 12840157Speter curp += next; 12940157Speter } else 13040157Speter curp = preload_metadata; 13140157Speter 13240157Speter for (;;) { 13340157Speter hdr = (u_int32_t *)curp; 13440157Speter if (hdr[0] == 0 && hdr[1] == 0) 13540157Speter break; 13640157Speter 13740157Speter /* Found a new record? */ 13840157Speter if (hdr[0] == MODINFO_NAME) 13940157Speter return curp; 14040157Speter 14140157Speter /* skip to next field */ 14240157Speter next = sizeof(u_int32_t) * 2 + hdr[1]; 14340157Speter next = roundup(next, sizeof(u_int32_t)); 14440157Speter curp += next; 14540157Speter } 14640157Speter } 14740157Speter return(NULL); 14840157Speter} 14940157Speter 15040157Speter/* 15140090Smsmith * Given a preloaded module handle (mod), return a pointer 15240090Smsmith * to the data for the attribute (inf). 15340090Smsmith */ 15440090Smsmithcaddr_t 15540157Speterpreload_search_info(caddr_t mod, int inf) 15640090Smsmith{ 15740090Smsmith caddr_t curp; 15840090Smsmith u_int32_t *hdr; 15940090Smsmith u_int32_t type = 0; 16040157Speter int next; 16140090Smsmith 16240090Smsmith curp = mod; 16340090Smsmith for (;;) { 16440090Smsmith hdr = (u_int32_t *)curp; 16540090Smsmith /* end of module data? */ 16640157Speter if (hdr[0] == 0 && hdr[1] == 0) 16740090Smsmith break; 16840090Smsmith /* 16940090Smsmith * We give up once we've looped back to what we were looking at 17040090Smsmith * first - this should normally be a MODINFO_NAME field. 17140090Smsmith */ 17240090Smsmith if (type == 0) { 17340090Smsmith type = hdr[0]; 17440090Smsmith } else { 17540090Smsmith if (hdr[0] == type) 17640090Smsmith break; 17740090Smsmith } 17840090Smsmith 17940090Smsmith /* 18040090Smsmith * Attribute match? Return pointer to data. 18140090Smsmith * Consumer may safely assume that size value preceeds 18240090Smsmith * data. 18340090Smsmith */ 18440090Smsmith if (hdr[0] == inf) 18540090Smsmith return(curp + (sizeof(u_int32_t) * 2)); 18640090Smsmith 18740090Smsmith /* skip to next field */ 18840157Speter next = sizeof(u_int32_t) * 2 + hdr[1]; 18940157Speter next = roundup(next, sizeof(u_int32_t)); 19040157Speter curp += next; 19140090Smsmith } 19240090Smsmith return(NULL); 19340090Smsmith} 19440090Smsmith 19540157Speter/* 19640157Speter * Delete a preload record by name. 19740157Speter */ 19840157Spetervoid 19940157Speterpreload_delete_name(const char *name) 20040157Speter{ 20140157Speter caddr_t curp; 20240157Speter u_int32_t *hdr; 20340157Speter int next; 20440157Speter int clearing; 20540157Speter 20640157Speter if (preload_metadata != NULL) { 20740157Speter 20840157Speter clearing = 0; 20940157Speter curp = preload_metadata; 21040157Speter for (;;) { 21140157Speter hdr = (u_int32_t *)curp; 21240157Speter if (hdr[0] == 0 && hdr[1] == 0) 21340157Speter break; 21440157Speter 21540157Speter /* Search for a MODINFO_NAME field */ 21640157Speter if (hdr[0] == MODINFO_NAME) { 21740157Speter if (!strcmp(name, curp + sizeof(u_int32_t) * 2)) 21840157Speter clearing = 1; /* got it, start clearing */ 21940157Speter else if (clearing) 22040157Speter clearing = 0; /* at next one now.. better stop */ 22140157Speter } 22240157Speter if (clearing) 22340157Speter hdr[0] = MODINFO_EMPTY; 22440157Speter 22540157Speter /* skip to next field */ 22640157Speter next = sizeof(u_int32_t) * 2 + hdr[1]; 22740157Speter next = roundup(next, sizeof(u_int32_t)); 22840157Speter curp += next; 22940157Speter } 23040157Speter } 23140157Speter} 23240157Speter 23340157Speter/* Called from locore on i386. Convert physical pointers to kvm. Sigh. */ 23440157Spetervoid 23540157Speterpreload_bootstrap_relocate(vm_offset_t offset) 23640157Speter{ 23740157Speter caddr_t curp; 23840157Speter u_int32_t *hdr; 23940157Speter vm_offset_t *ptr; 24040157Speter int next; 24140157Speter 24240157Speter if (preload_metadata != NULL) { 24340157Speter 24440157Speter curp = preload_metadata; 24540157Speter for (;;) { 24640157Speter hdr = (u_int32_t *)curp; 24740157Speter if (hdr[0] == 0 && hdr[1] == 0) 24840157Speter break; 24940157Speter 25040157Speter /* Look for a MODINFO_ADDR field */ 25140157Speter if (hdr[0] == MODINFO_ADDR) { 25240157Speter ptr = (vm_offset_t *)(curp + (sizeof(u_int32_t) * 2)); 25340157Speter *ptr += offset; 25440157Speter } 25540157Speter /* The rest is beyond us for now */ 25640157Speter 25740157Speter /* skip to next field */ 25840157Speter next = sizeof(u_int32_t) * 2 + hdr[1]; 25940157Speter next = roundup(next, sizeof(u_int32_t)); 26040157Speter curp += next; 26140157Speter } 26240157Speter } 26340157Speter} 264