简体   繁体   English

在LTO模式下用于ARM的GCC 8正在删除中断处理程序和弱功能 - 如何防止它?

[英]GCC 8 for ARM in LTO mode is removing interrupt handlers and weak functions - how to prevent it?

My target device is an EFM32 Cortex-M3 based device. 我的目标设备是基于EFM32 Cortex-M3的设备。 My toolchain is the official ARM GNU toolchain gcc-arm-none-eabi-8-2018-q4-major. 我的工具链是官方ARM GNU工具链gcc-arm-none-eabi-8-2018-q4-major。

Everything works fine without LTO, but to make LTO work I have to mark all interrupt handler code with -fno-lto . 没有LTO,一切正常,但要使LTO工作,我必须用-fno-lto标记所有中断处理程序代码。 I would like to get rid of this workaround. 我想摆脱这种解决方法。

The problem is, every interrupt handler is getting removed from the final binary. 问题是,每个中断处理程序都从最终的二进制文件中删除。 (I am checking with arm-none-eabi-nm --print-size --size-sort --radix=d -C -n file.out ) This makes the resulting binary crash. (我正在检查arm-none-eabi-nm --print-size --size-sort --radix=d -C -n file.out )这会导致生成的二进制文件崩溃。

Digging deeper and after googling for similar problems: 更深入地挖掘谷歌搜索类似的问题:

Sample code from startup_efm32gg.c defines default interrupt handlers as such: startup_efm32gg.c示例代码定义了默认的中断处理程序:

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

The same problem happens for regular interrupt handler definitions as well (as in, no aliases and not weak) 对于常规中断处理程序定义也会出现同样的问题(例如,没有别名而不是弱)

It might be related but it seems that weak symbols are misbehaving in LTO mode in the same way. 它可能是相关的,但似乎弱符号在LTO模式下以相同的方式行为不端。

Thank you in advance for any ideas! 提前感谢您的任何想法!

Edit: See my reply to the marked answer for a full solution! 编辑:请参阅我对标记答案的回复以获得完整的解决方案!

Where are your interrupt handlers referenced from? 您的中断处理程序在哪里引用? Just like unreferenced static functions and objects will be removed from a single translation unit, external ones that are unused will be removed during LTO. 就像未引用的静态函数和对象将从单个转换单元中删除一样,未使用的外部函数和对象将在LTO期间被删除。 In order to prevent this (and in order for your program to be valid anyway in the abstract model) there needs to be some chain of references, starting from the entry point, leading to the functions and objects; 为了防止这种情况(并且为了使程序在抽象模型中无论如何都是有效的),需要有一些引用链,从入口点开始,导致函数和对象; if none exists, then you're not actually using them in your program . 如果不存在,那么你实际上并没有在你的程序中使用它们

If the reference is from a linker script or asm source file, it's possible that this is a bug in LTO, and it's not seeing the references like it should. 如果引用来自链接器脚本或asm源文件,则可能是LTO中的错误,并且它没有看到类似的引用。 In this case you might be able to apply a hack like __attribute__((__used__)) to the affected function definitions. 在这种情况下,您可以将__attribute__((__used__))等hack应用于受影响的函数定义。 Alternatively you could make fake references to them, eg by storing their addresses to dummy volatile objects or using their addresses in input constraints to empty inline asm blocks. 或者,您可以对它们进行虚假引用,例如,通过将其地址存储到虚拟易失性对象或使用其输入约束中的地址来清空内联asm块。 As yet another alternative, there may be a way to redo whatever you're doing with asm source files or linked scripts to make your interrupt table at the C level, with appropriate structs/arrays in special sections, so that the compiler can actually see the references without you having to fake them. 作为另一种选择,可能有一种方法可以重做您正在使用asm源文件或链接脚本执行的任何操作,以使您的中断表处于C级别,并在特殊部分中使用适当的结构/数组,以便编译器可以实际看到引用而不必伪造它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM