DATE: 2018.11.19
1、参考
http://canlynet.blog.163.com/blog/static/25501365201191145113156/
https://stackoverflow.com/questions/40791074/linker-option-bsymbolic
2、问题描述
relocation R_X86_64_32 against `text' cannot be used when making a shared object;
recomplied with -fPIC
3、解决方案
在编译动态库时,出现重定位的问题,主要是由于在编译源文件成为目标文件时,没有添加-fPIC选项造成的。
CFLAGS += -fPIC //c文件编译添加编译flag
ASMFLAGS += -DPIC //汇编文件编译添加编译flag
Update:
在编译汇编文件时,加上-DPIC ,但是在链接成动态库时,还是会出现上面重定位的问题?
解决方案:在链接成动态库时,指定-Wl, -Bsymbolic的链接选项。
LDFLAGS += -shared -lm -fPIC -Wl,-Bsymbolic
对于一般符号,一般都是主程序和动态库在两块空间中, 但是对于使用extern出来的变量主程序和动态库都是在同一块空间中(注:由于32位下不用-fPIC也可以编译so, 在没有-fPIC的情况也是分开的, 但是由于64位一定要-fPIC,所以一定会出现同一块空间的问题), 对于这个问题的解决方案是在动态库链接的时候加上 -Wl,-Bsymbolic 参数将动态库的空间和主程序的空间强行分开。
参考:
http://cvs.tortall.net/pipermail/bug-yasm/2011-October/000086.html
http://ffmpeg.org/pipermail/ffmpeg-devel/2009-November/076757.html
Bsymbolic表示强制采用本地的全局变量定义,这样就不会出现动态链接库的全局变量定义被应用程序/动态链接库中的同名定义给覆盖了!
-Bsymbolic
When creating a shared library, bind references to global symbols to the
definition within the shared library, if any. Normally, it is possible
for a program linked against a shared library to override the definition
within the shared library.
This option is only meaningful on ELF platforms which support shared libraries.
-Bsymbolic-functions
When creating a shared library, bind references to global function symbols
to the definition within the shared library, if any.
This option is only meaningful on ELF platforms which support shared libraries.
-fPIC
Generate position-independent code (PIC) suitable for use in a
shared library, if supported for the target machine. Such code
accesses all constant addresses through a global offset table
(GOT).
Update: 2018.11.21
IOS编译汇编文件时,链接成动态库又又出现了重定位的问题?
解决方案:
LDFLAGS += -read_only_relocs suppress
更加深入分析:
https://www.technovelty.org/c/what-exactly-does-bsymblic-do.html
In fact, the only thing the -Bsymbolic flag does when building a shared library is add a flag in the dynamic section of the binary called DT_SYMBOLIC.
This element’s presence in a shared object library alters the dynamic linker’s symbol resolution algorithm for references within the library. Instead of starting a symbol search with the executable file, the dynamic linker starts from the shared object itself. If the shared object fails to supply the referenced symbol, the dynamic linker then searches the executable file and other shared objects as usual.
关于TEXTREL和-Bsymbolic更多参考:
https://ask.helplib.com/linker/post_1398417
https://flameeyes.blog/2012/10/07/symbolism-and-elf-files-or-what-does-bsymbolic-do/
4、补充知识
查看动态库或目标文件是否是PIC的方法:
nm libxxx | grep "TEXTREL"
如果上述命令运行后没有任何打印,则说明是PIC的。