[PATCH] D59559: [ELF] Make R_I386_GOTPC and R_X86_64_GOTPC32/64 resolve to .got.plt.

Siva Chandra via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 19 21:49:11 PDT 2019


sivachandra added a comment.

In D59559#1435809 <https://reviews.llvm.org/D59559#1435809>, @MaskRay wrote:

> I believe the patch in the current form will break some `_GLOBAL_OFFSET_TABLE_` use cases (see https://reviews.llvm.org/D48095) so I volunteer to be a reviewer :)


Thanks, I did not know who the correct reviewer is, so I just added ruiu.

About "will break some `_GLOBAL_OFFSET_TABLE_` use cases", can you elaborate which ones?

> `_GLOBAL_OFFSET_TABLE_ : specifies the offset to the base of the GOT from the current code location.`

AFAIU, this convention you are quoting (from http://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf I believe) pertains to the assembly language usage. See Figure 3.12 for example.

However, _GLOBAL_OFFSET_TABLE_ is also an ELF symbol (which is unrelated to the offset convention above.) So, AFAIU, this patch does not break anything wrt the symbol _GLOBAL_OFFSET_TABLE_. But, you can point me to examples if that is the case.

> The issue has been discussed a lot in https://bugs.llvm.org/show_bug.cgi?id=36555 . Some aspects in that thread no longer apply nowadays. I believe the remaining issue is that we have `_GLOBAL_OFFSET_TABLE_ = end(.got)` (lld's generalized `R_*_FROM_END` relocation types require this) but `end(.got) != start(.got.plt)` (we don't have a section rank rule for this).

Again AFAIU, where you place the symbol _GLOBAL_OFFSET_TABLE_ does not matter as long as it points to the zeroth location of the GOT (which is to say, the GOT itself.)

> As I noted in https://reviews.llvm.org/D56828 , after that patch we can make `end(.got) = start(.got.plt)` if we want and thus address the issue this patch intends to address. AFAIK no user application needs that but some ld.so implementations may want to have this property.

I think, that we should/can have end(.got) = start(.got.plt) is a very desirable thing because, again according to the same ABI doc, one should allow negative indices into GOT. Since the zeroth location of GOT is start(.got.plt) by convention, negative indices into GOT are meaningful only if end(.got) = start(.got.plt).

Note that, this change also does not do anything wrt where the symbol _GLOBAL_OFFSET_TABLE_ is placed. What this change is essentially doing is to follow the ABI docs which say that R_I386_GOTPC, R_X86_64_GOTPC32/64 are all this:

GOT + A - P

In ld.lld, GOT is at start(.got.plt). So, this change is essentially making the above relocations resolve as start(.got.plt) + A - P. If ld.lld decides to place GOT at a different location, then we should update how these relocations resolve accordingly.

> - More specifically, it allows to get rid of one lld-compatibility patch to glibc https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commit;h=575707c22f901b0adcce2478cc32da62afff287e

FWIW, an unrelated glibc use case is what drove me to this change.

> If people think that making `end(.got) = start(.got.plt)` is desirable I volunteer to do that, but it requires some more rules in `Writer.cpp:getSectionRank`?

I do not have any practical examples at hand to prove/disprove if it is desirable or not. But, end(.got) = start(.got.plt) makes GOT contiguous and allows negative indices into GOT as required by the ABI doc. So, it is probably desirable.


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