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

时间:2016-06-14 12:48:06

标签: c linux assembly linux-kernel x86

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

  

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

     
    

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

         

ftrace_disable_ftrace_graph_caller()修改了jmp指令     ftrace_graph_call假设它在jmp(e9)附近是5个字节。     然而,它是一个短的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)

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

我不明白用GLOBAL(ftrace_stub)替换WEAK(ftrace_stub)会产生什么影响。补丁中包含的评论以及GLOBAL()WEAK()的评论都没有帮助我理解为什么这个解决方案有效。

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

1 个答案:

答案 0 :(得分:7)

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

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