LINUX.ORG.RU

Как включить LTO

 ,


2

1

При сборке модулей добавляю -flto -fno-fat-lto-objects, при вызове ld ничего не добавляю, не знаю что надо, результат.

arm-none-eabi-ld: /tmp/pmc/hal/adc.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/hal/can.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/hal/hal.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/hal/pwm.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/hal/usart.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/ap.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/cml.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/lib.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/m.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/pmc.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/sh.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/task.o: plugin needed to handle lto object
arm-none-eabi-ld: /tmp/pmc/tel.o: plugin needed to handle lto object
/tmp/pmc/hal/entry.o: In function `__iRbssComp':
(.text+0x2a): undefined reference to `halStart'
/tmp/pmc/hal/entry.o: In function `__iRbssComp':
(.text+0x2e): undefined reference to `halMain'
/tmp/pmc/hal/entry.o:(.vectors+0x8): undefined reference to `irqNMI'
/tmp/pmc/hal/entry.o:(.vectors+0xc): undefined reference to `irqHardFault'
/tmp/pmc/hal/entry.o:(.vectors+0x10): undefined reference to `irqMemoryFault'
/tmp/pmc/hal/entry.o:(.vectors+0x14): undefined reference to `irqBusFault'
/tmp/pmc/hal/entry.o:(.vectors+0x18): undefined reference to `irqUsageFault'
/tmp/pmc/hal/entry.o:(.vectors+0x2c): undefined reference to `irqSVCall'
/tmp/pmc/hal/entry.o:(.vectors+0x38): undefined reference to `irqPendSV'
/tmp/pmc/hal/entry.o:(.vectors+0x3c): undefined reference to `irqSysTick'
/tmp/pmc/hal/entry.o:(.vectors+0x78): undefined reference to `irqDMA1_Stream3'
/tmp/pmc/hal/entry.o:(.vectors+0x88): undefined reference to `irqADC'
/tmp/pmc/hal/entry.o:(.vectors+0x90): undefined reference to `irqCAN1_RX0'
/tmp/pmc/hal/entry.o:(.vectors+0x94): undefined reference to `irqCAN1_RX1'
/tmp/pmc/hal/entry.o:(.vectors+0x98): undefined reference to `irqCAN1_SCE'
/tmp/pmc/hal/entry.o:(.vectors+0xa4): undefined reference to `irqTIM1_UP_TIM10'
/tmp/pmc/hal/entry.o:(.vectors+0xdc): undefined reference to `irqUSART3'
Makefile:57: recipe for target '/tmp/pmc/pmc' failed
make: *** [/tmp/pmc/pmc] Error 1

Если вызвать gcc вместо прямого вызова ld то получаю проблемы со всяким стартовым кодом и библиотеками которые мне не нужны. Когда-то я и перешел на вызов ld чтобы не иметь этих проблем.

/usr/libexec/gcc/arm-none-eabi/ld: error: /tmp/ccs6XVoG.ltrans0.ltrans.o uses VFP register arguments, /tmp/pmc/pmc.1.o does not
/usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /tmp/ccs6XVoG.ltrans0.ltrans.o
/usr/libexec/gcc/arm-none-eabi/ld: error: /tmp/ccs6XVoG.ltrans1.ltrans.o uses VFP register arguments, /tmp/pmc/pmc.1.o does not
/usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /tmp/ccs6XVoG.ltrans1.ltrans.o
/usr/libexec/gcc/arm-none-eabi/ld: error: /tmp/ccs6XVoG.ltrans2.ltrans.o uses VFP register arguments, /tmp/pmc/pmc.1.o does not
/usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /tmp/ccs6XVoG.ltrans2.ltrans.o
/usr/libexec/gcc/arm-none-eabi/ld: error: /tmp/ccs6XVoG.ltrans3.ltrans.o uses VFP register arguments, /tmp/pmc/pmc.1.o does not
/usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /tmp/ccs6XVoG.ltrans3.ltrans.o
/usr/libexec/gcc/arm-none-eabi/ld: error: /tmp/ccs6XVoG.ltrans4.ltrans.o uses VFP register arguments, /tmp/pmc/pmc.1.o does not
/usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /tmp/ccs6XVoG.ltrans4.ltrans.o
/usr/libexec/gcc/arm-none-eabi/ld: error: /tmp/ccs6XVoG.ltrans5.ltrans.o uses VFP register arguments, /tmp/pmc/pmc.1.o does not
/usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /tmp/ccs6XVoG.ltrans5.ltrans.o
/usr/libexec/gcc/arm-none-eabi/ld: error: /tmp/ccs6XVoG.ltrans6.ltrans.o uses VFP register arguments, /tmp/pmc/pmc.1.o does not
/usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /tmp/ccs6XVoG.ltrans6.ltrans.o
/usr/libexec/gcc/arm-none-eabi/ld: error: /tmp/ccs6XVoG.ltrans7.ltrans.o uses VFP register arguments, /tmp/pmc/pmc.1.o does not
/usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /tmp/ccs6XVoG.ltrans7.ltrans.o
/usr/libexec/gcc/arm-none-eabi/ld: error: /tmp/ccs6XVoG.ltrans8.ltrans.o uses VFP register arguments, /tmp/pmc/pmc.1.o does not
/usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /tmp/ccs6XVoG.ltrans8.ltrans.o
/usr/libexec/gcc/arm-none-eabi/ld: error: /tmp/ccs6XVoG.ltrans9.ltrans.o uses VFP register arguments, /tmp/pmc/pmc.1.o does not
/usr/libexec/gcc/arm-none-eabi/ld: failed to merge target specific data of file /tmp/ccs6XVoG.ltrans9.ltrans.o
/usr/lib/gcc/arm-none-eabi/5.3.0/../../../../arm-none-eabi/lib/crt0.o: In function `_start':
/var/tmp/portage/cross-arm-none-eabi/newlib-2.4.0/work/newlib-2.4.0/newlib/libc/sys/arm/crt0.S:403: undefined reference to `main'
/tmp/pmc/hal/entry.o: In function `__iRbssComp':
(.text+0x34): undefined reference to `ldSdata'
/tmp/pmc/hal/entry.o: In function `__iRbssComp':
(.text+0x38): undefined reference to `ldEtext'
/tmp/pmc/hal/entry.o: In function `__iRbssComp':
(.text+0x3c): undefined reference to `ldEdata'
/tmp/pmc/hal/entry.o: In function `__iRbssComp':
(.text+0x40): undefined reference to `ldSbss'
/tmp/pmc/hal/entry.o: In function `__iRbssComp':
(.text+0x44): undefined reference to `ldEbss'
/tmp/pmc/hal/entry.o:(.vectors+0x0): undefined reference to `ldStack'
/tmp/ccs6XVoG.ltrans4.ltrans.o: In function `halStart':
<artificial>:(.text+0x9c0): undefined reference to `ldSvectors'
collect2: error: ld returned 1 exit status
Makefile:57: recipe for target '/tmp/pmc/pmc' failed
make: *** [/tmp/pmc/pmc] Error 1

