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