第4章程序的链接详版课资

上传人:人*** 文档编号:569729190 上传时间:2024-07-30 格式:PPT 页数:49 大小:1.05MB
返回 下载 相关 举报
第4章程序的链接详版课资_第1页
第1页 / 共49页
第4章程序的链接详版课资_第2页
第2页 / 共49页
第4章程序的链接详版课资_第3页
第3页 / 共49页
第4章程序的链接详版课资_第4页
第4页 / 共49页
第4章程序的链接详版课资_第5页
第5页 / 共49页
点击查看更多>>
资源描述

《第4章程序的链接详版课资》由会员分享,可在线阅读,更多相关《第4章程序的链接详版课资(49页珍藏版)》请在金锄头文库上搜索。

1、本学期考核方法本学期考核方法本学期平时分占本学期平时分占60%,期末考试占,期末考试占40%小测试共小测试共2次,每次次,每次6分,共分,共20分分作业加考勤基础分作业加考勤基础分20分,少一次扣分,少一次扣4分,作业不交加考勤分,作业不交加考勤不到场超过不到场超过5次将取消考试资格。次将取消考试资格。实验课有两个实验,每次实验课有两个实验,每次10分,共分,共20各种加分,回答问题,实验提前做完等。各种加分,回答问题,实验提前做完等。期末考试形式为闭卷考试期末考试形式为闭卷考试1课堂优质第四章第四章 程序的链接程序的链接目标文件格式符号解析与重定位共享库与动态链接2课堂优质可执行文件的链接生

2、成可执行文件的链接生成主要教学目标使学生了解链接器是如何工作的,从而能够养成良好的程序设计习惯,并增加程序调试能力。通过了解可执行文件的存储器映像来进一步深入理解进程的虚拟地址空间的概念。包括以下内容链接和静态链接概念三种目标文件格式符号及符号表、符号解析使用静态库链接重定位信息及重定位过程可执行文件的存储器映像可执行文件的加载共享(动态)库链接3课堂优质程序的链接程序的链接分以下三个部分介绍第一讲:目标文件格式程序的链接概述、链接的意义与过程ELF目标文件、重定位目标文件格式、可执行目标文件格式第二讲:符号解析与重定位符号和符号表、符号解析与静态库的链接重定位信息第三讲:动态链接动态链接的特

3、性、程序加载时的动态链接、程序运行时的动态链接4课堂优质一个典型程序的转换处理过程一个典型程序的转换处理过程1 #include 23 int main()4 5 printf(hello, worldn);6 经典的经典的“ hello.c ”C-源程序源程序# i n c l u d e n n i n t m a i n ( ) n 104 62 10 10 105 110 116 32 109 97 105 110 40 41 10 123n p r i n t f ( h e l10 32 32 32 32 112 114 105 110 116 102 40 34 104 101

4、108l o , w o r l d n ) ; n 108 111 44 32 119 111 114 108 100 92 110 34 41 59 10 125hello.c的的ASCII文本表示文本表示计算机能够直接识计算机能够直接识别别hello.c源程序吗源程序吗?不能,需要转换为机器语言不能,需要转换为机器语言代码代码! ! 即:编译、汇编等即:编译、汇编等功能:输出功能:输出“hello,world”5课堂优质一个一个C语言程序举例语言程序举例intbuf2=1,2;voidswap();intmain()swap();return0;main.cswap.cexternint

5、buf;int*bufp0=&buf0;staticint*bufp1;voidswap()inttemp;bufp1=&buf1;temp=*bufp0;*bufp0=*bufp1;*bufp1=temp;(1)预处理(cpp)。在高级语言源程序中插入所有用#include命令指定的文件和用#define声明指定的宏。(2)编译(cc1)。将预处理后的源程序文件编译生成相应的汇编语言程序。(3)汇编(as)。由汇编程序将汇编语言源程序文件转换为可重定位目标文件。(4)链接(ld)。由链接器将多个可重定位目标文件及库例程(如printf.o)链接起来,生成可执行文件。6课堂优质可执行文件的生成

