.got 和 .got.plt 部分有啥区别?
Posted
技术标签:
【中文标题】.got 和 .got.plt 部分有啥区别?【英文标题】:What is the difference between .got and .got.plt section?.got 和 .got.plt 部分有什么区别? 【发布时间】:2012-07-25 11:06:55 【问题描述】:ELF 格式的 .got 和 .got.plt 部分有什么区别?
【问题讨论】:
根据:acsu.buffalo.edu/~charngda/elf.html.got
条目永远不会被延迟解析,但.got.plt
条目可以被延迟解析。
我认为 .got 用于关于全局“变量”的重定位,而 .got.plt 是在解析过程绝对地址时与 .plt 一起作用的辅助部分。
【参考方案1】:
我之前的评论是正确的:
我认为
.got
用于关于全局“变量”的重定位,而.got.plt
是在解析过程绝对地址时与.plt
一起行动的辅助部分。
下面的例子让事情变得更清楚了。
这些是我的 32 位 i686-linux /lib/libm.so 的重定位
Relocation section '.rel.dyn' at offset 0x32b8 contains 8 entries:
Offset Info Type Sym.Value Sym. Name
00025030 00000008 R_386_RELATIVE
00024fd8 00005706 R_386_GLOB_DAT 00025034 _LIB_VERSION
00024fdc 00000406 R_386_GLOB_DAT 00000000 __gmon_start__
00024fe0 00000506 R_386_GLOB_DAT 00000000 _Jv_RegisterClasses
00024fe4 00000806 R_386_GLOB_DAT 00000000 _rtld_global_ro
00024fe8 00000906 R_386_GLOB_DAT 00000000 stderr
00024fec 00013006 R_386_GLOB_DAT 0002507c signgam
00024ff0 00000e06 R_386_GLOB_DAT 00000000 __cxa_finalize
Relocation section '.rel.plt' at offset 0x32f8 contains 12 entries:
Offset Info Type Sym.Value Sym. Name
00025000 00000107 R_386_JUMP_SLOT 00000000 fputs
00025004 00000207 R_386_JUMP_SLOT 00000000 __errno_location
00025008 00000307 R_386_JUMP_SLOT 00000000 sprintf
0002500c 00000407 R_386_JUMP_SLOT 00000000 __gmon_start__
00025010 00000607 R_386_JUMP_SLOT 00000000 strtod
00025014 00000707 R_386_JUMP_SLOT 00000000 __assert_fail
00025018 00000a07 R_386_JUMP_SLOT 00000000 strlen
0002501c 00000b07 R_386_JUMP_SLOT 00000000 strtof
00025020 00000c07 R_386_JUMP_SLOT 00000000 fwrite
00025024 00000d07 R_386_JUMP_SLOT 00000000 strtold
00025028 00005e07 R_386_JUMP_SLOT 00005970 matherr
0002502c 00000e07 R_386_JUMP_SLOT 00000000 __cxa_finalize
您注意到有两个重定位部分,即 .rel.dyn 和 .rel.plt。您可以看到 .rel.plt 的所有重定位都是 R_386_JUMP_SLOT 类型,这意味着它们是分支重定位,另一方面,几乎所有 .rel.dyn 中的重定位都是 R_386_GLOB_DAT,这意味着全局变量的重定位。
.symtab 和 .dynsym 之间存在另一个细微差别。虽然第一个包含静态链接编辑期间使用的所有符号的引用,但后者仅包含动态链接所需的那些符号。因此,上面提到的重定位仅指 .dynsym 部分。
【讨论】:
IIRC,地址被占用的函数也需要.got
条目;编译器通常选择要求对它们进行早期绑定,以便它们可以从 GOT 加载最终地址,而不是仅仅将 PLT 存根的地址作为函数指针。以上是关于.got 和 .got.plt 部分有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
C温故补缺(十七):动态链接(ELF,PIC,GOT,PLT)
elf文件中的.plt .rel.dyn .rel.plt .got .got.plt的关系