c - 将符号从 .global 更改为 .weak 会产生什么后果?

标签 c linux assembly linux-kernel x86

previous question 上花了一些时间之后,一位用户向我介绍了有关以下问题的电子邮件线程:

[PATCH] ftrace/x86: Fix function graph tracer reset path

On my system, simply enabling and disabling function graph tracer can crash the kernel. I don't know how it worked until now.

The ftrace_disable_ftrace_graph_caller() modifies jmp instruction at ftrace_graph_call assuming it's a 5 bytes near jmp (e9 ). However it's a short jmp consisting of 2 bytes only (eb ). And ftrace_stub() is located just below the ftrace_graph_caller so modification above breaks the instruction resulting in kernel oops on the ftrace_stub() with the invalid opcode like below:

此问题的一个解决方案是以下补丁:

 diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/mcount_64.S
 index ed48a9f465f8..e13a695c3084 100644
 --- a/arch/x86/kernel/mcount_64.S
 +++ b/arch/x86/kernel/mcount_64.S
 @@ -182,7 +182,8 @@ GLOBAL(ftrace_graph_call)
    jmp ftrace_stub
  #endif

 -GLOBAL(ftrace_stub)
 +/* This is weak to keep gas from relaxing the jumps */
 +WEAK(ftrace_stub)
    retq
  END(ftrace_caller)

通过https://lkml.org/lkml/2016/5/16/493

我不明白将 GLOBAL(ftrace_stub) 替换为 WEAK(ftrace_stub) 会产生什么影响。补丁中既没有评论也没有调查 GLOBAL()WEAK()帮助我理解了为什么这个解决方案有效。

如标题所示,我的问题是:将符号从 .globl 更改为 .weak 会产生什么后果?我将不胜感激考虑如何将 GLOBAL(ftrace_stub) 替换为 WEAK(ftrace_stub) 可以解决所引用问题的答案。

最佳答案

由于 ftrace_stub 是在当前文件中定义的,因此汇编器知道距离并且可以使用范围有限的 jmp 的较短版本。

如果它更改为 weak 这意味着该符号可能无法解析为当前文件中的符号,因为其他模块可能会覆盖它。不知道该潜在覆盖的偏移量,因此汇编器必须使用完整范围的 jmp,这是修补代码所期望的。

关于c - 将符号从 .global 更改为 .weak 会产生什么后果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37812507/

相关文章:

c - 出于性能原因将代码推送到内核或用户空间?

c - 如何使用 C 设置 eclipse 进行大学工作

c - 链表中 Next 指针的大小?

c - 代码 "should"有效,但程序停止工作

linux - 我可以删除root用户主目录下的Matlab安装文件吗

linux - 比较两个目录中的文件名

c - mmap真的是将数据复制到内存中吗?

assembly - 如何将(最多)16 个单字节移动到 XMM 寄存器中?

assembly - 奇怪的汇编语言添加

c - 我对堆栈框架结构有疑问?