g ++ -fPIC不生成与位置无关的代码

时间:2016-12-24 09:17:06

标签: c++ g++ dynamic-linking fpic

我已阅读主题GCC -fPIC option

所以我创建了我的testlib.cpp。

int foo(int num)
{   
    int result;

    if (num != 0)
    {
        result = 1;
    }
    else
    {
        result = 2;
    }

    return result;
}

当我编译为 g ++ -c -o testlib.o testlib.cpp 并作为 g ++ -fPIC -c -o testlib.o testlib.cpp testlib.o的相应objdump是相同的:

objdump -d testlib.o -M intel

testlib.o:     file format elf32-i386

Disassembly of section .text:

00000000 <_Z3fooi>:
   0:   55                      push   ebp
   1:   89 e5                   mov    ebp,esp
   3:   83 ec 10                sub    esp,0x10
   6:   83 7d 08 00             cmp    DWORD PTR [ebp+0x8],0x0
   a:   74 09                   je     15 <_Z3fooi+0x15>
   c:   c7 45 fc 01 00 00 00    mov    DWORD PTR [ebp-0x4],0x1
  13:   eb 07                   jmp    1c <_Z3fooi+0x1c>
  15:   c7 45 fc 02 00 00 00    mov    DWORD PTR [ebp-0x4],0x2
  1c:   8b 45 fc                mov    eax,DWORD PTR [ebp-0x4]
  1f:   c9                      leave  
  20:   c3                      ret   

我希望在使用-fPIC进行编译时, jump je 命令的参数地址与位置无关。所以两个objdumps应该是不同的。我理解错了什么?

2 个答案:

答案 0 :(得分:2)

默认情况下,

-fPIC在较新的gcc版本中处于启用状态。即使没有选项,代码也与位置无关:

eb 07                   jmp    1c <_Z3fooi+0x1c>

这与位置无关,查看2字节操作码,即使反汇编打印符号及其偏移量也是为了清晰。

请注意,无论选项如何,编译器很可能会为那种短跳产生与位置无关的代码。

所以这个标志现在不是很有用。但您可以使用-fno-PIC开关禁用PIC。

答案 1 :(得分:2)

GCC编译器无法有意生成与位置相关的代码。这种能力没有任何实际意义。

GCC可以做的事实上是生成与位置无关的代码(使用-fPIC选项),或者&#34;无论什么&#34;代码(没有-fPIC选项)。当你使用&#34;无论什么&#34;模式,编译器只是忽略了位置依赖性的问题,并根据其他考虑因素来决定代码生成。这意味着,即使您没有请求-fPIC,您仍然可能很容易地完全依赖与位置无关的代码&#34;意外&#34;:因为恰好与位置无关的代码最适合其他原因(更紧凑,运行更快等)。

如果您想观察差异,则需要一个更具代表性的示例。在你的例子中,所有跳跃都接近跳跃。它们通过相对(基于偏移的)跳转指令自然地实现。任何敏感的编译器都会在这种情况下使用这种相对跳转。这样做的副作用是,即使您没有明确要求,也最终会得到与位置无关的代码。位置独立来自免费&#34;在这种情况下。

如果你想观察差异,你需要一个不会出现位置独立的例子#34;免费&#34;。你需要一些能够在位置独立性和其他重要因素(如效率和/或规模)之间进行明确权衡的事情。如果你想出这样一个例子,你会看到-fPIC所产生的差异。