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: |
