奇怪的链接器问题“重定位R_X86_64_32针对” - 不是典型的-fPIC问题 [英] Odd linker issue "relocation R_X86_64_32 against" - not a typical -fPIC issue

查看:968
本文介绍了奇怪的链接器问题“重定位R_X86_64_32针对” - 不是典型的-fPIC问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在尝试在Ubuntu 14.04(64)上创建一个胖共享库时,我遇到了一个奇怪的问题。如果您忘记添加-fPIC或链接到错误的体系结构库,则通常会收到错误消息:

  / usr / bin / ld:/usr/lib/libproj.a(pj_init.o):重新定位R_X86_64_32针对
`.rodata.str1.1'在创建共享对象时无法使用;使用-fPIC重新编译
/usr/lib/libproj.a:添加符号时出错:错误值



<第一个静态库是这样编译的:

  gcc -c -fPIC -m64 NativeDB.c 

之后,应该创建一个胖共享库,使用上面的库以及其他几个库(spatialite,proj4,geos ,sqlite)就像这样:

  gcc -shared -fPIC -m64 -o $ @ $(OUT_DIR)/NativeDB.o $ (OUT_DIR)/sqlite3.o $(SPATIALITE_DIR)/src/.libs/libspatialite.a $(SOME_OTHER_LIBS)



将NativeDB.o链接到共享库会引发链接器错误。还要注意,可以在没有NativeDB.o的情况下创建共享库。所以这里变得很奇怪,因为你从上面看到了NativeDB.o的编译方式,并且没有增加额外的(隐含的)链接。


观察结果:

<1>所有库都已正确编译。例如,我验证了libproj包含重定位信息,并且是正确的体系结构(通过objdump -f):

  ... 
pj_initcache.o:文件格式elf64-x86-64
架构:i386:x86-64,标志0x00000011:
HAS_RELOC,HAS_SYMS
起始地址0x0000000000000000
...

这也是我自己的NativeDB.o文件的情况。



2)当gcc创建的lib被遗弃时,共享库创建的很好(尽管当然没有我的库...)。 3)我最好的猜测是,当从包含32位.text段的静态库创建一个共享库时,这个问题来自gcc的一个奇怪现象:



 在归档目标/ libspatialite-4.2.1-rc0 / src / .libs / libspatialite.a中:

版本.o:文件格式elf64-x86-64

[.text]的迁移记录:
偏移类型值
0000000000000001 R_X86_64_32 spatialiteversion
0000000000000011 R_X86_64_32 spatialitetargetcpu
...
[.debug_info]的迁移记录:
偏移类型值
...
0000000000000307 R_X86_64_32 .debug_str + 0x0000000000000256
0000000000000313 R_X86_64_64 spatialiteversion
0000000000000331 R_X86_64_32 .debug_str + 0x000000000000022d
000000000000033d R_X86_64_64 spatialitetargetcpu

我已经做了一些实验以前失败的图书馆(versio在libspatialite.a内)。瞧,它修复了这个库的链接问题:

  mv version.o version_org.o 
objcopy -O elf64-x86-64 target / libspatialite-4.2.1-rc0 / src / .libs / version_org.o version64.o
#从存档中删除version.o
ar -d libspatialite.a version.o
#添加64位版本.o
ar -r libspatialite.a version.o

到目前为止的结论:

对我来说,这看起来像一个gcc编译器。我希望有一个解决方案,我想要做的。
顺便说一句,相同的代码库(具有相似但不相同的依赖关系)在OS X上使用clang和build作为dynamiclib可以很好地工作。它没有多大的意义,但是代码库可能没有错。



请注意,在您回答之前:

显而易见的答案是说我应该用另一种方式捆绑我的东西。但是,由于某些原因,我真的想使用(JNI加载,库大小等)创建一个共享库。



如果您可以分享我在你的编译器见解,并帮助我解决它。



更新1



删除对g ++的引用。该问题以完全使用gcc的相同方式发生。我之前考虑过gcc vs g ++的问题。

解决方案

使用eclipse构建时出现同样的错误:
试图使用-shared(gcc c linker-> shared library settings-> Shared)编译可执行文件,导致出现此错误。当共享选项被删除时,它解决了这个问题。
由于某些原因,当从eclipse中的excutable改为Static library时,-shared仍然存在,这就是为什么它在我的情况下失败。 -shared选项需要保留,仅用于库构建。



希望它可以帮助任何人,


I have an odd problem when trying to create a fat shared library on Ubuntu 14.04 (64). The error messages are what you typically get if you forgot to add -fPIC or link to a wrong architecture library:

/usr/bin/ld: /usr/lib/libproj.a(pj_init.o): relocation R_X86_64_32 against 
`.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/usr/lib/libproj.a: error adding symbols: Bad value

