[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