Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

关于链接的一些总结

一盏淡酒、醉了夕阳 2019-01-26 15:52:00 阅读数:196 评论数:0 点赞数:0 收藏数:0

1.程序的编译过程

  假设现在有如下两个c程序文件,sum.c内容如下:

int sum(int *a, int n){
int i, s = 0;
for( i = 0; i < n ; i++){
s += a[i];
}
return s;
}

主程序main.c的内容如下:

int sum(int *a,int n);
int array[2] = {1, 2};
int main(){
int val = sum(array,2 );
return val;
}

在linux上执行如下语句:

gcc -Og -o prog main.c sum.c

以main.c为例,程序首先调用C预处理器,将main.c翻译成一个Ascii码的中间件,mian.i,接下来将main.i翻译成一个汇编语言文件main.s,然后调用汇编器将main.s翻译可重定位的目标文件main.o,同理会生成相应的sum.o文件。最后,运行链接器程序ld,将main.o和sum.o以及一些必要的文件组合起来,创建一个可执行文件prog。

在构造可执行文件的时候,链接器要完成两个任务:

1、符号解析,符号解析的目的是将每个全局符号引用与符号定义关联起来,即可重定位的目标文件定义了符号,而可执行的目标文件引用符号,将两者的符号相互绑定,这里的符号对应一个函数、一个全局变量、或者一个静态变量。

2、重定位,编译器和汇编器生成从0开始的的代码和数据节,链接器将符号定义和内存的位置关联起来来重定位代码和数据节,然后修改所有这些对符号的引用,使得它们指向内存的位置。

2.一些基础知识

目标文件有三种类型:

可重定位的目标文件:包含二进制数据和代码,其形式可以在编译时与其他可重定位合并起来,创建一个可执行的目标文件

可执行的目标文件:包含二进制和代码,可以直接复制到内存并执行

共享目标文件:一类特殊的可重定位目标文件,可以在加载或者运行时被动态的加载到内存执行。

一个典型的ELF(可执行、可链接格式)的可重定位目标文件包含几个重要的部分,如下图:

 

.text 已编译程序的机器代码

.data 已初始化的全局和静态C变量,局部C变量的值保存在栈中。

.bss 未初始化的全局和静态C变量,以及所有被初始化为0的静态或全局变量。

.sysmtab 一个符号表,存放程序中定义和引用的函数以及全局或静态变量,不包含局部变量的信息。

 

对重定位的理解,在重定位,有两个步骤。

首先重定位节和符号定义,链接器将不同目标文件所有相同类型的节合并到同一个新的聚合节中,例如,来自所有输入模块的.data节会被合并到同一个节中。然后链接器将运行时内存的地址赋给新的聚合节,赋给输入模块中定义的那个节和其中定义的每个符号。此时,程序中的每条指令和全局变量都有一个唯一的运行时内存了。

其次是重定位符号的引用,修改数据节和代码节中符号的引用,使得他们指向正确的运行时内存地址。

 

处理目标文件的一些工具,如下:

AR :创建静态库,插入、删除、列出和提取成员。

NM :列出一个目标文件的符号表中定义的符号。

LDD :列出一个可执行程序文件在运行时所需的共享库。

 

 

收藏:不周山之读薄 CSAPP

参考:《深入理解计算机系统》

版权声明
本文为[一盏淡酒、醉了夕阳]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/helloworldcode/p/10323657.html

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;

支付宝红包,每日可领