众所周知,.bss 部分没有存储在磁盘中,但内存中的 .bss 部分应该初始化为零。但它应该在内存中的哪个位置?是否有任何信息显示在 ELF 标头或 .bss 部分是否可能出现在数据部分旁边,或其他内容?
问问题
6317 次
2 回答
15
BSS 位于数据和堆之间,如这篇精彩的文章中所述。
您可以使用以下命令找出每个部分的大小size
:
cnicutar@lemon:~$ size try
text data bss dec hex filename
1108 496 16 1620 654 try
于 2012-05-02T09:21:09.350 回答
12
要知道 bss 段在内存中的位置,运行readelf -S program
并检查行上的Addr列就足够了.bss
。
在大多数情况下,您还会看到已初始化的数据部分 ( .data
) 紧接在前面。也就是说,您将看到该部分的Addr+Size与该.data
部分的起始地址匹配.bss
。
然而,情况并非总是如此。这些是历史惯例,ELF 规范(与平台特定的补充一起阅读,例如涵盖32 位 x86 机器的第 5 章)允许更复杂的配置,但并非所有这些都受 Linux 支持。
例如,该部分可能根本不被调用.bss
。构成 BSS 部分的仅有 2 个属性是:
- 该部分标有
SHT_NOBITS
(即,它在内存中占用空间,但在存储中不占用空间),显示为NOBITS
的readelf
输出。 - 它映射到可加载 (
PT_LOAD
)、可读 (PF_R
) 和可写 (PF_W
) 段。这样的段在存储上也比在内存中短(p_filesz
<p_memsz
)。
您可以有多个 BSS 部分:PowerPC 可执行文件可能有.sbss
未.sbss2
初始化的数据变量。
最后,BSS 部分不一定与数据部分或堆相邻。如果您检查Linux 内核(尤其是load_elf_binary
函数),您可以看到 BSS 部分(或更准确地说,它映射到的段)甚至可能与代码和初始化数据交错。Linux 内核设法解决了这个问题。
于 2012-05-02T12:57:15.353 回答