可重定位目标文件的解析

Linux 操作系统中 gcc 的使用以及可重定位目标文件的解析

在做这次实验之前,我在Linux操作系统的Document中写了三个C程序,分别是main.c ,sum.c,hello.c
接下来我要做的工作有三步:
1.在Terminal中分别调动GCC程序的-o和-c命令将三个文件编译成可重定位目标文件及可执行文件,顺便执行程序
2.分别使用readelf的-h,-s,-S三个命令以读取.o文件的头部结构,程序的符号,以及每一节的头部信息,并在得到结果之后对其作相应的解析
3.分别使用objdump的-d,-s,-S三个命令查看编译后的汇编代码及头部信息等

代码展示

/* main.c */
/* $begin main */
int sum(int *a, int n);

int array [2]= {1, 2};

int main() 
{
    int val = sum(array, 2);
    return val;
}
/* $end main */

/* sum.c */
/* $begin sum */
int sum(int *a, int n)
{
    int i, s = 0;
    
    for (i = 0; i < n; i++) { 
        s += a[i];
    }
    return s;
}        
/* $end sum */

/* hello.c */
/* $begin hello */
int main()
{
  printf("hello,word!")
}        
/* $end hello */

其中main函数中包含对sum的调用,不能单独编译成可执行文件,必须通过和sum的链接,但是可以单独生成.o文件

gcc -o与gcc -c 的区别

功能上的区别就不必多说,格式上有必要记录一下我操作之中的一个小bug
~/Documents$ gcc -c hello.c
~/Documents$ gcc -Og -o test hello.c
这两个命令格式上的不同之处是执行-o命令必须给生成的文件取一个别名,之前听说如果省略命名则会给所有可执行文件统一命名为a.out,于是就偷懒少打了几个字但是错误提示:no input files
添加text别名后就可以编译

readelf程序

1.readelf -h读到的ELF header信息描述了生成该文件的字的大小和字节序列
readelf -h读到的ELF header信息描述了生成该文件的字的大小和字节序列
(1).magic表示的是ELF的魔数,其中45,4c, 46分别是E,L,F的ASCII码
(2).class表示格式为32位版本
(3).Data说明数据采用的是补码表示,且按照小端方式存放
(4).Version:版本是1
(5).OS/ABI:操作系统的型号
(6).Type:ELF文件类型是可重定位的文件类型
(7).Machine:机器是在64位上编译的目标代码
(8).Entry point address:程序的入口地址是0
(9).Start of program headers:0 程序头表的偏移量为0,表示没有程序头表
Size of program headers:0 程序头表的长度为0
Number of program headers:0 程序头表的表象为0
因为该文件类型是可重定位的目标文件,所以不包含程序头表
(10).Start of section headers: 672 节头表的起始位置是672字节
Size of section headers: 64 节头表的大小是64字节
Number of section headers:12 节头表一共有12个表象
节头表的大小:12*64B=768B
节头表的起始位置和大小就确定了节头表在ELF文件中的起始位置
(11).Size of this header:64 ELF头的大小是64个字节
(12).Section header string table index: 9 字符串表在节头表中的索引值是9
节头表中一共有12项其中第9项是字符串表
2.readelf -s读取ELF头和节头部表之间的节的信息
节信息
其中Ndx表示相应的符号放在第几节:array是全局变量放在第3节.data中,main函数放在第1节text中
3.readelf -S 读取节头表信息
节头表信息
该节头表共有12个节,起始位置在ox2a0
其中Address字段每个节都是0,因为该文件只是.0文件,并不会加载执行即:可重定位目标文件中,每个可装入节的起始地址总是0
其中每一列:offset表示起始位置,size表示节的大小,Flags表示执行方式(AX:可执行,WA:可读可写,A:可读),Align表示对齐方式
ELF头的起始位置是0加上它的大小64B就是下一节.text的起始位置ox40,.text的size是1f ,所以.text的终止位置是ox5f,所以下一节的起始位置就是ox60,即为.data节。data节的大小是8,所以data的终止位置就是ox68,这同时也是下一节.bss的起始位置。以此类推可以算出接下来每一节的起始地址及排序。

objdump程序

1.调用objdump -h 查看目标文件各个section的头部摘要信息

VMA是virtual address 运行地址
LMA是load address 加载地址
2.调用objdump -s显示指定section的所有内容
在这里插入图片描述
3.调用objdump -S查看反汇编出的源代码(该方式隐含了-d参数)
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值