防止GCC LTO删除函数
我与GCC ARM Embedded和FreeRTOS合作。 FreeRTOS具有函数防止GCC LTO删除函数,c,gcc,ld,freertos,lto,C,Gcc,Ld,Freertos,Lto,我与GCC ARM Embedded和FreeRTOS合作。 FreeRTOS具有函数vTaskSwitchContext(),该函数仅在某些情况下使用 内联汇编代码 问题是:当我使用LTO时,GCC不考虑内联汇编代码,认为函数不被使用,因此删除它。然后链接器失败,因为内联汇编程序代码中的函数调用无法解析 我会应用\uuuu属性(used)),但我不想接触FreeRTOS代码(它是由STM32CubeMX生成的) 我试着把它放在我的代码中,但实际上GCC足够聪明,不允许它工作: if(false
vTaskSwitchContext()
,该函数仅在某些情况下使用
内联汇编代码
问题是:当我使用LTO时,GCC不考虑内联汇编代码,认为函数不被使用,因此删除它。然后链接器失败,因为内联汇编程序代码中的函数调用无法解析
我会应用\uuuu属性(used))
,但我不想接触FreeRTOS代码(它是由STM32CubeMX生成的)
我试着把它放在我的代码中,但实际上GCC足够聪明,不允许它工作:
if(false)
vTaskSwitchContext();
是否有某种方法可以在不同的源文件中或通过参数告诉GCC不应删除此函数
示例
// file1.c
void vTaskSwitchContext( void )
{
...
}
// file2.c
void xPortPendSVHandler( void )
{
__asm volatile
(
...
" isb \n"
" bl vTaskSwitchContext \n"
" mov r0, #0 \n"
...
);
}
尝试从标记为
used
的单独函数调用该函数
void dummyFunction(void) __attribute__((used));
// Never called.
void dummyFunction(void) {
vTaskSwitchContext();
}
您可以将
-Wl,--undefined=vTaskSwitchContext
添加到您的LDFLAGS
由于某种原因,迪特里希提出的解决方案对我不起作用。我使用的是英飞凌的DAVE 4(基本上是eclipse,为他们的XMC微控制器系列提供了一个奇特的代码生成插件),这可能就是它不起作用的原因。对我来说,我必须在vTaskStartScheduler()
之后调用vTaskSwitchContext()
:
如果您的FreeRTOS版本已使用宏
portDONT\u DISCARD
用于vTaskSwitchContext()
您可以在自己的portmacro.h
中定义portDONT\u DISCARD
\define portDONT\u DISCARD\u属性(已使用))
本质上是后移我想知道这是怎么发生的。链接器可以看到对象文件及其外部引用。一个符号是从C代码还是从内联程序集中引用都不重要。@undur_gongor:LTO改变了很多事情,通常会引起意外。“链接器”实际上看不到对象文件和外部引用,而是充当编译器后端的前端,然后从编译器后端链接结果。
int main(){
initializationCode();
vTaskStartScheduler();
//Code never reaches here
vTaskSwitchContext();
}