ELF 文件 TLS 和 LOAD 程序部分

发布于 2024-10-01 08:42:57 字数 1382 浏览 5 评论 0原文

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

有人可以解释一下,为什么第二个和第四个程序头确实相交(它们以相同的偏移量 0x079f94 和 VirtAddr 0x080c2f94 开头) )。

此外,段部分 .tdata 被引用两次。

如何为第一个线程(程序本身)加载 PT_TLSPT_LOAD.tbss 位于内存中的什么位置?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我乃一代侩神 2024-10-08 08:42:57

第一个 .tdata 部分 - 是 TLS 数据的“初始图像”。它是 TLS 变量的初始值,将在每个线程(以及主线程)中使用。在 crt (我假设)中,有一个 TLS 初始图像复制到主线程的 TLS 中。相同的代码位于 pthread_create 中。

PT_TLS 未加载,因为 PT_LOAD 已加载,并且 PT_LOAD 已包含此 PT_TLS。我认为 PT_TLS 用于初始图像 - 因为它比整个线程本地数据短( tbss+tdata > size(PT_TLS) )。

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

一花一树开 2024-10-08 08:42:57

就映射内存区域而言,我认为内核只查看 PT_LOAD 段并映射它们。 (内核还会查看 PT_GNU_STACK 以确定堆栈是否应该使用执行权限进行映射。)查看 binfmt_elf.c:load_elf_binary() 以获得相关代码。

libc 读取 PT_TLS 段以找出要设置线程本地存储的内存。查看 __libc_setup_tls() 相关代码。

PT_TLS 段与 PT_LOAD 段相交,以便将其映射到进程内存中。

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.

软糯酥胸 2024-10-08 08:42:57

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 类型的一个或多个部分。)

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文