6、可执行文件的生成使用GCC编译器编译并链接生成可执行程序P:unixgcc-O2-g-opmain.cswap.cunix./pLinker(ld)Translators(cpp,cc1,as)main.cmain.oTranslators(cpp,cc1,as)swap.cswap.opSourcefilesSeparatelycompiledrelocatableobjectfilesFullylinkedexecutableobjectfile(containscodeanddataforallfunctionsdefinedinmain.candswap.c)GCC编译器的静态链接过程

7、7课堂优质引用符号的地址需要重定位引用符号的地址需要重定位main()main.oint*bufp0=&buf0swap()swap.oSystemcodeint buf2=1,2System data可重定位目标文件可执行目标文件.text.data.text.data.text.dataintbuf2=1,2Headersmain()swap()0int *bufp0=&buf0Moresystem codeSystem data.text.symtab.debug.dataint*bufp1.bssSystem codestaticint*bufp1.bss虽然是swap的本地符号,也需

8、在.bss节重定位8课堂优质使用链接的优点使用链接的优点链接带来的好处1:模块化(1)一个程序可以分成很多源程序文件(2)可构建公共函数库,如数学库,标准C库等链接带来的好处2:效率高(1)时间上,可分开编译只需重新编译修改的源程序文件,然后重新链接(2)空间上,无需包含共享库所有代码源文件中无需包含共享库函数的源码,只要直接调用即可可执行文件和运行时的内存中只需包含所调用函数的代码而不需要包含整个共享库9课堂优质链接操作的步骤链接操作的步骤Step1.符号解析(Symbolresolution)程序中有定义和引用的符号(包括变量和函数等)voidswap()/*定义符号swap*/swap(

9、);/*引用符号swap*/int*xp=&x;/*定义符号xp,引用符号x*/编译器将定义的符号存放在一个符号表(symboltable)中.符号表是一个结构数组每个表项包含符号名、长度和位置等信息链接器将每个符号的引用都与一个确定的符号定义建立关联Step2.重定位将多个代码段与数据段分别合并为一个单独的代码段和数据段将.o文件中每个符号的相对位置重定位为可执行文件中的绝对存储位置将原来符号表中的位置信息修改为重定位后的位置信息10课堂优质三类目标文件三类目标文件 可重定位目标文件(.ofile)其代码和数据可和其他可重定位文件合并为可执行文件每个.o文件由对应的.c文件生成每个.o文件代

10、码和数据地址都从0开始可执行目标文件(.afile)包含的代码和数据可以被直接复制到内存并被执行代码和数据地址为虚拟地址空间中的地址共享的目标文件(.sofile)特殊的可重定位目标文件,能在装入或运行时被装入到内存并自动被链接Windows中称其为DynamicLinkLibraries(DLLs) 11课堂优质00000000:0:55 push%ebp1:89e5mov%esp,%ebp3:83ec10sub$0x10,%esp6:8b450cmov0xc(%ebp),%eax9:8b5508mov0x8(%ebp),%edxc:8d0402lea(%edx,%eax,1),%eaxf:

11、8945fcmov%eax,-0x4(%ebp)12:8b45fcmov-0x4(%ebp),%eax15:c9leave16:c3ret080483d4:80483d4:55push%ebp80483d5:89e5mov%esp,%ebp80483d7:83ec10sub$0x10,%esp80483da:8b450cmov0xc(%ebp),%eax80483dd:8b5508mov0x8(%ebp),%edx80483e0:8d0402lea(%edx,%eax,1),%eax80483e3:8945fcmov%eax,-0x4(%ebp)80483e6:8b45fcmov-0x4(%e

12、bp),%eax80483e9:c9leave80483ea:c3retobjdump-dtest.o objdump-dtest /*main.c*/intadd(int,int);intmain()returnadd(20,13);/*test.c*/intadd(inti,intj)intx=i+j;returnx;12课堂优质Executable and Linkable Format (ELF)两种视图链接视图:Relocatableobjectfiles执行视图:Executableobjectfiles节(section)是ELF文件中具有相同特征的最小可处理单位.text节:代

