This is an archive of the discontinued LLVM Phabricator instance.

[ELF] - implemented R_386_TLS_IE_32 relocation.
AbandonedPublic

Authored by grimar on Dec 24 2015, 6:18 AM.

Details

Reviewers
ruiu
rafael
Summary

R_386_TLS_IE_32 is generated in such sequence:

movl %gs:0,%eax
addl tls0@gottpoff(%ebx),%eax

Urlich has the only mention of it as #define R_386_TLS_IE_32 /* GOT entry for static TLS block */ and no other info, so main source of information was gold output and source code mostly.
Patch has one problem I would like to discuss. Will add comment below.

Diff Detail

Event Timeline

grimar updated this revision to Diff 43596.EditedDec 24 2015, 6:18 AM
grimar retitled this revision from to [ELF] - implemented R_386_TLS_IE_32 relocation..
grimar updated this object.
grimar added reviewers: ruiu, rafael.
grimar added subscribers: llvm-commits, grimar.

So problem I have in this patch is next. Assume we have the code below:

movl %gs:0,%eax
addl tls0@gottpoff(%ebx),%eax

movl %gs:0,%eax
addl tls0@gotntpoff(%ebx),%eax

First sequence generates R_386_TLS_IE_32, second generates R_386_TLS_IE. And the problem is
that such part of code looks to require 2 got entries. First one is entry for positive TLS offset,
second is GOT entry for positive TLS offset.
gold implementation contains enum allowing it to generate different GOT entries:

enum Got_type
 {
   GOT_TYPE_STANDARD = 0,      // GOT entry for a regular symbol
   GOT_TYPE_TLS_NOFFSET = 1,   // GOT entry for negative TLS offset
   GOT_TYPE_TLS_OFFSET = 2,    // GOT entry for positive TLS offset
   GOT_TYPE_TLS_PAIR = 3,      // GOT entry for TLS module/offset pair
   GOT_TYPE_TLS_DESC = 4       // GOT entry for TLS_DESC pair
 };

We don`t have types of GOT entries. All we have now is uint32_t GotPltIndex; in SymbolBody.
Currently gold`s GOT_TYPE_TLS_OFFSET is only used for i386 R_386_TLS_IE_32 relocation so it is corner case.
I dont know how much is possible for one symbol to reproduce the case like above and require 2 entries.
So far I would suggest to check somehow that corner case and produce an "unsupported" error for now.
We could rewrite code in next way:
bool Regular = Target->requiresRegularGot(Type);

...
unsigned IsRegularGot : 1;
bool SymbolBody::isInGot(bool Regular) const {
  if (GotIndex == -1U)
    return false;
  if (IsRegularGot != Regular)
    error("...");
  return true;
}
...
template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym, bool Regular) {
  Sym->GotIndex = Target->getGotHeaderEntriesNum() + Entries.size();
  Sym->IsRegularGot = Regular;
  Entries.push_back(Sym);
}

Another option would be to implement GOT entries types I think.

rafael edited edge metadata.Dec 24 2015, 8:45 AM
rafael added a subscriber: rafael.

Do you know what uses gottpoff in x86? Looking at llvm it seems we
always produce gotntpoff.

Cheers,
Rafel

Do you know what uses gottpoff in x86? Looking at llvm it seems we
always produce gotntpoff.

Cheers,
Rafel

No, I dont. I just assumed that if relocation exist (and not marked as not supported/depricated in ABI) then
its worth to support it for potential users.
Do you think we should not do that ?

grimar abandoned this revision.Jan 8 2016, 12:42 AM

That relocation seems to be not used in real life atm.