/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <inttypes.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
static int wide;
static int count = 0;
/*
* When printing module load addresses on 32-bit kernels, the 8 hex
* character field width is obviously adequate. On sparcv9 kernels
* solely by virtue of the choice of code model enabled by the separate
* kernel context, the text addresses are currently in the lower 4G
* address range, and so -still- fit in 8 hex characters.
*
* However, amd64 kernels live at the top of the 64-bit address space, and
* so as to be honest about the addresses (and since this is a tool for
* humans to parse), we have to print out a 16 hex character address.
*
* We assume that we will print out all 16 hex characters on future
* 64-bit kernel ports too.
*/
static const char header[] =
" Id "
" "
#endif
"Loadaddr Size Info Rev Module Name\n";
static char *cheader =
" Id Loadcnt Module Name State\n";
static void usage();
/*
* These functions are in modsubr.c
*/
/*
* Display information of all loaded modules
*/
int
{
int id;
int opt;
switch (opt) {
case 'i':
if (id == -1)
id = 0;
info_all = 0;
break;
case 'w':
wide++;
break;
case 'c':
count++;
break;
case '?':
default:
usage();
break;
}
}
/*
* Next id of -1 means we're getting info on all modules.
*/
if (count)
do {
/*
* Get module information.
* If modinfo.mi_nextid == -1, get info about the
* next installed module with id > "id."
* Otherwise, get info about the module with id == "id."
*/
if (!info_all)
error("can't get module information");
break;
}
if (first_mod) {
first_mod = 0;
}
if (count)
else
/*
* If we're getting info about all modules, the next one
* we want is the one with an id greater than this one.
*/
} while (info_all);
return (0);
}
/*
* Display loadcounts.
*/
static void
{
(void) printf(" %s/%s\n",
}
/*
* Display info about a loaded module.
*
* The sparc kernel resides in its own address space, with modules
* loaded at low addresses. The low 32-bits of a module's base
* address is sufficient but does put a cap at 4gb here.
* The x86 64-bit kernel is loaded in high memory with the full
* address provided.
*/
static void
{
int n, p0;
for (n = 0; n < MODMAXLINK; n++) {
break;
#else
#endif
#if defined(_LP64)
#else
#endif
if (p0 != -1)
else
(void) printf(" - ");
if (wide) {
} else {
/* snprintf(3c) will always append a null character */
#else
#endif
}
}
}
static void
usage()
{
fatal("usage: modinfo [-w] [-c] [-i module-id]\n");
}