You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32 GCC下位置无关代码(-fpic)中的函数指针问题

解决STM32 GCC PIC固件中编译期初始化函数指针的硬 fault问题

针对你遇到的编译期初始化全局/静态函数指针在偏移运行时失效的问题,可通过以下几种方式解决:

方法1:运行时通过GOT初始化函数指针

避免编译期直接给函数指针赋值链接地址,改为在启动阶段从已被Bootloader修补的GOT段中获取函数的运行时地址来初始化指针:

#include <stdint.h>

void function() {
    // 业务逻辑
}

// 声明未初始化的函数指针,避免编译期写入无效的链接地址
void (*function_ptr)();

static void init_pointers() {
    // 使用GCC内置函数__builtin_gotptr获取函数在GOT中的条目地址
    uintptr_t* got_entry = (uintptr_t*)__builtin_gotptr(function);
    // 读取GOT条目中已修正的运行时地址,赋值给函数指针
    function_ptr = (void(*)())*got_entry;
}

int main() {
    init_pointers();
    function_ptr(); // 可正常调用,无硬 fault
    return 0;
}

方法2:强制编译器将初始化的函数指针关联到GOT

通过编译器属性将函数指针放入GOT相关段,让Bootloader在修补GOT时一并修正该指针:

void function() {
    // 业务逻辑
}

// 将函数指针放入GOT段,链接器会将其视为GOT条目
void (*function_ptr)() __attribute__((section(".got"))) = &function;

int main() {
    function_ptr(); // Bootloader修补GOT后即可正常调用
    return 0;
}

注意:此方法需要确保链接器脚本允许将用户变量放入.got段,部分默认链接器脚本可能需要调整。

方法3:调整编译/链接选项强制GOT寻址

在现有编译选项基础上,添加以下选项,强制GCC对全局函数指针使用GOT寻址:

-fpie -mpic-data-is-text-relative

说明:-mpic-data-is-text-relative会让数据段中的指针以文本段为基准计算偏移,在固件整体偏移运行时,该偏移量保持有效;配合-fpie进一步强化位置无关代码的生成逻辑。

内容的提问来源于stack exchange,提问作者Matteo Vittorio Ricciutelli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:53:21