目标文件
代码文件经过编译器编译、链接器链接后,将会生成目标文件。
与认知不同的是,即使是用于执行的可执行目标文件,都并非单纯由指令序列组成。所有的目标必须包含一系列供操作系统加载器使用的结构信息,这个结构信息由操作系统进行约定,因此不同操作系统的结构信息各异。
比较主流的目标文件格式如下表:
| 操作系统 | 文件格式 | MAGIC |
|---|---|---|
| Linux | ELF | ELF |
| Windows | PE | MZ |
| Mac | Mach-O | 0xfeedface/0xfeedfacf |
ELF
Executable and linking format
ELF是Linux系统下一种常见的目标文件,有三种主要类型
- 可执行文件
用于提供程序的进程映像,加载到内存执行 - 可重定位文件
用于与其他目标文件链接,一起创建可执行文件或共享目标文件 - 共享目标文件
用于与其他可重定位目标文件和共享文件链接成其他目标文件,或与可执行文件组合创建进程映像。
在看文件结构的详细定义之前,我们先动手编译一个简单的目标文件,亲自察看其文件内容并配合结构定义能更方便的理解。
为了更直观的理解,程序显然越简单越好。比如下面这个就很不错:
int main() {}gcc编译得到.out文件后,我们使用readelf来实际查看其文件内容
gcc -march=i686 -fno-builtin -fno-PIC -Wall -ggdb -m32 -gstabs -nostdinc a.cpp
readelf -a a.outELF Header在文件开头描述了整个文件的组织,结构如下
struct elfhdr {
uint magic; // must equal ELF_MAGIC
uchar elf[12];
ushort type;
ushort machine;
uint version;
uint entry; // 程序入口的虚拟地址
uint phoff; // program header 表的位置偏移
uint shoff;
uint flags;
ushort ehsize;
ushort phentsize;
ushort phnum; //program header表中的入口数目
ushort shentsize;
ushort shnum;
ushort shstrndx;
};而在我们的目标文件中,ELF Header长这个样子
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x1070
Start of program headers: 52 (bytes into file)
Start of section headers: 16020 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 12
Size of section headers: 40 (bytes)
Number of section headers: 33
Section header string table index: 32可以发现,ELF Header实际上是该文件的大体信息,包括Magic,文件类型,入口地址等等。
如果是可执行文件,紧接着Header将会是Program Header数组,结构如下
struct proghdr {
uint type; // 段类型
uint offset; // 段相对文件头的偏移值
uint va; // 段的第一个字节将被放到内存中的虚拟地址
uint pa;
uint filesz;
uint memsz; // 段在内存映像中占用的字节数
uint flags;
uint align;
};每个程序结构描述了一个段或者系统准备执行所必需的其它信息。
每个段包含一个或者多个 “节区”(section) ,也就是“段内容”(Segment Contents)
我们的目标文件Program Headers如下
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00000034 0x00000034 0x00180 0x00180 R 0x4
INTERP 0x0001b4 0x000001b4 0x000001b4 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x00000000 0x00000000 0x003d4 0x003d4 R 0x1000
LOAD 0x001000 0x00001000 0x00001000 0x00254 0x00254 R E 0x1000
LOAD 0x002000 0x00002000 0x00002000 0x00164 0x00164 R 0x1000
LOAD 0x002edc 0x00003edc 0x00003edc 0x0012c 0x00130 RW 0x1000
DYNAMIC 0x002ee4 0x00003ee4 0x00003ee4 0x000f8 0x000f8 RW 0x4
NOTE 0x0001c8 0x000001c8 0x000001c8 0x00060 0x00060 R 0x4
GNU_PROPERTY 0x0001ec 0x000001ec 0x000001ec 0x0001c 0x0001c R 0x4
GNU_EH_FRAME 0x002008 0x00002008 0x00002008 0x0004c 0x0004c R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
GNU_RELRO 0x002edc 0x00003edc 0x00003edc 0x00124 0x00124 R 0x1PE
Portable application
首先要说的是,PE这个“可移植可执行”中的“可移植”,并不是现在大家所理解的跨平台性。在我看来,这个可移植应该理解为从低版本操作系统到高版本操作系统的可移植性(比如为16位DOS编译的目标文件,依旧能在32位Windows上执行)。
也正是因为这个“可移植”,Windows的目标文件比Linux复杂了不少。
MS-DOS年代的目标文件由马克·茨柏克沃斯基(Mark Zbikowski)主持开发,因此他使用了自己名字缩写作为MS-DOS目标文件的MAGIC。
到了Windows年代,考虑到DOS-MZ文件格式的兼容性,MZ这个MAGIC需予以保留。而作为新的操作系统,自然要支持包含新特性的PE目标文件格式。微软使用了一个取巧的方法,它在MZ文件头之后,又增加了一个可选的COFF文件头,当文件含有这个文件头时,意味该目标文件为PE格式,操作系统将会使用PE的方式去解析。
与ELF一样,PE也有三种主要的目标文件
- 可执行文件(.exe)
- 静态链接库(.lib)
- 动态链接库(.dll)
与ELF一样,我们在看PE文件结构的详细定义之前,我们先动手编译一个只含有空白main函数的目标文件。
windows主要使用cl指令来编译,而使用dumpbin来实际查看其文件内容
gcc -march=i686 -fno-builtin -fno-PIC -Wall -ggdb -m32 -gstabs -nostdinc a.cpp
readelf -a a.outMZ Header如下
struct mzhdr {
char signature[2] = "MZ";
short lastsize;
short nblocks;
short nreloc;
short hdrsize;
short minalloc;
short maxalloc;
void *ss;
void *sp;
short checksum;
void *ip;
void *cs;
short relocpos;
short noverlay;
short reserved1[4];
short oem_id;
short oem_info;
short reserved2[10];
long e_lfanew;
}在我们的目标文件中,通过dumpbin能看到以下信息
FILE HEADER VALUES
14C machine (x86)
4 number of sections
5F93F9FA time date stamp Sat Oct 24 17:55:06 2020
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
102 characteristics
Executable
32 bit word machine
7 条评论
寻找华纳圣淘沙公司开户代理(183-8890-9465薇-STS5099】
华纳圣淘沙官方合作开户渠道(183-8890-9465薇-STS5099】
华纳圣淘沙公司开户代理服务(183-8890-9465薇-STS5099】
华纳圣淘沙公司开户咨询热线(183-8890-9465薇-STS5099】
联系客服了解华纳圣淘沙开户
(183-8890-9465薇-STS5099】
华纳圣淘沙公司开户专属顾问
(183-8890-9465薇-STS5099】
华纳圣淘沙公司开户新手教程
零基础学会(183-8890-9465薇-STS5099)
华纳圣淘沙公司开户
华纳圣淘沙公司开户保姆级教程(183-8890-9465薇-STS5099)
一步步教你开通华纳圣淘沙公司账户(183-8890-9465薇-STS5099)
华纳圣淘沙公司开户分步图解
首次开户必看:(183-8890-9465薇-STS5099)
华纳圣淘沙全攻略
华纳圣淘沙公司开户实操手册(183-8890-9465薇-STS5099)
华纳圣淘沙开户流程视频教程
手把手教学:(183-8890-9465薇-STS5099)
华纳圣淘沙公司开户
华纳圣淘沙公司开户完全指南(183-8890-9465薇-STS5099)
果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
文字流畅如丝,语言优美动人,读来令人心旷神怡。
修辞手法运用娴熟,比喻贴切,感染力强。
作者以非凡的视角解读平凡,让文字焕发出别样的光彩。