静态和动态链接,PLT需要什么? [英] Static and Dynamic Linking, What's the need for PLT?

查看:17
本文介绍了静态和动态链接,PLT需要什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读这篇精彩的文章:https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html 关于动态和静态链接.

I was reading this amazing article: https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html about dynamic and static linking.

阅读完后,还有 2 个问题没有回答或不够清楚,我无法理解.

After finishing the reading 2 questions are still unanswered or no clear enough for me to understand.

1)

这不适用于共享库 (.so).一个完整的点共享库是应用程序随机选择库的排列以实现他们想要的.如果您的共享库被构建为仅在加载到一个特定地址时才工作一切可能都很好——直到另一个图书馆出现也使用该地址构建.问题其实有点易于处理——你可以枚举每个共享库系统并为其分配所有唯一的地址范围,确保无论加载什么库组合,它们都不会重叠.这本质上是预链接的作用(尽管这是一个提示,而不是而不是一个固定的、必需的地址基数).除了维修噩梦,使用 32 位系统,您很快就会用尽如果您尝试为每个可能的库提供唯一的地址空间地点.因此,当您检查共享库时,它们不会指定要加载的特定基地址

This is not fine for a shared library (.so). The whole point of a shared library is that applications pick-and-choose random permutations of libraries to achieve what they want. If your shared library is built to only work when loaded at one particular address everything may be fine — until another library comes along that was built also using that address. The problem is actually somewhat tractable — you can just enumerate every single shared library on the system and assign them all unique address ranges, ensuring that whatever combinations of library are loaded they never overlap. This is essentially what prelinking does (although that is a hint, rather than a fixed, required address base). Apart from being a maintenance nightmare, with 32-bit systems you rapidly start to run out of address-space if you try to give every possible library a unique location. Thus when you examine a shared library, they do not specify a particular base address to be loaded at

那么动态链接是如何解决这个问题的呢?一方面,文章提到我们不能使用相同的地址,另一方面他说使用多个地址会导致可用内存不足.我看到一个矛盾的声音(注意:我知道什么是虚拟地址).

Then how does dynamic linking solve this issue? On the one hand the write mentions we can't use same address and on the other hand he says using multiple addresses will cause lack of free memory. I'm seeing a contradiction hear (Note: I know what's virtual address).

2)

这处理数据,但函数调用呢?使用的间接这里称为过程链接表或PLT.代码不调用直接的外部函数,但只能通过 PLT 存根.让我们检查一下这个:

This handles data, but what about function calls? The indirection used here is called a procedure linkage table or PLT. Code does not call an external function directly, but only via a PLT stub. Let's examine this:

我没明白,为什么数据处理和函数不同?像我们过去对普通变量所做的那样,在 GOT 中保存函数地址有什么问题?

I didn't get it, why the handling of data is different that functions? what's the problem of saving function's addresses inside GOT as we used to do with normal variables?

推荐答案

一方面,作者提到我们不能使用相同的地址,另一方面他说使用多个地址会导致可用内存不足.

On the one hand the write mentions we can't use same address and on the other hand he says using multiple addresses will cause lack of free memory.

在大约 15 到 20 年前切换到 ELF 之前的 Linux 上,所有共享库都必须在全球范围内进行协调.这是一场维护噩梦,因为一个系统可以拥有数百个共享库.您用尽了地址空间为每个库分配唯一地址,即使其中一些库从未一起加载(但地址空间范围的分配者事先不知道哪些库从未一起加载,因此可以加载到相同的范围内).

On Linux before the switch to ELF some 15-20 years ago, all shared libraries had to be globally coordinated. This was a maintenance nightmare, because a system can have many 100s of shared libraries. You run out of address space assigning unique address to each library, even though some of these libraries are never loaded together (but the assigner of address space range doesn't know a priori which libraries are never loaded together, and therefore could be loaded into the same range).

动态加载器解决了这个问题,方法是在加载库时将库放入任意地址范围,重新定位它们,以便它们在刚刚加载的地址处正确执行.

Dynamic loader solves this by placing libraries into an arbitrary address range as they are loaded, and relocating them so they correctly execute at the address they have just been loaded at.

这里的好处是您不需要提前对地址空间进行分区.

The advantage here is that you don't need to partition your address space ahead of time.

为什么数据处理与函数不同?

why the handling of data is different that functions?

这是不同的,因为当您访问数据时,不涉及链接器.第一次访问必须有效,并且必须在图书馆可用之前重新定位数据.没有可用于延迟动态链接的函数调用.

It's different because when you access data, the linker is not involved. The very first access must work, and the data must be relocated before the library is available. There's no function call you can hook for lazy dynamic linking.

但是对于函数调用,可能会涉及到链接器.该程序调用PLT存根".函数 foo@plt.在 first 调用该存根时,它会执行 resolve 指向 actual foo() 定义的指针,并保存该指针.在随后的调用中,foo@plt 只是使用已经保存的指针直接跳转到 foo() 的定义.

But for a function call, the linker can be involved. The program calls a PLT "stub" function foo@plt. On first call to that stub, it perform work to resolve a pointer to the actual foo() definition, and saves that pointer. On subsequent calls, foo@plt just uses the already-saved pointer to jump directly to the definition of foo().

这称为惰性重定位,如果程序永远无法访问许多它有调用站点的库函数,它可以节省很多工作.(例如,一个计算数学表达式并可以调用任何 libm.so.6 函数的程序,但对于普通的简单输入,或使用 --help,只调用几个.)

This is called lazy relocation, and it saves a lot of work if the program never reaches many of the library function that it has call-sites for. (e.g. a program that evaluates a math expression and could call any libm.so.6 function, but for normal simple inputs, or with --help, only calls a couple.)

您可以通过运行包含大量共享库的大型程序来观察延迟重定位的效果,该程序带有和不带有 LD_BIND_NOW 环境变量(禁用延迟重定位).

You can observe the effect of lazy relocation by running a large program with lots of shared libraries with and without LD_BIND_NOW environment variable (which disables lazy relocation).

或使用 gcc -fno-plt (https://gcc.gnu.org/ml/gcc-patches/2015-05/msg00225.html),GCC会通过GOT内联调用,意思是库函数一次性到达打电话而不是两个.(一些 x86-64 Linux 发行版为其二进制包启用此功能.)这需要早期绑定,但会略微降低每次调用的成本,因此对于长时间运行的程序很有用.(PLT + 早期绑定是两者中最糟糕的,除了在解决所有问题时具有缓存局部性.)

Or with gcc -fno-plt (https://gcc.gnu.org/ml/gcc-patches/2015-05/msg00225.html), GCC will inline the call through the GOT, meaning the library function is reached in one call instead of two. (Some x86-64 Linux distros enable this for their binary packages.) This requires early binding, but slightly reduces the cost of each call, so is good for long-running programs. (PLT + early binding is the worst of both, except for having cache locality while resolving everything.)

这篇关于静态和动态链接,PLT需要什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