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. 自定义TBE算子入门,不妨从单算子开发开始

    摘要:以单算子开发为例,带你了解算子开发及测试全流程. 为什么要自定义算子 深度学习算法由一个个计算单元组成,我们称这些计算单元为算子(Operator,简称Op).算子是一个函数空间到函数空间上的映 ...

  2. 华为云数据库GaussDB(for openGauss):初次见面,认识一下

    摘要:本文从总体架构.主打场景.关键技术特性等方面进行介绍GaussDB(for openGauss). 1.背景介绍 3月16日,在华为云主办的GaussDB(for openGauss)系列技术第 ...

  3. 带你认识大模型训练关键算法:分布式训练Allreduce算法

    摘要:现在的模型以及其参数愈加复杂,仅仅一两张的卡已经无法满足现如今训练规模的要求,分布式训练应运而生. 本文分享自华为云社区<分布式训练Allreduce算法>,原文作者:我抽签必中. ...

  4. 教你从零搭建Web漏洞靶场OWASP Benchmark

    摘要:Owasp benchmark 旨在评估安全测试工具的能力(准确率.覆盖度.扫描速度等等),量化安全测试工具的扫描能力,从而更好得比较各个安全工具优缺点. 本文分享自华为云社区<Web漏洞 ...

  5. 让快更快,火山引擎 ByteHouse 为 ClickHouse 提速

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群   近日,火山引擎数智平台VeDI与DataFun联合举办以"OLAP计算引擎"为主题的直播活 ...

  6. A/B测试有哪些常见应用场景?——火山引擎DataTester科普

      更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 火山引擎 DataTester不仅对外提供服务,也是字节跳动内部所应用的A/B实验平台,它基于先进的底层算法, ...

  7. AliSSR 语音超分算法:让在线会议语音更明亮更自然

    超分让在线会议语音更明亮,在线会议已成为日常工作中较为普遍的沟通交流方式,接入会议的方式也呈现多样化,比如电脑入会.手机入会又或是电话入会. 雪雅.曜辰|作者 众所周知,高采样率且高带宽的音频信号富含 ...

  8. 3.1 《数据库系统概论》SQL概述及数据定义(模式SCHEMA、表TABLE、索引INDEX)

    前言 本篇文章学习书籍:<数据库系统概论>第5版 王珊 萨师煊编著 视频资源来自:数据库系统概论完整版(基础篇+高级篇+新技术篇) 由于 BitHachi 学长已经系统的整理过本书了,我在 ...

  9. i 的二次幂求和

    学习 自为风月马前卒 大佬的数学笔记 \(i^2\) 求和 查阅资料我们很容易就发现 \(\sum_{i = 1}^ni^2 = \frac{n(n + 1)(2n + 1)}{6}\) 但具体怎么求 ...

  10. AtCoder Beginner Contest 182 Person Editorial

    Problem A - twiblr 直接输出 \(2A + 100 - B\) Problem B - Almost GCD 这里暴力枚举即可 int main() { ios_base::sync ...