其他引用:
所以Segment本质是作为一个节簇,使用某种相同的方式加载到内存中的一个整体操作单元。代表的是加载属性。影响的是加载时期的行为。运行时期的行为是节来其主要作用的。
所以还是用中文表达不准确。先看一段说明:参考如下描述:
下面是一个普通c函数编译后的效果:
#include "stdio.h"
int main()
{
printf("haha\n");
return 0;
}
# readelf -l a.out
Elf file type is DYN (Shared object file)
Entry point 0x530
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x00000000000001f8 0x00000000000001f8 R 0x8
INTERP 0x0000000000000238 0x0000000000000238 0x0000000000000238
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000830 0x0000000000000830 R E 0x200000
LOAD 0x0000000000000db8 0x0000000000200db8 0x0000000000200db8
0x0000000000000258 0x0000000000000260 RW 0x200000
DYNAMIC 0x0000000000000dc8 0x0000000000200dc8 0x0000000000200dc8
0x00000000000001f0 0x00000000000001f0 RW 0x8
NOTE 0x0000000000000254 0x0000000000000254 0x0000000000000254
0x0000000000000044 0x0000000000000044 R 0x4
GNU_EH_FRAME 0x00000000000006ec 0x00000000000006ec 0x00000000000006ec
0x000000000000003c 0x000000000000003c R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000000db8 0x0000000000200db8 0x0000000000200db8
0x0000000000000248 0x0000000000000248 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .dynamic .got .data .bss
04 .dynamic
05 .note.ABI-tag .note.gnu.build-id
06 .eh_frame_hdr
07
08 .init_array .fini_array .dynamic .got
ELF文件中程序头对应的就是段Segment,第03个Segment就是我们常说的数据段 data segment。然后数据段包含了 .data节和.bss节。并且.bss 节总是放在 data 段的末尾,这是链接器脚本决定的。
另外所谓的代码段不仅仅不好的是代码,比如.rodata是存储类似printf中的常量字符串,这个看似是数据段的,实际在代码段。
这些都是链接器脚本决定的,一个 ELF 可执行文件,链接器脚本能够决定该输出文件的布局,以及每个段里面包含哪些节。
所以,ELF文件中的段Segment和节Section的区别是什么?平时说的代码段和数据段是Section还是Segment?.bss .data是什么?
Segment是ELF加载到内存时候映射使用的控制属性的单元,是节的集合。影响的是加载期间的行为。(当然加载后段的属性 也会控制安全 比如段错误 而不是节错误)
Section是根据功能组织的程序单元,也是我们平时谈及所谓的"段"(代码段、数据段),真正正的代码段是多个section组合出来的section。影响的运行期间的行为。
是section 节,不是所谓的代码段,或者说他是代码段,但不是所有。是属于代码段。
最后记住readlef -l 是查看程序头的
参考:
https://bbs.kanxue.com/upload/attach/202007/767964_J5AKCEMWBFUQ655.pdf
因篇幅问题不能全部显示,请点此查看更多更全内容