13、码.data节:数据.rodata:只读数据.bss:未初始化数据由不同的段(segment)组成,描述节如何映射到存储段中,可多个节映射到同一段,如:可合并.data节和.bss节,并映射到一个可读可写数据段中 链接视图执行视图13课堂优质可重定位目标文件格式可重定位目标文件格式ELF头占16字节,包括字长、字节序(大端/小端)、文件类型(.o,exec,.so)、机器类型(如IA-32)、节头表的偏移、节头表的表项大小及表项个数.text节编译后的代码部分.rodata节只读数据,如printf格式串、switch跳转表等.data节已初始化的全局变量.bss节未初始化全局变量,仅是占位符

14、,不占据任何实际磁盘空间。目标文件格式区分初始化和非初始化是为了空间效率ELFheader.textsection.rodatasection.bsssection.symtabsection.rel.txtsection.rel.datasection.debugsectionSectionheadertable0.datasection.strtabsection.linesection14课堂优质可重定位目标文件格式可重定位目标文件格式.symtab节存放函数和全局变量(符号表)信息,它不包括局部变量条目.rel.text节.text节的重定位信息,用于重新修改代码段的指令中的地址信息.

15、rel.data节.data节的重定位信息,用于对被模块使用或定义的全局变量进行重定位的信息.debug节调试用符号表(gcc-g)strtab节包含symtab和debug节中符号及节名Sectionheadertable(节头表)每个节的节名、偏移和大小ELFheader.textsection.rodatasection.bsssection.symtabsection.rel.txtsection.rel.datasection.debugsectionSectionheadertable0.datasection.strtabsection.linesection15课堂优质可执行目

16、标文件格式可执行目标文件格式与.o文件稍有不同:ELF头中字段e_entry给出执行程序时第一条指令的地址,而在可重定位文件中,此字段为0多一个.init节,用于定义_init函数,该函数用来进行可执行目标文件开始执行时的初始化工作少两.rel节(无需重定位)多一个程序头表,也称段头表(segmentheadertable),是一个结构数组16课堂优质可执行文件的存储器映像可执行文件的存储器映像0%esp(栈顶)brk0xC000000000x08048000KernelvirtualmemoryMemory-mappedregionforshared librariesRun-timehea

17、p(createdby malloc)User stack(created at runtime)Unused0Read/write segment(.data,.bss)Read-onlysegment(.init,.text, .rodata)从可执行文件装入程序(段)头表描述如何映射ELFheaderSegmentheadertable.textsection.datasection.bsssection.symtab.debug.rodatasection.line.initsection.strtab17课堂优质可执行文件中的程序头表可执行文件中的程序头表typedefstructE

18、lf32_Wordp_type;Elf32_Offp_offset;Elf32_Addrp_vaddr;Elf32_Addrp_paddr;Elf32_Wordp_filesz;Elf32_Wordp_memsz;Elf32_Wordp_flags;Elf32_Wordp_align;Elf32_Phdr;程序头表能够描述可执行文件中的节与虚拟空间中的存储段之间的映射关系一个表项说明虚拟地址空间中一个连续的片段或一个特殊的节以下是GNUREADELF显示的某可执行目标文件的程序头表信息18课堂优质可执行文件中的程序头表可执行文件中的程序头表程序头表中有8个表项,其中有两个是可装入段(type=

19、LOAD)对应表项。第一可装入段对应第0x000000x004d3字节(包括ELF头、程序头表、.init、.text和.rodata节),映射到虚拟地址0x8048000开始长度为0x4d4字节的区域,按0x1000=212=4K字节对齐,具有只读/执行权限(Flg=RE),是只读代码段(read-onlycode)。第二可装入段对应第0x000f0c开始长度为0x108字节的.data节,映射到虚拟地址0x8049f0c开始的长度为0x110字节的存储区域,在0x110=272字节的存储区中,前0x108=264字节用.data节内容初始化,而后面272-264=8个字节对应.bss节,初

20、始化为0,该段按0x1000=4KB对齐,具有可读可写权限(Flg=RW),因此,它是一个可读写数据段(read/writedatasegment) 。19课堂优质程序的链接程序的链接分以下三个部分介绍第一讲:目标文件格式程序的链接概述、链接的意义与过程ELF目标文件、重定位目标文件格式、可执行目标文件格式第二讲:符号解析与重定位符号和符号表、符号解析与静态库的链接重定位信息第三讲:动态链接动态链接的特性、程序加载时的动态链接、程序运行时的动态链接20课堂优质符号和符号解析符号和符号解析 每个可重定位目标模块m都有一个符号表,它包含了在m中定义和引用的所有符号。有三种链接器符号:Globals

