125540Sdfr/*- 2330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3330449Seadler * 425540Sdfr * Copyright (c) 1997 Doug Rabson 525540Sdfr * All rights reserved. 625540Sdfr * 725540Sdfr * Redistribution and use in source and binary forms, with or without 825540Sdfr * modification, are permitted provided that the following conditions 925540Sdfr * are met: 1025540Sdfr * 1. Redistributions of source code must retain the above copyright 1125540Sdfr * notice, this list of conditions and the following disclaimer. 1225540Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1325540Sdfr * notice, this list of conditions and the following disclaimer in the 1425540Sdfr * documentation and/or other materials provided with the distribution. 1525540Sdfr * 1625540Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1725540Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1825540Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1925540Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2025540Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2125540Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2225540Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2325540Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2425540Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2525540Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2625540Sdfr * SUCH DAMAGE. 2725540Sdfr */ 2825540Sdfr 29114589Sobrien#include <sys/cdefs.h> 30114589Sobrien__FBSDID("$FreeBSD: stable/11/sbin/kldstat/kldstat.c 330449 2018-03-05 07:26:05Z eadler $"); 3132270Scharnier 3230573Sjmg#include <err.h> 33294624Strasz#include <libutil.h> 3425540Sdfr#include <stdio.h> 3530573Sjmg#include <stdlib.h> 3625540Sdfr#include <unistd.h> 3725540Sdfr#include <sys/types.h> 3825540Sdfr#include <sys/param.h> 3925540Sdfr#include <sys/module.h> 4025540Sdfr#include <sys/linker.h> 41297023Sjulian#include <strings.h> 4225540Sdfr 43129866Sdwmalone#define POINTER_WIDTH ((int)(sizeof(void *) * 2 + 2)) 4454130Smarcel 45297023Sjulianstatic int showdata = 0; 46297023Sjulian 4730627Sjmgstatic void 4830627Sjmgprintmod(int modid) 4925540Sdfr{ 5025540Sdfr struct module_stat stat; 5125540Sdfr 52297023Sjulian bzero(&stat, sizeof(stat)); 5325540Sdfr stat.version = sizeof(struct module_stat); 5425540Sdfr if (modstat(modid, &stat) < 0) 5532270Scharnier warn("can't stat module id %d", modid); 5625540Sdfr else 57297023Sjulian if (showdata) { 58297023Sjulian printf("\t\t%2d %s (%d, %u, 0x%lx)\n", stat.id, stat.name, 59297023Sjulian stat.data.intval, stat.data.uintval, stat.data.ulongval); 60297023Sjulian } else { 61297023Sjulian printf("\t\t%2d %s\n", stat.id, stat.name); 62297023Sjulian } 6325540Sdfr} 6425540Sdfr 65215248Skibstatic void 66294624Straszprintfile(int fileid, int verbose, int humanized) 6725540Sdfr{ 6825540Sdfr struct kld_file_stat stat; 6925540Sdfr int modid; 70294624Strasz char buf[5]; 7125540Sdfr 7225540Sdfr stat.version = sizeof(struct kld_file_stat); 73294624Strasz if (kldstat(fileid, &stat) < 0) { 74215248Skib err(1, "can't stat file id %d", fileid); 75294624Strasz } else { 76294624Strasz if (humanized) { 77294624Strasz humanize_number(buf, sizeof(buf), stat.size, 78294624Strasz "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE); 7925540Sdfr 80294624Strasz printf("%2d %4d %p %5s %s", 81294624Strasz stat.id, stat.refs, stat.address, buf, stat.name); 82294624Strasz } else { 83294624Strasz printf("%2d %4d %p %-8zx %s", 84294624Strasz stat.id, stat.refs, stat.address, stat.size, stat.name); 85294624Strasz } 86294624Strasz } 87294624Strasz 8825540Sdfr if (verbose) { 89186398Sthompsa printf(" (%s)\n", stat.pathname); 9025540Sdfr printf("\tContains modules:\n"); 9162327Sps printf("\t\tId Name\n"); 9225540Sdfr for (modid = kldfirstmod(fileid); modid > 0; 9325540Sdfr modid = modfnext(modid)) 9425540Sdfr printmod(modid); 95186398Sthompsa } else 96186398Sthompsa printf("\n"); 9725540Sdfr} 9825540Sdfr 9925540Sdfrstatic void 10030627Sjmgusage(void) 10125540Sdfr{ 102315210Smarkj fprintf(stderr, "usage: kldstat [-d] [-h] [-q] [-v] [-i id] [-n filename]\n"); 103297023Sjulian fprintf(stderr, " kldstat [-d] [-q] [-m modname]\n"); 10425540Sdfr exit(1); 10525540Sdfr} 10625540Sdfr 10730627Sjmgint 10830627Sjmgmain(int argc, char** argv) 10925540Sdfr{ 11025540Sdfr int c; 111294624Strasz int humanized = 0; 11225540Sdfr int verbose = 0; 11325540Sdfr int fileid = 0; 114150497Spjd int quiet = 0; 115113936Sjohan char* filename = NULL; 116145861Sfjoe char* modname = NULL; 117127004Sjmallett char* p; 11825540Sdfr 119297023Sjulian while ((c = getopt(argc, argv, "dhi:m:n:qv")) != -1) 12025540Sdfr switch (c) { 121297023Sjulian case 'd': 122297023Sjulian showdata = 1; 123297023Sjulian break; 124294624Strasz case 'h': 125294624Strasz humanized = 1; 126294624Strasz break; 12725540Sdfr case 'i': 128127004Sjmallett fileid = (int)strtoul(optarg, &p, 10); 129127004Sjmallett if (*p != '\0') 130127004Sjmallett usage(); 13125540Sdfr break; 132145861Sfjoe case 'm': 133145861Sfjoe modname = optarg; 134145861Sfjoe break; 13525540Sdfr case 'n': 13625540Sdfr filename = optarg; 13725540Sdfr break; 138150497Spjd case 'q': 139150497Spjd quiet = 1; 140150497Spjd break; 14130627Sjmg case 'v': 14230627Sjmg verbose = 1; 14330627Sjmg break; 14425540Sdfr default: 14525540Sdfr usage(); 14625540Sdfr } 14725540Sdfr argc -= optind; 14825540Sdfr argv += optind; 14925540Sdfr 15025540Sdfr if (argc != 0) 15125540Sdfr usage(); 15225540Sdfr 153145861Sfjoe if (modname != NULL) { 154145861Sfjoe int modid; 155145861Sfjoe struct module_stat stat; 156145861Sfjoe 157150497Spjd if ((modid = modfind(modname)) < 0) { 158150497Spjd if (!quiet) 159150497Spjd warn("can't find module %s", modname); 160150497Spjd return 1; 161150497Spjd } else if (quiet) { 162150497Spjd return 0; 163150497Spjd } 164145861Sfjoe 165145861Sfjoe stat.version = sizeof(struct module_stat); 166145861Sfjoe if (modstat(modid, &stat) < 0) 167145861Sfjoe warn("can't stat module id %d", modid); 168145861Sfjoe else { 169297023Sjulian if (showdata) { 170297023Sjulian printf("Id Refs Name data..(int, uint, ulong)\n"); 171297023Sjulian printf("%3d %4d %s (%d, %u, 0x%lx)\n", stat.id, stat.refs, stat.name, 172297023Sjulian stat.data.intval, stat.data.uintval, stat.data.ulongval); 173297023Sjulian } else { 174297023Sjulian printf("Id Refs Name\n"); 175297023Sjulian printf("%3d %4d %s\n", stat.id, stat.refs, stat.name); 176297023Sjulian } 177145861Sfjoe } 178145861Sfjoe 179145861Sfjoe return 0; 180145861Sfjoe } 181145861Sfjoe 182113936Sjohan if (filename != NULL) { 183261032Sbapt if ((fileid = kldfind(filename)) < 0) { 184261032Sbapt if (!quiet) 185261032Sbapt warn("can't find file %s", filename); 186261032Sbapt return 1; 187261032Sbapt } else if (quiet) { 188261032Sbapt return 0; 189261032Sbapt } 19025540Sdfr } 19125540Sdfr 192294624Strasz if (humanized) 193294624Strasz printf("Id Refs Address%*c Size Name\n", POINTER_WIDTH - 7, ' '); 194294624Strasz else 195294624Strasz printf("Id Refs Address%*c Size Name\n", POINTER_WIDTH - 7, ' '); 196113936Sjohan if (fileid != 0) 197294624Strasz printfile(fileid, verbose, humanized); 19825540Sdfr else 19925540Sdfr for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) 200294624Strasz printfile(fileid, verbose, humanized); 20125540Sdfr 20225540Sdfr return 0; 20325540Sdfr} 204