[PATCH] D47098: [ELF] Make R_GOTONLY_PC_FROM_END R_GOTREL_FROM_END relative to _GLOBAL_OFFSET_TABLE_ instead of end of .got
George Rimar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue May 29 07:54:15 PDT 2018
grimar added a comment.
In https://reviews.llvm.org/D47098#1114628, @peter.smith wrote:
> > 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();.
Looks a bit tricky for me honestly.
> 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.
>
>
I do not know.
I wonder if the next would be the correct way to solve this:
As far I understand, _GLOBAL_OFFSET_TABLE_ seems intended to be used with special types of relocations (this needs clarification).
R_X86_64_GOTPC64/R_X86_64_GOTPC32 and you mentioned R_ARM_BASE_PREL for arm, for example (your https://reviews.llvm.org/D46319 seems to make sense to me)
It seems that if we could know that symbol is _GLOBAL_OFFSET_TABLE_, we could always resolve it relative to the end of .got.
For x86 seems llvm-mc emits R_X86_64_PC32/R_X86_64_GOTPC64 and gas emits R_X86_64_GOTPC32/R_X86_64_GOTPC64 if _GLOBAL_OFFSET_TABLE_ is used.
If llvm-mc would emit R_X86_64_GOTPC32 too that we probably could do nothing here and continue resolving such relocations relative to the .got end.
I am not sure about the other targets, but if they also have special relocations for _GLOBAL_OFFSET_TABLE_, that could help to resolve this.
Or probably we could special case relocating _GLOBAL_OFFSET_TABLE_ symbol for now.
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D47098
More information about the llvm-commits
mailing list