我正在尝试实现gcc分析。
我在PowerPC上使用嵌入式环境eCos。我用C编程
当我使用-pg
开关进行编译和链接时,发现符号_mcount
未定义。
我意识到我需要实现此功能,因为它是针对特定目标的。_mcount
功能有什么要求?
我是否正确,它必须保存和还原所有寄存器?是否有必须与标准32一起保存和恢复的特殊寄存器?
我看到有评论说_mcount
必须在禁用中断的情况下调用,或者_mcount
在记录调用树数据之前是否禁用中断?
我的PowerPC是8245。这是603e系列处理器。
我正在使用GCC 4.6.1作为powerpc-eabi作为交叉编译器构建。
这是gcc生成的_mcount调用的示例。正在分析的函数的第一条指令是显示的第一行:
100b40: 7c 08 02 a6 mflr r0
100b44: 3d 80 00 23 lis r12,35
100b48: 90 01 00 04 stw r0,4(r1)
100b4c: 38 0c 82 a8 addi r0,r12,-32088
100b50: 48 05 19 25 bl 152474 <_mcount>
100b54: 94 21 ff 88 stwu r1,-120(r1)
100b58: 7c 08 02 a6 mflr r0
100b5c: 90 01 00 7c stw r0,124(r1)
100b60: 93 e1 00 74 stw r31,116(r1)
100b64: 7c 3f 0b 78 mr r31,r1
由编译器开关
-pg
创建的代码执行以下操作。1)调用者的地址通过两个指令
mflr r0
和stw r0,4(r1)
存储在堆栈中。2)刚输入的功能的地址用两个指令
r0
和lis r12,35
存储在addi r0,r12,-32088
中。因此,当调用
_mcount
时,r0
包含输入的函数地址,而4(r1)
包含调用者的程序计数器。这对信息将被存储并用于创建调用图。我通过阅读gcc源gcc / libffi / src / powerpc / asm.h找到了此信息。
我仍然不确定
_mcount
应该返回什么。看来它必须还原LR,以便_mcount
不能使用blr
,它必须从(4)r1
还原LR,并使用跳转指令而不是blr
返回到bl _mcount
之后的指令。这有意义吗? 最佳答案
现在已签入eCos RTOS信息库的PowerPC的_mcount
实现:
http://ecos.sourceware.org/cgi-bin/cvsweb.cgi/ecos/packages/hal/powerpc/arch/current/src/mcount.S?cvsroot=ecos