[hjl@gnu-6 relro-6]$ cat x.cc // This code is put into a shared library linked with -z relro. // i1 and i2 are not relro variables. int i1 = 1; static int i2 = 2; // P1 is a global relro variable. int* const p1 __attribute__ ((aligned(32))) = &i1; // P2 is a local relro variable. int* const p2 __attribute__ ((aligned(32))) = &i2; // Add a TLS variable to make sure -z relro works correctly with TLS. __thread int i3 = 1; __thread char i4[40] = { 1 }; [hjl@gnu-6 relro-6]$ make ./ld.gold -shared -z relro -o libx.so x.o ./strip --strip-debug libx.so -o bar readelf -lSW bar > new.txt readelf -lSW libx.so > old.txt diff -up old.txt new.txt --- old.txt 2013-12-11 12:38:48.674968042 -0800 +++ new.txt 2013-12-11 12:38:48.670968003 -0800 @@ -1,4 +1,4 @@ -There are 14 section headers, starting at offset 0x11d0: +There are 14 section headers, starting at offset 0x10c8: Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al @@ -13,9 +13,9 @@ Section Headers: [ 8] .bss NOBITS 0000000000002004 001004 000000 00 WA 0 0 1 [ 9] .comment PROGBITS 0000000000000000 001004 00002d 01 MS 0 0 1 [10] .note.gnu.gold-version NOTE 0000000000000000 001034 00001c 00 0 0 4 - [11] .symtab SYMTAB 0000000000000000 001050 0000d8 18 12 3 8 - [12] .strtab STRTAB 0000000000000000 001128 000030 00 0 0 1 - [13] .shstrtab STRTAB 0000000000000000 001158 000072 00 0 0 1 + [11] .shstrtab STRTAB 0000000000000000 001050 000072 00 0 0 1 + [12] .symtab SYMTAB 0000000000000000 001448 0001b0 18 13 12 8 + [13] .strtab STRTAB 0000000000000000 0015f8 00002b 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), l (large) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) @@ -32,7 +32,7 @@ Program Headers: LOAD 0x000f20 0x0000000000001f20 0x0000000000001f20 0x0000e4 0x0000e4 RW 0x1000 DYNAMIC 0x000f50 0x0000000000001f50 0x0000000000001f50 0x0000b0 0x0000b0 RW 0x8 GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0 - TLS 0x000f20 0x0000000000001f20 0x0000000000001f20 0x00002c 0x000030 R 0x10 + TLS 0x000f20 0x0000000000001f20 0x0000000000001f20 0x00002c 0x00002c R 0x10 GNU_RELRO 0x000f20 0x0000000000001f20 0x0000000000001f20 0x0000e0 0x0000e0 RW 0x10 Section to Segment mapping: make: *** [all] Error 1 [hjl@gnu-6 relro-6]$ Gold generates [ 5] .tdata PROGBITS 0000000000001f20 000f20 00002c 00 WAT 0 0 16 TLS 0x000f20 0x0000000000001f20 0x0000000000001f20 0x00002c 0x000030 R 0x10 Why is MemSiz > FileSiz?
I tried your test case and got: Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x000188 0x000188 R 0x8 LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000330 0x000330 R E 0x1000 LOAD 0x000ea0 0x0000000000001ea0 0x0000000000001ea0 0x000168 0x000168 RW 0x1000 DYNAMIC 0x000f08 0x0000000000001f08 0x0000000000001f08 0x0000f0 0x0000f0 RW 0x8 GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0 TLS 0x000ea0 0x0000000000001ea0 0x0000000000001ea0 0x00002c 0x00002c R 0x4 GNU_RELRO 0x000ea0 0x0000000000001ea0 0x0000000000001ea0 0x000160 0x000160 RW 0x20 The TLS segment has FileSiz and MemSiz both set to 0x2c.
Created attachment 7561 [details] x86-64 foo.o As of GNU gold (GNU Binutils 2.24.51.20140425) 1.11, I still got: [hjl@gnu-6 pr16320]$ ./ld.gold -shared -z relro -o libx.so foo.o [hjl@gnu-6 pr16320]$ readelf -lW libx.so | grep TLS TLS 0x000f20 0x0000000000001f20 0x0000000000001f20 0x00002c 0x000030 R 0x10 [hjl@gnu-6 pr16320]$
I still got the same result with the uploaded foo.o
In your case, the alignment specified for the TLS segment was 0x10. Gold explicitly pads the TLS segment to a multiple of the alignment.