跟踪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)的时候,生成了如下的代码:

<pre name="code" class="cpp">static const char__kstrtab_fuck = "fuck"; //按照__attribute__((section("__ksymtab_strings"), aligned(1)))的限制, __kstrtab_fuck放在<pre name="code" class="cpp"><pre name="code" class="cpp">//__ksymtab_strings section中

 
 
<pre name="code" class="cpp">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的执行效率

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值