]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sbin/kldstat/kldstat.c
MFC r368207,368607:
[FreeBSD/stable/10.git] / sbin / kldstat / kldstat.c
1 /*-
2  * Copyright (c) 1997 Doug Rabson
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <err.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/module.h>
37 #include <sys/linker.h>
38 #include <strings.h>
39
40 #define POINTER_WIDTH   ((int)(sizeof(void *) * 2 + 2))
41
42 static int showdata = 0;
43
44 static void
45 printmod(int modid)
46 {
47     struct module_stat stat;
48
49     bzero(&stat, sizeof(stat));
50     stat.version = sizeof(struct module_stat);
51     if (modstat(modid, &stat) < 0)
52         warn("can't stat module id %d", modid);
53     else
54         if (showdata) {
55             printf("\t\t%2d %s (%d, %u, 0x%lx)\n", stat.id, stat.name, 
56                 stat.data.intval, stat.data.uintval, stat.data.ulongval);
57         } else {
58                 printf("\t\t%2d %s\n", stat.id, stat.name);
59         }
60 }
61
62 static void
63 printfile(int fileid, int verbose)
64 {
65     struct kld_file_stat stat;
66     int modid;
67
68     stat.version = sizeof(struct kld_file_stat);
69     if (kldstat(fileid, &stat) < 0)
70         err(1, "can't stat file id %d", fileid);
71     else
72         printf("%2d %4d %p %-8zx %s",
73                stat.id, stat.refs, stat.address, stat.size, 
74                stat.name);
75
76     if (verbose) {
77         printf(" (%s)\n", stat.pathname);
78         printf("\tContains modules:\n");
79         printf("\t\tId Name\n");
80         for (modid = kldfirstmod(fileid); modid > 0;
81              modid = modfnext(modid))
82             printmod(modid);
83     } else
84         printf("\n");
85 }
86
87 static void
88 usage(void)
89 {
90     fprintf(stderr, "usage: kldstat [-d] [-q] [-v] [-i id] [-n filename]\n");
91     fprintf(stderr, "       kldstat [-d] [-q] [-m modname]\n");
92     exit(1);
93 }
94
95 int
96 main(int argc, char** argv)
97 {
98     int c;
99     int verbose = 0;
100     int fileid = 0;
101     int quiet = 0;
102     char* filename = NULL;
103     char* modname = NULL;
104     char* p;
105
106     while ((c = getopt(argc, argv, "di:m:n:qv")) != -1)
107         switch (c) {
108         case 'd':
109             showdata = 1;
110             break;
111         case 'i':
112             fileid = (int)strtoul(optarg, &p, 10);
113             if (*p != '\0')
114                 usage();
115             break;
116         case 'm':
117             modname = optarg;
118             break;
119         case 'n':
120             filename = optarg;
121             break;
122         case 'q':
123             quiet = 1;
124             break;
125         case 'v':
126             verbose = 1;
127             break;
128         default:
129             usage();
130         }
131     argc -= optind;
132     argv += optind;
133
134     if (argc != 0)
135         usage();
136
137     if (modname != NULL) {
138         int modid;
139         struct module_stat stat;
140
141         if ((modid = modfind(modname)) < 0) {
142             if (!quiet)
143                 warn("can't find module %s", modname);
144             return 1;
145         } else if (quiet) {
146             return 0;
147         }
148
149         stat.version = sizeof(struct module_stat);
150         if (modstat(modid, &stat) < 0)
151             warn("can't stat module id %d", modid);
152         else {
153                 if (showdata) {
154                     printf("Id  Refs Name data..(int, uint, ulong)\n");
155                     printf("%3d %4d %s (%d, %u, 0x%lx)\n", stat.id, stat.refs, stat.name, 
156                         stat.data.intval, stat.data.uintval, stat.data.ulongval);
157                 } else {
158                     printf("Id  Refs Name\n");
159                     printf("%3d %4d %s\n", stat.id, stat.refs, stat.name);
160                 }
161         }
162
163         return 0;
164     }
165
166     if (filename != NULL) {
167         if ((fileid = kldfind(filename)) < 0) {
168             if (!quiet)
169                 warn("can't find file %s", filename);
170             return 1;
171         } else if (quiet) {
172             return 0;
173         }
174     }
175
176     printf("Id Refs Address%*c Size     Name\n", POINTER_WIDTH - 7, ' ');
177     if (fileid != 0)
178         printfile(fileid, verbose);
179     else
180         for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid))
181             printfile(fileid, verbose);
182
183     return 0;
184 }