https://cloud.tencent.com/developer/article/1446849
 

1.目标文件的常用格式

目标文件是源代码编译后未进行链接的中间文件(Windows的.obj和Linux的.o),与可执行文件(Windows的.exe和Linux的ELF)的结构和内容相似,因此跟可执行文件采用同一种格式存储。PC平台常见的可执行文件格式主要有Windows的PE(Portable Executable)和Linux的ELF(Executable and Linkable Format)。PE和ELF都是通用目标文件格式(COFF,Common Object File Format)的变种。在Windows下,我们将目标文件与可执行文件统称为PE-COFF文件,Linux统称为ELF文件。除此之外,还有些不常用的目标文件与可执行文件格式,比如Intel和Microsoft以前使用的对象模型文件(OMF,Object Module File)、Unix的最初使用的a.out和MS-DOS的.COM格式等。

不光是可执行文件按照可执行文件格式存储,动态链接库(DLL,Dynamic Linking Library)(Windows的.dll和Linux的.so)及静态链接库(Static Linking Library)(Windows的.lib和Linux的.a)都按照可执行文件格式存储。它们在Windows下都按照PE-COFF格式存储,Linux下按照ELF格式存储。静态链接库稍有不同,它是把所有目标文件打包成一个文件,再加上一些索引,可以简单理解为一个包含很多目标文件的文件包。

Linux下的ELF文件主要有如下几种:

ELF文件类型

说明

实例

可重定位文件(Relocatable File)

包含了代码与数据,可以用来连接成可执行文件或共享目标文件,如目标文件与静态链接库

Linux的.o与.a,Windows的.obj与.lib

共享目标文件(Shared Object File)

包含了代码和数据,主要有两种用途,一是与目标文件或其它共享目标文件链接成新的共享目标文件,二是与可执行文件结合,作为进程映像的一部分来运行

Linux的.a,Windows的.dll

可执行文件(Executable File)

包含了可直接执行的程序

Linux下无后缀的ELF可执行文件,Windows的.exe文件

核心转储文件(Core Dump File)

当进程意外终止时,系统可以将该进程的地址空间的内容及终止时的一些其他信息转储到核心转储文件

Linux下的core dump

Linux下可以根据file命令查看上面表格中列出的四种ELF文件的格式。 (1)目标文件.o。 编译如下代码生成目标文件。

//@file:foo.cpp
#include <iostream>
using namespace std; int foo()
{
cout<<"hello world"<<endl;
}

复制

编译生成目标文件foo.o:

g++ -c foo.cpp -o foo.o

复制

使用file命令查看foo.o文件类型:

file foo.o
foo.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

复制

(2)共享目标文件.so,以C++标准库/lib64/libstdc++.so.6.0.19为例。

file /lib64/libstdc++.so.6.0.19
/lib64/libstdc++.so.6.0.19: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=8941888bf8ee9ced585599be5397a385fc1c73ce, stripped

复制

(3)可执行文件,以GNU的Shell /usr/bin/bash为例。

file /usr/bin/bash
/usr/bin/bash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=d0c7bc3186c85673fb2b14c90ab92eeaa27a18a5, stripped

复制

(4)核心转储文件core dump。 编译如下代码生成可执行文件a.out,运行a.out访问非法地址NULL后生成core文件。

//@file:main.cpp
#include <iostream>
using namespace std; int main()
{
int* iBar = NULL;
cout<<"*iBar"<<*iBar<<endl;
}

复制

编译并运行:

g++ main.cpp
./a.out
Segmentation fault (core dumped)

复制

使用file命令查看core文件类型:

file core.28355
core.28355: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from './a.out'

复制

可见,Linux下的目标文件.o,共享目标文件.so、可执行文件以及核心转储文件core dump均属于ELF文件。

2.目标文件与可执行文件格式的小历史

目标文件与可执行文件的格式和操作系统和编译器密切相关,不同的系统平台下会有不同的格式,但是这些格式又大同小异,可以说,目标文件与可执行文件格式的历史几乎是操作系统的发展史。

COFF是由Unix System V Release 3首次提出并使用的格式规范,后来Microsoft在其基础上,制定了PE格式标准,并将其应用于自家的Windows NT系统。后台,System V Release 4 在 COFF的基础上引入了ELF格式,目前流行的Linux系统也是以ELF作为基本的可执行文件格式。这也是为什么目前PE和ELF如此相似的原因,因为它们都是源于同一种可执行文件格式COFF。

在COFF之前,Unix最早的可执行文件格式是a.out格式,中文意为汇编器输出。因其设计简单,以至于后来共享库出现的时候,a.out格式变得捉襟见肘,难以满足共享库实现的要求,于是从Unix System V Release 3开始被COFF取代。由于COFF格式的设计非常通用,以至于COFF的继承者PE和ELF目前还在被广泛地使用。COFF的主要贡献是在目标文件中引入了“段”的机制,不同的目标文件可以拥有不同数量及不同类型的段。另外,还定义了调试数据的格式。


参考文献

[1]俞甲子,石凡.程序员的自我修养——链接、装载与库[M].北京:电子工业出版社,2009-04.C3.1目标文件格式.P56-58 [2]wikipedia.COFF [3]wikipedia.a.out

