diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-01-23 04:57:35 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-01-23 04:57:35 +0000 |
commit | be65c350ae535f80ea369be5366e09f730ab7ba8 (patch) | |
tree | 2c4a28c0533945a6551c1d794e79ccb8f0a0505e /modutils | |
parent | 889dd20c6998c0cded684f5557748fc13a3b769e (diff) | |
download | busybox-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.in | 21 | ||||
-rw-r--r-- | modutils/insmod.c | 113 |
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 | ||
61 | config 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 | |||
72 | config 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 | |||
61 | config CONFIG_LSMOD | 82 | config 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 |
235 | static const int MODUTILS_MODULE_H = 1; | 235 | static 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 |
456 | static const int MODUTILS_OBJ_H = 1; | 456 | static 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 | ||
3710 | static 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 | |||
3709 | extern int insmod_main( int argc, char **argv) | 3801 | extern 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 | ||
4010 | out: | 4119 | out: |