diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-01-23 04:48:34 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-01-23 04:48:34 +0000 |
commit | 889dd20c6998c0cded684f5557748fc13a3b769e (patch) | |
tree | cc128ffae1d15623a9c81956fa854e3365247494 /modutils | |
parent | 8eb214edbd305a200a4665080a4a248e9ca8c5bb (diff) | |
download | busybox-w32-889dd20c6998c0cded684f5557748fc13a3b769e.tar.gz busybox-w32-889dd20c6998c0cded684f5557748fc13a3b769e.tar.bz2 busybox-w32-889dd20c6998c0cded684f5557748fc13a3b769e.zip |
Patch from Joel Vallier to add modules symbols to the kernel symbol
table in order to obtain better debug output from ksymoops.
Diffstat (limited to 'modutils')
-rw-r--r-- | modutils/Config.in | 11 | ||||
-rw-r--r-- | modutils/insmod.c | 176 |
2 files changed, 185 insertions, 2 deletions
diff --git a/modutils/Config.in b/modutils/Config.in index 9af0ad6dc..98aef0032 100644 --- a/modutils/Config.in +++ b/modutils/Config.in | |||
@@ -40,6 +40,17 @@ config CONFIG_FEATURE_INSMOD_VERSION_CHECKING | |||
40 | help | 40 | help |
41 | Please submit a patch to add help text for this item. | 41 | Please submit a patch to add help text for this item. |
42 | 42 | ||
43 | config CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS | ||
44 | bool " Add module symbols to kernel symbol table" | ||
45 | default n | ||
46 | depends on CONFIG_INSMOD | ||
47 | help | ||
48 | By adding module symbols to the kernel symbol table, Oops messages | ||
49 | occuring within kernel modules can be properly debugged. By enabling | ||
50 | this feature, module symbols will always be added to the kernel symbol | ||
51 | table for properly debugging support. If you are not interested in | ||
52 | Oops messages from kernel modules, say N. | ||
53 | |||
43 | config CONFIG_FEATURE_INSMOD_LOADINKMEM | 54 | config CONFIG_FEATURE_INSMOD_LOADINKMEM |
44 | bool " In kernel memory optimization (uClinux only)" | 55 | bool " In kernel memory optimization (uClinux only)" |
45 | default n | 56 | default n |
diff --git a/modutils/insmod.c b/modutils/insmod.c index eda4e1a48..db9e1997e 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.92 2002/11/28 11:27:27 aaronl Exp $" | 237 | #ident "$Id: insmod.c,v 1.93 2003/01/23 04:48:34 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.92 2002/11/28 11:27:27 aaronl Exp $" | 458 | #ident "$Id: insmod.c,v 1.93 2003/01/23 04:48:34 andersen Exp $" |
459 | 459 | ||
460 | /* The relocatable object is manipulated using elfin types. */ | 460 | /* The relocatable object is manipulated using elfin types. */ |
461 | 461 | ||
@@ -2654,6 +2654,37 @@ static int new_create_this_module(struct obj_file *f, const char *m_name) | |||
2654 | return 1; | 2654 | return 1; |
2655 | } | 2655 | } |
2656 | 2656 | ||
2657 | #ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS | ||
2658 | /* add an entry to the __ksymtab section, creating it if necessary */ | ||
2659 | static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym) | ||
2660 | { | ||
2661 | struct obj_section *sec; | ||
2662 | ElfW(Addr) ofs; | ||
2663 | |||
2664 | /* ensure __ksymtab is allocated, EXPORT_NOSYMBOLS creates a non-alloc section. | ||
2665 | * If __ksymtab is defined but not marked alloc, x out the first character | ||
2666 | * (no obj_delete routine) and create a new __ksymtab with the correct | ||
2667 | * characteristics. | ||
2668 | */ | ||
2669 | sec = obj_find_section(f, "__ksymtab"); | ||
2670 | if (sec && !(sec->header.sh_flags & SHF_ALLOC)) { | ||
2671 | *((char *)(sec->name)) = 'x'; /* override const */ | ||
2672 | sec = NULL; | ||
2673 | } | ||
2674 | if (!sec) | ||
2675 | sec = obj_create_alloced_section(f, "__ksymtab", | ||
2676 | tgt_sizeof_void_p, 0); | ||
2677 | if (!sec) | ||
2678 | return; | ||
2679 | sec->header.sh_flags |= SHF_ALLOC; | ||
2680 | sec->header.sh_addralign = tgt_sizeof_void_p; /* Empty section might | ||
2681 | be byte-aligned */ | ||
2682 | ofs = sec->header.sh_size; | ||
2683 | obj_symbol_patch(f, sec->idx, ofs, sym); | ||
2684 | obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name); | ||
2685 | obj_extend_section(sec, 2 * tgt_sizeof_char_p); | ||
2686 | } | ||
2687 | #endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ | ||
2657 | 2688 | ||
2658 | static int new_create_module_ksymtab(struct obj_file *f) | 2689 | static int new_create_module_ksymtab(struct obj_file *f) |
2659 | { | 2690 | { |
@@ -2811,6 +2842,7 @@ new_init_module(const char *m_name, struct obj_file *f, | |||
2811 | 2842 | ||
2812 | #define new_init_module(x, y, z) TRUE | 2843 | #define new_init_module(x, y, z) TRUE |
2813 | #define new_create_this_module(x, y) 0 | 2844 | #define new_create_this_module(x, y) 0 |
2845 | #define new_add_ksymtab(x, y) -1 | ||
2814 | #define new_create_module_ksymtab(x) | 2846 | #define new_create_module_ksymtab(x) |
2815 | #define query_module(v, w, x, y, z) -1 | 2847 | #define query_module(v, w, x, y, z) -1 |
2816 | 2848 | ||
@@ -3538,6 +3570,142 @@ static void check_tainted_module(struct obj_file *f, char *m_name) | |||
3538 | #define check_tainted_module(x, y) do { } while(0); | 3570 | #define check_tainted_module(x, y) do { } while(0); |
3539 | #endif /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */ | 3571 | #endif /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */ |
3540 | 3572 | ||
3573 | #ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS | ||
3574 | /* add module source, timestamp, kernel version and a symbol for the | ||
3575 | * start of some sections. this info is used by ksymoops to do better | ||
3576 | * debugging. | ||
3577 | */ | ||
3578 | static int | ||
3579 | get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) | ||
3580 | { | ||
3581 | #ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING | ||
3582 | if (get_modinfo_value(f, "kernel_version") == NULL) | ||
3583 | return old_get_module_version(f, str); | ||
3584 | else | ||
3585 | return new_get_module_version(f, str); | ||
3586 | #else /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ | ||
3587 | strncpy(str, "???", sizeof(str)); | ||
3588 | return -1; | ||
3589 | #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ | ||
3590 | } | ||
3591 | |||
3592 | /* add module source, timestamp, kernel version and a symbol for the | ||
3593 | * start of some sections. this info is used by ksymoops to do better | ||
3594 | * debugging. | ||
3595 | */ | ||
3596 | static void | ||
3597 | add_ksymoops_symbols(struct obj_file *f, const char *filename, | ||
3598 | const char *m_name) | ||
3599 | { | ||
3600 | static const char symprefix[] = "__insmod_"; | ||
3601 | struct obj_section *sec; | ||
3602 | struct obj_symbol *sym; | ||
3603 | char *name, *absolute_filename; | ||
3604 | char str[STRVERSIONLEN], real[PATH_MAX]; | ||
3605 | int i, l, lm_name, lfilename, use_ksymtab, version; | ||
3606 | struct stat statbuf; | ||
3607 | |||
3608 | static const char *section_names[] = { | ||
3609 | ".text", | ||
3610 | ".rodata", | ||
3611 | ".data", | ||
3612 | ".bss" | ||
3613 | ".sbss" | ||
3614 | }; | ||
3615 | |||
3616 | if (realpath(filename, real)) { | ||
3617 | absolute_filename = xstrdup(real); | ||
3618 | } | ||
3619 | else { | ||
3620 | int save_errno = errno; | ||
3621 | error_msg("cannot get realpath for %s", filename); | ||
3622 | errno = save_errno; | ||
3623 | perror(""); | ||
3624 | absolute_filename = xstrdup(filename); | ||
3625 | } | ||
3626 | |||
3627 | lm_name = strlen(m_name); | ||
3628 | lfilename = strlen(absolute_filename); | ||
3629 | |||
3630 | /* add to ksymtab if it already exists or there is no ksymtab and other symbols | ||
3631 | * are not to be exported. otherwise leave ksymtab alone for now, the | ||
3632 | * "export all symbols" compatibility code will export these symbols later. | ||
3633 | */ | ||
3634 | use_ksymtab = obj_find_section(f, "__ksymtab") || !flag_export; | ||
3635 | |||
3636 | if ((sec = obj_find_section(f, ".this"))) { | ||
3637 | /* tag the module header with the object name, last modified | ||
3638 | * timestamp and module version. worst case for module version | ||
3639 | * is 0xffffff, decimal 16777215. putting all three fields in | ||
3640 | * one symbol is less readable but saves kernel space. | ||
3641 | */ | ||
3642 | l = sizeof(symprefix)+ /* "__insmod_" */ | ||
3643 | lm_name+ /* module name */ | ||
3644 | 2+ /* "_O" */ | ||
3645 | lfilename+ /* object filename */ | ||
3646 | 2+ /* "_M" */ | ||
3647 | 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */ | ||
3648 | 2+ /* "_V" */ | ||
3649 | 8+ /* version in dec */ | ||
3650 | 1; /* nul */ | ||
3651 | name = xmalloc(l); | ||
3652 | if (stat(absolute_filename, &statbuf) != 0) | ||
3653 | statbuf.st_mtime = 0; | ||
3654 | version = get_module_version(f, str); /* -1 if not found */ | ||
3655 | snprintf(name, l, "%s%s_O%s_M%0*lX_V%d", | ||
3656 | symprefix, m_name, absolute_filename, | ||
3657 | (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime, | ||
3658 | version); | ||
3659 | sym = obj_add_symbol(f, name, -1, | ||
3660 | ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), | ||
3661 | sec->idx, sec->header.sh_addr, 0); | ||
3662 | if (use_ksymtab) | ||
3663 | new_add_ksymtab(f, sym); | ||
3664 | } | ||
3665 | free(absolute_filename); | ||
3666 | #ifdef _NOT_SUPPORTED_ | ||
3667 | /* record where the persistent data is going, same address as previous symbol */ | ||
3668 | |||
3669 | if (f->persist) { | ||
3670 | l = sizeof(symprefix)+ /* "__insmod_" */ | ||
3671 | lm_name+ /* module name */ | ||
3672 | 2+ /* "_P" */ | ||
3673 | strlen(f->persist)+ /* data store */ | ||
3674 | 1; /* nul */ | ||
3675 | name = xmalloc(l); | ||
3676 | snprintf(name, l, "%s%s_P%s", | ||
3677 | symprefix, m_name, f->persist); | ||
3678 | sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), | ||
3679 | sec->idx, sec->header.sh_addr, 0); | ||
3680 | if (use_ksymtab) | ||
3681 | new_add_ksymtab(f, sym); | ||
3682 | } | ||
3683 | #endif /* _NOT_SUPPORTED_ */ | ||
3684 | /* tag the desired sections if size is non-zero */ | ||
3685 | |||
3686 | for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); ++i) { | ||
3687 | if ((sec = obj_find_section(f, section_names[i])) && | ||
3688 | sec->header.sh_size) { | ||
3689 | l = sizeof(symprefix)+ /* "__insmod_" */ | ||
3690 | lm_name+ /* module name */ | ||
3691 | 2+ /* "_S" */ | ||
3692 | strlen(sec->name)+ /* section name */ | ||
3693 | 2+ /* "_L" */ | ||
3694 | 8+ /* length in dec */ | ||
3695 | 1; /* nul */ | ||
3696 | name = xmalloc(l); | ||
3697 | snprintf(name, l, "%s%s_S%s_L%ld", | ||
3698 | symprefix, m_name, sec->name, | ||
3699 | (long)sec->header.sh_size); | ||
3700 | sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), | ||
3701 | sec->idx, sec->header.sh_addr, 0); | ||
3702 | if (use_ksymtab) | ||
3703 | new_add_ksymtab(f, sym); | ||
3704 | } | ||
3705 | } | ||
3706 | } | ||
3707 | #endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ | ||
3708 | |||
3541 | extern int insmod_main( int argc, char **argv) | 3709 | extern int insmod_main( int argc, char **argv) |
3542 | { | 3710 | { |
3543 | int opt; | 3711 | int opt; |
@@ -3788,6 +3956,10 @@ extern int insmod_main( int argc, char **argv) | |||
3788 | arch_create_got(f); | 3956 | arch_create_got(f); |
3789 | hide_special_symbols(f); | 3957 | hide_special_symbols(f); |
3790 | 3958 | ||
3959 | #ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS | ||
3960 | add_ksymoops_symbols(f, m_filename, m_name); | ||
3961 | #endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ | ||
3962 | |||
3791 | if (k_new_syscalls) | 3963 | if (k_new_syscalls) |
3792 | new_create_module_ksymtab(f); | 3964 | new_create_module_ksymtab(f); |
3793 | 3965 | ||