搜索
您的当前位置:首页正文

【1000个Linux内存知识-007】-ELF文件中的段Segment和节Section的区别是什么?代码段和数据段是段还是节?.bss .data是什么?【readlef -l】

来源:好走旅游网

基础意思

  • Segment 段,不是指平时所说的代码段,数据段。在ELF格式里面,他表示某一块具有相同属性的节的集合,所谓属性主要是可读、可写、可执行等。比如可读可执行段
  • Section 节,比如.data .bss叫做节 其实不是段

其他引用:

所以Segment本质是作为一个节簇,使用某种相同的方式加载到内存中的一个整体操作单元。代表的是加载属性。影响的是加载时期的行为。运行时期的行为是节来其主要作用的。

参考描述

所以还是用中文表达不准确。先看一段说明:参考如下描述:

实操例子

下面是一个普通c函数编译后的效果:

c语言:

#include "stdio.h"
int main()
{
	printf("haha\n");
	return 0;
}

二进制程序头 readelf -l

# 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。影响的运行期间的行为。

  1. 平时说的代码段和数据段是Section还是Segment?
  1. .bss .data是什么?

是section 节,不是所谓的代码段,或者说他是代码段,但不是所有。是属于代码段。
最后记住readlef -l 是查看程序头的

参考:
https://bbs.kanxue.com/upload/attach/202007/767964_J5AKCEMWBFUQ655.pdf

因篇幅问题不能全部显示,请点此查看更多更全内容

Top