我正在尝试使用符号文件链接CortexM3上的程序。 “程序”在RAM中运行,并使用ROM中的静态绑定函数。所以我使用符号文件来识别所有ROM函数的地址。
问题是gcc似乎认为符号文件中的所有函数都是ARM32而不是Thumb,因此我最终得到了一个thumb-> arm32转换(当然因为M3不支持ARM32指令而崩溃)
test.c的:
extern void tfunc();
int main()
{
tfunc();
return 0;
}
symbolfile:
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不起作用,而汇编选项将是可行,它使构建系统显着更复杂
答案 0 :(得分:0)
请注意'blx'调用是偶数地址
这些函数由链接器ld
生成。
arm-none-eabi-ld test.o --just-symbols=symbolfile
您必须告诉arm-none-eabi-ld
您要生成缩略图代码。使用arm-none-eabi-gcc
作为前端进行链接通常更简单。