程序的链接和装入及linux下动态链接的实现

程序的链接和装入及linux下动态链接的实现

ID:30441509

大小:86.11 KB

页数:13页

时间:2018-12-30

程序的链接和装入及linux下动态链接的实现_第1页
程序的链接和装入及linux下动态链接的实现_第2页
程序的链接和装入及linux下动态链接的实现_第3页
程序的链接和装入及linux下动态链接的实现_第4页
程序的链接和装入及linux下动态链接的实现_第5页
资源描述:

《程序的链接和装入及linux下动态链接的实现》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、程序的链接和装入及Linux下动态链接的实现程序的链接和装入及Linux下动态链接的实现2003年8月10日程序的链接和装入存在着多种方法,而如今最为流行的当属动态链接、动态装入方法。本文首先回顾了链接器和装入器的基本工作原理及这一技术的发展历史,然后通过实际的例子剖析了Linux系统下动态链接的实现。了解底层关键技术的实现细节对系统分析和设计人员无疑是必须的,尤其当我们在面对实时系统,需要对程序执行时的时空效率有着精确的度量和把握时,这种知识更显重要。一个程序要想在内存中运行,除了编译之外还要经过链接和装入这两个步骤。从程序员的角度来看,引入这两个步骤带来

2、的好处就是可以直接在程序中使用printf和errno这种有意义的函数名和变量名,而不用明确指明printf和errno在标准C库中的地址。当然,为了将程序员从早期直接使用地址编程的梦魇中解救出来,编译器和汇编器在这当中做出了革命性的贡献。编译器和汇编器的出现使得程序员可以在程序中使用更具意义的符号来为函数和变量命名,这样使得程序在正确性和可读性等方面都得到了极大的提高。但是随着C语言这种支持分别编译的程序设计语言的流行,一个完整的程序往往被分割为若干个独立的部分并行开发,而各个模块间通过函数接口或全局变量进行通讯。这就带来了一个问题,编译器只能在一个模块内

3、部完成符号名到地址的转换工作,不同模块间的符号解析由谁来做呢?比如前面所举的例子,调用printf的用户程序和实现了printf的标准C库显然就是两个不同的模块。实际上,这个工作是由链接器来完成的。为了解决不同模块间的链接问题,链接器主要有两个工作要做――符号解析和重定位:符号解析:当一个模块使用了在该模块中没有定义过的函数或全局变量时,编译器生成的符号表会标记出所有这样的函数或全局变量,而链接器的责任就是要到别的模块中去查找它们的定义,如果没有找到合适的定义或者找到的合适的定义不唯一,符号解析都无法正常完成。重定位:编译器在编译生成目标文件时,通常都使用从

4、零开始的相对地址。然而,在链接过程中,链接器将从一个指定的地址开始,根据输入的目标文件的顺序以段为单位将它们一个接一个的拼装起来。除了目标文件的拼装之外,在重定位的过程中还完成了两个任务:一是生成最终的符号表;二是对代码段中的某些位置进行修改,所有需要修改的位置都由编译器生成的重定位表指出。举个简单的例子,上面的概念对读者来说就一目了然了。假如我们有一个程序由两部分构成,m.c中的main函数调用f.c中实现的函数sum:/*m.c*/inti=1;intj=2;externintsum();voidmain()ints;s=sum(i,j);/*f.c*/

5、intsum(inti,intj)returni+j;在Linux用gcc分别将两段源程序编译成目标文件:$gcc-cm.c$gcc-cf.c我们通过objdump来看看在编译过程中生成的符号表和重定位表:$objdump-xm.o…SYMBOLTABLE:…00000000gO.data00000004i00000004gO.data00000004j00000000gF.text00000021main00000000*UND*00000000sumRELOCATIONRECORDSFOR[.text]:OFFSETTYPEVALUE00000007R_

6、386_32j0000000dR_386_32i00000013R_386_PC32sum首先,我们注意到符号表里面的sum被标记为UND(undefined),也就是在m.o中没有定义,所以将来要通过ld(Linux下的链接器)的符号解析功能到别的模块中去查找是否存在函数sum的定义。另外,在重定位表中有三条记录,指出了在重定位过程中代码段中三处需要修改的位置,分别位于7、d和13。下面以一种更加直观的方式来看一下这三个位置:$objdump-dxm.oDisassemblyofsection.text:00000000main:0:55push%ebp1

7、:89e5mov%esp,%ebp3:83ec04sub[message]x4,%esp6:a100000000mov0x0,%eax7:R_386_32jb:50push%eaxc:a100000000mov0x0,%eaxd:R_386_32i11:50push%eax12:e8fcffffffcall13main+0x1313:R_386_PC32sum17:83c408add[message]x8,%esp1a:89c0mov%eax,%eax1c:8945fcmov%eax,0xfffffffc(%ebp)1f:c9leave20:c3ret以su

8、m为例,对函数sum的调用是通过call指令实现的,

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。