objdump дает одинаковый вывод для объектных файлов, созданных с использованием -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все еще не повезло.

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-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
0

Другие решения

По умолчанию, objdump не выполняет обработку перемещения. Пытаться objdump --reloc вместо.

В вашем случае компилятор и ассемблер производят R_X86_64_PLT32 перемещение. Это позиционно-независимое перемещение. Похоже, ваш компилятор по умолчанию генерирует двоичные файлы PIE. -no-pie это флаг компоновщика, вам нужно использовать -fno-pie изменить вывод компилятора. (В данном конкретном случае это не имеет значения, поскольку после запуска редактора ссылок окончательный результат будет идентичным.)

1

По вопросам рекламы [email protected]