kldstat.c revision 207964
125540Sdfr/*- 225540Sdfr * Copyright (c) 1997 Doug Rabson 325540Sdfr * All rights reserved. 425540Sdfr * 525540Sdfr * Redistribution and use in source and binary forms, with or without 625540Sdfr * modification, are permitted provided that the following conditions 725540Sdfr * are met: 825540Sdfr * 1. Redistributions of source code must retain the above copyright 925540Sdfr * notice, this list of conditions and the following disclaimer. 1025540Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1125540Sdfr * notice, this list of conditions and the following disclaimer in the 1225540Sdfr * documentation and/or other materials provided with the distribution. 1325540Sdfr * 1425540Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1525540Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1625540Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1725540Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1825540Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1925540Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2025540Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2125540Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2225540Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2325540Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2425540Sdfr * SUCH DAMAGE. 2525540Sdfr */ 2625540Sdfr 27114589Sobrien#include <sys/cdefs.h> 28114589Sobrien__FBSDID("$FreeBSD: head/sbin/kldstat/kldstat.c 207964 2010-05-12 15:47:43Z brueffer $"); 2932270Scharnier 3030573Sjmg#include <err.h> 3125540Sdfr#include <stdio.h> 3230573Sjmg#include <stdlib.h> 3325540Sdfr#include <unistd.h> 3425540Sdfr#include <sys/types.h> 3525540Sdfr#include <sys/param.h> 3625540Sdfr#include <sys/module.h> 3725540Sdfr#include <sys/linker.h> 3825540Sdfr 39129866Sdwmalone#define POINTER_WIDTH ((int)(sizeof(void *) * 2 + 2)) 4054130Smarcel 4130627Sjmgstatic void 4230627Sjmgprintmod(int modid) 4325540Sdfr{ 4425540Sdfr struct module_stat stat; 4525540Sdfr 4625540Sdfr stat.version = sizeof(struct module_stat); 4725540Sdfr if (modstat(modid, &stat) < 0) 4832270Scharnier warn("can't stat module id %d", modid); 4925540Sdfr else 5062327Sps printf("\t\t%2d %s\n", stat.id, stat.name); 5125540Sdfr} 5225540Sdfr 5325540Sdfrstatic void printfile(int fileid, int verbose) 5425540Sdfr{ 5525540Sdfr struct kld_file_stat stat; 5625540Sdfr int modid; 5725540Sdfr 5825540Sdfr stat.version = sizeof(struct kld_file_stat); 5925540Sdfr if (kldstat(fileid, &stat) < 0) 6032270Scharnier warn("can't stat file id %d", fileid); 6125540Sdfr else 62207964Sbrueffer printf("%2d %4d %p %-8zx %s", 63207964Sbrueffer stat.id, stat.refs, stat.address, stat.size, 64186398Sthompsa stat.name); 6525540Sdfr 6625540Sdfr if (verbose) { 67186398Sthompsa printf(" (%s)\n", stat.pathname); 6825540Sdfr printf("\tContains modules:\n"); 6962327Sps printf("\t\tId Name\n"); 7025540Sdfr for (modid = kldfirstmod(fileid); modid > 0; 7125540Sdfr modid = modfnext(modid)) 7225540Sdfr printmod(modid); 73186398Sthompsa } else 74186398Sthompsa printf("\n"); 7525540Sdfr} 7625540Sdfr 7725540Sdfrstatic void 7830627Sjmgusage(void) 7925540Sdfr{ 80146465Sru fprintf(stderr, "usage: kldstat [-v] [-i id] [-n filename]\n"); 81150509Spjd fprintf(stderr, " kldstat [-q] [-m modname]\n"); 8225540Sdfr exit(1); 8325540Sdfr} 8425540Sdfr 8530627Sjmgint 8630627Sjmgmain(int argc, char** argv) 8725540Sdfr{ 8825540Sdfr int c; 8925540Sdfr int verbose = 0; 9025540Sdfr int fileid = 0; 91150497Spjd int quiet = 0; 92113936Sjohan char* filename = NULL; 93145861Sfjoe char* modname = NULL; 94127004Sjmallett char* p; 9525540Sdfr 96150497Spjd while ((c = getopt(argc, argv, "i:m:n:qv")) != -1) 9725540Sdfr switch (c) { 9825540Sdfr case 'i': 99127004Sjmallett fileid = (int)strtoul(optarg, &p, 10); 100127004Sjmallett if (*p != '\0') 101127004Sjmallett usage(); 10225540Sdfr break; 103145861Sfjoe case 'm': 104145861Sfjoe modname = optarg; 105145861Sfjoe break; 10625540Sdfr case 'n': 10725540Sdfr filename = optarg; 10825540Sdfr break; 109150497Spjd case 'q': 110150497Spjd quiet = 1; 111150497Spjd break; 11230627Sjmg case 'v': 11330627Sjmg verbose = 1; 11430627Sjmg break; 11525540Sdfr default: 11625540Sdfr usage(); 11725540Sdfr } 11825540Sdfr argc -= optind; 11925540Sdfr argv += optind; 12025540Sdfr 12125540Sdfr if (argc != 0) 12225540Sdfr usage(); 12325540Sdfr 124145861Sfjoe if (modname != NULL) { 125145861Sfjoe int modid; 126145861Sfjoe struct module_stat stat; 127145861Sfjoe 128150497Spjd if ((modid = modfind(modname)) < 0) { 129150497Spjd if (!quiet) 130150497Spjd warn("can't find module %s", modname); 131150497Spjd return 1; 132150497Spjd } else if (quiet) { 133150497Spjd return 0; 134150497Spjd } 135145861Sfjoe 136145861Sfjoe stat.version = sizeof(struct module_stat); 137145861Sfjoe if (modstat(modid, &stat) < 0) 138145861Sfjoe warn("can't stat module id %d", modid); 139145861Sfjoe else { 140145861Sfjoe printf("Id Refs Name\n"); 141145861Sfjoe printf("%3d %4d %s\n", stat.id, stat.refs, stat.name); 142145861Sfjoe } 143145861Sfjoe 144145861Sfjoe return 0; 145145861Sfjoe } 146145861Sfjoe 147113936Sjohan if (filename != NULL) { 14830627Sjmg if ((fileid = kldfind(filename)) < 0) 14932270Scharnier err(1, "can't find file %s", filename); 15025540Sdfr } 15125540Sdfr 15254130Smarcel printf("Id Refs Address%*c Size Name\n", POINTER_WIDTH - 7, ' '); 153113936Sjohan if (fileid != 0) 15425540Sdfr printfile(fileid, verbose); 15525540Sdfr else 15625540Sdfr for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) 15725540Sdfr printfile(fileid, verbose); 15825540Sdfr 15925540Sdfr return 0; 16025540Sdfr} 161