欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 啥是目标文件?目标文件里面有什么?

啥是目标文件?目标文件里面有什么?

2025/2/23 1:17:47 来源:https://blog.csdn.net/cl965081198/article/details/145652244  浏览:    关键词:啥是目标文件?目标文件里面有什么?

从c++文件到二进制可执行文件主要经过预处理、编译、汇编和链接的过程,而在这些过程中参与到的文件类型主要有源文件、头文件、目标文件、静态库、动态库和可执行文件。下面表格对这些文件的生成过程和涉及到的步骤名称做个总结。

过程涉及文件
编译source + header -> .s 对源文件和头文件进行预处理和编译,生成汇编代码文件。
汇编.s -> .o 对汇编代码进行汇编生成目标文件,目标文件中存储的已经是机器语言了。
链接(.o -> .a )/(.o -> .so)/ (.o + .a + .so-> executable) 目标文件可以链接成静态库或者动态库,也可以和静态库和动态库链接成为可执行文件

从上面的编译过程我们可以看出目标文件在编译过程中扮演了一个非常重要的角色。我们在编译过程中只需要一条指令就能够直接从源码生成可执行文件,往往忽略了在其中产生重要作用的目标文件。如果想要搞懂编译的原理和程序运行的底层逻辑,目标文件是我们绕不过去的一道坎。下面我们来分析一下目标文件到底是什么样的,以及在编译过程中起到了什么样的作用。

1. 目标文件是什么样的?

目标文件是以段的形式存储的,而不同段的内容都是不同的,例如代码和数据会放在不同的段。目标文件的开头是一个“文件头”,它描述了该文件是否可执行、是静态库还是动态库以及入口地址(如果是可执行文件)、目标硬件、目标操作系统等信息。之所以文件头会存储这么多看似和目标文件无关的信息是因为静态库、动态库和可执行文件都是同一种文件格式,叫做ELF。 这些冗余信息都是用来解析ELF文件的具体类型的。文件头还包括段表,一个描述文件中各个段的数据的数组。段表描述了文件中各个段在文件中的偏移位置及段的属性等。

int printf(const char* format, ...);int global_init_var = 84; //global variable inited
int global_uninit_var; //global variable uninitedvoid func1(int i) //function in the object
{printf("%d\n", i); //call function out of the object
}int main(void)
{static int static_var = 85;static int static_var2;int a = 1;int b;func1(static_var + static_var2 + a + b); //call function in the objectreturn a;
}

使用$ gcc -c SimpleSection.cpp命令编译这个文件可以得到SimpleSection.o文件。
使用$ objdump -h SimpleSection.o查看目标文件的结构。需要注意的是,这条命令是对目标文件的文件头中的段表进行解析。
目标文件
解析得到的表的各列的信息为:

IdxNameSizeVMALMAFile offAlgn
索引段名段的长度虚拟地址加载地址偏移地址对齐

根据我们获得的各个段的信息我们可以得到目标文件大致的结构如下图所示:
elf结构
上面需要注意的是.bss段在elf中并不存在所以它的属性里面并没有content字段。.bss段是用来为未初始化的全局变量和局部静态变量预留位置而已,会在加载过程中用到。还有两块padding指的是对齐产生的空白段,第一段是.data进行4字节对齐产生的,第二段是.note.gnu.property进行8字节对齐产生的。

2. 各个段解析

2.1 .text段

2.2 .data段

2.3 .bss段

3. ELF文件结构解析

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词