kldstat.c revision 172862
11590Srgrimes/*-
21590Srgrimes * Copyright (c) 1997 Doug Rabson
31590Srgrimes * All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes *
141590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
151590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
161590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
171590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
181590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
191590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
201590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
211590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
221590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
231590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
241590Srgrimes * SUCH DAMAGE.
251590Srgrimes */
261590Srgrimes
271590Srgrimes#include <sys/cdefs.h>
2818361Swollman__FBSDID("$FreeBSD: head/sbin/kldstat/kldstat.c 172862 2007-10-22 04:12:57Z jb $");
2950477Speter
301590Srgrimes#include <err.h>
31235541Skib#include <stdint.h>
321590Srgrimes#include <stdio.h>
3379535Sru#include <stdlib.h>
341590Srgrimes#include <unistd.h>
351590Srgrimes#include <sys/types.h>
36168367Sdds#include <sys/param.h>
371590Srgrimes#include <sys/module.h>
3827571Scharnier#include <sys/linker.h>
3916849Swosch
401590Srgrimes#define	POINTER_WIDTH	((int)(sizeof(void *) * 2 + 2))
41235541Skib
4270197Srustatic void
4370197Sruprintmod(int modid)
4470197Sru{
451590Srgrimes    struct module_stat stat;
4695162Scharnier
4795162Scharnier    stat.version = sizeof(struct module_stat);
4895162Scharnier    if (modstat(modid, &stat) < 0)
491590Srgrimes	warn("can't stat module id %d", modid);
5027571Scharnier    else
511590Srgrimes	printf("\t\t%2d %s\n", stat.id, stat.name);
521590Srgrimes}
531590Srgrimes
5416849Swoschstatic void printfile(int fileid, int verbose)
55132670Scharnier{
5616849Swosch    struct kld_file_stat stat;
5718361Swollman    int modid;
5816849Swosch
5918361Swollman    stat.version = sizeof(struct kld_file_stat);
6016849Swosch    if (kldstat(fileid, &stat) < 0)
6118361Swollman	warn("can't stat file id %d", fileid);
6216849Swosch    else
6318361Swollman	printf("%2d %4d %p %-8jx %s (%s)\n",
6416849Swosch	       stat.id, stat.refs, stat.address, (uintmax_t)stat.size,
6518361Swollman	       stat.name, stat.pathname);
6616849Swosch
6718361Swollman    if (verbose) {
681590Srgrimes	printf("\tContains modules:\n");
691590Srgrimes	printf("\t\tId Name\n");
701590Srgrimes	for (modid = kldfirstmod(fileid); modid > 0;
711590Srgrimes	     modid = modfnext(modid))
7218361Swollman	    printmod(modid);
73168367Sdds    }
74168367Sdds}
75168367Sdds
76168367Sddsstatic void
77168367Sddsusage(void)
78168367Sdds{
791590Srgrimes    fprintf(stderr, "usage: kldstat [-v] [-i id] [-n filename]\n");
801590Srgrimes    fprintf(stderr, "       kldstat [-q] [-m modname]\n");
81235541Skib    exit(1);
82235541Skib}
83235541Skib
84235541Skibint
85235541Skibmain(int argc, char** argv)
86235541Skib{
87235541Skib    int c;
88235541Skib    int verbose = 0;
89235541Skib    int fileid = 0;
9018361Swollman    int quiet = 0;
9118361Swollman    char* filename = NULL;
9218361Swollman    char* modname = NULL;
9318361Swollman    char* p;
9418361Swollman
9518361Swollman    while ((c = getopt(argc, argv, "i:m:n:qv")) != -1)
961590Srgrimes	switch (c) {
971590Srgrimes	case 'i':
981590Srgrimes	    fileid = (int)strtoul(optarg, &p, 10);
991590Srgrimes	    if (*p != '\0')
1001590Srgrimes		usage();
1011590Srgrimes	    break;
1021590Srgrimes	case 'm':
1031590Srgrimes	    modname = optarg;
1041590Srgrimes	    break;
10518361Swollman	case 'n':
1061590Srgrimes	    filename = optarg;
1071590Srgrimes	    break;
1081590Srgrimes	case 'q':
1091590Srgrimes	    quiet = 1;
1101590Srgrimes	    break;
1111590Srgrimes	case 'v':
1121590Srgrimes	    verbose = 1;
1131590Srgrimes	    break;
1141590Srgrimes	default:
115131507Sru	    usage();
1161590Srgrimes	}
1171590Srgrimes    argc -= optind;
1181590Srgrimes    argv += optind;
1191590Srgrimes
1201590Srgrimes    if (argc != 0)
1211590Srgrimes	usage();
1221590Srgrimes
1231590Srgrimes    if (modname != NULL) {
1241590Srgrimes	int modid;
1251590Srgrimes	struct module_stat stat;
1261590Srgrimes
12779755Sdd	if ((modid = modfind(modname)) < 0) {
12818361Swollman	    if (!quiet)
12918361Swollman		warn("can't find module %s", modname);
13018361Swollman	    return 1;
13118361Swollman	} else if (quiet) {
13218361Swollman	    return 0;
13318361Swollman	}
13418361Swollman
13518361Swollman	stat.version = sizeof(struct module_stat);
13618361Swollman	if (modstat(modid, &stat) < 0)
1371590Srgrimes	    warn("can't stat module id %d", modid);
13818361Swollman	else {
13918361Swollman	    printf("Id  Refs Name\n");
14018361Swollman	    printf("%3d %4d %s\n", stat.id, stat.refs, stat.name);
14118361Swollman	}
1421590Srgrimes
1431590Srgrimes	return 0;
1441590Srgrimes    }
1451590Srgrimes
1461590Srgrimes    if (filename != NULL) {
14795162Scharnier	if ((fileid = kldfind(filename)) < 0)
14818361Swollman	    err(1, "can't find file %s", filename);
14918361Swollman    }
1501590Srgrimes
1511590Srgrimes    printf("Id Refs Address%*c Size     Name\n", POINTER_WIDTH - 7, ' ');
1521590Srgrimes    if (fileid != 0)
153168367Sdds	printfile(fileid, verbose);
154168367Sdds    else
155168367Sdds	for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid))
156168367Sdds	    printfile(fileid, verbose);
157168367Sdds
158168367Sdds    return 0;
159168367Sdds}
160168367Sdds