前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ELF文件格式

ELF文件格式

作者头像
mingjie
发布2022-05-12 10:34:37
1.6K0
发布2022-05-12 10:34:37
举报
文章被收录于专栏:Postgresql源码分析

文章目录

  • 源码到可执行文件
  • ELF文件格式
    • ELF File header
    • Program header
    • Section header
  • 工具
  • Symbol Table

源码到可执行文件

linux中四类文件使用ELF文件格式

  • normal executable files
  • relocatable object files
  • core files
  • shared objects.

https://man7.org/linux/man-pages/man5/elf.5.html

1999年86open项目选择ELF作为x86处理器上Unix和类Unix系统的标准二进制文件格式。使用ELF的原因包括:灵活性、可扩展性、对不同字节序格式支持、跨平台支持地址size。

例如这些扩展名的文件一般都是elf格式:.axf, .bin, .elf, .o, .prx, .puff, .ko, .so, and .mod

ELF文件格式

引用wiki的一张图: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format

  • ELF header在文件开始处描述了整个文件的组织
  • Section提供了目标文件的各项信息(如指令、数据、符号表、重定位信息等)
  • Program header table指出怎样创建进程映像,含有每个program header的入口
  • section header table包含每一个section的入口,给出名字、大小等信息。其中Segment与section的关系后面会讲到。

touch头结构:

代码语言:javascript
复制
# hexdump -C /usr/bin/touch | head -5
00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 3e 00 01 00 00 00  1d 26 40 00 00 00 00 00  |..>......&@.....|
00000020  40 00 00 00 00 00 00 00  90 ec 00 00 00 00 00 00  |@...............|
00000030  00 00 00 00 40 00 38 00  09 00 40 00 1e 00 1d 00  |....@.8...@.....|
00000040  06 00 00 00 05 00 00 00  40 00 00 00 00 00 00 00  |........@.......|

https://en.wikipedia.org/wiki/Executable_and_Linkable_Format

ELF File header

e_ident的16个字节标识是个ELF文件(7F+’E’+’L’+’F’)。 e_type表示文件类型,2表示可执行文件。 e_machine说明机器类别,3表示386机器,8表示MIPS机器。 e_entry给出进程开始的虚地址,即系统将控制转移的位置。 e_phoff指出program header table的文件偏移。 e_phentsize表示一个program header表中的入口的长度(字节数表示)。 e_phnum给出program header表中的入口数目。类似的。 e_shoff,e_shentsize,e_shnum 分别表示section header表的文件偏移,表中每个入口的的字节数和入口数目。 e_flags给出与处理器相关的标志。 e_ehsize给出ELF文件头的长度(字节数表示)。 e_shstrndx表示section名表的位置,指出在section header表中的索引。

Program header

目标文件或者共享文件的program header table描述了系统执行一个程序所需要的段或者其它信息。目标文件的一个段(segment)包含一个或者多个section。Program header只对可执行文件和共享目标文件有意义,对于程序的链接没有任何意义。结构定义如下,可在/usr/include/elf.h中可以找到文件头结构定义:

其中p_type描述段的类型; p_offset给出该段相对于文件开关的偏移量; p_vaddr给出该段所在的虚拟地址; p_paddr给出该段的物理地址; p_filesz给出该段的大小,在字节为单元,可能为0; p_memsz给出该段在内存中所占的大小,可能为0; p_filesze与p_memsz的值可能会不相等。

Section header

目标文件的section header table可以定位所有的section,它是一个Elf64_Shdr结构的数组,Section头表的索引是这个数组的下标。有些索引号是保留的,目标文件不能使用这些特殊的索引。

Section包含目标文件除了ELF文件头、程序头表、section头表的所有信息,而且目标文件section满足几个条件:

  • 目标文件中的每个section都只有一个section头项描述,可以存在不指示任何section的section头项。
  • 每个section在文件中占据一块连续的空间。
  • Section之间不可重叠。
  • 目标文件可以有非活动空间,各种headers和sections没有覆盖目标文件的每一个字节,这些非活动空间是没有定义的。

sh_name指出section的名字,它的值是后面将会讲到的section header string table中的偏移,指出一个以null结尾的字符串。 sh_type是类别。 sh_flags指示该section在进程执行时的特性。 sh_addr指出若此section在进程的内存映像中出现,则给出开始的虚地址。 sh_offset给出此section在文件中的偏移。其它字段的意义不太常用,在此不细述。

文件的section含有程序和控制信息,系统使用一些特定的section,并有其固定的类型和属性(由sh_type和sh_info指出)。

下面介绍几个常用到的section:

  • “.bss”段含有占据程序内存映像的未初始化数据,当程序开始运行时系统对这段数据初始为零,但这个section并不占文件空间。
  • “.data.”和“.data1”段包含占据内存映像的初始化数据。
  • “.rodata”和“.rodata1”段含程序映像中的只读数据。
  • “.shstrtab”段含有每个section的名字,由section入口结构中的sh_name索引值来获取。
  • “.strtab”段含有表示符号表(symbol table)名字的字符串。
  • “.symtab”段含有文件的符号表,在后文专门介绍。
  • “.text”段包含程序的可执行指令。

工具

Main article: GNU Binutils

  • readelf is a Unix binary utility that displays information about one or more ELF files. A free software implementation is provided by GNU Binutils.
  • elfutils provides alternative tools to GNU Binutils purely for Linux.[10]
  • elfdump is a command for viewing ELF information in an ELF file, available under Solaris and FreeBSD.
  • objdump provides a wide range of information about ELF files and other object formats. objdump uses the Binary File Descriptor library as a back-end to structure the ELF data.
  • The Unix file utility can display some information about ELF files, including the instruction set architecture for which the code in a relocatable, executable, or shared object file is intended, or on which an ELF core dump was produced.

Symbol Table

目标文件的符号表包含定位或重定位程序符号定义和引用时所需要的信息。符号表入口结构定义如下,可在/usr/include/elf.h中可以找到文件头结构定义:

代码语言:javascript
复制
typedef struct elf64_sym {
  Elf64_Word st_name;		/* Symbol name, index in string tbl */
  unsigned char	st_info;	/* Type and binding attributes */
  unsigned char	st_other;	/* No defined meaning, 0 */
  Elf64_Half st_shndx;		/* Associated section index */
  Elf64_Addr st_value;		/* Value of the symbol */
  Elf64_Xword st_size;		/* Associated symbol size */
} Elf64_Sym;
  • st_name包含指向符号表字符串表(strtab)中的索引,从而可以获得符号名。
  • st_value指出符号的值,可能是一个绝对值、地址等。
  • st_size指出符号相关的内存大小,比如一个数据结构包含的字节数等。
  • st_info规定了符号的类型和绑定属性,指出这个符号是一个数据名、函数名、section名还是源文件名;并且指出该符号的绑定属性是local、global还是weak。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 源码到可执行文件
  • ELF文件格式
    • ELF File header
      • Program header
        • Section header
        • 工具
        • Symbol Table
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档