Patch from Artem Egorkine to support the -m option
This commit was genuinely broken at the time (not related to our build system): sysdeps/linux/Config.in "fileutils/Config.in" dosyasini kaynak gosteriyor ama bu dosya repoda hic var olmadi (2002-12-05 - 2003-02-15 arasi orijinal yazar hatasi, 3238ea167 ile duzeltildi)
No binary (build failed)
—
(log yok)
| @@ -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 }" | |
| @@ -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 | |
| @@ -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: | |