首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么.bss部分映射到比对象文件中报告的bss更小的进程?

为什么.bss部分映射到比对象文件中报告的bss更小的进程?
EN

Stack Overflow用户
提问于 2014-08-12 21:45:18
回答 1查看 803关注 0票数 3

我总是认为链接器分配了任何库的bss部分,并将其映射到进程中。本节的大小将取决于图书馆报告的bss的大小。

我查看了进程的/proc/PID/map文件,并计算了加载库的bss部分的大小。

代码语言:javascript
复制
7f1f5561f000-7f1f55637000 r-xp 00000000 08:01 3018048          /usr/lib/libpthread-2.19.so
7f1f55637000-7f1f55837000 ---p 00018000 08:01 3018048          /usr/lib/libpthread-2.19.so
7f1f55837000-7f1f55838000 r--p 00018000 08:01 3018048          /usr/lib/libpthread-2.19.so
7f1f55838000-7f1f55839000 rw-p 00019000 08:01 3018048          /usr/lib/libpthread-2.19.so
7f1f55839000-7f1f5583d000 rw-p 00000000 00:00 0 
7f1f5583d000-7f1f55851000 r-xp 00000000 08:01 3017945          /usr/lib/libresolv-2.19.so
7f1f55851000-7f1f55a50000 ---p 00014000 08:01 3017945          /usr/lib/libresolv-2.19.so
7f1f55a50000-7f1f55a51000 r--p 00013000 08:01 3017945          /usr/lib/libresolv-2.19.so
7f1f55a51000-7f1f55a52000 rw-p 00014000 08:01 3017945          /usr/lib/libresolv-2.19.so
7f1f55a52000-7f1f55a54000 rw-p 00000000 00:00 0 

在这里,我们可以看到size线程的bss位于地址范围7f1f55839000-7f1f5583d000,减去它们我们得到的大小为16384字节

使用size命令或readelf,size线程的bss部分的大小为16848字节。

这是有道理的,因为虚拟地址范围需要排列到页面边界,但虚拟大小如何能够比精灵文件报告的更小的?没有足够的空间来容纳所有的变量。

链接器是否能够确定bss中的某些变量对于特定的加载可执行文件来说并不是必需的?如果是的话,是如何做到的?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-21 23:21:15

在这里,我们可以看到size线程的bss在地址范围7f1f55839000-7f1f5583d000,减去它们就得到了16384字节的大小。

困难的根源在于陈述并不完全准确。ELF链接器和Linux加载程序实际上并不保证节、段和映射之间的一对一关系。结果是,突出显示的映射实际上并不代表所有的.bss (正如您已经发现的)。

通常,使用默认链接器脚本的ELF链接器将创建两个LOAD段:一个R/E (用于文本和只读数据)和一个R/W (用于可写数据,包括.bss)。它将安排.bss出现在段的末尾,这样它就可以将关联的精灵程序头 p_filesz设置为只覆盖初始化的数据,同时将p_memsz设置为更大的值,以便为.bss添加足够的空间。

当加载程序处理此段时,它将创建一个或两个映射。第一个映射将是p_offsetp_filesz提供的“文件支持”。因此,初始访问上的页面错误将保证所需的初始值。在第一次映射的最后一页中留下的任何空间都将是memset到零(访问本身在任何初始化值中都有第一个错误)。如果剩余的p_memsz符合新的零填充空间,那么加载程序就只需要这样做了。否则,如果需要更多的空间,加载程序将创建一个匿名映射(由/dev/zero支持)以覆盖其余部分。

因此,内存中.bss的大小实际上是第二个匿名映射和前面映射的“尾部”之和。获得内存中.bss的估计的最简单方法(在链接器、加载程序和内核根据各种适用的ELF、POSIX和Linux标准应用的各种对齐约束范围内)可能是使用例如readelf --program-headers来获得适用段的p_fileszp_memsz,并从后者中减去前者。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25274569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档