什么是__ksymtab?在linux内核中

Posted

技术标签:

【中文标题】什么是__ksymtab?在linux内核中【英文标题】:what is __ksymtab? in linux kernel 【发布时间】:2013-08-31 11:24:31 【问题描述】:

当我们 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
....
    T、r、D、d 的东西是什么意思? 我可以在内核源代码中找到符号 EXPORT_SYMBOL(...) 但还有其他前缀为 __ksymtab... 或 __kstrtab... 这些是什么? 是否可能 System.map 中有符号但 /proc/kallsyms 中排除了符号? (假设内核编译正确) 我启用了 netfilter 的 linux 内核,但我找不到符号 'nf_hooks' 但有'__ksymtab_nf_hook'。有没有办法获取 nf_hooks 的地址 使用 __ksymtab_nf_hook? 我在我的 linux 源代码中看到 EXPORT_SYMBOL(nf_hook) 但如果我找不到它 '猫/proc/kallsyms'。这有什么典型的原因吗?

提前谢谢你。

【问题讨论】:

【参考方案1】:

    格式类似于output of nm utility,另见this page。

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

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

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

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

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

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

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

    但是请注意,__ksymtab_nf_hook 是为nf_hook 而不是nf_hooks。名称必须匹配。 nf_hooksnf_hook 是不同的实体。

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

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

【讨论】:

以上是关于什么是__ksymtab?在linux内核中的主要内容,如果未能解决你的问题,请参考以下文章

在linux内核中为什么解析设备树时会使用be32_to_cpup()接口?

C语言在linux内核中do while妙用之法

linux内核中的虚拟到物理地址转换

Linux内核__setup()宏介绍

第1个linux驱动___打印"hello world"

第1个linux驱动___打印"hello world"