跟踪EXPORT_SYMBOL

来源:互联网 发布:学弹钢琴软件 编辑:程序博客网 时间:2024/05/16 17:41

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
原创粉丝点击