为什么 fPIC 在 64 位平台上是绝对必要的,而不是在 32 位平台上? [英] Why is fPIC absolutely necessary on 64 and not on 32bit platforms?

查看:31
本文介绍了为什么 fPIC 在 64 位平台上是绝对必要的,而不是在 32 位平台上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近收到了一个:

<块引用>

...重定位 R_X86_64_32 针对 `a local symbol' 不能在创建共享对象时使用;用 -fPIC 重新编译

尝试将程序编译为共享库时出错.

现在解决这个问题并不太难(用 -fPIC 重新编译所有依赖项),但经过一些研究发现这个问题只存在于 x86-64 平台上.在 32 位上,任何位置相关的代码仍然可以被动态加载器重新定位.

我能找到的最好的答案是:

<块引用>

x86 支持 .text 重定位(当你有位置相关代码).这种支持是有代价的,即每个包含此类重定位的页面基本上不会共享,即使它位于共享库中,从而破坏了共享的概念库.因此我们决定在 amd64 上禁止这个(加上它创建如果值需要超过 32 位,则会出现问题,因为所有 .text 仅重新定位有大小 'word32')

但我觉得这还不够.如果重定位破坏了共享库的概念,为什么可以在32位平台上进行呢?另外,如果需要对 ELF 格式进行更改以支持 64 位,那么为什么不是所有字段的大小都增加以适应?

这可能是一个小点,但它的动机是a) 有问题的代码是一个科学的代码,最好不要对性能造成影响 b) 这个信息是不可能的首先找到!

解决方案

据我所知,问题是 x86-64 似乎引入了一种新的、更快的方式来引用相对于指令指针的数据,而 x86 不存在这种方式-32.

这篇文章 对它有很好的深入分析,并给出以下执行摘要:

<块引用>

x86-64 使用指令指针相对偏移的能力数据地址是一个很好的优化,但在共享库中关于数据相对位置的情况假设无效并且不能使用.在这种情况下,访问全局数据(即任何可能会改变你的东西)必须经过一个层抽象的,即全局偏移表.

-fPIC 寻址为寻址添加了一个额外的抽象层,使以前在通常寻址方式中可能(和一个理想的特性)仍然适用于较新的架构.

I recently received a:

...relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC

error while trying to compile a program as a shared library.

Now the solution to this is not too difficult (recompile all dependencies with -fPIC), but after some research it turns out that this problem is only present on x86-64 platforms. On 32bit any position dependent code can still be relocated by the dynamic loader.

The best answer I could find is:

x86 has support for .text relocations (which is what happens when you have position-dependend code). This support comes at a cost, namely that every page containing such relocation becomes basically unshared, even if it sits in a shared library, thereby spoiling the very concept of shared libs. Hence we decided to disallow this on amd64 (plus it creates problems if the value needs more than 32bit, because all .text relocs only have size 'word32')

But I don't find this quite adequate. If it is the case that relocations spoil the concept of shared libraries, why can it be done on 32bit platforms? Also, if there were changes that needed to be made to the ELF format to support 64bit, then why were not all fields increased in size to accommodate?

This may be a minor point, but it is motivated by the fact that a) the code in question is a scientific code and it would be nice not to have to take a performance hit and b) this information was nye impossible to find in the first place!

[Edit: 'The Answer'

@awoodlands answer is probably the best 'literal answer', @servn added some good information.

In a search to find more about different types of relocations I found this and ultimately an x86_64 ABI reference (see page 68) ]

解决方案

As I understand it the problem is x86-64 seems to introduce a new, faster way of referencing data relative to the instruction pointer, which did not exist for x86-32.

This article has a nice in-depth analysis of it, and gives the following executive summary:

The ability of x86-64 to use instruction-pointer relative offsetting to data addresses is a nice optimisation, but in a shared-library situation assumptions about the relative location of data are invalid and can not be used. In this case, access to global data (i.e. anything that might be changed around on you) must go through a layer of abstraction, namely the global offset table.

I.e. -fPIC addressing adds an extra layer of abstraction to addressing, to make what was previously possible (and a desirable feature) in the usual addressing style still work with the newer architecture.

这篇关于为什么 fPIC 在 64 位平台上是绝对必要的,而不是在 32 位平台上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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