目标文件里有什么

  编译器在编译源代码后生成的文件叫目标文件,就是指编译后未进行链接的中间文件,目标文件与可执行文件的结构和内容很相似,从广义上看,目标文件和可执行文件的格式几乎是一样的。动态链接库也是按照可执行文件的格式存储的,静态链接库是把很多目标文件捆绑在一起形成一个文件,再加上一些索引。

ELF 文件的类型

  1. 可重定位文件:这类文件包含了代码和数据,可以用来被链接成可执行文件或共享目标文件,静态链接库也属于这一类。
  2. 可执行文件:可直接执行的文件。
  3. 共享目标文件:该文件包含了代码和数据。一.链接器可以使用这种文件跟其他的可重定位文件和目标文件链接产生新的目标文件。二. 动态链接器可以将这几个共享目标文件与可执行文件结合,作为进程映像的一部分来运行。
  4. 核心转储文件:当进程意外终止时,系统可以将该进程的地址的地址空间的内容和终止时的一些其他信息转储到核心存储文件。

 

目标文件是什么样子的--》分段 section。

文件头 代码段 数据段 bss段 roadata段 自定义段 其他段

文件头:描述了整个文件的属性,文件类型(.o .so 可执行文件等),包括是否可执行,以及段表(描述各个段的数组)。文件头中定义了ELF魔数、文件机器字节长度、数据存储方式、版本、运行平台、ABI版本、ELF重定位类型、硬件平台、硬件平台版本、入口地址、程序头入口和长度、段表的位置和长度及段的数量等

文件头--》有规定的结构体

 

(linux 下找的)

.text:一般c语言编译后的机器码都保存在.text段

.data:已初始化的全局变量和局部静态变量都保存在.data段

.bss:未初始化的全局变量和局部静态变量都保存在.bss段

.roadata:字面量,cnost 常量可以保存在.roadata段,只读段,操作系统在加载只读段时可以将该段的映射属性改成只读,这样操作系统的层面上就保证了不会修改。具体可能设计到特权级和一些属性。
 
为什么把程序的指令和数据分开,不直接合在一起?
  1. 程序被装载后,数据和指令可被映射到只读和可写内存区域,操作系统会保护指令不被修改。 
  2. CPU的缓存体系,数据和指令分离可以提高缓存命中率。
  3. 进程可共享指令,节约内存。
示例:

 

段:是除了文件头之外最重要的结构,包含描述各个段的段名,长度,在文件中的偏移量,读写权限及其他属性。

  1. 段名:其实是一个下标,指示段名这个字符串在字符串表的位置。
  2. 段虚拟地址:如果该段可以被加载,则存储了该段在进程中虚拟空间的地址。
  3. 段偏移:表示该段在文件中的偏移。
  4. 段的类型:指示该段的类型。
  5. 段的标志位:指示该段在进程虚拟空间的属性,是否可写,是否可执行等。

个人理解:段表--结构体数组(段描述符)

 

 

字符串表:ELF中用到了很多字符串,比如段名,变量名,把这些字符串放在一个表中来表示即为字符串表。段名字符串就放在段名字符串表中。字符串表和段名字符串表本身也是ELF文件中的一个普通的段。字符串表和符号表配合工作

 

重定位表:链接的时候需要对有绝对引用的位置进行重定位,对于每个需要重定位的代码段或数据段都会有一个相应的重定位表。

 

  只要分析文件头就可以得到段表和字符串表从而解析整个文件。ELF文件头的最后一个成员就是字符串段在段表中的下标

 

  主要介绍了ELF文件的代码段、数据段和BSS段等与程序运行密切相关的段结构。和ELF文件的文件头、段表、重定位表、字符串表、符号表、调试表等相关结构。我们可以了解到,无论是可执行文件、目标文件或库,它们实际上都是基于段的文件或是这种文件的集合。程序的源代码经过编译以后,按照代码和数据分别存放到相应的段中,编译器(汇编器)还会将一些辅助性的信息,诸如符号、重定位信息等也按照表的方式存放到目标文件中,而通常情况下,一个表往往就是一个段。

posted @   stu--wy  阅读(182)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示