ELF-файл TLS и разделы программы LOAD

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

После -static компиляции readelf -l показывает заголовки программы из 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

Может кто-нибудь объяснить, почему 2-й и 4-й заголовки программы пересекаются (они начинаются с одинакового смещения 0x079f94 и VirtAddr 0x080c2f94).

Кроме того, раздел сегмента .tdata упоминается дважды.

Как PT_TLS и PT_LOAD будут загружены для первого потока (сама программа)? Где в памяти лежит .tbss?


person osgx    schedule 08.11.2010    source источник
comment
похоже, что tls помещен в HEAP...   -  person osgx    schedule 17.12.2010
comment
Вы можете проверить, как загружается TLS, с помощью strace grepping для системного вызова set_thread_area.   -  person osgx    schedule 17.12.2010


Ответы (3)


Первая секция .tdata — это «исходный образ» данных TLS. Это начальные значения переменных TLS, которые будут использоваться в каждом потоке (и в основном потоке тоже). В crt (я предполагаю) происходит копирование исходного образа TLS в TLS основного потока. Тот же код находится в pthread_create.

PT_TLS не загружен, потому что загружается PT_LOAD, а PT_LOAD уже содержит этот PT_TLS. Я думаю, что PT_TLS предназначен для исходного изображения, потому что он короче, чем все локальные данные потока ( tbss+tdata > size(PT_TLS) ).

person osgx    schedule 17.02.2011

Что касается отображения областей памяти, я думаю, что ядро ​​​​просматривает только сегменты PT_LOAD и отображает их. (ядро также просматривает PT_GNU_STACK, чтобы выяснить, должен ли стек отображаться с разрешением Execute или нет.) Посмотрите соответствующий код в binfmt_elf.c:load_elf_binary().

Сегмент PT_TLS считывается libc, чтобы определить память для настройки хранилища Thread-Local. Посмотрите __libc_setup_tls() для соответствующего кода.

Сегмент PT_TLS пересекается с сегментом PT_LOAD, поэтому он отображается в памяти процесса.

person javed    schedule 05.01.2013

TLS означает «локальное хранилище потока».

Чтобы разрешить ассоциацию отдельных копий данных, выделенных во время компиляции, с отдельными потоками выполнения, можно использовать разделы локального хранилища потока для указания размера и начального содержимого таких данных. Реализации не должны поддерживать локальное хранилище потока. Запись программы PT_TLS имеет следующие элементы:

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

Шаблон TLS формируется из объединения всех секций с флагом SHF_TLS. Часть шаблона TLS, которая содержит инициализированные данные, — это образ инициализации TLS. (Оставшаяся часть шаблона TLS — это один или несколько разделов типа SHT_NOBITS.)

person asdf    schedule 22.05.2011
comment
в порядке. но как PT_TLS и PT_LOAD будут загружены для первого потока (сама программа)? это вопрос. - person osgx; 22.05.2011