У меня есть два файла, 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
все еще не повезло.
Скомпилируйте ваш код (или что-нибудь еще) в подробном режиме (-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-64Disassembly 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-64Disassembly 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-64Disassembly 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-64Disassembly 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
По умолчанию, objdump
не выполняет обработку перемещения. Пытаться objdump --reloc
вместо.
В вашем случае компилятор и ассемблер производят R_X86_64_PLT32
перемещение. Это позиционно-независимое перемещение. Похоже, ваш компилятор по умолчанию генерирует двоичные файлы PIE. -no-pie
это флаг компоновщика, вам нужно использовать -fno-pie
изменить вывод компилятора. (В данном конкретном случае это не имеет значения, поскольку после запуска редактора ссылок окончательный результат будет идентичным.)