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?
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) ).
As far as mapping memory regions are concerned, I think the kernel only looks at PT_LOAD segments and mmaps them. (kernel also looks at PT_GNU_STACK to figure out if stack should be mapped with Execute permission or not.) Have a look at binfmt_elf.c:load_elf_binary() for relevant code.
PT_TLS segment is read by libc to figure out memory to be setup of Thread-Local storage. Have a look at __libc_setup_tls() for relevant code.
PT_TLS segment intersects with the PT_LOAD segment so that it gets mapped into the process memory.
TLS stands for "Thread-Local Storage".
To permit association of separate copies of data allocated at compile-time with individual threads of execution, thread-local storage sections can be used to specify the size and initial contents of such data. Implementations need not support thread-local storage. A PT_TLS program entry has the following members:
Member Value
p_offset File offset of the TLS initialization image
p_vaddr Virtual memory address of the TLS initialization image
p_paddr reserved
p_filesz Size of the TLS initialization image
p_memsz Total size of the TLS template
p_flags PF_R
p_align Alignment of the TLS template
The TLS template is formed from the combination of all sections with the flag SHF_TLS. The portion of the TLS template that holds initialized data is the TLS initialization image. (The remaining portion of the TLS template is one or more sections of type SHT_NOBITS.)