Elf File Tls and Load Program Sections

ELF file TLS and LOAD program sections

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) ).

use program or section headers to load an ELF

The program loader should look at the program header only. The section headers are for tools such as debuggers. I don't think this is spelled out explicitly in the original ELF specification or the System V ABI specification, but it is very much implied:

  • System V Application Binary Interface

Even today, when new features are defined which are used by the dynamic linker, references are added the dynamic to the dynamic section, even though in theory, the information could also be obtained from the section header (but there are probably some exceptions for certain architectures).

Understanding ELF TBSS and TDATA section loading

Although the size of TLS here is 0xb12a. The alignment of 0x8 will make the TLS pointer move to 0xb130 which is the address of variable observed here.

Why ELF program headers have two LOAD entries, while the program layout three sections

I observed the program headers have 2 LOAD entries:

You've omitted an important program header: GNU_RELRO, which tells the loader that after mapping the LOAD segments, it should mprotect part of them as read-only.

When mprotect with different permissions is called on existing mapping, the kernel has to split that mapping into multiple mappings, which is where the extra entry is coming from.

In my test binary:

LOAD           0x000000 0x00000000 0x00000000 0x0075c 0x0075c R E 0x1000
LOAD 0x000ef4 0x00001ef4 0x00001ef4 0x0012c 0x00130 RW 0x1000
...
GNU_RELRO 0x000ef4 0x00001ef4 0x00001ef4 0x0010c 0x0010c R 0x1

The kernel actually maps the LOAD segments before the loader even starts, and the map at that point looks like this:

56555000-56556000 r-xp 00000000 fc:02 801500 /tmp/a.out
56556000-56558000 rw-p 00000000 fc:02 801500 /tmp/a.out
f7fdb000-f7fdc000 r-xp 00000000 00:00 0 [vdso]
...

After the mprotect, the map looks like this:

56555000-56556000 r-xp 00000000 fc:02 801500 /tmp/a.out
56556000-56557000 r--p 00000000 fc:02 801500 /tmp/a.out
56557000-56558000 rw-p 00001000 fc:02 801500 /tmp/a.out
...


Related Topics



Leave a reply



Submit