summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_module.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-10-09 23:59:01 +0000
committerpeter <peter@FreeBSD.org>1998-10-09 23:59:01 +0000
commit3b07ecc0e349ad3b115b01faeebdd8e297876232 (patch)
tree74a89c74fcde749f978232153066bf06015c1b40 /sys/kern/subr_module.c
parent4ab7ac8a2ae2d2c195d72b5145f63bc7d7a6aac2 (diff)
downloadFreeBSD-src-3b07ecc0e349ad3b115b01faeebdd8e297876232.zip
FreeBSD-src-3b07ecc0e349ad3b115b01faeebdd8e297876232.tar.gz
Updates for alignment rounding. XXX this is highly machine dependent and
should probably be moved to i386/i386/link_machdep.c (and the same for the alpha). Implement "deleting" a preloaded module by destroying it's tags. This is a hack. We cannot reuse the data, it's been destroyed by relocation, statically initialized variables have been modified, etc. Note that to reclaim the load space is going to be more machine-dependent work. Implement a relocate hook for machdep.c to call so that the physical addresses get converted to the equivalent KVM addresses.
Diffstat (limited to 'sys/kern/subr_module.c')
-rw-r--r--sys/kern/subr_module.c149
1 files changed, 134 insertions, 15 deletions
diff --git a/sys/kern/subr_module.c b/sys/kern/subr_module.c
index 91730f5..acff4d1 100644
--- a/sys/kern/subr_module.c
+++ b/sys/kern/subr_module.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: subr_module.c,v 1.1 1998/10/09 00:31:29 msmith Exp $
*/
#include <sys/param.h>
@@ -35,23 +35,24 @@
* Preloaded module support
*/
-caddr_t module_metadata;
+caddr_t preload_metadata;
/*
* Search for the preloaded module (name)
*/
caddr_t
-module_search_by_name(const char *name)
+preload_search_by_name(const char *name)
{
caddr_t curp;
u_int32_t *hdr;
+ int next;
- if (module_metadata != NULL) {
+ if (preload_metadata != NULL) {
- curp = module_metadata;
+ curp = preload_metadata;
for (;;) {
hdr = (u_int32_t *)curp;
- if (hdr[0] == 0)
+ if (hdr[0] == 0 && hdr[1] == 0)
break;
/* Search for a MODINFO_NAME field */
@@ -60,7 +61,9 @@ module_search_by_name(const char *name)
return(curp);
/* skip to next field */
- curp += sizeof(u_int32_t) * 2 + hdr[1];
+ next = sizeof(u_int32_t) * 2 + hdr[1];
+ next = roundup(next, sizeof(u_int32_t));
+ curp += next;
}
}
return(NULL);
@@ -70,18 +73,19 @@ module_search_by_name(const char *name)
* Search for the first preloaded module of (type)
*/
caddr_t
-module_search_by_type(const char *type)
+preload_search_by_type(const char *type)
{
caddr_t curp, lname;
u_int32_t *hdr;
+ int next;
- if (module_metadata != NULL) {
+ if (preload_metadata != NULL) {
- curp = module_metadata;
+ curp = preload_metadata;
lname = NULL;
for (;;) {
hdr = (u_int32_t *)curp;
- if (hdr[0] == 0)
+ if (hdr[0] == 0 && hdr[1] == 0)
break;
/* remember the start of each record */
@@ -94,7 +98,50 @@ module_search_by_type(const char *type)
return(lname);
/* skip to next field */
- curp += sizeof(u_int32_t) * 2 + hdr[1];
+ next = sizeof(u_int32_t) * 2 + hdr[1];
+ next = roundup(next, sizeof(u_int32_t));
+ curp += next;
+ }
+ }
+ return(NULL);
+}
+
+/*
+ * Walk through the preloaded module list
+ */
+caddr_t
+preload_search_next_name(caddr_t base)
+{
+ caddr_t curp;
+ u_int32_t *hdr;
+ int next;
+
+ if (preload_metadata != NULL) {
+
+ /* Pick up where we left off last time */
+ if (base) {
+ /* skip to next field */
+ curp = base;
+ hdr = (u_int32_t *)curp;
+ next = sizeof(u_int32_t) * 2 + hdr[1];
+ next = roundup(next, sizeof(u_int32_t));
+ curp += next;
+ } else
+ curp = preload_metadata;
+
+ for (;;) {
+ hdr = (u_int32_t *)curp;
+ if (hdr[0] == 0 && hdr[1] == 0)
+ break;
+
+ /* Found a new record? */
+ if (hdr[0] == MODINFO_NAME)
+ return curp;
+
+ /* skip to next field */
+ next = sizeof(u_int32_t) * 2 + hdr[1];
+ next = roundup(next, sizeof(u_int32_t));
+ curp += next;
}
}
return(NULL);
@@ -105,17 +152,18 @@ module_search_by_type(const char *type)
* to the data for the attribute (inf).
*/
caddr_t
-module_search_info(caddr_t mod, int inf)
+preload_search_info(caddr_t mod, int inf)
{
caddr_t curp;
u_int32_t *hdr;
u_int32_t type = 0;
+ int next;
curp = mod;
for (;;) {
hdr = (u_int32_t *)curp;
/* end of module data? */
- if (hdr[0] == 0)
+ if (hdr[0] == 0 && hdr[1] == 0)
break;
/*
* We give up once we've looped back to what we were looking at
@@ -137,8 +185,79 @@ module_search_info(caddr_t mod, int inf)
return(curp + (sizeof(u_int32_t) * 2));
/* skip to next field */
- curp += sizeof(u_int32_t) * 2 + hdr[1];
+ next = sizeof(u_int32_t) * 2 + hdr[1];
+ next = roundup(next, sizeof(u_int32_t));
+ curp += next;
}
return(NULL);
}
+/*
+ * Delete a preload record by name.
+ */
+void
+preload_delete_name(const char *name)
+{
+ caddr_t curp;
+ u_int32_t *hdr;
+ int next;
+ int clearing;
+
+ if (preload_metadata != NULL) {
+
+ clearing = 0;
+ curp = preload_metadata;
+ for (;;) {
+ hdr = (u_int32_t *)curp;
+ if (hdr[0] == 0 && hdr[1] == 0)
+ break;
+
+ /* Search for a MODINFO_NAME field */
+ if (hdr[0] == MODINFO_NAME) {
+ if (!strcmp(name, curp + sizeof(u_int32_t) * 2))
+ clearing = 1; /* got it, start clearing */
+ else if (clearing)
+ clearing = 0; /* at next one now.. better stop */
+ }
+ if (clearing)
+ hdr[0] = MODINFO_EMPTY;
+
+ /* skip to next field */
+ next = sizeof(u_int32_t) * 2 + hdr[1];
+ next = roundup(next, sizeof(u_int32_t));
+ curp += next;
+ }
+ }
+}
+
+/* Called from locore on i386. Convert physical pointers to kvm. Sigh. */
+void
+preload_bootstrap_relocate(vm_offset_t offset)
+{
+ caddr_t curp;
+ u_int32_t *hdr;
+ vm_offset_t *ptr;
+ int next;
+
+ if (preload_metadata != NULL) {
+
+ curp = preload_metadata;
+ for (;;) {
+ hdr = (u_int32_t *)curp;
+ if (hdr[0] == 0 && hdr[1] == 0)
+ break;
+
+ /* Look for a MODINFO_ADDR field */
+ if (hdr[0] == MODINFO_ADDR) {
+ ptr = (vm_offset_t *)(curp + (sizeof(u_int32_t) * 2));
+ *ptr += offset;
+ }
+ /* The rest is beyond us for now */
+
+ /* skip to next field */
+ next = sizeof(u_int32_t) * 2 + hdr[1];
+ next = roundup(next, sizeof(u_int32_t));
+ curp += next;
+ }
+ }
+}
OpenPOWER on IntegriCloud