我正在尝试使用符号文件来链接 CortexM3 上的程序。“程序”在 RAM 中运行并使用 ROM 中的静态绑定函数。所以我使用一个符号文件来识别所有 ROM 函数的地址。
问题是 gcc 似乎认为符号文件中的所有函数都是 ARM32 而不是 Thumb,所以我最终进行了 thumb->arm32 转换(由于 M3 不支持 ARM32 指令,这当然会崩溃)
测试.c:
extern void tfunc();
int main()
{
tfunc();
return 0;
}
符号文件:
tfunc = 0x08011029;
编译:
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c test.c
arm-none-eabi-ld test.o --just-symbols=symbolfile
结果代码如下:
arm-none-eabi-objdump -d a.out
a.out: file format elf32-littlearm
Disassembly of section .text:
00008000 <main>:
8000: b580 push {r7, lr}
8002: af00 add r7, sp, #0
8004: f000 e804 blx 8010 <__tfunc_from_thumb>
8008: 2300 movs r3, #0
800a: 4618 mov r0, r3
800c: bd80 pop {r7, pc}
800e: bf00 nop
00008010 <__tfunc_from_thumb>:
8010: e51ff004 ldr pc, [pc, #-4] ; 8014 <__tfunc_from_thumb+0x4>
8014: 08011029 .word 0x08011029
请注意,“blx”调用是到偶数地址,而 M3 规范要求所有跳转到奇数(拇指)地址
我在网上找到了一种使用汇编程序而不是符号文件的解决方案:sym.s:
.global tfunc
.type tfunc %function
.equ tfunc, 0x08011029
并建立:
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c test.c
arm-none-eabi-as -o sym.o sym.s
arm-none-eabi-ld test.o sym.o
这会生成一个(相当冗长,但至少在功能上正确的单板):
00008000 <main>:
8000: b580 push {r7, lr}
8002: af00 add r7, sp, #0
8004: f000 f804 bl 8010 <__tfunc_veneer>
8008: 2300 movs r3, #0
800a: 4618 mov r0, r3
800c: bd80 pop {r7, pc}
800e: bf00 nop
00008010 <__tfunc_veneer>:
8010: b401 push {r0}
8012: 4802 ldr r0, [pc, #8] ; (801c <__tfunc_veneer+0xc>)
8014: 4684 mov ip, r0
8016: bc01 pop {r0}
8018: 4760 bx ip
801a: bf00 nop
801c: 08011029 .word 0x08011029
我发现我可以通过在我的 c 代码顶部添加“#pragma long_calls”来解决这个问题。
但是,我的问题不是如何让我的代码正确构建,而是如何将符号文件与 CortexM 一起使用,因为在某些情况下 #pragma 不起作用,虽然汇编选项是可行的,但它使构建系统更加复杂