计算机系统-从应用程序到底层实现 课件 第17讲 Link-3_第1页
计算机系统-从应用程序到底层实现 课件 第17讲 Link-3_第2页
计算机系统-从应用程序到底层实现 课件 第17讲 Link-3_第3页
计算机系统-从应用程序到底层实现 课件 第17讲 Link-3_第4页
计算机系统-从应用程序到底层实现 课件 第17讲 Link-3_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

$

gcc–g–o–p

main.c

test.c继续观察可执行文件p加载可执行目标文件ELFheaderProgramheadertable(requiredforexecutables).textsection.datasection.bsssection.symtab.debugSectionheadertable(requiredforrelocatables)ExecutableObjectFileKernelvirtualmemoryMemory-mappedregionforsharedlibrariesRun-timeheap(createdbymalloc)Userstack(createdatruntime)Unused%esp

(stackpointer)Memoryoutside32-bitaddressspacebrk0x1000000000x080480000xf7e9ddc0Read/writesegment(.data,.bss)Read-onlysegment(.init,.text,.rodata)Loadedfromtheexecutablefile.rodatasection.line.initsection.strtab《计算机系统》链接下篇《计算机系统》课程教学组2025年春季学期库静态库共享库链接器本讲内容链接的作用&意义链接器的输入/出文件ELF细节链接器工作步骤符号属性符号解析解析规则重定位类型与过程链接符号全局符号Global由模块m定义并能被其他模块引用的符号例:非静态C函数和非静态的全局变量

外部符号External由其他模块定义并被模块m引用的全局符号

本地符号Local由模块m定义和引用的本地符号例:带静态属性的C函数和变量本地链接符号不是本地程序变量符号解析intbuf[2]={1,2};

intmain(){swap();return0;}main.cexternintbuf[];

int*bufp0=&buf[0];staticint*bufp1;voidswap(){inttemp;bufp1=&buf[1];temp=*bufp0;*bufp0=*bufp1;*bufp1=temp;}swap.cGlobalExternalExternalLocalGlobalLinkerknowsnothingoftempGlobal符号解析示例编译顺利进行,无报错!然后,链接时……符号解析再示例编译顺利进行,无报错!然后,链接时……本地符号,同一文件中的同名本地符号//以下两个函数在同一文件中intf(){statica=100;returna;}intg(){statica=-10;returna;}无误编译器在.data中为两个同名整数分配空间,并引导出两个唯一本地链接用符号,比如用a.1和a.2分别表示两个函数中的定义的同名a/*test.c*/intadd1(inti,intj){staticinta=20;staticintb;intx=a++;returnx;}/*test1.c*/intadd(inti,intj){staticinta=1;staticintb=0;intx=a+b;returnx;}如右所示代码,如下描述正确的是:f和g都是全局符号实际只有一个本地符号x若staticint变量不初始化,则缺省初值为0此代码中无外部符号ABCDSubmit多选题50分为什么?1#include<stdio.h>2intd=100;3intx=200;4voidp1(void);5intmain()6{7p1();8printf(“d=%d,x=%d\n”,d,x);9return0;10}1doubled;23voidp1()4{5d=1.0;6}p1.cmain.c打印结果是d=0,x=1072693248

强/弱符号编译时,编译器向汇编器输出的每个全局符号,或者是强符号或者是弱符号

Strong:函数和已初始化的全局变量

Weak:未初始化的全局变量intfoo=5;p1(){}intfoo;p2(){}p1.cp2.cstrongweakstrongstrong链接器的符号规则对于多重定义的全局符号——Rule1:不允许有多个强符号强符号只能被定义一次

否则:链接器产生错误信息Rule2:若有一个强符号和多个弱符号,则解析时选择强符号定义

此时引用弱符号会导致解析强符号Rule3:若有多个弱符号,则从这些弱符号中任意选择一个作为符号定义

使用gcc–fno-common选项调用链接器,在遇到多重定义的全局符号时,会有警告信息

