Search code examples
linuxelfglibcthread-local-storage

ELF file TLS and LOAD program sections


int i;
int main() {
     return i;    
}

After -static compile readelf -l shows program headers from elf:

Elf file type is EXEC (Executable file)
Entry point 0xxxxx30
There are 6 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x08048000 0x08048000 0x79868 0x79868 R E 0x1000
 > LOAD           0x079f94 0x080c2f94 0x080c2f94 0x0078c 0x02254 RW  0x1000  <<
  NOTE           0x0000f4 0x080480f4 0x080480f4 0x00020 0x00020 R   0x4
 > TLS            0x079f94 0x080c2f94 0x080c2f94 0x00010 0x0002c R   0x4     <<
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4
  PAX_FLAGS      0x000000 0x00000000 0x00000000 0x00000 0x00000     0x4

 Section to Segment mapping:
  Segment Sections...
   00     .note.ABI-tag .init .text __libc_freeres_fn .fini .rodata __libc_subfreeres __libc_atexit .eh_frame .gcc_except_table
   01     .tdata .ctors .dtors .jcr .data.rel.ro .got .got.plt .data .bss __libc_freeres_ptrs
   02     .note.ABI-tag
   03     .tdata .tbss

Can somebody explain, why the 2nd and 4th program headers does intersect (they begin with same offset 0x079f94 and VirtAddr 0x080c2f94).

Also, the segment section .tdata is referred twice.

How PT_TLS and PT_LOAD will be loaded for first thread (the program itself)? Where does .tbss lie in the memory?


Solution

  • First .tdata section - is an "initial image" of TLS data. It is the initial values of TLS vars, which will be used in every thread (and in main thread too). In the crt (I assume) there is a copying of TLS initial image into TLS of main thread. Same code is in pthread_create.

    PT_TLS is not loaded, because PT_LOAD does and PT_LOAD already contains this PT_TLS. I think that PT_TLS is for initial image - because it is shorter than entire thread-local data ( tbss+tdata > size(PT_TLS) ).