linux可执行文件格式
Linux可执行文件格式
Elf 也就是 “Executable and Linking Format.”
年账单怎么查
Elf 起源于Unix,经改进应用于FreeBSD和Linux等现有类Unix操作系统。
微软的PE格式也学习了ELF格式的优点。
ELF文档服务于在不同的操作系统上目标文件的创建或者执行文件的开发。它分以下三个部分:
“目标文件”描述了ELF目标文件格式三种主要的类型。
“程序装载和动态连接”描述了目标文件的信息和系统在创建运行时程序的行为。
“C 语言库”列出了所有包含在libsys中的符号、标准的ANSIC和libc的运行程序,还有libc运行程序所需的全局的数据符号。
三种主要类型:
一个可重定位文件(relocatable file)保存着代码和适当的数据,用来和其他的目标文件一起来创建一个可执行文件或者是一个共享文件。
一个可执行文件(executable file)保存着一个用来执行的程序,该文件指出了exec(BA_OS)如何来创建程序进程映象。
一个共享目标文件(shared object file)保存着代码和合适的数据,用来被下面的两个链接器链接。第一个是链接编辑器,可以和其他的重定位和共享目标文件来创建另一个目标文件。第二个是动态链接器,联合一个可执行文件和其他的共享目标文件来创建一个进程映象。
ELF的结构
ELF header
ELF header
Program header table (optional)
Program header table
Section 1
Segment 1
Segment 2
Section n
Section header table
Section header table (optional)
ELF
#define EI_NIDENT      16
      typedef struct {
      unsigned char        e_ident[EI_NIDENT];
      Elf32_Half          e_type;
      Elf32_Half            e_machine;
      Elf32_Word          e_version;
      Elf32_Addr          e_entry;
      Elf32_Off          e_phoff;
      Elf32_Off            e_shoff;
      Elf32_Word            e_flags;
      Elf32_Half            e_ehsize;
      Elf32_Half            e_phentsize;
      Elf32_Half            e_phnum;
      Elf32_Half            e_shentsize;
      Elf32_Half        e_shnum;
      Elf32_Half        e_shstrndx;
} Elf32_Ehdr;
常用标示
名称
偏移量
目的
EI_MAG0
0
e_ident[EI_MAG0] to e_ident[EI_MAG3]:文件的前4个字符保存一个魔术数(magic number),用来确定该文件是否为ELF的目标文件。参见表7-7
EI_MAG1
1
EI_MAG2
2
EI_MAG3
3
EI_CLASS
4
e_ident[EI_CLASS],用来确定文件的类型或者说是容量。参见表1-8
EI_DATA
5
e_ident[EI_DATA]指定了在目标文件中特定处理器数据的编码方式。参见表1-9
企业文化建设方案
EI_VERSION
6
e_ident[EI_VERSION]表明了ELF头的版本号。现在这个变量的值一定要设为EV_CURRENT,参见表7-5
EI_OSABI
7
操作系统和ABI的标识
EI_ABIVERSION
8
ABI版本
EI_PAD
9
e_ident[EI_PAD]标识了在e_ident中开始的未使用的字节,那些字节保留并被设置为0。程序把它们从目标文件中读出但应该忽略。如果当前未被使用的字节有了新的定义,EI_PAD变量将会被改变。
EI_NIDENT
16
e_ident[]的长度
一个目标文件的节头表可以让我们定位所有的节。节头表是一个Elf32_Shdr结构的数组。一个节头表的索引是这个数组的下标。
ELF头结构中的e_shoff成员给出了节头表的偏移量(从文件开始计数)。
e_shnum告诉我们节头表中包含了多少个表项;
e_shentsize 给出了每个表项的长度。某些节头表索引是保留的,这些索引在目标文件中没有与之对应的节。
typedef struct {
      Elf32_Word        sh_name;
      Elf32_Word        sh_type;
      Elf32_Word        sh_flags;
      Elf32_Addr        sh_addr;
      Elf32_Off        sh_offset;
      Elf32_Word        sh_size;
      Elf32_Word        sh_link;
      Elf32_Word        sh_info;
      Elf32_Word        sh_addralign;
      Elf32_Word        sh_entsize;
} Elf32_Shdr;
字符串表
字符串表节(String table sections)保存着以NULL终止的一系列字符,一般我们称为字符串。目标文件使用这些字符串来表示符号和节名。一个字符串的引用是一个字符串表节
的索引。
字符表
一个目标文件的符号表(symbol table)保存了定位和重定位程序的定义和引用的信息。一个符号表索引是相应的下标。0表项特指了该表的第一个表项,就象未定义的符号索引一样。
重定位(Relocation
重定位(Relocation)是链接符号引用和符号定义的过程。比如,当一个程序调用一个函数的时候,相关的调用必须在执行时把控制传送到正确的目标地址。换句话说,重定位文件应当包含如何修改他们的节内容的信息,从而允许可执行文件或共享目标文件为一个进程的程序映像保存正确的信息。
程序头
一个可执行的或共享的目标文件的程序头表是一个结构数组,每一个结构描述一个段或
其他系统准备执行该程序所需要的信息。一个目标文件段包含一个或多个部分(就象下面的“段目录”所描述的那样)。程序头仅仅对于可执行或共享的目标文件有意义。
typedef struct {
      Elf32_Word        p_type;
      Elf32_Off        p_offset;
      Elf32_Addr        p_vaddr;
      Elf32_Addr        p_paddr;
      Elf32_Word        p_filesz;
      Elf32_Word        p_memsz;
      Elf32_Word        p_flags;
      Elf32_Word        p_align;
推荐几部好看的爱情电影>人力资源管理就业  } Elf32_Phdr;
段内容实例
Text Segment                      Data Segment
程序载入
当创建或增加一个进程映像的时候,系统在逻辑上将拷贝一个文件的段到一个虚拟的内存段
动态链接
程序解释器(Progam Interpreter)
系统为解释器“编写”了一个内存映像,而不是使用原始的可执行文件的段映像。此时该解释器就负责接收来自系统的控制并且为应用程序提供一个环境变量。
动态链接器(Dynamic Linker)
火炬之光2 局域网联机当使用动态链接方式建立一个可执行文件时,链接器把一个PT_INTERP类型的元素加到可执行文件中,告诉系统像该系统的解释器一样调用动态链接器。
动态节(Dynamic Section)
如果一个目标文件参与动态的链接,它的程序头表将有一个类型为PT_DYNAMIC的元素。该“段”包含了.dynamic节。一个_DYNAMIC特别的符号,表明了该节包含了以下结构的一个数组。
共享目标的依赖关系(Shared Object Dependencies)
当链接器处理一个文档库时,它取出库中成员并且把它们拷贝到一个输出的目标文件中。当运行时没有包括一个动态链接器的时候,那些静态的链接服务是可用的。共享目标
爱情电视剧有哪些也提供服务,动态链接器必须把正确的共享目标文件链接到要执行的进程映象中。因此,可执行文件和共享的目标文件之间存在着明确的依赖性。
全局偏移量表 (Global Offset Table,GOT)
全局偏移量表在私有数据中保存着绝对地址,所以在不影响位置无关性和程序代码段共享能力的情况下应该使地址是可用的。一个程序参考它的GOT(使用位置无关的地址)并提取绝对的地址,所以与重定向无关的位置定位到绝对的位置。
PLT过程连接表(Procedure Linkage Table)
正如GOT重定位把位置无关的地址计算成绝对地址一样,PLT过程链接表重定向那些与位置无关的函数调用到绝对的地址。
简单的C程序及其ELF格式信息
int xx, yy;
main()
{
  xx = 1;
  yy = 2;
  printf ("xx %d yy %d\n", xx, yy);
}
ELF头信息
root# objdump -f a.out
a.out:    file format elf32-i386
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x080483dc
程序头
Program Header:
    PHDR off    0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
        filesz 0x000000c0 memsz 0x000000c0 flags r-x
  INTERP off    0x000000f4 vaddr 0x080480f4 paddr 0x080480f4 align 2**0
        filesz 0x00000019 memsz 0x00000019 flags r--
    LOAD off    0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。