objdump 为使用和不使用 -fPIC 生成的目标文件提供相同的输出

objdump gives the same output for object files generated with and without -fPIC

我有两个文件,a.h 和 a.cpp:

// a.h
extern "C" void a();

// a.cpp
#include "a.h"
#include <stdio.h>

void a()
{
    printf("a\n");
}

我在使用和不使用 -fPIC 的情况下编译了它,然后 objdump 编辑了两者。 奇怪的是,我得到了两个文件相同的输出。对于 a(),我在两种情况下都得到了:

callq 15 <a+0x15>

我也试过用-no-pie编译目标文件,还是不行。

默认情况下,objdump不执行重定位处理。请尝试 objdump --reloc

在您的情况下,编译器和汇编程序会产生 R_X86_64_PLT32 重定位。这是 position-independent 搬迁。您的编译器似乎默认生成 PIE 二进制文件。 -no-pie 是一个 linker 标志,您需要使用 -fno-pie 来更改编译器输出。 (在这种特殊情况下,这无关紧要,因为在 link 编辑器具有 运行 之后最终结果将是相同的。)

以详细模式 (-v) 编译您的代码(或任何东西),检查输出, 你会发现:

Configured with:  ... --enable-default-pie ...

从 GCC 6 开始,这意味着工具链是为编译 PIC 代码而构建的,link 默认情况下 PIE 可执行文件。

要坚持non-PIC编译,运行例如

g++ -Wall -c -fno-PIC -o anopic.o a.cpp

并坚持PIC编译,运行例如

g++ -Wall -c -fPIC -o apic.o a.cpp

然后运行:

$ objdump -d anopic.o 

anopic.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <a>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   bf 00 00 00 00          mov    [=13=]x0,%edi
   9:   e8 00 00 00 00          callq  e <a+0xe>
   e:   90                      nop
   f:   5d                      pop    %rbp
  10:   c3                      retq     

和:

$ objdump -d apic.o 

apic.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <a>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # b <a+0xb>
   b:   e8 00 00 00 00          callq  10 <a+0x10>
  10:   90                      nop
  11:   5d                      pop    %rbp
  12:   c3                      retq

你会看到区别的。

您可以通过以下方式将重定位与程序集交错:

$ objdump --reloc -d anopic.o 

anopic.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <a>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   bf 00 00 00 00          mov    [=15=]x0,%edi
            5: R_X86_64_32  .rodata
   9:   e8 00 00 00 00          callq  e <a+0xe>
            a: R_X86_64_PC32    puts-0x4
   e:   90                      nop
   f:   5d                      pop    %rbp
  10:   c3                      retq

和:

$ objdump --reloc -d apic.o 

apic.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <a>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # b <a+0xb>
            7: R_X86_64_PC32    .rodata-0x4
   b:   e8 00 00 00 00          callq  10 <a+0x10>
            c: R_X86_64_PLT32   puts-0x4
  10:   90                      nop
  11:   5d                      pop    %rbp
  12:   c3                      retq