Hello World 深入理解(3)——目标文件分析

前言:

   问题:最后编译出来的可执行文件里面是什么?除了机器码还有什么?他们怎么存放的?怎么组织的?

       在Linux系统中可执行文件属于elf文件格式中的一种,它里面有编译后的机器指令,数据,符号表,调试信息,字符串等等信息。如果要知道它是如何存放的,那就需要了解ELF文件格式

可执行程序:

可执行文件格式( Executable)主要是 Windows下 的 PE (Portable Executable)和 Linux 的 ELF (Executable Linkable Format),它们都是 COFF (Common file formal)格式的变种。目标文件就是源代码编译后但未进行链接的那些中间文件(Windows 的 .obj和 Linux下的.o)它跟可执行文件的内容与结构很相似,所以一般跟可执行文件格式一起采用同一种格式存储。从广义上看, 目标标文件与可执行文件的格式其实几乎是一样的,所以我们可以广义地将目标文件与吋执行文件看成是一种类型的文件,在 Windows下,我们 可以统称它们为 PE-COFF文件格式。在 Linux下,我们可以将它们统称为 ELF文件。其他不太常见的可执行文件格式还有Intel/Microsoft的OMF(Object Module Format)、Unix a.out 格式和MS-DOS .COM格式等。

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

ELF文件格式的文件归为下面所列的四类。

上面四种文件,都可以统称为编译的目标文件,它们都是通过编译得到的产物。它里面有编译后的机器指令,数据,符号表,调试信息,字符串等等信息,它们按节存储,也可以说是按段存储。下图可以查看程序与目标文件的示意图

对照上图,一般C语言的编译后执行语句都编译成机器代码,保存在. text段;己初始化的全局变量和局部静态变最都保存在. data段:未初始化的全局变最和局部静态变量一般放在一个叫. “bss”的段里。我们知道未初始化的全局变量和局部静态变最默认值都为 0,本来它们也可以被放在. data段的,但是因为它们都是0,所以为它们在. data段分配空间并且存放数据0是没有必要的。程序运行的时候它们的确是要占内存空间的,并且可执行文件必须记录所有未初始化的全局变量和局部静态变量的大小总和记为.bss段。所以.bss段只是为未初始化的全局变量和局部静态变量预留位置而己,它并没有内容,所以它在文件中也不占椐空间。

ELF文件

ELF文件类型:

  1. 可重定位文件:用户和其他目标文件一起创建可执行文件或者共享目标文件,例如lib*.a文件。
  2. 可执行文件:用于生成进程映像,载入内存执行,例如编译好的可执行文件a.out。
  3. 共享目标文件:用于和其他共享目标文件或者可重定位文件一起生成elf目标文件或者和执行文件一起创建进程映像,例如lib*.so文件。

ELF文件作用:

ELF文件参与程序的连接(建立一个程序)和程序的执行(运行一个程序),所以可以从不同的角度来看待elf格式的文件:

  1. 如果用于编译和链接(可重定位文件),则编译器和链接器将把elf文件看作是节头表描述的节的集合,程序头表可选。
  2. 如果用于加载执行(可执行文件),则加载器则将把elf文件看作是程序头表描述的段的集合,一个段可能包含多个节,节头表可选。
  3. 如果是共享文件,则两者都含有。

ELF文件总体组成:

elf文件头描述elf文件的总体信息。包括:系统相关,类型相关,加载相关,链接相关。

  1. 系统相关表示:elf文件标识的魔术数,以及硬件和平台等相关信息,增加了elf文件的移植性,使交叉编译成为可能。
  2. 类型相关就是前面说的那个类型。
  3. 加载相关:包括程序头表相关信息。
  4. 链接相关:节头表相关信息

ELF文件结构:

       整个ELF文件结构图如下:

       实际的ELF文件结构,除了我们上面提到的常见的数据段,代码段,bss段外,它还包含了其他的一些段。如下图:

ELF结构信息查看

在Linux 系统中,如果要查看ELF文件里面的信息,可以使用命令readelf 命令查看

-a

--all 显示全部信息,等价于 -h -l -S -s -r -d -V -A -I.

-h

--file-header 显示elf文件开始的文件头信息.

-l

--program-headers 

--segments 显示程序头(段头)信息(如果有的话)。

-S

--section-headers 

--sections 显示节头信息(如果有的话)。

-g

--section-groups 显示节组信息(如果有的话)。

-t

--section-details 显示节的详细信息(-S的)。

-s

--syms       

--symbols 显示符号表段中的项(如果有的话)。

-e

--headers 显示全部头信息,等价于: -h -l -S

-n

--notes 显示note段(内核注释)的信息。

-r

--relocs 显示可重定位段的信息。

-u

--unwind 显示unwind段信息。当前只支持IA64 ELF的unwind段信息。

-d

--dynamic 显示动态段的信息。

-V

--version-info 显示版本段的信息。

-A

--arch-specific 显示CPU构架信息。

-D

--use-dynamic 使用动态段中的符号表显示符号,而不是使用符号段。

-x <number or name>

--hex-dump=<number or name> 以16进制方式显示指定段内内容。number指定段表中段的索引,或字符串指定文件中的段名。

-w[liaprmfFsoR] or

--debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges] 显示调试段中指定的内容。

-I

--histogram 显示符号的时候,显示bucket list长度的柱状图。

-v

--version 显示readelf的版本信息。

-H

--help 显示readelf所支持的命令行选项。

-W

--wide 宽行输出。

@file 可以将选项集中到一个文件中,然后使用这个@file选项载入

引用:

https://man.linuxde.net/readelf

 

---------------------------------------2022.08.21日更新---------------------------------------

由于各种原因,本博客将不再更新,

新的文章内容和附件工程文件

可以通过面的方式获取:

||·-·||·==·||·-·||·-·||:liwen01

也可以通过博客主页信息进行获取

感恩您的关注,谢谢~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 你好!恭喜你开始学习Python!下面是Python中的传统开场白: ```python print("Hello World!") ``` 以上代码会输出一个简单的“Hello World!”消息。希望这能为你提供一个好的开始,祝你学习愉快! ### 回答2: Python是一种非常受欢迎的编程语言,它的语法简单、清晰,适合初学者入门学习编程。Hello World是Python编程中最基本也是最经典的入门示例,它是一个最简单的程序,只需要一行代码即可打印出“Hello World”。 Python中的print()函数可以输出一段文本,你可以在括号中写下你想要输出的内容。在这里,我们要输出的是“Hello World”。 在Python的IDE中,我们可以像下面这样写下第一行Python代码: ``` print("Hello World") ``` 在这行代码中,print是Python中的一个内置函数,它可以输出指定的内容。括号中的双引号是用来包含输出的文本的,它告诉Python这是一个字符串。当我们运行这段代码后,Python就会在控制台输出“Hello World”的文本。 除了在IDE中写入代码,我们还可以使用Python的命令行来输出Hello World。我们只需要打开命令行模式,键入python命令就可以打开Python解释器。然后,我们可以键入第一行代码print("Hello World"),按回车键,Python就会立即输出Hello World。 在初次体验Python的过程中,这个Hello World程序可以帮助我们了解程序如何工作,如何指定输出文本并将其打印到屏幕上。它也是我们编写更复杂的程序的基础和基石。无论你是计算机科学的专业人士还是仅仅是对编程感兴趣,学习Python编程都是一个不错的选择。 ### 回答3: Python初体验——Hello World Python是一门高级编程语言,而“Hello World”则是编程里的常见入门示例。让我们开始我们的Python初体验吧! 首先,我们需要安装Python解释器。Python解释器是一个解释执行Python代码的程序。Windows系统下可以在Python官网下载,并安装在本地计算机上。另外,Python也可以在很多云平台上使用,例如Google Colaboratory和Jupyter Notebook。 在安装完Python解释器之后,我们可以使用一些简单的文本编辑器,例如VS Code和Atom,在Python中运行代码。但是如果您是刚入门的新手,可以使用IDLE,IDLE是Python自带的集成开发环境,可以方便地输入、编辑、运行Python代码和在线调试。在Windows上,可以在开始菜单中找到它,然后输入“idle”或“Python”即可。 接下来,让我们通过经典的“Hello World”程序来进行Python的初体验。 打开IDLE编辑器之后,输入以下代码: print("Hello, World!") 该代码的含义是,输出一条带有“HelloWorld!”的提示信息。我们点击“运行”(或按F5)即可看到结果。 也可以在Python交互模式下操作,例如在命令行中键入“python”命令。随后,我们直接输入“print("Hello, World!")”即可看到输出。 Python还有许多其他的示例和功能,例如计算器和猜数字游戏等等。学习Python,你可以使用它来构建自己的小工具,处理数据、创建网站,以及编写各种有趣的程序。 总之,Python是一门入门门槛较低,功能强大的高级编程语言,非常适合初学者入门。通过“Hello World”程序,我们可以体验到它的简洁、易学、高效,也能够更好地了解Python编程的本质。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

li_wen01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值