【问题标题】:How do global variables get initialized by the elf loaderelf加载器如何初始化全局变量
【发布时间】:2011-02-08 14:40:06
【问题描述】:

对于像 C 语言中的全局变量

int aglobal = 5;

加载器何时将 5 转移到 aglobal 中,如何知道将 5 放入 aglobal 中。

函数中的静态声明也是如此。喜欢

int afunc() { 静态 int astatic = 8; 返回非静态; }

【问题讨论】:

    标签: initialization global elf


    【解决方案1】:

    在数据段中创建了一个 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个字节的实际地址已知,所以直接指定

    【讨论】:

    • 感谢您的帮助。如果我错了,请纠正我......因此,如果在我的代码中读取或写入 aglobal ,它正在访问 .data 部分。 .data 部分由加载程序将 .data 部分从 elf 文件复制到内存进行初始化。
    • 对,数据部分和文本部分一样被加载到内存中(但通常它是不可执行的,文本是不可写的,以防止漏洞利用)。在链接时,确定数据部分中特定单词的位置,并且所有引用它的指令(它们将具有名称为“aglobal”的重定位)固定为指向该偏移量。加载器需要做的就是将整个图像从它的基地址转移到它在内存中实际加载的地址(很多图像的基地址都是 0,所以它只是添加了起始内存地址)
    • 谢谢。感谢 Mike 的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-07
    • 2021-11-14
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多