ARM 堆栈分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ARM stack backtrace x.yin@
Jun1,2009
目录目录目录
1前言2
2ARM寄存器和APCS2
2.1ARM寄存器 (2)
2.1.1ARM寄存器的定义 (2)
2.2APCS (3)
2.2.1应用程序和kernel的APCS (3)
2.2.2APCS-32简介 (3)
3示例代码4
3.1代码清单 (4)
3.1.1test.c (4)
3.1.2test.s (4)
4kernel中的函数callback trace6
2ARM寄存器和APCS 1前言
对于每个C语言开发者来说中,内存错误(内存泄漏,内存越界,野指针,空指针等)恐怕是再熟悉不过了。这些错误通常严重级别很高,隐藏很深而且会产生随机错误,即便在很多调试工具的帮助下,为了找到重现的路径,也需要花费大量的时间。对于uClinux来说,情况就更糟糕了,那些在x86上能够导致程序退出的错误,在uClinux 中大多数情况下并不会退出而只是产生奇怪的运行结果.我们知道,这类错误尽管可以在编码时尽量减少却无法做到全部根除,那么,在这类错误产生时,有什么办法能够帮助我们迅速定位呢?此时只能借助kernel了,如果Kernel在应用程序出错时dump出相应的函数调用顺序,那也就离解决问题不远了。
2ARM寄存器和APCS
在了解如何backtrace ARM下应用程序函数调用顺序之前,有必要先了解一下ARM的寄存器和APCS(ARM Procedure Call Standard).以我们的系统为例:•kernel:uClinux-2.4.22-uc0,
•CPU:PT110,ARM7TDMI兼容。
•gcc:2.95.3
2.1ARM寄存器
2.1.1ARM寄存器的定义
include/asm-armnommu/proc/ptrace.h
1/*this struct defines the way the registers are stored on the
2stack during a system call.*/
3
4struct pt_regs...{
5long uregs[18];
6};
7
8#define ARM_cpsr uregs[16]/*程序状态寄存器*/
9#define ARM_pc uregs[15]/*程序计数器下一条将要执行的指令,*/
10#define ARM_lr uregs[14]/*寄存器,返回地址link*/
11#define ARM_sp uregs[13]/*栈指针类似于,的x86esp*/
12#define ARM_ip uregs[12]/*暂存sp没什么大用,*/
13#define ARM_fp uregs[11]/*栈帧指针类似
于,的x86ebp*/
14#define ARM_r10uregs[10]
15#define ARM_r9uregs[9]
16#define ARM_r8uregs[8]
17#define ARM_r7uregs[7]
18#define ARM_r6uregs[6]
19#define ARM_r5uregs[5]
20#define ARM_r4uregs[4]
21#define ARM_r3uregs[3]
22#define ARM_r2uregs[2]
23#define ARM_r1uregs[1]
24#define ARM_r0uregs[0]
25#define ARM_ORIG_r0uregs[17]
2.2APCS2ARM寄存器和APCS
2.2APCS
2.2.1应用程序和kernel的APCS
编译一个简单的应用程序时,gcc会自动加上-D__ARM_ARCH_4T__-D__APCS_32 ,
$arm-elf-gcc-v-Wl,-elf2flt="-s32768"-Wall-o test test.c ......
/opt/toolchain/lib/gcc-lib/arm-elf/2.95.3/cpp0
-lang-c-v-D__GNUC__=2-D__GNUC_MINOR__=95
-Darm-Darm_elf-D__ELF__-D__arm__-D__arm_elf__
-D__ELF__-D__arm-D__arm_elf-Acpu(arm)-Amachine(arm)
-D__CHAR_UNSIGNED__-Wall-D__ARM_ARCH_4T__-D__APCS_32__
test.c/tmp/ccP0jvq3.i
汇编时同样会加上-mapcs-frame
......
/opt/toolchain/arm-elf/bin/as-mapcs-frame\
-o/tmp/ccZ2wPsV.o/tmp/cc8LUy5Y.s
......
编译时kernel同样会加上-mapcs-32-march=armv4,
make CFLAGS="-D__KERNEL__
-I/mnt/sda2/kernel/linux-2.4.22-em86xx/include
-Wall-Wstrict-prototypes-Wno-trigraphs
-O2-fno-strict-aliasing-fno-common-pipe-fno-builtin
-D__linux__-DNO_MM-mapcs-32-march=armv4-mtune=arm7tdmi
-mshort-load-bytes-msoft-float"-C drivers
也就是说无论编译kernel还是应用程序,ARM所用的APCS都为APCS-32.
2.2.2APCS-32简介
APCS,ARM过程调用标准(ARM Procedure Call Standard),提供了紧凑的编写
例程的一种机制,定义的例程可以与其他例程交织在一起。最显著的一点是对这些例
程来自哪里没有明确的限制。它们可以编译自C,Pascal也可以是用汇编语言写成的。APCS定义了:
•对寄存器使用的限制。
•使用栈的惯例。
•在函数调用之间传递/返回参数。
•可以被‘回溯’的基于栈的结构的格式,用来提供从失败点到程序入口的函数(和给
予的参数)的列表。APCS-32是APCS-2(-R和-U)的一个扩展,APCS-R用于
RISC OS应用程序在USR模式下进行操作;或在SVC模式下的模块/处理程序。
•sl=R10,fp=R11,ip=R12,sp=R13,lr=R14,pc=R15。