例如我有一个函数
其中 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 符号?
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) |