本文共 2649 字,大约阅读时间需要 8 分钟。
上一篇文章学习了链接器之-main函数不是第一个执行的函数:
今天继续学习链接器,学习链接是如何动作的,从而引入链接脚本的概念。本文就学习链接脚本的概念。
我们都知道可重定位文件经过链接器链接后最终形成可执行文件。这个链接的过程大概就是分为符号解析和重定位。
那么链接器到底是如何工作的呢?这取决于链接脚本。我们可以看下图:
几个可重定位文件与相应的库文件进行链接,链接器经过链接器的指导,最终形成可执行程序。
在学习链接链接脚本的大致格式之前,先练总结一下链接脚本的几个作用(实际上这些作用我们都知道,只不过今天才知道链接脚本的存在而已):
链接脚本用于描述链接器处理目标文件(可重定位文件)与库文件的方式
链接脚本也就是一个脚本文件,语法比较简单,下面我们直接看一个例子,来说明一个链接脚本大致有哪些内容:
上述的的描述还是很全面很仔细的。我们主要注意一下几点:
我们现在可能还不理解上面的几条注意事项,但是经过下面的例子,就一定可以理解了:
我们写了如下的C程序与链接脚本:
8-1.c
#includeint s1;extern int s2;int main(){ printf("&s1 = %p\n", &s1); printf("&s2 = %p\n", &s2); return 0;}
8-1.lds
SECTIONS{ .text 0x08048400: { *(.text) } . = 0x01000000; s1 = .; . += 4; s2 = .; .data 0x0804a800: { *(.data) } .bss : { *(.bss) }}
我们看上面的程序,在C程序中有一个extern int s2;
这个s2不是这个C文件的,是外部文件的,很明显,我们只有两个文件,另一个就是我们指定的链接脚本文件。
使用下述命令进行编译:
生成可执行程序lyy
(注意如果编译的时候不加上我们自己定义的链接脚本,编译就会出错)
运行:
执行结果为:
很明显,s1的地址由于我们再链接脚本中指定了:
. = 0x01000000; s1 = .;
所以s1的地址是:0x01000000;
而由于在链接脚本中有如下的两句话:
. += 4; s2 = .;
所以s2的地址为:0x01000004;
如果我们不使用链接脚本指定这两个变量的地址,那么他们的地址就是随机的,这也符合我们平时的结果。
不知道是否还记得在上一篇文章中:。我们学习了程序的执行流程,知道了main函数并不是真正的第一个开始执行的函数。而且我们有办法在编译程序的时候改变第一个执行的程序。那个时候使用的是在编译的时候指定入口函数的地址,就像下面这样:
今天我们来学习另一种方法,来修改程序的入口函数。
那就是在链接脚本中指定,大概格式如下:
下面给出一个例子,这个例子中没有main函数,我们自己指定一个函数,然后将它设为入口函数:
8-2.c
#include#include int program(){ printf("D.T.Software\n"); exit(0);}
8-2.lds
ENTRY(program)SECTIONS{ .text 0x08048400: { *(.text) }}
使用下面命令进行编译(也可以先编译输出目标文件,然后进行链接,下面的命令直接一步完成而已):
没有报错,生成了可执行文件lyy2
运行程序结果为:
很明显,我们利用这个方法成功修改了这个C程序的入口函数。
为了更加深入,我们可以看看该可执行程序的符号信息:
使用以下命令查看可执行程序lyy2
由于上面的8-2.lds链接脚本指定代码段其实地址为: 0x08048400
,而我们的可执行程序的入口函数(program函数)的地址其实就是代码段(.text)地址,所以如上图,T代表代码段,地址为0x08048400。很完美的解释。
上面我们学习了链接脚本的各种知识,但是我们平时并没有使用它或者看到它。但是这并不意味着学习它就没有用处。它对于我们理解整个系统原理有很大帮助。
可以使用下面的命令查看默认的链接脚本:
上述命令将默认的链接脚本输出到文件defaults.lds文件中,我们可以打开defaults.lds文件来查看默认链接脚本文件。
记住,我们在学习的内容是可以让你走的更远,走的更高的铺垫。或许对你产生不了直接的影响,但是绝对会对你将来的学习之路产生深远的影响。不要一口吃一个胖子,慢慢来,从应用软件做起,深入学习底层原理!你的未来一定更加美好!!!
本文参考狄泰软件学院相关课程
想学习的可以加狄泰软件学院群, 群聊号码:199546072学习探讨加个人(可以免费帮忙下载CSDN资源):
qq:1126137994 微信:liu1126137994转载地址:http://mbytf.baihongyu.com/