[PATCH] D13986: [ELF2] - TLS relocations implemented

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 23 01:13:04 PDT 2015


grimar added inline comments.

================
Comment at: ELF/Writer.cpp:612-642
@@ -611,12 +611,33 @@
   uintX_t Last = PF_R;
+
+  bool HasTbss = false;
+  bool HasTdata = false;
+  bool InTls = false;
   for (OutputSectionBase<ELFT> *Sec : OutputSections) {
     if (!Sec->getSize() || !needsPhdr<ELFT>(Sec))
       continue;
+
+    bool EndPhdr = false;
+    if (Sec->getFlags() & SHF_TLS) {
+      if (Sec->getType() == SHT_PROGBITS)
+        HasTdata = true;
+      else
+        HasTbss = true;
+      EndPhdr = true;
+      InTls = true;
+    } else if (InTls) {
+      EndPhdr = true;
+      InTls = false;
+    }
+
     uintX_t Flags = toPhdrFlags(Sec->getFlags());
-    if (Last != Flags) {
+    if (EndPhdr || Last != Flags) {
       Last = Flags;
       ++NumPhdrs;
     }
   }
 
+  if (!HasTbss && HasTdata)
+    ++NumPhdrs;
+
   // Reserve space needed for the program header so that the array
----------------
Bigcheese wrote:
> 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.
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     

2) 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 

3) 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.


http://reviews.llvm.org/D13986





More information about the llvm-commits mailing list