2010-11-08 4 views
4
int i; 
int main() { 
    return i;  
} 

После -static компилировать заголовки readelf -l шоу программы из эльфа:ELF файл TLS и программа НАГРУЗКИ секция

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 

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

Кроме того, сегментная секция .tdata относится дважды.

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

+0

выглядит как tls, размещенный на HEAP ... – osgx

+0

Вы можете проверить, как TLS загружается strace grepping для ssetall_set_area' – osgx

ответ

3

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

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

2

TLS означает «Thread-Local Storage».

Чтобы разрешить объединение отдельных копий данных, выделенных во время компиляции, с отдельными потоками выполнения, секторы локального хранения потоков могут использоваться для указания размера и начального содержимого таких данных. Реализации не должны поддерживать локальное хранилище потоков. Запись 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.)

+0

ok. но «Как PT_TLS и PT_LOAD будут загружены для первого потока (сама программа)?» это вопрос. – osgx

2

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

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

Сегмент PT_TLS пересекает сегмент PT_LOAD, чтобы он отображался в память процесса.