[转帖]认识目标文件的格式——a.out COFF PE ELF的更多相关文章

  1. GCC编译器原理(二)------编译原理一:目标文件

    一.目标文件 在 UNIX® 和 Linux® 中,任何事物都是文件.UNIX 和 Linux 编程实际上是编写处理各种文件的代码.系统由许多类型的文件组成,但目标文件具有一种特殊的设计,提供了灵活和 ...

  2. diff和patch的使用、patch文件的格式解说

    为了弄懂 patch中的 p0   p1    和.orig文件是啥,找到了这篇文章! 来源:http://www.cnblogs.com/super119/archive/2010/12/18/19 ...

  3. Keil工程文件的建立、设置与目标文件的获得

    单片机开发中除必要的硬件外,同样离不开软件,我们写的汇编语言源程序要变为 CPU 可以执行的机器码有两种方法,一种是手工汇编,另一种是机器汇编,目前已极少使用手工 汇编的方法了.机器汇编是通过汇编软件 ...

  4. Lichee(三) Android4.0该产品的目标文件夹,Lichee链接---extract-bsp

    由<Lichee() 在sun4i_crane平台下的编译>介绍了编译lichee的基本情况,我们终于得到了编译后的结果例如以下: out/ ├── android │   ├── bIm ...

  5. convert 批量文件的格式转换

    1.将 a.gif 转为 png 格式 convert a.gif a.png 请注意,convert 命令的基本格式为 convert 源文件 [参数] 目标文件 在上面的命令中,源文件是 a.gi ...

  6. 使用ShellExecute打开目标文件所在文件夹并选中目标文件

    转载:http://blog.csdn.net/chenlycly/article/details/7366364 转载:http://bbs.csdn.net/topics/50440550 She ...

  7. ELF文件的格式和加载过程

    http://blog.csdn.net/lingfong_cool/article/details/7832896 (一) ELF 文件的格式       ELF 文件类型 (1) 可重定位文件(  ...

  8. 在Unix系统上,从源文件、目标文件、可执行文件的编译过程

    是由“编译器驱动”(compiler driver)完成的: unix> gcc -o hello hello.c 在这里,gcc的编译器驱动程序读取源文件hello.c, #include & ...

  9. linux 目标文件调试

    前言如果普通编程不需要了解这些东西,如果想精确控制你的对象文件的格式或者你想查看一下文件对象里的内容以便作出某种判断,刚你可以看一下下面的工具:objdump, nm, ar.当然,本文不可能非常详细 ...

  10. [Linux]第二部分-linux文件磁盘格式

    账户信息在/etc/passwd中,密码在/etc/shadow中,组信息在etc/group中 (d/-)rwxrwxrwx 1 root 293 Oct 19 21:24 test 文件属性 连接 ...

随机推荐

  1. 神经网络基础篇:详解导数(Derivatives)

    导数 一个函数\(f(a)=3a\),它是一条直线.下面来简单理解下导数.让 看看函数中几个点,假定\(a=2\),那么\(f(a)\)是\(a\)的3倍等于6,也就是说如果\(a=2\),那么函数\ ...

  2. 人人都在聊的云原生数据库Serverless到底是什么?

    摘要:华为云数据库营销专家Tony Chen和华为云数据库高级产品经理佳恩开展了一场关于云原生数据库与Serverless结合的直播对话. 云计算的迅猛发展推动了数据库的变革,云原生数据库成为当前数据 ...

  3. 适合新手的12个Mybatis-Plus常用注解

    摘要:MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生. 本文分享自华为云社区<那些年,我们一起学过 ...

  4. iOS应用程序发布流程:从测试到上架的完整指南

    ​ 目录 转载:iOS应用程序的签名.重签名和安装测试 前言 打开要处理的IPA文件 设置签名使用的证书和描述文件 开始ios ipa重签名 转载:iOS应用程序的签名.重签名和安装测试 前言 ipa ...

  5. 聊一聊为什么我要整合Microsoft.Extensions.DependencyInjection和Castle.Core

    前言 如果用到动态代理,大家可能会有几种选择,排到前列的是Autofac+Castle.AspectCore和DoraInterception, 我将从我当时研究的经历,以及我遇到的场景,为大家展示下 ...

  6. Jmeter对各种接口类型的测试

    JMeter对各种类型接口的测试 默认做接口测试前,已经给出明确的接口文档(如,http://test.nnzhp.cn/wiki/index.php?doc-view-59):本地配好了JMeter ...

  7. go build 跟 go run 的区别

    go build 和 go run 是 Go 语言中两个常用的命令,它们的主要区别在于编译和执行的过程. 1.go run go run 命令用于编译并运行 Go 程序.它将源代码直接编译成可执行文件 ...

  8. 【Boost】boost.log 要点笔记

    常用简写: namespace logging = boost::log; namespace src = boost::log::sources; namespace expr = boost::l ...

  9. 机器学习 | 剖析感知器算法 & Python实现

    前言:本系列博客参考于 <机器学习算法导论>和<Python机器学习> 如有侵权,敬请谅解.本书尽量用总结性的语言重述本书内容,避免侵权. 上一篇已经初步介绍了机器学习相关知识 ...

  10. 第六届蓝桥杯C++A组 A~F题题解

    蓝桥杯历年国赛真题汇总:Here 1.方格填数 在2行5列的格子中填入1到10的数字. 要求: 相邻的格子中的数,右边的大于左边的,下边的大于上边的. 如[图1.png]所示的2种,就是合格的填法. ...