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

Shankar Kalpathi Easwaran shankarke at gmail.com
Wed Jan 30 07:15:04 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,
----------------
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)


================
Comment at: lib/ReaderWriter/ELF/Atoms.h:265-266
@@ -258,4 +264,4 @@
 
     if (_symbol->st_shndx == llvm::ELF::SHN_COMMON)
       return typeZeroFill;
 
----------------
The way we are dealing with commons is wrong, We have to differentiate commons from BSS.

BSS symbols are part of a section while commons are not part of any.

================
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;
         }
----------------
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.

================
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();
----------------
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


================
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;
----------------
I didnt see the changes for virtual address. They are all offset from TP right.




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



More information about the llvm-commits mailing list