[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 08:49:04 PDT 2018


peter.smith added a comment.

> 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)

Given that in several processor specific ABIs the _GLOBAL_OFFSET_TABLE_ can have more than one legal location I think that it can only be used with relocations that are applied consistently with the location of _GLOBAL_OFFSET_TABLE_ chosen by the linker.

- Refs: http://refspecs.linuxbase.org/elf/x86_64-abi-0.98.pdf , http://refspecs.linuxfoundation.org/ELF/zSeries/lzsabi0_zSeries/x2251.html, https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-74186/index.html

> It seems that if we could know that symbol is _GLOBAL_OFFSET_TABLE_, we could always resolve relocation 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 I understand you correctly this would mean that LLD would:

- Resolve any relocation to _GLOBAL_OFFSET_TABLE_ as if it were defined at the end of the .got section.
- Possibly define the _GLOBAL_OFFSET_TABLE_ symbol to be somewhere else, such as the start of the .got.plt so that _GLOBAL_OFFSET_TABLE_[0] could be used to contain the link time address of _DYNAMIC.

I think that this could work, but would require a lot of comments to explain why.

> 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.

I think if we change anything we should probably make it Target specific or risk breaking something. I know that when I made the mistake of moving _GLOBAL_OFFSET_TABLE_ to be the base of .got.plt on Arm I broke Chrome https://bugs.llvm.org/show_bug.cgi?id=36555#c16 . This would have worked if llvm-mc had used R_ARM_BASE_PREL rather than R_ARM_REL32  but sadly it doesn't so it needs _GLOBAL_OFFSET_TABLE_ to be the base of the .got output section.


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D47098





More information about the llvm-commits mailing list