This is an archive of the discontinued LLVM Phabricator instance.

[ELF2] - TLS relocations implemented
AbandonedPublic

Authored by grimar on Oct 22 2015, 9:15 AM.

Details

Summary
  • Implements R_X86_64_TPOFF32, R_X86_64_DTPOFF32 relocations.
  • Implements PT_TLS header.

Diff Detail

Event Timeline

grimar updated this revision to Diff 38136.Oct 22 2015, 9:15 AM
grimar retitled this revision from to [ELF2] - TLS relocations implemented.
grimar updated this object.
grimar added reviewers: ruiu, rafael, davide.
grimar added subscribers: llvm-commits, grimar.
davide edited edge metadata.Oct 22 2015, 9:24 AM

If it's not a big amount of work, can you split PT_TLS and relocations in two different patches? If it is too much, forget about it.
Also, while I haven't reviewed his work very carefully, I think Michael Spencer is working on TLS as well, so I think you guys should coordinate to minimize the overlap.

davide edited edge metadata.Oct 22 2015, 9:25 AM
davide added a subscriber: Bigcheese.

If it's not a big amount of work, can you split PT_TLS and relocations in two different patches? If it is too much, forget about it.
Also, while I haven't reviewed his work very carefully, I think Michael Spencer is working on TLS as well, so I think you guys should coordinate to minimize the overlap.

I could split but just not sure how.
When I add some TLS data (variables) then R_X86_64_TPOFF32/R_X86_64_DTPOFF32 relocations are created and we need the size of TLS and its address to process them.
TLS info currently is calculated during headers creating.
At the same time TLS header will only present if we have some TLS data. And data means relocations.
So just not sure it is easy to split. Ideas are welcome.

If it's not a big amount of work, can you split PT_TLS and relocations in two different patches? If it is too much, forget about it.
Also, while I haven't reviewed his work very carefully, I think Michael Spencer is working on TLS as well, so I think you guys should coordinate to minimize the overlap.

I could split but just not sure how.
When I add some TLS data (variables) then R_X86_64_TPOFF32/R_X86_64_DTPOFF32 relocations are created and we need the size of TLS and its address to process them.
TLS info currently is calculated during headers creating.
At the same time TLS header will only present if we have some TLS data. And data means relocations.
So just not sure it is easy to split. Ideas are welcome.

Leave it as is then.

ruiu added inline comments.Oct 22 2015, 12:23 PM
ELF/OutputSections.h
330

TLS -> Tls

ELF/Writer.cpp
736

Too much code has been added to this function. It needs cleanup before adding more.

grimar added inline comments.Oct 22 2015, 12:37 PM
ELF/Writer.cpp
736

I agree. Its bulky now.
I`ll try to do something with it tomorrow.

emaste added a subscriber: emaste.Oct 22 2015, 1:17 PM
Bigcheese requested changes to this revision.Oct 22 2015, 4:40 PM
Bigcheese added a reviewer: Bigcheese.
Bigcheese added inline comments.
ELF/Writer.cpp
612–642

We don't need to handle the case of multiple disjoint TLS initialization blocks. The spec doesn't allow it. All this needs to do is add a phdr if it sees any allocated TLS section.

736

http://reviews.llvm.org/D13615 provides a much simpler implementation of the layout.

This revision now requires changes to proceed.Oct 22 2015, 4:40 PM
grimar added inline comments.Oct 23 2015, 1:13 AM
ELF/Writer.cpp
612–642

This code not about multiple disjoints. I tried to reproduce the same behavior as ld do.

There are 3 cases (first is cpp code, next is readelf output):

  1. Both .tbss and .tdata

thread int i;
thread int a = 56;

Program Headers:

Type           Offset             VirtAddr           PhysAddr
               FileSiz            MemSiz              Flags  Align
LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
               0x0000000000000168 0x0000000000000168  R E    200000
LOAD           0x0000000000000168 0x0000000000600168 0x0000000000600168
               0x0000000000000004 0x0000000000000004  RW     200000
TLS            0x0000000000000168 0x0000000000600168 0x0000000000600168
               0x0000000000000004 0x0000000000000008  R      4
GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
               0x0000000000000000 0x0000000000000000  RW     10

Section to Segment mapping:

Segment Sections...
 00     .text .eh_frame 
 01     .tdata 
 02     .tdata .tbss 
 03
  1. Only .tdata

__thread int a = 56;

Program Headers:

Type           Offset             VirtAddr           PhysAddr
               FileSiz            MemSiz              Flags  Align
LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
               0x0000000000000168 0x0000000000000168  R E    200000
LOAD           0x0000000000000168 0x0000000000600168 0x0000000000600168
               0x0000000000000004 0x0000000000000004  RW     200000
TLS            0x0000000000000168 0x0000000000600168 0x0000000000600168
               0x0000000000000004 0x0000000000000004  R      4
GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
               0x0000000000000000 0x0000000000000000  RW     10

Section to Segment mapping:

Segment Sections...
 00     .text .eh_frame 
 01     .tdata 
 02     .tdata 
 03
  1. Only tbss

__thread int i;

Program Headers:

Type           Offset             VirtAddr           PhysAddr
               FileSiz            MemSiz              Flags  Align
LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
               0x0000000000000130 0x0000000000000130  R E    200000
TLS            0x0000000000000130 0x0000000000601000 0x0000000000601000
               0x0000000000000000 0x0000000000000004  R      4
GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
               0x0000000000000000 0x0000000000000000  RW     10

Section to Segment mapping:

Segment Sections...
 00     .text .eh_frame 
 01     .tbss 
 02

As can be seen,

  1. For tdata and tbss it leaves tdata as LOAD and converts tbss to TLS header.
  2. For tdata only it leaves tdata as LOAD and emits TLS header after it.
  3. For tbss only it converts it to TLS.

So output of my implementation is currently compietely equal to ld.

grimar abandoned this revision.Oct 24 2015, 11:32 AM