Patch from Artem Egorkine to support the -m option

This commit is contained in:
Eric Andersen 2003-01-23 04:57:35 +00:00
parent 889dd20c69
commit be65c350ae
3 changed files with 139 additions and 3 deletions

View File

@ -1032,6 +1032,11 @@
" ::shutdown:/bin/umount -a -r\n" \
" ::shutdown:/sbin/swapoff -a\n"
#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
#define USAGE_INSMOD_MAP(a) a
#else
#define USAGE_INSMOD_MAP(a)
#endif
#define insmod_trivial_usage \
"[OPTION]... MODULE [symbol=value]..."
#define insmod_full_usage \
@ -1041,7 +1046,8 @@
"\t-k\tMake module autoclean-able.\n" \
"\t-v\tverbose output\n" \
"\t-L\tLock to prevent simultaneous loads of a module\n" \
"\t-x\tdo not export externs"
USAGE_INSMOD_MAP("\t-m\tOutput load map to stdout") \
"\t-x\tdo not export externs\n"
#define ip_trivial_usage \
"[ OPTIONS ] { address | link | route | tunnel } { COMMAND | help }"

View File

@ -58,6 +58,27 @@ config CONFIG_FEATURE_INSMOD_LOADINKMEM
help
Please submit a patch to add help text for this item.
config CONFIG_FEATURE_INSMOD_LOAD_MAP
bool " Enable load map (-m) option"
default n
depends on CONFIG_INSMOD
help
Enabling this, one would be able to get a load map
output on stdout. This makes kernel module debugging
easier.
If you don't plan to debug kernel modules, you
don't need this option.
config CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL
bool " Symbols in load map"
default y
depends on CONFIG_FEATURE_INSMOD_LOAD_MAP
help
Without this option, -m will only output section
load map.
With this option, -m will also output symbols
load map.
config CONFIG_LSMOD
bool "lsmod"
default n

View File

@ -234,7 +234,7 @@
#ifndef MODUTILS_MODULE_H
static const int MODUTILS_MODULE_H = 1;
#ident "$Id: insmod.c,v 1.93 2003/01/23 04:48:34 andersen Exp $"
#ident "$Id: insmod.c,v 1.94 2003/01/23 04:57:35 andersen Exp $"
/* This file contains the structures used by the 2.0 and 2.1 kernels.
We do not use the kernel headers directly because we do not wish
@ -455,7 +455,7 @@ int delete_module(const char *);
#ifndef MODUTILS_OBJ_H
static const int MODUTILS_OBJ_H = 1;
#ident "$Id: insmod.c,v 1.93 2003/01/23 04:48:34 andersen Exp $"
#ident "$Id: insmod.c,v 1.94 2003/01/23 04:57:35 andersen Exp $"
/* The relocatable object is manipulated using elfin types. */
@ -3706,6 +3706,98 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename,
}
#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
static void print_load_map(struct obj_file *f)
{
struct obj_symbol *sym;
struct obj_symbol **all, **p;
struct obj_section *sec;
int i, nsyms, *loaded;
/* Report on the section layout. */
printf("Sections: Size %-*s Align\n",
(int) (2 * sizeof(void *)), "Address");
for (sec = f->load_order; sec; sec = sec->load_next) {
int a;
unsigned long tmp;
for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a)
tmp >>= 1;
if (a == -1)
a = 0;
printf("%-15s %08lx %0*lx 2**%d\n",
sec->name,
(long)sec->header.sh_size,
(int) (2 * sizeof(void *)),
(long)sec->header.sh_addr,
a);
}
#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL
/* Quick reference which section indicies are loaded. */
loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
while (--i >= 0)
loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
/* Collect the symbols we'll be listing. */
for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
for (sym = f->symtab[i]; sym; sym = sym->next)
if (sym->secidx <= SHN_HIRESERVE
&& (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
++nsyms;
all = alloca(nsyms * sizeof(struct obj_symbol *));
for (i = 0, p = all; i < HASH_BUCKETS; ++i)
for (sym = f->symtab[i]; sym; sym = sym->next)
if (sym->secidx <= SHN_HIRESERVE
&& (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
*p++ = sym;
/* And list them. */
printf("\nSymbols:\n");
for (p = all; p < all + nsyms; ++p) {
char type = '?';
unsigned long value;
sym = *p;
if (sym->secidx == SHN_ABS) {
type = 'A';
value = sym->value;
} else if (sym->secidx == SHN_UNDEF) {
type = 'U';
value = 0;
} else {
sec = f->sections[sym->secidx];
if (sec->header.sh_type == SHT_NOBITS)
type = 'B';
else if (sec->header.sh_flags & SHF_ALLOC) {
if (sec->header.sh_flags & SHF_EXECINSTR)
type = 'T';
else if (sec->header.sh_flags & SHF_WRITE)
type = 'D';
else
type = 'R';
}
value = sym->value + sec->header.sh_addr;
}
if (ELFW(ST_BIND) (sym->info) == STB_LOCAL)
type = tolower(type);
printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value,
type, sym->name);
}
#endif
}
#endif
extern int insmod_main( int argc, char **argv)
{
int opt;
@ -3731,9 +3823,16 @@ extern int insmod_main( int argc, char **argv)
#else
FILE *fp;
#endif
#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
int flag_print_load_map = 0;
#endif
/* Parse any options */
#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
while ((opt = getopt(argc, argv, "fkqsvxmLo:")) > 0) {
#else
while ((opt = getopt(argc, argv, "fkqsvxLo:")) > 0) {
#endif
switch (opt) {
case 'f': /* force loading */
flag_force_load = 1;
@ -3766,6 +3865,11 @@ extern int insmod_main( int argc, char **argv)
* that. So be careful and plan your life around not
* loading the same module 50 times concurrently. */
break;
#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
case 'm': /* print module load map */
flag_print_load_map = 1;
break;
#endif
default:
show_usage();
}
@ -4005,6 +4109,11 @@ extern int insmod_main( int argc, char **argv)
goto out;
}
#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
if(flag_print_load_map)
print_load_map(f);
#endif
exit_status = EXIT_SUCCESS;
out: