CSAPP(链接)——使用readelf命令查看Linux的两种ELF文件

一.知识储备

1.目标文件概述

    目标文件是按照特定的目标文件格式来组织的,各个系统的目标文件格式都不同。现代x86-64 Linux和Unix系统使用可执行可链接格式——ELF,且有以下三种形式:

  • 可重定位目标文件
  • 可执行目标文件
  • 共享目标文件

接下来的主题就是讲解两种视图下的ELF文件的格式

2.需要用到的命令

ps:对于linux系统内的命令,可以用man 命令名称来查看相应文档!
    这里用到的查看命令是readelf,其相应的文档可用“ man readelf" 查看。
摘抄用到的命令:
readelf -h
readelf -S
readelf -t
readelf -l

在这里插入图片描述

二.查看目标文件

1.文件视图

要查看文件有两种视图:ELF的链接视图和ELF的执行视图,分别对应可重定位的目标文件
可执行的目标文件
1)ELF的链接视图

2)ELF的执行视图
在这里插入图片描述

2.代码素材+可执行文件生成

C程序1:main.c

/* 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 */

C程序2:sum.c

/* 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 */

命令:
gcc -c main.c -o main.o
gcc -c sum.c -o sum.o
gcc -static -o progc main.o sum.o
在这里插入图片描述

3.命令使用

1)链接视图下的可重定位目标文件

使用readelf -h main.o查看该文件头的信息
文件内容:
在这里插入图片描述
    1.Magic是一个16字节的数组,前面的四个字节为魔数(确定文件类型或格式):为7f 45 4c 46(不同平台下的目标文件魔数不一样,Unix下的a.out格式的魔数为:01H 07H,Windows下的PE格式的魔数为4DH 5AH)
    可以用魔数来确认文件类型是否正确
    2.类别:ELF64
    3.main.o的格式类别是64位版本的,数据采用补码(带符号数)和小端形式
    4.版本为1
    5.操作系统是UNIX-System V
    6.版本类型为REL(可重定位文件)
    7.系统架构::Advanced Micro Devices X86-64
    8.程序头起点: 0 (bytes into file)(因为这是一个可重定位文件,不是可执行的)
    9.Start of section headers: 696 (bytes into file)指定节头表的偏移地址(下面可以用命令来看的)
    10.Size of this header: 64 (bytes)(这个ELF头的大小为64字节)
    11.Size of section headers: 64 (bytes) 节头表中每个节的大小
    12.Number of section headers: 12 节头表中节的数量
    13.Section header string table index: 11 .strtab在节头表中的索引位置

用readelf -S main.o命令来读节头表信息:

在这里插入图片描述
和ELF头给出的信息一致,节头表中有12个节!(可结合ELF链接视图和节头表中每项的名称查看具体的节)
每个节给出了:”名称 类型 地址 偏移量 大小 全体大小 旗标 链接 信息 对齐 “ 等信息,每一个表象就是64个字节的数据结构!
具体结构如下:(32位系统)
图片引用自中国大学MOOC袁春风的计算机系统基础”系列课程的pdf资料
分析:.strtab这个表项的号为10,说明在节头表的第11项,符合前面结果

2)执行视图下的可执行目标文件

使用readelf -h progc查看可执行目标文件的头(这里的progc是我的一个可执行文件的名称)
在这里插入图片描述
注意到可执行文件的格式图,与可重定位文件的格式区别不大,但是有一点区别!
其中:
1.ELF头中的 ”入口点地址:”给除了具体的地址0x401ac0(因为它是可执行的,无需重定位ie可被加载到内存)
2.多了 程序头表,也称段头表,是一个结构数组。
3.多了.init节节,用来定义_init函数,可用于进行可执行文件开始执行时的初始化工作

使用readelf -S progc查看可执行目标文件的节头表(这里的progc是我的一个可执行文件的名称)

在这里插入图片描述
这里没有截全,因为通过看ELF头,可知这里有29个节。

使用:readelf -l progc 查看程序头部表
在这里插入图片描述注:
offset:目标文件中的偏移
VirtAddr:虚拟地址
PhysAddr:物理地址
FileSiz:目标文件中的段的大小
MemSiz :内存中的段大小
Flags Align:对齐方式
本博客中部分ppt演示照片引用自中国大学mooc南京大学袁春风老师的ppt

参考资源:
1.中国大学MOOC袁春风的《计算机系统基础(一)》
2.书籍:机械工业出版社——《深入理解计算机系统》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值