21、ymbols(模块内部定义的全局符号)由模块m定义并能被其他模块引用的符号。例如,非staticC函数和非static的C全局变量(指不带static的全局变量)如,main.c中的全局变量名bufExternalsymbols(外部定义的全局符号)由其他模块定义并被模块m引用的全局符号如,main.c中的函数名swapLocalsymbols(本模块的局部符号)仅由模块m定义和引用的本地符号。例如,在模块m中定义的带static的C函数和全局变量如,swap.c中的static变量名bufp1链接器局部符号不是指程序中的局部变量(分配在栈中的临时性变量),链接器不关心这种局部变量21课堂优质

22、符号和符号解析符号和符号解析intbuf2=1,2;voidswap();intmain()swap();return0;main.cexternintbuf;int*bufp0=&buf0;staticint*bufp1;voidswap()inttemp;bufp1=&buf1;temp=*bufp0;*bufp0=*bufp1;*bufp1=temp;swap.cGlobalExternalExternalLocalGlobal局部变量Global22课堂优质目标文件中的符号表目标文件中的符号表符号表(symtab)中每个条目的结构如下typedefstructintname;/*指向符

23、号对应字符串在strtab节中的偏移*/intvalue;/*在对应section中的偏移量,可执行文件中是虚拟地址*/intsize;/*符号对应目标所占字节数*/chartype:4,/*符号对应目标的类型:数据、函数、源文件、节*/binding:4;/*符号对应目标是全局符号还是局部符号*/charreserved;charsection;/*符号对应目标所在的section,或其他情况*/Elf_Symbol;其他情况:ABS表示不该被重定位;UND表示未定义;COM表示未初始化数据(.bss),此时,value表示对齐要求,size给出最小大小23课堂优质目标文件中的符号表目标文件

24、中的符号表main.o中的符号表中最后三个条目Num:valueSizeTypeBindOtNdxName8:08DataGlobal03buf9:033FuncGlobal 01main10:00Notype Global 0UNDswapswap.o中的符号表中最后4个条目Num:valueSizeTypeBindOtNdxName8:04DataGlobal03bufp09:00NotypeGlobal0UNDbuf10:036FuncGlobal 01swap11:44DataLocal0COMbufp1buf是main.o中第3节(.data)偏移为0的符号,是全局变量,占8B;ma

25、in是第1节(.text)偏移为0的符号,是全局函数,占33B;swap是main.o中未定义的符号,不知道类型和大小,全局的(在其他模块定义)bufp1是未分配地址且未初始化的本地变量(ndx=COM),按4B对齐且占4B24课堂优质符号解析符号解析目的:将每个模块中引用的符号与某个目标模块中的定义符号建立关联。每个定义符号在代码段或数据段中都被分配了存储空间,将引用符号与对应定义符号建立关联后,就可在重定位时将引用符号的地址重定位为相关联的定义符号的地址。本地符号在本模块内定义并引用,因此,其解析较简单,只要与本模块内唯一的定义符号关联即可。全局符号(外部定义的、内部定义的)的解析涉及多个

26、模块,故较复杂 “符号的定义”其实质是什么?是指符号被分配了虚拟地址空间。符号为函数名即指其代码所在区;符号为变量即指其占的静态数据区。25课堂优质全局符号的符号解析全局符号的符号解析全局符号的强/弱特性函数名和已初始化的全局变量名是强符号未初始化的全局变量名是弱符号 intfoo=5;p1()intfoo;p2()p1.cp2.cstrongweakstrongstrong以下符号哪些是强符号?哪些是弱符号?26课堂优质全局符号的符号解析全局符号的符号解析intbuf2=1,2;voidswap();intmain()swap();return0;main.cexternintbuf;int

27、*bufp0=&buf0;staticint*bufp1;voidswap()inttemp;bufp1=&buf1;temp=*bufp0;*bufp0=*bufp1;*bufp1=temp;swap.c强符号此处为引用弱符号本地符号强符号局部变量强符号以下符号哪些是强符号?哪些是弱符号?27课堂优质链接器对符号的解析规则链接器对符号的解析规则多重定义符号的处理规则Rule1:强符号不能多次定义强符号只能被定义一次,否则链接错误Rule2:若一个符号被定义为一次强符号和多次弱符号,则按强定义为准对弱符号的引用被解析为其强定义符号Rule3:若有多个弱符号定义,则任选其中一个使用命令gccfn

