ARCH64:怎样恢复函数的栈



static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
struct stackframe frame;


pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);


if (!tsk)
tsk = current;


if (regs) {
frame.fp = regs->regs[29];
frame.sp = regs->sp;
frame.pc = regs->pc;
} else if (tsk == current) {
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_stack_pointer;
frame.pc = (unsigned long)dump_backtrace;
} else {
/*
* task blocked in __switch_to
*/
frame.fp = thread_saved_fp(tsk);
frame.sp = thread_saved_sp(tsk);
frame.pc = thread_saved_pc(tsk);
}


pr_emerg("Call trace:\n");
while (1) {
unsigned long where = frame.pc;
int ret;


ret = unwind_frame(&frame);
if (ret < 0)
break;
dump_backtrace_entry(where, frame.sp);
}
}


/*
 * This struct defines the way the registers are stored on the stack during an
 * exception. Note that sizeof(struct pt_regs) has to be a multiple of 16 (for
 * stack alignment). struct user_pt_regs must form a prefix of struct pt_regs.
 */
struct pt_regs {
union {
struct user_pt_regs user_regs;
struct {
u64 regs[31];
u64 sp;
u64 pc;
u64 pstate;
};
};
u64 orig_x0;
u64 syscallno;
};


struct stackframe {
unsigned long fp;
unsigned long sp;
unsigned long pc;
};




/*
 * AArch64 PCS assigns the frame pointer to x29.
 *
 * A simple function prologue looks like this:
 * sub sp, sp, #0x10
 *   stp x29, x30, [sp]
 * mov x29, sp
 *
 * A simple function epilogue looks like this:
 * mov sp, x29
 * ldp x29, x30, [sp]
 * add sp, sp, #0x10
 */
int notrace unwind_frame(struct stackframe *frame)
{
unsigned long high, low;
unsigned long fp = frame->fp;



low  = frame->sp;
high = ALIGN(low, THREAD_SIZE);/*fp的内容是stack: 所以下面的位置比较*/


if (fp < low || fp > high - 0x18 || fp & 0xf)
return -EINVAL;


/*已知当前帧的fp:+0x10 得到caller的sp*/
/*已知当前帧的fp: 得到caller的fp*/
/*已知当前帧的fp: +0x8得到caller的pc*/
frame->sp = fp + 0x10;
frame->fp = *(unsigned long *)(fp);
/*
* -4 here because we care about the PC at time of bl,
* not where the return will go.
*/
frame->pc = *(unsigned long *)(fp + 8) - 4;


return 0;
}


static void dump_backtrace_entry(unsigned long where, unsigned long stack)
{
print_ip_sym(where);
if (in_exception_text(where))
dump_mem("", "Exception stack", stack,
stack + sizeof(struct pt_regs));
}


static inline void print_ip_sym(unsigned long ip)
{
printk("[<%p>] %pS\n", (void *) ip, (void *) ip);
}


进程的堆栈中保存的内容:肯定包括LR:
frame->pc = *(unsigned long *)(fp + 8) - 4;
如果从打印的看:应该是%p+4:在堆栈中.请验证下:找到了fp: 就找到了函数的栈.A4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值