编译
大多数编译系统提供编译驱动程序,用户在需要的时候调用预处理器(cpp),编译器(ccl),汇编器(as),连接器(ld)。
目标文件有三种类型
可重定位的目标文件 包含二进制的代码和数据,起形式可以再编译时与其他重定位目标文件合并起来,创建一个可执行的目标文件。
可执行的目标文件 包含二进制的代码和数据,其形式可以直接被拷贝至存储器中执行。
共享目标文件 一种特殊类型的可重定位的目标文件,可以再加载或者运行时被动态的加载到存储器并连接。
编译器和汇编器可以生成可重定位的目标文件(包括共享目标文件),连接器可生成可执行的目标文件。
可重定位的目标文件 ELF 可重定位目标文件的格式
ELF头 以一个16字节的序列开始,这个序列描述了生成该文件的系统的字的大小和字节的顺序。ELF头剩下的vyfeb包含帮助连接器语法分析和解释目标文件的信息。其中包括ELF头的大 小,,目标文件的类型(可重定位,可执行,共享),机器类型,节头部表的文件偏移,以及节头部表中条目的大小和数量。不同节的位置和大小是由节头部表表述的,其中,目 标文件中每个节都有一个固定大小的条目。
.text 已编译程序的机器码
.rodata 只读数据,比如printf语句中的格式串和开关语句的跳转表
.data 已初始化的C全局变量。局部C变量在运行时保存在栈中,既不出现在.data中也不出现在.bss中
.bss 未初始化的全局C变量。在目标文件中,这个节不占据实际的空间,他仅仅是一个占位符。目标文件区分初始化变量和未初始化变量是为了空间效率,在目标文件中,未初始化变量不
不需要占据任何实际的磁盘空间。
.symtab 一个符号表,他存放程序中定义和引用的函数和全局变量的信息,和编译器中的符号表不同,改符号表中不包含局部变量的条目
.rel.text .text节中位置的列表,当连接器把这个目标文件和其他文件结合的时候,需要修改这个位置。
.rel.data 被模块引用或者任何全局变量重定位的信息。
.debug
.line
.strtab
符号和符号表
每一个可重定位目标模块m都有一个符号表,他包含m所定义可引用的符号的信息,在连接器的上下文中,有三种不同的符号:
由m定义并能被其他模块引用的全局符号 全局连接器符号对应于非静态的C函数以及被定义为不带C static 属性的全局变量
由其他模块定义,并被m引用的全局符号 这些符号成为外部符号,external,对应于定义在其他模块中的C函数和变量
只被m定义和引用的本地符号 对应于带static属性的C 函数和全局变量,这些符号在m中可见,但是不能被其他模块引用。