28、o-common链接时,会告诉链接器在遇到多个弱定义的全局符号时输出一条警告信息。28课堂优质多重定义符号的解析举例多重定义符号的解析举例intx=10;intp1(void);intmain()x=p1();returnx;main.cintx=20;intp1()returnx;p1.cmain只有一次强定义p1有一次强定义,一次弱定义x有两次强定义,所以,链接器将输出一条出错信息以下程序会发生链接出错吗?29课堂优质多重定义符号的解析举例多重定义符号的解析举例p1.cy一次强定义,一次弱定义z两次弱定义p1一次强定义,一次弱定义main一次强定义#includeinty=100;intz

29、;voidp1(void);intmain()z=1000;p1();printf(“y=%d,z=%dn”,y,z);return0;main.cinty;intz;voidp1()y=200;z=2000;问题:打印结果是什么?y=200,z=2000以下程序会发生链接出错吗?该例说明:在两个不同模块定义相同变量名,很可能发生意想不到的结果!30课堂优质多重定义符号的解析举例多重定义符号的解析举例p1.c该例说明:两个重复定义的变量具有不同类型时,更容易出现难以理解的结果 ! main.c问题:打印结果是什么?d=0,x=1072693248 以下程序会发生链接出错吗?1#include2

30、intd=100;3intx=200;4voidp1(void);5intmain()67p1();8printf(“d=%d,x=%dn”,d,x);9return0;101doubled;23voidp1()45d=1.0;6p1执行后d和x处内容是什么?FLD1FSTPl&d1.0:00111111111100B=3FF0000000000000H31课堂优质多重定义符号的解析举例多重定义符号的解析举例打印结果:打印结果:d=0,x=1 072 693 248Why? 1doubled;23voidp1()45d=1.0;6.1intd=100;2intx=200;3intmain()4

31、5p1();6printf(“d=%d,x=%dn”,d,x);7return0;8main.c p1.c理解该问题需要知道:理解该问题需要知道:机器级数据的表示与存储机器级数据的表示与存储链接器的符号解析规则链接器的符号解析规则double型数1.0对应的机器数3FF0000000000000H低高IA-32是小端方式32课堂优质多重定义全局符号的问题多重定义全局符号的问题尽量避免使用全局变量一定需要用的话,就按以下规则使用尽量使用本地变量(static)全局变量要赋初值外部全局变量要使用extern多重定义全局变量会造成一些意想不到的错误,而且是默默发生的,编译系统不会警告,并会在程序执行

32、很久后才能表现出来,且远离错误引发处。特别是在一个具有几百个模块的大型软件中,这类错误很难修正。大部分程序员并不了解链接器如何工作,因而养成良好的编程习惯是非常重要的。33课堂优质头文件(头文件(.h文件)的作用文件)的作用#includeglobal.hintf()returng+1;c1.cglobal.h#ifdefINITIALIZEintg=23;staticintinit=1;#elseintg;staticintinit=0;#endif#include#includeglobal.hintmain()if(!init)g=37;intt=f();printf(Callingfy

33、ields%dn,t);return0;c2.c34课堂优质预处理操作预处理操作#includeglobal.hintf()returng+1;c1.cglobal.h#ifdefINITIALIZEintg=23;staticintinit=1;#elseintg;staticintinit=0;#endifintg=23;staticintinit=1;intf()returng+1;intg;staticintinit=0;intf()returng+1;定义INITIALIZE没有定义INITIALIZE#include指示被执行,插入.h文件的内容到源文件中35课堂优质如何划分模块?

34、如何划分模块?许多函数无需自己写,可使用共享库函数Math,I/O,memorymanagement,stringmanipulation,etc.避免以下两种极端做法将所有函数都放在一个源文件中修改一个函数需要对所有函数重新编译时间和空间两方面的效率都不高一个函数放在一个源文件中需要程序员显式地进行链接效率高,但模块太多,故太繁琐36课堂优质静态共享库静态共享库静态库(.aarchivefiles)将所有相关的目标模块打包为一个单独的文件,称为静态库文件,也称为存档文件(archive)增强链接器功能,使其能通过查找一个或多个库文件中的符号来解析符号在构建可执行文件时只需指定库文件名,链接器

