GCC 8 для ARM в режиме LTO убирает обработчики прерываний и слабые функции - как это предотвратить? - PullRequest
0 голосов
/ 01 января 2019

Мое целевое устройство - это устройство на основе EFM32 Cortex-M3.Мой набор инструментов - официальный набор инструментов ARM GNU gcc-arm-none-eabi-8-2018-q4-major.

Все отлично работает без LTO, но чтобы заставить LTO работать, я должен пометить весь код обработчика прерываний-fno-lto.Я хотел бы избавиться от этого обходного пути.

Проблема в том, что каждый обработчик прерываний удаляется из окончательного двоичного файла.(Я проверяю с помощью arm-none-eabi-nm --print-size --size-sort --radix=d -C -n file.out) Это приводит к бинарному сбою.

Копаем глубже и после поиска в Google похожих проблем:

Пример кода из startup_efm32gg.cопределяет обработчики прерываний по умолчанию следующим образом:

void DMA_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler")));
/* many other interrupts */
void Default_Handler(void) { while (1); }

Та же проблема возникает и для обычных определений обработчиков прерываний (например, без псевдонимов и не слабых)

Возможно, это связано, но кажетсячто слабые символы ведут себя неправильно в режиме LTO таким же образом.

Заранее спасибо за любые идеи!

Редактировать: Смотрите мой ответ на помеченный ответ для полного решения!

1 Ответ

0 голосов
/ 01 января 2019

Откуда ссылаются на ваши обработчики прерываний?Так же как статические функции и объекты, на которые нет ссылок, будут удалены из одного модуля перевода, так и неиспользуемые внешние будут удалены во время LTO.Чтобы предотвратить это (и чтобы ваша программа в любом случае была действительной в абстрактной модели), должна существовать некоторая цепочка ссылок, начиная с точки входа, ведущей к функциям и объектам;если ничего не существует, то вы фактически не используете их в своей программе .

Если ссылка взята из сценария компоновщика или исходного файла asm, возможно, это ошибка в LTOи он не видит ссылки, как это должно быть.В этом случае вы можете применить хак, подобный __attribute__((__used__)), к определениям уязвимых функций.В качестве альтернативы вы можете сделать поддельные ссылки на них, например, сохраняя их адреса в фиктивных изменчивых объектах или используя их адреса во входных ограничениях для очистки встроенных блоков asm.В качестве еще одной альтернативы может быть способ переделать все, что вы делаете с исходными файлами asm или связанными сценариями, чтобы сделать вашу таблицу прерываний на уровне C, с соответствующими структурами / массивами в специальных разделах, чтобы компилятор мог фактически видетьссылки без вас подделать их.

...