[PATCH] D47098: [ELF] Make R_GOTONLY_PC_FROM_END R_GOTREL_FROM_END relative to _GLOBAL_OFFSET_TABLE_ instead of end of .got
Peter Smith via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue May 29 06:25:56 PDT 2018
peter.smith added a comment.
> I am not sure that the second way should work (if I understand everything correctly).
> For x86 as you know we define _GLOBAL_OFFSET_TABLE_ in the .got.plt[0] now.
> Then for example if we have the following TLS code:
>
> addl $_GLOBAL_OFFSET_TABLE_, %ebx #add $0x199f,%ebx, R_386_GOTPC
> subl $8, %esp #sub $0x8,%esp
> leal gd at tlsgd(%ebx), %eax #lea -0x10(%ebx),%eax, R_386_TLS_GD
>
>
> it expects the first line to be resolved to the end of .got (to the GOT base in ABI terminology).
> If we redefine the relocations that use _FROM_END to use the location of the _GLOBAL_OFFSET_TABLE_ (I think that is what this patch tried to do),
> then it will not help us I think as we will end up with the address of .got.plt at the first line. And the code will fail to find a proper TLS slot as a result since .got.plt
> can be far away from .got in LLD.
I think that the raw calculation would work if R_386_TLS_GD (RelExpr R_TLSGD) were defined to be something like InX::Got->getGlobalDynAddr(Sym) + A - ("VA of where _GLOBAL_OFFSET_TABLE_ is defined"). Instead of InX::Got->getGlobalDynOffset(Sym) + A - InX::Got->getSize();. I think that you are right that this distance will be larger if _GLOBAL_OFFSET_TABLE_ is defined to be base of .got.plt, however isn't the immediate 32-bits in size? I don't know of too many programs that would have that large a separation of .got or .got.plt but I suppose it is possible. Hope I haven't misunderstood as my x86 asm isn't good.
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D47098
More information about the llvm-commits
mailing list