You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何edata减去etext的值无法得到正确的文本段大小?

问题描述

测试代码

#include <stdio.h>

extern char etext, edata, end;

int main(int argc, char* argv[], char* envp[]) {
    printf("TEXT END: %p\n", &etext);
    printf("DATA END: %p\n", &edata);
    printf("PROG BRK: %p\n", &end);

    register long volatile sp asm("rsp");
    printf("STCK PTR: %p\n", sp);

    return 0;
}

运行输出

TEXT END: 0x5565d48661d5
DATA END: 0x5565d4869018
PROG BRK: 0x5565d4869020
STCK PTR: 0x7fff8f6f34d0

疑问

原本认为text段、data段和bss段在内存中连续排布,彼此无间隔。但计算(&edata - &etext)得到的结果为0x2e43,而执行size -x a.out命令得到的data段大小仅为0x250,请问这种差异的原因是什么?

环境:gcc 12.2.0、Linux x86_64 5.19.9


原因分析
  • &etext到&edata的跨度包含多段内容:
    etext标记text段(代码段)的结束地址,但text段之后并非直接是data段。在ELF可执行文件的内存布局中,text段结束后会依次包含只读数据段(.rodata)、动态链接相关段(如.interp、.dynsym、.dynstr、.gnu.hash)、注释段(.comment)等辅助段,这些段都会占用内存空间,直到data段结束的edata地址。

  • size命令的统计范围有限:
    size -x a.out输出的data值,仅统计**已初始化数据段(.data)**的大小,不包含text段与data段之间的其他只读/辅助段。而&edata - &etext计算的是从text段结束到data段结束的总内存跨度,包含了中间所有额外段的空间,因此数值远大于size给出的data段大小。

  • 内存对齐的额外填充:
    ELF文件加载到内存时,每个段会按照系统要求的对齐规则(x86_64下通常为4KB页对齐)分配内存,段与段之间可能会因对齐要求产生填充空间,这也会进一步拉大两者的数值差异。


内容的提问来源于stack exchange,提问作者ZarakshR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 22:30:48