判断一个目标文件是否用-fPIC编译 - 可打印的版本 +- WeHack BBS (https://bbs.wehack.space) +-- 版块: 计算机技术 (https://bbs.wehack.space/forum-5.html) +--- 版块: 程序设计讨论区 (https://bbs.wehack.space/forum-14.html) +--- 主题: 判断一个目标文件是否用-fPIC编译 (/thread-362.html) |
判断一个目标文件是否用-fPIC编译 - vimacs - 04-07-2023 构建动态库所用的目标文件都必须是位置无关的,因此编译动态库的源文件的时候都会加-fPIC. 如果构建这个动态库需要通过链接外部的静态库,而外部的静态库不是用-fPIC编译的,那么就会链接失败。为了调试这类问题,需要知道怎么判断一个静态库,更具体的是静态库内的目标文件,是不是用-fPIC构建的。 在Bing问了一下,找到一个stackoverflow[1]链接,里面说可以用 readelf --relocs 查看,它的方法是找 PLT, GOT, JUMP_SLOT 这些字符串。然而不用 -fPIC 构建的静态库也会有 R_X86_64_PLT32 这样的重定位,似乎这方法不太行。另外可以用 nm 找 _GLOBAL_OFFSET_TABLE_, 似乎也有同样的问题。 之后我点进这个问题的一个相关问题[2],然后想明白是怎么回事了。这个方法也是用 readelf --relocs, 但是它找某些不符合位置无关这个性质的重定位,即 R_X86_64_32 等。 代码: readelf --relocs /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++.a |\ 找到了 R_X86_64_32 或者 R_X86_64_32S 就表明不是用 -fPIC 构建了。同时我也明白链接时报的错误信息是什么意思了,其实就是说遇到了不满足位置无关的重定位。 (后来我查到了为什么我构建某个动态库链接失败,原因是构建一个外部静态库的时候虽然加了-fPIC,但后来又被覆盖了。) [1] https://stackoverflow.com/questions/1340402/how-can-i-tell-with-something-like-objdump-if-an-object-file-has-been-built-wi [2] https://unix.stackexchange.com/questions/89211/how-to-test-whether-a-linux-binary-was-compiled-as-position-independent-code |