Linux/proc/kallsyms文件,内核在哪里保存核心符号列表?

Linux/proc/kallsyms文件,内核在哪里保存核心符号列表?,c,assembly,module,linux-kernel,symbols,C,Assembly,Module,Linux Kernel,Symbols,要在/proc/kallsyms中显示符号,对于模块符号,内核在以modules内核变量为首的模块对象上循环,并迭代每个模块的符号表。但对于“核心”内核内置符号,它使用了一组内核变量,如下函数所示: static unsigned long kallsyms_sym_address(int idx) { if (!IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE)) return kallsyms_addresses[idx];

要在
/proc/kallsyms
中显示符号,对于模块符号,内核在以
modules
内核变量为首的模块对象上循环,并迭代每个模块的符号表。但对于“核心”内核内置符号,它使用了一组内核变量,如下函数所示:

static unsigned long kallsyms_sym_address(int idx)
{
    if (!IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE))
        return kallsyms_addresses[idx];

    /* values are unsigned offsets if --absolute-percpu is not in effect */
    if (!IS_ENABLED(CONFIG_KALLSYMS_ABSOLUTE_PERCPU))
        return kallsyms_relative_base + (u32)kallsyms_offsets[idx];

    /* ...otherwise, positive offsets are absolute values */
    if (kallsyms_offsets[idx] >= 0)
        return kallsyms_offsets[idx];

    /* ...and negative offsets are relative to kallsyms_relative_base - 1 */
    return kallsyms_relative_base - 1 - kallsyms_offsets[idx];
}
问题是:

  • kallsyms_地址和kallsyms_偏移量数组在哪里定义?我试图grep内核源代码,但只找到引用,没有定义
  • 它们在哪里初始化
  • 这些变量和/boot/System.map.kernel\u版本文件之间有什么关系?我认为它们应该是一致的,但我还是没有找到初始化代码

  • 我不知道确切的答案,但相当肯定,一定有链接器魔术参与。您可能希望跟踪scripts/kallsysms.c,它在链接时似乎正在构造这些符号(和其他符号)。请参阅并感谢各位,这些提示解释了很多。有一件事我仍然不明白——如果
    nm-nvmlinux
    起作用,这是否意味着临时vmlinux二进制文件中已经有一个符号表?如果是这样,为什么不能直接使用这个符号表,而不是使用kallsyms.c和link-vmlinux.sh来修补从
    nm
    生成的另一个符号表?