ELF 可重定位目标文件简析

本博客在 X86-64 系统上运行,实验用例为以下两个 C 语言程序

  main.c

#include<stdio.h>
int sum(int *a, int n);
int array[2] = {1, 2};
int main(){
    int val = sum(array, 2);
    return val;
}

  sum.c

int sum(int *a, int n){
    int i, s = 0;
    for(i = 0; i < n; i++){
        s += a[i];
    }
    return s;
}

一、下面是一个典型程序的转换处理过程:

 

   本博客主要讲解可重定位目标文件(.o 文件),所以前面的处理过程就不展开讲解了。

 二、使用链接的前提是利用符号表示跳转位置和变量的方法简化了问题(汇编)

 

  左侧全部使用 0 1 来表示程序, 0010 表示“跳转”指令,指令后接的就是跳转的地址,现在跳转的地址是 0101 (即 5),但是如果在 3 的位置插入一条指令的话,那么需要跳转的地址可能就不是 0101 了,从而导致程序的修改。  

  而右侧使用符号很好地为程序员解决了这个烦恼。在程序中,用助记符表示操作码,用符号表示位置,用助记符表示寄存器

  例如上例,先确定 L0 的地址,再在 jmp 指令中填入 L0 的地址。

三、ELF 可重定位目标文件格式

 

 四、 ELF 头

  我们重点了解 ELF 头 和 节头表 的信息。

  ELF 头位于 ELF 文件开始,包含文件结构的说明信息,分 32 位系统和 64 位系统,下面分别是 32 位系统和 64 位系统对应的 ELF 头的数据结构。

  在Linux 的 /usr/include/elf.h 文件中查看

 

   其中魔数( Magic number) :文件开头几个字节,用来确定文件的类型或格式。(加载或读取文件时,用魔数确认文件类型是否正确)

  a.out 的魔数:01H 07H

  PE 的魔数:4DH 5AH

  ELF 的魔数:7f 45 4c 46  (其中 45 4c 46 是 ELF 的 ASCII 码值)

  可重定位目标文件是二进制文件,在linux终端 输入以下命令,就可以看见 ELF头的信息。(不同设备运行结果可能是不一样的)

readelf -h main.o

  

 

   1. 入口点地址为 0x0 :这是 ELF 文件,所以给出的是链接视图,不是执行视图。

  2. 本头的大小为 64 字节,说明在 ELF文件中,下一个块(.text) 的起始位置很有可能为 0x40。

  3. 最后方框中的内容的意思是:节头表中每一个表项的大小为 64 个字节,一共有 12 个表项,所以字节表的大小为 64*12 = 768(即 0x300)

五、节头表(Section header)

  下面是 32 位系统和 64 位系统的节头表的数据结构

 

  输入以下命令可以查看节头表的信息

readelf -S main.o

  

 

   根据偏移量和大小,可以得到以下 可重定位目标文件 main.o 的结构‘

  

 

 其中 .bss 是不分配空间的。

转载于:https://www.cnblogs.com/lyw-hunnu/p/11619512.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值