我正在尝试实现 gcc 分析。
我正在使用带有 PowerPC 的嵌入式环境 eCos。我用 C 编程。
当我使用开关编译和链接时-pg
,我发现符号_mcount
未定义。
我意识到我需要实现这个功能,因为它是特定于目标的。
对功能有什么要求_mcount
?
我是否正确,它必须保存和恢复所有寄存器?是否有任何特殊寄存器必须与标准 32 一起保存和恢复?
我看到评论说_mcount
必须在禁用中断的情况下调用,或者_mcount
在记录调用树数据之前禁用中断?
我的 PowerPC 是 8245。这是 603e 系列处理器。
我正在使用作为 powerpc-eabi 的交叉编译器构建的 GCC 4.6.1。
这是 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
执行以下操作。
mflr r0
1) 调用者的地址用两条指令和存储在堆栈中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
,它必须恢复LR(4)r1
并使用跳转指令而不是blr
返回到之后的指令bl _mcount
。这有意义吗?