4
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 は 2 回参照されます。

最初のスレッド (プログラム自体) にどのようPT_TLSにロードされますか? 記憶のPT_LOADどこにある?.tbss

4

3 に答える 3

3

メモリ領域のマッピングに関する限り、カーネルは PT_LOAD セグメントのみを見て、それらを mmap すると思います。(カーネルは PT_GNU_STACK も参照して、スタックを実行許可でマップする必要があるかどうかを判断します。) 関連するコードについては、binfmt_elf.c:load_elf_binary() を参照してください。

PT_TLS セグメントは libc によって読み取られ、スレッド ローカル ストレージの設定対象となるメモリが特定されます。関連するコードについては、__libc_setup_tls() を参照してください。

PT_TLS セグメントは、プロセス メモリにマップされるように PT_LOAD セグメントと交差します。

于 2013-01-05T15:30:30.527 に答える
3

最初.tdataのセクション - TLS データの「初期イメージ」です。これは、すべてのスレッド (およびメイン スレッドでも) で使用される TLS 変数の初期値です。(私が推測する) には、crtTLS の初期イメージがメイン スレッドの TLS にコピーされます。に同じコードがありpthread_createます。

PT_LOAD はロードされ、PT_LOAD には既にこの PT_TLS が含まれているため、PT_TLS はロードされません。PT_TLS は初期イメージ用だと思います-スレッドローカルデータ全体よりも短いためです( tbss+tdata > size(PT_TLS) )。

于 2011-02-17T03:34:07.300 に答える
1

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 の 1 つ以上のセクションです。)

于 2011-05-22T12:42:44.987 に答える