summaryrefslogtreecommitdiff
path: root/modutils
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-01-23 04:48:34 +0000
committerEric Andersen <andersen@codepoet.org>2003-01-23 04:48:34 +0000
commit889dd20c6998c0cded684f5557748fc13a3b769e (patch)
treecc128ffae1d15623a9c81956fa854e3365247494 /modutils
parent8eb214edbd305a200a4665080a4a248e9ca8c5bb (diff)
downloadbusybox-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.in11
-rw-r--r--modutils/insmod.c176
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
43config 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
43config CONFIG_FEATURE_INSMOD_LOADINKMEM 54config 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
235static const int MODUTILS_MODULE_H = 1; 235static 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
456static const int MODUTILS_OBJ_H = 1; 456static 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 */
2659static 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
2658static int new_create_module_ksymtab(struct obj_file *f) 2689static 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 */
3578static int
3579get_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 */
3596static void
3597add_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
3541extern int insmod_main( int argc, char **argv) 3709extern 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