【发布时间】:2017-10-24 00:52:44
【问题描述】:
为什么 /proc/kallsyms 中的某些符号会重复?例如:我看到_acpi_module_name、__this_module、cleanup_module、.LC0 重复多次。
为什么会这样?为什么有符号可以将名称解析为多个地址?我在 /proc/kallsyms 中看到 __acpi_module_name 重复了 113 次。
【问题讨论】:
标签: linux linux-kernel
为什么 /proc/kallsyms 中的某些符号会重复?例如:我看到_acpi_module_name、__this_module、cleanup_module、.LC0 重复多次。
为什么会这样?为什么有符号可以将名称解析为多个地址?我在 /proc/kallsyms 中看到 __acpi_module_name 重复了 113 次。
【问题讨论】:
标签: linux linux-kernel
这些是不同的情况。
对于_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,它是编译器在不同源文件中生成的标签,如静态全局变量。
【讨论】: