Компиляция кода GAS не определяет опцию -fPIC - PullRequest
0 голосов
/ 14 ноября 2018

Я пытаюсь скомпилировать некоторый код GAS для проекта, используя компилятор GCC GNU. Вот как я его компилирую:

gcc -c boot.s -o boot.o -fPIC

После того, как я скомпилировал файл kernel.c с аргументом -fPIC, я пытаюсь связать его с помощью этой команды:

gcc -N -T linker.ld -o Slack\ Berry.bin -ffreestanding -nostdlib kernel.o boot.o -lgcc

Это приходит с:

/usr/bin/ld: boot.o: relocation R_X86_64_32 against '.multiboot' can not be used when making a PIE object; recompile with -fPIC

Это заставляет меня думать, что он не компилирует мой код GAS с -fPIC. Как я могу это исправить?

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Перекомпиляция с -fPIC применяется только в том случае, если asm был сгенерирован компилятором, а не написан вручную. Это не влияет на то, как asm собирается в машинный код.

Проблема в том, что ваш исполняемый файл PIE не может быть связан с 32-битными абсолютными адресами. (Вы хотели сделать ПИРОГ вместо статического зависимого от позиции исполняемого файла)?

Вам не нужны полные ресурсы совместно используемой библиотеки для ссылки на символы в другой библиотеке или главном исполняемом файле (например, ответ @ yugr показывает, как это сделать). Ваше автономное ядро ​​может даже не иметь GOT или PLT, и определенно не должно использовать их для внутренних символов.

Единственное необходимое изменение - lea bar(%rip), %rdx, REA-относительный LEA вместо mov $imm32, %r/m64. (Movabs будет работать, но будет больше и, как правило, медленнее.)

Или, если вы действительно намеревались собрать с -static и создать исполняемый файл, который будет загружен по фиксированному адресу в младших 32 битах адресного пространства, вы должны использовать mov $bar, %edx, чтобы получить 5-байтовый mov $imm32, %r32 кодировка вместо 7-байтового mov $sign_extended_imm32, %r/m64 или 7-байтового LEA. См. Также Разница между movq и movabsq в x86-64

0 голосов
/ 14 ноября 2018

Прежде всего вам, вероятно, нужно -fPIE, а не -fPIC. -fPIE позволяет компилятору генерировать более эффективный код, но может использоваться только для кода, который является частью основного исполняемого файла (не разделяемой библиотеки).

Теперь и -fPIC, и -fPIE являются флагами только для компилятора и не передаются ассемблеру. Вам нужно явно использовать специфическую для PIC мнемонику в коде сборки вместо вызовов, зависящих от позиции, и ответвлений, например, вместо

movq $bar, %rdx

использование

movq bar@GOTPCREL(%rip), %rdx

(обычно, чтобы получить нужный мне синтаксис, я просто запускаю gcc -fPIE -S -o- в соответствующем фрагменте C).

...