Независимый от позиции исполняемый файл (-pie) для руки (cortex-m3)
Я программирую для stm32 (Cortex-m3) с помощью исходного кода g++ lite(на основе версии gcc4.7.2). И я хочу, чтобы исполняемые файлы загружались динамически. Я знал, что у меня есть два варианта:
1. перемещаемый эльф, которому нужен эльфийский парсер.
2. позиционно-независимый код (PIC) с регистром глобального смещения
Я предпочитаю PIC с глобальным регистром смещения, потому что кажется, что его проще реализовать, и я не знаком с elf или какой-либо библиотекой elf. Кроме того, с помощью некоторых инструментов легко сгенерировать файл.bin из файла elf.
Я пытался собрать свою программу с опциями компиляции "-msingle-pic-base -fpic" и опциями связывания "-pie", но затем я получил ошибку компоновки:
... path... ld.exe:... path... thumb2 \ libstdC++.a(pure.o): перемещение R_ARM_THM_MOVW_ABS_NC против `локального символа 'не может использоваться при создании общего объекта; перекомпилировать с -fPIC
Я не совсем понимаю сообщение об ошибке. Кажется, стандартная библиотека c/ C++ по умолчанию не может соответствовать моим параметрам, и мне нужно получить исходный код библиотеки и перестроить для своих собственных целей.
Так,
1. Может ли кто-нибудь предоставить мне полезную информацию / ссылку о том, как работать с независимым от позиции исполняемым файлом?
2. с опцией -msingle-pic-base мне больше не нужно заботиться о GOT и ld-скрипте, верно?
Примечание: без опции "-pie" я могу собрать программу. Но программа завершается неудачно при вызове виртуальной функции C++ (когда я использую симулятор IDE(keil) для отладки своей программы). Я не понимаю, что происходит и чего мне не хватает.
-------------------------------------------------- --------------------
- добавлено 20130314
- с опцией -msingle-pic-base мне больше не нужно беспокоиться о GOT и ld-скрипте, верно?
Из моих экспериментов регистр (r9 используется в моей программе) должен указывать на начало разделов got.plt. Удалите опцию "-pie", соединение будет успешным (с правильно установленным r9), после чего виртуальная функция C++ будет успешно вызвана. Тем не менее, я все еще думаю, что опция -pie важна, что может гарантировать, что текущая стандартная библиотека не зависит от позиции. Кто-нибудь может объяснить это для меня?
-------------------------------------------------- --------------------
- добавлено 20130315
Я взглянул на документы по ABI с сайта ARM. Но это мало помогло, потому что они не нацелены на конкретную платформу. Кажется, есть концепция EABI (я использую исходную версию arm-none-eabi), но я не смог найти никакой документации по EABI с веб-сайта arm. Я не могу также найти документацию по этой теме от Sourcery и GCC. Существует несколько реализаций PIC, так какой из них использует исходный код g ++ в случае none-eabi? Я думаю, что поведение опций "-msingle-pic-base", "-fpie", "-pie" так плохо документировано!
-------------------------------------------------- ---------------------
Из кода разборки я только что выяснил, что, с помощью -msingle-pic-base, r9 должен указывать на базовый адрес раздела.got, указатели в разделах.got являются абсолютными указателями. и адресация переменной аналогична описанию в статье: Независимый код положения (PIC) в разделяемых библиотеках. Поэтому мне все еще нужно изменить разделы ".got" при загрузке. Я не знаю, для чего используется раздел ".got.plt" в моей программе. Кажется, что вызовы функций используют адресацию, относящуюся к ПК.
Как собрать с помощью "-pie" или как связать стандартную библиотеку, скомпилированную с "-fpic", для меня все еще проблема.
2 ответа
Сообщение об ошибке говорит вам перекомпилировать библиотеку libstdC++, которая чаще всего собирается при сборке компилятора gcc.
Таким образом, вы должны перекомпилировать ваши стандартные библиотеки (libstdC++, libgcc_*, libc, libm и все) с -fPIC и связать ваш проект с ними.
Если вы полагаетесь на предварительно скомпилированные пакеты компилятора, вы в основном вне игры в мире микроконтроллеров. Если вы создаете свой компилятор самостоятельно (что, кстати, не так уж сложно, но является сложной / экспертной задачей), вы в пути.
Также возможно скомпилировать ваши стандартные библиотеки с помощью имеющегося у вас компилятора. Вам понадобятся исходные коды библиотек и выясните, как их собирает система сборки пакетов компилятора, и вы должны имитировать это. Возможно, вот некоторые эксперты, которые могут посоветовать вам по этому пути.
Есть хороший пост в блоге по этой теме через восемь лет после первоначального задания вопроса, но он есть: https://mcuoneclipse.com/2021/06/05/position-independent-code-with-gcc-for-arm-cortex -м /
Общая схема состоит в том, что вы должны:
- Настройте GOT на основе информации, созданной компоновщиком
- Настройте PLT из информации заголовка программы
- Реализуйте связыватель на основе записей GOT
- Скомпилируйте свою библиотеку как общий перемещаемый двоичный файл:
-msingle-pic-base -mpic-register=r9 -mno-pic-data-is-text-relative -fPIC
- Установите R9 соответственно