summaryrefslogtreecommitdiff
path: root/modutils
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-01-23 04:57:35 +0000
committerEric Andersen <andersen@codepoet.org>2003-01-23 04:57:35 +0000
commitbe65c350ae535f80ea369be5366e09f730ab7ba8 (patch)
tree2c4a28c0533945a6551c1d794e79ccb8f0a0505e /modutils
parent889dd20c6998c0cded684f5557748fc13a3b769e (diff)
downloadbusybox-w32-be65c350ae535f80ea369be5366e09f730ab7ba8.tar.gz
busybox-w32-be65c350ae535f80ea369be5366e09f730ab7ba8.tar.bz2
busybox-w32-be65c350ae535f80ea369be5366e09f730ab7ba8.zip
Patch from Artem Egorkine to support the -m option
Diffstat (limited to 'modutils')
-rw-r--r--modutils/Config.in21
-rw-r--r--modutils/insmod.c113
2 files changed, 132 insertions, 2 deletions
diff --git a/modutils/Config.in b/modutils/Config.in
index 98aef0032..c634e3938 100644
--- a/modutils/Config.in
+++ b/modutils/Config.in
@@ -58,6 +58,27 @@ config CONFIG_FEATURE_INSMOD_LOADINKMEM
58 help 58 help
59 Please submit a patch to add help text for this item. 59 Please submit a patch to add help text for this item.
60 60
61config CONFIG_FEATURE_INSMOD_LOAD_MAP
62 bool " Enable load map (-m) option"
63 default n
64 depends on CONFIG_INSMOD
65 help
66 Enabling this, one would be able to get a load map
67 output on stdout. This makes kernel module debugging
68 easier.
69 If you don't plan to debug kernel modules, you
70 don't need this option.
71
72config CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL
73 bool " Symbols in load map"
74 default y
75 depends on CONFIG_FEATURE_INSMOD_LOAD_MAP
76 help
77 Without this option, -m will only output section
78 load map.
79 With this option, -m will also output symbols
80 load map.
81
61config CONFIG_LSMOD 82config CONFIG_LSMOD
62 bool "lsmod" 83 bool "lsmod"
63 default n 84 default n
diff --git a/modutils/insmod.c b/modutils/insmod.c
index db9e1997e..af12f36a6 100644
--- a/modutils/insmod.c
+++ b/modutils/insmod.c
@@ -234,7 +234,7 @@
234#ifndef MODUTILS_MODULE_H 234#ifndef MODUTILS_MODULE_H
235static const int MODUTILS_MODULE_H = 1; 235static const int MODUTILS_MODULE_H = 1;
236 236
237#ident "$Id: insmod.c,v 1.93 2003/01/23 04:48:34 andersen Exp $" 237#ident "$Id: insmod.c,v 1.94 2003/01/23 04:57:35 andersen Exp $"
238 238
239/* This file contains the structures used by the 2.0 and 2.1 kernels. 239/* This file contains the structures used by the 2.0 and 2.1 kernels.
240 We do not use the kernel headers directly because we do not wish 240 We do not use the kernel headers directly because we do not wish
@@ -455,7 +455,7 @@ int delete_module(const char *);
455#ifndef MODUTILS_OBJ_H 455#ifndef MODUTILS_OBJ_H
456static const int MODUTILS_OBJ_H = 1; 456static const int MODUTILS_OBJ_H = 1;
457 457
458#ident "$Id: insmod.c,v 1.93 2003/01/23 04:48:34 andersen Exp $" 458#ident "$Id: insmod.c,v 1.94 2003/01/23 04:57:35 andersen Exp $"
459 459
460/* The relocatable object is manipulated using elfin types. */ 460/* The relocatable object is manipulated using elfin types. */
461 461
@@ -3706,6 +3706,98 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename,
3706} 3706}
3707#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ 3707#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
3708 3708
3709#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3710static void print_load_map(struct obj_file *f)
3711{
3712 struct obj_symbol *sym;
3713 struct obj_symbol **all, **p;
3714 struct obj_section *sec;
3715 int i, nsyms, *loaded;
3716
3717 /* Report on the section layout. */
3718
3719 printf("Sections: Size %-*s Align\n",
3720 (int) (2 * sizeof(void *)), "Address");
3721
3722 for (sec = f->load_order; sec; sec = sec->load_next) {
3723 int a;
3724 unsigned long tmp;
3725
3726 for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a)
3727 tmp >>= 1;
3728 if (a == -1)
3729 a = 0;
3730
3731 printf("%-15s %08lx %0*lx 2**%d\n",
3732 sec->name,
3733 (long)sec->header.sh_size,
3734 (int) (2 * sizeof(void *)),
3735 (long)sec->header.sh_addr,
3736 a);
3737 }
3738#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL
3739 /* Quick reference which section indicies are loaded. */
3740
3741 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
3742 while (--i >= 0)
3743 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
3744
3745 /* Collect the symbols we'll be listing. */
3746
3747 for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
3748 for (sym = f->symtab[i]; sym; sym = sym->next)
3749 if (sym->secidx <= SHN_HIRESERVE
3750 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3751 ++nsyms;
3752
3753 all = alloca(nsyms * sizeof(struct obj_symbol *));
3754
3755 for (i = 0, p = all; i < HASH_BUCKETS; ++i)
3756 for (sym = f->symtab[i]; sym; sym = sym->next)
3757 if (sym->secidx <= SHN_HIRESERVE
3758 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3759 *p++ = sym;
3760
3761 /* And list them. */
3762 printf("\nSymbols:\n");
3763 for (p = all; p < all + nsyms; ++p) {
3764 char type = '?';
3765 unsigned long value;
3766
3767 sym = *p;
3768 if (sym->secidx == SHN_ABS) {
3769 type = 'A';
3770 value = sym->value;
3771 } else if (sym->secidx == SHN_UNDEF) {
3772 type = 'U';
3773 value = 0;
3774 } else {
3775 sec = f->sections[sym->secidx];
3776
3777 if (sec->header.sh_type == SHT_NOBITS)
3778 type = 'B';
3779 else if (sec->header.sh_flags & SHF_ALLOC) {
3780 if (sec->header.sh_flags & SHF_EXECINSTR)
3781 type = 'T';
3782 else if (sec->header.sh_flags & SHF_WRITE)
3783 type = 'D';
3784 else
3785 type = 'R';
3786 }
3787 value = sym->value + sec->header.sh_addr;
3788 }
3789
3790 if (ELFW(ST_BIND) (sym->info) == STB_LOCAL)
3791 type = tolower(type);
3792
3793 printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value,
3794 type, sym->name);
3795 }
3796#endif
3797}
3798
3799#endif
3800
3709extern int insmod_main( int argc, char **argv) 3801extern int insmod_main( int argc, char **argv)
3710{ 3802{
3711 int opt; 3803 int opt;
@@ -3731,9 +3823,16 @@ extern int insmod_main( int argc, char **argv)
3731#else 3823#else
3732 FILE *fp; 3824 FILE *fp;
3733#endif 3825#endif
3826#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3827 int flag_print_load_map = 0;
3828#endif
3734 3829
3735 /* Parse any options */ 3830 /* Parse any options */
3831#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3832 while ((opt = getopt(argc, argv, "fkqsvxmLo:")) > 0) {
3833#else
3736 while ((opt = getopt(argc, argv, "fkqsvxLo:")) > 0) { 3834 while ((opt = getopt(argc, argv, "fkqsvxLo:")) > 0) {
3835#endif
3737 switch (opt) { 3836 switch (opt) {
3738 case 'f': /* force loading */ 3837 case 'f': /* force loading */
3739 flag_force_load = 1; 3838 flag_force_load = 1;
@@ -3766,6 +3865,11 @@ extern int insmod_main( int argc, char **argv)
3766 * that. So be careful and plan your life around not 3865 * that. So be careful and plan your life around not
3767 * loading the same module 50 times concurrently. */ 3866 * loading the same module 50 times concurrently. */
3768 break; 3867 break;
3868#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3869 case 'm': /* print module load map */
3870 flag_print_load_map = 1;
3871 break;
3872#endif
3769 default: 3873 default:
3770 show_usage(); 3874 show_usage();
3771 } 3875 }
@@ -4005,6 +4109,11 @@ extern int insmod_main( int argc, char **argv)
4005 goto out; 4109 goto out;
4006 } 4110 }
4007 4111
4112#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
4113 if(flag_print_load_map)
4114 print_load_map(f);
4115#endif
4116
4008 exit_status = EXIT_SUCCESS; 4117 exit_status = EXIT_SUCCESS;
4009 4118
4010out: 4119out: