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. 花了1块钱体验一把最近很火的ChatGPT

    前言 最近 OpenAI 发布了 ChatGPT,一经发布就在科技圈火得不行. ChatGPT是什么呢? 简单得说,ChatGPT,是一种基于对话的 AI 聊天工具.我们来看看ChatGPT自己得回答 ...

  2. Blog Statistics Dec 1, 2021 - Dec 1, 2022

    1. Overview Data Date: Dec 1, 2021 - Dec 1, 2022 Number of articles: 51 All Platform Total Visits: 3 ...

  3. .NET技术分享日活动-202110

    2021年10月15日下午,个人组织举办了山东地区的第三次.NET技术分享日活动.围绕.NET.低代码Low Code.云原生 Cloud Native.大数据.算法等方向进行创新技术的实践分享. 本 ...

  4. Serverless: AI everywhere的下一块拼图

    摘要:本文介绍华为云函数工作流(FunctionGraph)的灵活.速度,如何让开发人员提升工程效率,缩短TTM等 本文分享自华为云社区<华为云FunctionGraph函数工作流-- Serv ...

  5. AI开发效率低,你可以试试华为NAIE AutoML

    摘要:为解决AI工程师在开发AI应用场景所遇到的问题,NAIE平台落地AutoML框架(工具)来辅助大家更高效.更迅速解决AI开发问题. 你是不是还在为掌握的AI算法少而烦恼? 你是不是还在为选择某个 ...

  6. 云图说:云数据库 RDS for MySQL一键开通读写分离,轻松应对业务高峰期

    摘要:华为云数据库 RDS for MySQL提供一键开通读写分离功能,只需要一个连接地址,让您在业务高峰期不再迷茫,不再慌乱,so easy 的应对业务. 本文分享自华为云社区<云图说 | 第 ...

  7. 教你一个快速视频处理的神器:Python moviepy

    摘要:python 中的视频处理模块,有一个叫做 moviepy,今天我们就来唠唠它. 本文分享自华为云社区<python moviepy 的用法,看这篇就能入门>,作者: 梦想橡皮擦. ...

  8. 面对 Log4j2 漏洞,安全人都做了什么?

    摘要:本文从漏洞复现.漏洞防护.漏洞检测.软件供应链安全等方面,介绍安全人针对该漏洞做的尝试. 本文分享自华为云社区<面对 Log4j2 漏洞,安全人都做了什么?>,作者:maijun. ...

  9. 在距离distribution 证书过期一个月(或被手动revoke了)的时候会受到apple的邮件

    ​ ​编辑 虽然distribution过期(或者被手动revoke)了,如果你的开发者账号是company(公司)类型或个人类型的,只要你的每年99$的开发者membership没有过期,就不会对已 ...

  10. Hudi Bucket Index 在字节跳动的设计与实践

    由字节跳动数据湖团队贡献的 RFC-29 Bucket Index 在近期合入 Hudi 主分支,本文详细介绍 Hudi Bucket Index 产生的背景与实践经验.字节跳动数据湖团队持续招人中, ...