跟踪EXPORT_SYMBOL

1. EXPORT_SYMBOL的定义

/* For every exported symbol, place a struct in the __ksymtab section */
#define __EXPORT_SYMBOL(sym, sec)				\
	extern typeof(sym) sym;					\
	__CRC_SYMBOL(sym, sec)					\
	static const char __kstrtab_##sym[]			\
	__attribute__((section("__ksymtab_strings"), aligned(1))) \
	= MODULE_SYMBOL_PREFIX #sym;                    	\
	static const struct kernel_symbol __ksymtab_##sym	\
	__used							\
	__attribute__((section("___ksymtab" sec "+" #sym), unused))	\
	= { (unsigned long)&sym, __kstrtab_##sym }

#define EXPORT_SYMBOL(sym)					\
	__EXPORT_SYMBOL(sym, "")

#define EXPORT_SYMBOL_GPL(sym)					\
	__EXPORT_SYMBOL(sym, "_gpl")

#define EXPORT_SYMBOL_GPL_FUTURE(sym)				\
	__EXPORT_SYMBOL(sym, "_gpl_future")

So, 当你EXPORT_SYMBOL(fuck)的时候,生成了如下的代码:

static const char__kstrtab_fuck = "fuck"; //按照__attribute__((section("__ksymtab_strings"), aligned(1)))的限制, __kstrtab_fuck放在
//__ksymtab_strings section中


static const struct kernel_symbol__ksymtab_fuck = {&fuck, __kstrtab_fuck};
//按照__attribute__((section("___ksymtab" sec "+" #sym),unused))的限制,应该放在___ksymtab+fuck section中



2. *.ko是个ELF的文件, 使用readelf 查看编译出来的结果, __ksymtab_strings是存在的,可是说好的fuck section呢?肯定是被放在__ksytab中,怎么link进去的呢?

  [ 8] __ksymtab         PROGBITS        00000024 00385c 000010 00   A  0   0  4
  [ 9] .rel__ksymtab     REL             00000000 04bd70 000020 08     42   8  4
  [10] __ksymtab_gpl     PROGBITS        00000034 00386c 000098 00   A  0   0  4
  [11] .rel__ksymtab_gpl REL             00000000 04bd90 000130 08     42  10  4
  [12] .rodata           PROGBITS        00000000 003904 000462 00   A  0   0  4
  [13] .rel.rodata       REL             00000000 04bec0 0000d0 08     42  12  4
  [14] .modinfo          PROGBITS        00000000 003d66 0000e9 00   A  0   0  1
  [15] .rodata.str1.1    PROGBITS        00000000 003e4f 000c37 01 AMS  0   0  1
  [16] __ksymtab_strings PROGBITS        00000000 004a86 000230 00   A  0   0  1

3. 原来是ld根据linker script来工作的,我的项目的script: kernel/linux-3.0.35/dist/scripts/module-common.lds

/*
 * Common module linker script, always used when linking a module.
 * Archs are free to supply their own linker scripts.  ld will
 * combine them automatically.
 */
SECTIONS {
	/DISCARD/ : { *(.discard) }

	__ksymtab		: { *(SORT(___ksymtab+*)) }
	__ksymtab_gpl		: { *(SORT(___ksymtab_gpl+*)) }
	__ksymtab_unused	: { *(SORT(___ksymtab_unused+*)) }
	__ksymtab_unused_gpl	: { *(SORT(___ksymtab_unused_gpl+*)) }
	__ksymtab_gpl_future	: { *(SORT(___ksymtab_gpl_future+*)) }
	__kcrctab		: { *(SORT(___kcrctab+*)) }
	__kcrctab_gpl		: { *(SORT(___kcrctab_gpl+*)) }
	__kcrctab_unused	: { *(SORT(___kcrctab_unused+*)) }
	__kcrctab_unused_gpl	: { *(SORT(___kcrctab_unused_gpl+*)) }
	__kcrctab_gpl_future	: { *(SORT(___kcrctab_gpl_future+*)) }

4. 在insmod的时候,find_module_sections就可以查找到__ksymtab

5. 为什么要

__attribute__((section("___ksymtab" sec "+" #sym), unused))
而不是直接

__attribute__((section("___ksymtab"), unused))

搜索了下,是为了提高ld的执行效率

你可能感兴趣的:(Android,BSP)