重新编译-fPIC问题

Aks*_*ay 3 c assembly

我有以下c程序

#include <stdio.h>

int main() 
{
    printf("hello');
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我编译这个文件

gcc -c rr2.c
Run Code Online (Sandbox Code Playgroud)

然后使用带有共享选项的链接器

/ld-new -shared    -o tmpdir/dump rr2.o 
Run Code Online (Sandbox Code Playgroud)

它给出以下错误

rr2.o:在创建共享对象时,不能使用针对`.rodata'的重定位R_X86_64_32; 用-fPIC重新编译

我不明白为什么会出现这种错误.任何人都可以帮我理解为什么会出现这个错误?

Som*_*ude 5

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

如链接器所建议的那样,通过-fPIC在编译时添加标志来完成:

> gcc -fPIC -c rr2.c
Run Code Online (Sandbox Code Playgroud)

  • @GauravPathak代码可以在不与位置无关的情况下重定位.非位置无关的代码可能需要在运行之前进行修改.这种修改可能会对虚拟内存使用产生一些有趣(坏)的影响,因此更现代的操作系统往往需要PIC来共享对象.请参阅https://en.wikipedia.org/wiki/Position-independent_code (4认同)
  • 通常,这意味着代码可以从不同的地址运行,并且它包含带有数据的特殊表,这些数据必须在代码中进行修改以使其运行.后者可以放在任何地址并运行而无需任何更改 (2认同)
  • @GauravPathak在问题中字符串文字`"hello"`存储在内存中(可能在`.rodata`部分),链接器将它放在可执行文件中的某个位置并为操作系统构建重定位表,因此操作系统会将可执行文件加载到一些内存,并修补代码,让它知道,"你好"`落在哪里.在类似PIC的代码中,机器代码以"相对"的方式生成,它知道文字是例如当前指令的+300字节,所以它不需要来自OS的绝对地址,它只是使用它的当前地址指令(`cs:rip`)加上相对偏移量. (2认同)