ELF共享库-PLT的动机


11

可以使用自修改代码来加速动态链接库中的函数调用吗?

据我了解,ELF共享库使用一种间接跳转表(过程链接表或PLT)来实现库函数的延迟绑定。目的似乎是为了避免必须修改代码段中的表,同时仍允许在第一次调用时对函数位置进行延迟解析。

在加载时甚至可能在第一个函数调用时为该表动态创建代码会更快吗?

是否能够在进程之间尽可能多地共享代码段(动态表对于进程是私有的)?是出于安全原因(可写代码不应执行 -但是JIT始终这样做,并且加载程序可以在实际启动程序之前由加载程序添加和删​​除写许可权)?

还是这两者的结合,而每次函数调用获得的小性能提升是不值得的?

Answers:


8

我想我们正在谈论x86体系结构。

您不能在保护模式下使用自我修改代码,该模式在我所知道的大多数基于UNIX的操作系统中(不仅是)都使用,因为代码段始终是只读的。加载程序无法控制-内核的内存管理子系统正在处理它。

但是,即使您可以像您所说的那样“在加载时为该表创建代码”,也无法实现共享库的全部目的。这样,每个进程将在其地址空间中具有库功能的“私有”副本,从而有效地增加了其内存占用量(创建共享库的原因之一)就是为了解决此问题。

您描述的整个过程非常复杂,并且比当前使用的PLT方法花费更多的处理周期,并且可能会引入更多,新的和有趣的安全问题。


2
您可以使用mprotect(2)系统调用使.text段页面可写和可执行。
Bruce Ediger 2012年

1
是的,先生。它可能在基于UNIX的普通系统上正常运行,但是一旦有人尝试使用PaX加固系统,整个链接过程就会中断,这会对mprotect(2)施加了限制。
dkaragasidis

(似乎我在以前的评论中没有提到@BruceEdiger)
dkaragasidis 2012年

1

ELF DSO可以使用标志(DF_TEXREL)来声明它们需要通过修改其文本部分(通常是只读的)来进行重新分配。不过,跳转表方法以及与PIE位置无关的代码应更为优化。

(在http://www.akkadia.org/drepper/dsohowto.pdf中找到了该方法,但其他资源也提到了这一点)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.