Linux-gcc编译
- gcc编译流程
- ELF文件分类
- 总结
gcc编译流程
a. 头文件.h和.c源文件 通过gcc 编译成.o可重定位文件目标文件(如:gcc -c -fPIC process.c)
b. 可重定位文件.o 通过ar归档生成静态链接库.a文件(如:ar cr libstaticprocess.a process.o)。可执行程序编译: gcc -o staticcreateprocess createprocess.o -L. -lstaticprocess
c. 或者将.o文件编译成动态链接库.so文件 (如:gcc -shared -fPIC -o libdynamicprocess.so process.o)。可执行程序编译 (gcc -o dynamiccreateprocess createprocess.o -L. -ldynamicprocess)。执行需要添加环境变量 export LD_LIBRARY_PATH=.
d. 静态链接库.a 在编译过程就将函数调用情况链接。动态链接库.so在运行工作中动态链接函数
ELF文件分类
a. 第一种.o可重定位目标文件
* .text 放编译好的二进制可执行代码
* .data 已经初始化好的全局变量
* .rodata 只读数据,例如字符串常量、const 的变量
* .bss 未初始化全局变量,运行时会置 0
* .symtab 符号表,记录的则是函数和变量
* .strtab 字符串表、字符串常量和变量名
* .rel .text 与重定位相关
* .rel .data 与重定位相关
b. 第二种可执行文件 section节被分成了需要加载到内存里面的代码段、数据段和不需要加载到内存里面的部分,将小的 section 合成了大的段 segment,并且在最前面加一个段头表(Segment Header Table)。在 ELF 头里面,有一项 e_entry,也是个虚拟地址,是这个程序运行的入口。
c. 第三种动态链接库,也就是共享对象文件
* 首先,多了一个.interp 的 Segment,这里面是 ld-linux.so,这是动态链接器,也就是说,运行时的链接动作都是它做的。
* ELF 文件中还多了两个 section,一个是.plt,过程链接表(Procedure Linkage Table,PLT),一个是.got.plt,全局偏移量表(Global Offset Table,GOT)