R_PPC_REL24重定位超出范围

6

我正在使用嵌入式 PowerPC(e500v2)平台进行工作。我使用 gcc 4.6.3 和 eglibc 2.13 进行交叉编译。有一个 swig 库被编译并加载到目标设备上。在 Python 中加载它时,我在回溯中遇到了以下错误:

ImportError: /opt/load/lib/libISSDcn.so: R_PPC_REL24 relocation at 0x0ddc99c0 for symbol `longjmp' out of range

我以前曾经遇到过这个库的问题,现在我正在从我们的目标机器上的Python 2.5迁移到2.7。当我最初尝试编译这个库时,根据使用的标志不同,我会在编译时得到重定位错误或操作数超出范围错误。我切换到gcc 4.6.3后现在它可以构建了,但是加载时出现了这个错误。
我正在努力理解这个错误,但是到目前为止我还不清楚它究竟表示什么以及如何解决它。我知道由于某种原因找不到符号,但我不知道为什么以及如何解决它。
1个回答

8
R_PPC_REL24重定位用于24位相对偏移。这种类型的重定位不应出现在动态重定位表中(这些是用于在可加载对象内部进行引用,而不是在它们之间进行引用,因为库可以加载到相隔超过16 MiB的地址)。
默认情况下,编译器会尽可能地生成这些重定位,因为这比使用完整的32位地址更小更快,但是对于动态链接,需要使用完整的地址来生成 PIC/GOT 条目和外部可见符号。
请检查是否在构建库时使用了-fPIC标志,并且链接器也被告知正在构建共享对象(通常是通过-shared-Bshared实现的)。

好的,谢谢。我在其他地方也看到了这个建议。有人告诉我这个库是使用fPIC编译的,但它很可能不是。事后有没有办法判断一个库是否是PIC? - Eric Seifert
另一个问题是,如果我执行readelf -r命令,我应该期望在共享对象中看到R_PPC_REL24吗?我看到了很多这样的东西。这个列表是否包括非外部符号? - Eric Seifert
一个PIC库不应该对除了PIC和GOT区域以外的任何东西应用动态重定位,而且所有这些重定位都应该能够覆盖整个地址空间。 - Simon Richter
使用readelf命令而不添加 -D 选项可以显示静态链接的信息,这些重定位已经在最终链接过程中被应用,除了指向缺失符号的那些重定位(它们已转换为动态重定位)。 - Simon Richter
5
好的,这个问题很难追踪,因为我的项目涵盖了大量的代码和第三方模块,但找到了一些编译时没有使用-fPIC选项的代码。现在问题已经解决了,谢谢!如果有其他人遇到类似情况,只需运行“readelf -D -r | grep R_PPC_REL24”命令。如果它发现任何R_PPC_REL24 relocs,则表示存在一些对象是在没有使用-fPIC选项的情况下编译的。 - Eric Seifert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接