[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