[PATCH] D59594: [ELF] Change GOT*_FROM_END (relative to end(.got)) to GOTPLT* (start(.got.plt))

Siva Chandra via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 21 20:48:00 PDT 2019


sivachandra added inline comments.


================
Comment at: ELF/Relocations.cpp:1073-1075
+    // These x86 and x86_64 relocation types are relative to GOTPLT but their
+    // description uses GOT (the address of the global offset table), thus also
+    // ensure GOT is created.
----------------
MaskRay wrote:
> sivachandra wrote:
> > ruiu wrote:
> > > Is this logically x86-64 only? I think it is fine to create a .got when you create .got.plt, but the comment should explain that.
> > One need not emit `.got` even if emitting `.got.plt`. For example, for non-PIE but statically linked excutables, ld.bfd does not emit `.got` but still emits `.got.plt`.
> > 
> > That said, I am not sure if not emitting a `.got` (when emitting `.got.plt`) for other kinds of executables is a good/bad thing. IMO, emitting a `.got` even when not required will only add a few bytes at most.
> `R_GOTPLT, R_GOTPLTONLY_PC, and R_GOTPLTREL` are x86-32 x86-64 only. It currently emits `.got` because we need to compute the distance between `.got` and `.got.plt`. The empty `.got` will serve as an anchor.
> 
> I read some history in the past and I remember that `*_FROM_END` was chosen to make the GOT base in the middle of `.got`
> 
> AMD64 psABI p.75
> 
> > The symbol _GLOBAL_OFFSET_TABLE_ may reside in the middle of the .got section,
> allowing both negative and non-negative offsets into the array of addresses.
> 
> But in reality that rule doesn't have to be followed strictly.. @sivachandra mentioned https://fedoraproject.org/wiki/Changes/.got.plt_Isolation Now I'm thinking ld.bfd may in some configuration allow `.got` and `.got.plt` to be separated. If that is true, The start of `.got.plt` would still be the GOT base as `end(.got)` would break things...
Note that the ABI doc does not prescribe `.got.plt`. In fact, AFAICT, there is no mention of such a section in the doc. 

The way I view/interpret it is this:

1. `.got.plt` is a section which linkers have been emitting as a convenient logical separation: everything `.got` pertains to global variables, and every thing after that supports `.plt`.
2. As a convention, they have been making the address of GOT = `start(.got.plt)`
3. So, by placing `.got.plt` right after `.got`, they still adhere to the ABI which says GOT may reside  in the middle of `.got`. That is, `.got.plt` is merely an extension of `.got`.

Just curious, for what purposes does one need to compute the distance between `.got` and `.got.plt`?


Repository:
  rLLD LLVM Linker

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59594/new/

https://reviews.llvm.org/D59594





More information about the llvm-commits mailing list