为什么我需要-FPIC来与 - 未分辨 - 符号=忽略对象的文件
Why do I need -fPIC for compiling with --unresolved-symbols=ignore-in-object-files?
我有以下2个文件:
main.cpp:
#include <iostream>
int f();
int main(){
std::cout<<f();
}
functions.cpp:
int f(){
return 42;
}
i compile functions.cpp中的libfunctions.o使用此命令:
g++ -fPIC -shared functions.cpp -o libfunctions.so
i使用此命令将main.cpp汇编为A.out:
g++ main.cpp -Wl,--unresolved-symbols=ignore-in-object-files
我在使用此命令的A. un A. out:
LD_PRELOAD=./libfunctions.so ./a.out
我会得到一个分段故障。
但是,如果我将main.cpp编译为A.
g++ -fPIC main.cpp -Wl,--unresolved-symbols=ignore-in-object-files
然后起作用。
我理解为什么必须使用-fpic编译共享库,因为人们不知道在加载时加载的地址。但是,我不明白为什么还必须将main.cpp
编译为PIC。我认为,由于a.out
的负载地址在链接时间已知,因此肯定无需使用-fPIC
编译。
我想念什么?
我假设您正在使用GNU工具链。不幸的是,Binutils LD有时会为无效的输入产生损坏的二进制文件,而不是失败。
在您的情况下,我得到:
./a.out: error while loading shared libraries: unexpected PLT reloc type 0x00
此错误消息是正确的:
Relocation section '.rela.plt' at offset 0x628 contains 4 entries:
Offset Info Type Sym. Value Sym. Name + Addend
…
000000000000 000000000000 R_X86_64_NONE 0
R_X86_64_NONE
具有零值,如果遇到错误,有时会由LD使用,而不是实际重置。
这是否是LD错误,值得商but。LD产生了您要的二进制文件,忽略了错误。它确实产生了无效的搬迁。使用-fno-plt
编译时,我根本没有搬迁,但是该程序仍然崩溃,因为已解决的符号似乎相对于可执行文件或文本部分具有偏移0。
我怀疑使用-fPIC
,它恰好适合您,因为LD会为未知符号产生动态迁移。(不过,我无法获得Binutils 2.30来产生此搬迁。(
通常,不可能生成正确的动态迁移到未定义的符号。没有定义,在许多架构上,就无法确定目标是函数还是对象。如果使用复制重新定位,则对对象的未定义引用需要准确的尺寸信息。功能和对象引用都需要一个符号定义来获得正确的符号版本(如果有(。下连接极为问题的原因有很多。
可能值得将其报告为Binutils Linker错误,但我认为它将被视为非常低的优先级。
- 使用gcc从静态链接的文件中查找可选符号
- 检测 COFF 对象文件中C++内联符号
- 使用 fopen 打开 .pak 文件并使该文件应用于 const 无符号字符* (C++)
- 如何从二进制文件中的给定符号中获取调用程序图
- 如何将 UTF-8 文本从文件转换为某个可以迭代的容器,并检查每个符号是否为C++字母数字?
- CMake 生成的 MSVC 项目找不到符号,即使为其相关 dll 正确生成了 lib 文件也是如此
- 错误:当我从"WinDbg"打开可执行文件时,找不到符号文件。默认导出 ntdll 的符号.dll
- 可以在 cpp 文件中C++定义为特殊符号的变量β
- 尝试将字符串从文件读取到无符号字符向量中
- C++和带有国家符号的文件路径(也许用 UTF8 编码)
- 体系结构x86_64的未定义符号:c++/ h 文件和 cpp 文件
- 错误LNK2019:未解析的外部符号.c文件到cpp
- Visual Studio 2012 性能分析无法加载符号文件
- 查看给定VC++ exe中的所有符号/文件的方法
- gdb:在0x2aaaaaaab000添加的符号文件系统提供的 DSO 中找不到可加载的部分
- gdb:在添加的符号文件系统提供的编号为0x#的DSO中找不到可加载的节
- 类型是否在最终二进制文件中公开?它们在符号文件和RTTI中可用吗?
- Oracle是否为OCCI/OCI提供公共符号文件(PDB)
- gdb:什么是用于调试的符号文件
- 非常困如何找到符号文件