2 * Copyright (c) 1998 Michael Smith
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/linker.h>
35 * Preloaded module support
38 vm_offset_t preload_addr_relocate = 0;
39 caddr_t preload_metadata;
42 * Search for the preloaded module (name)
45 preload_search_by_name(const char *name)
51 if (preload_metadata != NULL) {
53 curp = preload_metadata;
55 hdr = (uint32_t *)curp;
56 if (hdr[0] == 0 && hdr[1] == 0)
59 /* Search for a MODINFO_NAME field */
60 if ((hdr[0] == MODINFO_NAME) &&
61 !strcmp(name, curp + sizeof(uint32_t) * 2))
64 /* skip to next field */
65 next = sizeof(uint32_t) * 2 + hdr[1];
66 next = roundup(next, sizeof(u_long));
74 * Search for the first preloaded module of (type)
77 preload_search_by_type(const char *type)
83 if (preload_metadata != NULL) {
85 curp = preload_metadata;
88 hdr = (uint32_t *)curp;
89 if (hdr[0] == 0 && hdr[1] == 0)
92 /* remember the start of each record */
93 if (hdr[0] == MODINFO_NAME)
96 /* Search for a MODINFO_TYPE field */
97 if ((hdr[0] == MODINFO_TYPE) &&
98 !strcmp(type, curp + sizeof(uint32_t) * 2))
101 /* skip to next field */
102 next = sizeof(uint32_t) * 2 + hdr[1];
103 next = roundup(next, sizeof(u_long));
111 * Walk through the preloaded module list
114 preload_search_next_name(caddr_t base)
120 if (preload_metadata != NULL) {
122 /* Pick up where we left off last time */
124 /* skip to next field */
126 hdr = (uint32_t *)curp;
127 next = sizeof(uint32_t) * 2 + hdr[1];
128 next = roundup(next, sizeof(u_long));
131 curp = preload_metadata;
134 hdr = (uint32_t *)curp;
135 if (hdr[0] == 0 && hdr[1] == 0)
138 /* Found a new record? */
139 if (hdr[0] == MODINFO_NAME)
142 /* skip to next field */
143 next = sizeof(uint32_t) * 2 + hdr[1];
144 next = roundup(next, sizeof(u_long));
152 * Given a preloaded module handle (mod), return a pointer
153 * to the data for the attribute (inf).
156 preload_search_info(caddr_t mod, int inf)
168 hdr = (uint32_t *)curp;
169 /* end of module data? */
170 if (hdr[0] == 0 && hdr[1] == 0)
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.
184 * Attribute match? Return pointer to data.
185 * Consumer may safely assume that size value precedes
189 return(curp + (sizeof(uint32_t) * 2));
191 /* skip to next field */
192 next = sizeof(uint32_t) * 2 + hdr[1];
193 next = roundup(next, sizeof(u_long));
200 * Delete a preload record by name.
203 preload_delete_name(const char *name)
210 if (preload_metadata != NULL) {
213 curp = preload_metadata;
215 hdr = (uint32_t *)curp;
216 if (hdr[0] == 0 && hdr[1] == 0)
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 */
224 clearing = 0; /* at next one now.. better stop */
227 hdr[0] = MODINFO_EMPTY;
229 /* skip to next field */
230 next = sizeof(uint32_t) * 2 + hdr[1];
231 next = roundup(next, sizeof(u_long));
238 preload_fetch_addr(caddr_t mod)
242 mdp = (caddr_t *)preload_search_info(mod, MODINFO_ADDR);
245 return (*mdp + preload_addr_relocate);
249 preload_fetch_size(caddr_t mod)
253 mdp = (size_t *)preload_search_info(mod, MODINFO_SIZE);
259 /* Called from locore. Convert physical pointers to kvm. Sigh. */
261 preload_bootstrap_relocate(vm_offset_t offset)
268 if (preload_metadata != NULL) {
270 curp = preload_metadata;
272 hdr = (uint32_t *)curp;
273 if (hdr[0] == 0 && hdr[1] == 0)
276 /* Deal with the ones that we know we have to fix */
279 case MODINFO_METADATA|MODINFOMD_SSYM:
280 case MODINFO_METADATA|MODINFOMD_ESYM:
281 ptr = (vm_offset_t *)(curp + (sizeof(uint32_t) * 2));
285 /* The rest is beyond us for now */
287 /* skip to next field */
288 next = sizeof(uint32_t) * 2 + hdr[1];
289 next = roundup(next, sizeof(u_long));