我有一堆在没有该-fPIC选项的情况下编译的目标文件。因此对函数的调用不使用@PLT. (源代码是 C 语言并用 编译clang)。
我想将这些对象文件链接到一个共享库中,我可以使用dlopen. .so我需要这样做,因为在加载实际内容之前我必须进行大量设置。
但每次我尝试链接该-shared选项时,都会收到错误 -
创建共享库时不能使用
R_X86_64_PC32针对符号的重定位;splay_tree_lookup重新编译-fPIC
我从源代码重新编译没有任何问题。但我不想使用-fPIC. 这是我们正在开发自定义编译器的研究项目的一部分。PIC 不适用于我们试图在编译器中提供的保证类型。
是否有一些我可以使用的标志,ld以便它生成加载时重定位库。事实上,我没有搬家,也没什么问题。我可以为库提供基地址,dlopen如果虚拟地址不可用,则可能会失败。
我用来编译c文件的命令相当于 -
clang -m64 -c foo.c
Run Code Online (Sandbox Code Playgroud)
为了链接我正在使用
clang -m64 -shared *.o -o foo.so
Run Code Online (Sandbox Code Playgroud)
我说等效是因为它是一个自定义编译器(forked off clang)并且有一些额外的步骤。但它是等价的。
小智 -1
如果可能的话,使用选项重新编译库的目标文件-fpic -shared将是最好的选择!
man ld说:
\n\n\n
-i执行增量链接(与选项 -r 相同)。\n
-r
\n--relocatable生成可重定位的输出——即生成一个输出文件,该文件又可以用作
\nld. 这通常称为部分链接。作为副作用,在支持标准 Unix 幻数的环境中,此选项还会将输出文件\xe2\x80\x99s 幻数设置为“OMAGIC”。如果未指定此选项,则会生成绝对文件。当链接 C++ 程序时,此选项不会解析对构造函数的引用;为此,请使用-Ur.当输入文件与输出文件的格式不同时,仅当该输入文件不包含任何重定位时才支持部分链接。不同的输出格式可能有进一步的限制;例如,某些基于“a.out”的格式根本不支持与其他格式的输入文件的部分链接。
\n
我相信您可以将库对象文件部分链接到可重定位(PIC)库,然后将该库与源代码对象文件链接以创建共享库。
\nld -r -o libfoo.so *.o\ncp libfoo.so /foodir/libfoo.so\ncd foodir\nclang -m32 -fpic -c foo.c\nclang -m32 -fpic -shared *.o -o foo.so\nRun Code Online (Sandbox Code Playgroud)\n关于库基地址:
\n(再次来自man ld)
\n\n\n
--section-start=sectionname=org在输出文件中的绝对地址处找到 org. 您可以根据需要多次使用此选项来定位命令行中的多个部分。org 必须是单个十六进制整数;为了与其他链接器兼容,您可以省略通常与十六进制值关联的前导 0x。注意:节名、等号 (“=”) 和 org.xml 之间不应有空格。
\n
您也许可以移动图书馆的.text部分?
\n\n\n
--image-base value使用 value 作为程序或 dll 的基地址。这是加载程序或 dll 时将使用的最低内存位置。为了减少重新定位的需要并提高 dll 的性能,每个 dll 都应具有唯一的基地址并且不与任何其他 dll 重叠。对于可执行文件,默认值为 0x400000;对于 dll,默认值为 0x10000000。[此选项特定于链接器的 i386 PE 目标端口]
\n