防止GCC LTO删除函数

防止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

我与GCC ARM Embedded和FreeRTOS合作。 FreeRTOS具有函数
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();
}