出错啦,错在哪里?intx=0;p1(){}intx;p2(){

x=100}intx;inty;p1(){}doublex;p2(){}intx=7;inty=5;p1(){}doublex;p2(){}intx;p1(){}intx;p2(){}intx;p1(){}p1(){}Linktimeerror:twostrongsymbols(p1)Referencestoxwillrefertothesameuninitializedint.Isthiswhatyoureallywant?Writestoxinp2mightoverwritey!Evil!Writestoxinp2

willoverwritey!Nasty!Nightmarescenario:twoidenticalweakstructs,compiledbydifferentcompilerswithdifferentalignmentrules.Referencestoxwillrefertothesameinitializedvariable.d到底如何被定义?1#include<stdio.h>2intd=100;3intx=200;4voidp1(void);5intmain()6{7p1();8printf(“d=%d,x=%d\n”,d,x);9return0;10}1doubled;23voidp1()4{5d=1.0;6}p1.cmain.c为什么?1#include<stdio.h>2intd=100;3intx=200;4voidp1(void);5intmain()6{7p1();8printf(“d=%d,x=%d\n”,d,x);9return0;10}1doubled;23voidp1()4{5d=1.0;6}p1.cmain.c打印结果是d=0,x=1072693248

为什么?1#include<stdio.h>2intd=100;3intx=200;4voidp1(void);5intmain()6{7p1();8printf(“d=%d,x=%d\n”,d,x);9return0;10}1doubled;23voidp1()4{5d=1.0;6}p1.cmain.c打印结果是d=0,x=1072693248

1.0:0011111111110…0Binary=3FF0000000000000Hexadecimal悟了十个1则打印输出:

[填空1]

[填空2]

作答//main.c#include<stdio.h>inty=100;intz;voidp1(void);intmain(){z=1000;p1();printf(“y=%d,z=%d\n”,y,z);return0;}//p1.cinty;intz;voidp1(){y=200;z=2000;}填空题15分则打印输出:

[填空1]

[填空2]

[填空3]

作答//main.c#include<stdio.h>inty=100;intz=11;inta=99;voidp1(void);intmain(){z=1000;p1();printf(“y=%d\n”,y);printf(“z=%d\n”,z);printf(“a=%d\n”,a);return0;}//p1.cdoublez;inty;voidp1(){z=0.0;y=200;}填空题30分全局变量的使用若可以要尽量避免使用全局变量否则尽可能使用static定义全局变量时要初始化如果要使用外部全局变量需使用extern链接第一步符号定义符号引用符号解析将符号引用与符号定义连接起来链接第二步重定位……

重定位第1步:重定位节和符号定义相同类型的节合并形成新的聚合段

将运行时的存储器地址赋给新的聚合段

使得每个指令和全局变量有唯一的运行时存储器地址重定位第2步:重定位节中的符号引用修改代码节和数据节中的每个符号的引用,使其指向相应的符号定义的存储器地址依赖重定位条目重定位

R_386_PC32:重定位一个使用32位PC相对地址的引用PC相对地址:指距程序计数器PC当前运行值的偏移量PC总是指向下一条将要执行的指令地址

总是与跨文件的函数调用有关

R_386_32:重定位一个使用32位地址的绝对地址的引用通过绝对寻址,直接使用编码中的32位地址作为有效地址总是与使用跨文件的全局变量有关基本重定位类型重定位代码与数据main()main.oint*bufp0=&buf[0]swap()swap.ointbuf[2]={1,2}Headersmain()swap()0Systemcodeint*bufp0=&buf[0]intbuf[2]={1,2}SystemdataMoresystemcodeSystemdata可重定位目标文件可执行目标文件.text.text.data.text.data.text.data.symtab.debug.dataint*bufp1.bssSystemcodestaticint*bufp1.bssEventhoughprivatetoswap,requiresallocationin.bss回顾示例//main.cintbuf[2]={1,2};

