- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我一直假设链接器分配了任何库的 bss 部分并将其映射到进程中。该部分的大小将取决于库报告的 bss 的大小。
我查看了进程的/proc/[PID]/maps 文件,并计算了加载库的 bss 部分的大小。
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
这里我们可以看到 libpthread 的 bss 在地址范围 7f1f55839000-7f1f5583d000 中减去它们得到的大小为 16384 字节。
使用size
命令或readelf,libpthread的bss段大小为16848字节。
它们的不同是有道理的,因为虚拟地址范围需要与页面边界对齐,但虚拟大小如何小于 elf 文件报告的大小?没有足够的空间来容纳所有变量。
链接器是否能够确定 bss 中的某些变量对于特定的加载可执行文件不是必需的?如果是这样,这是如何完成的?
最佳答案
Here we can see that the bss of libpthread is in the address range 7f1f55839000-7f1f5583d000 and subtracting them gives us a size of 16384 bytes.
困难在于陈述并不完全准确。 ELF 链接器和 Linux 加载器实际上不保证节、段和映射之间的一对一关系。结果是突出显示的映射实际上并不代表 .bss
的所有(如您所见)。
通常使用默认链接器脚本的 ELF 链接器会创建两个 LOAD
段:一个 R/E(用于文本和只读数据)和一个 R/W(用于可写数据,包括.bss
)。它将安排 .bss
出现在段的末尾,以便它可以设置关联的 ELF program header p_filesz
仅覆盖初始化数据,同时将 p_memsz
设置为更大的值以为 .bss
添加足够的空间。
当加载器处理这个段时,它会创建一个或两个映射。第一个映射将从 p_offset
为 p_filesz
“支持文件”。因此,初始访问时的页面错误将保证必要的初始值。第一个映射的最后一页中剩余的任何空间都将 memset
设置为零(访问本身首先在任何初始化值中出错)。如果剩余的 p_memsz
适合新填充的零空间,那么这就是加载程序需要做的全部。否则,如果需要更多空间,加载程序将创建一个匿名映射(由 /dev/zero
支持)来覆盖剩余空间。
因此,.bss
在内存中的大小实际上是第二个匿名映射和前一个映射的“尾部”之和。可能是估计内存中 .bss
的最简单方法(在链接器、加载器和内核根据各种适用的 ELF、POSIX 和 Linux 标准应用的各种对齐约束内)正在使用 e.g. readelf --program-headers
获取适用段的 p_filesz
和 p_memsz
并减去前者来自后者。
关于linux - 为什么 .bss 部分映射到一个比目标文件中报告的 bss 更小的进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25274569/
我一直假设链接器分配了任何库的 bss 部分并将其映射到进程中。该部分的大小将取决于库报告的 bss 的大小。 我查看了进程的/proc/[PID]/maps 文件,并计算了加载库的 bss 部分的大
这个问题已经有答案了: No .BSS in PE file (2 个回答) 已关闭 6 年前。 我使用 NASM 组装了以下代码: global _start section .data v
我正在编写一些适用于 .o 文件的自定义 ELF 二进制后处理代码。部分处理包括对二进制数据执行重定位。输入文件由 GNU 汇编程序根据我自己的汇编代码生成。 看看 GNU 汇编程序生成的这些疯狂的重
“.bss”命令在 MSP430 汇编代码中起什么作用?例如,“.bss beep_cnt,2”对变量 beep_cnt2 有何作用? .bss beep_cnt,2
我知道 BSS 段存储未初始化的全局和静态变量并将它们初始化为零。但是如果全局/静态变量被初始化并且我的第二个问题是我读到 BSS 段不消耗内存,那么它存储这些变量的位置呢?谢谢 最佳答案 您可能读到
我一直在研究减少应用程序的内存占用。继上一个问题后:GDB - can I find large data elements in memory我已经找到并删除了大多数最大的罪魁祸首。 nm --si
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: .bss section in elf file 你好, BSS(Block started by symb
这个问题在这里已经有了答案: Why is the .bss segment required? (6 个答案) 关闭 4 年前。 .bss 部分的意义是什么,因为我们已经有单独的数据部分。它比数据
这个问题在这里已经有了答案: Why is the .bss segment required? (6 个答案) 关闭 6 年前。 在C编程中,当一个程序执行时,程序中使用的所有数据都会被放在不同的
这是简短的控制台应用程序示例 static char buffer[4096]; int main() { for(int i=0;i<4096;i++) { buffer[i
正如我们所知,.bss 包含未初始化的变量。如果在 C 代码中,程序员在使用它们之前初始化变量。那么在执行 C 代码之前.bss 不必为零。 我说得对吗? 谢谢 最佳答案 在 C 代码中,任何具有静态
我正在使用一个测试程序来了解内核版本为 2.6.32-279.el6.x86_64 的 linux 6.3 上的 C 内存模型。 首先我编译了下面的代码, #include int main(voi
我想在编译时声明我的 C 程序中的所有变量,例如: char cache[CACHE_SIZE]; char udp_ring[MAX_UDP_PACKET_SIZE*MAX_REQUESTS]; i
我知道 .bss 的默认对齐方式对于 GCC 是 8 字节,正如这个问题中提到的 Why the int type takes up 8 bytes in BSS section but 4 byte
我有一个功能: void testfunction() { static char_t theChar1 = 1; static unsigned char smallArray[1]; sta
据我所知,如果设置了 -fzero-initialized-in-bss,则未明确初始化的静态变量(并且对于 GCC,即使是那些明确初始化为零的变量,默认情况下就是这种情况)通常存储在 BSS 段中。
静态内存布局的 BSS 部分 [应该] 用于“未初始化的全局变量”或“设置为 0 的全局变量”。 我正在运行一些测试,突然注意到局部静态变量也在增加 BSS 段的大小。 例子:- 在任何静态变量之前
静态内存布局的 BSS 部分 [应该] 用于“未初始化的全局变量”或“设置为 0 的全局变量”。 我正在运行一些测试,突然注意到局部静态变量也在增加 BSS 段的大小。 例子:- 在任何静态变量之前
我正在学习虚拟内存管理和进程内存分配。并对此做一些实验。有以下一些容易混淆的地方: 案例1 #include int main() { return 0; } 编译代码并使用二进制文件运行
希望有人能帮助我了解我在大学学习的一个漏洞。 在c代码中有一个未绑定(bind)的strcat strcat(buffer, argv[1]); 目的是将该缓冲区溢出到保存的 EIP 中,并让它显示在
我是一名优秀的程序员,十分优秀!