链接和加载:符号解析和地址定位的过程

本文详细解析了如何在编译后的目标文件中确定特定变量的地址,通过重定位表和符号表的联合使用,以及如何修正地址以适应运行时环境。通过具体代码示例,展示了整个过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 如何确定符号所对应的地址?

  先看如下一段代码simpleSection.c,对于这段代码的问题是,如果定位到global_init_var2,  global_init_var3 的地址呢?

int printf(const char* fromat, ...);

int global_init_var = 84;
int global_init_var2 = 85;
int global_init_var3 = 86;
int global_uninit_var;

void func1(int i)
{
        printf("%d\n", i);
}

int main(void)
{
        static int static_var = 85;
        static int static_var2;
        global_init_var2 = 40;
        global_init_var3 = 50;
        int a = 1;
        int b = 1;
        func1(static_var + static_var2 + a + b);
        return a + b;
}

gcc  -c simpleSection.c,  编译完成后用 objdump -s -d  simpleSection.o  查看生成的.o文件

 

 

这两行对应的分别是global_init_var2 = 40; global_init_var3 = 50; 绿色的 00000000 是虚拟地址,需要进行重定位。那么如何确认这里操作的是global_init_var2, global_init_va3 呢? 这里先给出答案  从重定位表和符号表中共同确定,下面给出确定过程,我们先用 readelf -a simpleSection.o 查看重定位表

绿色框中的0x2b, 0x35 正是.text 段(第二张图)中movl   $0x28,0x0(%rip), movl   $0x32,0x0(%rip) 的起始地址,接下来再看Sys.value 中对应的值,这两项值是符号表中的index , 下面用 objdump -t simpleSection.o 来查看证明

我们再看.data 段对应的第2,第3项的值,的确是85,86 ,正是 global_init_var2, global_init_var3 

 

二 地址的修正

我们执行 gcc simpleSection.c -o simpleSection 生成elf 可执行文件,用 objdump -s -d simpleSection 查看下 main()函数对应的汇编语言

同simpleSection.o 对应的main()函数来比对,可以看出地址已经不是00000000 了,显然这里的值经过修正,那么这些值又是如何得来的呢? 红圈结尾部分可以看标注的是601038 <global_init_var2), 0x601038 = 0x40556 + 0x2 + 0x8 + 0x200ad8 ,  0x40556 是movl 指令的开始地址,2 代表 c7 05 这两个字节, 0x8 是 0x2000ad8, 和 0x 0000000 这8个字节,也就是说这条指令是相对地址,从把0x28 这个立即数传送到 0x200ad8 (相对地址) 即绝对地址为0x601038 的地方, 那接下来再看0x601038 对应的是什么呢?依旧通过objdump -s -d simpleSection ,我们可以看到这个位置位于.data段,0x601038  正是global_init_var2 的地址位置

 

三 总结

以上的总结过程参考了《程序员的自我修养》这本书,无疑这本书值得一看,但个人认为这本书过于专业,对于符号解析和地址定位的简要过程缺少扼要描述,本博正式对这一过程的补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值