intmain(){swap();return0;}//swap.cexternintbuf[];

int*bufp0=&buf[0];staticint*bufp1;voidswap(){inttemp;bufp1=&buf[1];temp=*bufp0;*bufp0=*bufp1;*bufp1=temp;}重定位信息mainintbuf[2]={1,2};

intmain(){swap();return0;}Disassemblyofsection.data:00000000<buf>:0:0100000002000000Source:objdump–r-dmain.cmain.o0000000<main>:0: 8d4c2404lea0x4(%esp),%ecx4: 83e4f0and$0xfffffff0,%esp7: ff71fcpushl0xfffffffc(%ecx)a: 55push%ebpb: 89e5mov%esp,%ebpd: 51push%ecxe: 83ec04sub$0x4,%esp11: e8fcffffffcall12<main+0x12>

12:R_386_PC32 swap16: 83c404add$0x4,%esp19: 31c0xor%eax,%eax1b: 59pop%ecx1c: 5dpop%ebp1d: 8d61fclea0xfffffffc(%ecx),%esp20: c3retELF重定位条目:重定位信息mainDisassemblyofsection.data:00000000<buf>:0:0100000002000000Source:objdump–r-dmain.o0000000<main>:0: 8d4c2404lea0x4(%esp),%ecx4: 83e4f0and$0xfffffff0,%esp7: ff71fcpushl0xfffffffc(%ecx)a: 55push%ebpb: 89e5mov%esp,%ebpd: 51push%ecxe: 83ec04sub$0x4,%esp11: e8fcffffffcall12<main+0x12>

12:R_386_PC32 swap16: 83c404add$0x4,%esp19: 31c0xor%eax,%eax1b: 59pop%ecx1c: 5dpop%ebp1d: 8d61fclea0xfffffffc(%ecx),%esp20: c3retELF重定位条目:假设发生重定位的当前text节开始地址ADDR(.text)=0x8048380

swap的代码段开始地址为ADDR(swap.text)=0x80483b0当前PC值=0x8048380+0x12-init=0x8048392-(-4)10=0x8048396偏移地址:ADDR(swap)-当前PC值=0X1aPC

原PC+0x1a080483b0<swap>:80483b0: 8b1520960408 mov0x8049620,%edx80483b6: a124960408 mov0x8049624,%eax80483bb: 55 push%ebp80483bc: 89e5 mov%esp,%ebp80483be: c7053096040824 movl$0x8049624,0x804963080483c5: 96040880483c8: 8b08 mov(%eax),%ecx80483ca: 8910 mov%edx,(%eax)80483cc: 5d pop%ebp80483cd: 890d24960408 mov%ecx,0x804962480483d3: c3 ret重定位信息swap的.textexternintbuf[];

int*bufp0=&buf[0];staticint*bufp1;voidswap(){inttemp;bufp1=&buf[1];temp=*bufp0;*bufp0=*bufp1;*bufp1=temp;}swap.cswap.oDisassemblyofsection.text:00000000<swap>:0: 8b1500000000 mov0x0,%edx

2:R_386_32 buf6: a104000000 mov0x4,%eax

7:R_386_32 bufb: 55 push%ebpc: 89e5 mov%esp,%ebpe: c7050000000004 movl$0x4,0x015: 000000

10:R_386_32 .bss

14:R_386_32 buf

18: 8b08 mov(%eax),%ecx1a: 8910 mov%edx,(%eax)1c: 5d pop%ebp1d: 890d04000000 mov%ecx,0x4

1f:R_386_32 buf23: c3 ret重定位信息swap,.textswap.oDisassemblyofsection.text:00000000<swap>:0: 8b1500000000 mov0x0,%edx

2:R_386_32 buf6: a104000000 mov0x4,%eax

7:R_386_32 bufb: 55 push%ebpc: 89e5 mov%esp,%ebpe: c7050000000004 movl$0x4,0x015: 000000

