【问题标题】:Recompile with -fPIC issue使用 -fPIC 问题重新编译
【发布时间】:2017-08-22 10:29:08
【问题描述】:

我有以下c程序

#include <stdio.h>

int main() 
{
    printf("hello');
    return 0;
}

当我编译这个文件时

gcc -c rr2.c

然后使用带有 shared 选项的链接器,例如

/ld-new -shared    -o tmpdir/dump rr2.o 

它给出了以下错误

rr2.o: 重定位 R_X86_64_32 对 `.rodata' 在制作共享对象时不能使用;用 -fPIC 重新编译

我不明白为什么会发生此错误。谁能帮我理解为什么会出现这个错误?

【问题讨论】:

    标签: c assembly


    【解决方案1】:

    动态共享“对象”没有固定地址,它们被加载到内存中。这意味着对函数和变量的所有引用都必须位置独立。您必须创建位置无关代码(或简称 PIC)。

    按照链接器的建议,这是通过在编译时添加 -fPIC 标志来完成的:

    > gcc -fPIC -c rr2.c
    

    【讨论】:

    • 我现在对可重定位和位置无关的代码感到困惑。
    • 通常这意味着代码可以从不同的地址运行,并且它包含特殊的表格,其中包含必须在代码中修改以使其运行的数据。后者是可以放置在任何地址并且无需任何更改即可运行的东西
    • @GauravPathak 代码可以重定位,而不与位置无关。非位置无关的代码可能需要在运行之前进行修改。这种修改可能会对虚拟内存的使用产生一些有趣的(坏的)影响,因此更现代的操作系统往往需要 PIC 来共享对象。见en.wikipedia.org/wiki/Position-independent_code
    • @GauravPathak 在问题中,字符串文字"hello" 存储在内存中(可能在.rodata 部分中),链接器将其放在可执行文件中的某个位置并为操作系统构建重定位表,因此操作系统会将可执行文件加载到一些内存中,并修补代码以使其知道"hello" 所在的位置。在类似 PIC 的代码中,机器代码是以“相对”方式生成的,它知道文字是当前指令的例如 +300 个字节,因此它不需要来自操作系统的绝对地址,它只会使用它的当前地址指令(cs:rip)加上相对偏移量。
    猜你喜欢
    • 2021-09-03
    • 2013-08-25
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    相关资源
    最近更新 更多