ELF 共享库 - PLT 的动机

ELF 共享库 - PLT 的动机

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

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

在加载时甚至在第一次函数调用时动态创建该表的代码不是更快吗?

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

或者它是这些的组合,并且每个函数调用的微小性能增益不值得付出努力?

答案1

我想我们正在谈论 x86 架构。

你不能有自修改代码保护模式,据我所知,大多数基于 UNIX 的操作系统(而且不仅仅是)都使用它,因为代码段是总是只读。加载程序无法控制它 - 它是由内核的内存管理子系统处理的。

但是,即使您可以像您所说的那样“在加载时为该表创建代码”,它也会违背共享库的全部目的。这样,每个进程都会在其地址空间中拥有库函数的“私有”副本,从而有效地增加其内存占用量 - 创建共享库的原因之一就是解决这个问题。

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

答案2

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

(发现在http://www.akkadia.org/drepper/dsohowto.pdf,但其他资源也提到了这一点)。

相关内容