The first static library is compiled like this:

gcc -c -fPIC -m64 NativeDB.c 

After that a single fat shared library should be created, using above library as well as a few others (spatialite, proj4, geos, sqlite) like so:

gcc -shared -fPIC -m64 -o $@ $(OUT_DIR)/NativeDB.o $(OUT_DIR)/sqlite3.o $(SPATIALITE_DIR)/src/.libs/libspatialite.a $(SOME_OTHER_LIBS) 

Linking NativeDB.o to the shared library throws mentioned linker error. Note also that the shared library can be created without NativeDB.o. So here it's getting strange, because you see above how NativeDB.o is compiled and adds no additional (implicit) linkage.

Observations:

1) All libraries are compiled properly. I verified for example that libproj contains relocation info and is the right architecture (via objdump -f):

...
pj_initcache.o:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
...

This is also the case for my own NativeDB.o file.

2) When the gcc created lib is left away, the shared library is created fine (though of course without my library...).

3) My best guess is that the issue comes from an oddity from gcc when creating a shared library from static libraries that contain 32 bit .text sections:

In archive target/libspatialite-4.2.1-rc0/src/.libs/libspatialite.a:

version.o:     file format elf64-x86-64

RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE 
0000000000000001 R_X86_64_32       spatialiteversion
0000000000000011 R_X86_64_32       spatialitetargetcpu
...
RELOCATION RECORDS FOR [.debug_info]:
OFFSET           TYPE              VALUE 
...
0000000000000307 R_X86_64_32       .debug_str+0x0000000000000256
0000000000000313 R_X86_64_64       spatialiteversion
0000000000000331 R_X86_64_32       .debug_str+0x000000000000022d
000000000000033d R_X86_64_64       spatialitetargetcpu

I have made some experiments with one previously failing library (version.o within libspatialite.a). And voila - it fixed the linkage issue for this library:

mv version.o version_org.o
objcopy -O elf64-x86-64 target/libspatialite-4.2.1-rc0/src/.libs/version_org.o version64.o
# delete version.o from archive
ar -d libspatialite.a version.o
# add 64 bit version.o
ar -r libspatialite.a version.o

Conclusions so far:

It seems like an gcc compiler oddity to me. I hope there is a workaround for what I'm trying to do. By the way, the same code base (with similar but not same dependencies) works fine on OS X using clang and build as dynamiclib. It doesn't tell much, but that the code base is likely not at fault.

Please note before you answer:

The obvious answer would be to say that I should bundle my stuff in another way. But for given reasons, I really want to create a single fat shared library using (JNI loading, library size etc).

I'd be glad if you could share with me your compiler insights on this one and help me solve it.

UPDATE 1

Removed references to g++. The issue occurs in the same way solely using gcc. I previously considered a gcc vs g++ issue.

解决方案

I got the same error when building with eclipse: Trying to compile executable build with "-shared" (gcc c linker->shared library settings->Shared), resulted with this error. When the shared option is removed it solved this issue. From some reason when changing from excutable to "Static library" build in eclipse the "-shared" still remains, that's why it failed in my case. The "-shared" option need to remain only for library build.

Hope it helps anyone,

这篇关于奇怪的链接器问题“重定位R_X86_64_32针对” - 不是典型的-fPIC问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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