为何可执行文件中.data.rel.ro段占用大量空间?
问题:共享库中只读大数组导致可执行文件体积异常增大
我在Linux下构建了一个包含大型初始化数组的共享库,原本期望多个可执行文件复用该数组时能减小编译输出体积,但当共享对象中的数据标记为只读时,结果并不符合预期。
目标文件里的tab符号大小为4MiB:
$ nm --print-size bigfile.o 0000000000000000 0000000000400000 R tab
我通过ld创建共享对象:
ld -o libbigfile.so -shared bigfile.o
但执行gcc -o bigfile main.o libbigfile.so链接生成可执行文件后,文件大小达到4MiB,排查发现是.data.rel.ro段导致的:
$ readelf --section-headers bigfile [21] .data.rel.ro PROGBITS 0000000000403dc0 00002dc0 0000000000400000 0000000000000000 WA 0 0 64
用readelf -x .data.rel.ro bigfile查看后发现,这个段的内容全是0x00。既然共享对象的.rodata段内容仅在加载时复制,为什么它会占用可执行文件的磁盘空间,而不是像.bss段那样只在程序加载时分配内存?
复现步骤
我使用了一个简单的main函数:
#include <stdio.h> extern char tab[]; int main() { puts(tab); return 0; }
共享库可以通过C或汇编文件生成,汇编版本的体积更小,代码如下:
global tab:data BYTESIZE BYTESIZE equ (1 << 22) section .rodata align 64 tab: times (BYTESIZE - 2) db 'A' db 0xA db 0x0
完整构建步骤:
nasm -f elf64 bigfile.asm ld -o libbigfile.so -shared bigfile.o gcc -c main.c gcc -o bigfile main.o libbigfile.so
注:如果将tab符号放在.data段,体积异常的问题就会消失。
内容的提问来源于stack exchange,提问作者Paul-Marie Masschelier
相关产品推荐
相关产品推荐

