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