简体   繁体   English

-fPIC 对不使用 -fPIE -pie 构建的可执行文件有任何影响吗?

[英]Does -fPIC has any effect on an executable built without -fPIE -pie?

I've seen a lot of questions at SO asking why not all code is compiled as PIC or why we can't always use -fPIC .我在 SO 看到了很多问题,询问为什么不是所有代码都编译为 PIC或者为什么我们不能总是使用-fPIC

However all of the answers lack an explanation about what happens when your objects are compiled with -fPIC but you link them to an executable that is not a PIE (position-independent executable).但是,所有答案都没有解释当您的对象使用-fPIC编译但您将它们链接到不是PIE(位置无关的可执行文件)的可执行文件时会发生什么。

From my understanding (using a few small examples and disassembling/inspecting them with readelf ), it looks like compiling with -fPIC does not result in a different binary when linked without -pie -fPIE .根据我的理解(使用一些小示例并使用readelf反汇编/检查它们),看起来使用-fPIC进行编译在不使用-pie -fPIE进行链接时不会产生不同的二进制文件。

My (simplistic?) explanation would be that during link time, it is known that the final executable is not intended to be relocatable, so we can resolve all addresses as in a non-PIC build and get rid of GOT and PLT completely.我(简单?)的解释是,在链接时,已知最终的可执行文件不是可重定位的,因此我们可以像在非 PIC 构建中一样解析所有地址,并完全摆脱 GOT 和 PLT。 That is also my observation: If I build a PIE, readelf displays a GOT/PLT section.这也是我的观察:如果我构建一个 PIE, readelf会显示一个 GOT/PLT 部分。 If I don't build a PIE, the GOT/PLT is gone, no matter if I used -fPIC or not.如果我不构建 PIE,无论我是否使用-fPIC ,GOT/PLT 都会消失。

My question is whether this observation我的问题是这个观察是否

  • is correct (as well as my explanation) and是正确的(以及我的解释)并且
  • if not, why is my reasoning wrong then?如果不是,那为什么我的推理是错误的呢?

I found it surprisingly difficult to find a concrete answer to this simple question, that's why I'm asking here.我发现很难找到这个简单问题的具体答案,这就是我在这里问的原因。

it looks like compiling with -fPIC does not result in a different binary when linked without -pie -fPIE.看起来在没有-pie -fPIE 的情况下链接时,使用-fPIC 进行编译不会产生不同的二进制文件。

It is trivial to prove that this is not the case.证明事实并非如此是微不足道的。

#include <stdio.h>

const char *p = "Hello";
int x[1024];

int main()
{
  printf("%d: %s\n", __LINE__, p);
  x[1] = 42;
  return x[2];
}

Using gcc (GCC) 12.3.1 20230508 (Red Hat 12.3.1-1) and GNU ld version 2.38-27.fc37使用gcc (GCC) 12.3.1 20230508 (Red Hat 12.3.1-1)GNU ld version 2.38-27.fc37

gcc -c -fPIC -c x.c && gcc -no-pie x.o -o x1
gcc -no-pie x.c -o x2

Disassembly for x1 : x1的反汇编:

   0x0000000000401126 <+0>:     push   %rbp
   0x0000000000401127 <+1>:     mov    %rsp,%rbp
   0x000000000040112a <+4>:     mov    $0x404028,%rax
   0x0000000000401131 <+11>:    mov    (%rax),%rax
   0x0000000000401134 <+14>:    mov    %rax,%rdx
   0x0000000000401137 <+17>:    mov    $0x8,%esi
   0x000000000040113c <+22>:    lea    0xed3(%rip),%rax        # 0x402016
   0x0000000000401143 <+29>:    mov    %rax,%rdi
   0x0000000000401146 <+32>:    mov    $0x0,%eax
   0x000000000040114b <+37>:    call   0x401030 <printf@plt>
   0x0000000000401150 <+42>:    mov    $0x404060,%rax
   0x0000000000401157 <+49>:    movl   $0x2a,0x4(%rax)
   0x000000000040115e <+56>:    mov    $0x404060,%rax
   0x0000000000401165 <+63>:    mov    0x8(%rax),%eax
   0x0000000000401168 <+66>:    pop    %rbp
   0x0000000000401169 <+67>:    ret

For x2 :对于x2

   0x0000000000401126 <+0>:     push   %rbp
   0x0000000000401127 <+1>:     mov    %rsp,%rbp
   0x000000000040112a <+4>:     mov    0x2ef7(%rip),%rax        # 0x404028 <p>
   0x0000000000401131 <+11>:    mov    %rax,%rdx
   0x0000000000401134 <+14>:    mov    $0x8,%esi
   0x0000000000401139 <+19>:    mov    $0x402016,%edi
   0x000000000040113e <+24>:    mov    $0x0,%eax
   0x0000000000401143 <+29>:    call   0x401030 <printf@plt>
   0x0000000000401148 <+34>:    movl   $0x2a,0x2f12(%rip)        # 0x404064 <x+4>
   0x0000000000401152 <+44>:    mov    0x2f10(%rip),%eax        # 0x404068 <x+8>
   0x0000000000401158 <+50>:    pop    %rbp
   0x0000000000401159 <+51>:    ret

That is not an identical binary -- using -fPIC added some overhead.不是一个完全相同的二进制文件——使用-fPIC增加了一些开销。

The amount of overhead depends on the platform, and may also depend on the amount of linker optimizations which can be performed.开销的数量取决于平台,也可能取决于可以执行的 linker 优化的数量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM