使用EXPORT_SYMBOL声明函数后,加载到系统中内核符号集却没有该符号

参考问题:what is __ksymtab? in linux kernel

1. 使用cat /proc/kallsyms 看到的符号集输出表,类似于nm工具输出的样式, output of nm utility, 也可以参考 this page.

简单来说,'T'通常表明全局的(非静态但不需要输出的)函数,‘t'编译单元的本地函数(例如:static),'D'全局数据,’d‘编译单元的本地数据。’R‘和’r‘ 与 ’D'/‘d'一样,是只读数据。

2. 下面是导出符号所需的特殊部分的项,以便内核模块可以使用这些符号。对于每个导出的符号,至少以下内容由EXPORT_SYMBOL()定义:

  • __kstrtab_  - 符号的名称为字符串
  • __ksymtab_ - 包含符号信息的结构:它的地址和 __kstrtab_ 的地址,等等。
  • __kcrctab_ - 用来表示符号的控制和(CRC)的地址。例如,检查内核或模块是否提供了与给定内核模块所需完全相同的符号。如果模块需要具有给定名称和CRC的符号,而内核提供具有该名称但具有不同CRC的符号(例如:如果模块是为不同的内核版本编译的),模块加载器将拒绝加载内核模块(除非禁用此检查)。

详细了解 linux/export.h 中EXPORT_SYMBOL()宏的实现。

3. 不确定,但是到目前为止,我还没有遇到过内核编译正确的情况下,并且完全启用了kallsyms时(CONFIG_KALLSYMS=y, CONFIG_KALLSYMS_ALL=y),function ("text symbol")或variable ("data symbol") 出现在System.map中,但没有出现在/proc/kallsyms中的情况.如果CONFIG_KALLSYMS_ALL=n,只有函数(确切的说来自*.text 部分的符号)会出现在/proc/kallsyms.

4. 取决于你的内核版本。你可以查看一下EXPORT_SYMBOL()的定义,和在你的内核中找到__ksymtab_变量的类型。在内核3.11中是定义在linux/export.h中的struct kernel_symbol。有那个结构的定义和它的地址,我认为你就可以得到所要符号的地址了struct kernel_symbol::value,尽管我自己没有去实践。

注意,符号__ksymtab_nf_hook 是对应于 nf_hook 而不是 nf_hooks. 名称必须匹配. nf_hooks 和 nf_hook 是不同的实体.

5. 没有看到和/proc/kallsyms相关的部分很难说清楚,或许它是在#ifdef'd之外而没有编译,也或许是其他可能。

此外,nf_hooks是数据项,因此如果CONFIG_KALLSYMS_ALL 是 'n'它不会出现在 /proc/kallsyms中。

你可能感兴趣的:(Linux)