readelf elf文件格式分析


背景

目标文件

首先需要介绍的概念是目标文件(Object file)的概念。目标文件是计算机科学中编译器或汇编器处理源代码后所生成的代码(目标代码,Object code)的计算机文件,它常被称作二进制文件(binaries)。这个文件类型主要是区别于你看得懂的用人话写的代码文件(.c、.cpp etc.)、中间文件(.i)、汇编文件(.s)。常见的.exe、.dll、.so啥的都算目标文件。

目标文件有三种类型: - 可重定位的对象文件(Relocatable file) 由汇编器汇编生成的 .o 文件(下面会详细讲到) - 可执行的对象文件(Executable file) 可执行应用程序 - 可被共享的对象文件(Shared object file) 动态库文件

编译过程

编译的过程如下图所示

代码文件经过语言预处理器、编译器、汇编器和链接器处理,最终生成可执行目标文件。

下面以一个简单的c语言文件为例:

sum.c源文件内容如下:

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

通过运行C预处理器(cpp)可以生成sum.i中间文件:

# 1 "sum.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "sum.c"
int sum(int *a, int n)
{int i, s = 0;for (i = 0; i < n; ++i) {s += a[i];}return s;
}

通过运行C编译器(cc1),将中间文件生成为sum.s汇编文件:

.file›"sum.i".text.globl  sum.type›sum, @function
sum:
.LFB0:.cfi_startprocmovl  $0, %eaxmovl  $0, %edxjmp›.L2
.L3:movslq  %edx, %rcxaddl  (%rdi,%rcx,4), %eaxaddl  $1, %edx
.L2:cmpl  %esi, %edxjl  .L3rep ret.cfi_endproc
.LFE0:.size›sum, .-sum.ident  "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)".section  .note.GNU-stack,"",@progbits

最终生成通过汇编器(as)生成一个可重定位目标文件(reloacatable object file)。

什么是ELF

系统里的目标文件是按照特定的目标文件格式来组织的,各个系统的目标文件格式都不相同。

从贝尔实验室诞生的第一个Unix系统使用的是a.out格式(直到今天,可执行文件仍然称为a.out文件)。Windows使用可移植可执行(PortableExecutable,PE)格式。Mac OS-X使用Mach-O格式。现代x86-64Linux和Unix系统使用可执行可链接格式(Executable and Linkable Format,ELF)。

ELF格式的文件在Linux系统下有.axf、 .bin、 .elf、 .o、 .prx、 .puff、 .ko、 .mod和.so等等

readelf指令

前面介绍了这么多ELF的背景知识,下面回来来说说readelf这个指令。这个指令正是用来查看目标文件的内容的。

ELF可重定位目标文件的格式

典型格式

典型的ELF可重定位目标文件的格式如下图:

其中: - .text 节里装载了程序的可执行机器码 - .rodata 节里装载了只读数据 - .data 节里面装载了被初始化的数据,包括全局和静态C变量 - .bss 节里面装载了未被初始化的全局和静态C变量(在目标文件中只是占位符,不占空间) - .symtab 或者 .dynsym 节里面装载了符号信息 - 以 .rel 打头的 节里面装载了重定位条目 - .debug 一个调试符号表,只有使用了-g参数编译时才会有,用于debug - .line 用于记录C源程序的行号和.text节中机器指令之间的映射,也是只有使用了-g参数编译时才会有 - .strtab 或者 .dynstr 节里面装载了字符串信息(以null结尾的字符串信息)

符号表部分解析

符号表每节定义如下:

typedef struct { int   name;      /* String table offset */ char  type:4,    /* Function or data (4 bits) */ binding:4; /* Local or global (4 bits) */ char  reserved;  /* Unused */  short section;   /* Section header index */long  value;     /* Section offset or absolute address */ long  size;      /* Object size in bytes */
} Elf64_Symbol;

具体解释如下:

举个例子

以上面的sum.c生成的sum.o为例,我们选取readelf-all参数输出全部内容:

