This is an archive of the discontinued LLVM Phabricator instance.

[ELF] - Implemented some GD, LD and IE TLS access models for x86 target.
ClosedPublic

Authored by grimar on Nov 29 2015, 3:16 PM.

Details

Summary

Main aim of the patch to introduce basic support for TLS access models for x86 target.
Models using @tlsgd, @tlsldm and @gotntpoff are implemented.
There are no any TLS optimizations yet - I plan to add them in another following patches.

Diff Detail

Repository
rL LLVM

Event Timeline

grimar updated this revision to Diff 41356.Nov 29 2015, 3:16 PM
grimar retitled this revision from to [ELF] - Implemented some GD, LD and IE TLS access models for x86 target..
grimar updated this object.
grimar added reviewers: ruiu, rafael.
grimar added subscribers: llvm-commits, grimar.
ruiu added inline comments.Nov 30 2015, 9:53 AM
ELF/OutputSections.cpp
84 ↗(On Diff #41356)

Why do we need a different member variable than GotIndex?

ELF/OutputSections.h
126 ↗(On Diff #41356)

getNumEntries

ELF/Target.cpp
350 ↗(On Diff #41356)
  break;
}
grimar added inline comments.Nov 30 2015, 11:04 AM
ELF/OutputSections.cpp
84 ↗(On Diff #41356)

Thats needed for the next code sequence to work correctly:

leal tls0@tlsgd(,%ebx,1),%eax
call __tls_get_addr@plt
movl %gs:0,%eax
addl tls0@gotntpoff(%ebx),%eax

@tlsgd(x) - Allocates two contiguous entries in the GOT to hold a TLS_index structure.
@gotntpoff(x) - Allocates a entry in the GOT, and initializes it with the negative tlsoffset relative to the static TLS block. This is performed at runtime via the R_386_TLS_TPOFF relocation.

Problem is that next part of code terminates execution flow:

void Writer<ELFT>::scanRelocs(
.....
    if (Body && Body->isTLS() && Target->isTlsGlobalDynamicReloc(Type)) {
      if (Target->isTlsOptimized(Type, Body))
        continue;
      if (Body->isInGot())
        continue;

Make it continue and unable to move forward and create R_386_TLS_TPOFF relocation (and single entry) below at the end of that method.

ruiu added inline comments.Nov 30 2015, 3:25 PM
ELF/OutputSections.cpp
84 ↗(On Diff #41356)

Understood, but can you do that in a different way? I think the new variable is rather confusing, since symbols added to GOT using addDynTlsEntry are in GOT, but isInGot returns false for them (although they are in GOT).

grimar added inline comments.Dec 1 2015, 3:40 AM
ELF/OutputSections.cpp
84 ↗(On Diff #41356)

First of all: I reproduced the same situation on x64 target and decided to split patch for that from this one: http://reviews.llvm.org/D15105.

About making that in a different way:
I think we can`t avoid using additional index variable because we need to use different got entry ids for different places. I mean we must know id of dynamic tls entry and the normal tls entry and use them both.

But I dont see problem here for design. At fact we dont use isInGot() for GD reloc because it is special case and processed separately everywhere. So its even more confusing to have this to respond isInGot() call when this call looks like should never be used in according to current logic.

I prepared that separate patch to make code look more consistent with code for LocalModuleTlsIndexOffset to hightlight their special nature (also updated a test case for x64 there).

ELF/OutputSections.h
126 ↗(On Diff #41356)

Will be fixed in update.

ELF/Target.cpp
350 ↗(On Diff #41356)

Will be fixed in update.

ruiu added inline comments.Dec 1 2015, 9:41 AM
ELF/OutputSections.cpp
84 ↗(On Diff #41356)

Mostly my concern is about the name isInGot(). If something is in GOT, that function should return true no matter how that is in GOT, because the function is named is-in-got.

grimar updated this revision to Diff 41544.Dec 1 2015, 11:41 AM

Updated patch to match the latest code.
Addressed review comments.

grimar added inline comments.Dec 1 2015, 11:52 AM
ELF/OutputSections.cpp
84 ↗(On Diff #41356)

There is no more that code in this patch :) It dissolved during other commits, so I guess its fine now.

ruiu accepted this revision.Dec 1 2015, 1:05 PM
ruiu edited edge metadata.

LGTM with a few nits.

ELF/Target.cpp
338 ↗(On Diff #41544)

Move this after R_386_PC32.

341 ↗(On Diff #41544)

Offset -> V for consistency.

347 ↗(On Diff #41544)

Move this before R_386_TLS_PC32 to sort.

This revision is now accepted and ready to land.Dec 1 2015, 1:05 PM
This revision was automatically updated to reflect the committed changes.
grimar added inline comments.Dec 2 2015, 2:02 AM
ELF/Target.cpp
338 ↗(On Diff #41544)

Done.

341 ↗(On Diff #41544)

Done.

347 ↗(On Diff #41544)

There is no R_386_TLS_PC32 here, I think you meant before R_386_TLS_LE. Moved there.