xref: /freebsd/sys/kern/subr_module.c (revision 63a40b65c9be74193bb07a76fd66c249bd562eae)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 1998 Michael Smith
5  * All rights reserved.
6  * Copyright (c) 2020 NetApp Inc.
7  * Copyright (c) 2020 Klara Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/linker.h>
34 #include <sys/sbuf.h>
35 #include <sys/sysctl.h>
36 
37 #include <machine/metadata.h>
38 
39 #include <vm/vm.h>
40 #include <vm/vm_extern.h>
41 
42 /*
43  * Preloaded module support
44  */
45 
46 vm_offset_t preload_addr_relocate = 0;
47 caddr_t preload_metadata, preload_kmdp;
48 
49 const char preload_modtype[] = MODTYPE;
50 const char preload_kerntype[] = KERNTYPE;
51 const char preload_modtype_obj[] = MODTYPE_OBJ;
52 
53 void
54 preload_initkmdp(bool fatal)
55 {
56 	preload_kmdp = preload_search_by_type(preload_kerntype);
57 
58 	if (preload_kmdp == NULL && fatal)
59 		panic("unable to find kernel metadata");
60 }
61 
62 /*
63  * Search for the preloaded module (name)
64  */
65 caddr_t
66 preload_search_by_name(const char *name)
67 {
68     caddr_t	curp;
69     uint32_t	*hdr;
70     int		next;
71 
72     if (preload_metadata != NULL) {
73 	curp = preload_metadata;
74 	for (;;) {
75 	    hdr = (uint32_t *)curp;
76 	    if (hdr[0] == 0 && hdr[1] == 0)
77 		break;
78 
79 	    /* Search for a MODINFO_NAME field */
80 	    if ((hdr[0] == MODINFO_NAME) &&
81 		!strcmp(name, curp + sizeof(uint32_t) * 2))
82 		return(curp);
83 
84 	    /* skip to next field */
85 	    next = sizeof(uint32_t) * 2 + hdr[1];
86 	    next = roundup(next, sizeof(u_long));
87 	    curp += next;
88 	}
89     }
90     return(NULL);
91 }
92 
93 /*
94  * Search for the first preloaded module of (type)
95  */
96 caddr_t
97 preload_search_by_type(const char *type)
98 {
99     caddr_t	curp, lname;
100     uint32_t	*hdr;
101     int		next;
102 
103     if (preload_metadata != NULL) {
104 	curp = preload_metadata;
105 	lname = NULL;
106 	for (;;) {
107 	    hdr = (uint32_t *)curp;
108 	    if (hdr[0] == 0 && hdr[1] == 0)
109 		break;
110 
111 	    /* remember the start of each record */
112 	    if (hdr[0] == MODINFO_NAME)
113 		lname = curp;
114 
115 	    /* Search for a MODINFO_TYPE field */
116 	    if ((hdr[0] == MODINFO_TYPE) &&
117 		!strcmp(type, curp + sizeof(uint32_t) * 2))
118 		return(lname);
119 
120 	    /* skip to next field */
121 	    next = sizeof(uint32_t) * 2 + hdr[1];
122 	    next = roundup(next, sizeof(u_long));
123 	    curp += next;
124 	}
125     }
126     return(NULL);
127 }
128 
129 /*
130  * Walk through the preloaded module list
131  */
132 caddr_t
133 preload_search_next_name(caddr_t base)
134 {
135     caddr_t	curp;
136     uint32_t	*hdr;
137     int		next;
138 
139     if (preload_metadata != NULL) {
140 	/* Pick up where we left off last time */
141 	if (base) {
142 	    /* skip to next field */
143 	    curp = base;
144 	    hdr = (uint32_t *)curp;
145 	    next = sizeof(uint32_t) * 2 + hdr[1];
146 	    next = roundup(next, sizeof(u_long));
147 	    curp += next;
148 	} else
149 	    curp = preload_metadata;
150 
151 	for (;;) {
152 	    hdr = (uint32_t *)curp;
153 	    if (hdr[0] == 0 && hdr[1] == 0)
154 		break;
155 
156 	    /* Found a new record? */
157 	    if (hdr[0] == MODINFO_NAME)
158 		return curp;
159 
160 	    /* skip to next field */
161 	    next = sizeof(uint32_t) * 2 + hdr[1];
162 	    next = roundup(next, sizeof(u_long));
163 	    curp += next;
164 	}
165     }
166     return(NULL);
167 }
168 
169 /*
170  * Given a preloaded module handle (mod), return a pointer
171  * to the data for the attribute (inf).
172  */
173 caddr_t
174 preload_search_info(caddr_t mod, int inf)
175 {
176     caddr_t	curp;
177     uint32_t	*hdr;
178     uint32_t	type = 0;
179     int		next;
180 
181     if (mod == NULL)
182     	return (NULL);
183 
184     curp = mod;
185     for (;;) {
186 	hdr = (uint32_t *)curp;
187 	/* end of module data? */
188 	if (hdr[0] == 0 && hdr[1] == 0)
189 	    break;
190 	/*
191 	 * We give up once we've looped back to what we were looking at
192 	 * first - this should normally be a MODINFO_NAME field.
193 	 */
194 	if (type == 0) {
195 	    type = hdr[0];
196 	} else {
197 	    if (hdr[0] == type)
198 		break;
199 	}
200 
201 	/*
202 	 * Attribute match? Return pointer to data.
203 	 * Consumer may safely assume that size value precedes
204 	 * data.
205 	 */
206 	if (hdr[0] == inf)
207 	    return(curp + (sizeof(uint32_t) * 2));
208 
209 	/* skip to next field */
210 	next = sizeof(uint32_t) * 2 + hdr[1];
211 	next = roundup(next, sizeof(u_long));
212 	curp += next;
213     }
214     return(NULL);
215 }
216 
217 /*
218  * Delete a preload record by name.
219  */
220 void
221 preload_delete_name(const char *name)
222 {
223     caddr_t	addr, curp;
224     uint32_t	*hdr, sz;
225     int		next;
226     int		clearing;
227 
228     addr = 0;
229     sz = 0;
230 
231     if (preload_metadata != NULL) {
232 	clearing = 0;
233 	curp = preload_metadata;
234 	for (;;) {
235 	    hdr = (uint32_t *)curp;
236 	    if (hdr[0] == MODINFO_NAME || (hdr[0] == 0 && hdr[1] == 0)) {
237 		/* Free memory used to store the file. */
238 		if (addr != 0 && sz != 0)
239 		    kmem_bootstrap_free((vm_offset_t)addr, sz);
240 		addr = 0;
241 		sz = 0;
242 
243 		if (hdr[0] == 0)
244 		    break;
245 		if (!strcmp(name, curp + sizeof(uint32_t) * 2))
246 		    clearing = 1;	/* got it, start clearing */
247 		else if (clearing) {
248 		    clearing = 0;	/* at next one now.. better stop */
249 		}
250 	    }
251 	    if (clearing) {
252 		if (hdr[0] == MODINFO_ADDR)
253 		    addr = *(caddr_t *)(curp + sizeof(uint32_t) * 2);
254 		else if (hdr[0] == MODINFO_SIZE)
255 		    sz = *(uint32_t *)(curp + sizeof(uint32_t) * 2);
256 		hdr[0] = MODINFO_EMPTY;
257 	    }
258 
259 	    /* skip to next field */
260 	    next = sizeof(uint32_t) * 2 + hdr[1];
261 	    next = roundup(next, sizeof(u_long));
262 	    curp += next;
263 	}
264     }
265 }
266 
267 void *
268 preload_fetch_addr(caddr_t mod)
269 {
270 	caddr_t *mdp;
271 
272 	mdp = (caddr_t *)preload_search_info(mod, MODINFO_ADDR);
273 	if (mdp == NULL)
274 		return (NULL);
275 	return (*mdp + preload_addr_relocate);
276 }
277 
278 size_t
279 preload_fetch_size(caddr_t mod)
280 {
281 	size_t *mdp;
282 
283 	mdp = (size_t *)preload_search_info(mod, MODINFO_SIZE);
284 	if (mdp == NULL)
285 		return (0);
286 	return (*mdp);
287 }
288 
289 /* Called from locore.  Convert physical pointers to kvm. Sigh. */
290 void
291 preload_bootstrap_relocate(vm_offset_t offset)
292 {
293     caddr_t	curp;
294     uint32_t	*hdr;
295     vm_offset_t	*ptr;
296     int		next;
297 
298     if (preload_metadata != NULL) {
299 	curp = preload_metadata;
300 	for (;;) {
301 	    hdr = (uint32_t *)curp;
302 	    if (hdr[0] == 0 && hdr[1] == 0)
303 		break;
304 
305 	    /* Deal with the ones that we know we have to fix */
306 	    switch (hdr[0]) {
307 	    case MODINFO_ADDR:
308 	    case MODINFO_METADATA|MODINFOMD_FONT:
309 	    case MODINFO_METADATA|MODINFOMD_SPLASH:
310 	    case MODINFO_METADATA|MODINFOMD_SHTDWNSPLASH:
311 	    case MODINFO_METADATA|MODINFOMD_SSYM:
312 	    case MODINFO_METADATA|MODINFOMD_ESYM:
313 		ptr = (vm_offset_t *)(curp + (sizeof(uint32_t) * 2));
314 		*ptr += offset;
315 		break;
316 	    }
317 	    /* The rest is beyond us for now */
318 
319 	    /* skip to next field */
320 	    next = sizeof(uint32_t) * 2 + hdr[1];
321 	    next = roundup(next, sizeof(u_long));
322 	    curp += next;
323 	}
324     }
325 }
326 
327 /*
328  * Parse the modinfo type and append to the provided sbuf.
329  */
330 static void
331 preload_modinfo_type(struct sbuf *sbp, int type)
332 {
333 
334 	if ((type & MODINFO_METADATA) == 0) {
335 		switch (type) {
336 		case MODINFO_END:
337 			sbuf_cat(sbp, "MODINFO_END");
338 			break;
339 		case MODINFO_NAME:
340 			sbuf_cat(sbp, "MODINFO_NAME");
341 			break;
342 		case MODINFO_TYPE:
343 			sbuf_cat(sbp, "MODINFO_TYPE");
344 			break;
345 		case MODINFO_ADDR:
346 			sbuf_cat(sbp, "MODINFO_ADDR");
347 			break;
348 		case MODINFO_SIZE:
349 			sbuf_cat(sbp, "MODINFO_SIZE");
350 			break;
351 		case MODINFO_EMPTY:
352 			sbuf_cat(sbp, "MODINFO_EMPTY");
353 			break;
354 		case MODINFO_ARGS:
355 			sbuf_cat(sbp, "MODINFO_ARGS");
356 			break;
357 		default:
358 			sbuf_cat(sbp, "unrecognized modinfo attribute");
359 		}
360 
361 		return;
362 	}
363 
364 	sbuf_cat(sbp, "MODINFO_METADATA | ");
365 	switch (type & ~MODINFO_METADATA) {
366 	case MODINFOMD_ELFHDR:
367 		sbuf_cat(sbp, "MODINFOMD_ELFHDR");
368 		break;
369 	case MODINFOMD_SSYM:
370 		sbuf_cat(sbp, "MODINFOMD_SSYM");
371 		break;
372 	case MODINFOMD_ESYM:
373 		sbuf_cat(sbp, "MODINFOMD_ESYM");
374 		break;
375 	case MODINFOMD_DYNAMIC:
376 		sbuf_cat(sbp, "MODINFOMD_DYNAMIC");
377 		break;
378 	case MODINFOMD_ENVP:
379 		sbuf_cat(sbp, "MODINFOMD_ENVP");
380 		break;
381 	case MODINFOMD_HOWTO:
382 		sbuf_cat(sbp, "MODINFOMD_HOWTO");
383 		break;
384 	case MODINFOMD_KERNEND:
385 		sbuf_cat(sbp, "MODINFOMD_KERNEND");
386 		break;
387 	case MODINFOMD_SHDR:
388 		sbuf_cat(sbp, "MODINFOMD_SHDR");
389 		break;
390 	case MODINFOMD_CTORS_ADDR:
391 		sbuf_cat(sbp, "MODINFOMD_CTORS_ADDR");
392 		break;
393 	case MODINFOMD_CTORS_SIZE:
394 		sbuf_cat(sbp, "MODINFOMD_CTORS_SIZE");
395 		break;
396 	case MODINFOMD_FW_HANDLE:
397 		sbuf_cat(sbp, "MODINFOMD_FW_HANDLE");
398 		break;
399 	case MODINFOMD_KEYBUF:
400 		sbuf_cat(sbp, "MODINFOMD_KEYBUF");
401 		break;
402 #ifdef MODINFOMD_SMAP
403 	case MODINFOMD_SMAP:
404 		sbuf_cat(sbp, "MODINFOMD_SMAP");
405 		break;
406 #endif
407 #ifdef MODINFOMD_SMAP_XATTR
408 	case MODINFOMD_SMAP_XATTR:
409 		sbuf_cat(sbp, "MODINFOMD_SMAP_XATTR");
410 		break;
411 #endif
412 #ifdef MODINFOMD_DTBP
413 	case MODINFOMD_DTBP:
414 		sbuf_cat(sbp, "MODINFOMD_DTBP");
415 		break;
416 #endif
417 #ifdef MODINFOMD_EFI_MAP
418 	case MODINFOMD_EFI_MAP:
419 		sbuf_cat(sbp, "MODINFOMD_EFI_MAP");
420 		break;
421 #endif
422 #ifdef MODINFOMD_EFI_FB
423 	case MODINFOMD_EFI_FB:
424 		sbuf_cat(sbp, "MODINFOMD_EFI_FB");
425 		break;
426 #endif
427 #ifdef MODINFOMD_MODULEP
428 	case MODINFOMD_MODULEP:
429 		sbuf_cat(sbp, "MODINFOMD_MODULEP");
430 		break;
431 #endif
432 #ifdef MODINFOMD_VBE_FB
433 	case MODINFOMD_VBE_FB:
434 		sbuf_cat(sbp, "MODINFOMD_VBE_FB");
435 		break;
436 #endif
437 	case MODINFOMD_FONT:
438 		sbuf_cat(sbp, "MODINFOMD_FONT");
439 		break;
440 	case MODINFOMD_SPLASH:
441 		sbuf_cat(sbp, "MODINFOMD_SPLASH");
442 		break;
443 	case MODINFOMD_SHTDWNSPLASH:
444 		sbuf_cat(sbp, "MODINFOMD_SHTDWNSPLASH");
445 		break;
446 #ifdef MODINFOMD_BOOT_HARTID
447 	case MODINFOMD_BOOT_HARTID:
448 		sbuf_cat(sbp, "MODINFOMD_BOOT_HARTID");
449 		break;
450 #endif
451 #ifdef MODINFOMD_EFI_ARCH
452 	case MODINFOMD_EFI_ARCH:
453 		sbuf_cat(sbp, "MODINFOMD_EFI_ARCH");
454 		break;
455 #endif
456 	default:
457 		sbuf_cat(sbp, "unrecognized metadata type");
458 	}
459 }
460 
461 /*
462  * Print the modinfo value, depending on type.
463  */
464 static void
465 preload_modinfo_value(struct sbuf *sbp, uint32_t *bptr, int type, int len)
466 {
467 #ifdef __LP64__
468 #define sbuf_print_vmoffset(sb, o)	sbuf_printf(sb, "0x%016lx", o);
469 #else
470 #define sbuf_print_vmoffset(sb, o)	sbuf_printf(sb, "0x%08x", o);
471 #endif
472 
473 	switch (type) {
474 	case MODINFO_NAME:
475 	case MODINFO_TYPE:
476 	case MODINFO_ARGS:
477 #ifdef MODINFOMD_EFI_ARCH
478 	case MODINFO_METADATA | MODINFOMD_EFI_ARCH:
479 #endif
480 		sbuf_printf(sbp, "%s", (char *)bptr);
481 		break;
482 	case MODINFO_SIZE:
483 	case MODINFO_METADATA | MODINFOMD_CTORS_SIZE:
484 		sbuf_printf(sbp, "%lu", *(u_long *)bptr);
485 		break;
486 	case MODINFO_ADDR:
487 	case MODINFO_METADATA | MODINFOMD_SSYM:
488 	case MODINFO_METADATA | MODINFOMD_ESYM:
489 	case MODINFO_METADATA | MODINFOMD_DYNAMIC:
490 	case MODINFO_METADATA | MODINFOMD_KERNEND:
491 	case MODINFO_METADATA | MODINFOMD_ENVP:
492 	case MODINFO_METADATA | MODINFOMD_CTORS_ADDR:
493 #ifdef MODINFOMD_SMAP
494 	case MODINFO_METADATA | MODINFOMD_SMAP:
495 #endif
496 #ifdef MODINFOMD_SMAP_XATTR
497 	case MODINFO_METADATA | MODINFOMD_SMAP_XATTR:
498 #endif
499 #ifdef MODINFOMD_DTBP
500 	case MODINFO_METADATA | MODINFOMD_DTBP:
501 #endif
502 #ifdef MODINFOMD_EFI_FB
503 	case MODINFO_METADATA | MODINFOMD_EFI_FB:
504 #endif
505 #ifdef MODINFOMD_VBE_FB
506 	case MODINFO_METADATA | MODINFOMD_VBE_FB:
507 #endif
508 	case MODINFO_METADATA | MODINFOMD_FONT:
509 	case MODINFO_METADATA | MODINFOMD_SPLASH:
510 	case MODINFO_METADATA | MODINFOMD_SHTDWNSPLASH:
511 		sbuf_print_vmoffset(sbp, *(vm_offset_t *)bptr);
512 		break;
513 	case MODINFO_METADATA | MODINFOMD_HOWTO:
514 		sbuf_printf(sbp, "0x%08x", *bptr);
515 		break;
516 #ifdef MODINFOMD_BOOT_HARTID
517 	case MODINFO_METADATA | MODINFOMD_BOOT_HARTID:
518 		sbuf_printf(sbp, "0x%lu", *(uint64_t *)bptr);
519 		break;
520 #endif
521 	case MODINFO_METADATA | MODINFOMD_SHDR:
522 	case MODINFO_METADATA | MODINFOMD_ELFHDR:
523 	case MODINFO_METADATA | MODINFOMD_FW_HANDLE:
524 	case MODINFO_METADATA | MODINFOMD_KEYBUF:
525 #ifdef MODINFOMD_EFI_MAP
526 	case MODINFO_METADATA | MODINFOMD_EFI_MAP:
527 #endif
528 		/* Don't print data buffers. */
529 		sbuf_cat(sbp, "buffer contents omitted");
530 		break;
531 	default:
532 		break;
533 	}
534 #undef sbuf_print_vmoffset
535 }
536 
537 static void
538 preload_dump_internal(struct sbuf *sbp)
539 {
540 	uint32_t *bptr, type, len;
541 
542 	KASSERT(preload_metadata != NULL,
543 	    ("%s called without setting up preload_metadata", __func__));
544 
545 	/*
546 	 * Iterate through the TLV-encoded sections.
547 	 */
548 	bptr = (uint32_t *)preload_metadata;
549 	sbuf_putc(sbp, '\n');
550 	while (bptr[0] != MODINFO_END || bptr[1] != MODINFO_END) {
551 		sbuf_printf(sbp, " %p:\n", bptr);
552 		type = *bptr++;
553 		len = *bptr++;
554 
555 		sbuf_printf(sbp, "\ttype:\t(%#04x) ", type);
556 		preload_modinfo_type(sbp, type);
557 		sbuf_putc(sbp, '\n');
558 		sbuf_printf(sbp, "\tlen:\t%u\n", len);
559 		sbuf_cat(sbp, "\tvalue:\t");
560 		preload_modinfo_value(sbp, bptr, type, len);
561 		sbuf_putc(sbp, '\n');
562 
563 		bptr += roundup(len, sizeof(u_long)) / sizeof(uint32_t);
564 	}
565 }
566 
567 /*
568  * Print the preloaded data to the console. Called from the machine-dependent
569  * initialization routines, e.g. hammer_time().
570  */
571 void
572 preload_dump(void)
573 {
574 	char buf[512];
575 	struct sbuf sb;
576 
577 	/*
578 	 * This function is expected to be called before malloc is available,
579 	 * so use a static buffer and struct sbuf.
580 	 */
581 	sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN);
582 	sbuf_set_drain(&sb, sbuf_printf_drain, NULL);
583 	preload_dump_internal(&sb);
584 
585 	sbuf_finish(&sb);
586 	sbuf_delete(&sb);
587 }
588 
589 static int
590 sysctl_preload_dump(SYSCTL_HANDLER_ARGS)
591 {
592 	struct sbuf sb;
593 	int error;
594 
595 	if (preload_metadata == NULL)
596 		return (EINVAL);
597 
598 	sbuf_new_for_sysctl(&sb, NULL, 512, req);
599 	preload_dump_internal(&sb);
600 
601 	error = sbuf_finish(&sb);
602 	sbuf_delete(&sb);
603 
604 	return (error);
605 }
606 SYSCTL_PROC(_debug, OID_AUTO, dump_modinfo,
607     CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
608     NULL, 0, sysctl_preload_dump, "A",
609     "pretty-print the bootloader metadata");
610