全局变量如何被ELF加载器初始化

7

对于C语言中的全局变量,例如

int aglobal = 5;

5何时被加载器传送到aglobal中,它如何知道将5放入aglobal中。

同样的情况也出现在函数内的静态声明中。例如:

int afunc() { static int astatic = 8; return astatic; }

1个回答

7
在数据段中创建一个int大小的空间,将值5编码在其中,并添加一个名为“aglobal”的全局非函数符号指向它。对aglobal的引用被转换为重定位,在链接时解析为指向该数据块,因此在完全链接的映像中,指令将直接从内存中保存5值的位置加载。
例如,(x86)汇编代码可能如下所示:
.data
.globl aglobal
aglobal: .long 5

.text
main:
    mov eax, aglobal

在目标文件中,mov指令将变成mov eax, 0,并带有一个重定位R_386_32 aglobal+0,因为目标文件无法确定数据段在内存中的确切位置。
在完全链接的映像中,可能会是这样的:
mov eax, 0x804a010

现在已知数据段中4个字节的实际地址,因此可以直接指定


谢谢,这很有帮助。如果我在代码中读取或写入全局变量,那么它将访问.data节。.data节由加载器从elf文件复制到内存中进行初始化。请纠正我如果我错了... - newguy
数据段和文本段一样被加载到内存中(但通常情况下,它是不可执行的,而文本是不可写的,以防止攻击)。在连接时,确定数据段中特定单词的位置,并修正所有引用它的指令(它们将具有名称为“aglobal”的重定位)以指向该偏移量。所有加载器需要做的就是将整个映像从其基址移动到实际在内存中加载的地址(许多映像的基地址为0,因此只需添加起始内存地址)。 - Michael Mrozek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接