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
我有两个文件,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