subr_module.c (6fed89b17970606e6b9562d8f9dc7ffee732839c) subr_module.c (22e6a670868487bc17e36270eb34f34074693b6a)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1998 Michael Smith
5 * All rights reserved.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1998 Michael Smith
5 * All rights reserved.
6 * Copyright (c) 2020 NetApp Inc.
7 * Copyright (c) 2020 Klara Inc.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the

--- 13 unchanged lines hidden (view full) ---

27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD$");
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/linker.h>
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

--- 13 unchanged lines hidden (view full) ---

29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD$");
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>
35
39
40#include <machine/metadata.h>
41
36#include <vm/vm.h>
37#include <vm/vm_extern.h>
38
39/*
40 * Preloaded module support
41 */
42
43vm_offset_t preload_addr_relocate = 0;

--- 255 unchanged lines hidden (view full) ---

299
300 /* skip to next field */
301 next = sizeof(uint32_t) * 2 + hdr[1];
302 next = roundup(next, sizeof(u_long));
303 curp += next;
304 }
305 }
306}
42#include <vm/vm.h>
43#include <vm/vm_extern.h>
44
45/*
46 * Preloaded module support
47 */
48
49vm_offset_t preload_addr_relocate = 0;

--- 255 unchanged lines hidden (view full) ---

305
306 /* skip to next field */
307 next = sizeof(uint32_t) * 2 + hdr[1];
308 next = roundup(next, sizeof(u_long));
309 curp += next;
310 }
311 }
312}
313
314/*
315 * Parse the modinfo type and append to the provided sbuf.
316 */
317static void
318preload_modinfo_type(struct sbuf *sbp, int type)
319{
320
321 if ((type & MODINFO_METADATA) == 0) {
322 switch (type) {
323 case MODINFO_END:
324 sbuf_cat(sbp, "MODINFO_END");
325 break;
326 case MODINFO_NAME:
327 sbuf_cat(sbp, "MODINFO_NAME");
328 break;
329 case MODINFO_TYPE:
330 sbuf_cat(sbp, "MODINFO_TYPE");
331 break;
332 case MODINFO_ADDR:
333 sbuf_cat(sbp, "MODINFO_ADDR");
334 break;
335 case MODINFO_SIZE:
336 sbuf_cat(sbp, "MODINFO_SIZE");
337 break;
338 case MODINFO_EMPTY:
339 sbuf_cat(sbp, "MODINFO_EMPTY");
340 break;
341 case MODINFO_ARGS:
342 sbuf_cat(sbp, "MODINFO_ARGS");
343 break;
344 default:
345 sbuf_cat(sbp, "unrecognized modinfo attribute");
346 }
347
348 return;
349 }
350
351 sbuf_cat(sbp, "MODINFO_METADATA | ");
352 switch (type & ~MODINFO_METADATA) {
353 case MODINFOMD_ELFHDR:
354 sbuf_cat(sbp, "MODINFOMD_ELFHDR");
355 break;
356 case MODINFOMD_SSYM:
357 sbuf_cat(sbp, "MODINFOMD_SSYM");
358 break;
359 case MODINFOMD_ESYM:
360 sbuf_cat(sbp, "MODINFOMD_ESYM");
361 break;
362 case MODINFOMD_DYNAMIC:
363 sbuf_cat(sbp, "MODINFOMD_DYNAMIC");
364 break;
365 case MODINFOMD_ENVP:
366 sbuf_cat(sbp, "MODINFOMD_ENVP");
367 break;
368 case MODINFOMD_HOWTO:
369 sbuf_cat(sbp, "MODINFOMD_HOWTO");
370 break;
371 case MODINFOMD_KERNEND:
372 sbuf_cat(sbp, "MODINFOMD_KERNEND");
373 break;
374 case MODINFOMD_SHDR:
375 sbuf_cat(sbp, "MODINFOMD_SHDR");
376 break;
377 case MODINFOMD_CTORS_ADDR:
378 sbuf_cat(sbp, "MODINFOMD_CTORS_ADDR");
379 break;
380 case MODINFOMD_CTORS_SIZE:
381 sbuf_cat(sbp, "MODINFOMD_CTORS_SIZE");
382 break;
383 case MODINFOMD_FW_HANDLE:
384 sbuf_cat(sbp, "MODINFOMD_FW_HANDLE");
385 break;
386 case MODINFOMD_KEYBUF:
387 sbuf_cat(sbp, "MODINFOMD_KEYBUF");
388 break;
389#ifdef MODINFOMD_SMAP
390 case MODINFOMD_SMAP:
391 sbuf_cat(sbp, "MODINFOMD_SMAP");
392 break;
393#endif
394#ifdef MODINFOMD_SMAP_XATTR
395 case MODINFOMD_SMAP_XATTR:
396 sbuf_cat(sbp, "MODINFOMD_SMAP_XATTR");
397 break;
398#endif
399#ifdef MODINFOMD_DTBP
400 case MODINFOMD_DTBP:
401 sbuf_cat(sbp, "MODINFOMD_DTBP");
402 break;
403#endif
404#ifdef MODINFOMD_EFI_MAP
405 case MODINFOMD_EFI_MAP:
406 sbuf_cat(sbp, "MODINFOMD_EFI_MAP");
407 break;
408#endif
409#ifdef MODINFOMD_EFI_FB
410 case MODINFOMD_EFI_FB:
411 sbuf_cat(sbp, "MODINFOMD_EFI_FB");
412 break;
413#endif
414#ifdef MODINFOMD_MODULEP
415 case MODINFOMD_MODULEP:
416 sbuf_cat(sbp, "MODINFOMD_MODULEP");
417 break;
418#endif
419 default:
420 sbuf_cat(sbp, "unrecognized metadata type");
421 }
422}
423
424/*
425 * Print the modinfo value, depending on type.
426 */
427static void
428preload_modinfo_value(struct sbuf *sbp, uint32_t *bptr, int type, int len)
429{
430#ifdef __LP64__
431#define sbuf_print_vmoffset(sb, o) sbuf_printf(sb, "0x%016lx", o);
432#else
433#define sbuf_print_vmoffset(sb, o) sbuf_printf(sb, "0x%08x", o);
434#endif
435
436 switch (type) {
437 case MODINFO_NAME:
438 case MODINFO_TYPE:
439 case MODINFO_ARGS:
440 sbuf_printf(sbp, "%s", (char *)bptr);
441 break;
442 case MODINFO_SIZE:
443 case MODINFO_METADATA | MODINFOMD_CTORS_SIZE:
444 sbuf_printf(sbp, "%lu", *(u_long *)bptr);
445 break;
446 case MODINFO_ADDR:
447 case MODINFO_METADATA | MODINFOMD_SSYM:
448 case MODINFO_METADATA | MODINFOMD_ESYM:
449 case MODINFO_METADATA | MODINFOMD_DYNAMIC:
450 case MODINFO_METADATA | MODINFOMD_KERNEND:
451 case MODINFO_METADATA | MODINFOMD_ENVP:
452 case MODINFO_METADATA | MODINFOMD_CTORS_ADDR:
453#ifdef MODINFOMD_SMAP
454 case MODINFO_METADATA | MODINFOMD_SMAP:
455#endif
456#ifdef MODINFOMD_SMAP_XATTR
457 case MODINFO_METADATA | MODINFOMD_SMAP_XATTR:
458#endif
459#ifdef MODINFOMD_DTBP
460 case MODINFO_METADATA | MODINFOMD_DTBP:
461#endif
462#ifdef MODINFOMD_EFI_FB
463 case MODINFO_METADATA | MODINFOMD_EFI_FB:
464#endif
465 sbuf_print_vmoffset(sbp, *(vm_offset_t *)bptr);
466 break;
467 case MODINFO_METADATA | MODINFOMD_HOWTO:
468 sbuf_printf(sbp, "0x%08x", *bptr);
469 break;
470 case MODINFO_METADATA | MODINFOMD_SHDR:
471 case MODINFO_METADATA | MODINFOMD_ELFHDR:
472 case MODINFO_METADATA | MODINFOMD_FW_HANDLE:
473 case MODINFO_METADATA | MODINFOMD_KEYBUF:
474#ifdef MODINFOMD_EFI_MAP
475 case MODINFO_METADATA | MODINFOMD_EFI_MAP:
476#endif
477 /* Don't print data buffers. */
478 sbuf_cat(sbp, "buffer contents omitted");
479 break;
480 default:
481 break;
482 }
483#undef sbuf_print_vmoffset
484}
485
486static void
487preload_dump_internal(struct sbuf *sbp)
488{
489 uint32_t *bptr, type, len;
490
491 KASSERT(preload_metadata != NULL,
492 ("%s called without setting up preload_metadata", __func__));
493
494 /*
495 * Iterate through the TLV-encoded sections.
496 */
497 bptr = (uint32_t *)preload_metadata;
498 sbuf_putc(sbp, '\n');
499 while (bptr[0] != MODINFO_END || bptr[0] != MODINFO_END) {
500 sbuf_printf(sbp, " %p:\n", bptr);
501 type = *bptr++;
502 len = *bptr++;
503
504 sbuf_printf(sbp, "\ttype:\t(%#04x) ", type);
505 preload_modinfo_type(sbp, type);
506 sbuf_putc(sbp, '\n');
507 sbuf_printf(sbp, "\tlen:\t%u\n", len);
508 sbuf_cat(sbp, "\tvalue:\t");
509 preload_modinfo_value(sbp, bptr, type, len);
510 sbuf_putc(sbp, '\n');
511
512 bptr += roundup(len, sizeof(u_long)) / sizeof(uint32_t);
513 }
514}
515
516/*
517 * Print the preloaded data to the console. Called from the machine-dependent
518 * initialization routines, e.g. hammer_time().
519 */
520void
521preload_dump(void)
522{
523 char buf[512];
524 struct sbuf sb;
525
526 /*
527 * This function is expected to be called before malloc is available,
528 * so use a static buffer and struct sbuf.
529 */
530 sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN);
531 sbuf_set_drain(&sb, sbuf_printf_drain, NULL);
532 preload_dump_internal(&sb);
533
534 sbuf_finish(&sb);
535 sbuf_delete(&sb);
536}
537
538static int
539sysctl_preload_dump(SYSCTL_HANDLER_ARGS)
540{
541 struct sbuf sb;
542 int error;
543
544 if (preload_metadata == NULL)
545 return (EINVAL);
546
547 sbuf_new_for_sysctl(&sb, NULL, 512, req);
548 preload_dump_internal(&sb);
549
550 error = sbuf_finish(&sb);
551 sbuf_delete(&sb);
552
553 return (error);
554}
555SYSCTL_PROC(_debug, OID_AUTO, dump_modinfo,
556 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
557 NULL, 0, sysctl_preload_dump, "A",
558 "pretty-print the bootloader metadata");