[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