Связывание с GCC не обнаруживает флаг -fPIC

Вопрос или проблема

Я пытаюсь связать некоторые файлы. Вот моя команда:

gcc -T linker.ld -o Stack\ Berry.bin -ffreestanding -O2 -nostlib kernel.o boot.o -fPIC -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
/usr/bin/ld: final link failed: Nonrepresentable section on output

Я включил аргумент -fPIC, может быть, я просто поставил его не на то место? Я не смог найти ничего о синтаксисе этого флага. Спасибо!

Ваш boot.o имеет elf секцию .multiboot, что несовместимо с -fPIC. Вы можете попробовать скомпилировать boot.o с -fPIC, но это должно завершиться неудачей.

Смотрите https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#OS-image-format для заголовка.

С другой стороны, нет особого смысла создавать загрузочный объект с -fPIC. Даже если был бы “динамический загрузчик”, во время процесса загрузки не может быть ничего, с чем можно было бы динамически связываться.

Ответ или решение

При попытке связать файлы с использованием компилятора GCC и флага -fPIC, вы столкнулись с ошибкой, связанной с несовместимостью секций, а именно:

/usr/bin/ld: boot.o: relocation R_X86_64_32 against `.multiboot' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output

Понимание проблемы

Ваше сообщение об ошибке указывает на то, что объектный файл boot.o содержит секцию .multiboot, которая несовместима с флагом -fPIC (Position Independent Code). -fPIC используется для создания кода, который можно загружать в любое место в памяти, что обычно требуется для динамически связываемых библиотек. Однако хостовая система, загружающая загрузочный образ, не предоставляет такой возможности, поскольку при загрузке используется статическое связывание.

Ваша команда

Вы использовали следующую команду:

gcc -T linker.ld -o Stack\ Berry.bin -ffreestanding -O2 -nostlib kernel.o boot.o -fPIC -lgcc

Несмотря на то, что флаг -fPIC добавлен, проблема заключается в том, что boot.o необходимо компилировать без этого флага. Таким образом, не имеет смысла использовать -fPIC для создания загрузочного объекта, поскольку сам процесс загрузки не поддерживает динамическую компоновку.

Решение

  1. Компиляция без -fPIC: Убедитесь, что boot.o компилируется без флага -fPIC. Для этого необходимо проверить команду, с которой компилируется boot.o. Убедитесь, что для него не используется -fPIC.

  2. Проверка флагов компиляции: Если вы контролируете процесс компиляции boot.o, убедитесь, что используете правильные флаги. Например, команда для компиляции boot.o может выглядеть так:

    gcc -c -ffreestanding -O2 boot.c -o boot.o
  3. Объединение объектов: После компиляции обоих объектов (kernel.o и boot.o) без флага -fPIC, попробуйте выполнить линковку снова без этого флага:

    gcc -T linker.ld -o Stack\ Berry.bin -ffreestanding -O2 -nostlib kernel.o boot.o -lgcc

Заключение

Ваша ошибка возникла не из-за неправильного использования флага -fPIC непосредственно в команде линковки, а из-за того, что файл boot.o не должен компилироваться с этим флагом. В случае нагрузок, когда важна независимость расположения кода (например, создание динамических библиотек), -fPIC является обязательным. Но когда дело касается загрузочных образов, таких как boot.o, лучше обойтись статическим кодом. Поддержание ясности и правильности флагов компиляции — ключ к успеху в разработке низкоуровневого программного обеспечения.

Оцените материал
Добавить комментарий

Капча загружается...