6

当我们 cat 'proc/kallsyms' 或 'system.map' 我们得到这样的符号

....
c033718c T nf_hook_slow
c04ca284 r __ksymtab_nf_hook_slow
c04ca28c r __ksymtab_nf_hooks
c04d24a0 r __kcrctab_nf_hook_slow
c04d24a4 r __kcrctab_nf_hooks
c04e9122 r __kstrtab_nf_hook_slow
c04e9179 r __kstrtab_nf_hooks
c054d854 D nf_hooks
c0571ca0 d nf_hook_mutex
....
  1. T, r, D, d 的东西是什么意思?
  2. 我可以在内核源代码中找到 EXPORT_SYMBOL(...) 的符号,但还有其他前缀为 __ksymtab... 或 __kstrtab... 这些是什么?
  3. System.map 中是否有符号但 /proc/kallsyms 中排除了符号?(假设内核编译正确)
  4. 我启用了 netfilter 的 linux 内核,但我找不到符号“nf_hooks”,但有“__ksymtab_nf_hook”。有没有办法使用 __ksymtab_nf_hook 获取 nf_hooks 的地址?
  5. 我在我的 linux 源代码中看到 EXPORT_SYMBOL(nf_hook) 但如果我“cat /proc/kallsyms”就找不到它。这有什么典型的原因吗?

先感谢您。

4

1 回答 1

8
  1. 该格式类似于nm 实用程序的输出格式,另请参阅此页面

    简单来说,'T' 通常表示全局(非静态但不一定导出)函数,'t' - 编译单元本地的函数(即静态),'D' - 全局数据,'d' -编译单元的本地数据。'R' 和 'r' - 与 'D'/'d' 相同,但用于只读数据。

  2. 这些是导出符号所需的特殊部分中的项目,以便内核模块可以使用这些符号。

    对于每个导出的符号,至少以下内容由 定义EXPORT_SYMBOL()

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

    详情请查看linux/export.hEXPORT_SYMBOL()中宏的实现。

  3. 不确定,但到目前为止,我还没有遇到过 System.map 中存在函数(“文本符号”)或变量(“数据符号”)但如果内核编译正确且未显示在 /proc/kallsyms 中的情况,并且完全启用 kallsyms (CONFIG_KALLSYMS=y, CONFIG_KALLSYMS_ALL=y)。如果 CONFIG_KALLSYMS_ALL=n,则只有函数(准确地说,来自 *.text 部分的符号)将显示在 /proc/kallsyms 中。

  4. 取决于你的内核版本。您可以查看EXPORT_SYMBOL()内核的定义并找到哪些类型__ksymtab_<symbol_name>变量。在内核 3.11 中,它struct kernel_symbol定义在linux/export.h中。我想,有了该结构及其地址的定义,您就可以获得符号的地址:struct kernel_symbol::value。虽然我自己没有尝试过。

    但是请注意,这__ksymtab_nf_hook是针对nf_hook而不是针对nf_hooks。名称必须匹配。nf_hooks并且nf_hook是不同的实体。

  5. 如果没有看到 /proc/kallsyms 的代码和相关部分,很难说清楚。也许它是#ifdef'ed并且根本没有编译,可能还有别的东西。

    此外,nf_hooks是一个数据项,因此如果 CONFIG_KALLSYMS_ALL 为“n”,它可能不会显示在 /proc/kallsyms 中。

于 2013-09-08T12:29:27.197 回答