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

ARM v7平台下如何将libc/libgcc共享库符号加入GOT以实现PIC固件?

解决ARM v7 PIC固件中libc非fPIC符号的GOT适配问题

针对你遇到的utoa无法正确引用digits字符串的问题,核心是非fPIC编译的libc库中全局符号未通过GOT寻址,以下是几种可行的解决思路:

1. 替换为fPIC编译的libc/libgcc库

arm-none-eabi工具链在Debian中通常提供支持PIC的嵌入式库变体:

  • 安装libnewlib-arm-none-eabi包(Debian官方仓库),该库默认包含fPIC编译的版本。
  • 编译时明确指定PIC相关选项:
    arm-none-eabi-gcc -mcpu=cortex-a7 -mthumb -fPIC -DPIC -c your_code.c -o your_code.o
    
    链接时添加-Wl,-pie以生成位置无关可执行,同时确保链接到PIC版本的库:
    arm-none-eabi-ld -pie -L/usr/lib/arm-none-eabi/thumb/v7-m/fpu -lc -lgcc your_code.o -o firmware.elf
    
    注意路径需根据你的工具链版本调整,可通过arm-none-eabi-gcc -print-search-dirs查询库路径。

2. 手动强制全局符号进入GOT

如果无法获取fPIC库,可通过代码和链接器技巧将特定符号(如digits)纳入GOT:

  • 在你的代码中添加对目标符号的弱引用并显式使用,强制编译器生成GOT条目:
    // 声明digits为弱引用,确保编译器为其生成GOT项
    extern const char digits[] __attribute__((weak));
    // 显式引用以触发GOT生成(即使代码中实际不用)
    static const char *dummy = digits;
    
  • 链接时使用-Wl,-y,digits验证符号是否被正确引用,并用readelf -r firmware.elf检查是否生成了R_ARM_GOT_PREL或R_ARM_GOT_BREL类型的重定位。

3. 自定义链接器脚本处理符号

编写链接器脚本,将指定符号标记为需通过GOT寻址:

SECTIONS {
  /* 保留原有脚本内容 */
  .got : {
    __got_start = .;
    /* 将digits符号加入GOT */
    PROVIDE_HIDDEN (__got_digits = .);
    LONG(digits - __got_start);
    __got_end = .;
  }
}

然后在你的GOT初始化代码中,手动修正__got_digits指向的地址,将其加上固件加载基地址,完成digits的GOT寻址适配。

4. 调整链接器重定位行为

使用链接器选项强制将全局符号重定向到GOT:

  • 添加-Wl,-q选项,禁止链接器对全局符号进行绝对地址绑定,强制使用GOT寻址。
  • 结合-Wl,-z,relro启用只读重定位段,提升安全性的同时确保GOT条目被正确初始化。

内容的提问来源于stack exchange,提问作者PTB

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:15:25