kldstat.c revision 215248
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 */ 2630627Sjmg 2725540Sdfr#include <sys/cdefs.h> 2825540Sdfr__FBSDID("$FreeBSD: head/sbin/kldstat/kldstat.c 215248 2010-11-13 16:49:07Z kib $"); 2930573Sjmg 3025540Sdfr#include <err.h> 3130573Sjmg#include <stdio.h> 3225540Sdfr#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> 3830627Sjmg 3930627Sjmg#define POINTER_WIDTH ((int)(sizeof(void *) * 2 + 2)) 4025540Sdfr 4125540Sdfrstatic void 4225540Sdfrprintmod(int modid) 4325540Sdfr{ 4425540Sdfr struct module_stat stat; 4530573Sjmg 4625540Sdfr stat.version = sizeof(struct module_stat); 4725540Sdfr if (modstat(modid, &stat) < 0) 4825540Sdfr warn("can't stat module id %d", modid); 4925540Sdfr else 5025540Sdfr printf("\t\t%2d %s\n", stat.id, stat.name); 5125540Sdfr} 5225540Sdfr 5325540Sdfrstatic void 5425540Sdfrprintfile(int fileid, int verbose) 5525540Sdfr{ 5625540Sdfr struct kld_file_stat stat; 5730573Sjmg int modid; 5825540Sdfr 5930573Sjmg stat.version = sizeof(struct kld_file_stat); 6025540Sdfr if (kldstat(fileid, &stat) < 0) 6125540Sdfr err(1, "can't stat file id %d", fileid); 6225540Sdfr else 6325540Sdfr printf("%2d %4d %p %-8zx %s", 6425540Sdfr stat.id, stat.refs, stat.address, stat.size, 6525540Sdfr stat.name); 6625540Sdfr 6725540Sdfr if (verbose) { 6825540Sdfr printf(" (%s)\n", stat.pathname); 6925540Sdfr printf("\tContains modules:\n"); 7025540Sdfr printf("\t\tId Name\n"); 7125540Sdfr for (modid = kldfirstmod(fileid); modid > 0; 7230627Sjmg modid = modfnext(modid)) 7325540Sdfr printmod(modid); 7430627Sjmg } else 7525540Sdfr printf("\n"); 7625540Sdfr} 7725540Sdfr 7830627Sjmgstatic void 7930627Sjmgusage(void) 8025540Sdfr{ 8125540Sdfr fprintf(stderr, "usage: kldstat [-v] [-i id] [-n filename]\n"); 8225540Sdfr fprintf(stderr, " kldstat [-q] [-m modname]\n"); 8325540Sdfr exit(1); 8425540Sdfr} 8525540Sdfr 8630627Sjmgint 8725540Sdfrmain(int argc, char** argv) 8825540Sdfr{ 8925540Sdfr int c; 9025540Sdfr int verbose = 0; 9125540Sdfr int fileid = 0; 9225540Sdfr int quiet = 0; 9325540Sdfr char* filename = NULL; 9430627Sjmg char* modname = NULL; 9530627Sjmg char* p; 9630627Sjmg 9725540Sdfr while ((c = getopt(argc, argv, "i:m:n:qv")) != -1) 9825540Sdfr switch (c) { 9925540Sdfr case 'i': 10025540Sdfr fileid = (int)strtoul(optarg, &p, 10); 10125540Sdfr if (*p != '\0') 10225540Sdfr usage(); 10325540Sdfr break; 10425540Sdfr case 'm': 10525540Sdfr modname = optarg; 10625540Sdfr break; 10730627Sjmg case 'n': 10825540Sdfr filename = optarg; 10925540Sdfr break; 11025540Sdfr case 'q': 11125540Sdfr quiet = 1; 11225540Sdfr break; 11325540Sdfr case 'v': 11425540Sdfr verbose = 1; 11525540Sdfr break; 11625540Sdfr default: 11725540Sdfr usage(); 11825540Sdfr } 11925540Sdfr argc -= optind; 120 argv += optind; 121 122 if (argc != 0) 123 usage(); 124 125 if (modname != NULL) { 126 int modid; 127 struct module_stat stat; 128 129 if ((modid = modfind(modname)) < 0) { 130 if (!quiet) 131 warn("can't find module %s", modname); 132 return 1; 133 } else if (quiet) { 134 return 0; 135 } 136 137 stat.version = sizeof(struct module_stat); 138 if (modstat(modid, &stat) < 0) 139 warn("can't stat module id %d", modid); 140 else { 141 printf("Id Refs Name\n"); 142 printf("%3d %4d %s\n", stat.id, stat.refs, stat.name); 143 } 144 145 return 0; 146 } 147 148 if (filename != NULL) { 149 if ((fileid = kldfind(filename)) < 0) 150 err(1, "can't find file %s", filename); 151 } 152 153 printf("Id Refs Address%*c Size Name\n", POINTER_WIDTH - 7, ' '); 154 if (fileid != 0) 155 printfile(fileid, verbose); 156 else 157 for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) 158 printfile(fileid, verbose); 159 160 return 0; 161} 162