在Linux内核中如何解决线程本地存储偏移?

问题描述

我正在学习有关线程本地存储及其在Linux内核中的用法。我知道它允许存储每个线程的数据。例如,访问current task_struct时就是这种情况。

我看到在我的x86_64体系结构中,这是通过使用全局段(%gs)完成的。我的问题是:GCC如何解析此全局段的地址(即,它如何将mov rax,QWORD PTR gs:0中的.(k)o转换为已编译对象中的mov rax,QWORD PTR gs:0x17d80?)

解决方法

.ko是已编译的对象。 gs前缀是显式发出的,其余只是普通的符号重定位。例如,摘自运行objdump -dr amdgpu.ko的内容:

12b51:       65 48 8b 14 25 00 00    mov    %gs:0x0,%rdx
12b58:       00 00 
                    12b56: R_X86_64_32S     current_task

R_X86_64_32S只是一个标准的符号重定位,它将由内核模块加载程序解决。代码中已经有gs前缀了。