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/types.h> 30 #include <sys/param.h> 31 #include <sys/module.h> 32 #include <sys/linker.h> 33 34 #include <err.h> 35 #include <libutil.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <strings.h> 39 #include <unistd.h> 40 41 #define PTR_WIDTH ((int)(sizeof(void *) * 2 + 2)) 42 43 static void printmod(int); 44 static void printfile(int, int, int); 45 static void usage(void) __dead2; 46 47 static int showdata = 0; 48 49 static void 50 printmod(int modid) 51 { 52 struct module_stat stat; 53 54 bzero(&stat, sizeof(stat)); 55 stat.version = sizeof(struct module_stat); 56 if (modstat(modid, &stat) < 0) { 57 warn("can't stat module id %d", modid); 58 return; 59 } 60 if (showdata) { 61 printf("\t\t%3d %s (%d, %u, 0x%lx)\n", stat.id, 62 stat.name, stat.data.intval, stat.data.uintval, 63 stat.data.ulongval); 64 } else 65 printf("\t\t%3d %s\n", stat.id, stat.name); 66 } 67 68 static void 69 printfile(int fileid, int verbose, int humanized) 70 { 71 struct kld_file_stat stat; 72 int modid; 73 char buf[5]; 74 75 stat.version = sizeof(struct kld_file_stat); 76 if (kldstat(fileid, &stat) < 0) 77 err(1, "can't stat file id %d", fileid); 78 if (humanized) { 79 humanize_number(buf, sizeof(buf), stat.size, 80 "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE); 81 82 printf("%2d %4d %*p %5s %s", 83 stat.id, stat.refs, PTR_WIDTH, stat.address, 84 buf, stat.name); 85 } else { 86 printf("%2d %4d %*p %8zx %s", 87 stat.id, stat.refs, PTR_WIDTH, stat.address, 88 stat.size, stat.name); 89 } 90 91 if (verbose) { 92 printf(" (%s)\n", stat.pathname); 93 printf("\tContains modules:\n"); 94 printf("\t\t Id Name\n"); 95 for (modid = kldfirstmod(fileid); modid > 0; modid = modfnext(modid)) 96 printmod(modid); 97 } else 98 printf("\n"); 99 } 100 101 static void __dead2 102 usage(void) 103 { 104 fprintf(stderr, "usage: %1$s [-dhqv] [-i id] [-n filename]\n" 105 " %1$s [-dq] [-m modname]\n", getprogname()); 106 exit(1); 107 } 108 109 int 110 main(int argc, char *argv[]) 111 { 112 struct module_stat stat; 113 int humanized = 0; 114 int verbose = 0; 115 int fileid = 0; 116 int quiet = 0; 117 int c, modid; 118 char *filename = NULL; 119 char *modname = NULL; 120 char *p; 121 122 while ((c = getopt(argc, argv, "dhi:m:n:qv")) != -1) { 123 switch (c) { 124 case 'd': 125 showdata = 1; 126 break; 127 case 'h': 128 humanized = 1; 129 break; 130 case 'i': 131 fileid = (int)strtoul(optarg, &p, 10); 132 if (*p != '\0') 133 usage(); 134 break; 135 case 'm': 136 modname = optarg; 137 break; 138 case 'n': 139 filename = optarg; 140 break; 141 case 'q': 142 quiet = 1; 143 break; 144 case 'v': 145 verbose = 1; 146 break; 147 default: 148 usage(); 149 } 150 } 151 argc -= optind; 152 argv += optind; 153 154 if (argc != 0) 155 usage(); 156 157 if (modname != NULL) { 158 if ((modid = modfind(modname)) < 0) { 159 if (!quiet) 160 warn("can't find module %s", modname); 161 return (1); 162 } else if (quiet) 163 return (0); 164 165 stat.version = sizeof(struct module_stat); 166 if (modstat(modid, &stat) < 0) 167 warn("can't stat module id %d", modid); 168 else { 169 if (showdata) { 170 printf("Id Refs Name data..(int, uint, ulong)\n"); 171 printf("%3d %4d %s (%d, %u, 0x%lx)\n", 172 stat.id, stat.refs, stat.name, 173 stat.data.intval, stat.data.uintval, 174 stat.data.ulongval); 175 } else { 176 printf("Id Refs Name\n"); 177 printf("%3d %4d %s\n", stat.id, stat.refs, 178 stat.name); 179 } 180 } 181 182 return (0); 183 } 184 185 if (filename != NULL) { 186 if ((fileid = kldfind(filename)) < 0) { 187 if (!quiet) 188 warn("can't find file %s", filename); 189 return (1); 190 } else if (quiet) 191 return (0); 192 } 193 194 if (humanized) { 195 printf("Id Refs Address%*c %5s Name\n", PTR_WIDTH - 7, 196 ' ', "Size"); 197 } else { 198 printf("Id Refs Address%*c %8s Name\n", PTR_WIDTH - 7, 199 ' ', "Size"); 200 } 201 if (fileid != 0) 202 printfile(fileid, verbose, humanized); 203 else 204 for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) 205 printfile(fileid, verbose, humanized); 206 207 return (0); 208 } 209