35、会自动到库中寻找那些应用程序用到的目标模块,并且只把用到的模块从库中拷贝出来在gcc命令行中无需明显指定C标准库libc.a(默认库)37课堂优质静态库的创建静态库的创建Translatoratoi.catoi.oTranslatorprintf.cprintf.olibc.aArchiver(ar).Translatorrandom.crandom.ounixarrslibc.aatoi.oprintf.orandom.oCstandardlibraryArchiver(归档器)允许增量更新,只要重新编译需修改的源码并将其.o文件替换到静态库中。38课堂优质自定义一个静态库文件自定义一个静态

36、库文件#includevoidmyfunc1()printf(%s,Thisismyfunc1!n);#includevoidmyfunc2()printf(%s,Thisismyfunc2n);gcccmyproc1.cmyproc2.carrcsmylib.amyproc1.omyproc2.omyproc1.cmyproc2.c39课堂优质链接器中符号解析的全过程链接器中符号解析的全过程 voidmyfunc1(viod);intmain()myfunc1();return0;main.c调用关系:mainmyfunc1printfgcccmain.cgccstaticomyprocma

37、in.o./mylib.a开始E、U、D为空,首先扫描main.o,把它加入E,同时把myfun1加入U,main加入D。接着扫描到mylib.a,将U中所有符号(本例中为myfunc1)与mylib.a中所有目标模块(myproc1.o和myproc2.o)依次匹配,发现在myproc1.o中定义了myfunc1,故myproc1.o加入E,myfunc1从U转移到D。在myproc1.o中发现还有未解析符号printf,将其加到U。不断在mylib.a的各模块上进行迭代以匹配U中的符号,直到U、D都不再变化。此时U中只有一个未解析符号printf,而D中有main和myfunc1。因为模块

38、myproc2.o没有被加入E中,因而它被丢弃。E将被合并以组成可执行文件的所有目标文件集合U当前所有未解析的引用符号的集合D当前所有定义符号的集合接着,扫描默认的库文件libc.a,发现其目标模块printf.o定义了printf,于是printf也从U移到D,并将printf.o加入E,同时把它定义的所有符号加入D,而所有未解析符号加入U。处理完libc.a时,U一定是空的。 libc.a无需明显指出!40课堂优质链接器中符号解析的全过程链接器中符号解析的全过程 main.cvoidmyfunc1(viod);intmain()myfunc1();return0;gcccmain.cgcc

39、staticomyprocmain.o./mylib.a问题:若命令为:gccstaticomyproc./mylib.amain.o,结果怎样?main.o中的myfunc1不能被解析,故出现链接错误!41课堂优质链接顺序问题链接顺序问题假设调用关系如下:func.o libx.a和liby.a中的函数libx.alibz.a中的函数libx.a和liby.a之间、liby.a和libz.a相互独立则以下几个命令行都是可行的:gcc-staticomyfuncfunc.olibx.aliby.alibz.agcc-staticomyfuncfunc.oliby.alibx.alibz.agc

40、c-staticomyfuncfunc.olibx.alibz.aliby.a假设调用关系如下:func.o libx.a和liby.a中的函数libx.aliby.a同时liby.alibx.a则以下命令行可行:gcc-staticomyfuncfunc.olibx.aliby.alibx.a42课堂优质重定位重定位符号解析完成后,可进行重定位工作,分两步对节和定义符号进行重定位将集合E的所有目标模块中相同的节合并成新节,并将运行时的虚拟地址赋给每个新节中所有的定义符号。例如,所有.text节合并作为可执行文件中的.text节,并为每个.text节确定在新.text节中的绝对地址,从而为其中

