Compiler construction “在哪里?”;“节到段映射”;存储在ELF文件中?

Compiler construction “在哪里?”;“节到段映射”;存储在ELF文件中?,compiler-construction,elf,readelf,Compiler Construction,Elf,Readelf,作为完全从头开始编写编译器的一部分,我目前正在处理ELF文件的部分 在浏览了几篇关于它们的文章和规范之后,我仍然不太明白节到段映射存储在哪里。 当观察NASM+ld生成的小可执行文件时,我可以看到.text部分以某种方式映射到加载类型的程序头上,但是如何映射呢 当给定一个小的(工作的)可执行文件作为输入时,readelf的一小段输出: Program Headers: Type Offset VirtAddr PhysAddr

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

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

当给定一个小的(工作的)可执行文件作为输入时,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 
这个映射是否需要有一个工作的可执行文件?或者可以完全忽略它们,而您仍然拥有一个有效的可执行文件

我仍然不太明白节到段映射存储在哪里

它们没有存放在任何地方


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

我根据@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加载偏移量:0x000000文件大小0x0f830
.ARM.exidx段端地址:十六进制(0x00f2e8+0x00548)=0xf830

02加载偏移量:0x010000文件大小:0x00cf4
.init_数组段开始地址:10000h
.bss段端地址:十六进制(0x00f2e8+0)=0x10cf4


您可以看到
readelf
确实可以通过计算打印段中的部分。它们匹配得很好。

文件偏移量,就是这样!我认为这与相等的虚拟内存地址有关。谢谢,它可以工作。你的意思是:如果可执行文件包含可选的节头表,那么该表将指向包含节的段的中间,是吗?@CiroSantilli巴拿馬文件六四事件法轮功 如果节头不存在,则
readelf
将不会生成“节到段映射”输出。如何确定是否有节头?这是readelf-S吗?如果它给出了一个输出,那么您有一个节标题表?在注释中,它作为“可选”部分标题给出,这意味着只有一个标题存在。您是指节头数组吗?@Har U可以找到带有
readelf--sections--wide a.out
的节,请注意节头是可选的,可能根本不存在。节仅在链接期间可用。段在执行期间可用。段基本上只是大块的数据,即多个段一起淬火成相应的段。通过段到段的映射,您可以看到哪些节位于哪个节中