首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >linux进程中的多个全局偏移表

linux进程中的多个全局偏移表
EN

Stack Overflow用户
提问于 2020-10-29 05:29:02
回答 1查看 37关注 0票数 0

我正在检查一个正在运行的进程的内存布局,并做了一个有趣的观察。似乎有多个GOT(全局偏移表)。下面是我在学习malloc函数时在调试器中看到的内容:

代码语言:javascript
运行
复制
(gdb) p (void *) 0x7ff5806ae020
$5 = (void *) 0x7ff5806ae020 <malloc@got.plt>
(gdb) p (void *) 0x7ff5806471d0
$6 = (void *) 0x7ff5806471d0 <malloc@got.plt>
(gdb) p (void *) 0x5634ef446030
$7 = (void *) 0x5634ef446030 <malloc@got.plt>

我检查了3个不同地址的malloc弹床。当我查看进程的内存映射时,这些地址对应于以下条目:

代码语言:javascript
运行
复制
7ff580647000-7ff580648000 rw-p 0001c000 fd:01 547076                     /lib/x86_64-linux-gnu/libpthread-2.31.so
5634ef446000-5634ef447000 rw-p 00003000 fd:02 12248955                   /home/user/binary
7ff5806ae000-7ff5806af000 rw-p 0002a000 fd:01 523810                     /lib/x86_64-linux-gnu/ld-2.31.so

我看到不同的条目对应于不同的“可链接对象”:二进制和两个动态库。

此外,三个弹床中有两个指向实际功能。两个指针都是一样的。第三个弹床指向短节。

代码语言:javascript
运行
复制
(gdb) p *(void **) 0x5634ef446030
$8 = (void *) 0x7ff5804ef1b0 <__GI___libc_malloc>
(gdb) p *(void **) 0x7ff5806471d0
$9 = (void *) 0x7ff580631396 <malloc@plt+6>
(gdb) p *(void **) 0x7ff5806ae020
$10 = (void *) 0x7ff5804ef1b0 <__GI___libc_malloc>

真的需要三张跳床吗?如果是,那是为什么?

EN

回答 1

Stack Overflow用户

发布于 2020-10-29 22:50:11

我意识到这样的系统是实现跳床的唯一明智的方式。

在汇编中,对动态链接函数的每个调用指令基本上都引用GOT中该函数的一个索引。索引直接编码在指令中。因此,在静态链接期间,索引必须是最新的。否则,每次程序启动时,动态链接器都必须更新程序代码。显然,这是一项非常繁琐的任务。

此外,每个库都是单独编译的,因此不能依赖于其他库,包括它们确切的GOT布局。如果只有一个GOT,那么所有加载在一起的库必须以某种方式在GOT中的每个条目的含义上达成一致。拥有一个由所有库共同填充的共享数据结构(GOT),几乎肯定会创建这样的依赖关系。

例如,readelf说.so-files也有表:

代码语言:javascript
运行
复制
$ readelf -S /lib/ld-linux.so.2 
   [18] .got              PROGBITS        00029ff4 028ff4 000008 04  WA  0   0  4
   [19] .got.plt          PROGBITS        0002a000 029000 000028 04  WA  0   0  4
$ readelf -S /usr/lib/libpurple.so.0.13.0
   [21] .got              PROGBITS         0000000000137318  00136318
   0000000000003cd8  0000000000000008  WA       0     0     8

不过,libpurple没有.got.plt,这一点我并不完全理解。

我的困惑来自于表被称为“全局”的事实。“全局”一词实际上意味着表在可链接对象级别是全局的,而不是编译模块(.o文件)。

其次,我有一个错觉,GOT引用的是一个可执行的应用程序,而不是任何动态可链接的对象。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64581570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档