10:R_386_32 .bss

14:R_386_32 buf

18: 8b08 mov(%eax),%ecx1a: 8910 mov%edx,(%eax)1c: 5d pop%ebp1d: 890d04000000 mov%ecx,0x4

1f:R_386_32 buf23: c3 retELF重定位条目:这是一个绝对引用若符号buf的绝对地址ADDR(buf)=0x8049620继续重定位绝对地址……

重定位信息swap,.textswap.oDisassemblyofsection.text:00000000<swap>:0: 8b1500000000 mov0x0,%edx

2:R_386_32 buf6: a104000000 mov0x4,%eax

7:R_386_32 bufb: 55 push%ebpc: 89e5 mov%esp,%ebpe: c7050000000004 movl$0x4,0x015: 000000

10:R_386_32 .bss

14:R_386_32 buf

18: 8b08 mov(%eax),%ecx1a: 8910 mov%edx,(%eax)1c: 5d pop%ebp1d: 890d04000000 mov%ecx,0x4

1f:R_386_32 buf23: c3 retELF重定位条目:这是一个绝对引用若符号buf的绝对地址ADDR(buf)=0x8049620继续重定位绝对地址……

080483b0<swap>:80483b0: 8b1520960408 mov0x8049620,%edx80483b6: a124960408 mov0x8049624,%eax80483bb: 55 push%ebp80483bc: 89e5 mov%esp,%ebp80483be: c7053096040824 movl$0x8049624,0x804963080483c5: 96040880483c8: 8b08 mov(%eax),%ecx80483ca: 8910 mov%edx,(%eax)80483cc: 5d pop%ebp80483cd: 890d24960408 mov%ecx,0x804962480483d3: c3 retDisassemblyofsection.data:08049620<buf>:

8049620:010000000200000008049628<bufp0>:8049628:20960408重定位信息swap,.textDisassemblyofsection.text:00000000<swap>:0: 8b1500000000 mov0x0,%edx

2:R_386_32 buf6: a104000000 mov0x4,%eax

7:R_386_32 bufb: 55 push%ebpc: 89e5 mov%esp,%ebpe: c7050000000004 movl$0x4,0x015: 000000

10:R_386_32 .bss

14:R_386_32 buf

18: 8b08 mov(%eax),%ecx1a: 8910 mov%edx,(%eax)1c: 5d pop%ebp1d: 890d04000000 mov%ecx,0x4

1f:R_386_32 buf23: c3 retELF重定位条目:这是一个绝对引用若符号buf的绝对地址ADDR(buf)=0x8049620继续重定位绝对地址……

080483b0<swap>:80483b0: 8b1520960408 mov0x8049620,%edx80483b6: a124960408 mov0x8049624,%eax80483bb: 55 push%ebp80483bc: 89e5 mov%esp,%ebp80483be: c7053096040824 movl$0x8049624,0x804963080483c5: 96040880483c8: 8b08 mov(%eax),%ecx80483ca: 8910 mov%edx,(%eax)80483cc: 5d pop%ebp80483cd: 890d24960408 mov%ecx,0x804962480483d3: c3 ret重定位前/后.data绝对地址引用重定位前/后你还能找到其他绝对地址重定位吗?相对地址引用重定位前/后可执行文件的存储器映像%espbrk0xC000000000x080480000内核虚存区共享库区域堆(heap)动态生成)用户栈动态生成未使用读写数据段(.data,.bss)只读代码段(.text,.rodata等)从可执行文件装入1GB可执行目标文件intbuf[2]={1,2}Headersmain()swap()0int

*bufp0=&buf[0]更多系统代码系统数据.text.symtab.debug.dataint*bufp1.bss系统代码程序(段)头表描述如何映射!可执行文件中的程序头表typedefstruct{Elf32_Wordp_type;Elf32_Offp_offset;Elf32_Addrp_vaddr;Elf32_Addr

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论