问题描述
我正在学习有关线程本地存储及其在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
前缀了。