为什么对象(ELF)文件中没有.bss部分的内容?

时间:2018-02-23 18:20:17

标签: c operating-system elf

这个问题让我很困惑。据我所知,.bss部分用于保存已初始化但尚未使用的数据。但是我不明白什么是内容'这里的意思是为什么这里没有内容?

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

BSS(符号由符号启动)部分中没有内容,因为它会浪费存储空间。 BSS的内容全为零,在调用main之前由启动代码清除。将BSS视为行程压缩的字节块。解压缩该块需要知道的是值(0)和长度,它存储在BSS的ELF条目中。

你的“初始化但尚未使用的数据”的概念有点过时了。考虑到ELF文件中的所有部分以某种方式“尚未使用”。文本段可能会或可能不会被使用(它可能包含死/无法访问的代码)。可以使用或不使用数据段(您可以定义代码从不使用的对象)。

答案 1 :(得分:2)

快速响应是:嗯,没有内容可以填充.bss,因此将可执行文件中的任何数据放入该部分是没有意义的。仅存储变量的位置,但属于另一个ELF部分。

.bss部分是您的程序具有所有未初始化变量的位置(默认情况下全部初始化为零)链接器只需要知道该区域的实际大小和实际变量位置,而不是值,因为它的内容是显而易见的,与变量的性质或分布无关。

加载程序时,内核通常会为程序的不可修改文本(.text部分)分配一个只读段,并在该段中放入已初始化的const变量的内容(.rodata部分)所以如果你试图修改那里的东西,你会得到一个例外。然后是初始化数据部分,其中包含程序的所有初始化变量(.data部分)和未初始化变量(.bss部分)的初始值

数据段(看我如何称之为不同的部分和加载段)被赋予更多空间,即.data.bss部分的总和,以容纳所有变量(两者都包括在内,这就是它使用其长度的原因)但是虽然必须从文件中填充.data部分的内容,但.bss部分的内容却没有,因为所有部分都被操作归零系统,在允许用户进程访问分配的段之前。对于小型系统来说并非如此,操作系统不会用零填充数据......但是,编译器会添加一些代码以将所有.bss段都归零,所以再次,不需要复制任何来自可执行文件的数据。

此行为的历史(和主要)原因是内核分配必须加载程序的页面出于安全原因被清除为零(因此您不能幸运地获得一个充满其他用户密码的页面,或其他明智的信息)所以没有理由再次用零填充它,没有什么必须在那里复制,没有理由在可执行文件上放任何东西。内核正常维护的页面仅在将它们提供给用户时才归零,但在被覆盖之前维护(因为它们是为此目的设计的)信息。