[PATCH] [lld][ELF] Add static TLS support.

Michael Spencer bigcheesegs at gmail.com
Wed Jan 30 10:32:10 PST 2013



================
Comment at: lib/ReaderWriter/ELF/DefaultLayout.h:75-76
@@ -74,2 +74,4 @@
     ORDER_BSS = 210,
+    ORDER_TLSDATA = 215,
+    ORDER_TLSBSS = 216,
     ORDER_OTHER = 220,
----------------
Shankar Kalpathi Easwaran wrote:
> I see that gnu ld / gold puts .tdata/.tbss before .data, why are you ordering it differently ?
> 
> $cat t.c
> __thread int a = 10;
> __thread int b = 20;
> __thread int f;
> __thread int g;
> int initdata = 10;
> int bssdata;
> 
> int main()
> {
>   return 0;
> }
> 
> $gcc -c t.c
> $gold t.o
> $readelf -S a.out
> There are 12 section headers, starting at offset 0x2ac:
> 
> Section Headers:
>   [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
>   [ 0]                   NULL            00000000 000000 000000 00      0   0  0
>   [ 1] .text             PROGBITS        080480b4 0000b4 00000a 00  AX  0   0  4
>   [ 2] .eh_frame         PROGBITS        080480c0 0000c0 000038 00   A  0   0  4
>   [ 3] .tdata            PROGBITS        080490f8 0000f8 000008 00 WAT  0   0  4
>   [ 4] .tbss             NOBITS          08049100 000100 000008 00 WAT  0   0  4
>   [ 5] .data             PROGBITS        08049100 000100 000004 00  WA  0   0  4
>   [ 6] .bss              NOBITS          08049104 000104 000004 00  WA  0   0  4
>   [ 7] .comment          PROGBITS        00000000 000104 00002b 01  MS  0   0  1
>   [ 8] .note.gnu.gold-ve NOTE            00000000 000130 00001c 00      0   0  4
>   [ 9] .symtab           SYMTAB          00000000 00014c 0000c0 10     10   2  4
>   [10] .strtab           STRTAB          00000000 00020c 00003b 00      0   0  1
>   [11] .shstrtab         STRTAB          00000000 000247 000063 00      0   0  1
> Key to Flags:
>   W (write), A (alloc), X (execute), M (merge), S (strings)
>   I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
>   O (extra OS processing required) o (OS specific), p (processor specific)
> 
I'll fix. I see how they are handling it now. Note that they are still going to get separate LOAD segments currently because we don't have a way to say that .tbss should be ignored in the LOAD segment, but not the TLS segment.

================
Comment at: lib/ReaderWriter/ELF/File.h:211-214
@@ -210,5 +210,6 @@
           c = elfAtomHandler.contentType(*si);
 
-          if (c == DefinedAtom::typeZeroFill)
+          if (c == DefinedAtom::typeZeroFill ||
+              c == DefinedAtom::typeTLVInitialZeroFill)
             isCommon = true;
         }
----------------
Shankar Kalpathi Easwaran wrote:
> Same here commons should be treated seperately.
> 
> $cat t.s
>         .byte 0
>         .tls_common     foo,4,4
>         .globl  a
>         .bss
>         .align 4
>         .type   a, @object
>         .size   a, 4
> a:
>         .zero   4
> 
> $gcc -c t.s
> $readelf -s t.o
> 
> Symbol table '.symtab' contains 6 entries:
>    Num:    Value  Size Type    Bind   Vis      Ndx Name
>      0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
>      1: 00000000     0 SECTION LOCAL  DEFAULT    1
>      2: 00000000     0 SECTION LOCAL  DEFAULT    2
>      3: 00000000     0 SECTION LOCAL  DEFAULT    3
>      4: 00000004     4 TLS     GLOBAL DEFAULT  COM foo
>      5: 00000000     4 OBJECT  GLOBAL DEFAULT    3 a
> 
> Note the difference between foo, a.
We don't really support commons at all currently. I'd like to defer fixing this to a different patch.

================
Comment at: lib/ReaderWriter/ELF/HeaderChunks.h:183-190
@@ +182,10 @@
+  bool allocatedNew = false;
+  for (auto slice : segment->slices()) {
+    // If we have a TLS segment, emit a LOAD first.
+    if (segment->segmentType() == llvm::ELF::PT_TLS) {
+      auto phdr = allocateProgramHeader();
+      if (phdr.second)
+        allocatedNew = true;
+      phdr.first->p_type = llvm::ELF::PT_LOAD;
+      phdr.first->p_offset = slice->fileOffset();
+      phdr.first->p_vaddr = slice->virtualAddr();
----------------
Shankar Kalpathi Easwaran wrote:
> Why is the linker creating a seperate load segment. This is needed only when combining tdata with .data/.bss. Are we doing that ?
> 
> Elf file type is EXEC (Executable file)
> Entry point 0x0
> There are 4 program headers, starting at offset 52
> 
> Program Headers:
>   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
>   LOAD           0x000000 0x08048000 0x08048000 0x000f8 0x000f8 R E 0x1000
>   LOAD           0x0000f8 0x080490f8 0x080490f8 0x0000c 0x00010 RW  0x1000
>   GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0
>   TLS            0x0000f8 0x080490f8 0x080490f8 0x00008 0x00010 R   0x4
> 
>  Section to Segment mapping:
>   Segment Sections...
>    00     .text .eh_frame
>    01     .tdata .data .bss
>    02
>    03     .tdata .tbss
> 
We are not currently combining because we don't have the infrastructure to set it up properly. As the TLS segment is a different fsize and msize than the LOAD segment.

================
Comment at: lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp:73-77
@@ +72,7 @@
+  case R_X86_64_TPOFF32: {
+    // Get the start and end of the TLS segment.
+    auto tdata = _targetInfo.getTargetHandler<X86_64ELFType>().targetLayout()
+        .findOutputSection(".tdata");
+    auto tbss = _targetInfo.getTargetHandler<X86_64ELFType>().targetLayout()
+        .findOutputSection(".tbss");
+    uint64_t tlsStart = 0;
----------------
Shankar Kalpathi Easwaran wrote:
> I didnt see the changes for virtual address. They are all offset from TP right.
> 
> 
For the output symbol table? Right. It's not currently doing that because the infrastructure is not there to do it yet. 


http://llvm-reviews.chandlerc.com/D351



More information about the llvm-commits mailing list