【问题标题】:Repeating names in /proc/kallsyms在 /proc/kallsyms 中重复名称
【发布时间】:2017-10-24 00:52:44
【问题描述】:

为什么 /proc/kallsyms 中的某些符号会重复?例如:我看到_acpi_module_name__this_modulecleanup_module.LC0 重复多次。

为什么会这样?为什么有符号可以将名称解析为多个地址?我在 /proc/kallsyms 中看到 __acpi_module_name 重复了 113 次。

【问题讨论】:

    标签: linux linux-kernel


    【解决方案1】:

    这些是不同的情况。

    对于_acpi_module_name,它们只是静态全局变量。静态全局变量或函数仅在声明它的文件中“可见”。它在 include/acpi/acoutput.h 中定义。

    #define ACPI_MODULE_NAME(name)          static const char ACPI_UNUSED_VAR _acpi_module_name[] = name;
    

    对于__this_module,它们定义在每个内核模块中,由script/mod/modpost添加。

     /**
     * Header for the generated file
     **/
    static void add_header(struct buffer *b, struct module *mod)
    {
            buf_printf(b, "#include <linux/module.h>\n");
            buf_printf(b, "#include <linux/vermagic.h>\n");
            buf_printf(b, "#include <linux/compiler.h>\n");
            buf_printf(b, "\n");
            buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
            buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
            buf_printf(b, "\n");
            buf_printf(b, "__visible struct module __this_module\n");
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
            buf_printf(b, "\t.name = KBUILD_MODNAME,\n");
            if (mod->has_init)
                    buf_printf(b, "\t.init = init_module,\n");
            if (mod->has_cleanup)
                    buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
                                  "\t.exit = cleanup_module,\n"
                                  "#endif\n");
            buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n");
            buf_printf(b, "};\n");
    }
    

    对于cleanup_module,它在include/linux/module.h中定义

    #define module_exit(exitfn)                                     \
            static inline exitcall_t __maybe_unused __exittest(void)                \
            { return exitfn; }                                      \
            void cleanup_module(void) __attribute__((alias(#exitfn)));
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    #endif
    

    对于.LC0,它是编译器在不同源文件中生成的标签,如静态全局变量。

    【讨论】:

      猜你喜欢
      • 2019-08-30
      • 2016-12-31
      • 2021-12-18
      • 1970-01-01
      • 2016-01-03
      • 2021-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多