[PATCH] D59559: [ELF] Make R_I386_GOTPC and R_X86_64_GOTPC32/64 resolve to .got.plt.
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 19 23:48:30 PDT 2019
MaskRay added a comment.
> [2] - Glibc's X86_64 code uses extern long _DYNAMIC[] __attribute__((visibility("hidden"))); just like the test in question. However, it refers to only &_DYNAMIC, for which the compiler emits R_X86_64_PC32. Hence, we do not hit the problem with
glibc emits `leaq _DYNAMIC(%rip), %rax` (`R_X86_64_PC32`) because it assumes small code model. I agree that this patch won't break that. However, internally we have medium code model instruction sequences:
leaq _GLOBAL_OFFSET_TABLE_(%rip), %rdx
movabsq $_DYNAMIC at GOTOFF, %rax
addq %rdx, %rax
> But, the test is passing and working as intended because the current implementations of GOTPC64 and GOTOFF64 are cancelling each other out [3]
Yes. Currently the example above relies on the cancellation effect.
> In ld.lld currently, R_X86_64_GOTOFF64 resolves as this:
>
> Sym.getVA(A) - In.Got->getVA() - In.Got->getSize()
>
> Sym.getVA(A) - In.GotPlt->getVA() // [4]
Agree. Most `In.Got->getVA() + In.Got->getSize()` should be changed to `In.GotPlt->getVA()` to be compatible with the address of `_GLOBAL_OFFSET_TABLE_`.
Two relocation types can not have such simple transformation:
case R_TLSGD_GOT_FROM_END:
return In.Got->getGlobalDynOffset(Sym) + A - In.Got->getSize();
case R_TLSLD_GOT_FROM_END:
return In.Got->getTlsIndexOff() + A - In.Got->getSize();
> [1] - To fix R_X86_64_GOTOFF64 the right way, I really think we need .got and .got.plt to be adjacent as we need negative indices into GOT. May be this is _the_ reason why we should make end(.got) == start(.got.plt).
Can you quote the paragraph where negative indices into GOT are used in i386/amd64 psABI?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D59559/new/
https://reviews.llvm.org/D59559
More information about the llvm-commits
mailing list