4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
32 #include <sys/modctl.h>
33 #include <sys/errno.h>
37 static int first_mod
= 1;
40 * When printing module load addresses on 32-bit kernels, the 8 hex
41 * character field width is obviously adequate. On sparcv9 kernels
42 * solely by virtue of the choice of code model enabled by the separate
43 * kernel context, the text addresses are currently in the lower 4G
44 * address range, and so -still- fit in 8 hex characters.
46 * However, amd64 kernels live at the top of the 64-bit address space, and
47 * so as to be honest about the addresses (and since this is a tool for
48 * humans to parse), we have to print out a 16 hex character address.
50 * We assume that we will print out all 16 hex characters on future
51 * 64-bit kernel ports too.
53 static const char header
[] =
55 #if defined(_LP64) && !defined(__sparcv9)
58 "Loadaddr Size Info Rev Module Name\n";
60 static char *cheader
=
61 " Id Loadcnt Module Name State\n";
65 static void print_info(struct modinfo
*mi
);
66 static void print_cinfo(struct modinfo
*mi
);
69 * These functions are in modsubr.c
71 void fatal(char *fmt
, ...);
72 void error(char *fmt
, ...);
75 * Display information of all loaded modules
78 main(int argc
, char *argv
[])
80 struct modinfo modinfo
;
85 id
= -1; /* assume we're getting all loaded modules */
87 while ((opt
= getopt(argc
, argv
, "i:wc")) != EOF
) {
90 if (sscanf(optarg
, "%d", &id
) != 1)
91 fatal("Invalid id %s\n", optarg
);
111 * Next id of -1 means we're getting info on all modules.
113 modinfo
.mi_id
= modinfo
.mi_nextid
= id
;
114 modinfo
.mi_info
= (info_all
) ? MI_INFO_ALL
: MI_INFO_ONE
;
117 modinfo
.mi_info
|= MI_INFO_CNT
;
121 * Get module information.
122 * If modinfo.mi_nextid == -1, get info about the
123 * next installed module with id > "id."
124 * Otherwise, get info about the module with id == "id."
126 if (modctl(MODINFO
, id
, &modinfo
) < 0) {
128 error("can't get module information");
134 (void) printf("%s", count
? cheader
: header
);
137 print_cinfo(&modinfo
);
139 print_info(&modinfo
);
141 * If we're getting info about all modules, the next one
142 * we want is the one with an id greater than this one.
151 * Display loadcounts.
154 print_cinfo(struct modinfo
*mi
)
156 (void) printf("%3d %10d %-32s", mi
->mi_id
, mi
->mi_loadcnt
, mi
->mi_name
);
157 (void) printf(" %s/%s\n",
158 mi
->mi_state
& MI_LOADED
? "LOADED" : "UNLOADED",
159 mi
->mi_state
& MI_INSTALLED
? "INSTALLED" : "UNINSTALLED");
163 * Display info about a loaded module.
165 * The sparc kernel resides in its own address space, with modules
166 * loaded at low addresses. The low 32-bits of a module's base
167 * address is sufficient but does put a cap at 4gb here.
168 * The x86 64-bit kernel is loaded in high memory with the full
172 print_info(struct modinfo
*mi
)
177 for (n
= 0; n
< MODMAXLINK
; n
++) {
178 if (n
> 0 && mi
->mi_msinfo
[n
].msi_linkinfo
[0] == '\0')
181 (void) printf("%3d ", mi
->mi_id
);
182 #if defined(_LP64) && !defined(__sparcv9)
183 (void) printf("%16lx ", (uintptr_t)mi
->mi_base
);
185 (void) printf("%8lx ", (uintptr_t)mi
->mi_base
);
187 (void) printf("%8x ", (uintptr_t)mi
->mi_base
);
190 (void) printf("%6lx ", mi
->mi_size
);
192 (void) printf("%6x ", mi
->mi_size
);
195 p0
= mi
->mi_msinfo
[n
].msi_p0
;
198 (void) printf("%3d ", p0
);
200 (void) printf(" - ");
202 (void) printf(" %d ", mi
->mi_rev
);
204 mi
->mi_name
[MODMAXNAMELEN
- 1] = '\0';
205 mi
->mi_msinfo
[n
].msi_linkinfo
[MODMAXNAMELEN
- 1] = '\0';
208 (void) printf("%s (%s)\n", mi
->mi_name
,
209 mi
->mi_msinfo
[n
].msi_linkinfo
);
211 /* snprintf(3c) will always append a null character */
212 (void) snprintf(namebuf
, sizeof (namebuf
), "%s (%s)",
213 mi
->mi_name
, mi
->mi_msinfo
[n
].msi_linkinfo
);
214 #if defined(_LP64) && !defined(__sparcv9)
215 (void) printf("%.43s\n", namebuf
);
217 (void) printf("%.51s\n", namebuf
);
226 fatal("usage: modinfo [-w] [-c] [-i module-id]\n");