将符号从.globl更改为.weak的后果是什么?

bur*_*ino 7 c linux x86 assembly linux-kernel

在上一个问题上花了一些时间之后,用户向我介绍了有关以下问题的电子邮件主题:

[PATCH] ftrace/x86:修复功能图跟踪器重置路径

在我的系统上,只需启用和禁用功能图跟踪器就可以使内核崩溃.直到现在我还不知道它是如何运作的.

假设ftrace_disable_ftrace_graph_caller()jmp指令在ftrace_graph_calljmp(e9)附近是5个字节,则修改jmp指令 .然而,它是一个短的jmp,只包含2个字节(eb).并且 ftrace_stub()位于ftrace_graph_caller上面这样的修改之下,打破导致内核oops的指令ftrace_stub()与无效的操作码如下所示:

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

 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)
Run Code Online (Sandbox Code Playgroud)

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

我不明白的作用是什么替换GLOBAL(ftrace_stub)WEAK(ftrace_stub).补丁中包含的注释和查看GLOBAL()WEAK()都没有帮助我理解为什么这个解决方案有效.

正如标题所暗示的那样,我的问题是: 将符号从.globl更改为.weak的后果什么?我希望的是考虑如何更换一个答案GLOBAL(ftrace_stub)WEAK(ftrace_stub)可以解决引用问题.

Jes*_*ter 7

由于ftrace_stub在当前文件中定义,汇编程序知道距离并且可以使用jmp仅具有有限范围的较短版本.

如果更改为weak,则表示符号可能无法解析为当前文件中的符号,因为其他模块可能会覆盖它.该潜在覆盖的偏移量是未知的,因此汇编程序必须使用jmp修补代码所期望的整个范围.