19

作为尝试完全从头开始编写编译器的一部分,我目前正在处理处理 ELF 文件的部分。

在浏览了几篇关于它们的文章和规范之后,我仍然不太明白节到段映射的存储位置。在观察由 NASM+ld 生成的小型可执行文件时,我可以看到 .text 部分以某种方式映射到 LOAD 类型的程序头,但是如何?

当给定一个小的(工作的)可执行文件作为输入时,一小段 readelf 的输出:

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x0000000000000084 0x0000000000000084  R E    200000

 Section to Segment mapping:
  Segment Sections...
   00     .text 

这个映射甚至需要有一个工作的可执行文件吗?还是可以完全省略它们而您仍然有一个有效的可执行文件?

4

2 回答 2

28

我仍然不太明白节到段映射的存储位置。

它们存储在任何地方。

相反,readelf通过查看文件偏移量以及节和段的大小来计算映射。

于 2014-04-12T16:05:28.857 回答
3

我根据@Employed 俄语做了一个测试。

readelf -l ./libandroid_servers.so

Elf file type is DYN (Shared object file)
Entry point 0x0
There are 6 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00000034 0x00000034 0x000c0 0x000c0 R   0x4
  LOAD           0x000000 0x00000000 0x00000000 0x0f830 0x0f830 R E 0x1000
  LOAD           0x010000 0x00010000 0x00010000 0x00cf4 0x011ac RW  0x1000
  DYNAMIC        0x010540 0x00010540 0x00010540 0x00130 0x00130 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0
  EXIDX          0x00f2e8 0x0000f2e8 0x0000f2e8 0x00548 0x00548 R   0x4

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .hash .dynsym .dynstr .rel.plt .rel.dyn .plt .text .rodata .ARM.extab .ARM.exidx 
   02     .init_array .fini_array .data.rel.ro .dynamic .got .data .bss 
   03     .dynamic 
   04     
   05     .ARM.exidx 

01 LOAD offset: 0x000000 fileSize 0x0f830
.ARM.exidx section end addr: hex(0x00f2e8 + 0x00548) = 0xf830

02 LOAD offset: 0x010000 fileSize: 0x00cf4
.init_array section begin addr: 10000h
.bss section end addr: hex(0x00f2e8 + 0 ) = 0x10cf4

readelf会看到通过计算确定打印段中的部分。他们匹配得很好。

于 2018-09-12T18:15:49.533 回答