有没有参数可以修改 linker 重定位符号的方式

2020-06-22 14:46:01 +08:00
 liuminghao233

例如我有一个函数

其中 isr0 地址在使用 LD 和 LLD 定位的时候有不同的结果

set_intr_gate(0, 1, (void*)&isr0);

mov    0x0(%rip),%rax        # 385 <idt_init+0xb6>

使用 ld 链接它会使用绝对地址 结果为

mov    $0x103645,%rax

使用 LLD 的话又是另外一种情况 变成了

lea    0x89d(%rip),%rax        # 103645 <isr0>

因为使在写系统内核 把 0x000000000000 开始的页表映射取消了 只留下 0xffffff8000000000 开始的内核也就是

0xffffff8000000000-0xffffff80005fffff -> 0x000000000000-0x0000005fffff

RIP 也是加上了 0xffffff8000000000 的

使用 LD 得到的是 0x103645 需要把 isr0 地址加上 PAGE_OFFSET 不然会缺页

使用 LLD 的话它通过 RIP 寻址 isr0 就没必要加上 PAGE_OFFSET 了

有没有参数可以让 ld 按照 lld 那样取 resolve 符号?

869 次点击
所在节点    问与答
1 条回复
MaskRay
2020-09-30 14:45:34 +08:00
objdump -dr 可以看使用的 relocation type

LLD 只优化 R_X86_64_[REX_]GOT_PCRELX (-Wa,-mrelax-relocations=yes)
对于

(1) movq foo@GOTPCREL(%rip), %reg -> leaq foo(%rip), %reg
(2) call *foo@GOTPCREL(%rip) -> nop; call foo
(3) jmp *foo@GOTPCREL(%rip) -> jmp foo; nop

GNU ld 对于 R_X86_64_[REX_]GOT_PCREL (注意没有 X)也会优化 (1)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/683757

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX