[PATCH] D47098: [ELF] Make R_GOTONLY_PC_FROM_END R_GOTREL_FROM_END relative to _GLOBAL_OFFSET_TABLE_ instead of end of .got
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue May 29 14:06:25 PDT 2018
MaskRay added inline comments.
================
Comment at: ELF/InputSection.cpp:501
+ // If we scanned relocations earlier, GlobalOffsetTable could't be null.
+ return (GOTBase ? GOTBase->getVA()
+ : InX::Got->getVA() + InX::Got->getSize()) +
----------------
MaskRay wrote:
> peter.smith wrote:
> > grimar wrote:
> > > MaskRay wrote:
> > > > grimar wrote:
> > > > > What is your plan to fix this `FIXME`? It does not seem nice approach to add weak _GLOBAL_OFFSET_TABLE_ symbols to test cases
> > > > > which affects the calculation.
> > > > Changed the description. I think the usage of `InX::Got->getVA() + InX::Got->getSize()` is incorrect. We should use either:
> > > >
> > > > * `ElfSym::GlobalOffsetTable`. but it can be null when `_GLOBAL_OFFSET_TABLE_` is not explicitly referenced.
> > > > * If `GlobalOffsetTable` is null, use `InX::Got` or `InX::GotPlt` depending on `GotBaseSymInGotPlt`. We can avoid this if we scan relocations earlier and decide to emit `GlobalOffsetTable`.
> > > >
> > > > To properly address this I also need to study the TLS stuff. This revision is already sort of complicated, I want to keep the changes in a future revision
> > > > If GlobalOffsetTable is null, use InX::Got or InX::GotPlt depending on GotBaseSymInGotPlt. We can avoid this if we scan relocations earlier and decide to emit GlobalOffsetTable.
> > >
> > > I think `GlobalOffsetTable` should never be null here and scanning earlier seems to be the correct way to me. I am not sure if there will be problems or it is easy to do.
> > > Because of that, I think it would be better to see the full patch. It should reveal the whole picture and get rid of the need to
> > > add symbols to the existent test cases.
> > >
> > >
> > I think that _GLOBAL_OFFSET_TABLE_ should not be null here in a well formed program (by convention rather than any specific wording in the ABI). It will be possible to create an example with assembly but I don't think that there would be any expectation that it would work. I think it would be better to error rather than make an arbitrary choice of value.
> We are on the same page. I said we could "scan relocations earlier" then _GLOBAL_OFFSET_TABLE_ would not be null and that is why I left a "FIXME" there.
>
> But doing that is probably too difficult for me. The current change is imperfect but is compatible with other places. When _GLOBAL_OFFSET_TABLE_ is null, the code makes an arbitrary choice (the same as the old code does): the end of the .got section.
Added some comments about
return (ElfSym::GlobalOffsetTable
? ElfSym::GlobalOffsetTable->getVA()
: InX::Got->getVA() + InX::Got->getSize()) +
A - P;
It is very difficult to scan relocations earlier
ElfSym::GlobalOffsetTable is defined in
https://github.com/llvm-mirror/lld/tree/got2/ELF/Driver.cpp#L1254
addReservedSymbols();
scanRelocations is transitively called in Writer<ELFT>::finalizeSections
createSyntheticSections and a bunch of other handlers are called in between and some of them checks ElfSym::GlobalOffsetTable.
I have left a comment here why the choice albeit imperfect, does not cause trouble in practice: because the two relocations S+A-GOT and GOT+A-P counteract each other.
So an arbitrary address (end of .got) works.
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D47098
More information about the llvm-commits
mailing list