作为尝试从头开始编写编译器的一部分,我目前正处理处理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
这个映射是否需要具有可运行的可执行文件?或者它们可以完全省略,你仍然有一个有效的可执行文件吗?
答案 0 :(得分:18)
我仍然不太明白存储段映射的部分。
他们不存储在任何地方。
相反,readelf
通过查看文件偏移量和节和段的大小来计算映射。
答案 1 :(得分:1)
我根据@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偏移量:0x000000文件大小0x0f830
.ARM.exidx部分结束地址:hex(0x00f2e8 + 0x00548)= 0xf830
02 LOAD偏移量:0x010000文件大小:0x00cf4
.init_array节开始地址:10000h
.bss段结尾地址:hex(0x00f2e8 + 0)= 0x10cf4
您看到readelf
肯定会通过计算将分段中的部分打印出来。它们匹配得很好。