1

我有两个文件,ah 和 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,仍然没有运气。

4

2 回答 2

1

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

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

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

要坚持非 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    $0x0,%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    $0x0,%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
于 2018-04-02T14:39:26.313 回答
1

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

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

于 2018-04-01T19:50:48.563 回答