`ELF`文件(Linux上运行,被统称为object file)

文件类型:

  • 可执行文件(.exec):Linker对.o文件进行处理输出的文件,进程映像
  • 可重定位文件(.rel):编译器和汇编器产生的.o文件,被Linker所处理
  • 共享目标文件(.dyn):动态库文件.so

文件组成:

  • ELF文件头:
    包含文件基本信息,文件头部存在魔术字符(7f 45 4c 46),即字符串\177ELF,当文件被映射到内存时,可以通过搜索该字符确定映射地址,dump内存时有用
#define EI_NIDENT 16
typedef struct{
    /*ELF的一些标识信息,固定值*/
    unsigned char e_ident[EI_NIDENT];
    /*目标文件类型:1-可重定位文件,2-可执行文件,3-共享目标文件等*/
    Elf32_Half e_type;
    /*文件的目标体系结构类型:3-intel 80386*/
    Elf32_Half e_machine;
    /*目标文件版本:1-当前版本*/
    Elf32_Word e_version;
    /*程序入口的虚拟地址,如果没有入口,可为0*/
    Elf32_Addr e_entry;
    /*程序头表(segment header table)的偏移量,如果没有,可为0*/
    Elf32_Off e_phoff;
    /*节区头表(section header table)的偏移量,没有可为0*/
    Elf32_Off e_shoff;
    /*与文件相关的,特定于处理器的标志*/
    Elf32_Word e_flags;
    /*ELF头部的大小,单位字节*/
    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;
  • 节头表(可去以增加反编译器分析难度)
    目标文件的节信息保存在节头表,表的每一项都是一个结构体,记录节的名字、长度、偏移、读写权限等信息

可执行文件的装载:

详见知乎专栏


静态链接

地址空间分配(将目标链接为可执行文件时)

  • 按序叠加
    当目标文件过多时,输出的可执行文件非常零散,且段的装载地址和空间以页为单位对齐造成内存浪费

  • 相似节合并
    将不同目标文件的相同属性的节合并为一个节

静态链接过程

符号解析(符号的引用与其定义相关联)
重定位(将符号的定义与内存地址相关联,然后修改其引用,使其指向这些内存地址)

静态链接库

类似CPP头文件


动态链接

在运行或装载时,在内存中完成链接的过程

位置无关代码

地址无关代码(英文: position-independent code,缩写为PIC),又称地址无关可执行文件(英文:
position-independent executable,缩写为PIE) ,是指可在主存储器中任意位置正确地运行,
而不受其绝对地址影响的一种机器码

延迟绑定

类似segment tree的lazy tag操作,为优化效率存在