Undefined reference это понятно, надо как-то объяснять, что функция вызывается из вне и выбрасывать ее нельзя.

В первом случае похоже никакого LTO нет, судя по времени работы ld и сообщениях о плагинах, но почему есть undefined reference? Во втором не знаю как сделать, чтобы компоновки не было, а только бы произошла оптимизация и генерация объектного кода, дальше я бы сам вызвал ld как мне надо.

Исходный Makefile.

★★

Если линковать драйвером, то ему надо тоже передавать -flto. В выводе с -v можно глянуть параметры для линкера в таком случае (т.е. gcc -v -flto ...), но как бы там не абсолютные пути к плагину всегда (не знаю, можно ли с относительными делать). Поэтому, я бы линковал драйвером с опциями вроде -nostartfiles -nodefaultlibs -nostdlib, чтобы ничего дополнительно не добавлялось.

xaizek ★★★★★
()

Для векторов нужно таблицу прерываний объявить как используемую:

__attribute__ ((used, section(".vectors")))
void (* const vectors[])(void) =
{
  &_stack_top,                   // 0 - Initial Stack Pointer Value
.......

alexru ★★★★
()
Ответ на: комментарий от xaizek

Похоже помогло, и даже все undefined reference пропали.

amaora ★★
() автор топика
Ответ на: комментарий от amaora

Для .s файлов тоже должен быть такой синтаксис, нужно гуглить. Если не указывать, то выбросит.

PS: Какой смысл делать стартовый код на ассемблере, если специально сделали, чтобы на Си можно было?

alexru ★★★★
()
Последнее исправление: alexru (всего исправлений: 1)
Ответ на: комментарий от alexru

Но не выбрасывает, получается работающий код, быстрее работающий, но больше размером.

used не проходит в ассемблерный выхлоп компилятора, проверил. Видимо не нужно, там поздно уже.

Догадываюсь, то содержимое .s передается на компоновку как есть, а LTO работает с только тем внутренним представлением кода.

amaora ★★
() автор топика

*** Чтобы линковать lto-объектники и библиотеки требуется в ld, nm и ar подгружать плагин от gcc.

Это можно сделать двумя способами:

1) использовать gcc-nm, gcc-ar и т.п. если эти заглушки собраны вместе с gcc. Примерно так = https://github.com/ReOpen/ReOpenLDAP/blob/ps-stable/ps-build.sh#L57

2) использовать ключик --plugin при вызове binutils-утилит. Примерно так = https://github.com/ReOpen/ReOpenLDAP/blob/ps-stable/ps/ci-build.sh#L182

При этом желательно понимать чем ld.gold отличается от ld.bfd, и что именно скрывается за ld.

*** Чтобы линкер не выкидывал «ненужные символы» придется использовать атрибуты (used, externally_visible) или ld-ключик --undefined. С атрибутами проблема в том, что они могут не доходить до объектников, особенно при включенном lto. Это из-за багов в gcc и binutils, поэтому для lto настоятельно рекомендую только последние версии.

*** Чтобы при своем startup-коде не иметь проблем с линковкой через gcc обычно достаточно добавить -nostartfiles -nodefaultlibs -nostdlib и указать точку входа (--entry для ld). Но возможно придеться глянуть (или даже поправить) linker script - грубо говоря там задается как именно ld должен собирать исполнимый модуль, имена секций, их порядок и т.п.

ly
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.