41、定义的函数确定首地址(含有多个函数时),进而确定每条指令的地址。完成这一步后,每条指令和每个全局变量都可确定地址。对节中的引用符号进行重定位修改.text节和.data节中对每个符号的引用(地址)。需要用到在.rel_data和.rel_text节中保存的重定位信息。43课堂优质重定位信息重定位信息汇编器遇到对位置未知的目标引用时,生成一个重定位条目数据引用的重定位条目在.rel_data节中指令中引用的重定位条目在.rel_text节中ELF中重定位条目格式如下:有两种最基本的重定位类型R_386_PC32:使用32位PC相对地址的引用,重定位指令R_386_32:使用32位绝对地址重定位数

42、据typedefstructintoffset;/*需重定位的引用的节偏移*/intsymbol:24,/*需重定位的引用所指向的符号*/type:8;/*重定位类型(即修改方式)*/Elf32_Rel;例如,在rel_text节中有重定位条目offset:0x12symbol:swaptype:R_386_PC32说明在.text节中偏移为0x12的地方需重定位,按PC相对地址方式修改,引用的符号为swap44课堂优质程序的链接程序的链接分以下三个部分介绍第一讲:目标文件格式程序的链接概述、链接的意义与过程ELF目标文件、重定位目标文件格式、可执行目标文件格式第二讲:符号解析与重定位符号和符

43、号表、符号解析与静态库的链接重定位信息第三讲:动态链接动态链接的特性、程序加载时的动态链接、程序运行时的动态链接45课堂优质动态链接的共享库(动态链接的共享库(Shared Libraries) 静态库有一些缺点:静态库中的常用函数(如printf)被包含在每一个运行进程的代码段中,这对于并发运行50-100个进程的系统,造成极大的主存资源浪费程序员需关注是否有新版本出现,并须定期维护和更新链接现代解决方案:SharedLibraries是一个目标文件,包含有代码和数据可以动态地在装入时或运行时被加载并链接也被称为dynamiclinklibraries(动态链接库),DLLs,.sofile

44、s46课堂优质共享库(共享库(Shared Libraries)动态链接可以按以下两种方式进行:在第一次加载并运行时进行(load-timelinking).Linux通常由动态链接器(ld-linux.so)自动处理标准C库(libc.so)通常按这种方式动态被链接在已经开始运行后进行(run-timelinking).在Linux中,通过调用dlopen()接口来实现.Distributingsoftware.High-performancewebservers.Runtimelibraryinterpositioning.共享库例程在系统中只有一个备份,被所有进程共享47课堂优质本章小结

45、本章小结链接处理涉及到三种目标文件格式:可重定位目标文件、可执行目标文件和共享目标文件。共享库文件是一种特殊的可重定位目标。ELF目标文件格式有链接视图和执行视图两种,前者是可重定位目标格式,后者是可执行目标格式。链接视图中包含ELF头、各个节以及节头表执行视图中包含ELF头、程序头表(段头表)以及各种节组成的段链接分为静态链接和动态链接两种静态链接将多个可重定位目标模块中相同类型的节合并起来,以生成完全链接的可执行目标文件,其中所有符号的引用都是在虚拟地址空间中确定的最终地址,因而可以直接被加载执行。动态链接的可执行目标文件是部分链接的,还有一部分符号的引用地址没有确定,需要利用共享库中定义

46、的符号进行重定位,因而需要由动态链接器来加载共享库并重定位可执行文件中部分符号的引用。加载时进行共享库的动态链接执行时进行共享库的动态链接48课堂优质本章小结本章小结链接过程需要完成符号解析和重定位两方面的工作符号解析的目的就是将符号的引用与符号的定义关联起来重定位的目的是分别合并代码和数据,并根据代码和数据在虚拟地址空间中的位置,确定每个符号的最终存储地址,然后根据符号的确切地址来修改符号的引用处的地址。在不同目标模块中可能会定义相同符号,因为相同的多个符号只能分配一个地址,因而链接器需要确定以哪个符号为准。编译器通过对定义符号标识其为强符号还是弱符号,由链接器根据一套规则来确定多重定义符号中哪个是唯一的定义符号,如果不了解这些规则,则可能无法理解程序执行的有些结果。加载器在加载可执行目标文件时,实际上只是把可执行目标文件中的只读代码段和可读写数据段通过页表映射到了虚拟地址空间中确定的位置,并没有真正把代码和数据从磁盘装入主存。49课堂优质

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 资格认证/考试 > 自考

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号