$readelf -all sum.o
ELF Header:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              REL (Relocatable file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x0Start of program headers:          0 (bytes into file)Start of section headers:          536 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           0 (bytes)Number of program headers:         0Size of section headers:           64 (bytes)Number of section headers:         11Section header string table index: 10Section Headers:[Nr] Name              Type             Address           OffsetSize              EntSize          Flags  Link  Info  Align[ 0]                   NULL             0000000000000000  000000000000000000000000  0000000000000000           0     0     0[ 1] .text             PROGBITS         0000000000000000  00000040000000000000001b  0000000000000000  AX       0     0     1[ 2] .data             PROGBITS         0000000000000000  0000005b0000000000000000  0000000000000000  WA       0     0     1[ 3] .bss              NOBITS           0000000000000000  0000005b0000000000000000  0000000000000000  WA       0     0     11 int sum(int *a, int n)2 {[ 4] .comment          PROGBITS         0000000000000000  0000005b000000000000002e  0000000000000001  MS       0     0     1[ 5] .note.GNU-stack   PROGBITS         0000000000000000  000000890000000000000000  0000000000000000           0     0     1[ 6] .eh_frame         PROGBITS         0000000000000000  000000900000000000000030  0000000000000000   A       0     0     8[ 7] .rela.eh_frame    RELA             0000000000000000  000001a80000000000000018  0000000000000018   I       8     6     8[ 8] .symtab           SYMTAB           0000000000000000  000000c000000000000000d8  0000000000000018           9     8     8[ 9] .strtab           STRTAB           0000000000000000  00000198000000000000000b  0000000000000000           0     0     1[10] .shstrtab         STRTAB           0000000000000000  000001c00000000000000054  0000000000000000           0     0     1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), I (info),L (link order), O (extra OS processing required), G (group), T (TLS),C (compressed), x (unknown), o (OS specific), E (exclude),l (large), p (processor specific)There are no section groups in this file.There are no program headers in this file.Relocation section '.rela.eh_frame' at offset 0x1a8 contains 1 entries:Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.Symbol table '.symtab' contains 9 entries:Num:    Value          Size Type    Bind   Vis      Ndx Name0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS sum.i2: 0000000000000000     0 SECTION LOCAL  DEFAULT    13: 0000000000000000     0 SECTION LOCAL  DEFAULT    24: 0000000000000000     0 SECTION LOCAL  DEFAULT    35: 0000000000000000     0 SECTION LOCAL  DEFAULT    56: 0000000000000000     0 SECTION LOCAL  DEFAULT    67: 0000000000000000     0 SECTION LOCAL  DEFAULT    48: 0000000000000000    27 FUNC    GLOBAL DEFAULT    1 sumNo version information found in this file.

其中第一部分是ELF头(ELF header)中的描述信息。(用-h参数可以单独得到)。

最后一部分是符号表部分(用-s参数可以单独得到该部分),前面八个条目是链接器内部使用的局部符号,最后一行是全局符号sum定义的条目。可以通过最后一行看出,它是一个位于.text节中偏移量为0处的27字节函数。(Ndx部分表示在哪个节中,1表示.text节,3表示.data节,对应上面输出的Section Headers部分)

原文见我的博客:

[一天一个命令]ELF目标文件与readelf​www.miluo.us

.axf文件_ELF文件格式与readelf命令使用相关推荐

  1. .axf文件_Keil开发环境如何生成BIN文件

    为什么需要BIN文件呢? 有些烧录器只支持BIN文件. 进行OTA远程升级时,只能使用BIN文件. 使用JLink脚本文件进行一键烧录时,只支持BIN文件. BIN文件要比HEX和AXF文件小的多. ...

  2. .axf文件_干货!STM32晶振的更改,BIN文件的生成

    STM32因为硬件设计的不同,要根据实际安装晶振修改程序参数, 一般使用的晶振是8M,如果遇到使用24M晶振的时候程序配置要怎么去修改呢? 一共有两处需要修改,如果是24M就把这个修改为24,同理8M ...

  3. Linux中光盘使用的文件类型,linux下mount命令使用详解---linux挂载光盘等文件系统...

    mount 命令详解 功能:加载指定的文件系统. 语法:mount [-afFhnrvVw] [-L标签] [-o选项] [-t文件系统类型] [设备名] [加载点] 用法说明:mount可将指定设备 ...

  4. linux上传文件操作,每天一个linux命令(文件上传下载文件操作):【转载】gzip命令(示例代码)...

    减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间.gzip是在Linux系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用.gzip不仅可以用 ...

  5. linux之readelf命令

    1.readelf命令解释       readelf命令用来显示一个或者多个elf格式的目标文件的信息 2.ELF文件类型 可重定位文件:用户和其他目标文件一起创建可执行文件或者共享目标文件,例如l ...

  6. linux中nm、ldd、readelf命令

    一.nm 1.     说明: nm用来列出目标文件的符号清单.Makefile中将产生的目标文件的符号清单列出, 调查bug时,可以工具清单中的信息准确定位问题. 2.     用法下面是nm命令的 ...

  7. Linux 命令(58)—— readelf 命令

    1.功能简介 readelf 用于读取 ELF(Executable and Linkable Format)格式文件的详细信息,包括目标文件.可执行文件.共享目标文件与核心转储文件. 1.1 ELF ...

  8. Keil关于.axf文件报错

    项目场景: 熟悉Keil C51的同学在使用Keil MDK编译STM32系列单片机时会更容易上手. Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与 ...

  9. 一文弄懂BIN、HEX、AXF、ELF文件格式的区别

    数据量比较 从存储数据的信息量上看:ELF>AXF>HEX>BIN,所以这也就确定了只能将大信息量的文件格式向小信息量的文件格式转换,如只能将HEX文件转换为BIN文件,当然如果指定 ...

最新文章

  1. tesseract3.01的训练和使用
  2. 对机械臂的肩关节与肘关节编码器连接与设置
  3. 关于xml的一些知识,DTD,XSD
  4. python爬虫(五)_urllib2:urlerror和httperror
  5. CSS 锦囊[收藏]
  6. jQuery插件备忘
  7. android webview javascript不执行,WebView中的JavaScript为什么不执行?
  8. oracle捕捉所有异常,如何捕获和处理特定的Oracle异常?
  9. 内联滴灌行业调研报告 - 市场现状分析与发展前景预测
  10. Spring使用经验之Listener综述
  11. 你应该知道的RPC原理
  12. 我的世界java版地牢种子_我的世界地牢种子坐标解析 地牢种子代码介绍
  13. 测试LOL帧数的软件,lol手游画质帧率修改器
  14. matlab安装matconvnet
  15. 主流手机游戏引擎介绍
  16. layui - 模板引擎
  17. 小喵的VUE项目搭建(一)
  18. centos静态ip天坑
  19. LabVIEW在模拟输入通道上同时使用差动(Differential)和RSE(ReferencedSingle Ended)作读取
  20. NetFPGA-SUME开发环境安装

热门文章

  1. 面向对象——类设计(二)
  2. linux的进程和作业控制实验报告,Linux基础--进程管理和作业控制
  3. php object 对象不存在。增加对象_《相亲者女》:找一个匹配的对象,但永远不存在...
  4. python爬虫怎么赚钱-如何利用python爬虫挣钱
  5. 开课吧学python靠谱吗-开课吧成为CNCC中国计算机大会唯一教育合作伙伴
  6. 讯飞语音输入法免费版
  7. 解密车载语音识别架构 车载系统能听懂人说话?
  8. Kaldi语音识别库linux环境下的安装和编译
  9. 多角度了解科大讯飞公司之一(语音识别)
  10. start.bat怎么启动java项目_部署java项目为服务,设置开机自启动