如何在没有-fpic-plag的情况下编译代码



当我编译一段没有fPIC的代码,然后编写以下命令时。我得到这个错误。如何解决此问题?

└──╼ $gcc -shared -o libmlpic.so ml_mainpic.o
/usr/bin/ld: ml_mainpic.o: warning: relocation against `myglob' in read-only section `.text'
/usr/bin/ld: ml_mainpic.o: relocation R_X86_64_PC32 against symbol `myglob' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status

问题的简短答案是,应该删除编译命令中的-shared选项。这将产生";正常的";将具有起始地址并且必须具有主函数的可执行文件。

在回答你的问题时,我自己也提出了一个问题,我在StackOverflow上问了这个问题,你可以浏览:在共享对象中,为什么gcc会通过GOT重新定位在同一共享对象中定义的全局变量?。

必须删除-shared的主要原因是,使用gcc编译时,默认情况下-fpie选项处于启用状态。这将产生位置无关的代码,该代码将使用RIP相对寻址访问可执行文件的数据段。正如我自己的问题(链接到上面(所述,RIP相对寻址被限制为32位偏移(由于x86-64机器代码的限制(。现在我想知道为什么这是个问题。问题实际上在于符号的插入。如果你在另一个共享库中或在与你自己的共享库一起加载的主程序中重新定义一个符号,那么这个符号可能是";选择";成为将在执行过程中使用的实际符号。这是一个问题,因为如果共享库距离此重新定义的偏移量超过32位,则它将溢出,共享库的代码将无法访问该符号。

这是relocation R_X86_64_PC32 against symbol `myglob' can not be used when making a shared object; recompile with -fPIC错误的原因,该错误指出RIP相对寻址重定位在用于访问导出的符号的共享对象中是非法的,因为该符号可能被插入。

通过使用__attribute__ ((visibility ("hidden")))隐藏符号,可以避免导出符号。这将阻止gcc导出符号,从而不存在插入的可能性。因此,将使用RIP相对寻址来访问该符号,而无需通过GOT进行间接寻址。

最新更新