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"); |
|