[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