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

问题描述 投票:0回答:2

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

感谢您的帮助!

c operating-system elf
2个回答
5
投票

快速响应是:嗯,没有内容可以填充

.bss
,因此在与该部分相关的可执行文件上放置任何数据是没有意义的。仅存储变量的位置,但这属于另一个 ELF 部分。

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

加载程序时,内核通常会为程序的不可修改文本分配一个只读段(

.text
部分),并在该段中放入初始化的
const
变量的内容(
.rodata
部分)因此,如果您尝试修改其中的某些内容,则会出现异常。然后是初始化数据部分,其中包含程序中所有已初始化变量的初始值(
.data
部分)和未初始化变量(
.bss
部分)

数据段(看看我如何称呼不同的部分和负载段)被给予更多的空间,即

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

此行为的历史(也是主要原因)原因是,出于安全原因,内核分配的必须与您的程序一起加载的页面被清除为零(因此您无法幸运地获得充满其他用户密码的页面,或者其他敏感信息),因此没有理由再次用零填充它,并且不需要在那里复制任何内容,没有理由在可执行文件上放置任何内容。内核通常维护的页面仅在将要提供给用户时才清零,但会维护(因为它们是为此目的而设计的)信息,直到它们被覆盖。


3
投票

BSS(由符号开始的块)部分没有任何内容,因为这会浪费存储空间。 BSS 的内容全为零,并且在调用

main
之前由启动代码清除。将 BSS 视为运行长度压缩的字节块。要解压缩该块,您需要知道的只是值 (0) 和长度,该值存储在 BSS 的 ELF 条目中。

您的“已初始化但尚未使用的数据”的概念有点偏离。考虑一下 ELF 文件中的all部分在某种程度上“尚未使用”。文本段可能会也可能不会被使用(它可能包含死/无法访问的代码)。数据段可能会被使用,也可能根本不会被使用(您可以定义代码从未使用过的对象)。

© www.soinside.com 2019 - 2024. All rights reserved.