• ELF文件格式


    ELF文件简介

    ELF(Executable and Linkable Format)是一种常见的二进制文件格式,用于可执行文件、共享库、目标文件等。
    ELF 文件格式是一种灵活、可扩展的文件格式,被广泛用于 UNIX 和类 UNIX 操作系统。

    一个 ELF 文件通常由以下几个主要部分组成:

    • 文件头(ELF Header): 文件头包含了关于 ELF 文件本身的信息,如文件类型、目标体系结构、入口点地址等。文件头是 ELF 文件的第一个部分,其长度是固定的。
    • 程序头表(Program Header Table): 程序头表描述了程序在内存中的布局。对于可执行文件,程序头表指定了如何将文件内容映射到内存;对于目标文件,它描述了程序在内存中的段的布局。
    • 段头表(Section Header Table): 段头表包含了一系列段头条目,每个条目描述了一个段的信息,如段的类型、大小、偏移等。段通常包含代码、数据、符号表等信息。
    • 数据段: 包含实际的程序数据,如代码段、数据段等。
    • 符号表: 符号表包含了程序中使用的符号的信息,如函数、变量等。符号表与调试信息相关联,用于调试和符号解析。
    • 重定位信息: 重定位信息包含了需要在链接时或加载时进行地址调整的信息,确保程序正确地连接和执行。
    • 动态链接信息: 如果 ELF 文件支持动态链接,那么它包含了动态链接器所需的信息,如共享库的位置、动态符号表等。

    ELF 文件格式的灵活性使其成为多种体系结构和操作系统上的标准格式。
    不同的体系结构可能会有一些特定的字段,但整体结构基本保持一致。
    ELF 文件通常以 .elf、.o(目标文件)、.so(共享库)等扩展名结尾。

    文件结构

    常见的ELF格式如上图所示,左边为链接视图,右边为执行视图。

    链接视图:
    静态链接器(即编译后参与生成最终ELF过程的链接器,如ld )会以链接视图解析ELF。
    编译时生成的 .o(目标文件)以及链接后的 .so (共享库)均可通过链接视图解析,链接视图可以没有段表(如目标文件不会有段表)。

    执行视图:
    动态链接器(即加载器,如x86架构 linux下的 /lib/ld-linux.so.2或者安卓系统下的 /system/linker均为动态链接器)会以执行视图解析ELF并动态链接。
    执行视图可以没有节表。

    文件头

    ELF的结构声明位于系统头文件 elf.h 中,ELF格式分为32位与64位两种,除了重定位类型稍有区别,其它大致相同,为了简化描述,后续说明将省略32/64字样。

    ELF Header的声明如下 :

    #define EI_NIDENT (16)
    typedef struct
    {
        unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
        Elf_Half		e_type;			/* Object file type */
        Elf_Half		e_machine;		/* Architecture */
        Elf_Word	        e_version;		/* Object file version */
        Elf_Addr		e_entry;		/* Entry point virtual address */
        Elf_Off		e_phoff;		/* Program header table file offset */
        Elf_Off		e_shoff;		/* Section header table file offset */
        Elf_Word	        e_flags;		/* Processor-specific flags */
        Elf_Half		e_ehsize;		/* ELF header size in bytes */
        Elf_Half		e_phentsize;		/* Program header table entry size */
        Elf_Half		e_phnum;		/* Program header table entry count */
        Elf_Half		e_shentsize;		/* Section header table entry size */
        Elf_Half		e_shnum;		/* Section header table entry count */
        Elf_Half		e_shstrndx;		/* Section header string table index */
    } Elf_Ehdr;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    e_ident

    包含了Maigc Number和其它信息,共16字节。	
    0~3:前4字节为Magic Number,固定为ELFMAG。
    4(EI_CLASS):ELFCLASS32代表是32位ELF,ELFCLASS64 代表64位ELF。
    5(EI_DATA):ELFDATA2LSB代表小端,ELFDATA2MSB代表大端。
    6(EI_VERSION):固定为EV_CURRENT(1)。
    7(EI_OSABI):操作系统ABI标识(实际未使用)。
    8(EI_ABIVERSION):ABI版本(实际 未使用)。
    9~15:对齐填充,无实际意义。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    e_type

    ELF的文件类型,定义如下:
         ET_REL		可重定位文 件(如目标文件)
         ET_EXEC	        可执行文件(可直接执行的文件)
         DT_DYN	        共享目标文件(如SO库)
         DT_CORE	        Core文件(吐核文件)
    注:GCC使用编译选项 -pie 编译的可执行文件实际 也是DT_DYN类型。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    other

    e_machine
    目标体系结构,即程序要在哪种体系结构上运行,此字段定义了目标处理器的架构。
    e_verison
    文件版本,目前常见的ELF 文件版本均为EV_CURRENT(1)。
    e_entry
    入口虚拟地址。
    e_phoff
    段表文件偏移。
    e_shoff
    节表文件偏移。
    e_flags
    处理器特定的标志,一般为0。
    e_ehsize
    Elf_Header的大小(字节)
    e_phentsize
    段头(Program Header)的大小(字节)。
    e_phnum
    段的数量。
    e_shentsize
    节头(Section Header)的大小(字节)。
    e_shnum
    字的数量。
    e_shstrndx
    节字符串表的节索引。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    免费研讨会 | 邀您体验 Ansys Zemax Enterprise 的 STAR 模块
    运动检测辅助系统
    uni-app 之 v-on:click点击事件
    基于COE和LPSP粒子群优化(PSO)的独立光伏-电池-柴油发电机选型(Matlab代码实现)
    cwe_checker初识别
    学习SLAM:SLAM进阶(九)以激光点云赋色为例讲述如何自定义ROS的消息格式并实现消息的订阅与发布
    数据结构与算法(一) 时间复杂度
    手游模拟器长时间运行后,游戏掉帧且不恢复
    Python缺失值的处理
    3d模型怎么一缩放模型都散了?---模大狮模型网
  • 原文地址:https://blog.csdn.net/NSJim/article/details/134449318