在 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 atftrace_graph_call
assuming it's a 5 bytes near jmp (e9 ). However it's a short jmp consisting of 2 bytes only (eb ). Andftrace_stub()
is located just below theftrace_graph_caller
so modification above breaks the instruction resulting in kernel oops on theftrace_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/